Interrupt allocation

Hi all!

I'm porting device drivers from Linux to FreeBSD. I have been looking around for a way, how to register an interrupt service routine for the standard PC's serial port, i.e. 0x3f8/IRQ4, but have not found :(

I have ported succesfully a PCI card, where I have used bus_alloc_resource_any(), bus_setup_intr(), .. but haven't found the way for a correct registration of an non-bus interrupt, as there is no probe/attach and no device_t dev structure. Is there something like Linux's request_irq() on FreeBSD? Or how is the correct way to do that?

Thanks in advance! ;)
 
Hi,

thanks for the response but it's not what I was looking for. Nevertheless I have found the solution. I have read about the Newbus and understood that FreeBSD implemented the bus_space APIs, which is quite nice.

This implies that everything having a child is supposed to be a bus. In this case the serial port is considered to be a child of the ACPI. The API offers an unified way to allocate the resources. Please correct me if I'm wrong.

I have ported the drivers and have been testing without any problem. If you ever need to work with Profibus, here is an open solution: http://www.pbmaster.org .

This is a simple example how to attach a serial port (taken from sio and uart drivers /usr/src/sys):

Code:
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <isa/isavar.h>

static struct isa_pnp_id acpi_ns8250_ids[] = {
        {0x0005d041, "Standard PC COM port"},           /* PNP0500 */
        {0x0105d041, "16550A-compatible COM port"},     /* PNP0501 */
        {0}
};

static int
acpi_simple_probe(device_t dev)
{
        device_t parent;

        parent = device_get_parent(dev);

        if (!ISA_PNP_PROBE(parent, dev, acpi_ns8250_ids)) {
                return (BUS_PROBE_DEFAULT);
        }

        return (ENXIO);
}

static int
acpi_simple_attach(device_t dev)
{
        printf("attach\n");
        return (0);
}

static int
acpi_simple_detach(device_t dev)
{
        printf("detach\n");
        return 0;
}

static device_method_t acpi_simple_methods[] = {
        /* Device interface */
        DEVMETHOD(device_probe,         acpi_simple_probe),
        DEVMETHOD(device_attach,        acpi_simple_attach),
        DEVMETHOD(device_detach,        acpi_simple_detach),
        { 0, 0 }
};

struct acpi_simple_softc {
        int     a;
};

static driver_t acpi_simple_driver = {
        "acpi_simple",
        acpi_simple_methods,
        sizeof(struct acpi_simple_softc),
};

static devclass_t acpi_simple_devclass;

DRIVER_MODULE(acpi_simple, acpi, acpi_simple_driver, acpi_simple_devclass, 0, 0);
 
Back
Top