aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2014-04-25 09:23:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-31 00:52:13 -0400
commit9e036f060793ddb0a9f3f70d4753877b85e894b4 (patch)
tree9518f3e87b63eae33e07c8bb624908d50218a726
parent2eb1a584d440a3aed1b4793f39d091c1fff3f6d7 (diff)
USB: io_ti: fix firmware download on big-endian machines
commit 5509076d1b4485ce9fb07705fcbcd2695907ab5b upstream. During firmware download the device expects memory addresses in big-endian byte order. As the wIndex parameter which hold the address is sent in little-endian byte order regardless of host byte order, we need to use swab16 rather than cpu_to_be16. Also make sure to handle the struct ti_i2c_desc size parameter which is returned in little-endian byte order. Reported-by: Ludovic Drolez <ldrolez@debian.org> Tested-by: Ludovic Drolez <ldrolez@debian.org> Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/serial/io_ti.c50
1 files changed, 33 insertions, 17 deletions
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 1be6ba7bee27..c5c9cbf107d1 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -29,6 +29,7 @@
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/mutex.h> 30#include <linux/mutex.h>
31#include <linux/serial.h> 31#include <linux/serial.h>
32#include <linux/swab.h>
32#include <linux/kfifo.h> 33#include <linux/kfifo.h>
33#include <linux/ioctl.h> 34#include <linux/ioctl.h>
34#include <linux/firmware.h> 35#include <linux/firmware.h>
@@ -284,7 +285,7 @@ static int read_download_mem(struct usb_device *dev, int start_address,
284{ 285{
285 int status = 0; 286 int status = 0;
286 __u8 read_length; 287 __u8 read_length;
287 __be16 be_start_address; 288 u16 be_start_address;
288 289
289 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length); 290 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length);
290 291
@@ -300,10 +301,14 @@ static int read_download_mem(struct usb_device *dev, int start_address,
300 if (read_length > 1) { 301 if (read_length > 1) {
301 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length); 302 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length);
302 } 303 }
303 be_start_address = cpu_to_be16(start_address); 304 /*
305 * NOTE: Must use swab as wIndex is sent in little-endian
306 * byte order regardless of host byte order.
307 */
308 be_start_address = swab16((u16)start_address);
304 status = ti_vread_sync(dev, UMPC_MEMORY_READ, 309 status = ti_vread_sync(dev, UMPC_MEMORY_READ,
305 (__u16)address_type, 310 (__u16)address_type,
306 (__force __u16)be_start_address, 311 be_start_address,
307 buffer, read_length); 312 buffer, read_length);
308 313
309 if (status) { 314 if (status) {
@@ -400,7 +405,7 @@ static int write_i2c_mem(struct edgeport_serial *serial,
400 struct device *dev = &serial->serial->dev->dev; 405 struct device *dev = &serial->serial->dev->dev;
401 int status = 0; 406 int status = 0;
402 int write_length; 407 int write_length;
403 __be16 be_start_address; 408 u16 be_start_address;
404 409
405 /* We can only send a maximum of 1 aligned byte page at a time */ 410 /* We can only send a maximum of 1 aligned byte page at a time */
406 411
@@ -415,11 +420,16 @@ static int write_i2c_mem(struct edgeport_serial *serial,
415 __func__, start_address, write_length); 420 __func__, start_address, write_length);
416 usb_serial_debug_data(dev, __func__, write_length, buffer); 421 usb_serial_debug_data(dev, __func__, write_length, buffer);
417 422
418 /* Write first page */ 423 /*
419 be_start_address = cpu_to_be16(start_address); 424 * Write first page.
425 *
426 * NOTE: Must use swab as wIndex is sent in little-endian byte order
427 * regardless of host byte order.
428 */
429 be_start_address = swab16((u16)start_address);
420 status = ti_vsend_sync(serial->serial->dev, 430 status = ti_vsend_sync(serial->serial->dev,
421 UMPC_MEMORY_WRITE, (__u16)address_type, 431 UMPC_MEMORY_WRITE, (__u16)address_type,
422 (__force __u16)be_start_address, 432 be_start_address,
423 buffer, write_length); 433 buffer, write_length);
424 if (status) { 434 if (status) {
425 dev_dbg(dev, "%s - ERROR %d\n", __func__, status); 435 dev_dbg(dev, "%s - ERROR %d\n", __func__, status);
@@ -442,11 +452,16 @@ static int write_i2c_mem(struct edgeport_serial *serial,
442 __func__, start_address, write_length); 452 __func__, start_address, write_length);
443 usb_serial_debug_data(dev, __func__, write_length, buffer); 453 usb_serial_debug_data(dev, __func__, write_length, buffer);
444 454
445 /* Write next page */ 455 /*
446 be_start_address = cpu_to_be16(start_address); 456 * Write next page.
457 *
458 * NOTE: Must use swab as wIndex is sent in little-endian byte
459 * order regardless of host byte order.
460 */
461 be_start_address = swab16((u16)start_address);
447 status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE, 462 status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
448 (__u16)address_type, 463 (__u16)address_type,
449 (__force __u16)be_start_address, 464 be_start_address,
450 buffer, write_length); 465 buffer, write_length);
451 if (status) { 466 if (status) {
452 dev_err(dev, "%s - ERROR %d\n", __func__, status); 467 dev_err(dev, "%s - ERROR %d\n", __func__, status);
@@ -593,8 +608,8 @@ static int get_descriptor_addr(struct edgeport_serial *serial,
593 if (rom_desc->Type == desc_type) 608 if (rom_desc->Type == desc_type)
594 return start_address; 609 return start_address;
595 610
596 start_address = start_address + sizeof(struct ti_i2c_desc) 611 start_address = start_address + sizeof(struct ti_i2c_desc) +
597 + rom_desc->Size; 612 le16_to_cpu(rom_desc->Size);
598 613
599 } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type); 614 } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);
600 615
@@ -607,7 +622,7 @@ static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer)
607 __u16 i; 622 __u16 i;
608 __u8 cs = 0; 623 __u8 cs = 0;
609 624
610 for (i = 0; i < rom_desc->Size; i++) 625 for (i = 0; i < le16_to_cpu(rom_desc->Size); i++)
611 cs = (__u8)(cs + buffer[i]); 626 cs = (__u8)(cs + buffer[i]);
612 627
613 if (cs != rom_desc->CheckSum) { 628 if (cs != rom_desc->CheckSum) {
@@ -661,7 +676,7 @@ static int check_i2c_image(struct edgeport_serial *serial)
661 break; 676 break;
662 677
663 if ((start_address + sizeof(struct ti_i2c_desc) + 678 if ((start_address + sizeof(struct ti_i2c_desc) +
664 rom_desc->Size) > TI_MAX_I2C_SIZE) { 679 le16_to_cpu(rom_desc->Size)) > TI_MAX_I2C_SIZE) {
665 status = -ENODEV; 680 status = -ENODEV;
666 dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__); 681 dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__);
667 break; 682 break;
@@ -676,7 +691,8 @@ static int check_i2c_image(struct edgeport_serial *serial)
676 /* Read the descriptor data */ 691 /* Read the descriptor data */
677 status = read_rom(serial, start_address + 692 status = read_rom(serial, start_address +
678 sizeof(struct ti_i2c_desc), 693 sizeof(struct ti_i2c_desc),
679 rom_desc->Size, buffer); 694 le16_to_cpu(rom_desc->Size),
695 buffer);
680 if (status) 696 if (status)
681 break; 697 break;
682 698
@@ -685,7 +701,7 @@ static int check_i2c_image(struct edgeport_serial *serial)
685 break; 701 break;
686 } 702 }
687 start_address = start_address + sizeof(struct ti_i2c_desc) + 703 start_address = start_address + sizeof(struct ti_i2c_desc) +
688 rom_desc->Size; 704 le16_to_cpu(rom_desc->Size);
689 705
690 } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && 706 } while ((rom_desc->Type != I2C_DESC_TYPE_ION) &&
691 (start_address < TI_MAX_I2C_SIZE)); 707 (start_address < TI_MAX_I2C_SIZE));
@@ -724,7 +740,7 @@ static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer)
724 740
725 /* Read the descriptor data */ 741 /* Read the descriptor data */
726 status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc), 742 status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
727 rom_desc->Size, buffer); 743 le16_to_cpu(rom_desc->Size), buffer);
728 if (status) 744 if (status)
729 goto exit; 745 goto exit;
730 746