diff options
| author | ad <ad@NetBSD.org> | 2007-06-16 12:32:12 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2007-06-16 12:32:12 +0000 |
| commit | e5bca80a53681efbb44dbeeb018a534b735d3d1f (patch) | |
| tree | d447f30d6e16e12c0eb42dd8c0778f34b0f8d611 /sys/dev/i2o | |
| parent | 62ad7214e7dd20845844706f0141290a6891262a (diff) | |
- Merge changes from the vmlocking branch.
- Eliminate opt_i2o.h, since I2OVERBOSE is gone.
Diffstat (limited to 'sys/dev/i2o')
| -rw-r--r-- | sys/dev/i2o/dpti.c | 6 | ||||
| -rw-r--r-- | sys/dev/i2o/files.i2o | 4 | ||||
| -rw-r--r-- | sys/dev/i2o/iop.c | 177 | ||||
| -rw-r--r-- | sys/dev/i2o/iopl.c | 5 | ||||
| -rw-r--r-- | sys/dev/i2o/iopsp.c | 53 | ||||
| -rw-r--r-- | sys/dev/i2o/iopspvar.h | 8 | ||||
| -rw-r--r-- | sys/dev/i2o/iopvar.h | 5 | ||||
| -rw-r--r-- | sys/dev/i2o/ld_iop.c | 40 |
8 files changed, 139 insertions, 159 deletions
diff --git a/sys/dev/i2o/dpti.c b/sys/dev/i2o/dpti.c index 78399e907c6..50ad2422533 100644 --- a/sys/dev/i2o/dpti.c +++ b/sys/dev/i2o/dpti.c @@ -1,4 +1,4 @@ -/* $NetBSD: dpti.c,v 1.33 2007/03/04 06:01:47 christos Exp $ */ +/* $NetBSD: dpti.c,v 1.34 2007/06/16 12:32:12 ad Exp $ */ /*- * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc. @@ -64,9 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dpti.c,v 1.33 2007/03/04 06:01:47 christos Exp $"); - -#include "opt_i2o.h" +__KERNEL_RCSID(0, "$NetBSD: dpti.c,v 1.34 2007/06/16 12:32:12 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> diff --git a/sys/dev/i2o/files.i2o b/sys/dev/i2o/files.i2o index c0553ab50e5..0a156c72774 100644 --- a/sys/dev/i2o/files.i2o +++ b/sys/dev/i2o/files.i2o @@ -1,6 +1,4 @@ -# $NetBSD: files.i2o,v 1.6 2001/11/28 10:21:21 lukem Exp $ - -defflag opt_i2o.h I2OVERBOSE I2ODEBUG +# $NetBSD: files.i2o,v 1.7 2007/06/16 12:32:12 ad Exp $ device iop {tid = -1} file dev/i2o/iop.c iop needs-flag diff --git a/sys/dev/i2o/iop.c b/sys/dev/i2o/iop.c index fdfc3e73581..55dfc12482d 100644 --- a/sys/dev/i2o/iop.c +++ b/sys/dev/i2o/iop.c @@ -1,4 +1,4 @@ -/* $NetBSD: iop.c,v 1.64 2007/03/04 06:01:47 christos Exp $ */ +/* $NetBSD: iop.c,v 1.65 2007/06/16 12:32:12 ad Exp $ */ /*- * Copyright (c) 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc. @@ -41,9 +41,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iop.c,v 1.64 2007/03/04 06:01:47 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iop.c,v 1.65 2007/06/16 12:32:12 ad Exp $"); -#include "opt_i2o.h" #include "iop.h" #include <sys/param.h> @@ -86,14 +85,6 @@ do { \ #define DPRINTF(x) #endif -#ifdef I2OVERBOSE -#define IFVERBOSE(x) x -#define COMMENT(x) NULL -#else -#define IFVERBOSE(x) -#define COMMENT(x) -#endif - #define IOP_ICTXHASH_NBUCKETS 16 #define IOP_ICTXHASH(ictx) (&iop_ictxhashtbl[(ictx) & iop_ictxhash]) @@ -125,83 +116,80 @@ const struct cdevsw iop_cdevsw = { static struct iop_class { u_short ic_class; u_short ic_flags; -#ifdef I2OVERBOSE - const char *ic_caption; -#endif + const char *ic_caption; } const iop_class[] = { { I2O_CLASS_EXECUTIVE, 0, - IFVERBOSE("executive") + "executive" }, { I2O_CLASS_DDM, 0, - COMMENT("device driver module") + "device driver module" }, { I2O_CLASS_RANDOM_BLOCK_STORAGE, IC_CONFIGURE | IC_PRIORITY, - IFVERBOSE("random block storage") + "random block storage" }, { I2O_CLASS_SEQUENTIAL_STORAGE, IC_CONFIGURE | IC_PRIORITY, - IFVERBOSE("sequential storage") + "sequential storage" }, { I2O_CLASS_LAN, IC_CONFIGURE | IC_PRIORITY, - IFVERBOSE("LAN port") + "LAN port" }, { I2O_CLASS_WAN, IC_CONFIGURE | IC_PRIORITY, - IFVERBOSE("WAN port") + "WAN port" }, { I2O_CLASS_FIBRE_CHANNEL_PORT, IC_CONFIGURE, - IFVERBOSE("fibrechannel port") + "fibrechannel port" }, { I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL, 0, - COMMENT("fibrechannel peripheral") + "fibrechannel peripheral" }, { I2O_CLASS_SCSI_PERIPHERAL, 0, - COMMENT("SCSI peripheral") + "SCSI peripheral" }, { I2O_CLASS_ATE_PORT, IC_CONFIGURE, - IFVERBOSE("ATE port") + "ATE port" }, { I2O_CLASS_ATE_PERIPHERAL, 0, - COMMENT("ATE peripheral") + "ATE peripheral" }, { I2O_CLASS_FLOPPY_CONTROLLER, IC_CONFIGURE, - IFVERBOSE("floppy controller") + "floppy controller" }, { I2O_CLASS_FLOPPY_DEVICE, 0, - COMMENT("floppy device") + "floppy device" }, { I2O_CLASS_BUS_ADAPTER_PORT, IC_CONFIGURE, - IFVERBOSE("bus adapter port" ) + "bus adapter port" }, }; -#if defined(I2ODEBUG) && defined(I2OVERBOSE) static const char * const iop_status[] = { "success", "abort (dirty)", @@ -216,7 +204,6 @@ static const char * const iop_status[] = { "process abort (partial transfer)", "transaction error", }; -#endif static inline u_int32_t iop_inl(struct iop_softc *, int); static inline void iop_outl(struct iop_softc *, int, u_int32_t); @@ -305,6 +292,10 @@ iop_init(struct iop_softc *sc, const char *intrstr) printf("I2O adapter"); + mutex_init(&sc->sc_intrlock, MUTEX_DRIVER, IPL_VM); + mutex_init(&sc->sc_conflock, MUTEX_DRIVER, IPL_NONE); + cv_init(&sc->sc_confcv, "iopconf"); + if (iop_ictxhashtbl == NULL) iop_ictxhashtbl = hashinit(IOP_ICTXHASH_NBUCKETS, HASH_LIST, M_DEVBUF, M_NOWAIT, &iop_ictxhash); @@ -348,6 +339,9 @@ iop_init(struct iop_softc *sc, const char *intrstr) sc->sc_framesize = 128; #endif + /* Avoid syncing the reply map until it's set up. */ + sc->sc_curib = 0x123; + /* Reset the adapter and request status. */ if ((rv = iop_reset(sc)) != 0) { printf("%s: not responding (reset)\n", sc->sc_dv.dv_xname); @@ -421,6 +415,7 @@ iop_init(struct iop_softc *sc, const char *intrstr) im->im_tctx = i; SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain); + cv_init(&im->im_cv, "iopmsg"); } /* Initialise the IOP's outbound FIFO. */ @@ -455,8 +450,6 @@ iop_init(struct iop_softc *sc, const char *intrstr) sc->sc_maxob, le32toh(sc->sc_status.maxoutboundmframes)); #endif - mutex_init(&sc->sc_conflock, MUTEX_DRIVER, IPL_NONE); - cv_init(&sc->sc_confcv, "iopzzz"); return; bail_out3: @@ -489,12 +482,15 @@ iop_config_interrupts(struct device *self) int locs[IOPCF_NLOCS]; sc = device_private(self); + mutex_enter(&sc->sc_conflock); + LIST_INIT(&sc->sc_iilist); printf("%s: configuring...\n", sc->sc_dv.dv_xname); if (iop_hrt_get(sc) != 0) { printf("%s: unable to retrieve HRT\n", sc->sc_dv.dv_xname); + mutex_exit(&sc->sc_conflock); return; } @@ -515,8 +511,10 @@ iop_config_interrupts(struct device *self) } niop++; } - if (niop == 0) + if (niop == 0) { + mutex_exit(&sc->sc_conflock); return; + } i = sizeof(struct i2o_systab_entry) * (niop - 1) + sizeof(struct i2o_systab); @@ -551,10 +549,12 @@ iop_config_interrupts(struct device *self) */ if (iop_systab_set(sc) != 0) { printf("%s: unable to set system table\n", sc->sc_dv.dv_xname); + mutex_exit(&sc->sc_conflock); return; } if (iop_sys_enable(sc) != 0) { printf("%s: unable to enable system\n", sc->sc_dv.dv_xname); + mutex_exit(&sc->sc_conflock); return; } @@ -582,6 +582,7 @@ iop_config_interrupts(struct device *self) I2O_EVENT_GEN_GENERAL_WARNING); if (rv != 0) { printf("%s: unable to register for events", sc->sc_dv.dv_xname); + mutex_exit(&sc->sc_conflock); return; } @@ -597,13 +598,14 @@ iop_config_interrupts(struct device *self) /* * Start device configuration. */ - mutex_enter(&sc->sc_conflock); if ((rv = iop_reconfigure(sc, 0)) == -1) printf("%s: configure failed (%d)\n", sc->sc_dv.dv_xname, rv); + mutex_exit(&sc->sc_conflock); if (rv == 0) kthread_create(iop_create_reconf_thread, sc); + } /* @@ -617,7 +619,9 @@ iop_create_reconf_thread(void *cookie) int rv; sc = cookie; + mutex_enter(&sc->sc_conflock); sc->sc_flags |= IOP_ONLINE; + mutex_exit(&sc->sc_conflock); rv = kthread_create1(iop_reconf_thread, sc, &sc->sc_reconf_proc, "%s", sc->sc_dv.dv_xname); @@ -645,25 +649,22 @@ iop_reconf_thread(void *cookie) chgind = sc->sc_chgind + 1; l = curlwp; - mutex_enter(&sc->sc_conflock); - for (;;) { DPRINTF(("%s: async reconfig: requested 0x%08x\n", sc->sc_dv.dv_xname, chgind)); - PHOLD(l); rv = iop_lct_get0(sc, &lct, sizeof(lct), chgind); - PRELE(l); DPRINTF(("%s: async reconfig: notified (0x%08x, %d)\n", sc->sc_dv.dv_xname, le32toh(lct.changeindicator), rv)); + mutex_enter(&sc->sc_conflock); if (rv == 0) { iop_reconfigure(sc, le32toh(lct.changeindicator)); chgind = sc->sc_chgind + 1; } - - cv_timedwait(&sc->sc_confcv, &sc->sc_conflock, hz * 10); + (void)cv_timedwait(&sc->sc_confcv, &sc->sc_conflock, hz * 5); + mutex_exit(&sc->sc_conflock); } } @@ -679,6 +680,8 @@ iop_reconfigure(struct iop_softc *sc, u_int chgind) struct iop_initiator *ii, *nextii; int rv, tid, i; + KASSERT(mutex_owned(&sc->sc_conflock)); + /* * If the reconfiguration request isn't the result of LCT change * notification, then be more thorough: ask all bus ports to scan @@ -868,7 +871,6 @@ iop_adjqparam(struct iop_softc *sc, int mpi) static void iop_devinfo(int class, char *devinfo, size_t l) { -#ifdef I2OVERBOSE int i; for (i = 0; i < sizeof(iop_class) / sizeof(iop_class[0]); i++) @@ -879,10 +881,6 @@ iop_devinfo(int class, char *devinfo, size_t l) snprintf(devinfo, l, "device (class 0x%x)", class); else strlcpy(devinfo, iop_class[i].ic_caption, l); -#else - - snprintf(devinfo, l, "device (class 0x%x)", class); -#endif } static int @@ -975,7 +973,7 @@ iop_status_get(struct iop_softc *sc, int nosleep) if (nosleep) DELAY(100*1000); else - tsleep(iop_status_get, PWAIT, "iopstat", hz / 10); + kpause("iopstat", false, hz / 10, NULL); } if (st->syncbyte != 0xff) { @@ -1076,6 +1074,9 @@ iop_ofifo_init(struct iop_softc *sc) } sc->sc_rep_phys = sc->sc_rep_dmamap->dm_segs[0].ds_addr; + + /* Now safe to sync the reply map. */ + sc->sc_curib = 0; } /* Populate the outbound FIFO. */ @@ -1616,7 +1617,6 @@ void iop_initiator_register(struct iop_softc *sc, struct iop_initiator *ii) { static int ictxgen; - int s; /* 0 is reserved (by us) for system messages. */ ii->ii_ictx = ++ictxgen; @@ -1632,9 +1632,11 @@ iop_initiator_register(struct iop_softc *sc, struct iop_initiator *ii) } else sc->sc_nuii++; - s = splbio(); + cv_init(&ii->ii_cv, "iopevt"); + + mutex_spin_enter(&sc->sc_intrlock); LIST_INSERT_HEAD(IOP_ICTXHASH(ii->ii_ictx), ii, ii_hash); - splx(s); + mutex_spin_exit(&sc->sc_intrlock); } /* @@ -1644,7 +1646,6 @@ iop_initiator_register(struct iop_softc *sc, struct iop_initiator *ii) void iop_initiator_unregister(struct iop_softc *sc, struct iop_initiator *ii) { - int s; if ((ii->ii_flags & II_UTILITY) == 0) { LIST_REMOVE(ii, ii_list); @@ -1652,9 +1653,11 @@ iop_initiator_unregister(struct iop_softc *sc, struct iop_initiator *ii) } else sc->sc_nuii--; - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); LIST_REMOVE(ii, ii_hash); - splx(s); + mutex_spin_exit(&sc->sc_intrlock); + + cv_destroy(&ii->ii_cv); } /* @@ -1669,6 +1672,8 @@ iop_handle_reply(struct iop_softc *sc, u_int32_t rmfa) struct iop_initiator *ii; u_int off, ictx, tctx, status, size; + KASSERT(mutex_owned(&sc->sc_intrlock)); + off = (int)(rmfa - sc->sc_rep_phys); rb = (struct i2o_reply *)((char *)sc->sc_rep + off); @@ -1773,10 +1778,13 @@ iop_handle_reply(struct iop_softc *sc, u_int32_t rmfa) /* Notify the initiator. */ if ((im->im_flags & IM_WAIT) != 0) - wakeup(im); + cv_broadcast(&im->im_cv); else if ((im->im_flags & (IM_POLL | IM_POLL_INTR)) != IM_POLL) { - if (ii) + if (ii != NULL) { + mutex_spin_exit(&sc->sc_intrlock); (*ii->ii_intr)(ii->ii_dv, im, rb); + mutex_spin_enter(&sc->sc_intrlock); + } } } else { /* @@ -1784,8 +1792,11 @@ iop_handle_reply(struct iop_softc *sc, u_int32_t rmfa) * * Simply pass the reply frame to the initiator. */ - if (ii) + if (ii != NULL) { + mutex_spin_exit(&sc->sc_intrlock); (*ii->ii_intr)(ii->ii_dv, NULL, rb); + mutex_spin_enter(&sc->sc_intrlock); + } } return (status); @@ -1802,8 +1813,12 @@ iop_intr(void *arg) sc = arg; - if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) == 0) + mutex_spin_enter(&sc->sc_intrlock); + + if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) == 0) { + mutex_spin_exit(&sc->sc_intrlock); return (0); + } for (;;) { /* Double read to account for IOP bug. */ @@ -1816,6 +1831,7 @@ iop_intr(void *arg) iop_outl(sc, IOP_REG_OFIFO, rmfa); } + mutex_spin_exit(&sc->sc_intrlock); return (1); } @@ -1845,21 +1861,21 @@ iop_msg_alloc(struct iop_softc *sc, int flags) { struct iop_msg *im; static u_int tctxgen; - int s, i; + int i; #ifdef I2ODEBUG if ((flags & IM_SYSMASK) != 0) panic("iop_msg_alloc: system flags specified"); #endif - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); im = SLIST_FIRST(&sc->sc_im_freelist); #if defined(DIAGNOSTIC) || defined(I2ODEBUG) if (im == NULL) panic("iop_msg_alloc: no free wrappers"); #endif SLIST_REMOVE_HEAD(&sc->sc_im_freelist, im_chain); - splx(s); + mutex_spin_exit(&sc->sc_intrlock); im->im_tctx = (im->im_tctx & IOP_TCTX_MASK) | tctxgen; tctxgen += (1 << IOP_TCTX_SHIFT); @@ -1879,7 +1895,6 @@ iop_msg_alloc(struct iop_softc *sc, int flags) void iop_msg_free(struct iop_softc *sc, struct iop_msg *im) { - int s; #ifdef I2ODEBUG if ((im->im_flags & IM_ALLOCED) == 0) @@ -1887,9 +1902,9 @@ iop_msg_free(struct iop_softc *sc, struct iop_msg *im) #endif im->im_flags = 0; - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); SLIST_INSERT_HEAD(&sc->sc_im_freelist, im, im_chain); - splx(s); + mutex_spin_exit(&sc->sc_intrlock); } /* @@ -2127,19 +2142,18 @@ int iop_post(struct iop_softc *sc, u_int32_t *mb) { u_int32_t mfa; - int s; #ifdef I2ODEBUG if ((mb[0] >> 16) > (sc->sc_framesize >> 2)) panic("iop_post: frame too large"); #endif - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); /* Allocate a slot with the IOP. */ if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY) if ((mfa = iop_inl(sc, IOP_REG_IFIFO)) == IOP_MFA_EMPTY) { - splx(s); + mutex_spin_exit(&sc->sc_intrlock); printf("%s: mfa not forthcoming\n", sc->sc_dv.dv_xname); return (EAGAIN); @@ -2159,7 +2173,7 @@ iop_post(struct iop_softc *sc, u_int32_t *mb) /* Post the MFA back to the IOP. */ iop_outl(sc, IOP_REG_IFIFO, mfa); - splx(s); + mutex_spin_exit(&sc->sc_intrlock); return (0); } @@ -2170,7 +2184,7 @@ int iop_msg_post(struct iop_softc *sc, struct iop_msg *im, void *xmb, int timo) { u_int32_t *mb; - int rv, s; + int rv; mb = xmb; @@ -2187,7 +2201,7 @@ iop_msg_post(struct iop_softc *sc, struct iop_msg *im, void *xmb, int timo) else iop_msg_wait(sc, im, timo); - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); if ((im->im_flags & IM_REPLIED) != 0) { if ((im->im_flags & IM_NOSTATUS) != 0) rv = 0; @@ -2199,7 +2213,7 @@ iop_msg_post(struct iop_softc *sc, struct iop_msg *im, void *xmb, int timo) rv = 0; } else rv = EBUSY; - splx(s); + mutex_spin_exit(&sc->sc_intrlock); } else rv = 0; @@ -2213,11 +2227,9 @@ static void iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo) { u_int32_t rmfa; - int s; - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); - /* Wait for completion. */ for (timo *= 10; timo != 0; timo--) { if ((iop_inl(sc, IOP_REG_INTR_STATUS) & IOP_INTR_OFIFO) != 0) { /* Double read to account for IOP bug. */ @@ -2236,7 +2248,9 @@ iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo) } if ((im->im_flags & IM_REPLIED) != 0) break; + mutex_spin_exit(&sc->sc_intrlock); DELAY(100); + mutex_spin_enter(&sc->sc_intrlock); } if (timo == 0) { @@ -2250,7 +2264,7 @@ iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo) #endif } - splx(s); + mutex_spin_exit(&sc->sc_intrlock); } /* @@ -2259,15 +2273,15 @@ iop_msg_poll(struct iop_softc *sc, struct iop_msg *im, int timo) static void iop_msg_wait(struct iop_softc *sc, struct iop_msg *im, int timo) { - int s, rv; + int rv; - s = splbio(); + mutex_spin_enter(&sc->sc_intrlock); if ((im->im_flags & IM_REPLIED) != 0) { - splx(s); + mutex_spin_exit(&sc->sc_intrlock); return; } - rv = tsleep(im, PRIBIO, "iopmsg", mstohz(timo)); - splx(s); + rv = cv_timedwait(&im->im_cv, &sc->sc_intrlock, mstohz(timo)); + mutex_spin_exit(&sc->sc_intrlock); #ifdef I2ODEBUG if (rv != 0) { @@ -2305,16 +2319,13 @@ static void iop_reply_print(struct iop_softc *sc, struct i2o_reply *rb) { u_int function, detail; -#ifdef I2OVERBOSE const char *statusstr; -#endif function = (le32toh(rb->msgfunc) >> 24) & 0xff; detail = le16toh(rb->detail); printf("%s: reply:\n", sc->sc_dv.dv_xname); -#ifdef I2OVERBOSE if (rb->reqstatus < sizeof(iop_status) / sizeof(iop_status[0])) statusstr = iop_status[rb->reqstatus]; else @@ -2322,10 +2333,6 @@ iop_reply_print(struct iop_softc *sc, struct i2o_reply *rb) printf("%s: function=0x%02x status=0x%02x (%s)\n", sc->sc_dv.dv_xname, function, rb->reqstatus, statusstr); -#else - printf("%s: function=0x%02x status=0x%02x\n", - sc->sc_dv.dv_xname, function, rb->reqstatus); -#endif printf("%s: detail=0x%04x ictx=0x%08x tctx=0x%08x\n", sc->sc_dv.dv_xname, detail, le32toh(rb->msgictx), le32toh(rb->msgtctx)); diff --git a/sys/dev/i2o/iopl.c b/sys/dev/i2o/iopl.c index f07959449f3..6d169fb2ea7 100644 --- a/sys/dev/i2o/iopl.c +++ b/sys/dev/i2o/iopl.c @@ -1,4 +1,4 @@ -/* $NetBSD: iopl.c,v 1.24 2007/03/04 06:01:47 christos Exp $ */ +/* $NetBSD: iopl.c,v 1.25 2007/06/16 12:32:12 ad Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -46,9 +46,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iopl.c,v 1.24 2007/03/04 06:01:47 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: iopl.c,v 1.25 2007/06/16 12:32:12 ad Exp $"); -#include "opt_i2o.h" #include "opt_inet.h" #include "bpfilter.h" diff --git a/sys/dev/i2o/iopsp.c b/sys/dev/i2o/iopsp.c index 3f590d51bc0..e080a074fb3 100644 --- a/sys/dev/i2o/iopsp.c +++ b/sys/dev/i2o/iopsp.c @@ -1,7 +1,7 @@ -/* $NetBSD: iopsp.c,v 1.27 2007/03/04 06:01:47 christos Exp $ */ +/* $NetBSD: iopsp.c,v 1.28 2007/06/16 12:32:12 ad Exp $ */ /*- - * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2001, 2007 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -42,9 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: iopsp.c,v 1.27 2007/03/04 06:01:47 christos Exp $"); - -#include "opt_i2o.h" +__KERNEL_RCSID(0, "$NetBSD: iopsp.c,v 1.28 2007/06/16 12:32:12 ad Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -130,9 +128,7 @@ iopsp_attach(struct device *parent, struct device *self, void *aux) } p; } __attribute__ ((__packed__)) param; int fc, rv; -#ifdef I2OVERBOSE int size; -#endif ia = (struct iop_attach_args *)aux; sc = device_private(self); @@ -167,7 +163,6 @@ iopsp_attach(struct device *parent, struct device *self, void *aux) if (rv != 0) goto bad; -#ifdef I2OVERBOSE printf("%s: ", sc->sc_dv.dv_xname); if (fc) printf("FC"); @@ -176,7 +171,6 @@ iopsp_attach(struct device *parent, struct device *self, void *aux) printf(", max sync rate %dMHz, initiator ID %d\n", (u_int32_t)le64toh(param.p.sci.maxsyncrate) / 1000, le32toh(param.p.sci.initiatorid)); -#endif sc->sc_openings = 1; @@ -198,14 +192,12 @@ iopsp_attach(struct device *parent, struct device *self, void *aux) sc->sc_channel.chan_id = le32toh(param.p.sci.initiatorid); sc->sc_channel.chan_flags = SCSIPI_CHAN_NOSETTLE; -#ifdef I2OVERBOSE /* * Allocate the target map. Currently used for informational * purposes only. */ size = sc->sc_channel.chan_ntargets * sizeof(struct iopsp_target); sc->sc_targetmap = malloc(size, M_DEVBUF, M_NOWAIT|M_ZERO); -#endif /* Build the two maps, and attach to scsipi. */ if (iopsp_reconfig(self) != 0) { @@ -235,17 +227,18 @@ iopsp_reconfig(struct device *dv) struct i2o_param_read_results prr; struct i2o_param_scsi_device_info sdi; } __attribute__ ((__packed__)) param; - u_int tid, nent, i, targ, lun, size, s, rv, bptid; + u_int tid, nent, i, targ, lun, size, rv, bptid; u_short *tidmap; -#ifdef I2OVERBOSE + void *tofree; struct iopsp_target *it; int syncrate; -#endif sc = (struct iopsp_softc *)dv; iop = (struct iop_softc *)device_parent(&sc->sc_dv); sc_chan = &sc->sc_channel; + KASSERT(mutex_owned(&iop->sc_conflock)); + /* Anything to do? */ if (iop->sc_chgind == sc->sc_chgind) return (0); @@ -259,10 +252,8 @@ iopsp_reconfig(struct device *dv) if ((tidmap = malloc(size, M_DEVBUF, M_WAITOK|M_ZERO)) == NULL) return (ENOMEM); -#ifdef I2OVERBOSE for (i = 0; i < sc_chan->chan_ntargets; i++) sc->sc_targetmap[i].it_flags &= ~IT_PRESENT; -#endif /* * A quick hack to handle Intel's stacked bus port arrangement. @@ -300,7 +291,6 @@ iopsp_reconfig(struct device *dv) } #endif -#ifdef I2OVERBOSE /* * If we've already described this target, and nothing has * changed, then don't describe it again. @@ -323,11 +313,9 @@ iopsp_reconfig(struct device *dv) printf("synchronous at %dMHz, offset 0x%x\n", it->it_syncrate, it->it_offset); } -#endif /* Ignore the device if it's in use by somebody else. */ if ((le32toh(le->usertid) & 4095) != I2O_TID_NONE) { -#ifdef I2OVERBOSE if (sc->sc_tidmap == NULL || IOPSP_TIDMAP(sc->sc_tidmap, targ, lun) != IOPSP_TID_INUSE) @@ -335,24 +323,23 @@ iopsp_reconfig(struct device *dv) " tid %d\n", sc->sc_dv.dv_xname, targ, lun, tid, le32toh(le->usertid) & 4095); -#endif IOPSP_TIDMAP(tidmap, targ, lun) = IOPSP_TID_INUSE; } else IOPSP_TIDMAP(tidmap, targ, lun) = (u_short)tid; } -#ifdef I2OVERBOSE for (i = 0; i < sc_chan->chan_ntargets; i++) if ((sc->sc_targetmap[i].it_flags & IT_PRESENT) == 0) sc->sc_targetmap[i].it_width = 0; -#endif /* Swap in the new map and return. */ - s = splbio(); - if (sc->sc_tidmap != NULL) - free(sc->sc_tidmap, M_DEVBUF); + mutex_spin_enter(&iop->sc_intrlock); + tofree = sc->sc_tidmap; sc->sc_tidmap = tidmap; - splx(s); + mutex_spin_exit(&iop->sc_intrlock); + + if (tofree != NULL) + free(tofree, M_DEVBUF); sc->sc_chgind = iop->sc_chgind; return (0); } @@ -535,10 +522,9 @@ iopsp_scsi_abort(struct iopsp_softc *sc, int atid, struct iop_msg *aim) mf.msgtctx = im->im_tctx; mf.tctxabort = aim->im_tctx; - s = splbio(); rv = iop_msg_post(iop, im, &mf, 30000); - splx(s); iop_msg_free(iop, im); + return (rv); } #endif @@ -637,7 +623,7 @@ iopsp_ioctl(struct scsipi_channel *chan, u_long cmd, void *data, * maps built. Locking would stop re-configuration, but we * want to fake success. */ - if (p != &proc0) + if (curlwp != &lwp0) rv = iopsp_rescan( (struct iopsp_softc *)chan->chan_adapter->adapt_dev); else @@ -659,12 +645,13 @@ static void iopsp_adjqparam(struct device *dv, int mpi) { struct iopsp_softc *sc; - int s; + struct iop_softc *iop; - sc = (struct iopsp_softc *)dv; + sc = device_private(dv); + iop = device_private(device_parent(dv)); - s = splbio(); + mutex_spin_enter(&iop->sc_intrlock); sc->sc_adapter.adapt_openings += mpi - sc->sc_openings; sc->sc_openings = mpi; - splx(s); + mutex_spin_exit(&iop->sc_intrlock); } diff --git a/sys/dev/i2o/iopspvar.h b/sys/dev/i2o/iopspvar.h index 899995e04fa..1a6de3ba960 100644 --- a/sys/dev/i2o/iopspvar.h +++ b/sys/dev/i2o/iopspvar.h @@ -1,7 +1,7 @@ -/* $NetBSD: iopspvar.h,v 1.6 2003/06/13 02:33:09 thorpej Exp $ */ +/* $NetBSD: iopspvar.h,v 1.7 2007/06/16 12:32:12 ad Exp $ */ /*- - * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. + * Copyright (c) 2000, 2001, 2007 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -47,7 +47,6 @@ #define IOPSP_TID_ABSENT 0x0000 /* Device is absent */ #define IOPSP_TID_INUSE 0xffff /* Device in use by another module */ -#ifdef I2OVERBOSE struct iopsp_target { u_int8_t it_width; u_int8_t it_syncrate; @@ -55,7 +54,6 @@ struct iopsp_target { u_int8_t it_flags; }; #define IT_PRESENT 0x01 /* Target is present */ -#endif struct iopsp_softc { struct device sc_dv; /* Generic device data */ @@ -65,9 +63,7 @@ struct iopsp_softc { u_short *sc_tidmap; /* Target/LUN -> TID map */ u_int sc_chgind; /* Last LCT change # */ int sc_openings; /* # command openings */ -#ifdef I2OVERBOSE struct iopsp_target *sc_targetmap; /* Target information */ -#endif }; #endif /* !_I2O_IOPSPVAR_H_ */ diff --git a/sys/dev/i2o/iopvar.h b/sys/dev/i2o/iopvar.h index e1ddec472d1..26acb7c7db2 100644 --- a/sys/dev/i2o/iopvar.h +++ b/sys/dev/i2o/iopvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: iopvar.h,v 1.18 2007/03/04 06:01:48 christos Exp $ */ +/* $NetBSD: iopvar.h,v 1.19 2007/06/16 12:32:13 ad Exp $ */ /*- * Copyright (c) 2000, 2001, 2002, 2007 The NetBSD Foundation, Inc. @@ -62,6 +62,7 @@ struct iop_msg { u_int im_tctx; /* Transaction context */ void *im_dvcontext; /* Un*x device context */ struct i2o_reply *im_rb; /* Reply buffer */ + kcondvar_t im_cv; /* Notifier */ u_int im_reqstatus; /* Status from reply */ u_int im_detstatus; /* Detailed status code */ struct iop_xfer im_xfer[IOP_MAX_MSG_XFERS]; @@ -87,6 +88,7 @@ struct iop_initiator { void (*ii_adjqparam)(struct device *, int); struct device *ii_dv; + kcondvar_t ii_cv; int ii_flags; int ii_ictx; /* Initiator context */ int ii_tid; @@ -120,6 +122,7 @@ struct iop_softc { struct iop_msg *sc_ims; /* Message wrappers */ SLIST_HEAD(, iop_msg) sc_im_freelist; /* Free wrapper list */ + kmutex_t sc_intrlock; /* Interrupt level lock */ bus_dmamap_t sc_rep_dmamap; /* Reply frames DMA map */ int sc_rep_size; /* Reply frames size */ diff --git a/sys/dev/i2o/ld_iop.c b/sys/dev/i2o/ld_iop.c index 483a9a9c44a..e57f0acdb27 100644 --- a/sys/dev/i2o/ld_iop.c +++ b/sys/dev/i2o/ld_iop.c @@ -1,4 +1,4 @@ -/* $NetBSD: ld_iop.c,v 1.23 2006/11/16 01:32:50 christos Exp $ */ +/* $NetBSD: ld_iop.c,v 1.24 2007/06/16 12:32:13 ad Exp $ */ /*- * Copyright (c) 2000, 2001 The NetBSD Foundation, Inc. @@ -43,9 +43,8 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.23 2006/11/16 01:32:50 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ld_iop.c,v 1.24 2007/06/16 12:32:13 ad Exp $"); -#include "opt_i2o.h" #include "rnd.h" #include <sys/param.h> @@ -96,7 +95,6 @@ static void ld_iop_unconfig(struct ld_iop_softc *, int); CFATTACH_DECL(ld_iop, sizeof(struct ld_iop_softc), ld_iop_match, ld_iop_attach, ld_iop_detach, NULL); -#ifdef I2OVERBOSE static const char * const ld_iop_errors[] = { "success", "media error", @@ -114,7 +112,6 @@ static const char * const ld_iop_errors[] = { "volume changed, waiting for acknowledgement", "timeout", }; -#endif static int ld_iop_match(struct device *parent, struct cfdata *match, @@ -296,7 +293,6 @@ static void ld_iop_unconfig(struct ld_iop_softc *sc, int evreg) { struct iop_softc *iop; - int s; iop = (struct iop_softc *)device_parent(&sc->sc_ld.sc_dv); @@ -310,18 +306,18 @@ ld_iop_unconfig(struct ld_iop_softc *sc, int evreg) * Note that some adapters won't reply to this (XXX We * should check the event capabilities). */ + mutex_spin_enter(&iop->sc_intrlock); sc->sc_flags &= ~LD_IOP_NEW_EVTMASK; + mutex_spin_exit(&iop->sc_intrlock); + iop_util_eventreg(iop, &sc->sc_eventii, I2O_EVENT_GEN_EVENT_MASK_MODIFIED); - s = splbio(); - if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0) - tsleep(&sc->sc_eventii, PRIBIO, "ld_iopevt", hz * 5); - splx(s); -#ifdef I2ODEBUG + + mutex_spin_enter(&iop->sc_intrlock); if ((sc->sc_flags & LD_IOP_NEW_EVTMASK) == 0) - printf("%s: didn't reply to event unregister", - sc->sc_ld.sc_dv.dv_xname); -#endif + cv_timedwait(&sc->sc_eventii.ii_cv, + &iop->sc_intrlock, hz * 5); + mutex_spin_exit(&iop->sc_intrlock); } iop_initiator_unregister(iop, &sc->sc_eventii); @@ -475,7 +471,7 @@ ld_iop_flush(struct ld_softc *ld) mf.msgtctx = im->im_tctx; mf.flags = 1 << 16; /* time multiplier */ - /* XXX Aincent disks will return an error here. */ + /* Aincent disks will return an error here. */ rv = iop_msg_post(iop, im, &mf, LD_IOP_TIMEOUT * 2); iop_msg_free(iop, im); return (rv); @@ -489,9 +485,7 @@ ld_iop_intr(struct device *dv, struct iop_msg *im, void *reply) struct ld_iop_softc *sc; struct iop_softc *iop; int err, detail; -#ifdef I2OVERBOSE const char *errstr; -#endif rb = reply; bp = im->im_dvcontext; @@ -502,15 +496,11 @@ ld_iop_intr(struct device *dv, struct iop_msg *im, void *reply) if (!err && rb->reqstatus != I2O_STATUS_SUCCESS) { detail = le16toh(rb->detail); -#ifdef I2OVERBOSE if (detail >= __arraycount(ld_iop_errors)) errstr = "<unknown>"; else errstr = ld_iop_errors[detail]; printf("%s: error 0x%04x: %s\n", dv->dv_xname, detail, errstr); -#else - printf("%s: error 0x%04x\n", dv->dv_xname, detail); -#endif err = 1; } @@ -531,6 +521,7 @@ ld_iop_intr_event(struct device *dv, struct iop_msg *im, void *reply) { struct i2o_util_event_register_reply *rb; struct ld_iop_softc *sc; + struct iop_softc *iop; u_int event; rb = reply; @@ -542,11 +533,12 @@ ld_iop_intr_event(struct device *dv, struct iop_msg *im, void *reply) sc = (struct ld_iop_softc *)dv; if (event == I2O_EVENT_GEN_EVENT_MASK_MODIFIED) { + iop = device_private(device_parent(dv)); + mutex_spin_enter(&iop->sc_intrlock); sc->sc_flags |= LD_IOP_NEW_EVTMASK; - wakeup(&sc->sc_eventii); -#ifndef I2ODEBUG + cv_broadcast(&sc->sc_eventii.ii_cv); + mutex_spin_exit(&iop->sc_intrlock); return; -#endif } printf("%s: event 0x%08x received\n", dv->dv_xname, event); |
