Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio: allow caller to override device id in vp_modern

To add a bit of vendor flexibility with various virtio based devices,
allow the caller to check for a different device id. This adds a function
pointer field to struct virtio_pci_modern_device to specify an override
device id check. If defined by the driver, this function will be called
to check that the PCI device is the vendor's expected device, and will
return the found device id to be stored in mdev->id.device. This allows
vendors with alternative vendor device ids to use this library on their
own device BAR.

Note: A lot of the diff in this is simply indenting the existing code
into an else block.

Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Message-Id: <20230519215632.12343-2-shannon.nelson@amd.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Shannon Nelson and committed by
Michael S. Tsirkin
a37c0191 4f0fc225

+22 -11
+19 -11
drivers/virtio/virtio_pci_modern_dev.c
··· 218 218 int err, common, isr, notify, device; 219 219 u32 notify_length; 220 220 u32 notify_offset; 221 + int devid; 221 222 222 223 check_offsets(); 223 224 224 - /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */ 225 - if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f) 226 - return -ENODEV; 227 - 228 - if (pci_dev->device < 0x1040) { 229 - /* Transitional devices: use the PCI subsystem device id as 230 - * virtio device id, same as legacy driver always did. 231 - */ 232 - mdev->id.device = pci_dev->subsystem_device; 225 + if (mdev->device_id_check) { 226 + devid = mdev->device_id_check(pci_dev); 227 + if (devid < 0) 228 + return devid; 229 + mdev->id.device = devid; 233 230 } else { 234 - /* Modern devices: simply use PCI device id, but start from 0x1040. */ 235 - mdev->id.device = pci_dev->device - 0x1040; 231 + /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */ 232 + if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f) 233 + return -ENODEV; 234 + 235 + if (pci_dev->device < 0x1040) { 236 + /* Transitional devices: use the PCI subsystem device id as 237 + * virtio device id, same as legacy driver always did. 238 + */ 239 + mdev->id.device = pci_dev->subsystem_device; 240 + } else { 241 + /* Modern devices: simply use PCI device id, but start from 0x1040. */ 242 + mdev->id.device = pci_dev->device - 0x1040; 243 + } 236 244 } 237 245 mdev->id.vendor = pci_dev->subsystem_vendor; 238 246
+3
include/linux/virtio_pci_modern.h
··· 38 38 int modern_bars; 39 39 40 40 struct virtio_device_id id; 41 + 42 + /* optional check for vendor virtio device, returns dev_id or -ERRNO */ 43 + int (*device_id_check)(struct pci_dev *pdev); 41 44 }; 42 45 43 46 /*