Commit bebf1f18 authored by Peter E. Berger's avatar Peter E. Berger Committed by Johan Hovold
Browse files

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: default avatarPeter E. Berger <pberger@brimson.com>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent ef9324b2
Loading
Loading
Loading
Loading
+195 −167
Original line number Diff line number Diff line
@@ -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 */