From afad89848f1bad2ab8cbacc82d3bb1153290dc45 Mon Sep 17 00:00:00 2001 From: simokawa Date: Fri, 30 Jan 2004 14:28:11 +0000 Subject: Use device_identify and bus_add_child methods to add a firewire bus on fwohci. This should fix attach failure caused by a race between firewire and fwochi initialization for the kernel module. --- sys/dev/firewire/firewire.c | 17 ++++++++--- sys/dev/firewire/fwohci.c | 1 - sys/dev/firewire/fwohci_pci.c | 69 +++++++++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 30 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index f3f7b16..6af01a0 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -80,7 +80,8 @@ MALLOC_DEFINE(M_FWXFER, "fw_xfer", "XFER/FireWire"); devclass_t firewire_devclass; -static int firewire_match (device_t); +static void firewire_identify (driver_t *, device_t); +static int firewire_probe (device_t); static int firewire_attach (device_t); static int firewire_detach (device_t); static int firewire_resume (device_t); @@ -105,7 +106,8 @@ static int fw_bmr (struct firewire_comm *); static device_method_t firewire_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, firewire_match), + DEVMETHOD(device_identify, firewire_identify), + DEVMETHOD(device_probe, firewire_probe), DEVMETHOD(device_attach, firewire_attach), DEVMETHOD(device_detach, firewire_detach), DEVMETHOD(device_suspend, bus_generic_suspend), @@ -310,11 +312,17 @@ fw_asystart(struct fw_xfer *xfer) return; } +static void +firewire_identify(driver_t *driver, device_t parent) +{ + BUS_ADD_CHILD(parent, 0, "firewire", -1); +} + static int -firewire_match( device_t dev ) +firewire_probe(device_t dev) { device_set_desc(dev, "IEEE1394(FireWire) bus"); - return -140; + return (0); } static void @@ -412,6 +420,7 @@ firewire_attach(device_t dev) bus_generic_attach(dev); /* bus_reset */ + fw_busreset(fc); fc->ibr(fc); return 0; diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c index 8cf9cf8..147285e 100644 --- a/sys/dev/firewire/fwohci.c +++ b/sys/dev/firewire/fwohci.c @@ -537,7 +537,6 @@ fwohci_reset(struct fwohci_softc *sc, device_t dev) OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_POSTWR); OWRITE(sc, OHCI_SID_BUF, sc->sid_dma.bus_addr); OWRITE(sc, OHCI_LNKCTL, OHCI_CNTL_SID); - fw_busreset(&sc->fc); /* Enable link */ OWRITE(sc, OHCI_HCCCTL, OHCI_HCC_LINKEN); diff --git a/sys/dev/firewire/fwohci_pci.c b/sys/dev/firewire/fwohci_pci.c index 6f516ed..f790f40 100644 --- a/sys/dev/firewire/fwohci_pci.c +++ b/sys/dev/firewire/fwohci_pci.c @@ -231,7 +231,7 @@ fwohci_pci_attach(device_t self) { fwohci_softc_t *sc = device_get_softc(self); int err; - int rid, s; + int rid; #if __FreeBSD_version < 500000 int intr; /* For the moment, put in a message stating what is wrong */ @@ -269,13 +269,6 @@ fwohci_pci_attach(device_t self) return ENXIO; } - sc->fc.bdev = device_add_child(self, "firewire", -1); - if (!sc->fc.bdev) { - device_printf(self, "Could not add firewire device\n"); - fwohci_pci_detach(self); - return ENOMEM; - } - device_set_ivars(sc->fc.bdev, sc); err = bus_setup_intr(self, sc->irq_res, #if FWOHCI_TASKQUEUE @@ -330,23 +323,9 @@ fwohci_pci_attach(device_t self) return EIO; } - err = device_probe_and_attach(sc->fc.bdev); - - if (err) { - device_printf(self, "probe_and_attach failed with err=%d\n", - err); - fwohci_pci_detach(self); - return EIO; - } - - /* XXX - * Clear the bus reset event flag to start transactions even when - * interrupt is disabled during the boot process. - */ - DELAY(250); /* 2 cycles */ - s = splfw(); - fwohci_poll((void *)sc, 0, -1); - splx(s); + /* probe and attach a child device(firewire) */ + bus_generic_probe(self); + bus_generic_attach(self); return 0; } @@ -444,6 +423,42 @@ fwohci_pci_shutdown(device_t dev) return 0; } +static device_t +fwohci_pci_add_child(device_t dev, int order, const char *name, int unit) +{ + struct fwohci_softc *sc; + device_t child; + int s, err = 0; + + sc = (struct fwohci_softc *)device_get_softc(dev); + child = device_add_child(dev, name, unit); + if (child == NULL) + return (child); + + sc->fc.bdev = child; + device_set_ivars(child, (void *)&sc->fc); + + err = device_probe_and_attach(child); + if (err) { + device_printf(dev, "probe_and_attach failed with err=%d\n", + err); + fwohci_pci_detach(dev); + device_delete_child(dev, child); + return NULL; + } + + /* XXX + * Clear the bus reset event flag to start transactions even when + * interrupt is disabled during the boot process. + */ + DELAY(250); /* 2 cycles */ + s = splfw(); + fwohci_poll((void *)sc, 0, -1); + splx(s); + + return (child); +} + static device_method_t fwohci_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fwohci_pci_probe), @@ -454,6 +469,7 @@ static device_method_t fwohci_methods[] = { DEVMETHOD(device_shutdown, fwohci_pci_shutdown), /* Bus interface */ + DEVMETHOD(bus_add_child, fwohci_pci_add_child), DEVMETHOD(bus_print_child, bus_generic_print_child), { 0, 0 } @@ -467,5 +483,8 @@ static driver_t fwohci_driver = { static devclass_t fwohci_devclass; +#ifdef FWOHCI_MODULE +MODULE_DEPEND(fwohci, firewire, 1, 1, 1); +#endif DRIVER_MODULE(fwohci, pci, fwohci_driver, fwohci_devclass, 0, 0); DRIVER_MODULE(fwohci, cardbus, fwohci_driver, fwohci_devclass, 0, 0); -- cgit v1.1