diff --git a/sys/dev/cardbus/fwohci_cardbus.c b/sys/dev/cardbus/fwohci_cardbus.c index 1c5189525759..7c1aaff336c9 100644 --- a/sys/dev/cardbus/fwohci_cardbus.c +++ b/sys/dev/cardbus/fwohci_cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: fwohci_cardbus.c,v 1.34 2011/08/01 11:20:27 drochner Exp $ */ +/* $NetBSD: fwohci_cardbus.c,v 1.35 2012/08/04 03:55:43 riastradh Exp $ */ /*- * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.34 2011/08/01 11:20:27 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fwohci_cardbus.c,v 1.35 2012/08/04 03:55:43 riastradh Exp $"); #include #include @@ -98,6 +98,8 @@ fwohci_cardbus_attach(device_t parent, device_t self, void *aux) PCI_REVISION(ca->ca_class)); aprint_naive("\n"); + fwohci_init(&sc->sc_sc); + /* Map I/O registers */ if (Cardbus_mapreg_map(ct, PCI_OHCI_MAP_REGISTER, PCI_MAPREG_TYPE_MEM, 0, @@ -128,7 +130,7 @@ fwohci_cardbus_attach(device_t parent, device_t self, void *aux) } /* XXX NULL should be replaced by some call to Cardbus coed */ - if (fwohci_init(&sc->sc_sc) != 0) { + if (fwohci_attach(&sc->sc_sc) != 0) { Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = NULL; } diff --git a/sys/dev/ieee1394/firewire.c b/sys/dev/ieee1394/firewire.c index 941a5d1a40a0..afa221e03763 100644 --- a/sys/dev/ieee1394/firewire.c +++ b/sys/dev/ieee1394/firewire.c @@ -1,4 +1,4 @@ -/* $NetBSD: firewire.c,v 1.39 2012/04/29 18:31:40 dsl Exp $ */ +/* $NetBSD: firewire.c,v 1.40 2012/08/04 03:55:43 riastradh Exp $ */ /*- * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa @@ -37,7 +37,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.39 2012/04/29 18:31:40 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: firewire.c,v 1.40 2012/08/04 03:55:43 riastradh Exp $"); #include #include @@ -259,7 +259,6 @@ firewireattach(device_t parent, device_t self, void *aux) if (kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, fw_bus_probe_thread, fc, &fc->probe_thread, "fw%dprobe", device_unit(fc->bdev))) aprint_error_dev(self, "kthread_create failed\n"); - config_pending_incr(); devlist = malloc(sizeof(struct firewire_dev_list), M_DEVBUF, M_NOWAIT); if (devlist == NULL) { @@ -679,6 +678,15 @@ fw_init(struct firewire_comm *fc) fc->crom_src_buf = NULL; } +void +fw_destroy(struct firewire_comm *fc) +{ + mutex_destroy(&fc->arq->q_mtx); + mutex_destroy(&fc->ars->q_mtx); + mutex_destroy(&fc->atq->q_mtx); + mutex_destroy(&fc->ats->q_mtx); +} + #define BIND_CMP(addr, fwb) \ (((addr) < (fwb)->start) ? -1 : ((fwb)->end < (addr)) ? 1 : 0) @@ -1935,8 +1943,6 @@ fw_bus_probe_thread(void *arg) { struct firewire_comm *fc = (struct firewire_comm *)arg; - config_pending_decr(); - mutex_enter(&fc->wait_lock); while (fc->status != FWBUSDETACH) { if (fc->status == FWBUSEXPLORE) { diff --git a/sys/dev/ieee1394/firewirereg.h b/sys/dev/ieee1394/firewirereg.h index 2cbaf083ce7d..322d6cb54453 100644 --- a/sys/dev/ieee1394/firewirereg.h +++ b/sys/dev/ieee1394/firewirereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: firewirereg.h,v 1.17 2012/04/29 18:31:40 dsl Exp $ */ +/* $NetBSD: firewirereg.h,v 1.18 2012/08/04 03:55:43 riastradh Exp $ */ /*- * Copyright (c) 2003 Hidetoshi Shimokawa * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa @@ -283,6 +283,7 @@ int fw_xferwait(struct fw_xfer *); void fw_drain_txq(struct firewire_comm *); void fw_busreset(struct firewire_comm *, uint32_t); void fw_init(struct firewire_comm *); +void fw_destroy(struct firewire_comm *); struct fw_bind *fw_bindlookup(struct firewire_comm *, uint16_t, uint32_t); int fw_bindadd(struct firewire_comm *, struct fw_bind *); int fw_bindremove(struct firewire_comm *, struct fw_bind *); diff --git a/sys/dev/ieee1394/fwohci.c b/sys/dev/ieee1394/fwohci.c index 07e60b19c03f..5cb81a94df22 100644 --- a/sys/dev/ieee1394/fwohci.c +++ b/sys/dev/ieee1394/fwohci.c @@ -1,4 +1,4 @@ -/* $NetBSD: fwohci.c,v 1.132 2011/07/31 13:51:53 uebayasi Exp $ */ +/* $NetBSD: fwohci.c,v 1.133 2012/08/04 03:55:43 riastradh Exp $ */ /*- * Copyright (c) 2003 Hidetoshi Shimokawa @@ -37,7 +37,7 @@ * */ #include -__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.132 2011/07/31 13:51:53 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fwohci.c,v 1.133 2012/08/04 03:55:43 riastradh Exp $"); #include #include @@ -323,38 +323,15 @@ static void fwohci_arcv(struct fwohci_softc *, struct fwohci_dbch *); #define IRX_CH 36 -int +/* + * Call fwohci_init before fwohci_attach to initialize the kernel's + * data structures well enough that fwohci_detach won't crash, even if + * fwohci_attach fails. + */ + +void fwohci_init(struct fwohci_softc *sc) { - uint32_t reg; - uint8_t ui[8]; - int i, mver; - -/* OHCI version */ - reg = OREAD(sc, OHCI_VERSION); - mver = (reg >> 16) & 0xff; - aprint_normal_dev(sc->fc.dev, "OHCI version %x.%x (ROM=%d)\n", - mver, reg & 0xff, (reg >> 24) & 1); - if (mver < 1 || mver > 9) { - aprint_error_dev(sc->fc.dev, "invalid OHCI version\n"); - return ENXIO; - } - -/* Available Isochronous DMA channel probe */ - OWRITE(sc, OHCI_IT_MASK, 0xffffffff); - OWRITE(sc, OHCI_IR_MASK, 0xffffffff); - reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK); - OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff); - OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff); - for (i = 0; i < 0x20; i++) - if ((reg & (1 << i)) == 0) - break; - sc->fc.nisodma = i; - aprint_normal_dev(sc->fc.dev, "No. of Isochronous channels is %d.\n", - i); - if (i == 0) - return ENXIO; - sc->fc.arq = &sc->arrq.xferq; sc->fc.ars = &sc->arrs.xferq; sc->fc.atq = &sc->atrq.xferq; @@ -395,6 +372,68 @@ fwohci_init(struct fwohci_softc *sc) sc->atrq.off = OHCI_ATQOFF; sc->atrs.off = OHCI_ATSOFF; + sc->fc.tcode = tinfo; + + sc->fc.cyctimer = fwohci_cyctimer; + sc->fc.ibr = fwohci_ibr; + sc->fc.set_bmr = fwohci_set_bus_manager; + sc->fc.ioctl = fwohci_ioctl; + sc->fc.irx_enable = fwohci_irx_enable; + sc->fc.irx_disable = fwohci_irx_disable; + + sc->fc.itx_enable = fwohci_itxbuf_enable; + sc->fc.itx_disable = fwohci_itx_disable; + sc->fc.timeout = fwohci_timeout; + sc->fc.set_intr = fwohci_set_intr; +#if BYTE_ORDER == BIG_ENDIAN + sc->fc.irx_post = fwohci_irx_post; +#else + sc->fc.irx_post = NULL; +#endif + sc->fc.itx_post = NULL; + + sc->intmask = sc->irstat = sc->itstat = 0; + + fw_init(&sc->fc); +} + +/* + * Call fwohci_attach after fwohci_init to initialize the hardware and + * attach children. + */ + +int +fwohci_attach(struct fwohci_softc *sc) +{ + uint32_t reg; + uint8_t ui[8]; + int i, mver; + +/* OHCI version */ + reg = OREAD(sc, OHCI_VERSION); + mver = (reg >> 16) & 0xff; + aprint_normal_dev(sc->fc.dev, "OHCI version %x.%x (ROM=%d)\n", + mver, reg & 0xff, (reg >> 24) & 1); + if (mver < 1 || mver > 9) { + aprint_error_dev(sc->fc.dev, "invalid OHCI version\n"); + return ENXIO; + } + +/* Available Isochronous DMA channel probe */ + OWRITE(sc, OHCI_IT_MASK, 0xffffffff); + OWRITE(sc, OHCI_IR_MASK, 0xffffffff); + reg = OREAD(sc, OHCI_IT_MASK) & OREAD(sc, OHCI_IR_MASK); + OWRITE(sc, OHCI_IT_MASKCLR, 0xffffffff); + OWRITE(sc, OHCI_IR_MASKCLR, 0xffffffff); + for (i = 0; i < 0x20; i++) + if ((reg & (1 << i)) == 0) + break; + sc->fc.nisodma = i; + aprint_normal_dev(sc->fc.dev, "No. of Isochronous channels is %d.\n", + i); + if (i == 0) + return ENXIO; + for (i = 0; i < sc->fc.nisodma; i++) { sc->fc.it[i] = &sc->it[i].xferq; sc->fc.ir[i] = &sc->ir[i].xferq; @@ -406,8 +445,6 @@ fwohci_init(struct fwohci_softc *sc) sc->ir[i].off = OHCI_IROFF(i); } - sc->fc.tcode = tinfo; - sc->fc.config_rom = fwdma_alloc_setup(sc->fc.dev, sc->fc.dmat, CROMSIZE, &sc->crom_dma, CROMSIZE, BUS_DMA_NOWAIT); if (sc->fc.config_rom == NULL) { @@ -467,27 +504,6 @@ fwohci_init(struct fwohci_softc *sc) "EUI64 %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", ui[0], ui[1], ui[2], ui[3], ui[4], ui[5], ui[6], ui[7]); - sc->fc.cyctimer = fwohci_cyctimer; - sc->fc.ibr = fwohci_ibr; - sc->fc.set_bmr = fwohci_set_bus_manager; - sc->fc.ioctl = fwohci_ioctl; - sc->fc.irx_enable = fwohci_irx_enable; - sc->fc.irx_disable = fwohci_irx_disable; - - sc->fc.itx_enable = fwohci_itxbuf_enable; - sc->fc.itx_disable = fwohci_itx_disable; - sc->fc.timeout = fwohci_timeout; - sc->fc.set_intr = fwohci_set_intr; -#if BYTE_ORDER == BIG_ENDIAN - sc->fc.irx_post = fwohci_irx_post; -#else - sc->fc.irx_post = NULL; -#endif - sc->fc.itx_post = NULL; - - sc->intmask = sc->irstat = sc->itstat = 0; - - fw_init(&sc->fc); fwohci_reset(sc); sc->fc.bdev = @@ -499,10 +515,13 @@ fwohci_init(struct fwohci_softc *sc) int fwohci_detach(struct fwohci_softc *sc, int flags) { - int i; + int i, rv; - if (sc->fc.bdev != NULL) - config_detach(sc->fc.bdev, flags); + if (sc->fc.bdev != NULL) { + rv = config_detach(sc->fc.bdev, flags); + if (rv) + return rv; + } if (sc->sid_buf != NULL) fwdma_free(sc->sid_dma.dma_tag, sc->sid_dma.dma_map, sc->sid_dma.v_addr); @@ -519,10 +538,7 @@ fwohci_detach(struct fwohci_softc *sc, int flags) fwohci_db_free(sc, &sc->ir[i]); } - mutex_destroy(&sc->arrq.xferq.q_mtx); - mutex_destroy(&sc->arrs.xferq.q_mtx); - mutex_destroy(&sc->atrq.xferq.q_mtx); - mutex_destroy(&sc->atrs.xferq.q_mtx); + fw_destroy(&sc->fc); return 0; } diff --git a/sys/dev/ieee1394/fwohcivar.h b/sys/dev/ieee1394/fwohcivar.h index 49340cbc8405..d8625ac656b4 100644 --- a/sys/dev/ieee1394/fwohcivar.h +++ b/sys/dev/ieee1394/fwohcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: fwohcivar.h,v 1.33 2012/04/29 18:31:40 dsl Exp $ */ +/* $NetBSD: fwohcivar.h,v 1.34 2012/08/04 03:55:43 riastradh Exp $ */ /*- * Copyright (c) 2003 Hidetoshi SHimokawa @@ -77,7 +77,8 @@ struct fwohci_softc { #define OWRITE(sc, r, x) bus_space_write_4((sc)->bst, (sc)->bsh, (r), (x)) #define OREAD(sc, r) bus_space_read_4((sc)->bst, (sc)->bsh, (r)) -int fwohci_init(struct fwohci_softc *); +void fwohci_init(struct fwohci_softc *); +int fwohci_attach(struct fwohci_softc *); int fwohci_detach(struct fwohci_softc *, int); int fwohci_intr(void *arg); int fwohci_resume(struct fwohci_softc *); diff --git a/sys/dev/pci/fwohci_pci.c b/sys/dev/pci/fwohci_pci.c index e703604d57b2..aab9b52f2f8b 100644 --- a/sys/dev/pci/fwohci_pci.c +++ b/sys/dev/pci/fwohci_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: fwohci_pci.c,v 1.40 2012/01/30 19:41:19 drochner Exp $ */ +/* $NetBSD: fwohci_pci.c,v 1.41 2012/08/04 03:55:44 riastradh Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.40 2012/01/30 19:41:19 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: fwohci_pci.c,v 1.41 2012/08/04 03:55:44 riastradh Exp $"); #include #include @@ -102,6 +102,8 @@ fwohci_pci_attach(device_t parent, device_t self, void *aux) pci_aprint_devinfo(pa, "IEEE 1394 Controller"); + fwohci_init(&psc->psc_sc); + psc->psc_sc.fc.dev = self; psc->psc_sc.fc.dmat = pa->pa_dmat; psc->psc_pc = pa->pa_pc; @@ -149,15 +151,12 @@ fwohci_pci_attach(device_t parent, device_t self, void *aux) } aprint_normal_dev(self, "interrupting at %s\n", intrstr); + if (fwohci_attach(&psc->psc_sc) != 0) + goto fail; + if (!pmf_device_register(self, fwohci_pci_suspend, fwohci_pci_resume)) aprint_error_dev(self, "couldn't establish power handler\n"); - if (fwohci_init(&psc->psc_sc) != 0) { - pci_intr_disestablish(pa->pa_pc, psc->psc_ih); - bus_space_unmap(psc->psc_sc.bst, psc->psc_sc.bsh, - psc->psc_sc.bssize); - } - return; fail: