Skip to content

Commit

Permalink
edgeport: use request_firmware()
Browse files Browse the repository at this point in the history
Version number provided in first HEX record.

Signed-off-by: Jaswinder Singh <[email protected]>
Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
Jaswinder Singh authored and David Woodhouse committed Jul 14, 2008
1 parent fb54be8 commit 5b9ea93
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 3,557 deletions.
183 changes: 90 additions & 93 deletions drivers/usb/serial/io_edgeport.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
#include <linux/serial.h>
#include <linux/ioctl.h>
#include <linux/wait.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
Expand All @@ -56,26 +58,6 @@
#define DRIVER_AUTHOR "Greg Kroah-Hartman <[email protected]> and David Iacovelli"
#define DRIVER_DESC "Edgeport USB Serial Driver"

/* First, the latest boot code - for first generation edgeports */
#define IMAGE_ARRAY_NAME BootCodeImage_GEN1
#define IMAGE_VERSION_NAME BootCodeImageVersion_GEN1
#include "io_fw_boot.h" /* the bootloader firmware to download to a device, if it needs it */

/* for second generation edgeports */
#define IMAGE_ARRAY_NAME BootCodeImage_GEN2
#define IMAGE_VERSION_NAME BootCodeImageVersion_GEN2
#include "io_fw_boot2.h" /* the bootloader firmware to download to a device, if it needs it */

/* Then finally the main run-time operational code - for first generation edgeports */
#define IMAGE_ARRAY_NAME OperationalCodeImage_GEN1
#define IMAGE_VERSION_NAME OperationalCodeImageVersion_GEN1
#include "io_fw_down.h" /* Define array OperationalCodeImage[] */

/* for second generation edgeports */
#define IMAGE_ARRAY_NAME OperationalCodeImage_GEN2
#define IMAGE_VERSION_NAME OperationalCodeImageVersion_GEN2
#include "io_fw_down2.h" /* Define array OperationalCodeImage[] */

#define MAX_NAME_LEN 64

#define CHASE_TIMEOUT (5*HZ) /* 5 seconds */
Expand Down Expand Up @@ -256,9 +238,9 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8
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 sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __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 int rom_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __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);
Expand All @@ -283,45 +265,49 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
{
__u32 BootCurVer;
__u32 BootNewVer;
__u8 BootMajorVersion;
__u8 BootMinorVersion;
__le16 BootBuildNumber;
__u8 *BootImage;
__u32 BootSize;
struct edge_firmware_image_record *record;
unsigned char *firmware;
__u8 BootMajorVersion;
__u8 BootMinorVersion;
__u16 BootBuildNumber;
__u32 Bootaddr;
const struct ihex_binrec *rec;
const struct firmware *fw;
const char *fw_name;
int response;


switch (edge_serial->product_info.iDownloadFile) {
case EDGE_DOWNLOAD_FILE_I930:
BootMajorVersion = BootCodeImageVersion_GEN1.MajorVersion;
BootMinorVersion = BootCodeImageVersion_GEN1.MinorVersion;
BootBuildNumber = cpu_to_le16(BootCodeImageVersion_GEN1.BuildNumber);
BootImage = &BootCodeImage_GEN1[0];
BootSize = sizeof( BootCodeImage_GEN1 );
fw_name = "edgeport/boot.fw";
break;

case EDGE_DOWNLOAD_FILE_80251:
BootMajorVersion = BootCodeImageVersion_GEN2.MajorVersion;
BootMinorVersion = BootCodeImageVersion_GEN2.MinorVersion;
BootBuildNumber = cpu_to_le16(BootCodeImageVersion_GEN2.BuildNumber);
BootImage = &BootCodeImage_GEN2[0];
BootSize = sizeof( BootCodeImage_GEN2 );
fw_name = "edgeport/boot2.fw";
break;

default:
return;
}

response = request_ihex_firmware(&fw, fw_name,
&edge_serial->serial->dev->dev);
if (response) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fw_name, response);
return;
}

rec = (const struct ihex_binrec *)fw->data;
BootMajorVersion = rec->data[0];
BootMinorVersion = rec->data[1];
BootBuildNumber = (rec->data[2] << 8) | rec->data[3];

// Check Boot Image Version
BootCurVer = (edge_serial->boot_descriptor.MajorVersion << 24) +
(edge_serial->boot_descriptor.MinorVersion << 16) +
le16_to_cpu(edge_serial->boot_descriptor.BuildNumber);

