struct ihex_record {
u16 address;
u8 len;
u8 data[256]; char error; /* true if an error occurred parsing this record */
u8 max_len; /* maximum record length in whole ihex */
/* private */ constchar *txt_data; unsignedint txt_length; unsignedint txt_offset; /* current position in txt_data */
};
static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc)
{
u8 val = 0; int hval;
hval = hex_to_bin(data[0]); if (hval >= 0)
val |= (hval << 4);
hval = hex_to_bin(data[1]); if (hval >= 0)
val |= hval;
*crc += val; return val;
}
/* * returns true if record is available, false otherwise. * iff an error occurred, false will be returned and record->error will be true.
*/ staticbool usb6fire_fw_ihex_next_record(struct ihex_record *record)
{
u8 crc = 0;
u8 type; int i;
record->error = false;
/* find begin of record (marked by a colon) */ while (record->txt_offset < record->txt_length
&& record->txt_data[record->txt_offset] != ':')
record->txt_offset++; if (record->txt_offset == record->txt_length) returnfalse;
/* number of characters needed for len, addr and type entries */
record->txt_offset++; if (record->txt_offset + 8 > record->txt_length) {
record->error = true; returnfalse;
}
ret = request_firmware(&fw, fwname, &device->dev); if (ret < 0) {
kfree(rec);
dev_err(&intf->dev, "error requesting ezusb firmware %s.\n", fwname); return ret;
}
ret = usb6fire_fw_ihex_init(fw, rec); if (ret < 0) {
kfree(rec);
release_firmware(fw);
dev_err(&intf->dev, "error validating ezusb firmware %s.\n", fwname); return ret;
} /* upload firmware image */
data = 0x01; /* stop ezusb cpu */
ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1); if (ret) {
kfree(rec);
release_firmware(fw);
dev_err(&intf->dev, "unable to upload ezusb firmware %s: begin message.\n",
fwname); return ret;
}
while (usb6fire_fw_ihex_next_record(rec)) { /* write firmware */
ret = usb6fire_fw_ezusb_write(device, 0xa0, rec->address,
rec->data, rec->len); if (ret) {
kfree(rec);
release_firmware(fw);
dev_err(&intf->dev, "unable to upload ezusb firmware %s: data urb.\n",
fwname); return ret;
}
}
release_firmware(fw);
kfree(rec); if (postdata) { /* write data after firmware has been uploaded */
ret = usb6fire_fw_ezusb_write(device, 0xa0, postaddr,
postdata, postlen); if (ret) {
dev_err(&intf->dev, "unable to upload ezusb firmware %s: post urb.\n",
fwname); return ret;
}
}
data = 0x00; /* resume ezusb cpu */
ret = usb6fire_fw_ezusb_write(device, 0xa0, 0xe600, &data, 1); if (ret) {
dev_err(&intf->dev, "unable to upload ezusb firmware %s: end message.\n",
fwname); return ret;
} return 0;
}
ret = request_firmware(&fw, fwname, &device->dev); if (ret < 0) {
dev_err(&intf->dev, "unable to get fpga firmware %s.\n",
fwname);
kfree(buffer); return -EIO;
}
c = fw->data;
end = fw->data + fw->size;
ret = usb6fire_fw_ezusb_write(device, 8, 0, NULL, 0); if (ret) {
kfree(buffer);
release_firmware(fw);
dev_err(&intf->dev, "unable to upload fpga firmware: begin urb.\n"); return ret;
}
while (c != end) { for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++)
buffer[i] = bitrev8((u8)*c);
ret = usb6fire_fw_fpga_write(device, buffer, i); if (ret < 0) {
release_firmware(fw);
kfree(buffer);
dev_err(&intf->dev, "unable to upload fpga firmware: fw urb.\n"); return ret;
}
}
release_firmware(fw);
kfree(buffer);
ret = usb6fire_fw_ezusb_write(device, 9, 0, NULL, 0); if (ret) {
dev_err(&intf->dev, "unable to upload fpga firmware: end urb.\n"); return ret;
} return 0;
}
/* check, if the firmware version the devices has currently loaded * is known by this driver. 'version' needs to have 4 bytes version
* info data. */ staticint usb6fire_fw_check(struct usb_interface *intf, const u8 *version)
{ int i;
for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++) if (!memcmp(version, known_fw_versions + i, 2)) return 0;
dev_err(&intf->dev, "invalid firmware version in device: %4ph. " "please reconnect to power. if this failure " "still happens, check your firmware installation.",
version); return -EINVAL;
}
int usb6fire_fw_init(struct usb_interface *intf)
{ int i; int ret; struct usb_device *device = interface_to_usbdev(intf); /* buffer: 8 receiving bytes from device and
* sizeof(EP_W_MAX_PACKET_SIZE) bytes for non-const copy */
u8 buffer[12];
ret = usb6fire_fw_ezusb_read(device, 1, 0, buffer, 8); if (ret) {
dev_err(&intf->dev, "unable to receive device firmware state.\n"); return ret;
} if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) {
dev_err(&intf->dev, "unknown device firmware state received from device:"); for (i = 0; i < 8; i++)
printk(KERN_CONT "%02x ", buffer[i]);
printk(KERN_CONT "\n"); return -EIO;
} /* do we need fpga loader ezusb firmware? */ if (buffer[3] == 0x01) {
ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6firel2.ihx", 0, NULL, 0); if (ret < 0) return ret; return FW_NOT_READY;
} /* do we need fpga firmware and application ezusb firmware? */ elseif (buffer[3] == 0x02) {
ret = usb6fire_fw_check(intf, buffer + 4); if (ret < 0) return ret;
ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); if (ret < 0) return ret;
memcpy(buffer, ep_w_max_packet_size, sizeof(ep_w_max_packet_size));
ret = usb6fire_fw_ezusb_upload(intf, "6fire/dmx6fireap.ihx",
0x0003, buffer, sizeof(ep_w_max_packet_size)); if (ret < 0) return ret; return FW_NOT_READY;
} /* all fw loaded? */ elseif (buffer[3] == 0x03) return usb6fire_fw_check(intf, buffer + 4); /* unknown data? */ else {
dev_err(&intf->dev, "unknown device firmware state received from device: "); for (i = 0; i < 8; i++)
printk(KERN_CONT "%02x ", buffer[i]);
printk(KERN_CONT "\n"); return -EIO;
} return 0;
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.26 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.