Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Fix error branches and config pending races in firew...
details: https://anonhg.NetBSD.org/src/rev/3c013772d511
branches: trunk
changeset: 780699:3c013772d511
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Aug 04 03:55:43 2012 +0000
description:
Fix error branches and config pending races in firewire init.
This way, if anything fails, it just fails; you don't panic. This can
happen if suspending and resuming of firewire is broken (e.g., as I
encountered in PR kern/44581).
diffstat:
sys/dev/cardbus/fwohci_cardbus.c | 8 +-
sys/dev/ieee1394/firewire.c | 16 +++-
sys/dev/ieee1394/firewirereg.h | 3 +-
sys/dev/ieee1394/fwohci.c | 140 +++++++++++++++++++++-----------------
sys/dev/ieee1394/fwohcivar.h | 5 +-
sys/dev/pci/fwohci_pci.c | 15 +--
6 files changed, 106 insertions(+), 81 deletions(-)
diffs (truncated from 368 to 300 lines):
diff -r 64c0c4e6270a -r 3c013772d511 sys/dev/cardbus/fwohci_cardbus.c
--- a/sys/dev/cardbus/fwohci_cardbus.c Sat Aug 04 03:53:55 2012 +0000
+++ b/sys/dev/cardbus/fwohci_cardbus.c Sat Aug 04 03:55:43 2012 +0000
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/systm.h>
@@ -98,6 +98,8 @@
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 @@
}
/* 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 -r 64c0c4e6270a -r 3c013772d511 sys/dev/ieee1394/firewire.c
--- a/sys/dev/ieee1394/firewire.c Sat Aug 04 03:53:55 2012 +0000
+++ b/sys/dev/ieee1394/firewire.c Sat Aug 04 03:55:43 2012 +0000
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/bus.h>
@@ -259,7 +259,6 @@
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 @@
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 @@
{
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 -r 64c0c4e6270a -r 3c013772d511 sys/dev/ieee1394/firewirereg.h
--- a/sys/dev/ieee1394/firewirereg.h Sat Aug 04 03:53:55 2012 +0000
+++ b/sys/dev/ieee1394/firewirereg.h Sat Aug 04 03:55:43 2012 +0000
@@ -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 @@
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 -r 64c0c4e6270a -r 3c013772d511 sys/dev/ieee1394/fwohci.c
--- a/sys/dev/ieee1394/fwohci.c Sat Aug 04 03:53:55 2012 +0000
+++ b/sys/dev/ieee1394/fwohci.c Sat Aug 04 03:55:43 2012 +0000
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/atomic.h>
@@ -323,38 +323,15 @@
#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 @@
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 @@
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 @@
"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 @@
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_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);
Home |
Main Index |
Thread Index |
Old Index