On Tue, Nov 12, 2019 at 10:28:26PM +0100, Greg KH wrote: > > + */ > > +struct virtbus_device { > > + const char *name; > > + int id; > > + const struct virtbus_dev_id *dev_id; > > + struct device dev; > > + void *data; > > +}; > > + > > +struct virtbus_driver { > > + int (*probe)(struct virtbus_device *); > > + int (*remove)(struct virtbus_device *); > > + void (*shutdown)(struct virtbus_device *); > > + int (*suspend)(struct virtbus_device *, pm_message_t state); > > + int (*resume)(struct virtbus_device *); > > + struct device_driver driver; > > + const struct virtbus_dev_id *id_table; > > +}; > > + > > +#define virtbus_get_dev_id(vdev) ((vdev)->id_entry) > > +#define virtbus_get_devdata(dev) ((dev)->devdata) > > What are these for? As far as I can see, the scheme here, using the language from the most recent discussion is: // in core or netdev module int mlx5_core_create() { struct mlx5_core_dev *core = kzalloc(..) [..] core->vdev = virtbus_dev_alloc("mlx5_core", core); } // in rdma module static int mlx5_rdma_probe(struct virtbus_device *dev) { // Get the value passed to virtbus_dev_alloc() struct mlx5_core_dev *core = virtbus_get_devdata(dev) // Use the huge API surrounding struct mlx5_core_dev qp = mlx5_core_create_qp(core, ...); } static struct virtbus_driver mlx5_rdma_driver = { .probe = mlx5_rdma_probe, .match = {"mlx5_core"} } Drivers that match "mlx5_core" know that the opaque 'virtbus_get_devdata()' is a 'struct mlx5_core_dev *' and use that access the core driver. A "ice_core" would know it is some 'struct ice_core_dev *' for Intel and uses that pointer, etc. ie it is just a way to a pass a 'void *' from one module to another while using the driver core to manage module autoloading and binding. Jason