1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Interrupt allocation

Discussion in 'FreeBSD Development' started by trandk1, Dec 1, 2008.

  1. trandk1

    trandk1 New Member

    Messages:
    2
    Thanks Received:
    2
    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! ;)
     
  2. paulfrottawa

    paulfrottawa New Member

    Messages:
    242
    Thanks Received:
    14
    I don't know if this is the right direction but I noticed some details from the configuration file. Near the bottom half about this sio(4)

    I'm having problems too with an old computer
     
  3. trandk1

    trandk1 New Member

    Messages:
    2
    Thanks Received:
    2
    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);
    
     
    Maledictus and trasz@ thanked for this.