drivers/usb/misc/emi62.c

Source file repositories/reference/linux-study-clean/drivers/usb/misc/emi62.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/misc/emi62.c
Extension
.c
Size
7857 bytes
Lines
273
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

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 = emi62_writememory(dev, addr, buf, i, ANCHOR_LOAD_FPGA);
		if (err < 0)
			goto wraperr;
	} while (rec);

	/* Assert reset (stop the CPU in the EMI) */
	err = emi62_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 = emi62_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 = emi62_set_reset(dev,0);
	if (err < 0)
		goto wraperr;
	msleep(250);	/* let device settle */

	/* 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 = emi62_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 = emi62_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 = emi62_writememory(dev, be32_to_cpu(rec->addr),
						rec->data, be16_to_cpu(rec->len),
						ANCHOR_LOAD_EXTERNAL);
			if (err < 0)
				goto wraperr;
		}
	}

	/* De-assert reset (let the CPU run) */
	err = emi62_set_reset(dev,0);
	if (err < 0)
		goto wraperr;
	msleep(250);	/* let device settle */

	release_firmware(loader_fw);
	release_firmware(bitstream_fw);
	release_firmware(firmware_fw);

	kfree(buf);

	/* return 1 to fail the driver inialization
	 * and give real driver change to load */
	return 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);
	dev_err(&dev->dev, "Error\n");
	return err;
}

static const struct usb_device_id id_table[] = {

Annotation

Implementation Notes