Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Feb 2002 15:39:26 +0100 (MET)
From:      Andy Sporner <sporner@nentec.de>
To:        freebsd-hackers@freebsd.org
Subject:   Porting a device driver from NetBSD to FreeBSD
Message-ID:  <XFMail.020213153926.sporner@nentec.de>

next in thread | raw e-mail | index | archive | help
Hello Everyone,

I have been trying to port a driver I had written on NetBSD to FreeBSD.  
On NetBSD the driver functions without incident, On FreeBSD, after a time
the whole system locks up.

I can create this by doing an FTP over the network interface (or sometimes
heavy disk activity).

I hope somebody can give me a hint of where I should look.  It seems that 
the PCI performance on FreeBSD is much faster in talking to this particular
devic.

Many thanks in advance!


Andy Sporner

PS: Here is the relavent attach() code for both systems:

NetBSD:
/*
 * galnet_attach()
 *
 * Here is where we attach the device to the system.
 */
void galnet_attach(struct device *parent, struct device *self, void *aux)
{
galnet_softc_t          *sc = (galnet_softc_t *)self;
struct pci_attach_args  *pa = aux;
bus_space_handle_t      memh;
bus_space_tag_t         memt;
pci_chipset_tag_t       pc = pa->pa_pc;
pci_intr_handle_t       ih;
pcireg_t                val;
bus_addr_t              addr;
bus_addr_t              size;
const char              *intrstr;
int                     flags;

        printf(": GALNET-2 GT48300 Crossbar Switch\n");

        memt = pa->pa_memt;

        if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, PCI_GNMA,
                (PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT),
                &addr, &size, &flags) == 0) {
                        flags &= ~BUS_SPACE_MAP_PREFETCHABLE;
                        if (bus_space_map(memt, addr, size, flags, &memh)) {
                                printf("%s: Failed to initialize memory\n",
                                        sc->sc_dev.dv_xname);
                                return;
                        } /* if */
        } else {
                printf("%s: Cannot locate mapped memory\n",
                        sc->sc_dev.dv_xname);
                return;
        } /* if */

        /* Enable the device */

        val = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);

        val |= PCI_COMMAND_MASTER_ENABLE;

        pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, val);

        /* Map interrupt. */

        if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin,
                pa->pa_intrline, &ih)) {
                        printf("%s: couldn't map interrupt\n",
                                sc->sc_dev.dv_xname);
                        return;
        } /* if */

        intrstr = pci_intr_string(pc, ih);
        sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, switch_intr, sc);

        if (sc->sc_ih == NULL) {
                printf("%s: couldn't map interrupt", sc->sc_dev.dv_xname);

                if (intrstr != NULL) {
                        printf(" at %s", intrstr);
                } /* if */

                printf("\n");

                return;
        } /* if */

        if (intrstr != NULL) {
                printf("%s: %s addr=0x0%08x size=0x0%x\n", sc->sc_dev.dv_xname,
                        intrstr, (unsigned int)addr, (unsigned int)size);
        } /* if */

        sc->sc_st = memt;
        sc->sc_sh = memh;
        sc->addr = addr;
        sc->size = size;
        sc->flags = flags;
        sc->sc_dmat = pa->pa_dmat;

        init_nitro(sc);

        return;

} /* galnet_attach() */


FreeBSD:

/*
 *  Galnet GN-48300 Driver
 */

#include "freebsd_kinclude.h"
#include "galnet_types.h"
#include "galnet_proto.h"


int             galnet_probe(device_t dev);
int             galnet_attach(device_t dev);
int             galnet_detach(device_t dev);
int             galnet_no_support(device_t dev);
void            galnet_release(galnet_softc_t *sc);

static device_method_t gn_methods[] = {

        DEVMETHOD(device_probe,         galnet_probe),
        DEVMETHOD(device_attach,        galnet_attach),
        DEVMETHOD(device_detach,        galnet_detach),
        DEVMETHOD(device_shutdown,      galnet_no_support),
        DEVMETHOD(device_suspend,       galnet_no_support),
        DEVMETHOD(device_resume,        galnet_no_support),

        { 0, 0 }
};

static driver_t gn_driver = {
        "gn",
        gn_methods,
        sizeof(galnet_softc_t),
};

static devclass_t gn_devclass;

nitro_admin_t   *nitro_ctrl=NULL;

#define GN_VENDOR_ID            0x011ab
#define GN_DEVICE_ID            0x04809
#define PCI_GNMA                0x10

DRIVER_MODULE(if_gn, pci, gn_driver, gn_devclass, 0, 0);

/*
 * Return identification string if this is device is ours.
 */
int galnet_probe(device_t dev)
{
        if ((pci_get_vendor(dev) == GN_VENDOR_ID)  &&
            (pci_get_device(dev) == GN_DEVICE_ID)) {
                device_set_desc(dev, "GALNET GN=48300");
                return (0);
        } /* if */

        return (ENXIO);

} /* galnet_probe() */

int galnet_attach(device_t dev)
{
galnet_softc_t          *sc;
u_int32_t               i, val;
int                     s;
int                     error;

        sc = device_get_softc(dev);
        bzero(sc, sizeof(*sc));
        error = 0;
        sc->sc_dev = dev;

        s = splimp();

        /*
         * Enable bus mastering. Enable memory space too, in case
         * BIOS/Prom forgot about it.
         */
        val = pci_read_config(dev, PCIR_COMMAND, 2);
        printf("ATTACH: VAL=%08x\n", val);

        val |= (PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
        pci_write_config(dev, PCIR_COMMAND, val, 2);
        val = pci_read_config(dev, PCIR_COMMAND, 2);

        /*
         * Figure out which we should try first - memory mapping or i/o
mapping?         * We default to memory mapping. Then we accept an override
from the
         * command line. Then we check to see which one is enabled.
         */

        i = 0x010;
        sc->addr = bus_alloc_resource(dev, SYS_RES_MEMORY, &i,
                        0, ~0, 1, RF_ACTIVE);
        device_printf(dev, "using memory space register mapping\n");

        if (!sc->addr) {
                device_printf(dev, "could not map device registers\n");
                error = ENXIO;
                galnet_release(sc);
                goto exit;
        } /* if */


        sc->sc_st = rman_get_bustag(sc->addr);
        sc->sc_sh = rman_get_bushandle(sc->addr);


        /*
         * Allocate our interrupt.
         */

        i = 0;
        if ((sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &i, 0, ~0, 1,
                RF_ACTIVE)) == NULL) {

                device_printf(dev, "could not map interrupt\n");
                error = ENXIO;
                galnet_release(sc);
                goto exit;
        } /* if */

        if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
                switch_intr, sc, &sc->sc_ih))) {

                device_printf(dev, "could not setup irq\n");
                galnet_release(sc);
                goto exit;
        } /* if */

#ifdef NOTDEF
        if (init_nitro(sc) == -1) {
                device_printf(dev, "Failed to initialize device\n");
                error = ENXIO;
                galnet_release(sc);
        } /* if */
#endif

exit:
        splx(s);
        return (error);

} /* galnet_attach() */


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.020213153926.sporner>