diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c index 7d2fac05f86..7a7b1e00b8e 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!"); + panic("mlx_work 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); - - /* - * 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 20d013609fc..17991e32dfa 100644 --- a/sys/dev/mlx/mlx_disk.c +++ b/sys/dev/mlx/mlx_disk.c @@ -48,6 +48,7 @@ #include #include +#include #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 8aa9e1a0032..673b5eb3a45 100644 --- a/sys/dev/mlx/mlx_pci.c +++ b/sys/dev/mlx/mlx_pci.c @@ -48,6 +48,7 @@ #include #include +#include #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 e287067c7cb..6843b3ef542 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 ec69b25eebc..ae1d39978d5 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; -}