summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/mlx/mlx.c94
-rw-r--r--sys/dev/mlx/mlx_disk.c4
-rw-r--r--sys/dev/mlx/mlx_pci.c1
-rw-r--r--sys/dev/mlx/mlxreg.h126
-rw-r--r--sys/dev/mlx/mlxvar.h128
5 files changed, 185 insertions, 168 deletions
diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c
index 7d2fac0..7a7b1e0 100644
--- a/sys/dev/mlx/mlx.c
+++ b/sys/dev/mlx/mlx.c
@@ -278,7 +278,7 @@ mlx_attach(struct mlx_softc *sc)
/*
* Initialise per-controller queues.
*/
- TAILQ_INIT(&sc->mlx_donecmd);
+ TAILQ_INIT(&sc->mlx_work);
TAILQ_INIT(&sc->mlx_freecmds);
bufq_init(&sc->mlx_bufq);
@@ -379,7 +379,7 @@ mlx_attach(struct mlx_softc *sc)
sc->mlx_hwid = me2->me_hardware_id;
/* print a little information about the controller and ourselves */
- device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%d, %dMB RAM\n",
+ device_printf(sc->mlx_dev, "Mylex %s, firmware %d.%02d, %dMB RAM\n",
mlx_name_controller(sc->mlx_hwid), sc->mlx_fwmajor, sc->mlx_fwminor,
me2->me_mem_size / (1024 * 1024));
free(me2, M_DEVBUF);
@@ -390,16 +390,16 @@ mlx_attach(struct mlx_softc *sc)
switch(sc->mlx_iftype) {
case MLX_IFTYPE_3:
/* XXX certify 3.52? */
- if (sc->mlx_fwminor != 51) {
- device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
- device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 only\n");
+ if (sc->mlx_fwminor < 51) {
+ device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
+ device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n");
}
break;
case MLX_IFTYPE_4:
/* XXX certify firmware versions? */
- if (sc->mlx_fwminor != 6) {
- device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is NOT SUPPORTED\n");
- device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.6 only\n");
+ if (sc->mlx_fwminor < 6) {
+ device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
+ device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n");
}
break;
default:
@@ -653,10 +653,14 @@ mlx_intr(void *arg)
int
mlx_submit_buf(struct mlx_softc *sc, struct buf *bp)
{
+ int s;
+
debug("called");
+ s = splbio();
bufq_insert_tail(&sc->mlx_bufq, bp);
sc->mlx_waitbufs++;
+ splx(s);
mlx_startio(sc);
return(0);
}
@@ -1557,7 +1561,7 @@ mlx_poll_command(struct mlx_command *mc)
} while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 10000));
if (mc->mc_status != MLX_STATUS_BUSY) {
s = splbio();
- TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
+ TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
splx(s);
return(0);
}
@@ -1581,8 +1585,10 @@ mlx_startio(struct mlx_softc *sc)
int blkcount;
int driveno;
int cmd;
+ int s;
/* spin until something prevents us from doing any work */
+ s = splbio();
for (;;) {
/* see if there's work to be done */
@@ -1599,6 +1605,7 @@ mlx_startio(struct mlx_softc *sc)
/* get the buf containing our work */
bufq_remove(&sc->mlx_bufq, bp);
sc->mlx_waitbufs--;
+ splx(s);
/* connect the buf to the command */
mc->mc_complete = mlx_completeio;
@@ -1643,7 +1650,9 @@ mlx_startio(struct mlx_softc *sc)
mc->mc_status = MLX_STATUS_WEDGED;
mlx_completeio(mc);
}
+ s = splbio();
}
+ splx(s);
}
/********************************************************************************
@@ -1881,7 +1890,7 @@ mlx_start(struct mlx_command *mc)
/* save the slot number as ident so we can handle this command when complete */
mc->mc_mailbox[0x1] = mc->mc_slot;
- /* set impossible status so that a woken sleeper can tell the command is in progress */
+ /* mark the command as currently being processed */
mc->mc_status = MLX_STATUS_BUSY;
/* assume we don't collect any completed commands */
@@ -1890,7 +1899,11 @@ mlx_start(struct mlx_command *mc)
/* spin waiting for the mailbox */
for (i = 100000, done = 0; (i > 0) && !done; i--) {
s = splbio();
- done = sc->mlx_tryqueue(sc, mc);
+ if (sc->mlx_tryqueue(sc, mc)) {
+ done = 1;
+ /* move command to work queue */
+ TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
+ }
splx(s);
/* check for command completion while we're at it */
if (mlx_done(sc))
@@ -1931,20 +1944,17 @@ mlx_done(struct mlx_softc *sc)
debug("called");
- s = splbio();
mc = NULL;
slot = 0;
/* poll for a completed command's identifier and status */
+ s = splbio();
if (sc->mlx_findcomplete(sc, &slot, &status)) {
- mc = sc->mlx_busycmd[slot]; /* find command */
- if (mc != NULL) { /* paranoia */
+ mc = sc->mlx_busycmd[slot]; /* find command */
+ if (mc != NULL) { /* paranoia */
if (mc->mc_status == MLX_STATUS_BUSY) {
mc->mc_status = status; /* save status */
- /* move completed command to 'done' queue */
- TAILQ_INSERT_TAIL(&sc->mlx_donecmd, mc, mc_link);
-
/* free slot for reuse */
sc->mlx_busycmd[slot] = NULL;
sc->mlx_busycmds--;
@@ -1981,35 +1991,40 @@ mlx_complete(struct mlx_softc *sc)
count = 0;
/* scan the list of done commands */
- mc = TAILQ_FIRST(&sc->mlx_donecmd);
+ mc = TAILQ_FIRST(&sc->mlx_work);
while (mc != NULL) {
nc = TAILQ_NEXT(mc, mc_link);
/* XXX this is slightly bogus */
if (count++ > (sc->mlx_maxiop * 2))
- panic("mlx_donecmd list corrupt!");
-
- /*
- * Does the command have a completion handler?
- */
- if (mc->mc_complete != NULL) {
- /* remove from list and give to handler */
- TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
- mc->mc_complete(mc);
+ panic("mlx_work list corrupt!");
- /*
- * Is there a sleeper waiting on this command?
- */
- } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */
-
- /* remove from list and wake up sleeper */
- TAILQ_REMOVE(&sc->mlx_donecmd, mc, mc_link);
- wakeup_one(mc->mc_private);
+ /* Skip commands that are still busy */
+ if (mc->mc_status != MLX_STATUS_BUSY) {
+
/*
- * Leave the command for a caller that's polling for it.
- */
- } else {
+ * Does the command have a completion handler?
+ */
+ if (mc->mc_complete != NULL) {
+ /* remove from list and give to handler */
+ TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
+ mc->mc_complete(mc);
+
+ /*
+ * Is there a sleeper waiting on this command?
+ */
+ } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */
+
+ /* remove from list and wake up sleeper */
+ TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
+ wakeup_one(mc->mc_private);
+
+ /*
+ * Leave the command for a caller that's polling for it.
+ */
+ } else {
+ }
}
mc = nc;
}
@@ -2356,6 +2371,9 @@ mlx_name_controller(u_int32_t hwid)
case 0x11:
submodel = "PJ";
break;
+ case 0x16:
+ submodel = "PTL";
+ break;
default:
sprintf(smbuf, " model 0x%x", hwid & 0xff);
submodel = smbuf;
diff --git a/sys/dev/mlx/mlx_disk.c b/sys/dev/mlx/mlx_disk.c
index 20d0136..17991e3 100644
--- a/sys/dev/mlx/mlx_disk.c
+++ b/sys/dev/mlx/mlx_disk.c
@@ -48,6 +48,7 @@
#include <dev/mlx/mlxio.h>
#include <dev/mlx/mlxvar.h>
+#include <dev/mlx/mlxreg.h>
#if 0
#define debug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args)
@@ -174,7 +175,6 @@ static void
mlxd_strategy(struct buf *bp)
{
struct mlxd_softc *sc = (struct mlxd_softc *)bp->b_dev->si_drv1;
- int s;
debug("called");
@@ -194,10 +194,8 @@ mlxd_strategy(struct buf *bp)
if (bp->b_bcount == 0)
goto done;
- s = splbio();
devstat_start_transaction(&sc->mlxd_stats);
mlx_submit_buf(sc->mlxd_controller, bp);
- splx(s);
return;
bad:
diff --git a/sys/dev/mlx/mlx_pci.c b/sys/dev/mlx/mlx_pci.c
index 8aa9e1a..673b5eb 100644
--- a/sys/dev/mlx/mlx_pci.c
+++ b/sys/dev/mlx/mlx_pci.c
@@ -48,6 +48,7 @@
#include <dev/mlx/mlxio.h>
#include <dev/mlx/mlxvar.h>
+#include <dev/mlx/mlxreg.h>
#if 0
#define debug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args)
diff --git a/sys/dev/mlx/mlxreg.h b/sys/dev/mlx/mlxreg.h
index e287067..6843b3e 100644
--- a/sys/dev/mlx/mlxreg.h
+++ b/sys/dev/mlx/mlxreg.h
@@ -26,6 +26,11 @@
* $FreeBSD$
*/
+#define MLX_CFG_BASE0 0x10 /* first region */
+#define MLX_CFG_BASE1 0x14 /* second region (type 3 only) */
+
+#define MLX_BLKSIZE 512 /* fixed feature */
+
/*
* Selected command codes.
*/
@@ -245,3 +250,124 @@ struct mlx_rebuild_stat /* MLX_CMD_REBUILDSTAT */
u_int32_t rb_remaining;
} __attribute__ ((packed));
+/*
+ * Inlines to build various command structures
+ */
+static __inline void
+mlx_make_type1(struct mlx_command *mc,
+ u_int8_t code,
+ u_int16_t f1,
+ u_int32_t f2,
+ u_int8_t f3,
+ u_int32_t f4,
+ u_int8_t f5)
+{
+ mc->mc_mailbox[0x0] = code;
+ mc->mc_mailbox[0x2] = f1 & 0xff;
+ mc->mc_mailbox[0x3] = (((f2 >> 24) & 0x3) << 6) | ((f1 >> 8) & 0x3f);
+ mc->mc_mailbox[0x4] = f2 & 0xff;
+ mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
+ mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
+ mc->mc_mailbox[0x7] = f3;
+ mc->mc_mailbox[0x8] = f4 & 0xff;
+ mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
+ mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
+ mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
+ mc->mc_mailbox[0xc] = f5;
+}
+
+static __inline void
+mlx_make_type2(struct mlx_command *mc,
+ u_int8_t code,
+ u_int8_t f1,
+ u_int8_t f2,
+ u_int8_t f3,
+ u_int8_t f4,
+ u_int8_t f5,
+ u_int8_t f6,
+ u_int32_t f7,
+ u_int8_t f8)
+{
+ mc->mc_mailbox[0x0] = code;
+ mc->mc_mailbox[0x2] = f1;
+ mc->mc_mailbox[0x3] = f2;
+ mc->mc_mailbox[0x4] = f3;
+ mc->mc_mailbox[0x5] = f4;
+ mc->mc_mailbox[0x6] = f5;
+ mc->mc_mailbox[0x7] = f6;
+ mc->mc_mailbox[0x8] = f7 & 0xff;
+ mc->mc_mailbox[0x9] = (f7 >> 8) & 0xff;
+ mc->mc_mailbox[0xa] = (f7 >> 16) & 0xff;
+ mc->mc_mailbox[0xb] = (f7 >> 24) & 0xff;
+ mc->mc_mailbox[0xc] = f8;
+}
+
+static __inline void
+mlx_make_type3(struct mlx_command *mc,
+ u_int8_t code,
+ u_int8_t f1,
+ u_int8_t f2,
+ u_int16_t f3,
+ u_int8_t f4,
+ u_int8_t f5,
+ u_int32_t f6,
+ u_int8_t f7)
+{
+ mc->mc_mailbox[0x0] = code;
+ mc->mc_mailbox[0x2] = f1;
+ mc->mc_mailbox[0x3] = f2;
+ mc->mc_mailbox[0x4] = f3 & 0xff;
+ mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
+ mc->mc_mailbox[0x6] = f4;
+ mc->mc_mailbox[0x7] = f5;
+ mc->mc_mailbox[0x8] = f6 & 0xff;
+ mc->mc_mailbox[0x9] = (f6 >> 8) & 0xff;
+ mc->mc_mailbox[0xa] = (f6 >> 16) & 0xff;
+ mc->mc_mailbox[0xb] = (f6 >> 24) & 0xff;
+ mc->mc_mailbox[0xc] = f7;
+}
+
+static __inline void
+mlx_make_type4(struct mlx_command *mc,
+ u_int8_t code,
+ u_int16_t f1,
+ u_int32_t f2,
+ u_int32_t f3,
+ u_int8_t f4)
+{
+ mc->mc_mailbox[0x0] = code;
+ mc->mc_mailbox[0x2] = f1 & 0xff;
+ mc->mc_mailbox[0x3] = (f1 >> 8) & 0xff;
+ mc->mc_mailbox[0x4] = f2 & 0xff;
+ mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
+ mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
+ mc->mc_mailbox[0x7] = (f2 >> 24) & 0xff;
+ mc->mc_mailbox[0x8] = f3 & 0xff;
+ mc->mc_mailbox[0x9] = (f3 >> 8) & 0xff;
+ mc->mc_mailbox[0xa] = (f3 >> 16) & 0xff;
+ mc->mc_mailbox[0xb] = (f3 >> 24) & 0xff;
+ mc->mc_mailbox[0xc] = f4;
+}
+
+static __inline void
+mlx_make_type5(struct mlx_command *mc,
+ u_int8_t code,
+ u_int8_t f1,
+ u_int8_t f2,
+ u_int32_t f3,
+ u_int32_t f4,
+ u_int8_t f5)
+{
+ mc->mc_mailbox[0x0] = code;
+ mc->mc_mailbox[0x2] = f1;
+ mc->mc_mailbox[0x3] = f2;
+ mc->mc_mailbox[0x4] = f3 & 0xff;
+ mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
+ mc->mc_mailbox[0x6] = (f3 >> 16) & 0xff;
+ mc->mc_mailbox[0x7] = (f3 >> 24) & 0xff;
+ mc->mc_mailbox[0x8] = f4 & 0xff;
+ mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
+ mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
+ mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
+ mc->mc_mailbox[0xc] = f5;
+}
diff --git a/sys/dev/mlx/mlxvar.h b/sys/dev/mlx/mlxvar.h
index ec69b25..ae1d399 100644
--- a/sys/dev/mlx/mlxvar.h
+++ b/sys/dev/mlx/mlxvar.h
@@ -34,13 +34,8 @@
#define MLX_NSEG 32 /* max scatter/gather segments we use */
#define MLX_NSLOTS 256 /* max number of command slots */
-#define MLX_CFG_BASE0 0x10 /* first region */
-#define MLX_CFG_BASE1 0x14 /* second region (type 3 only) */
-
#define MLX_MAXDRIVES 32
-#define MLX_BLKSIZE 512 /* fixed feature */
-
/*
* Structure describing a System Drive as attached to the controller.
*/
@@ -121,7 +116,7 @@ struct mlx_softc
/* controller queues and arrays */
TAILQ_HEAD(, mlx_command) mlx_freecmds; /* command structures available for reuse */
- TAILQ_HEAD(, mlx_command) mlx_donecmd; /* commands waiting for completion processing */
+ TAILQ_HEAD(, mlx_command) mlx_work; /* active commands */
struct mlx_command *mlx_busycmd[MLX_NSLOTS]; /* busy commands */
int mlx_busycmds; /* count of busy commands */
struct mlx_sysdrive mlx_sysdrive[MLX_MAXDRIVES]; /* system drives */
@@ -202,125 +197,4 @@ extern int mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_
caddr_t addr, int32_t flag, struct proc *p);
extern void mlxd_intr(void *data);
-/*
- * Inlines to build various command structures
- */
-static __inline void
-mlx_make_type1(struct mlx_command *mc,
- u_int8_t code,
- u_int16_t f1,
- u_int32_t f2,
- u_int8_t f3,
- u_int32_t f4,
- u_int8_t f5)
-{
- mc->mc_mailbox[0x0] = code;
- mc->mc_mailbox[0x2] = f1 & 0xff;
- mc->mc_mailbox[0x3] = (((f2 >> 24) & 0x3) << 6) | ((f1 >> 8) & 0x3f);
- mc->mc_mailbox[0x4] = f2 & 0xff;
- mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
- mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
- mc->mc_mailbox[0x7] = f3;
- mc->mc_mailbox[0x8] = f4 & 0xff;
- mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
- mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
- mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
- mc->mc_mailbox[0xc] = f5;
-}
-
-static __inline void
-mlx_make_type2(struct mlx_command *mc,
- u_int8_t code,
- u_int8_t f1,
- u_int8_t f2,
- u_int8_t f3,
- u_int8_t f4,
- u_int8_t f5,
- u_int8_t f6,
- u_int32_t f7,
- u_int8_t f8)
-{
- mc->mc_mailbox[0x0] = code;
- mc->mc_mailbox[0x2] = f1;
- mc->mc_mailbox[0x3] = f2;
- mc->mc_mailbox[0x4] = f3;
- mc->mc_mailbox[0x5] = f4;
- mc->mc_mailbox[0x6] = f5;
- mc->mc_mailbox[0x7] = f6;
- mc->mc_mailbox[0x8] = f7 & 0xff;
- mc->mc_mailbox[0x9] = (f7 >> 8) & 0xff;
- mc->mc_mailbox[0xa] = (f7 >> 16) & 0xff;
- mc->mc_mailbox[0xb] = (f7 >> 24) & 0xff;
- mc->mc_mailbox[0xc] = f8;
-}
-
-static __inline void
-mlx_make_type3(struct mlx_command *mc,
- u_int8_t code,
- u_int8_t f1,
- u_int8_t f2,
- u_int16_t f3,
- u_int8_t f4,
- u_int8_t f5,
- u_int32_t f6,
- u_int8_t f7)
-{
- mc->mc_mailbox[0x0] = code;
- mc->mc_mailbox[0x2] = f1;
- mc->mc_mailbox[0x3] = f2;
- mc->mc_mailbox[0x4] = f3 & 0xff;
- mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
- mc->mc_mailbox[0x6] = f4;
- mc->mc_mailbox[0x7] = f5;
- mc->mc_mailbox[0x8] = f6 & 0xff;
- mc->mc_mailbox[0x9] = (f6 >> 8) & 0xff;
- mc->mc_mailbox[0xa] = (f6 >> 16) & 0xff;
- mc->mc_mailbox[0xb] = (f6 >> 24) & 0xff;
- mc->mc_mailbox[0xc] = f7;
-}
-
-static __inline void
-mlx_make_type4(struct mlx_command *mc,
- u_int8_t code,
- u_int16_t f1,
- u_int32_t f2,
- u_int32_t f3,
- u_int8_t f4)
-{
- mc->mc_mailbox[0x0] = code;
- mc->mc_mailbox[0x2] = f1 & 0xff;
- mc->mc_mailbox[0x3] = (f1 >> 8) & 0xff;
- mc->mc_mailbox[0x4] = f2 & 0xff;
- mc->mc_mailbox[0x5] = (f2 >> 8) & 0xff;
- mc->mc_mailbox[0x6] = (f2 >> 16) & 0xff;
- mc->mc_mailbox[0x7] = (f2 >> 24) & 0xff;
- mc->mc_mailbox[0x8] = f3 & 0xff;
- mc->mc_mailbox[0x9] = (f3 >> 8) & 0xff;
- mc->mc_mailbox[0xa] = (f3 >> 16) & 0xff;
- mc->mc_mailbox[0xb] = (f3 >> 24) & 0xff;
- mc->mc_mailbox[0xc] = f4;
-}
-
-static __inline void
-mlx_make_type5(struct mlx_command *mc,
- u_int8_t code,
- u_int8_t f1,
- u_int8_t f2,
- u_int32_t f3,
- u_int32_t f4,
- u_int8_t f5)
-{
- mc->mc_mailbox[0x0] = code;
- mc->mc_mailbox[0x2] = f1;
- mc->mc_mailbox[0x3] = f2;
- mc->mc_mailbox[0x4] = f3 & 0xff;
- mc->mc_mailbox[0x5] = (f3 >> 8) & 0xff;
- mc->mc_mailbox[0x6] = (f3 >> 16) & 0xff;
- mc->mc_mailbox[0x7] = (f3 >> 24) & 0xff;
- mc->mc_mailbox[0x8] = f4 & 0xff;
- mc->mc_mailbox[0x9] = (f4 >> 8) & 0xff;
- mc->mc_mailbox[0xa] = (f4 >> 16) & 0xff;
- mc->mc_mailbox[0xb] = (f4 >> 24) & 0xff;
- mc->mc_mailbox[0xc] = f5;
-}
OpenPOWER on IntegriCloud