mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Add a new PCI interface method, assign_interrupt, to determine the
interrupt to be used for a device. This is intended solely for internal use of PCI bus implementations, and exists so that PCI bus drivers implementing special interrupt assignment methods which require additional work at the bus level to work right can be easily derived from the generic driver (or any other one) without resorting to hacks. It will be used in the sparc64 ofw_pcibus driver, which will be committed shortly. Make use of this method in the generic implementation, and add it to the method table of bus drivers derived from the PCI one. Reviewed by: imp, -hackers
This commit is contained in:
parent
c5c68dcde3
commit
3920999db7
5 changed files with 25 additions and 6 deletions
|
|
@ -111,6 +111,7 @@ static device_method_t acpi_pci_methods[] = {
|
|||
/* XXX: We should override these two. */
|
||||
DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method),
|
||||
DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
|
||||
DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -387,6 +387,7 @@ static device_method_t cardbus_methods[] = {
|
|||
DEVMETHOD(pci_disable_io, pci_disable_io_method),
|
||||
DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method),
|
||||
DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
|
||||
DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
|
||||
|
||||
{0,0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -70,7 +70,8 @@ static int pci_porten(device_t pcib, int b, int s, int f);
|
|||
static int pci_memen(device_t pcib, int b, int s, int f);
|
||||
static int pci_add_map(device_t pcib, int b, int s, int f, int reg,
|
||||
struct resource_list *rl);
|
||||
static void pci_add_resources(device_t pcib, device_t dev);
|
||||
static void pci_add_resources(device_t pcib, device_t bus,
|
||||
device_t dev);
|
||||
static int pci_probe(device_t dev);
|
||||
static int pci_attach(device_t dev);
|
||||
static void pci_load_vendor_data(void);
|
||||
|
|
@ -119,6 +120,7 @@ static device_method_t pci_methods[] = {
|
|||
DEVMETHOD(pci_disable_io, pci_disable_io_method),
|
||||
DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method),
|
||||
DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
|
||||
DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
|
@ -776,7 +778,7 @@ pci_add_map(device_t pcib, int b, int s, int f, int reg,
|
|||
}
|
||||
|
||||
static void
|
||||
pci_add_resources(device_t pcib, device_t dev)
|
||||
pci_add_resources(device_t pcib, device_t bus, device_t dev)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(dev);
|
||||
pcicfgregs *cfg = &dinfo->cfg;
|
||||
|
|
@ -805,7 +807,7 @@ pci_add_resources(device_t pcib, device_t dev)
|
|||
* If the re-route fails, then just stick with what we
|
||||
* have.
|
||||
*/
|
||||
irq = PCIB_ROUTE_INTERRUPT(pcib, dev, cfg->intpin);
|
||||
irq = PCI_ASSIGN_INTERRUPT(bus, dev);
|
||||
if (PCI_INTERRUPT_VALID(irq)) {
|
||||
pci_write_config(dev, PCIR_INTLINE, irq, 1);
|
||||
cfg->intline = irq;
|
||||
|
|
@ -855,7 +857,7 @@ pci_add_child(device_t bus, struct pci_devinfo *dinfo)
|
|||
pcib = device_get_parent(bus);
|
||||
dinfo->cfg.dev = device_add_child(bus, NULL, -1);
|
||||
device_set_ivars(dinfo->cfg.dev, dinfo);
|
||||
pci_add_resources(pcib, dinfo->cfg.dev);
|
||||
pci_add_resources(pcib, bus, dinfo->cfg.dev);
|
||||
pci_print_verbose(dinfo);
|
||||
}
|
||||
|
||||
|
|
@ -1356,8 +1358,7 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
|
|||
*/
|
||||
if (!PCI_INTERRUPT_VALID(cfg->intline) &&
|
||||
(cfg->intpin != 0)) {
|
||||
cfg->intline = PCIB_ROUTE_INTERRUPT(
|
||||
device_get_parent(dev), child, cfg->intpin);
|
||||
cfg->intline = PCI_ASSIGN_INTERRUPT(dev, child);
|
||||
if (PCI_INTERRUPT_VALID(cfg->intline)) {
|
||||
pci_write_config(child, PCIR_INTLINE,
|
||||
cfg->intline, 1);
|
||||
|
|
@ -1479,6 +1480,16 @@ pci_child_pnpinfo_str_method(device_t cbdev, device_t child, char *buf,
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pci_assign_interrupt_method(device_t dev, device_t child)
|
||||
{
|
||||
struct pci_devinfo *dinfo = device_get_ivars(child);
|
||||
pcicfgregs *cfg = &dinfo->cfg;
|
||||
|
||||
return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child,
|
||||
cfg->intpin));
|
||||
}
|
||||
|
||||
static int
|
||||
pci_modevent(module_t mod, int what, void *arg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -77,3 +77,8 @@ METHOD int disable_io {
|
|||
device_t child;
|
||||
int space;
|
||||
};
|
||||
|
||||
METHOD int assign_interrupt {
|
||||
device_t dev;
|
||||
device_t child;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -72,4 +72,5 @@ int pci_child_location_str_method(device_t cbdev, device_t child,
|
|||
char *buf, size_t buflen);
|
||||
int pci_child_pnpinfo_str_method(device_t cbdev, device_t child,
|
||||
char *buf, size_t buflen);
|
||||
int pci_assign_interrupt_method(device_t dev, device_t child);
|
||||
#endif /* _PCI_PRIVATE_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue