Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/vmm/io/ppt.c
Show First 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | struct { | ||||
void *cookie[MAX_MSIMSGS]; | void *cookie[MAX_MSIMSGS]; | ||||
struct pptintr_arg arg[MAX_MSIMSGS]; | struct pptintr_arg arg[MAX_MSIMSGS]; | ||||
} msi; | } msi; | ||||
struct { | struct { | ||||
int num_msgs; | int num_msgs; | ||||
int startrid; | int startrid; | ||||
int msix_table_rid; | int msix_table_rid; | ||||
int msix_pba_rid; | |||||
struct resource *msix_table_res; | struct resource *msix_table_res; | ||||
struct resource *msix_pba_res; | |||||
struct resource **res; | struct resource **res; | ||||
void **cookie; | void **cookie; | ||||
struct pptintr_arg *arg; | struct pptintr_arg *arg; | ||||
} msix; | } msix; | ||||
}; | }; | ||||
SYSCTL_DECL(_hw_vmm); | SYSCTL_DECL(_hw_vmm); | ||||
SYSCTL_NODE(_hw_vmm, OID_AUTO, ppt, CTLFLAG_RW, 0, "bhyve passthru devices"); | SYSCTL_NODE(_hw_vmm, OID_AUTO, ppt, CTLFLAG_RW, 0, "bhyve passthru devices"); | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | ppt_teardown_msix(struct pptdev *ppt) | ||||
int i; | int i; | ||||
if (ppt->msix.num_msgs == 0) | if (ppt->msix.num_msgs == 0) | ||||
return; | return; | ||||
for (i = 0; i < ppt->msix.num_msgs; i++) | for (i = 0; i < ppt->msix.num_msgs; i++) | ||||
ppt_teardown_msix_intr(ppt, i); | ppt_teardown_msix_intr(ppt, i); | ||||
free(ppt->msix.res, M_PPTMSIX); | |||||
free(ppt->msix.cookie, M_PPTMSIX); | |||||
free(ppt->msix.arg, M_PPTMSIX); | |||||
pci_release_msi(ppt->dev); | |||||
if (ppt->msix.msix_table_res) { | if (ppt->msix.msix_table_res) { | ||||
bus_release_resource(ppt->dev, SYS_RES_MEMORY, | bus_release_resource(ppt->dev, SYS_RES_MEMORY, | ||||
ppt->msix.msix_table_rid, | ppt->msix.msix_table_rid, | ||||
ppt->msix.msix_table_res); | ppt->msix.msix_table_res); | ||||
ppt->msix.msix_table_res = NULL; | ppt->msix.msix_table_res = NULL; | ||||
ppt->msix.msix_table_rid = 0; | ppt->msix.msix_table_rid = 0; | ||||
} | } | ||||
if (ppt->msix.msix_pba_res) { | |||||
bus_release_resource(ppt->dev, SYS_RES_MEMORY, | |||||
ppt->msix.msix_pba_rid, | |||||
ppt->msix.msix_pba_res); | |||||
ppt->msix.msix_pba_res = NULL; | |||||
ppt->msix.msix_pba_rid = 0; | |||||
} | |||||
free(ppt->msix.res, M_PPTMSIX); | |||||
free(ppt->msix.cookie, M_PPTMSIX); | |||||
free(ppt->msix.arg, M_PPTMSIX); | |||||
pci_release_msi(ppt->dev); | |||||
ppt->msix.num_msgs = 0; | ppt->msix.num_msgs = 0; | ||||
} | } | ||||
int | int | ||||
ppt_avail_devices(void) | ppt_avail_devices(void) | ||||
{ | { | ||||
return (num_pptdevs); | return (num_pptdevs); | ||||
▲ Show 20 Lines • Show All 312 Lines • ▼ Show 20 Lines | ppt->msix.msix_table_res = bus_alloc_resource_any(ppt->dev, | ||||
SYS_RES_MEMORY, &rid, RF_ACTIVE); | SYS_RES_MEMORY, &rid, RF_ACTIVE); | ||||
if (ppt->msix.msix_table_res == NULL) { | if (ppt->msix.msix_table_res == NULL) { | ||||
ppt_teardown_msix(ppt); | ppt_teardown_msix(ppt); | ||||
return (ENOSPC); | return (ENOSPC); | ||||
} | } | ||||
ppt->msix.msix_table_rid = rid; | ppt->msix.msix_table_rid = rid; | ||||
if (dinfo->cfg.msix.msix_table_bar != | |||||
dinfo->cfg.msix.msix_pba_bar) { | |||||
rid = dinfo->cfg.msix.msix_pba_bar; | |||||
ppt->msix.msix_pba_res = bus_alloc_resource_any( | |||||
ppt->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); | |||||
if (ppt->msix.msix_pba_res == NULL) { | |||||
ppt_teardown_msix(ppt); | |||||
return (ENOSPC); | |||||
} | |||||
ppt->msix.msix_pba_rid = rid; | |||||
} | |||||
alloced = numvec; | alloced = numvec; | ||||
error = pci_alloc_msix(ppt->dev, &alloced); | error = pci_alloc_msix(ppt->dev, &alloced); | ||||
if (error || alloced != numvec) { | if (error || alloced != numvec) { | ||||
ppt_teardown_msix(ppt); | ppt_teardown_msix(ppt); | ||||
return (error == 0 ? ENOSPC: error); | return (error == 0 ? ENOSPC: error); | ||||
} | } | ||||
} | } | ||||
Show All 15 Lines | if ((vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { | ||||
/* Setup the MSI-X interrupt */ | /* Setup the MSI-X interrupt */ | ||||
error = bus_setup_intr(ppt->dev, ppt->msix.res[idx], | error = bus_setup_intr(ppt->dev, ppt->msix.res[idx], | ||||
INTR_TYPE_NET | INTR_MPSAFE, | INTR_TYPE_NET | INTR_MPSAFE, | ||||
pptintr, NULL, &ppt->msix.arg[idx], | pptintr, NULL, &ppt->msix.arg[idx], | ||||
&ppt->msix.cookie[idx]); | &ppt->msix.cookie[idx]); | ||||
if (error != 0) { | if (error != 0) { | ||||
bus_teardown_intr(ppt->dev, ppt->msix.res[idx], ppt->msix.cookie[idx]); | |||||
bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, ppt->msix.res[idx]); | bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, ppt->msix.res[idx]); | ||||
ppt->msix.cookie[idx] = NULL; | ppt->msix.cookie[idx] = NULL; | ||||
ppt->msix.res[idx] = NULL; | ppt->msix.res[idx] = NULL; | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
} else { | } else { | ||||
/* Masked, tear it down if it's already been set up */ | /* Masked, tear it down if it's already been set up */ | ||||
ppt_teardown_msix_intr(ppt, idx); | ppt_teardown_msix_intr(ppt, idx); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } |