USB: io_ti: Move download and boot mode code out of download_fw

Separate the download and boot mode code from download_fw() into two new
helper functions: do_download_mode() and do_boot_mode().

Signed-off-by: Peter E. Berger <pberger@brimson.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
Peter E. Berger 2015-09-16 03:13:00 -05:00 committed by Johan Hovold
parent ef9324b2bd
commit bebf1f185c
1 changed files with 194 additions and 166 deletions

View File

@ -223,6 +223,11 @@ static void edge_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios);
static void edge_send(struct usb_serial_port *port, struct tty_struct *tty);
static int do_download_mode(struct edgeport_serial *serial,
const struct firmware *fw);
static int do_boot_mode(struct edgeport_serial *serial,
const struct firmware *fw);
/* sysfs attributes */
static int edge_create_sysfs_attrs(struct usb_serial_port *port);
static int edge_remove_sysfs_attrs(struct usb_serial_port *port);
@ -991,11 +996,7 @@ static int download_fw(struct edgeport_serial *serial,
{
struct device *dev = &serial->serial->interface->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;
struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
if (check_fw_sanity(serial, fw))
@ -1029,16 +1030,27 @@ static int download_fw(struct edgeport_serial *serial,
* if we have more than one endpoint we are definitely in download
* mode
*/
if (interface->bNumEndpoints > 1)
if (interface->bNumEndpoints > 1) {
serial->product_info.TiMode = TI_MODE_DOWNLOAD;
else
return do_download_mode(serial, fw);
}
/* Otherwise we will remain in configuring mode */
serial->product_info.TiMode = TI_MODE_CONFIGURING;
return do_boot_mode(serial, fw);
/********************************************************************/
/* Download Mode */
/********************************************************************/
if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
}
static int do_download_mode(struct edgeport_serial *serial,
const struct firmware *fw)
{
struct device *dev = &serial->serial->interface->dev;
int status = 0;
int start_address;
struct edge_ti_manuf_descriptor *ti_manuf_desc;
int download_cur_ver;
int download_new_ver;
struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
struct ti_i2c_desc *rom_desc;
dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
@ -1083,7 +1095,8 @@ static int download_fw(struct edgeport_serial *serial,
struct ti_i2c_firmware_rec *firmware_version;
u8 *record;
dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n", __func__);
dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n",
__func__);
firmware_version = kmalloc(sizeof(*firmware_version),
GFP_KERNEL);
@ -1108,7 +1121,7 @@ static int download_fw(struct edgeport_serial *serial,
}
/* Check version number of download with current
version in I2c */
* version in I2c */
download_cur_ver = (firmware_version->Ver_Major << 8) +
(firmware_version->Ver_Minor);
download_new_ver = (fw_hdr->major_version << 8) +
@ -1120,7 +1133,7 @@ static int download_fw(struct edgeport_serial *serial,
fw_hdr->major_version, fw_hdr->minor_version);
/* Check if we have an old version in the I2C and
update if necessary */
* update if necessary */
if (download_cur_ver < download_new_ver) {
dev_dbg(dev, "%s - Update I2C dld from %d.%d to %d.%d\n",
__func__,
@ -1136,7 +1149,8 @@ static int download_fw(struct edgeport_serial *serial,
kfree(ti_manuf_desc);
return -ENOMEM;
}
/* In order to update the I2C firmware we must
/*
* 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
@ -1151,7 +1165,7 @@ static int download_fw(struct edgeport_serial *serial,
*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
/* Change the I2C Firmware record type to
0xf2 to trigger an update */
* 0xf2 to trigger an update */
status = write_rom(serial, start_address,
sizeof(*record), record);
if (status) {
@ -1179,7 +1193,8 @@ static int download_fw(struct edgeport_serial *serial,
}
if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
dev_err(dev, "%s - error resetting device\n", __func__);
dev_err(dev, "%s - error resetting device\n",
__func__);
kfree(record);
kfree(firmware_version);
kfree(rom_desc);
@ -1195,7 +1210,8 @@ static int download_fw(struct edgeport_serial *serial,
0, 0, NULL, 0,
TI_VSEND_TIMEOUT_DEFAULT);
dev_dbg(dev, "%s - HARDWARE RESET return %d\n", __func__, status);
dev_dbg(dev, "%s - HARDWARE RESET return %d\n",
__func__, status);
/* return an error on purpose. */
kfree(record);
@ -1203,14 +1219,16 @@ static int download_fw(struct edgeport_serial *serial,
kfree(rom_desc);
kfree(ti_manuf_desc);
return -ENODEV;
} else {
}
/* Same or newer fw version is already loaded */
serial->fw_version = download_cur_ver;
}
kfree(firmware_version);
}
/* Search for type 0xF2 record (firmware blank record) */
else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
else {
start_address = get_descriptor_addr(serial,
I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc);
if (start_address != 0) {
#define HEADER_SIZE (sizeof(struct ti_i2c_desc) + \
sizeof(struct ti_i2c_firmware_rec))
__u8 *header;
@ -1231,7 +1249,8 @@ static int download_fw(struct edgeport_serial *serial,
return -ENOMEM;
}
dev_dbg(dev, "%s - Found Type BLANK FIRMWARE (Type F2) record\n", __func__);
dev_dbg(dev, "%s - Found Type BLANK FIRMWARE (Type F2) record\n",
__func__);
/*
* In order to update the I2C firmware we must change
@ -1254,7 +1273,7 @@ static int download_fw(struct edgeport_serial *serial,
}
/* Update I2C with type 0xf2 record with correct
size and checksum */
* size and checksum */
status = write_rom(serial,
start_address,
HEADER_SIZE,
@ -1268,12 +1287,13 @@ static int download_fw(struct edgeport_serial *serial,
}
/* verify the write -- must do this in order for
write to complete before we do the hardware reset */
* write to complete before we do the hardware reset */
status = read_rom(serial, start_address,
HEADER_SIZE, vheader);
if (status) {
dev_dbg(dev, "%s - can't read header back\n", __func__);
dev_dbg(dev, "%s - can't read header back\n",
__func__);
kfree(vheader);
kfree(header);
kfree(rom_desc);
@ -1281,7 +1301,8 @@ static int download_fw(struct edgeport_serial *serial,
return status;
}
if (memcmp(vheader, header, HEADER_SIZE)) {
dev_dbg(dev, "%s - write download record failed\n", __func__);
dev_dbg(dev, "%s - write download record failed\n",
__func__);
kfree(vheader);
kfree(header);
kfree(rom_desc);
@ -1300,7 +1321,8 @@ static int download_fw(struct edgeport_serial *serial,
0, 0, NULL, 0,
TI_VSEND_TIMEOUT_FW_DOWNLOAD);
dev_dbg(dev, "%s - Update complete 0x%x\n", __func__, status);
dev_dbg(dev, "%s - Update complete 0x%x\n", __func__,
status);
if (status) {
dev_err(dev,
"%s - UMPC_COPY_DNLD_TO_I2C failed\n",
@ -1310,16 +1332,22 @@ static int download_fw(struct edgeport_serial *serial,
return status;
}
}
}
// The device is running the download code
/* The device is running the download code */
kfree(rom_desc);
kfree(ti_manuf_desc);
return 0;
}
/********************************************************************/
/* Boot Mode */
/********************************************************************/
static int do_boot_mode(struct edgeport_serial *serial,
const struct firmware *fw)
{
struct device *dev = &serial->serial->interface->dev;
int status = 0;
struct edge_ti_manuf_descriptor *ti_manuf_desc;
struct edgeport_fw_hdr *fw_hdr = (struct edgeport_fw_hdr *)fw->data;
dev_dbg(dev, "%s - RUNNING IN BOOT MODE\n", __func__);
/* Configure the TI device so we can use the BULK pipes for download */