int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) { const struct firmware *fw_entry = NULL; printk(KERN_INFO "prism2_usb: Checking for firmware %s\n", PRISM2_USB_FWFILE); if (request_ihex_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) { printk(KERN_INFO "prism2_usb: Firmware not available, but not essential\n"); printk(KERN_INFO "prism2_usb: can continue to use card anyway.\n"); return 1; } printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n", PRISM2_USB_FWFILE, fw_entry->size); prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); release_firmware(fw_entry); return 0; }
/*---------------------------------------------------------------- * prism2_fwtry * * Try and get firmware into memory * * Arguments: * udev usb device structure * wlandev wlan device structure * * Returns: * 0 - success * ~0 - failure ----------------------------------------------------------------*/ int prism2_fwtry(struct usb_device *udev, wlandevice_t *wlandev) { const struct firmware *fw_entry = NULL; // printk(KERN_INFO "prism2_usb: Checking for firmware %s\n", ; if (request_ihex_firmware(&fw_entry, PRISM2_USB_FWFILE, &udev->dev) != 0) { // printk(KERN_INFO ; // printk(KERN_INFO ; return 1; } // printk(KERN_INFO "prism2_usb: %s will be processed, size %zu\n", ; prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); release_firmware(fw_entry); return 0; }
static int emi26_load_firmware (struct usb_device *dev) { const struct firmware *loader_fw = NULL; const struct firmware *bitstream_fw = NULL; const struct firmware *firmware_fw = NULL; const struct ihex_binrec *rec; int err; int i; __u32 addr; __u8 *buf; buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); if (!buf) { dev_err(&dev->dev, "%s - error loading firmware: error = %d\n", __func__, -ENOMEM); err = -ENOMEM; goto wraperr; } err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); if (err) goto nofw; err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", &dev->dev); if (err) goto nofw; err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", &dev->dev); if (err) { nofw: dev_err(&dev->dev, "%s - request_firmware() failed\n", __func__); goto wraperr; } err = emi26_set_reset(dev,1); if (err < 0) { dev_err(&dev->dev,"%s - error loading firmware: error = %d\n", __func__, err); goto wraperr; } rec = (const struct ihex_binrec *)loader_fw->data; while (rec) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } rec = ihex_next_binrec(rec); } err = emi26_set_reset(dev,0); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); rec = (const struct ihex_binrec *)bitstream_fw->data; do { i = 0; addr = be32_to_cpu(rec->addr); while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); i += be16_to_cpu(rec->len); rec = ihex_next_binrec(rec); } err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } while (rec); err = emi26_set_reset(dev,1); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } for (rec = (const struct ihex_binrec *)loader_fw->data; rec; rec = ihex_next_binrec(rec)) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } msleep(250); err = emi26_set_reset(dev,0); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } for (rec = (const struct ihex_binrec *)firmware_fw->data; rec; rec = ihex_next_binrec(rec)) { if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_EXTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } } err = emi26_set_reset(dev,1); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } for (rec = (const struct ihex_binrec *)firmware_fw->data; rec; rec = ihex_next_binrec(rec)) { if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } } } err = emi26_set_reset(dev,0); if (err < 0) { err("%s - error loading firmware: error = %d", __func__, err); goto wraperr; } msleep(250); err = 1; wraperr: release_firmware(loader_fw); release_firmware(bitstream_fw); release_firmware(firmware_fw); kfree(buf); return err; }
int mga_warp_install_microcode(drm_mga_private_t *dev_priv) { unsigned char *vcbase = dev_priv->warp->handle; unsigned long pcbase = dev_priv->warp->offset; const char *firmware_name; struct platform_device *pdev; const struct firmware *fw = NULL; const struct ihex_binrec *rec; unsigned int size; int n_pipes, where; int rc = 0; switch (dev_priv->chipset) { case MGA_CARD_TYPE_G400: case MGA_CARD_TYPE_G550: firmware_name = FIRMWARE_G400; n_pipes = MGA_MAX_G400_PIPES; break; case MGA_CARD_TYPE_G200: firmware_name = FIRMWARE_G200; n_pipes = MGA_MAX_G200_PIPES; break; default: return -EINVAL; } pdev = platform_device_register_simple("mga_warp", 0, NULL, 0); if (IS_ERR(pdev)) { DRM_ERROR("mga: Failed to register microcode\n"); return PTR_ERR(pdev); } rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); platform_device_unregister(pdev); if (rc) { DRM_ERROR("mga: Failed to load microcode \"%s\"\n", firmware_name); return rc; } size = 0; where = 0; for (rec = (const struct ihex_binrec *)fw->data; rec; rec = ihex_next_binrec(rec)) { size += WARP_UCODE_SIZE(be16_to_cpu(rec->len)); where++; } if (where != n_pipes) { DRM_ERROR("mga: Invalid microcode \"%s\"\n", firmware_name); rc = -EINVAL; goto out; } size = PAGE_ALIGN(size); DRM_DEBUG("MGA ucode size = %d bytes\n", size); if (size > dev_priv->warp->size) { DRM_ERROR("microcode too large! (%u > %lu)\n", size, dev_priv->warp->size); rc = -ENOMEM; goto out; } memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys)); where = 0; for (rec = (const struct ihex_binrec *)fw->data; rec; rec = ihex_next_binrec(rec)) { unsigned int src_size, dst_size; DRM_DEBUG(" pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase); dev_priv->warp_pipe_phys[where] = pcbase; src_size = be16_to_cpu(rec->len); dst_size = WARP_UCODE_SIZE(src_size); memcpy(vcbase, rec->data, src_size); pcbase += dst_size; vcbase += dst_size; where++; } out: release_firmware(fw); return rc; }
/* steps to download the firmware to the WhiteHEAT device: - hold the reset (by writing to the reset bit of the CPUCS register) - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD - release the reset (by writing to the CPUCS register) - download the WH.HEX file for all addresses greater than 0x1b3f using VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD - hold the reset - download the WH.HEX file for all addresses less than 0x1b40 using VENDOR_REQUEST_ANCHOR_LOAD - release the reset - device renumerated itself and comes up as new device id with all firmware download completed. */ static int whiteheat_firmware_download(struct usb_serial *serial, const struct usb_device_id *id) { int response, ret = -ENOENT; const struct firmware *loader_fw = NULL, *firmware_fw = NULL; const struct ihex_binrec *record; if (request_ihex_firmware(&firmware_fw, "whiteheat.fw", &serial->dev->dev)) { dev_err(&serial->dev->dev, "%s - request \"whiteheat.fw\" failed\n", __func__); goto out; } if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw", &serial->dev->dev)) { dev_err(&serial->dev->dev, "%s - request \"whiteheat_loader.fw\" failed\n", __func__); goto out; } ret = 0; response = ezusb_set_reset (serial, 1); record = (const struct ihex_binrec *)loader_fw->data; while (record) { response = ezusb_writememory (serial, be32_to_cpu(record->addr), (unsigned char *)record->data, be16_to_cpu(record->len), 0xa0); if (response < 0) { dev_err(&serial->dev->dev, "%s - ezusb_writememory " "failed for loader (%d %04X %p %d)\n", __func__, response, be32_to_cpu(record->addr), record->data, be16_to_cpu(record->len)); break; } record = ihex_next_binrec(record); } response = ezusb_set_reset(serial, 0); record = (const struct ihex_binrec *)firmware_fw->data; while (record && be32_to_cpu(record->addr) < 0x1b40) record = ihex_next_binrec(record); while (record) { response = ezusb_writememory (serial, be32_to_cpu(record->addr), (unsigned char *)record->data, be16_to_cpu(record->len), 0xa3); if (response < 0) { dev_err(&serial->dev->dev, "%s - ezusb_writememory " "failed for first firmware step " "(%d %04X %p %d)\n", __func__, response, be32_to_cpu(record->addr), record->data, be16_to_cpu(record->len)); break; } ++record; } response = ezusb_set_reset(serial, 1); record = (const struct ihex_binrec *)firmware_fw->data; while (record && be32_to_cpu(record->addr) < 0x1b40) { response = ezusb_writememory (serial, be32_to_cpu(record->addr), (unsigned char *)record->data, be16_to_cpu(record->len), 0xa0); if (response < 0) { dev_err(&serial->dev->dev, "%s - ezusb_writememory " "failed for second firmware step " "(%d %04X %p %d)\n", __func__, response, be32_to_cpu(record->addr), record->data, be16_to_cpu(record->len)); break; } ++record; } ret = 0; response = ezusb_set_reset (serial, 0); out: release_firmware(loader_fw); release_firmware(firmware_fw); return ret; }
static int emi26_load_firmware (struct usb_device *dev) { const struct firmware *loader_fw = NULL; const struct firmware *bitstream_fw = NULL; const struct firmware *firmware_fw = NULL; const struct ihex_binrec *rec; int err = -ENOMEM; int i; __u32 addr; /* Address to write */ __u8 *buf; buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL); if (!buf) goto wraperr; err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); if (err) goto nofw; err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", &dev->dev); if (err) goto nofw; err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", &dev->dev); if (err) { nofw: dev_err(&dev->dev, "%s - request_firmware() failed\n", __func__); goto wraperr; } /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) goto wraperr; rec = (const struct ihex_binrec *)loader_fw->data; /* 1. We need to put the loader for the FPGA into the EZ-USB */ while (rec) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) goto wraperr; rec = ihex_next_binrec(rec); } /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) goto wraperr; msleep(250); /* let device settle */ /* 2. We upload the FPGA firmware into the EMI * Note: collect up to 1023 (yes!) bytes and send them with * a single request. This is _much_ faster! */ rec = (const struct ihex_binrec *)bitstream_fw->data; do { i = 0; addr = be32_to_cpu(rec->addr); /* intel hex records are terminated with type 0 element */ while (rec && (i + be16_to_cpu(rec->len) < FW_LOAD_SIZE)) { memcpy(buf + i, rec->data, be16_to_cpu(rec->len)); i += be16_to_cpu(rec->len); rec = ihex_next_binrec(rec); } err = emi26_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA); if (err < 0) goto wraperr; } while (rec); /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) goto wraperr; /* 3. We need to put the loader for the firmware into the EZ-USB (again...) */ for (rec = (const struct ihex_binrec *)loader_fw->data; rec; rec = ihex_next_binrec(rec)) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) goto wraperr; } msleep(250); /* let device settle */ /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) goto wraperr; /* 4. We put the part of the firmware that lies in the external RAM into the EZ-USB */ for (rec = (const struct ihex_binrec *)firmware_fw->data; rec; rec = ihex_next_binrec(rec)) { if (!INTERNAL_RAM(be32_to_cpu(rec->addr))) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_EXTERNAL); if (err < 0) goto wraperr; } } /* Assert reset (stop the CPU in the EMI) */ err = emi26_set_reset(dev,1); if (err < 0) goto wraperr; for (rec = (const struct ihex_binrec *)firmware_fw->data; rec; rec = ihex_next_binrec(rec)) { if (INTERNAL_RAM(be32_to_cpu(rec->addr))) { err = emi26_writememory(dev, be32_to_cpu(rec->addr), rec->data, be16_to_cpu(rec->len), ANCHOR_LOAD_INTERNAL); if (err < 0) goto wraperr; } } /* De-assert reset (let the CPU run) */ err = emi26_set_reset(dev,0); if (err < 0) goto wraperr; msleep(250); /* let device settle */ /* return 1 to fail the driver inialization * and give real driver change to load */ err = 1; wraperr: if (err < 0) dev_err(&dev->dev,"%s - error loading firmware: error = %d\n", __func__, err); release_firmware(loader_fw); release_firmware(bitstream_fw); release_firmware(firmware_fw); kfree(buf); return err; }