Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 35154
b: refs/heads/master
c: d066c21
h: refs/heads/master
v: v3
  • Loading branch information
Daniel Drake authored and John W. Linville committed Aug 14, 2006
1 parent d5ff3d3 commit 135082c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 12f393089775ca33c53541eb67112fc04d799131
refs/heads/master: d066c2190de86d75e17dc35beba48b920cb125ee
1 change: 1 addition & 0 deletions trunk/drivers/net/wireless/zd1211rw/zd_chip.h
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ enum {
LOAD_CODE_SIZE = 0xe, /* words */
LOAD_VECT_SIZE = 0x10000 - 0xfff7, /* words */
EEPROM_REGS_OFFSET = LOAD_CODE_SIZE + LOAD_VECT_SIZE,
EEPROM_REGS_SIZE = 0x7e, /* words */
E2P_BASE_OFFSET = EEPROM_START_OFFSET +
EEPROM_REGS_OFFSET,
};
Expand Down
50 changes: 43 additions & 7 deletions trunk/drivers/net/wireless/zd1211rw/zd_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/

#include <asm/unaligned.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/firmware.h>
Expand Down Expand Up @@ -267,6 +268,39 @@ static char *get_fw_name(char *buffer, size_t size, u8 device_type,
return buffer;
}

static int handle_version_mismatch(struct usb_device *udev, u8 device_type,
const struct firmware *ub_fw)
{
const struct firmware *ur_fw = NULL;
int offset;
int r = 0;
char fw_name[128];

r = request_fw_file(&ur_fw,
get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"),
&udev->dev);
if (r)
goto error;

r = upload_code(udev, ur_fw->data, ur_fw->size, FW_START_OFFSET,
REBOOT);
if (r)
goto error;

offset = ((EEPROM_REGS_OFFSET + EEPROM_REGS_SIZE) * sizeof(u16));
r = upload_code(udev, ub_fw->data + offset, ub_fw->size - offset,
E2P_BASE_OFFSET + EEPROM_REGS_SIZE, REBOOT);

/* At this point, the vendor driver downloads the whole firmware
* image, hacks around with version IDs, and uploads it again,
* completely overwriting the boot code. We do not do this here as
* it is not required on any tested devices, and it is suspected to
* cause problems. */
error:
release_firmware(ur_fw);
return r;
}

static int upload_firmware(struct usb_device *udev, u8 device_type)
{
int r;
Expand All @@ -286,15 +320,17 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)

fw_bcdDevice = get_word(ub_fw->data, EEPROM_REGS_OFFSET);

/* FIXME: do we have any reason to perform the kludge that the vendor
* driver does when there is a version mismatch? (their driver uploads
* different firmwares and stuff)
*/
if (fw_bcdDevice != bcdDevice) {
dev_info(&udev->dev,
"firmware device id %#06x and actual device id "
"%#06x differ, continuing anyway\n",
fw_bcdDevice, bcdDevice);
"firmware version %#06x and device bootcode version "
"%#06x differ\n", fw_bcdDevice, bcdDevice);
if (bcdDevice <= 0x4313)
dev_warn(&udev->dev, "device has old bootcode, please "
"report success or failure\n");

r = handle_version_mismatch(udev, device_type, ub_fw);
if (r)
goto error;
} else {
dev_dbg_f(&udev->dev,
"firmware device id %#06x is equal to the "
Expand Down

0 comments on commit 135082c

Please sign in to comment.