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>
index | next in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?XFMail.020213153926.sporner>
