Home | History | Annotate | Line # | Download | only in ic
mlx.c revision 1.56
      1 /*	$NetBSD: mlx.c,v 1.56 2008/06/08 12:43:51 tsutsui Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Andrew Doran.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*-
     33  * Copyright (c) 1999 Michael Smith
     34  * All rights reserved.
     35  *
     36  * Redistribution and use in source and binary forms, with or without
     37  * modification, are permitted provided that the following conditions
     38  * are met:
     39  * 1. Redistributions of source code must retain the above copyright
     40  *    notice, this list of conditions and the following disclaimer.
     41  * 2. Redistributions in binary form must reproduce the above copyright
     42  *    notice, this list of conditions and the following disclaimer in the
     43  *    documentation and/or other materials provided with the distribution.
     44  *
     45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     55  * SUCH DAMAGE.
     56  *
     57  * from FreeBSD: mlx.c,v 1.14.2.3 2000/08/04 06:52:50 msmith Exp
     58  */
     59 
     60 /*
     61  * Driver for the Mylex DAC960 family of RAID controllers.
     62  *
     63  * TODO:
     64  *
     65  * o Test and enable channel pause.
     66  * o SCSI pass-through.
     67  */
     68 
     69 #include <sys/cdefs.h>
     70 __KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.56 2008/06/08 12:43:51 tsutsui Exp $");
     71 
     72 #include "ld.h"
     73 
     74 #include <sys/param.h>
     75 #include <sys/systm.h>
     76 #include <sys/kernel.h>
     77 #include <sys/device.h>
     78 #include <sys/queue.h>
     79 #include <sys/proc.h>
     80 #include <sys/buf.h>
     81 #include <sys/bufq.h>
     82 #include <sys/endian.h>
     83 #include <sys/malloc.h>
     84 #include <sys/conf.h>
     85 #include <sys/kthread.h>
     86 #include <sys/disk.h>
     87 #include <sys/kauth.h>
     88 
     89 #include <machine/vmparam.h>
     90 #include <sys/bus.h>
     91 
     92 #include <uvm/uvm_extern.h>
     93 
     94 #include <dev/ldvar.h>
     95 
     96 #include <dev/ic/mlxreg.h>
     97 #include <dev/ic/mlxio.h>
     98 #include <dev/ic/mlxvar.h>
     99 
    100 #include "locators.h"
    101 
    102 #define	MLX_TIMEOUT	60
    103 
    104 #ifdef DIAGNOSTIC
    105 #define	DPRINTF(x)	printf x
    106 #else
    107 #define	DPRINTF(x)
    108 #endif
    109 
    110 static void	mlx_adjqparam(struct mlx_softc *, int, int);
    111 static int	mlx_ccb_submit(struct mlx_softc *, struct mlx_ccb *);
    112 static int	mlx_check(struct mlx_softc *, int);
    113 static void	mlx_configure(struct mlx_softc *, int);
    114 static void	mlx_describe(struct mlx_softc *);
    115 static void	*mlx_enquire(struct mlx_softc *, int, size_t,
    116 			     void (*)(struct mlx_ccb *), int);
    117 static int	mlx_fw_message(struct mlx_softc *, int, int, int);
    118 static void	mlx_pause_action(struct mlx_softc *);
    119 static void	mlx_pause_done(struct mlx_ccb *);
    120 static void	mlx_periodic(struct mlx_softc *);
    121 static void	mlx_periodic_enquiry(struct mlx_ccb *);
    122 static void	mlx_periodic_eventlog_poll(struct mlx_softc *);
    123 static void	mlx_periodic_eventlog_respond(struct mlx_ccb *);
    124 static void	mlx_periodic_rebuild(struct mlx_ccb *);
    125 static void	mlx_periodic_thread(void *);
    126 static int	mlx_print(void *, const char *);
    127 static int	mlx_rebuild(struct mlx_softc *, int, int);
    128 static void	mlx_shutdown(void *);
    129 static int	mlx_user_command(struct mlx_softc *, struct mlx_usercommand *);
    130 
    131 dev_type_open(mlxopen);
    132 dev_type_close(mlxclose);
    133 dev_type_ioctl(mlxioctl);
    134 
    135 const struct cdevsw mlx_cdevsw = {
    136 	mlxopen, mlxclose, noread, nowrite, mlxioctl,
    137 	nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
    138 };
    139 
    140 extern struct	cfdriver mlx_cd;
    141 static struct	lwp *mlx_periodic_lwp;
    142 static void	*mlx_sdh;
    143 
    144 static struct {
    145 	int	hwid;
    146 	const char	*name;
    147 } const mlx_cname[] = {
    148 	{ 0x00, "960E/960M" },
    149 	{ 0x01, "960P/PD" },
    150 	{ 0x02,	"960PL" },
    151 	{ 0x10, "960PG" },
    152 	{ 0x11, "960PJ" },
    153 	{ 0x12, "960PR" },
    154 	{ 0x13,	"960PT" },
    155 	{ 0x14, "960PTL0" },
    156 	{ 0x15, "960PRL" },
    157 	{ 0x16, "960PTL1" },
    158 	{ 0x20, "1164PVX" },
    159 };
    160 
    161 static const char * const mlx_sense_msgs[] = {
    162 	"because write recovery failed",
    163 	"because of SCSI bus reset failure",
    164 	"because of double check condition",
    165 	"because it was removed",
    166 	"because of gross error on SCSI chip",
    167 	"because of bad tag returned from drive",
    168 	"because of timeout on SCSI command",
    169 	"because of reset SCSI command issued from system",
    170 	"because busy or parity error count exceeded limit",
    171 	"because of 'kill drive' command from system",
    172 	"because of selection timeout",
    173 	"due to SCSI phase sequence error",
    174 	"due to unknown status"
    175 };
    176 
    177 static const char * const mlx_status_msgs[] = {
    178 	"normal completion",				/* 0 */
    179 	"irrecoverable data error",			/* 1 */
    180 	"drive does not exist, or is offline",		/* 2 */
    181 	"attempt to write beyond end of drive",		/* 3 */
    182 	"bad data encountered",				/* 4 */
    183 	"invalid log entry request",			/* 5 */
    184 	"attempt to rebuild online drive",		/* 6 */
    185 	"new disk failed during rebuild",		/* 7 */
    186 	"invalid channel/target",			/* 8 */
    187 	"rebuild/check already in progress",		/* 9 */
    188 	"one or more disks are dead",			/* 10 */
    189 	"invalid or non-redundant drive",		/* 11 */
    190 	"channel is busy",				/* 12 */
    191 	"channel is not stopped",			/* 13 */
    192 	"rebuild successfully terminated",		/* 14 */
    193 	"unsupported command",				/* 15 */
    194 	"check condition received",			/* 16 */
    195 	"device is busy",				/* 17 */
    196 	"selection or command timeout",			/* 18 */
    197 	"command terminated abnormally",		/* 19 */
    198 	"controller wedged",				/* 20 */
    199 	"software timeout",				/* 21 */
    200 	"command busy (?)",				/* 22 */
    201 };
    202 
    203 static struct {
    204 	u_char	command;
    205 	u_char	msg;		/* Index into mlx_status_msgs[]. */
    206 	u_short	status;
    207 } const mlx_msgs[] = {
    208 	{ MLX_CMD_READSG,	1,	0x0001 },
    209 	{ MLX_CMD_READSG,	1,	0x0002 },
    210 	{ MLX_CMD_READSG,	3,	0x0105 },
    211 	{ MLX_CMD_READSG,	4,	0x010c },
    212 	{ MLX_CMD_WRITESG,	1,	0x0001 },
    213 	{ MLX_CMD_WRITESG,	1,	0x0002 },
    214 	{ MLX_CMD_WRITESG,	3,	0x0105 },
    215 	{ MLX_CMD_READSG_OLD,	1,	0x0001 },
    216 	{ MLX_CMD_READSG_OLD,	1,	0x0002 },
    217 	{ MLX_CMD_READSG_OLD,	3,	0x0105 },
    218 	{ MLX_CMD_WRITESG_OLD,	1,	0x0001 },
    219 	{ MLX_CMD_WRITESG_OLD,	1,	0x0002 },
    220 	{ MLX_CMD_WRITESG_OLD,	3,	0x0105 },
    221 	{ MLX_CMD_LOGOP,	5,	0x0105 },
    222 	{ MLX_CMD_REBUILDASYNC,	6,	0x0002 },
    223 	{ MLX_CMD_REBUILDASYNC,	7,	0x0004 },
    224 	{ MLX_CMD_REBUILDASYNC,	8,	0x0105 },
    225 	{ MLX_CMD_REBUILDASYNC,	9,	0x0106 },
    226 	{ MLX_CMD_REBUILDASYNC,	14,	0x0107 },
    227 	{ MLX_CMD_CHECKASYNC,	10,	0x0002 },
    228 	{ MLX_CMD_CHECKASYNC,	11,	0x0105 },
    229 	{ MLX_CMD_CHECKASYNC,	9,	0x0106 },
    230 	{ MLX_CMD_STOPCHANNEL,	12,	0x0106 },
    231 	{ MLX_CMD_STOPCHANNEL,	8,	0x0105 },
    232 	{ MLX_CMD_STARTCHANNEL,	13,	0x0005 },
    233 	{ MLX_CMD_STARTCHANNEL,	8,	0x0105 },
    234 	{ MLX_CMD_DIRECT_CDB,	16,	0x0002 },
    235 	{ MLX_CMD_DIRECT_CDB,	17,	0x0008 },
    236 	{ MLX_CMD_DIRECT_CDB,	18,	0x000e },
    237 	{ MLX_CMD_DIRECT_CDB,	19,	0x000f },
    238 	{ MLX_CMD_DIRECT_CDB,	8,	0x0105 },
    239 
    240 	{ 0,			20,	MLX_STATUS_WEDGED },
    241 	{ 0,			21,	MLX_STATUS_LOST },
    242 	{ 0,			22,	MLX_STATUS_BUSY },
    243 
    244 	{ 0,			14,	0x0104 },
    245 };
    246 
    247 /*
    248  * Initialise the controller and our interface.
    249  */
    250 void
    251 mlx_init(struct mlx_softc *mlx, const char *intrstr)
    252 {
    253 	struct mlx_ccb *mc;
    254 	struct mlx_enquiry_old *meo;
    255 	struct mlx_enquiry2 *me2;
    256 	struct mlx_cinfo *ci;
    257 	int rv, fwminor, hscode, hserr, hsparam1, hsparam2, hsmsg;
    258 	int size, i, rseg;
    259 	const char *wantfwstr;
    260 	bus_dma_segment_t seg;
    261 
    262 	SIMPLEQ_INIT(&mlx->mlx_ccb_queue);
    263 	SLIST_INIT(&mlx->mlx_ccb_freelist);
    264 	TAILQ_INIT(&mlx->mlx_ccb_worklist);
    265 
    266 	if (intrstr != NULL)
    267 		printf("%s: interrupting at %s\n", device_xname(&mlx->mlx_dv),
    268 		    intrstr);
    269 
    270 	/*
    271 	 * Allocate the scatter/gather lists.
    272 	 */
    273         size = MLX_SGL_SIZE * MLX_MAX_QUEUECNT;
    274 
    275 	if ((rv = bus_dmamem_alloc(mlx->mlx_dmat, size, PAGE_SIZE, 0, &seg, 1,
    276 	    &rseg, BUS_DMA_NOWAIT)) != 0) {
    277 		aprint_error_dev(&mlx->mlx_dv, "unable to allocate sglists, rv = %d\n", rv);
    278 		return;
    279 	}
    280 
    281 	if ((rv = bus_dmamem_map(mlx->mlx_dmat, &seg, rseg, size,
    282 	    (void **)&mlx->mlx_sgls,
    283 	    BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
    284 		aprint_error_dev(&mlx->mlx_dv, "unable to map sglists, rv = %d\n", rv);
    285 		return;
    286 	}
    287 
    288 	if ((rv = bus_dmamap_create(mlx->mlx_dmat, size, 1, size, 0,
    289 	    BUS_DMA_NOWAIT, &mlx->mlx_dmamap)) != 0) {
    290 		aprint_error_dev(&mlx->mlx_dv, "unable to create sglist DMA map, rv = %d\n", rv);
    291 		return;
    292 	}
    293 
    294 	if ((rv = bus_dmamap_load(mlx->mlx_dmat, mlx->mlx_dmamap,
    295 	    mlx->mlx_sgls, size, NULL, BUS_DMA_NOWAIT)) != 0) {
    296 		aprint_error_dev(&mlx->mlx_dv, "unable to load sglist DMA map, rv = %d\n", rv);
    297 		return;
    298 	}
    299 
    300 	mlx->mlx_sgls_paddr = mlx->mlx_dmamap->dm_segs[0].ds_addr;
    301 	memset(mlx->mlx_sgls, 0, size);
    302 
    303 	/*
    304 	 * Allocate and initialize the CCBs.
    305 	 */
    306 	mc = malloc(sizeof(*mc) * MLX_MAX_QUEUECNT, M_DEVBUF, M_NOWAIT);
    307 	mlx->mlx_ccbs = mc;
    308 
    309 	for (i = 0; i < MLX_MAX_QUEUECNT; i++, mc++) {
    310 		mc->mc_ident = i;
    311 		rv = bus_dmamap_create(mlx->mlx_dmat, MLX_MAX_XFER,
    312 		    MLX_MAX_SEGS, MLX_MAX_XFER, 0,
    313 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
    314 		    &mc->mc_xfer_map);
    315 		if (rv != 0)
    316 			break;
    317 		mlx->mlx_nccbs++;
    318 		mlx_ccb_free(mlx, mc);
    319 	}
    320 	if (mlx->mlx_nccbs != MLX_MAX_QUEUECNT)
    321 		printf("%s: %d/%d CCBs usable\n", device_xname(&mlx->mlx_dv),
    322 		    mlx->mlx_nccbs, MLX_MAX_QUEUECNT);
    323 
    324 	/* Disable interrupts before we start talking to the controller */
    325 	(*mlx->mlx_intaction)(mlx, 0);
    326 
    327 	/* If we've got a reset routine, then reset the controller now. */
    328 	if (mlx->mlx_reset != NULL) {
    329 		printf("%s: resetting controller...\n", device_xname(&mlx->mlx_dv));
    330 		if ((*mlx->mlx_reset)(mlx) != 0) {
    331 			aprint_error_dev(&mlx->mlx_dv, "reset failed\n");
    332 			return;
    333 		}
    334 	}
    335 
    336 	/*
    337 	 * Wait for the controller to come ready, handshaking with the
    338 	 * firmware if required.  This is typically only necessary on
    339 	 * platforms where the controller BIOS does not run.
    340 	 */
    341 	hsmsg = 0;
    342 
    343 	for (;;) {
    344 		hscode = (*mlx->mlx_fw_handshake)(mlx, &hserr, &hsparam1,
    345 		    &hsparam2);
    346 		if (hscode == 0) {
    347 			if (hsmsg != 0)
    348 				printf("%s: initialization complete\n",
    349 				    device_xname(&mlx->mlx_dv));
    350 			break;
    351 		}
    352 
    353 		/* Report first time around... */
    354 		if (hsmsg == 0) {
    355 			printf("%s: initializing (may take some time)...\n",
    356 			    device_xname(&mlx->mlx_dv));
    357 			hsmsg = 1;
    358 		}
    359 
    360 		/* Did we get a real message? */
    361 		if (hscode == 2) {
    362 			hscode = mlx_fw_message(mlx, hserr, hsparam1, hsparam2);
    363 
    364 			/* Fatal initialisation error? */
    365 			if (hscode != 0)
    366 				return;
    367 		}
    368 	}
    369 
    370 	/*
    371 	 * Do quirk/feature related things.
    372 	 */
    373 	ci = &mlx->mlx_ci;
    374 
    375 	if (ci->ci_iftype > 1) {
    376 		me2 = mlx_enquire(mlx, MLX_CMD_ENQUIRY2,
    377 		    sizeof(struct mlx_enquiry2), NULL, 0);
    378 		if (me2 == NULL) {
    379 			aprint_error_dev(&mlx->mlx_dv, "ENQUIRY2 failed\n");
    380 			return;
    381 		}
    382 
    383 		ci->ci_firmware_id[0] = me2->me_firmware_id[0];
    384 		ci->ci_firmware_id[1] = me2->me_firmware_id[1];
    385 		ci->ci_firmware_id[2] = me2->me_firmware_id[2];
    386 		ci->ci_firmware_id[3] = me2->me_firmware_id[3];
    387 		ci->ci_hardware_id = me2->me_hardware_id[0];
    388 		ci->ci_mem_size = le32toh(me2->me_mem_size);
    389 		ci->ci_max_sg = le16toh(me2->me_max_sg);
    390 		ci->ci_max_commands = le16toh(me2->me_max_commands);
    391 		ci->ci_nchan = me2->me_actual_channels;
    392 
    393 		free(me2, M_DEVBUF);
    394 	}
    395 
    396 	if (ci->ci_iftype <= 2) {
    397 		/*
    398 		 * These controllers may not report the firmware version in
    399 		 * the ENQUIRY2 response, or may not even support it.
    400 		 */
    401 		meo = mlx_enquire(mlx, MLX_CMD_ENQUIRY_OLD,
    402 		    sizeof(struct mlx_enquiry_old), NULL, 0);
    403 		if (meo == NULL) {
    404 			aprint_error_dev(&mlx->mlx_dv, "ENQUIRY_OLD failed\n");
    405 			return;
    406 		}
    407 		ci->ci_firmware_id[0] = meo->me_fwmajor;
    408 		ci->ci_firmware_id[1] = meo->me_fwminor;
    409 		ci->ci_firmware_id[2] = 0;
    410 		ci->ci_firmware_id[3] = '0';
    411 
    412 		if (ci->ci_iftype == 1) {
    413 			ci->ci_hardware_id = 0;	/* XXX */
    414 			ci->ci_mem_size = 0;	/* XXX */
    415 			ci->ci_max_sg = 17;	/* XXX */
    416 			ci->ci_max_commands = meo->me_max_commands;
    417 		}
    418 
    419 		free(meo, M_DEVBUF);
    420 	}
    421 
    422 	wantfwstr = NULL;
    423 	fwminor = ci->ci_firmware_id[1];
    424 
    425 	switch (ci->ci_firmware_id[0]) {
    426 	case 2:
    427 		if (ci->ci_iftype == 1) {
    428 			if (fwminor < 14)
    429 				wantfwstr = "2.14";
    430 		} else if (fwminor < 42)
    431 			wantfwstr = "2.42";
    432 		break;
    433 
    434 	case 3:
    435 		if (fwminor < 51)
    436 			wantfwstr = "3.51";
    437 		break;
    438 
    439 	case 4:
    440 		if (fwminor < 6)
    441 			wantfwstr = "4.06";
    442 		break;
    443 
    444 	case 5:
    445 		if (fwminor < 7)
    446 			wantfwstr = "5.07";
    447 		break;
    448 	}
    449 
    450 	/* Print a little information about the controller. */
    451 	mlx_describe(mlx);
    452 
    453 	if (wantfwstr != NULL) {
    454 		printf("%s: WARNING: this f/w revision is not recommended\n",
    455 		    device_xname(&mlx->mlx_dv));
    456 		printf("%s: WARNING: use revision %s or later\n",
    457 		    device_xname(&mlx->mlx_dv), wantfwstr);
    458 	}
    459 
    460 	/* We don't (yet) know where the event log is up to. */
    461 	mlx->mlx_currevent = -1;
    462 
    463 	/* No user-requested background operation is in progress. */
    464 	mlx->mlx_bg = 0;
    465 	mlx->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
    466 
    467 	/* Set maximum number of queued commands for `regular' operations. */
    468 	mlx->mlx_max_queuecnt =
    469 	    min(ci->ci_max_commands, MLX_MAX_QUEUECNT) -
    470 	    MLX_NCCBS_CONTROL;
    471 #ifdef DIAGNOSTIC
    472 	if (mlx->mlx_max_queuecnt < MLX_NCCBS_CONTROL + MLX_MAX_DRIVES)
    473 		printf("%s: WARNING: few CCBs available\n",
    474 		    device_xname(&mlx->mlx_dv));
    475 	if (ci->ci_max_sg < MLX_MAX_SEGS) {
    476 		aprint_error_dev(&mlx->mlx_dv, "oops, not enough S/G segments\n");
    477 		return;
    478 	}
    479 #endif
    480 
    481 	/* Attach child devices and enable interrupts. */
    482 	mlx_configure(mlx, 0);
    483 	(*mlx->mlx_intaction)(mlx, 1);
    484 	mlx->mlx_flags |= MLXF_INITOK;
    485 
    486 	if (mlx_sdh == NULL) {
    487 		/*
    488 		 * Set our `shutdownhook' before we start any device
    489 		 * activity.
    490 		 */
    491 		mlx_sdh = shutdownhook_establish(mlx_shutdown, NULL);
    492 
    493 		/* Create a status monitoring thread. */
    494 		rv = kthread_create(PRI_NONE, 0, NULL, mlx_periodic_thread,
    495 		    NULL, &mlx_periodic_lwp, "mlxtask");
    496 		if (rv != 0)
    497 			printf("mlx_init: unable to create thread (%d)\n", rv);
    498 	}
    499 }
    500 
    501 /*
    502  * Tell the world about the controller.
    503  */
    504 static void
    505 mlx_describe(struct mlx_softc *mlx)
    506 {
    507 	struct mlx_cinfo *ci;
    508 	static char tbuf[80];
    509 	const char *model;
    510 	int i;
    511 
    512 	model = NULL;
    513 	ci = &mlx->mlx_ci;
    514 
    515 	for (i = 0; i < sizeof(mlx_cname) / sizeof(mlx_cname[0]); i++)
    516 		if (ci->ci_hardware_id == mlx_cname[i].hwid) {
    517 			model = mlx_cname[i].name;
    518 			break;
    519 		}
    520 
    521 	if (model == NULL) {
    522 		snprintf(tbuf, sizeof(tbuf), " model 0x%x", ci->ci_hardware_id);
    523 		model = tbuf;
    524 	}
    525 
    526 	printf("%s: DAC%s, %d channel%s, firmware %d.%02d-%c-%02d",
    527 	    device_xname(&mlx->mlx_dv), model, ci->ci_nchan,
    528 	    ci->ci_nchan > 1 ? "s" : "",
    529 	    ci->ci_firmware_id[0], ci->ci_firmware_id[1],
    530 	    ci->ci_firmware_id[3], ci->ci_firmware_id[2]);
    531 	if (ci->ci_mem_size != 0)
    532 		printf(", %dMB RAM", ci->ci_mem_size >> 20);
    533 	printf("\n");
    534 }
    535 
    536 /*
    537  * Locate disk resources and attach children to them.
    538  */
    539 static void
    540 mlx_configure(struct mlx_softc *mlx, int waitok)
    541 {
    542 	struct mlx_enquiry *me;
    543 	struct mlx_enquiry_old *meo;
    544 	struct mlx_enq_sys_drive *mes;
    545 	struct mlx_sysdrive *ms;
    546 	struct mlx_attach_args mlxa;
    547 	int i, nunits;
    548 	u_int size;
    549 	int locs[MLXCF_NLOCS];
    550 
    551 	mlx->mlx_flags |= MLXF_RESCANNING;
    552 
    553 	if (mlx->mlx_ci.ci_iftype <= 2) {
    554 		meo = mlx_enquire(mlx, MLX_CMD_ENQUIRY_OLD,
    555 		    sizeof(struct mlx_enquiry_old), NULL, waitok);
    556 		if (meo == NULL) {
    557 			aprint_error_dev(&mlx->mlx_dv, "ENQUIRY_OLD failed\n");
    558 			goto out;
    559 		}
    560 		mlx->mlx_numsysdrives = meo->me_num_sys_drvs;
    561 		free(meo, M_DEVBUF);
    562 	} else {
    563 		me = mlx_enquire(mlx, MLX_CMD_ENQUIRY,
    564 		    sizeof(struct mlx_enquiry), NULL, waitok);
    565 		if (me == NULL) {
    566 			aprint_error_dev(&mlx->mlx_dv, "ENQUIRY failed\n");
    567 			goto out;
    568 		}
    569 		mlx->mlx_numsysdrives = me->me_num_sys_drvs;
    570 		free(me, M_DEVBUF);
    571 	}
    572 
    573 	mes = mlx_enquire(mlx, MLX_CMD_ENQSYSDRIVE,
    574 	    sizeof(*mes) * MLX_MAX_DRIVES, NULL, waitok);
    575 	if (mes == NULL) {
    576 		aprint_error_dev(&mlx->mlx_dv, "error fetching drive status\n");
    577 		goto out;
    578 	}
    579 
    580 	/* Allow 1 queued command per unit while re-configuring. */
    581 	mlx_adjqparam(mlx, 1, 0);
    582 
    583 	ms = &mlx->mlx_sysdrive[0];
    584 	nunits = 0;
    585 	for (i = 0; i < MLX_MAX_DRIVES; i++, ms++) {
    586 		size = le32toh(mes[i].sd_size);
    587 		ms->ms_state = mes[i].sd_state;
    588 
    589 		/*
    590 		 * If an existing device has changed in some way (e.g. no
    591 		 * longer present) then detach it.
    592 		 */
    593 		if (ms->ms_dv != NULL && (size != ms->ms_size ||
    594 		    (mes[i].sd_raidlevel & 0xf) != ms->ms_raidlevel))
    595 			config_detach(ms->ms_dv, DETACH_FORCE);
    596 
    597 		ms->ms_size = size;
    598 		ms->ms_raidlevel = mes[i].sd_raidlevel & 0xf;
    599 		ms->ms_state = mes[i].sd_state;
    600 		ms->ms_dv = NULL;
    601 
    602 		if (i >= mlx->mlx_numsysdrives)
    603 			continue;
    604 		if (size == 0xffffffffU || size == 0)
    605 			continue;
    606 
    607 		/*
    608 		 * Attach a new device.
    609 		 */
    610 		mlxa.mlxa_unit = i;
    611 
    612 		locs[MLXCF_UNIT] = i;
    613 
    614 		ms->ms_dv = config_found_sm_loc(&mlx->mlx_dv, "mlx", locs,
    615 				&mlxa, mlx_print, config_stdsubmatch);
    616 		nunits += (ms->ms_dv != NULL);
    617 	}
    618 
    619 	free(mes, M_DEVBUF);
    620 
    621 	if (nunits != 0)
    622 		mlx_adjqparam(mlx, mlx->mlx_max_queuecnt / nunits,
    623 		    mlx->mlx_max_queuecnt % nunits);
    624  out:
    625  	mlx->mlx_flags &= ~MLXF_RESCANNING;
    626 }
    627 
    628 /*
    629  * Print autoconfiguration message for a sub-device.
    630  */
    631 static int
    632 mlx_print(void *aux, const char *pnp)
    633 {
    634 	struct mlx_attach_args *mlxa;
    635 
    636 	mlxa = (struct mlx_attach_args *)aux;
    637 
    638 	if (pnp != NULL)
    639 		aprint_normal("block device at %s", pnp);
    640 	aprint_normal(" unit %d", mlxa->mlxa_unit);
    641 	return (UNCONF);
    642 }
    643 
    644 /*
    645  * Shut down all configured `mlx' devices.
    646  */
    647 static void
    648 mlx_shutdown(void *cookie)
    649 {
    650 	struct mlx_softc *mlx;
    651 	int i;
    652 
    653 	for (i = 0; i < mlx_cd.cd_ndevs; i++)
    654 		if ((mlx = device_lookup_private(&mlx_cd, i)) != NULL)
    655 			mlx_flush(mlx, 0);
    656 }
    657 
    658 /*
    659  * Adjust queue parameters for all child devices.
    660  */
    661 static void
    662 mlx_adjqparam(struct mlx_softc *mlx, int mpu, int slop)
    663 {
    664 #if NLD > 0
    665 	extern struct cfdriver ld_cd;
    666 	struct ld_softc *ld;
    667 	int i;
    668 
    669 	for (i = 0; i < ld_cd.cd_ndevs; i++) {
    670 		if ((ld = device_lookup_private(&ld_cd, i)) == NULL)
    671 			continue;
    672 		if (device_parent(&ld->sc_dv) != &mlx->mlx_dv)
    673 			continue;
    674 		ldadjqparam(ld, mpu + (slop-- > 0));
    675 	}
    676 #endif
    677 }
    678 
    679 /*
    680  * Accept an open operation on the control device.
    681  */
    682 int
    683 mlxopen(dev_t dev, int flag, int mode, struct lwp *l)
    684 {
    685 	struct mlx_softc *mlx;
    686 
    687 	if ((mlx = device_lookup_private(&mlx_cd, minor(dev))) == NULL)
    688 		return (ENXIO);
    689 	if ((mlx->mlx_flags & MLXF_INITOK) == 0)
    690 		return (ENXIO);
    691 	if ((mlx->mlx_flags & MLXF_OPEN) != 0)
    692 		return (EBUSY);
    693 
    694 	mlx->mlx_flags |= MLXF_OPEN;
    695 	return (0);
    696 }
    697 
    698 /*
    699  * Accept the last close on the control device.
    700  */
    701 int
    702 mlxclose(dev_t dev, int flag, int mode,
    703     struct lwp *l)
    704 {
    705 	struct mlx_softc *mlx;
    706 
    707 	mlx = device_lookup_private(&mlx_cd, minor(dev));
    708 	mlx->mlx_flags &= ~MLXF_OPEN;
    709 	return (0);
    710 }
    711 
    712 /*
    713  * Handle control operations.
    714  */
    715 int
    716 mlxioctl(dev_t dev, u_long cmd, void *data, int flag,
    717     struct lwp *l)
    718 {
    719 	struct mlx_softc *mlx;
    720 	struct mlx_rebuild_request *rb;
    721 	struct mlx_rebuild_status *rs;
    722 	struct mlx_pause *mp;
    723 	struct mlx_sysdrive *ms;
    724 	int i, rv, *arg, result;
    725 
    726 	mlx = device_lookup_private(&mlx_cd, minor(dev));
    727 
    728 	rb = (struct mlx_rebuild_request *)data;
    729 	rs = (struct mlx_rebuild_status *)data;
    730 	arg = (int *)data;
    731 	rv = 0;
    732 
    733 	switch (cmd) {
    734 	case MLX_RESCAN_DRIVES:
    735 		/*
    736 		 * Scan the controller to see whether new drives have
    737 		 * appeared, or old ones disappeared.
    738 		 */
    739 		mlx_configure(mlx, 1);
    740 		return (0);
    741 
    742 	case MLX_PAUSE_CHANNEL:
    743 		/*
    744 		 * Pause one or more SCSI channels for a period of time, to
    745 		 * assist in the process of hot-swapping devices.
    746 		 *
    747 		 * Note that at least the 3.51 firmware on the DAC960PL
    748 		 * doesn't seem to do this right.
    749 		 */
    750 		if ((mlx->mlx_flags & MLXF_PAUSEWORKS) == 0)
    751 			return (EOPNOTSUPP);
    752 
    753 		mp = (struct mlx_pause *)data;
    754 
    755 		if ((mp->mp_which == MLX_PAUSE_CANCEL) &&
    756 		    (mlx->mlx_pause.mp_when != 0)) {
    757 			/* Cancel a pending pause operation. */
    758 			mlx->mlx_pause.mp_which = 0;
    759 			break;
    760 		}
    761 
    762 		/* Fix for legal channels. */
    763 		mp->mp_which &= ((1 << mlx->mlx_ci.ci_nchan) -1);
    764 
    765 		/* Check time values. */
    766 		if (mp->mp_when < 0 || mp->mp_when > 3600 ||
    767 		    mp->mp_howlong < 1 || mp->mp_howlong > (0xf * 30)) {
    768 			rv = EINVAL;
    769 			break;
    770 		}
    771 
    772 		/* Check for a pause currently running. */
    773 		if ((mlx->mlx_pause.mp_which != 0) &&
    774 		    (mlx->mlx_pause.mp_when == 0)) {
    775 			rv = EBUSY;
    776 			break;
    777 		}
    778 
    779 		/* Looks ok, go with it. */
    780 		mlx->mlx_pause.mp_which = mp->mp_which;
    781 		mlx->mlx_pause.mp_when = time_second + mp->mp_when;
    782 		mlx->mlx_pause.mp_howlong =
    783 		    mlx->mlx_pause.mp_when + mp->mp_howlong;
    784 
    785 		return (0);
    786 
    787 	case MLX_COMMAND:
    788 		rv = kauth_authorize_device_passthru(l->l_cred, dev,
    789 		    KAUTH_REQ_DEVICE_RAWIO_PASSTHRU_ALL, data);
    790 		if (rv)
    791 			return (rv);
    792 
    793 		/*
    794 		 * Accept a command passthrough-style.
    795 		 */
    796 		return (mlx_user_command(mlx, (struct mlx_usercommand *)data));
    797 
    798 	case MLX_REBUILDASYNC:
    799 		/*
    800 		 * Start a rebuild on a given SCSI disk
    801 		 */
    802 		if (mlx->mlx_bg != 0) {
    803 			rb->rr_status = 0x0106;
    804 			rv = EBUSY;
    805 			break;
    806 		}
    807 
    808 		rb->rr_status = mlx_rebuild(mlx, rb->rr_channel, rb->rr_target);
    809 		switch (rb->rr_status) {
    810 		case 0:
    811 			rv = 0;
    812 			break;
    813 		case 0x10000:
    814 			rv = ENOMEM;	/* Couldn't set up the command. */
    815 			break;
    816 		case 0x0002:
    817 			rv = EBUSY;
    818 			break;
    819 		case 0x0104:
    820 			rv = EIO;
    821 			break;
    822 		case 0x0105:
    823 			rv = ERANGE;
    824 			break;
    825 		case 0x0106:
    826 			rv = EBUSY;
    827 			break;
    828 		default:
    829 			rv = EINVAL;
    830 			break;
    831 		}
    832 
    833 		if (rv == 0)
    834 			mlx->mlx_bg = MLX_BG_REBUILD;
    835 
    836 		return (0);
    837 
    838 	case MLX_REBUILDSTAT:
    839 		/*
    840 		 * Get the status of the current rebuild or consistency check.
    841 		 */
    842 		*rs = mlx->mlx_rebuildstat;
    843 		return (0);
    844 
    845 	case MLX_GET_SYSDRIVE:
    846 		/*
    847 		 * Return the system drive number matching the `ld' device
    848 		 * unit in (arg), if it happens to belong to us.
    849 		 */
    850 		for (i = 0; i < MLX_MAX_DRIVES; i++) {
    851 			ms = &mlx->mlx_sysdrive[i];
    852 			if (ms->ms_dv != NULL)
    853 				if (device_xname(ms->ms_dv)[2] == '0' + *arg) {
    854 					*arg = i;
    855 					return (0);
    856 				}
    857 		}
    858 		return (ENOENT);
    859 
    860 	case MLX_GET_CINFO:
    861 		/*
    862 		 * Return controller info.
    863 		 */
    864 		memcpy(arg, &mlx->mlx_ci, sizeof(mlx->mlx_ci));
    865 		return (0);
    866 	}
    867 
    868 	switch (cmd) {
    869 	case MLXD_DETACH:
    870 	case MLXD_STATUS:
    871 	case MLXD_CHECKASYNC:
    872 		if ((u_int)*arg >= MLX_MAX_DRIVES)
    873 			return (EINVAL);
    874 		ms = &mlx->mlx_sysdrive[*arg];
    875 		if (*arg > MLX_MAX_DRIVES || ms->ms_dv == NULL)
    876 			return (ENOENT);
    877 		break;
    878 
    879 	default:
    880 		return (ENOTTY);
    881 	}
    882 
    883 	switch (cmd) {
    884 	case MLXD_DETACH:
    885 		/*
    886 		 * Disconnect from the specified drive; it may be about to go
    887 		 * away.
    888 		 */
    889 		return (config_detach(ms->ms_dv, 0));
    890 
    891 	case MLXD_STATUS:
    892 		/*
    893 		 * Return the current status of this drive.
    894 		 */
    895 		*arg = ms->ms_state;
    896 		return (0);
    897 
    898 	case MLXD_CHECKASYNC:
    899 		/*
    900 		 * Start a background consistency check on this drive.
    901 		 */
    902 		if (mlx->mlx_bg != 0) {
    903 			*arg = 0x0106;
    904 			return (EBUSY);
    905 		}
    906 
    907 		switch (result = mlx_check(mlx, *arg)) {
    908 		case 0:
    909 			rv = 0;
    910 			break;
    911 		case 0x10000:
    912 			rv = ENOMEM;	/* Couldn't set up the command. */
    913 			break;
    914 		case 0x0002:
    915 			rv = EIO;
    916 			break;
    917 		case 0x0105:
    918 			rv = ERANGE;
    919 			break;
    920 		case 0x0106:
    921 			rv = EBUSY;
    922 			break;
    923 		default:
    924 			rv = EINVAL;
    925 			break;
    926 		}
    927 
    928 		if (rv == 0)
    929 			mlx->mlx_bg = MLX_BG_CHECK;
    930 		*arg = result;
    931 		return (rv);
    932 	}
    933 
    934 	return (ENOTTY);	/* XXX shut up gcc */
    935 }
    936 
    937 static void
    938 mlx_periodic_thread(void *cookie)
    939 {
    940 	struct mlx_softc *mlx;
    941 	int i;
    942 
    943 	for (;;) {
    944 		for (i = 0; i < mlx_cd.cd_ndevs; i++)
    945 			if ((mlx = device_lookup_private(&mlx_cd, i)) != NULL)
    946 				if (mlx->mlx_ci.ci_iftype > 1)
    947 					mlx_periodic(mlx);
    948 
    949 		tsleep(mlx_periodic_thread, PWAIT, "mlxzzz", hz * 2);
    950 	}
    951 }
    952 
    953 static void
    954 mlx_periodic(struct mlx_softc *mlx)
    955 {
    956 	struct mlx_ccb *mc, *nmc;
    957 	int etype, s;
    958 
    959 	if ((mlx->mlx_pause.mp_which != 0) &&
    960 	    (mlx->mlx_pause.mp_when > 0) &&
    961 	    (time_second >= mlx->mlx_pause.mp_when)) {
    962 	    	/*
    963 	    	 * Start bus pause.
    964 	    	 */
    965 		mlx_pause_action(mlx);
    966 		mlx->mlx_pause.mp_when = 0;
    967 	} else if ((mlx->mlx_pause.mp_which != 0) &&
    968 		   (mlx->mlx_pause.mp_when == 0)) {
    969 		/*
    970 		 * Stop pause if required.
    971 		 */
    972 		if (time_second >= mlx->mlx_pause.mp_howlong) {
    973 			mlx_pause_action(mlx);
    974 			mlx->mlx_pause.mp_which = 0;
    975 		}
    976 	} else if (time_second > (mlx->mlx_lastpoll + 10)) {
    977 		/*
    978 		 * Run normal periodic activities...
    979 		 */
    980 		mlx->mlx_lastpoll = time_second;
    981 
    982 		/*
    983 		 * Check controller status.
    984 		 */
    985 		if ((mlx->mlx_flags & MLXF_PERIODIC_CTLR) == 0) {
    986 			mlx->mlx_flags |= MLXF_PERIODIC_CTLR;
    987 
    988 			if (mlx->mlx_ci.ci_iftype <= 2)
    989 				etype = MLX_CMD_ENQUIRY_OLD;
    990 			else
    991 				etype =  MLX_CMD_ENQUIRY;
    992 
    993 			mlx_enquire(mlx, etype, max(sizeof(struct mlx_enquiry),
    994 			    sizeof(struct mlx_enquiry_old)),
    995 			    mlx_periodic_enquiry, 1);
    996 		}
    997 
    998 		/*
    999 		 * Check system drive status.
   1000 		 */
   1001 		if ((mlx->mlx_flags & MLXF_PERIODIC_DRIVE) == 0) {
   1002 			mlx->mlx_flags |= MLXF_PERIODIC_DRIVE;
   1003 			mlx_enquire(mlx, MLX_CMD_ENQSYSDRIVE,
   1004 			    sizeof(struct mlx_enq_sys_drive) * MLX_MAX_DRIVES,
   1005 			    mlx_periodic_enquiry, 1);
   1006 		}
   1007 	}
   1008 
   1009 	/*
   1010 	 * Get drive rebuild/check status.
   1011 	 */
   1012 	if ((mlx->mlx_flags & MLXF_PERIODIC_REBUILD) == 0) {
   1013 		mlx->mlx_flags |= MLXF_PERIODIC_REBUILD;
   1014 		mlx_enquire(mlx, MLX_CMD_REBUILDSTAT,
   1015 		    sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild, 1);
   1016 	}
   1017 
   1018 	/*
   1019 	 * Time-out busy CCBs.
   1020 	 */
   1021 	s = splbio();
   1022 	for (mc = TAILQ_FIRST(&mlx->mlx_ccb_worklist); mc != NULL; mc = nmc) {
   1023 		nmc = TAILQ_NEXT(mc, mc_chain.tailq);
   1024 		if (mc->mc_expiry > time_second) {
   1025 			/*
   1026 			 * The remaining CCBs will expire after this one, so
   1027 			 * there's no point in going further.
   1028 			 */
   1029 			break;
   1030 		}
   1031 		TAILQ_REMOVE(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
   1032 		mc->mc_status = MLX_STATUS_LOST;
   1033 		if (mc->mc_mx.mx_handler != NULL)
   1034 			(*mc->mc_mx.mx_handler)(mc);
   1035 		else if ((mc->mc_flags & MC_WAITING) != 0)
   1036 			wakeup(mc);
   1037 	}
   1038 	splx(s);
   1039 }
   1040 
   1041 /*
   1042  * Handle the result of an ENQUIRY command instigated by periodic status
   1043  * polling.
   1044  */
   1045 static void
   1046 mlx_periodic_enquiry(struct mlx_ccb *mc)
   1047 {
   1048 	struct mlx_softc *mlx;
   1049 	struct mlx_enquiry *me;
   1050 	struct mlx_enquiry_old *meo;
   1051 	struct mlx_enq_sys_drive *mes;
   1052 	struct mlx_sysdrive *dr;
   1053 	const char *statestr;
   1054 	int i, j;
   1055 	u_int lsn;
   1056 
   1057 	mlx = (struct mlx_softc *)mc->mc_mx.mx_dv;
   1058 	mlx_ccb_unmap(mlx, mc);
   1059 
   1060 	/*
   1061 	 * Command completed OK?
   1062 	 */
   1063 	if (mc->mc_status != 0) {
   1064 		aprint_error_dev(&mlx->mlx_dv, "periodic enquiry failed - %s\n",
   1065 		    mlx_ccb_diagnose(mc));
   1066 		goto out;
   1067 	}
   1068 
   1069 	/*
   1070 	 * Respond to command.
   1071 	 */
   1072 	switch (mc->mc_mbox[0]) {
   1073 	case MLX_CMD_ENQUIRY_OLD:
   1074 		/*
   1075 		 * This is currently a bit fruitless, as we don't know how
   1076 		 * to extract the eventlog pointer yet.
   1077 		 */
   1078 		me = (struct mlx_enquiry *)mc->mc_mx.mx_context;
   1079 		meo = (struct mlx_enquiry_old *)mc->mc_mx.mx_context;
   1080 
   1081 		/* Convert data in-place to new format */
   1082 		i = sizeof(me->me_dead) / sizeof(me->me_dead[0]);
   1083 		while (--i >= 0) {
   1084 			me->me_dead[i].dd_chan = meo->me_dead[i].dd_chan;
   1085 			me->me_dead[i].dd_targ = meo->me_dead[i].dd_targ;
   1086 		}
   1087 
   1088 		me->me_misc_flags = 0;
   1089 		me->me_rebuild_count = meo->me_rebuild_count;
   1090 		me->me_dead_count = meo->me_dead_count;
   1091 		me->me_critical_sd_count = meo->me_critical_sd_count;
   1092 		me->me_event_log_seq_num = 0;
   1093 		me->me_offline_sd_count = meo->me_offline_sd_count;
   1094 		me->me_max_commands = meo->me_max_commands;
   1095 		me->me_rebuild_flag = meo->me_rebuild_flag;
   1096 		me->me_fwmajor = meo->me_fwmajor;
   1097 		me->me_fwminor = meo->me_fwminor;
   1098 		me->me_status_flags = meo->me_status_flags;
   1099 		me->me_flash_age = meo->me_flash_age;
   1100 
   1101 		i = sizeof(me->me_drvsize) / sizeof(me->me_drvsize[0]);
   1102 		j = sizeof(meo->me_drvsize) / sizeof(meo->me_drvsize[0]);
   1103 
   1104 		while (--i >= 0) {
   1105 			if (i >= j)
   1106 				me->me_drvsize[i] = 0;
   1107 			else
   1108 				me->me_drvsize[i] = meo->me_drvsize[i];
   1109 		}
   1110 
   1111 		me->me_num_sys_drvs = meo->me_num_sys_drvs;
   1112 
   1113 		/* FALLTHROUGH */
   1114 
   1115 	case MLX_CMD_ENQUIRY:
   1116 		/*
   1117 		 * Generic controller status update.  We could do more with
   1118 		 * this than just checking the event log.
   1119 		 */
   1120 		me = (struct mlx_enquiry *)mc->mc_mx.mx_context;
   1121 		lsn = le16toh(me->me_event_log_seq_num);
   1122 
   1123 		if (mlx->mlx_currevent == -1) {
   1124 			/* Initialise our view of the event log. */
   1125 			mlx->mlx_currevent = lsn;
   1126 			mlx->mlx_lastevent = lsn;
   1127 		} else if (lsn != mlx->mlx_lastevent &&
   1128 			   (mlx->mlx_flags & MLXF_EVENTLOG_BUSY) == 0) {
   1129 			/* Record where current events are up to */
   1130 			mlx->mlx_currevent = lsn;
   1131 
   1132 			/* Mark the event log as busy. */
   1133 			mlx->mlx_flags |= MLXF_EVENTLOG_BUSY;
   1134 
   1135 			/* Drain new eventlog entries. */
   1136 			mlx_periodic_eventlog_poll(mlx);
   1137 		}
   1138 		break;
   1139 
   1140 	case MLX_CMD_ENQSYSDRIVE:
   1141 		/*
   1142 		 * Perform drive status comparison to see if something
   1143 		 * has failed.  Don't perform the comparison if we're
   1144 		 * reconfiguring, since the system drive table will be
   1145 		 * changing.
   1146 		 */
   1147 		if ((mlx->mlx_flags & MLXF_RESCANNING) != 0)
   1148 			break;
   1149 
   1150 		mes = (struct mlx_enq_sys_drive *)mc->mc_mx.mx_context;
   1151 		dr = &mlx->mlx_sysdrive[0];
   1152 
   1153 		for (i = 0; i < mlx->mlx_numsysdrives; i++) {
   1154 			/* Has state been changed by controller? */
   1155 			if (dr->ms_state != mes[i].sd_state) {
   1156 				switch (mes[i].sd_state) {
   1157 				case MLX_SYSD_OFFLINE:
   1158 					statestr = "offline";
   1159 					break;
   1160 
   1161 				case MLX_SYSD_ONLINE:
   1162 					statestr = "online";
   1163 					break;
   1164 
   1165 				case MLX_SYSD_CRITICAL:
   1166 					statestr = "critical";
   1167 					break;
   1168 
   1169 				default:
   1170 					statestr = "unknown";
   1171 					break;
   1172 				}
   1173 
   1174 				printf("%s: unit %d %s\n", device_xname(&mlx->mlx_dv),
   1175 				    i, statestr);
   1176 
   1177 				/* Save new state. */
   1178 				dr->ms_state = mes[i].sd_state;
   1179 			}
   1180 		}
   1181 		break;
   1182 
   1183 #ifdef DIAGNOSTIC
   1184 	default:
   1185 		printf("%s: mlx_periodic_enquiry: eh?\n",
   1186 		    device_xname(&mlx->mlx_dv));
   1187 		break;
   1188 #endif
   1189 	}
   1190 
   1191  out:
   1192 	if (mc->mc_mbox[0] == MLX_CMD_ENQSYSDRIVE)
   1193 		mlx->mlx_flags &= ~MLXF_PERIODIC_DRIVE;
   1194 	else
   1195 		mlx->mlx_flags &= ~MLXF_PERIODIC_CTLR;
   1196 
   1197 	free(mc->mc_mx.mx_context, M_DEVBUF);
   1198 	mlx_ccb_free(mlx, mc);
   1199 }
   1200 
   1201 /*
   1202  * Instigate a poll for one event log message on (mlx).  We only poll for
   1203  * one message at a time, to keep our command usage down.
   1204  */
   1205 static void
   1206 mlx_periodic_eventlog_poll(struct mlx_softc *mlx)
   1207 {
   1208 	struct mlx_ccb *mc;
   1209 	void *result;
   1210 	int rv;
   1211 
   1212 	result = NULL;
   1213 
   1214 	if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
   1215 		goto out;
   1216 
   1217 	if ((result = malloc(1024, M_DEVBUF, M_WAITOK)) == NULL) {
   1218 		rv = ENOMEM;
   1219 		goto out;
   1220 	}
   1221 	if ((rv = mlx_ccb_map(mlx, mc, result, 1024, MC_XFER_IN)) != 0)
   1222 		goto out;
   1223 	if (mc->mc_nsgent != 1) {
   1224 		mlx_ccb_unmap(mlx, mc);
   1225 		printf("mlx_periodic_eventlog_poll: too many segs\n");
   1226 		goto out;
   1227 	}
   1228 
   1229 	/* Build the command to get one log entry. */
   1230 	mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1,
   1231 	    mlx->mlx_lastevent, 0, 0, mc->mc_xfer_phys, 0);
   1232 
   1233 	mc->mc_mx.mx_handler = mlx_periodic_eventlog_respond;
   1234 	mc->mc_mx.mx_dv = &mlx->mlx_dv;
   1235 	mc->mc_mx.mx_context = result;
   1236 
   1237 	/* Start the command. */
   1238 	mlx_ccb_enqueue(mlx, mc);
   1239 
   1240  out:
   1241 	if (rv != 0) {
   1242 		if (mc != NULL)
   1243 			mlx_ccb_free(mlx, mc);
   1244 		if (result != NULL)
   1245 			free(result, M_DEVBUF);
   1246 	}
   1247 }
   1248 
   1249 /*
   1250  * Handle the result of polling for a log message, generate diagnostic
   1251  * output.  If this wasn't the last message waiting for us, we'll go collect
   1252  * another.
   1253  */
   1254 static void
   1255 mlx_periodic_eventlog_respond(struct mlx_ccb *mc)
   1256 {
   1257 	struct mlx_softc *mlx;
   1258 	struct mlx_eventlog_entry *el;
   1259 	const char *reason;
   1260 	u_int8_t sensekey, chan, targ;
   1261 
   1262 	mlx = (struct mlx_softc *)mc->mc_mx.mx_dv;
   1263 	el = mc->mc_mx.mx_context;
   1264 	mlx_ccb_unmap(mlx, mc);
   1265 
   1266 	mlx->mlx_lastevent++;
   1267 
   1268 	if (mc->mc_status == 0) {
   1269 		switch (el->el_type) {
   1270 		case MLX_LOGMSG_SENSE:		/* sense data */
   1271 			sensekey = el->el_sense & 0x0f;
   1272 			chan = (el->el_target >> 4) & 0x0f;
   1273 			targ = el->el_target & 0x0f;
   1274 
   1275 			/*
   1276 			 * This is the only sort of message we understand at
   1277 			 * the moment.  The tests here are probably
   1278 			 * incomplete.
   1279 			 */
   1280 
   1281 			/*
   1282 			 * Mylex vendor-specific message indicating a drive
   1283 			 * was killed?
   1284 			 */
   1285 			if (sensekey == 9 && el->el_asc == 0x80) {
   1286 				if (el->el_asq < sizeof(mlx_sense_msgs) /
   1287 				    sizeof(mlx_sense_msgs[0]))
   1288 					reason = mlx_sense_msgs[el->el_asq];
   1289 				else
   1290 					reason = "for unknown reason";
   1291 
   1292 				printf("%s: physical drive %d:%d killed %s\n",
   1293 				    device_xname(&mlx->mlx_dv), chan, targ, reason);
   1294 			}
   1295 
   1296 			/*
   1297 			 * SCSI drive was reset?
   1298 			 */
   1299 			if (sensekey == 6 && el->el_asc == 0x29)
   1300 				printf("%s: physical drive %d:%d reset\n",
   1301 				    device_xname(&mlx->mlx_dv), chan, targ);
   1302 
   1303 			/*
   1304 			 * SCSI drive error?
   1305 			 */
   1306 			if (!(sensekey == 0 ||
   1307 			    (sensekey == 2 &&
   1308 			    el->el_asc == 0x04 &&
   1309 			    (el->el_asq == 0x01 || el->el_asq == 0x02)))) {
   1310 				printf("%s: physical drive %d:%d error log: "
   1311 				    "sense = %d asc = %x asq = %x\n",
   1312 				    device_xname(&mlx->mlx_dv), chan, targ, sensekey,
   1313 				    el->el_asc, el->el_asq);
   1314 				printf("%s:   info = %d:%d:%d:%d "
   1315 				    " csi = %d:%d:%d:%d\n",
   1316 				    device_xname(&mlx->mlx_dv),
   1317 				    el->el_information[0],
   1318 				    el->el_information[1],
   1319 				    el->el_information[2],
   1320 				    el->el_information[3],
   1321 				    el->el_csi[0], el->el_csi[1],
   1322 				    el->el_csi[2], el->el_csi[3]);
   1323 			}
   1324 
   1325 			break;
   1326 
   1327 		default:
   1328 			aprint_error_dev(&mlx->mlx_dv, "unknown log message type 0x%x\n",
   1329 			    el->el_type);
   1330 			break;
   1331 		}
   1332 	} else {
   1333 		aprint_error_dev(&mlx->mlx_dv, "error reading message log - %s\n",
   1334 		    mlx_ccb_diagnose(mc));
   1335 
   1336 		/*
   1337 		 * Give up on all the outstanding messages, as we may have
   1338 		 * come unsynched.
   1339 		 */
   1340 		mlx->mlx_lastevent = mlx->mlx_currevent;
   1341 	}
   1342 
   1343 	free(mc->mc_mx.mx_context, M_DEVBUF);
   1344 	mlx_ccb_free(mlx, mc);
   1345 
   1346 	/*
   1347 	 * Is there another message to obtain?
   1348 	 */
   1349 	if (mlx->mlx_lastevent != mlx->mlx_currevent)
   1350 		mlx_periodic_eventlog_poll(mlx);
   1351 	else
   1352 		mlx->mlx_flags &= ~MLXF_EVENTLOG_BUSY;
   1353 }
   1354 
   1355 /*
   1356  * Handle check/rebuild operations in progress.
   1357  */
   1358 static void
   1359 mlx_periodic_rebuild(struct mlx_ccb *mc)
   1360 {
   1361 	struct mlx_softc *mlx;
   1362 	const char *opstr;
   1363 	struct mlx_rebuild_status *mr;
   1364 
   1365 	mlx = (struct mlx_softc *)mc->mc_mx.mx_dv;
   1366 	mr = mc->mc_mx.mx_context;
   1367 	mlx_ccb_unmap(mlx, mc);
   1368 
   1369 	switch (mc->mc_status) {
   1370 	case 0:
   1371 		/*
   1372 		 * Operation running, update stats.
   1373 		 */
   1374 		mlx->mlx_rebuildstat = *mr;
   1375 
   1376 		/* Spontaneous rebuild/check? */
   1377 		if (mlx->mlx_bg == 0) {
   1378 			mlx->mlx_bg = MLX_BG_SPONTANEOUS;
   1379 			printf("%s: background check/rebuild started\n",
   1380 			    device_xname(&mlx->mlx_dv));
   1381 		}
   1382 		break;
   1383 
   1384 	case 0x0105:
   1385 		/*
   1386 		 * Nothing running, finalise stats and report.
   1387 		 */
   1388 		switch (mlx->mlx_bg) {
   1389 		case MLX_BG_CHECK:
   1390 			/* XXX Print drive? */
   1391 			opstr = "consistency check";
   1392 			break;
   1393 
   1394 		case MLX_BG_REBUILD:
   1395 			/* XXX Print channel:target? */
   1396 			opstr = "drive rebuild";
   1397 			break;
   1398 
   1399 		case MLX_BG_SPONTANEOUS:
   1400 		default:
   1401 			/*
   1402 			 * If we have previously been non-idle, report the
   1403 			 * transition
   1404 			 */
   1405 			if (mlx->mlx_rebuildstat.rs_code !=
   1406 			    MLX_REBUILDSTAT_IDLE)
   1407 				opstr = "background check/rebuild";
   1408 			else
   1409 				opstr = NULL;
   1410 		}
   1411 
   1412 		if (opstr != NULL)
   1413 			printf("%s: %s completed\n", device_xname(&mlx->mlx_dv),
   1414 			    opstr);
   1415 
   1416 		mlx->mlx_bg = 0;
   1417 		mlx->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
   1418 		break;
   1419 	}
   1420 
   1421 	free(mc->mc_mx.mx_context, M_DEVBUF);
   1422 	mlx_ccb_free(mlx, mc);
   1423 	mlx->mlx_flags &= ~MLXF_PERIODIC_REBUILD;
   1424 }
   1425 
   1426 /*
   1427  * It's time to perform a channel pause action for (mlx), either start or
   1428  * stop the pause.
   1429  */
   1430 static void
   1431 mlx_pause_action(struct mlx_softc *mlx)
   1432 {
   1433 	struct mlx_ccb *mc;
   1434 	int failsafe, i, cmd;
   1435 
   1436 	/* What are we doing here? */
   1437 	if (mlx->mlx_pause.mp_when == 0) {
   1438 		cmd = MLX_CMD_STARTCHANNEL;
   1439 		failsafe = 0;
   1440 	} else {
   1441 		cmd = MLX_CMD_STOPCHANNEL;
   1442 
   1443 		/*
   1444 		 * Channels will always start again after the failsafe
   1445 		 * period, which is specified in multiples of 30 seconds.
   1446 		 * This constrains us to a maximum pause of 450 seconds.
   1447 		 */
   1448 		failsafe = ((mlx->mlx_pause.mp_howlong - time_second) + 5) / 30;
   1449 
   1450 		if (failsafe > 0xf) {
   1451 			failsafe = 0xf;
   1452 			mlx->mlx_pause.mp_howlong =
   1453 			     time_second + (0xf * 30) - 5;
   1454 		}
   1455 	}
   1456 
   1457 	/* Build commands for every channel requested. */
   1458 	for (i = 0; i < mlx->mlx_ci.ci_nchan; i++) {
   1459 		if ((1 << i) & mlx->mlx_pause.mp_which) {
   1460 			if (mlx_ccb_alloc(mlx, &mc, 1) != 0) {
   1461 				aprint_error_dev(&mlx->mlx_dv, "%s failed for channel %d\n",
   1462 				    cmd == MLX_CMD_STOPCHANNEL ?
   1463 				    "pause" : "resume", i);
   1464 				continue;
   1465 			}
   1466 
   1467 			/* Build the command. */
   1468 			mlx_make_type2(mc, cmd, (failsafe << 4) | i, 0, 0,
   1469 			    0, 0, 0, 0, 0);
   1470 			mc->mc_mx.mx_handler = mlx_pause_done;
   1471 			mc->mc_mx.mx_dv = &mlx->mlx_dv;
   1472 
   1473 			mlx_ccb_enqueue(mlx, mc);
   1474 		}
   1475 	}
   1476 }
   1477 
   1478 static void
   1479 mlx_pause_done(struct mlx_ccb *mc)
   1480 {
   1481 	struct mlx_softc *mlx;
   1482 	int command, channel;
   1483 
   1484 	mlx = (struct mlx_softc *)mc->mc_mx.mx_dv;
   1485 	command = mc->mc_mbox[0];
   1486 	channel = mc->mc_mbox[2] & 0xf;
   1487 
   1488 	if (mc->mc_status != 0)
   1489 		aprint_error_dev(&mlx->mlx_dv, "%s command failed - %s\n",
   1490 		    command == MLX_CMD_STOPCHANNEL ? "pause" : "resume",
   1491 		    mlx_ccb_diagnose(mc));
   1492 	else if (command == MLX_CMD_STOPCHANNEL)
   1493 		printf("%s: channel %d pausing for %ld seconds\n",
   1494 		    device_xname(&mlx->mlx_dv), channel,
   1495 		    (long)(mlx->mlx_pause.mp_howlong - time_second));
   1496 	else
   1497 		printf("%s: channel %d resuming\n", device_xname(&mlx->mlx_dv),
   1498 		    channel);
   1499 
   1500 	mlx_ccb_free(mlx, mc);
   1501 }
   1502 
   1503 /*
   1504  * Perform an Enquiry command using a type-3 command buffer and a return a
   1505  * single linear result buffer.  If the completion function is specified, it
   1506  * will be called with the completed command (and the result response will
   1507  * not be valid until that point).  Otherwise, the command will either be
   1508  * busy-waited for (interrupts must be blocked), or slept for.
   1509  */
   1510 static void *
   1511 mlx_enquire(struct mlx_softc *mlx, int command, size_t bufsize,
   1512 	    void (*handler)(struct mlx_ccb *mc), int waitok)
   1513 {
   1514 	struct mlx_ccb *mc;
   1515 	void *result;
   1516 	int rv, mapped;
   1517 
   1518 	result = NULL;
   1519 	mapped = 0;
   1520 
   1521 	if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
   1522 		goto out;
   1523 
   1524 	result = malloc(bufsize, M_DEVBUF, waitok ? M_WAITOK : M_NOWAIT);
   1525 	if (result == NULL) {
   1526 		printf("mlx_enquire: malloc() failed\n");
   1527 		goto out;
   1528 	}
   1529 	if ((rv = mlx_ccb_map(mlx, mc, result, bufsize, MC_XFER_IN)) != 0)
   1530 		goto out;
   1531 	mapped = 1;
   1532 	if (mc->mc_nsgent != 1) {
   1533 		printf("mlx_enquire: too many segs\n");
   1534 		goto out;
   1535 	}
   1536 
   1537 	/* Build an enquiry command. */
   1538 	mlx_make_type2(mc, command, 0, 0, 0, 0, 0, 0, mc->mc_xfer_phys, 0);
   1539 
   1540 	/* Do we want a completion callback? */
   1541 	if (handler != NULL) {
   1542 		mc->mc_mx.mx_context = result;
   1543 		mc->mc_mx.mx_dv = &mlx->mlx_dv;
   1544 		mc->mc_mx.mx_handler = handler;
   1545 		mlx_ccb_enqueue(mlx, mc);
   1546 	} else {
   1547 		/* Run the command in either polled or wait mode. */
   1548 		if (waitok)
   1549 			rv = mlx_ccb_wait(mlx, mc);
   1550 		else
   1551 			rv = mlx_ccb_poll(mlx, mc, 5000);
   1552 	}
   1553 
   1554  out:
   1555 	/* We got a command, but nobody else will free it. */
   1556 	if (handler == NULL && mc != NULL) {
   1557 		if (mapped)
   1558 			mlx_ccb_unmap(mlx, mc);
   1559 		mlx_ccb_free(mlx, mc);
   1560 	}
   1561 
   1562 	/* We got an error, and we allocated a result. */
   1563 	if (rv != 0 && result != NULL) {
   1564 		if (mc != NULL)
   1565 			mlx_ccb_free(mlx, mc);
   1566 		free(result, M_DEVBUF);
   1567 		result = NULL;
   1568 	}
   1569 
   1570 	return (result);
   1571 }
   1572 
   1573 /*
   1574  * Perform a Flush command on the nominated controller.
   1575  *
   1576  * May be called with interrupts enabled or disabled; will not return until
   1577  * the flush operation completes or fails.
   1578  */
   1579 int
   1580 mlx_flush(struct mlx_softc *mlx, int async)
   1581 {
   1582 	struct mlx_ccb *mc;
   1583 	int rv;
   1584 
   1585 	if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
   1586 		goto out;
   1587 
   1588 	/* Build a flush command and fire it off. */
   1589 	mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0);
   1590 
   1591 	if (async)
   1592 		rv = mlx_ccb_wait(mlx, mc);
   1593 	else
   1594 		rv = mlx_ccb_poll(mlx, mc, MLX_TIMEOUT * 1000);
   1595 	if (rv != 0)
   1596 		goto out;
   1597 
   1598 	/* Command completed OK? */
   1599 	if (mc->mc_status != 0) {
   1600 		aprint_error_dev(&mlx->mlx_dv, "FLUSH failed - %s\n",
   1601 		    mlx_ccb_diagnose(mc));
   1602 		rv = EIO;
   1603 	}
   1604  out:
   1605 	if (mc != NULL)
   1606 		mlx_ccb_free(mlx, mc);
   1607 
   1608 	return (rv);
   1609 }
   1610 
   1611 /*
   1612  * Start a background consistency check on (drive).
   1613  */
   1614 static int
   1615 mlx_check(struct mlx_softc *mlx, int drive)
   1616 {
   1617 	struct mlx_ccb *mc;
   1618 	int rv;
   1619 
   1620 	/* Get ourselves a command buffer. */
   1621 	rv = 0x10000;
   1622 
   1623 	if (mlx_ccb_alloc(mlx, &mc, 1) != 0)
   1624 		goto out;
   1625 
   1626 	/* Build a checkasync command, set the "fix it" flag. */
   1627 	mlx_make_type2(mc, MLX_CMD_CHECKASYNC, 0, 0, 0, 0, 0, drive | 0x80,
   1628 	    0, 0);
   1629 
   1630 	/* Start the command and wait for it to be returned. */
   1631 	if (mlx_ccb_wait(mlx, mc) != 0)
   1632 		goto out;
   1633 
   1634 	/* Command completed OK? */
   1635 	if (mc->mc_status != 0)
   1636 		aprint_error_dev(&mlx->mlx_dv, "CHECK ASYNC failed - %s\n",
   1637 		    mlx_ccb_diagnose(mc));
   1638 	else
   1639 		printf("%s: consistency check started",
   1640 		    device_xname(mlx->mlx_sysdrive[drive].ms_dv));
   1641 
   1642 	rv = mc->mc_status;
   1643  out:
   1644 	if (mc != NULL)
   1645 		mlx_ccb_free(mlx, mc);
   1646 
   1647 	return (rv);
   1648 }
   1649 
   1650 /*
   1651  * Start a background rebuild of the physical drive at (channel),(target).
   1652  *
   1653  * May be called with interrupts enabled or disabled; will return as soon as
   1654  * the operation has started or been refused.
   1655  */
   1656 static int
   1657 mlx_rebuild(struct mlx_softc *mlx, int channel, int target)
   1658 {
   1659 	struct mlx_ccb *mc;
   1660 	int error;
   1661 
   1662 	error = 0x10000;
   1663 	if (mlx_ccb_alloc(mlx, &mc, 1) != 0)
   1664 		goto out;
   1665 
   1666 	/* Build a rebuildasync command, set the "fix it" flag. */
   1667 	mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0,
   1668 	    0, 0);
   1669 
   1670 	/* Start the command and wait for it to be returned. */
   1671 	if (mlx_ccb_wait(mlx, mc) != 0)
   1672 		goto out;
   1673 
   1674 	/* Command completed OK? */
   1675 	aprint_normal_dev(&mlx->mlx_dv, "");
   1676 	if (mc->mc_status != 0)
   1677 		printf("REBUILD ASYNC failed - %s\n", mlx_ccb_diagnose(mc));
   1678 	else
   1679 		printf("rebuild started for %d:%d\n", channel, target);
   1680 
   1681 	error = mc->mc_status;
   1682 
   1683  out:
   1684 	if (mc != NULL)
   1685 		mlx_ccb_free(mlx, mc);
   1686 
   1687 	return (error);
   1688 }
   1689 
   1690 /*
   1691  * Take a command from user-space and try to run it.
   1692  *
   1693  * XXX Note that this can't perform very much in the way of error checking,
   1694  * XXX and as such, applications _must_ be considered trustworthy.
   1695  *
   1696  * XXX Commands using S/G for data are not supported.
   1697  */
   1698 static int
   1699 mlx_user_command(struct mlx_softc *mlx, struct mlx_usercommand *mu)
   1700 {
   1701 	struct mlx_ccb *mc;
   1702 	struct mlx_dcdb *dcdb;
   1703 	void *kbuf;
   1704 	int rv, mapped;
   1705 
   1706 	if ((mu->mu_bufdir & ~MU_XFER_MASK) != 0)
   1707 		return (EINVAL);
   1708 
   1709 	kbuf = NULL;
   1710 	dcdb = NULL;
   1711 	mapped = 0;
   1712 
   1713 	/* Get ourselves a command and copy in from user space. */
   1714 	if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0) {
   1715 		DPRINTF(("mlx_user_command: mlx_ccb_alloc = %d\n", rv));
   1716 		goto out;
   1717 	}
   1718 
   1719 	memcpy(mc->mc_mbox, mu->mu_command, sizeof(mc->mc_mbox));
   1720 
   1721 	/*
   1722 	 * If we need a buffer for data transfer, allocate one and copy in
   1723 	 * its initial contents.
   1724 	 */
   1725 	if (mu->mu_datasize > 0) {
   1726 		if (mu->mu_datasize > MAXPHYS)
   1727 			return (EINVAL);
   1728 
   1729 		kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK);
   1730 		if (kbuf == NULL) {
   1731 			DPRINTF(("mlx_user_command: malloc = NULL\n"));
   1732 			rv = ENOMEM;
   1733 			goto out;
   1734 		}
   1735 
   1736 		if ((mu->mu_bufdir & MU_XFER_OUT) != 0) {
   1737 			rv = copyin(mu->mu_buf, kbuf, mu->mu_datasize);
   1738 			if (rv != 0) {
   1739 				DPRINTF(("mlx_user_command: copyin = %d\n",
   1740 				    rv));
   1741 				goto out;
   1742 			}
   1743 		}
   1744 
   1745 		/* Map the buffer so the controller can see it. */
   1746 		rv = mlx_ccb_map(mlx, mc, kbuf, mu->mu_datasize, mu->mu_bufdir);
   1747 		if (rv != 0) {
   1748 			DPRINTF(("mlx_user_command: mlx_ccb_map = %d\n", rv));
   1749 			goto out;
   1750 		}
   1751 		if (mc->mc_nsgent > 1) {
   1752 			DPRINTF(("mlx_user_command: too many s/g entries\n"));
   1753 			rv = EFBIG;
   1754 			goto out;
   1755 		}
   1756 		mapped = 1;
   1757 		/*
   1758 		 * If this is a passthrough SCSI command, the DCDB is packed at
   1759 		 * the beginning of the data area.  Fix up the DCDB to point to
   1760 		 * the correct physical address and override any bufptr
   1761 		 * supplied by the caller since we know what it's meant to be.
   1762 		 */
   1763 		if (mc->mc_mbox[0] == MLX_CMD_DIRECT_CDB) {
   1764 			dcdb = (struct mlx_dcdb *)kbuf;
   1765 			dcdb->dcdb_physaddr = mc->mc_xfer_phys + sizeof(*dcdb);
   1766 			mu->mu_bufptr = 8;
   1767 		}
   1768 	}
   1769 
   1770 
   1771 	/*
   1772 	 * If there's a data buffer, fix up the command's buffer pointer.
   1773 	 */
   1774 	if (mu->mu_datasize > 0) {
   1775 		/* Range check the pointer to physical buffer address. */
   1776 		if (mu->mu_bufptr < 0 ||
   1777 		    mu->mu_bufptr > sizeof(mu->mu_command) - 4) {
   1778 			DPRINTF(("mlx_user_command: bufptr botch\n"));
   1779 			rv = EINVAL;
   1780 			goto out;
   1781 		}
   1782 
   1783 		mc->mc_mbox[mu->mu_bufptr] = mc->mc_xfer_phys;
   1784 		mc->mc_mbox[mu->mu_bufptr+1] = mc->mc_xfer_phys >> 8;
   1785 		mc->mc_mbox[mu->mu_bufptr+2] = mc->mc_xfer_phys >> 16;
   1786 		mc->mc_mbox[mu->mu_bufptr+3] = mc->mc_xfer_phys >> 24;
   1787 	}
   1788 
   1789 	/* Submit the command and wait. */
   1790 	if ((rv = mlx_ccb_wait(mlx, mc)) != 0) {
   1791 #ifdef DEBUG
   1792 		printf("mlx_user_command: mlx_ccb_wait = %d\n", rv);
   1793 #endif
   1794 	}
   1795 
   1796  out:
   1797 	if (mc != NULL) {
   1798 		/* Copy out status and data */
   1799 		mu->mu_status = mc->mc_status;
   1800 		if (mapped)
   1801 			mlx_ccb_unmap(mlx, mc);
   1802 		mlx_ccb_free(mlx, mc);
   1803 	}
   1804 
   1805 	if (kbuf != NULL) {
   1806 		if (mu->mu_datasize > 0 && (mu->mu_bufdir & MU_XFER_IN) != 0) {
   1807 			rv = copyout(kbuf, mu->mu_buf, mu->mu_datasize);
   1808 #ifdef DIAGNOSTIC
   1809 			if (rv != 0)
   1810 				printf("mlx_user_command: copyout = %d\n", rv);
   1811 #endif
   1812 		}
   1813 	}
   1814 	if (kbuf != NULL)
   1815 		free(kbuf, M_DEVBUF);
   1816 
   1817 	return (rv);
   1818 }
   1819 
   1820 /*
   1821  * Allocate and initialise a CCB.
   1822  */
   1823 int
   1824 mlx_ccb_alloc(struct mlx_softc *mlx, struct mlx_ccb **mcp, int control)
   1825 {
   1826 	struct mlx_ccb *mc;
   1827 	int s;
   1828 
   1829 	s = splbio();
   1830 	mc = SLIST_FIRST(&mlx->mlx_ccb_freelist);
   1831 	if (control) {
   1832 		if (mlx->mlx_nccbs_ctrl >= MLX_NCCBS_CONTROL) {
   1833 			splx(s);
   1834 			*mcp = NULL;
   1835 			return (EAGAIN);
   1836 		}
   1837 		mc->mc_flags |= MC_CONTROL;
   1838 		mlx->mlx_nccbs_ctrl++;
   1839 	}
   1840 	SLIST_REMOVE_HEAD(&mlx->mlx_ccb_freelist, mc_chain.slist);
   1841 	splx(s);
   1842 
   1843 	*mcp = mc;
   1844 	return (0);
   1845 }
   1846 
   1847 /*
   1848  * Free a CCB.
   1849  */
   1850 void
   1851 mlx_ccb_free(struct mlx_softc *mlx, struct mlx_ccb *mc)
   1852 {
   1853 	int s;
   1854 
   1855 	s = splbio();
   1856 	if ((mc->mc_flags & MC_CONTROL) != 0)
   1857 		mlx->mlx_nccbs_ctrl--;
   1858 	mc->mc_flags = 0;
   1859 	SLIST_INSERT_HEAD(&mlx->mlx_ccb_freelist, mc, mc_chain.slist);
   1860 	splx(s);
   1861 }
   1862 
   1863 /*
   1864  * If a CCB is specified, enqueue it.  Pull CCBs off the software queue in
   1865  * the order that they were enqueued and try to submit their mailboxes to
   1866  * the controller for execution.
   1867  */
   1868 void
   1869 mlx_ccb_enqueue(struct mlx_softc *mlx, struct mlx_ccb *mc)
   1870 {
   1871 	int s;
   1872 
   1873 	s = splbio();
   1874 
   1875 	if (mc != NULL)
   1876 		SIMPLEQ_INSERT_TAIL(&mlx->mlx_ccb_queue, mc, mc_chain.simpleq);
   1877 
   1878 	while ((mc = SIMPLEQ_FIRST(&mlx->mlx_ccb_queue)) != NULL) {
   1879 		if (mlx_ccb_submit(mlx, mc) != 0)
   1880 			break;
   1881 		SIMPLEQ_REMOVE_HEAD(&mlx->mlx_ccb_queue, mc_chain.simpleq);
   1882 		TAILQ_INSERT_TAIL(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
   1883 	}
   1884 
   1885 	splx(s);
   1886 }
   1887 
   1888 /*
   1889  * Map the specified CCB's data buffer onto the bus, and fill the
   1890  * scatter-gather list.
   1891  */
   1892 int
   1893 mlx_ccb_map(struct mlx_softc *mlx, struct mlx_ccb *mc, void *data, int size,
   1894 	    int dir)
   1895 {
   1896 	struct mlx_sgentry *sge;
   1897 	int nsegs, i, rv, sgloff;
   1898 	bus_dmamap_t xfer;
   1899 
   1900 	xfer = mc->mc_xfer_map;
   1901 
   1902 	rv = bus_dmamap_load(mlx->mlx_dmat, xfer, data, size, NULL,
   1903 	    BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
   1904 	    ((dir & MC_XFER_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
   1905 	if (rv != 0)
   1906 		return (rv);
   1907 
   1908 	nsegs = xfer->dm_nsegs;
   1909 	mc->mc_xfer_size = size;
   1910 	mc->mc_flags |= dir;
   1911 	mc->mc_nsgent = nsegs;
   1912 	mc->mc_xfer_phys = xfer->dm_segs[0].ds_addr;
   1913 
   1914 	sgloff = MLX_SGL_SIZE * mc->mc_ident;
   1915 	sge = (struct mlx_sgentry *)((char *)mlx->mlx_sgls + sgloff);
   1916 
   1917 	for (i = 0; i < nsegs; i++, sge++) {
   1918 		sge->sge_addr = htole32(xfer->dm_segs[i].ds_addr);
   1919 		sge->sge_count = htole32(xfer->dm_segs[i].ds_len);
   1920 	}
   1921 
   1922 	if ((dir & MC_XFER_OUT) != 0)
   1923 		i = BUS_DMASYNC_PREWRITE;
   1924 	else
   1925 		i = 0;
   1926 	if ((dir & MC_XFER_IN) != 0)
   1927 		i |= BUS_DMASYNC_PREREAD;
   1928 
   1929 	bus_dmamap_sync(mlx->mlx_dmat, xfer, 0, mc->mc_xfer_size, i);
   1930 	bus_dmamap_sync(mlx->mlx_dmat, mlx->mlx_dmamap, sgloff,
   1931 	    MLX_SGL_SIZE, BUS_DMASYNC_PREWRITE);
   1932 
   1933 	return (0);
   1934 }
   1935 
   1936 /*
   1937  * Unmap the specified CCB's data buffer.
   1938  */
   1939 void
   1940 mlx_ccb_unmap(struct mlx_softc *mlx, struct mlx_ccb *mc)
   1941 {
   1942 	int i;
   1943 
   1944 	bus_dmamap_sync(mlx->mlx_dmat, mlx->mlx_dmamap,
   1945 	    MLX_SGL_SIZE * mc->mc_ident, MLX_SGL_SIZE,
   1946 	    BUS_DMASYNC_POSTWRITE);
   1947 
   1948 	if ((mc->mc_flags & MC_XFER_OUT) != 0)
   1949 		i = BUS_DMASYNC_POSTWRITE;
   1950 	else
   1951 		i = 0;
   1952 	if ((mc->mc_flags & MC_XFER_IN) != 0)
   1953 		i |= BUS_DMASYNC_POSTREAD;
   1954 
   1955 	bus_dmamap_sync(mlx->mlx_dmat, mc->mc_xfer_map, 0, mc->mc_xfer_size, i);
   1956 	bus_dmamap_unload(mlx->mlx_dmat, mc->mc_xfer_map);
   1957 }
   1958 
   1959 /*
   1960  * Submit the CCB, and busy-wait for it to complete.  Return non-zero on
   1961  * timeout or submission error.  Must be called with interrupts blocked.
   1962  */
   1963 int
   1964 mlx_ccb_poll(struct mlx_softc *mlx, struct mlx_ccb *mc, int timo)
   1965 {
   1966 	int rv;
   1967 
   1968 	mc->mc_mx.mx_handler = NULL;
   1969 
   1970 	if ((rv = mlx_ccb_submit(mlx, mc)) != 0)
   1971 		return (rv);
   1972 	TAILQ_INSERT_TAIL(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
   1973 
   1974 	for (timo *= 10; timo != 0; timo--) {
   1975 		mlx_intr(mlx);
   1976 		if (mc->mc_status != MLX_STATUS_BUSY)
   1977 			break;
   1978 		DELAY(100);
   1979 	}
   1980 
   1981 	if (timo != 0) {
   1982 		if (mc->mc_status != 0) {
   1983 			aprint_error_dev(&mlx->mlx_dv, "command failed - %s\n",
   1984 			    mlx_ccb_diagnose(mc));
   1985 			rv = EIO;
   1986 		} else
   1987 			rv = 0;
   1988 	} else {
   1989 		printf("%s: command timed out\n", device_xname(&mlx->mlx_dv));
   1990 		rv = EIO;
   1991 	}
   1992 
   1993 	return (rv);
   1994 }
   1995 
   1996 /*
   1997  * Enqueue the CCB, and sleep until it completes.  Return non-zero on
   1998  * timeout or error.
   1999  */
   2000 int
   2001 mlx_ccb_wait(struct mlx_softc *mlx, struct mlx_ccb *mc)
   2002 {
   2003 	int s;
   2004 
   2005 	mc->mc_flags |= MC_WAITING;
   2006 	mc->mc_mx.mx_handler = NULL;
   2007 
   2008 	s = splbio();
   2009 	mlx_ccb_enqueue(mlx, mc);
   2010 	tsleep(mc, PRIBIO, "mlxwccb", 0);
   2011 	splx(s);
   2012 
   2013 	if (mc->mc_status != 0) {
   2014 		aprint_error_dev(&mlx->mlx_dv, "command failed - %s\n",
   2015 		    mlx_ccb_diagnose(mc));
   2016 		return (EIO);
   2017 	}
   2018 
   2019 	return (0);
   2020 }
   2021 
   2022 /*
   2023  * Try to submit a CCB's mailbox to the controller for execution.  Return
   2024  * non-zero on timeout or error.  Must be called with interrupts blocked.
   2025  */
   2026 static int
   2027 mlx_ccb_submit(struct mlx_softc *mlx, struct mlx_ccb *mc)
   2028 {
   2029 	int i, s, r;
   2030 
   2031 	/* Save the ident so we can handle this command when complete. */
   2032 	mc->mc_mbox[1] = (u_int8_t)(mc->mc_ident + 1);
   2033 
   2034 	/* Mark the command as currently being processed. */
   2035 	mc->mc_status = MLX_STATUS_BUSY;
   2036 	mc->mc_expiry = time_second + MLX_TIMEOUT;
   2037 
   2038 	/* Spin waiting for the mailbox. */
   2039 	for (i = 100; i != 0; i--) {
   2040 		s = splbio();
   2041 		r = (*mlx->mlx_submit)(mlx, mc);
   2042 		splx(s);
   2043 		if (r != 0)
   2044 			break;
   2045 		DELAY(100);
   2046 	}
   2047 	if (i != 0)
   2048 		return (0);
   2049 
   2050 	DPRINTF(("mlx_ccb_submit: rejected; queueing\n"));
   2051 	mc->mc_status = MLX_STATUS_WEDGED;
   2052 	return (EIO);
   2053 }
   2054 
   2055 /*
   2056  * Return a string that describes why a command has failed.
   2057  */
   2058 const char *
   2059 mlx_ccb_diagnose(struct mlx_ccb *mc)
   2060 {
   2061 	static char tbuf[80];
   2062 	int i;
   2063 
   2064 	for (i = 0; i < sizeof(mlx_msgs) / sizeof(mlx_msgs[0]); i++)
   2065 		if ((mc->mc_mbox[0] == mlx_msgs[i].command ||
   2066 		    mlx_msgs[i].command == 0) &&
   2067 		    mc->mc_status == mlx_msgs[i].status) {
   2068 			snprintf(tbuf, sizeof(tbuf), "%s (0x%x)",
   2069 			    mlx_status_msgs[mlx_msgs[i].msg], mc->mc_status);
   2070 			return (tbuf);
   2071 		}
   2072 
   2073 	snprintf(tbuf, sizeof(tbuf), "unknown response 0x%x for command 0x%x",
   2074 	    (int)mc->mc_status, (int)mc->mc_mbox[0]);
   2075 
   2076 	return (tbuf);
   2077 }
   2078 
   2079 /*
   2080  * Poll the controller for completed commands.  Returns non-zero if one or
   2081  * more commands were completed.  Must be called with interrupts blocked.
   2082  */
   2083 int
   2084 mlx_intr(void *cookie)
   2085 {
   2086 	struct mlx_softc *mlx;
   2087 	struct mlx_ccb *mc;
   2088 	int result;
   2089 	u_int ident, status;
   2090 
   2091 	mlx = cookie;
   2092 	result = 0;
   2093 
   2094 	while ((*mlx->mlx_findcomplete)(mlx, &ident, &status) != 0) {
   2095 		result = 1;
   2096 		ident--;
   2097 
   2098 		if (ident >= MLX_MAX_QUEUECNT) {
   2099 			aprint_error_dev(&mlx->mlx_dv, "bad completion returned\n");
   2100 			continue;
   2101 		}
   2102 
   2103 		mc = mlx->mlx_ccbs + ident;
   2104 
   2105 		if (mc->mc_status != MLX_STATUS_BUSY) {
   2106 			aprint_error_dev(&mlx->mlx_dv, "bad completion returned\n");
   2107 			continue;
   2108 		}
   2109 
   2110 		TAILQ_REMOVE(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
   2111 
   2112 		/* Record status and notify the initiator, if requested. */
   2113 		mc->mc_status = status;
   2114 		if (mc->mc_mx.mx_handler != NULL)
   2115 			(*mc->mc_mx.mx_handler)(mc);
   2116 		else if ((mc->mc_flags & MC_WAITING) != 0)
   2117 			wakeup(mc);
   2118 	}
   2119 
   2120 	/* If we've completed any commands, try posting some more. */
   2121 	if (result)
   2122 		mlx_ccb_enqueue(mlx, NULL);
   2123 
   2124 	return (result);
   2125 }
   2126 
   2127 /*
   2128  * Emit a string describing the firmware handshake status code, and return a
   2129  * flag indicating whether the code represents a fatal error.
   2130  *
   2131  * Error code interpretations are from the Linux driver, and don't directly
   2132  * match the messages printed by Mylex's BIOS.  This may change if
   2133  * documentation on the codes is forthcoming.
   2134  */
   2135 static int
   2136 mlx_fw_message(struct mlx_softc *mlx, int error, int param1, int param2)
   2137 {
   2138 	const char *fmt;
   2139 
   2140 	switch (error) {
   2141 	case 0x00:
   2142 		fmt = "physical drive %d:%d not responding";
   2143 		break;
   2144 
   2145 	case 0x08:
   2146 		/*
   2147 		 * We could be neater about this and give some indication
   2148 		 * when we receive more of them.
   2149 		 */
   2150 		if ((mlx->mlx_flags & MLXF_SPINUP_REPORTED) == 0) {
   2151 			printf("%s: spinning up drives...\n",
   2152 			    device_xname(&mlx->mlx_dv));
   2153 			mlx->mlx_flags |= MLXF_SPINUP_REPORTED;
   2154 		}
   2155 		return (0);
   2156 
   2157 	case 0x30:
   2158 		fmt = "configuration checksum error";
   2159 		break;
   2160 
   2161 	case 0x60:
   2162 		fmt = "mirror race recovery failed";
   2163 		break;
   2164 
   2165 	case 0x70:
   2166 		fmt = "mirror race recovery in progress";
   2167 		break;
   2168 
   2169 	case 0x90:
   2170 		fmt = "physical drive %d:%d COD mismatch";
   2171 		break;
   2172 
   2173 	case 0xa0:
   2174 		fmt = "logical drive installation aborted";
   2175 		break;
   2176 
   2177 	case 0xb0:
   2178 		fmt = "mirror race on a critical system drive";
   2179 		break;
   2180 
   2181 	case 0xd0:
   2182 		fmt = "new controller configuration found";
   2183 		break;
   2184 
   2185 	case 0xf0:
   2186 		aprint_error_dev(&mlx->mlx_dv, "FATAL MEMORY PARITY ERROR\n");
   2187 		return (1);
   2188 
   2189 	default:
   2190 		aprint_error_dev(&mlx->mlx_dv, "unknown firmware init error %02x:%02x:%02x\n",
   2191 		    error, param1, param2);
   2192 		return (0);
   2193 	}
   2194 
   2195 	aprint_normal_dev(&mlx->mlx_dv, "");
   2196 	aprint_normal(fmt, param2, param1);
   2197 	aprint_normal("\n");
   2198 
   2199 	return (0);
   2200 }
   2201