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