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