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>