BootNewVer = (BootMajorVersion << 24) +
(BootMinorVersion << 16) +
le16_to_cpu(BootBuildNumber);
BootBuildNumber;

dbg("Current Boot Image version %d.%d.%d",
edge_serial->boot_descriptor.MajorVersion,
Expand All @@ -334,30 +320,30 @@ static void update_edgeport_E2PROM (struct edgeport_serial *edge_serial)
edge_serial->boot_descriptor.MajorVersion,
edge_serial->boot_descriptor.MinorVersion,
le16_to_cpu(edge_serial->boot_descriptor.BuildNumber),
BootMajorVersion,
BootMinorVersion,
le16_to_cpu(BootBuildNumber));

BootMajorVersion, BootMinorVersion, BootBuildNumber);

dbg("Downloading new Boot Image");

firmware = BootImage;

for (;;) {
record = (struct edge_firmware_image_record *)firmware;
response = rom_write (edge_serial->serial, le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len), &record->Data[0]);
for (rec = ihex_next_binrec(rec); rec;
rec = ihex_next_binrec(rec)) {
Bootaddr = be32_to_cpu(rec->addr);
response = rom_write(edge_serial->serial,
Bootaddr >> 16,
Bootaddr & 0xFFFF,
be16_to_cpu(rec->len),
&rec->data[0]);
if (response < 0) {
dev_err(&edge_serial->serial->dev->dev, "rom_write failed (%x, %x, %d)\n", le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len));
break;
}
firmware += sizeof (struct edge_firmware_image_record) + le16_to_cpu(record->Len);
if (firmware >= &BootImage[BootSize]) {
dev_err(&edge_serial->serial->dev->dev,
"rom_write failed (%x, %x, %d)\n",
Bootaddr >> 16, Bootaddr & 0xFFFF,
be16_to_cpu(rec->len));
break;
}
}
} else {
dbg("Boot Image -- already up to date");
}
release_firmware(fw);
}


Expand Down Expand Up @@ -447,9 +433,6 @@ static void dump_product_info(struct edgeport_product_info *product_info)
dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion,
product_info->BootMinorVersion,
le16_to_cpu(product_info->BootBuildNumber));
dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion,
product_info->FirmwareMinorVersion,
le16_to_cpu(product_info->FirmwareBuildNumber));
dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0],
product_info->ManufactureDescDate[1],
product_info->ManufactureDescDate[2]+1900);
Expand Down Expand Up @@ -480,14 +463,8 @@ static void get_product_info(struct edgeport_serial *edge_serial)

