struct gb_firmware {
struct gb_connection *connection;
const struct firmware *fw;
- u32 vendor_id;
- u32 product_id;
};
static void free_firmware(struct gb_firmware *firmware)
* This fetches VID/PID (over firmware protocol) for es2 chip only, when VID/PID
* already sent during hotplug are 0.
*
- * Otherwise, we keep firmware->vendor_id/product_id same as what's passed
+ * Otherwise, we keep intf->vendor_id/product_id same as what's passed
* during hotplug.
*/
static void firmware_es2_fixup_vid_pid(struct gb_firmware *firmware)
return;
}
- firmware->vendor_id = le32_to_cpu(response.vendor_id);
- firmware->product_id = le32_to_cpu(response.product_id);
+ /*
+ * NOTE: This is hacked, so that the same values of VID/PID can be used
+ * by next firmware level as well. The uevent for bootrom will still
+ * have VID/PID as 0, though after this point the sysfs files will start
+ * showing the updated values. But yeah, that's a bit racy as the same
+ * sysfs files would be showing 0 before this point.
+ */
+ intf->vendor_id = le32_to_cpu(response.vendor_id);
+ intf->product_id = le32_to_cpu(response.product_id);
dev_dbg(&connection->bundle->dev, "Firmware got vid (0x%x)/pid (0x%x)\n",
- firmware->vendor_id, firmware->product_id);
+ intf->vendor_id, intf->product_id);
}
/* This returns path of the firmware blob on the disk */
snprintf(firmware_name, sizeof(firmware_name),
"ara_%08x_%08x_%08x_%08x_%02x.tftf",
intf->ddbl1_manufacturer_id, intf->ddbl1_product_id,
- firmware->vendor_id, firmware->product_id, stage);
+ intf->vendor_id, intf->product_id, stage);
// FIXME:
// Turn to dev_dbg later after everyone has valid bootloaders with good
firmware->connection = connection;
connection->private = firmware;
- firmware->vendor_id = connection->intf->vendor_id;
- firmware->product_id = connection->intf->product_id;
-
firmware_es2_fixup_vid_pid(firmware);
/* Tell bootrom we're ready. */
struct gb_host_device *hd = connection->hd;
struct gb_interface *intf;
u8 intf_id, device_id;
+ u32 vendor_id = 0;
+ u32 product_id = 0;
int ret;
/* The request message size has already been verified. */
intf = gb_interface_find(hd, intf_id);
if (intf) {
+ /*
+ * For ES2, we need to maintain the same vendor/product ids we
+ * got from bootrom, otherwise userspace can't distinguish
+ * between modules.
+ */
+ vendor_id = intf->vendor_id;
+ product_id = intf->product_id;
+
/*
* We have received a hotplug request for an interface that
* already exists.
intf->product_id = le32_to_cpu(request->data.ara_prod_id);
intf->serial_number = le64_to_cpu(request->data.serial_number);
+ /*
+ * Use VID/PID specified at hotplug if:
+ * - Bridge ASIC chip isn't ES2
+ * - Received non-zero Vendor/Product ids
+ *
+ * Otherwise, use the ids we received from bootrom.
+ */
+ if (intf->ddbl1_manufacturer_id == ES2_DDBL1_MFR_ID &&
+ intf->ddbl1_product_id == ES2_DDBL1_PROD_ID &&
+ intf->vendor_id == 0 && intf->product_id == 0) {
+ intf->vendor_id = vendor_id;
+ intf->product_id = product_id;
+ }
+
ret = gb_svc_read_and_clear_module_boot_status(intf);
if (ret) {
dev_err(&svc->dev, "failed to clear boot status of interface %u: %d\n",