mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
pds_vdpa: subscribe to the pds_core events
Register for the pds_core's notification events, primarily to find out when the FW has been reset so we can pass this on back up the chain. Signed-off-by: Shannon Nelson <shannon.nelson@amd.com> Acked-by: Jason Wang <jasowang@redhat.com> Message-Id: <20230519215632.12343-11-shannon.nelson@amd.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
151cc834f3
commit
67f27b8b3a
@@ -23,6 +23,52 @@ static struct pds_vdpa_device *vdpa_to_pdsv(struct vdpa_device *vdpa_dev)
|
|||||||
return container_of(vdpa_dev, struct pds_vdpa_device, vdpa_dev);
|
return container_of(vdpa_dev, struct pds_vdpa_device, vdpa_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int pds_vdpa_notify_handler(struct notifier_block *nb,
|
||||||
|
unsigned long ecode,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct pds_vdpa_device *pdsv = container_of(nb, struct pds_vdpa_device, nb);
|
||||||
|
struct device *dev = &pdsv->vdpa_aux->padev->aux_dev.dev;
|
||||||
|
|
||||||
|
dev_dbg(dev, "%s: event code %lu\n", __func__, ecode);
|
||||||
|
|
||||||
|
if (ecode == PDS_EVENT_RESET || ecode == PDS_EVENT_LINK_CHANGE) {
|
||||||
|
if (pdsv->config_cb.callback)
|
||||||
|
pdsv->config_cb.callback(pdsv->config_cb.private);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv)
|
||||||
|
{
|
||||||
|
struct device *dev = &pdsv->vdpa_aux->padev->aux_dev.dev;
|
||||||
|
struct notifier_block *nb = &pdsv->nb;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!nb->notifier_call) {
|
||||||
|
nb->notifier_call = pds_vdpa_notify_handler;
|
||||||
|
err = pdsc_register_notify(nb);
|
||||||
|
if (err) {
|
||||||
|
nb->notifier_call = NULL;
|
||||||
|
dev_err(dev, "failed to register pds event handler: %ps\n",
|
||||||
|
ERR_PTR(err));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
dev_dbg(dev, "pds event handler registered\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pds_vdpa_unregister_event_handler(struct pds_vdpa_device *pdsv)
|
||||||
|
{
|
||||||
|
if (pdsv->nb.notifier_call) {
|
||||||
|
pdsc_unregister_notify(&pdsv->nb);
|
||||||
|
pdsv->nb.notifier_call = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int pds_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid,
|
static int pds_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid,
|
||||||
u64 desc_addr, u64 driver_addr, u64 device_addr)
|
u64 desc_addr, u64 driver_addr, u64 device_addr)
|
||||||
{
|
{
|
||||||
@@ -595,6 +641,12 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
|
|||||||
|
|
||||||
pdsv->vdpa_dev.mdev = &vdpa_aux->vdpa_mdev;
|
pdsv->vdpa_dev.mdev = &vdpa_aux->vdpa_mdev;
|
||||||
|
|
||||||
|
err = pds_vdpa_register_event_handler(pdsv);
|
||||||
|
if (err) {
|
||||||
|
dev_err(dev, "Failed to register for PDS events: %pe\n", ERR_PTR(err));
|
||||||
|
goto err_unmap;
|
||||||
|
}
|
||||||
|
|
||||||
/* We use the _vdpa_register_device() call rather than the
|
/* We use the _vdpa_register_device() call rather than the
|
||||||
* vdpa_register_device() to avoid a deadlock because our
|
* vdpa_register_device() to avoid a deadlock because our
|
||||||
* dev_add() is called with the vdpa_dev_lock already set
|
* dev_add() is called with the vdpa_dev_lock already set
|
||||||
@@ -603,13 +655,15 @@ static int pds_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name,
|
|||||||
err = _vdpa_register_device(&pdsv->vdpa_dev, pdsv->num_vqs);
|
err = _vdpa_register_device(&pdsv->vdpa_dev, pdsv->num_vqs);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "Failed to register to vDPA bus: %pe\n", ERR_PTR(err));
|
dev_err(dev, "Failed to register to vDPA bus: %pe\n", ERR_PTR(err));
|
||||||
goto err_unmap;
|
goto err_unevent;
|
||||||
}
|
}
|
||||||
|
|
||||||
pds_vdpa_debugfs_add_vdpadev(vdpa_aux);
|
pds_vdpa_debugfs_add_vdpadev(vdpa_aux);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_unevent:
|
||||||
|
pds_vdpa_unregister_event_handler(pdsv);
|
||||||
err_unmap:
|
err_unmap:
|
||||||
put_device(&pdsv->vdpa_dev.dev);
|
put_device(&pdsv->vdpa_dev.dev);
|
||||||
vdpa_aux->pdsv = NULL;
|
vdpa_aux->pdsv = NULL;
|
||||||
@@ -619,8 +673,11 @@ err_unmap:
|
|||||||
static void pds_vdpa_dev_del(struct vdpa_mgmt_dev *mdev,
|
static void pds_vdpa_dev_del(struct vdpa_mgmt_dev *mdev,
|
||||||
struct vdpa_device *vdpa_dev)
|
struct vdpa_device *vdpa_dev)
|
||||||
{
|
{
|
||||||
|
struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);
|
||||||
struct pds_vdpa_aux *vdpa_aux;
|
struct pds_vdpa_aux *vdpa_aux;
|
||||||
|
|
||||||
|
pds_vdpa_unregister_event_handler(pdsv);
|
||||||
|
|
||||||
vdpa_aux = container_of(mdev, struct pds_vdpa_aux, vdpa_mdev);
|
vdpa_aux = container_of(mdev, struct pds_vdpa_aux, vdpa_mdev);
|
||||||
_vdpa_unregister_device(vdpa_dev);
|
_vdpa_unregister_device(vdpa_dev);
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ struct pds_vdpa_device {
|
|||||||
u8 vdpa_index; /* rsvd for future subdevice use */
|
u8 vdpa_index; /* rsvd for future subdevice use */
|
||||||
u8 num_vqs; /* num vqs in use */
|
u8 num_vqs; /* num vqs in use */
|
||||||
struct vdpa_callback config_cb;
|
struct vdpa_callback config_cb;
|
||||||
|
struct notifier_block nb;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PDS_VDPA_PACKED_INVERT_IDX 0x8000
|
#define PDS_VDPA_PACKED_INVERT_IDX 0x8000
|
||||||
|
|||||||
Reference in New Issue
Block a user