// check if this is 2nd generation hardware
if (le16_to_cpu(edge_serial->serial->dev->descriptor.idProduct) & ION_DEVICE_ID_80251_NETCHIP) {
product_info->FirmwareMajorVersion = OperationalCodeImageVersion_GEN2.MajorVersion;
product_info->FirmwareMinorVersion = OperationalCodeImageVersion_GEN2.MinorVersion;
product_info->FirmwareBuildNumber = cpu_to_le16(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 = cpu_to_le16(OperationalCodeImageVersion_GEN1.BuildNumber);
product_info->iDownloadFile = EDGE_DOWNLOAD_FILE_I930;
}

Expand Down Expand Up @@ -2130,7 +2107,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData, __u8 l
* If successful returns the number of bytes written, otherwise it returns
* a negative error number of the problem.
****************************************************************************/
static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data)
static int sram_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, const __u8 *data)
{
int result;
__u16 current_length;
Expand Down Expand Up @@ -2175,7 +2152,7 @@ static int sram_write (struct usb_serial *serial, __u16 extAddr, __u16 addr, __u
* If successful returns the number of bytes written, otherwise it returns
* a negative error number of the problem.
****************************************************************************/
static int rom_write (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, const __u8 *data)
{
int result;
__u16 current_length;
Expand Down Expand Up @@ -2761,32 +2738,23 @@ static void get_boot_desc (struct edgeport_serial *edge_serial)
****************************************************************************/
static void load_application_firmware (struct edgeport_serial *edge_serial)
{
struct edge_firmware_image_record *record;
unsigned char *firmware;
unsigned char *FirmwareImage;
int ImageSize;
const struct ihex_binrec *rec;
const struct firmware *fw;
const char *fw_name;
const char *fw_info;
int response;

__u32 Operaddr;
__u16 build;

switch (edge_serial->product_info.iDownloadFile) {
case EDGE_DOWNLOAD_FILE_I930:
dbg("downloading firmware version (930) %d.%d.%d",
OperationalCodeImageVersion_GEN1.MajorVersion,
OperationalCodeImageVersion_GEN1.MinorVersion,
OperationalCodeImageVersion_GEN1.BuildNumber);
firmware = &OperationalCodeImage_GEN1[0];
FirmwareImage = &OperationalCodeImage_GEN1[0];
ImageSize = sizeof(OperationalCodeImage_GEN1);
fw_info = "downloading firmware version (930)";
fw_name = "edgeport/down.fw";
break;

case EDGE_DOWNLOAD_FILE_80251:
dbg("downloading firmware version (80251) %d.%d.%d",
OperationalCodeImageVersion_GEN2.MajorVersion,
OperationalCodeImageVersion_GEN2.MinorVersion,
OperationalCodeImageVersion_GEN2.BuildNumber);
firmware = &OperationalCodeImage_GEN2[0];
FirmwareImage = &OperationalCodeImage_GEN2[0];
ImageSize = sizeof(OperationalCodeImage_GEN2);
fw_info = "downloading firmware version (80251)";
fw_name = "edgeport/down2.fw";
break;

case EDGE_DOWNLOAD_FILE_NONE:
Expand All @@ -2797,16 +2765,36 @@ static void load_application_firmware (struct edgeport_serial *edge_serial)
return;
}

response = request_ihex_firmware(&fw, fw_name,
&edge_serial->serial->dev->dev);
if (response) {
printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
fw_name, response);
return;
}

rec = (const struct ihex_binrec *)fw->data;
build = (rec->data[2] << 8) | rec->data[3];

dbg("%s %d.%d.%d", fw_info, rec->data[0], rec->data[1], build);

edge_serial->product_info.FirmwareMajorVersion = fw->data[0];
edge_serial->product_info.FirmwareMinorVersion = fw->data[1];
edge_serial->product_info.FirmwareBuildNumber = cpu_to_le16(build);

for (;;) {
record = (struct edge_firmware_image_record *)firmware;
response = sram_write (edge_serial->serial, le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len), &record->Data[0]);
for (rec = ihex_next_binrec(rec); rec;
rec = ihex_next_binrec(rec)) {
Operaddr = be32_to_cpu(rec->addr);
response = sram_write(edge_serial->serial,
Operaddr >> 16,
Operaddr & 0xFFFF,
be16_to_cpu(rec->len),
&rec->data[0]);
if (response < 0) {
dev_err(&edge_serial->serial->dev->dev, "sram_write failed (%x, %x, %d)\n", le16_to_cpu(record->ExtAddr), le16_to_cpu(record->Addr), le16_to_cpu(record->Len));
break;
}
firmware += sizeof (struct edge_firmware_image_record) + le16_to_cpu(record->Len);
if (firmware >= &FirmwareImage[ImageSize]) {
dev_err(&edge_serial->serial->dev->dev,
"sram_write failed (%x, %x, %d)\n",
Operaddr >> 16, Operaddr & 0xFFFF,
be16_to_cpu(rec->len));
break;
}
}
Expand All @@ -2817,6 +2805,7 @@ static void load_application_firmware (struct edgeport_serial *edge_serial)
USB_REQUEST_ION_EXEC_DL_CODE,
0x40, 0x4000, 0x0001, NULL, 0, 3000);

release_firmware(fw);
return;
}

Expand Down Expand Up @@ -2903,6 +2892,10 @@ static int edge_startup (struct usb_serial *serial)
// dbg("set_configuration 1");
// usb_set_configuration (dev, 1);
}
dbg(" FirmwareMajorVersion %d.%d.%d",
edge_serial->product_info.FirmwareMajorVersion,
edge_serial->product_info.FirmwareMinorVersion,
le16_to_cpu(edge_serial->product_info.FirmwareBuildNumber));

/* we set up the pointers to the endpoints in the edge_open function,
* as the structures aren't created yet. */
Expand Down Expand Up @@ -3115,6 +3108,10 @@ module_exit(edgeport_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("edgeport/boot.fw");
MODULE_FIRMWARE("edgeport/boot2.fw");
MODULE_FIRMWARE("edgeport/down.fw");
MODULE_FIRMWARE("edgeport/down2.fw");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
Expand Down
Loading

0 comments on commit 5b9ea93

Please sign in to comment.