summaryrefslogtreecommitdiff
path: root/sys/dev/i2o
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2007-06-16 12:32:12 +0000
committerad <ad@NetBSD.org>2007-06-16 12:32:12 +0000
commite5bca80a53681efbb44dbeeb018a534b735d3d1f (patch)
treed447f30d6e16e12c0eb42dd8c0778f34b0f8d611 /sys/dev/i2o
parent62ad7214e7dd20845844706f0141290a6891262a (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.c6
-rw-r--r--sys/dev/i2o/files.i2o4
-rw-r--r--sys/dev/i2o/iop.c177
-rw-r--r--sys/dev/i2o/iopl.c5
-rw-r--r--sys/dev/i2o/iopsp.c53
-rw-r--r--sys/dev/i2o/iopspvar.h8
-rw-r--r--sys/dev/i2o/iopvar.h5
-rw-r--r--sys/dev/i2o/ld_iop.c40
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);