[PATCH v2 3/6] USB: io_ti: Move download and boot mode code out of download_fw

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Peter E. Berger" <pberger@xxxxxxxxxxx>

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@xxxxxxxxxxx>
---
 drivers/usb/serial/io_ti.c | 362 ++++++++++++++++++++++++---------------------
 1 file changed, 195 insertions(+), 167 deletions(-)

diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index d41ba74..b371a0a 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -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,190 +1030,207 @@ 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
-		/* Otherwise we will remain in configuring mode */
-		serial->product_info.TiMode = TI_MODE_CONFIGURING;
+		return do_download_mode(serial, fw);
+	}
 
-	/********************************************************************/
-	/* Download Mode */
-	/********************************************************************/
-	if (serial->product_info.TiMode == TI_MODE_DOWNLOAD) {
-		struct ti_i2c_desc *rom_desc;
+	/* Otherwise we will remain in configuring mode */
+	serial->product_info.TiMode = TI_MODE_CONFIGURING;
+	return do_boot_mode(serial, fw);
 
-		dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
+}
 
-		status = check_i2c_image(serial);
-		if (status) {
-			dev_dbg(dev, "%s - DOWNLOAD MODE -- BAD I2C\n", __func__);
-			return status;
-		}
+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;
 
-		/* 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)
-			return -ENOMEM;
+	dev_dbg(dev, "%s - RUNNING IN DOWNLOAD MODE\n", __func__);
 
-		status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
-		if (status) {
-			kfree(ti_manuf_desc);
-			return status;
-		}
+	status = check_i2c_image(serial);
+	if (status) {
+		dev_dbg(dev, "%s - DOWNLOAD MODE -- BAD I2C\n", __func__);
+		return status;
+	}
 
-		/* Check version number of ION descriptor */
-		if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
-			dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
-				__func__, ti_cpu_rev(ti_manuf_desc));
-			kfree(ti_manuf_desc);
-			return -EINVAL;
-  		}
+	/* 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)
+		return -ENOMEM;
 
-		rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
-		if (!rom_desc) {
+	status = get_manuf_info(serial, (__u8 *)ti_manuf_desc);
+	if (status) {
+		kfree(ti_manuf_desc);
+		return status;
+	}
+
+	/* Check version number of ION descriptor */
+	if (!ignore_cpu_rev && ti_cpu_rev(ti_manuf_desc) < 2) {
+		dev_dbg(dev, "%s - Wrong CPU Rev %d (Must be 2)\n",
+			__func__, ti_cpu_rev(ti_manuf_desc));
+		kfree(ti_manuf_desc);
+		return -EINVAL;
+	}
+
+	rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL);
+	if (!rom_desc) {
+		kfree(ti_manuf_desc);
+		return -ENOMEM;
+	}
+
+	/* Search for type 2 record (firmware record) */
+	start_address = get_descriptor_addr(serial,
+			I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
+	if (start_address != 0) {
+		struct ti_i2c_firmware_rec *firmware_version;
+		u8 *record;
+
+		dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n",
+				__func__);
+
+		firmware_version = kmalloc(sizeof(*firmware_version),
+							GFP_KERNEL);
+		if (!firmware_version) {
+			kfree(rom_desc);
 			kfree(ti_manuf_desc);
 			return -ENOMEM;
 		}
 
-		/* Search for type 2 record (firmware record) */
-		start_address = get_descriptor_addr(serial,
-				I2C_DESC_TYPE_FIRMWARE_BASIC, rom_desc);
-		if (start_address != 0) {
-			struct ti_i2c_firmware_rec *firmware_version;
-			u8 *record;
+		/* Validate version number
+		 * Read the descriptor data
+		 */
+		status = read_rom(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;
+		}
 
-			dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n", __func__);
+		/* 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 = (fw_hdr->major_version << 8) +
+				   (fw_hdr->minor_version);
+
+		dev_dbg(dev, "%s - >> FW Versions Device %d.%d  Driver %d.%d\n",
+			__func__, firmware_version->Ver_Major,
+			firmware_version->Ver_Minor,
+			fw_hdr->major_version, fw_hdr->minor_version);
+
+		/* Check if we have an old version in the I2C and
+		 * 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__,
+				firmware_version->Ver_Major,
+				firmware_version->Ver_Minor,
+				fw_hdr->major_version,
+				fw_hdr->minor_version);
 
-			firmware_version = kmalloc(sizeof(*firmware_version),
-								GFP_KERNEL);
-			if (!firmware_version) {
+			record = kmalloc(1, GFP_KERNEL);
+			if (!record) {
+				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return -ENOMEM;
 			}
-
-			/* Validate version number
-			 * Read the descriptor data
+			/*
+			 * 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. 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 = read_rom(serial, start_address +
-					sizeof(struct ti_i2c_desc),
-					sizeof(struct ti_i2c_firmware_rec),
-					(__u8 *)firmware_version);
+			*record = I2C_DESC_TYPE_FIRMWARE_BLANK;
+
+			/* Change the I2C Firmware record type to
+			 * 0xf2 to trigger an update */
+			status = write_rom(serial, start_address,
+					sizeof(*record), record);
 			if (status) {
+				kfree(record);
 				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 = (fw_hdr->major_version << 8) +
-					   (fw_hdr->minor_version);
-
-			dev_dbg(dev, "%s - >> FW Versions Device %d.%d  Driver %d.%d\n",
-				__func__, firmware_version->Ver_Major,
-				firmware_version->Ver_Minor,
-				fw_hdr->major_version, fw_hdr->minor_version);
+			/* verify the write -- must do this in order
+			 * for write to complete before we do the
+			 * hardware reset
+			 */
+			status = read_rom(serial,
+						start_address,
+						sizeof(*record),
+						record);
+			if (status) {
+				kfree(record);
+				kfree(firmware_version);
+				kfree(rom_desc);
+				kfree(ti_manuf_desc);
+				return status;
+			}
 
-			/* Check if we have an old version in the I2C and
-			   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__,
-					firmware_version->Ver_Major,
-					firmware_version->Ver_Minor,
-					fw_hdr->major_version,
-					fw_hdr->minor_version);
-
-				record = kmalloc(1, GFP_KERNEL);
-				if (!record) {
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return -ENOMEM;
-				}
-				/* 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. 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 = write_rom(serial, start_address,
-						sizeof(*record), record);
-				if (status) {
-					kfree(record);
-					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 = read_rom(serial,
-							start_address,
-							sizeof(*record),
-							record);
-				if (status) {
-					kfree(record);
-					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", __func__);
-					kfree(record);
-					kfree(firmware_version);
-					kfree(rom_desc);
-					kfree(ti_manuf_desc);
-					return -ENODEV;
-				}
-
-				dev_dbg(dev, "%s - HARDWARE RESET\n", __func__);
-
-				/* Reset UMP -- Back to BOOT MODE */
-				status = ti_vsend_sync(serial->serial->dev,
-						UMPC_HARDWARE_RESET,
-						0, 0, NULL, 0,
-						TI_VSEND_TIMEOUT_DEFAULT);
-
-				dev_dbg(dev, "%s - HARDWARE RESET return %d\n", __func__, status);
-
-				/* return an error on purpose. */
+			if (*record != I2C_DESC_TYPE_FIRMWARE_BLANK) {
+				dev_err(dev, "%s - error resetting device\n",
+						__func__);
 				kfree(record);
 				kfree(firmware_version);
 				kfree(rom_desc);
 				kfree(ti_manuf_desc);
 				return -ENODEV;
-			} else {
-				/* Same or newer fw version is already loaded */
-				serial->fw_version = download_cur_ver;
 			}
+
+			dev_dbg(dev, "%s - HARDWARE RESET\n", __func__);
+
+			/* Reset UMP -- Back to BOOT MODE */
+			status = ti_vsend_sync(serial->serial->dev,
+					UMPC_HARDWARE_RESET,
+					0, 0, NULL, 0,
+					TI_VSEND_TIMEOUT_DEFAULT);
+
+			dev_dbg(dev, "%s - HARDWARE RESET return %d\n",
+					__func__, status);
+
+			/* return an error on purpose. */
+			kfree(record);
 			kfree(firmware_version);
+			kfree(rom_desc);
+			kfree(ti_manuf_desc);
+			return -ENODEV;
 		}
-		/* Search for type 0xF2 record (firmware blank record) */
-		else if ((start_address = get_descriptor_addr(serial, I2C_DESC_TYPE_FIRMWARE_BLANK, rom_desc)) != 0) {
+		/* 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 {
+		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))
+				sizeof(struct ti_i2c_firmware_rec))
 			__u8 *header;
 			__u8 *vheader;
 
@@ -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,26 +1321,33 @@ 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",
-								__func__);
+					__func__);
 				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 */
-	/********************************************************************/
+	/* The device is running the download code */
+	kfree(rom_desc);
+	kfree(ti_manuf_desc);
+	return 0;
+}
+
+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 */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux