aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2014-04-25 09:23:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-04-25 12:34:10 -0400
commit5509076d1b4485ce9fb07705fcbcd2695907ab5b (patch)
tree8b60716a6f575040d3cc10d97d97fb891a9b9f18 /drivers/usb
parent01bb59ebffdec314da8da66266edf29529372f9b (diff)
USB: io_ti: fix firmware download on big-endian machines
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> Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
-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 a2db5be9c305..df90dae53eb9 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -28,6 +28,7 @@
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/serial.h> 30#include <linux/serial.h>
31#include <linux/swab.h>
31#include <linux/kfifo.h> 32#include <linux/kfifo.h>
32#include <linux/ioctl.h> 33#include <linux/ioctl.h>
33#include <linux/firmware.h> 34#include <linux/firmware.h>
@@ -280,7 +281,7 @@ static int read_download_mem(struct usb_device *dev, int start_address,
280{ 281{
281 int status = 0; 282 int status = 0;
282 __u8 read_length; 283 __u8 read_length;
283 __be16 be_start_address; 284 u16 be_start_address;
284 285
285 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length); 286 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length);
286 287
@@ -296,10 +297,14 @@ static int read_download_mem(struct usb_device *dev, int start_address,
296 if (read_length > 1) { 297 if (read_length > 1) {
297 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length); 298 dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length);
298 } 299 }
299 be_start_address = cpu_to_be16(start_address); 300 /*
301 * NOTE: Must use swab as wIndex is sent in little-endian
302 * byte order regardless of host byte order.
303 */
304 be_start_address = swab16((u16)start_address);
300 status = ti_vread_sync(dev, UMPC_MEMORY_READ, 305 status = ti_vread_sync(dev, UMPC_MEMORY_READ,
301 (__u16)address_type, 306 (__u16)address_type,
302 (__force __u16)be_start_address, 307 be_start_address,
303 buffer, read_length); 308 buffer, read_length);
304 309
305 if (status) { 310 if (status) {
@@ -394,7 +399,7 @@ static int write_i2c_mem(struct edgeport_serial *serial,
394 struct device *dev = &serial->serial->dev->dev; 399 struct device *dev = &serial->serial->dev->dev;
395 int status = 0; 400 int status = 0;
396 int write_length; 401 int write_length;
397 __be16 be_start_address; 402 u16 be_start_address;
398 403
399 /* We can only send a maximum of 1 aligned byte page at a time */ 404 /* We can only send a maximum of 1 aligned byte page at a time */
400 405
@@ -409,11 +414,16 @@ static int write_i2c_mem(struct edgeport_serial *serial,
409 __func__, start_address, write_length); 414 __func__, start_address, write_length);
410 usb_serial_debug_data(dev, __func__, write_length, buffer); 415 usb_serial_debug_data(dev, __func__, write_length, buffer);
411 416
412 /* Write first page */ 417 /*
413 be_start_address = cpu_to_be16(start_address); 418 * Write first page.
419 *
420 * NOTE: Must use swab as wIndex is sent in little-endian byte order
421 * regardless of host byte order.
422 */
423 be_start_address = swab16((u16)start_address);
414 status = ti_vsend_sync(serial->serial->dev, 424 status = ti_vsend_sync(serial->serial->dev,
415 UMPC_MEMORY_WRITE, (__u16)address_type, 425 UMPC_MEMORY_WRITE, (__u16)address_type,
416 (__force __u16)be_start_address, 426 be_start_address,
417 buffer, write_length); 427 buffer, write_length);
418 if (status) { 428 if (status) {
419 dev_dbg(dev, "%s - ERROR %d\n", __func__, status); 429 dev_dbg(dev, "%s - ERROR %d\n", __func__, status);
@@ -436,11 +446,16 @@ static int write_i2c_mem(struct edgeport_serial *serial,
436 __func__, start_address, write_length); 446 __func__, start_address, write_length);
437 usb_serial_debug_data(dev, __func__, write_length, buffer); 447 usb_serial_debug_data(dev, __func__, write_length, buffer);
438 448
439 /* Write next page */ 449 /*
440 be_start_address = cpu_to_be16(start_address); 450 * Write next page.
451 *
452 * NOTE: Must use swab as wIndex is sent in little-endian byte
453 * order regardless of host byte order.
454 */
455 be_start_address = swab16((u16)start_address);
441 status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE, 456 status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE,
442 (__u16)address_type, 457 (__u16)address_type,
443 (__force __u16)be_start_address, 458 be_start_address,
444 buffer, write_length); 459 buffer, write_length);
445 if (status) { 460 if (status) {
446 dev_err(dev, "%s - ERROR %d\n", __func__, status); 461 dev_err(dev, "%s - ERROR %d\n", __func__, status);
@@ -585,8 +600,8 @@ static int get_descriptor_addr(struct edgeport_serial *serial,
585 if (rom_desc->Type == desc_type) 600 if (rom_desc->Type == desc_type)
586 return start_address; 601 return start_address;
587 602
588 start_address = start_address + sizeof(struct ti_i2c_desc) 603 start_address = start_address + sizeof(struct ti_i2c_desc) +
589 + rom_desc->Size; 604 le16_to_cpu(rom_desc->Size);
590 605
591 } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type); 606 } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type);
592 607
@@ -599,7 +614,7 @@ static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer)
599 __u16 i; 614 __u16 i;
600 __u8 cs = 0; 615 __u8 cs = 0;
601 616
602 for (i = 0; i < rom_desc->Size; i++) 617 for (i = 0; i < le16_to_cpu(rom_desc->Size); i++)
603 cs = (__u8)(cs + buffer[i]); 618 cs = (__u8)(cs + buffer[i]);
604 619
605 if (cs != rom_desc->CheckSum) { 620 if (cs != rom_desc->CheckSum) {
@@ -650,7 +665,7 @@ static int check_i2c_image(struct edgeport_serial *serial)
650 break; 665 break;
651 666
652 if ((start_address + sizeof(struct ti_i2c_desc) + 667 if ((start_address + sizeof(struct ti_i2c_desc) +
653 rom_desc->Size) > TI_MAX_I2C_SIZE) { 668 le16_to_cpu(rom_desc->Size)) > TI_MAX_I2C_SIZE) {
654 status = -ENODEV; 669 status = -ENODEV;
655 dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__); 670 dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__);
656 break; 671 break;
@@ -665,7 +680,8 @@ static int check_i2c_image(struct edgeport_serial *serial)
665 /* Read the descriptor data */ 680 /* Read the descriptor data */
666 status = read_rom(serial, start_address + 681 status = read_rom(serial, start_address +
667 sizeof(struct ti_i2c_desc), 682 sizeof(struct ti_i2c_desc),
668 rom_desc->Size, buffer); 683 le16_to_cpu(rom_desc->Size),
684 buffer);
669 if (status) 685 if (status)
670 break; 686 break;
671 687
@@ -674,7 +690,7 @@ static int check_i2c_image(struct edgeport_serial *serial)
674 break; 690 break;
675 } 691 }
676 start_address = start_address + sizeof(struct ti_i2c_desc) + 692 start_address = start_address + sizeof(struct ti_i2c_desc) +
677 rom_desc->Size; 693 le16_to_cpu(rom_desc->Size);
678 694
679 } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && 695 } while ((rom_desc->Type != I2C_DESC_TYPE_ION) &&
680 (start_address < TI_MAX_I2C_SIZE)); 696 (start_address < TI_MAX_I2C_SIZE));
@@ -712,7 +728,7 @@ static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer)
712 728
713 /* Read the descriptor data */ 729 /* Read the descriptor data */
714 status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc), 730 status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc),
715 rom_desc->Size, buffer); 731 le16_to_cpu(rom_desc->Size), buffer);
716 if (status) 732 if (status)
717 goto exit; 733 goto exit;
718 734