1 /*- 2 * Copyright (c) 1999 Michael Smith 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 /* 30 * Driver for the Mylex DAC960 family of RAID controllers. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/malloc.h> 36 #include <sys/kernel.h> 37 38 #include <sys/bus.h> 39 #include <sys/conf.h> 40 #include <sys/stat.h> 41 42 #include <machine/resource.h> 43 #include <machine/bus.h> 44 #include <machine/clock.h> 45 #include <sys/rman.h> 46 47 #include <geom/geom_disk.h> 48 49 #include <dev/mlx/mlx_compat.h> 50 #include <dev/mlx/mlxio.h> 51 #include <dev/mlx/mlxvar.h> 52 #include <dev/mlx/mlxreg.h> 53 54 static struct cdevsw mlx_cdevsw = { 55 .d_version = D_VERSION, 56 .d_flags = D_NEEDGIANT, 57 .d_open = mlx_open, 58 .d_close = mlx_close, 59 .d_ioctl = mlx_ioctl, 60 .d_name = "mlx", 61 }; 62 63 devclass_t mlx_devclass; 64 65 /* 66 * Per-interface accessor methods 67 */ 68 static int mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 69 static int mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 70 static void mlx_v3_intaction(struct mlx_softc *sc, int action); 71 static int mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2); 72 73 static int mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 74 static int mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 75 static void mlx_v4_intaction(struct mlx_softc *sc, int action); 76 static int mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2); 77 78 static int mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 79 static int mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 80 static void mlx_v5_intaction(struct mlx_softc *sc, int action); 81 static int mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2); 82 83 /* 84 * Status monitoring 85 */ 86 static void mlx_periodic(void *data); 87 static void mlx_periodic_enquiry(struct mlx_command *mc); 88 static void mlx_periodic_eventlog_poll(struct mlx_softc *sc); 89 static void mlx_periodic_eventlog_respond(struct mlx_command *mc); 90 static void mlx_periodic_rebuild(struct mlx_command *mc); 91 92 /* 93 * Channel Pause 94 */ 95 static void mlx_pause_action(struct mlx_softc *sc); 96 static void mlx_pause_done(struct mlx_command *mc); 97 98 /* 99 * Command submission. 100 */ 101 static void *mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, 102 void (*complete)(struct mlx_command *mc)); 103 static int mlx_flush(struct mlx_softc *sc); 104 static int mlx_check(struct mlx_softc *sc, int drive); 105 static int mlx_rebuild(struct mlx_softc *sc, int channel, int target); 106 static int mlx_wait_command(struct mlx_command *mc); 107 static int mlx_poll_command(struct mlx_command *mc); 108 void mlx_startio_cb(void *arg, 109 bus_dma_segment_t *segs, 110 int nsegments, int error); 111 static void mlx_startio(struct mlx_softc *sc); 112 static void mlx_completeio(struct mlx_command *mc); 113 static int mlx_user_command(struct mlx_softc *sc, 114 struct mlx_usercommand *mu); 115 void mlx_user_cb(void *arg, bus_dma_segment_t *segs, 116 int nsegments, int error); 117 118 /* 119 * Command buffer allocation. 120 */ 121 static struct mlx_command *mlx_alloccmd(struct mlx_softc *sc); 122 static void mlx_releasecmd(struct mlx_command *mc); 123 static void mlx_freecmd(struct mlx_command *mc); 124 125 /* 126 * Command management. 127 */ 128 static int mlx_getslot(struct mlx_command *mc); 129 static void mlx_setup_dmamap(struct mlx_command *mc, 130 bus_dma_segment_t *segs, 131 int nsegments, int error); 132 static void mlx_unmapcmd(struct mlx_command *mc); 133 static int mlx_start(struct mlx_command *mc); 134 static int mlx_done(struct mlx_softc *sc); 135 static void mlx_complete(struct mlx_softc *sc); 136 137 /* 138 * Debugging. 139 */ 140 static char *mlx_diagnose_command(struct mlx_command *mc); 141 static void mlx_describe_controller(struct mlx_softc *sc); 142 static int mlx_fw_message(struct mlx_softc *sc, int status, int param1, int param2); 143 144 /* 145 * Utility functions. 146 */ 147 static struct mlx_sysdrive *mlx_findunit(struct mlx_softc *sc, int unit); 148 149 /******************************************************************************** 150 ******************************************************************************** 151 Public Interfaces 152 ******************************************************************************** 153 ********************************************************************************/ 154 155 /******************************************************************************** 156 * Free all of the resources associated with (sc) 157 * 158 * Should not be called if the controller is active. 159 */ 160 void 161 mlx_free(struct mlx_softc *sc) 162 { 163 struct mlx_command *mc; 164 165 debug_called(1); 166 167 /* cancel status timeout */ 168 untimeout(mlx_periodic, sc, sc->mlx_timeout); 169 170 /* throw away any command buffers */ 171 while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) { 172 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link); 173 mlx_freecmd(mc); 174 } 175 176 /* destroy data-transfer DMA tag */ 177 if (sc->mlx_buffer_dmat) 178 bus_dma_tag_destroy(sc->mlx_buffer_dmat); 179 180 /* free and destroy DMA memory and tag for s/g lists */ 181 if (sc->mlx_sgtable) 182 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap); 183 if (sc->mlx_sg_dmat) 184 bus_dma_tag_destroy(sc->mlx_sg_dmat); 185 186 /* disconnect the interrupt handler */ 187 if (sc->mlx_intr) 188 bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr); 189 if (sc->mlx_irq != NULL) 190 bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq); 191 192 /* destroy the parent DMA tag */ 193 if (sc->mlx_parent_dmat) 194 bus_dma_tag_destroy(sc->mlx_parent_dmat); 195 196 /* release the register window mapping */ 197 if (sc->mlx_mem != NULL) 198 bus_release_resource(sc->mlx_dev, sc->mlx_mem_type, sc->mlx_mem_rid, sc->mlx_mem); 199 200 /* free controller enquiry data */ 201 if (sc->mlx_enq2 != NULL) 202 free(sc->mlx_enq2, M_DEVBUF); 203 204 /* destroy control device */ 205 if (sc->mlx_dev_t != (struct cdev *)NULL) 206 destroy_dev(sc->mlx_dev_t); 207 } 208 209 /******************************************************************************** 210 * Map the scatter/gather table into bus space 211 */ 212 static void 213 mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 214 { 215 struct mlx_softc *sc = (struct mlx_softc *)arg; 216 217 debug_called(1); 218 219 /* save base of s/g table's address in bus space */ 220 sc->mlx_sgbusaddr = segs->ds_addr; 221 } 222 223 static int 224 mlx_sglist_map(struct mlx_softc *sc) 225 { 226 size_t segsize; 227 int error, ncmd; 228 229 debug_called(1); 230 231 /* destroy any existing mappings */ 232 if (sc->mlx_sgtable) 233 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap); 234 if (sc->mlx_sg_dmat) 235 bus_dma_tag_destroy(sc->mlx_sg_dmat); 236 237 /* 238 * Create a single tag describing a region large enough to hold all of 239 * the s/g lists we will need. If we're called early on, we don't know how 240 * many commands we're going to be asked to support, so only allocate enough 241 * for a couple. 242 */ 243 if (sc->mlx_enq2 == NULL) { 244 ncmd = 2; 245 } else { 246 ncmd = sc->mlx_enq2->me_max_commands; 247 } 248 segsize = sizeof(struct mlx_sgentry) * MLX_NSEG * ncmd; 249 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */ 250 1, 0, /* alignment,boundary */ 251 BUS_SPACE_MAXADDR, /* lowaddr */ 252 BUS_SPACE_MAXADDR, /* highaddr */ 253 NULL, NULL, /* filter, filterarg */ 254 segsize, 1, /* maxsize, nsegments */ 255 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 256 0, /* flags */ 257 NULL, NULL, /* lockfunc, lockarg */ 258 &sc->mlx_sg_dmat); 259 if (error != 0) { 260 device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n"); 261 return(ENOMEM); 262 } 263 264 /* 265 * Allocate enough s/g maps for all commands and permanently map them into 266 * controller-visible space. 267 * 268 * XXX this assumes we can get enough space for all the s/g maps in one 269 * contiguous slab. We may need to switch to a more complex arrangement 270 * where we allocate in smaller chunks and keep a lookup table from slot 271 * to bus address. 272 */ 273 error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable, 274 BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap); 275 if (error) { 276 device_printf(sc->mlx_dev, "can't allocate s/g table\n"); 277 return(ENOMEM); 278 } 279 (void)bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable, 280 segsize, mlx_dma_map_sg, sc, 0); 281 return(0); 282 } 283 284 /******************************************************************************** 285 * Initialise the controller and softc 286 */ 287 int 288 mlx_attach(struct mlx_softc *sc) 289 { 290 struct mlx_enquiry_old *meo; 291 int rid, error, fwminor, hscode, hserror, hsparam1, hsparam2, hsmsg; 292 293 debug_called(1); 294 295 /* 296 * Initialise per-controller queues. 297 */ 298 TAILQ_INIT(&sc->mlx_work); 299 TAILQ_INIT(&sc->mlx_freecmds); 300 MLX_BIO_QINIT(sc->mlx_bioq); 301 302 /* 303 * Select accessor methods based on controller interface type. 304 */ 305 switch(sc->mlx_iftype) { 306 case MLX_IFTYPE_2: 307 case MLX_IFTYPE_3: 308 sc->mlx_tryqueue = mlx_v3_tryqueue; 309 sc->mlx_findcomplete = mlx_v3_findcomplete; 310 sc->mlx_intaction = mlx_v3_intaction; 311 sc->mlx_fw_handshake = mlx_v3_fw_handshake; 312 break; 313 case MLX_IFTYPE_4: 314 sc->mlx_tryqueue = mlx_v4_tryqueue; 315 sc->mlx_findcomplete = mlx_v4_findcomplete; 316 sc->mlx_intaction = mlx_v4_intaction; 317 sc->mlx_fw_handshake = mlx_v4_fw_handshake; 318 break; 319 case MLX_IFTYPE_5: 320 sc->mlx_tryqueue = mlx_v5_tryqueue; 321 sc->mlx_findcomplete = mlx_v5_findcomplete; 322 sc->mlx_intaction = mlx_v5_intaction; 323 sc->mlx_fw_handshake = mlx_v5_fw_handshake; 324 break; 325 default: 326 return(ENXIO); /* should never happen */ 327 } 328 329 /* disable interrupts before we start talking to the controller */ 330 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 331 332 /* 333 * Wait for the controller to come ready, handshake with the firmware if required. 334 * This is typically only necessary on platforms where the controller BIOS does not 335 * run. 336 */ 337 hsmsg = 0; 338 DELAY(1000); 339 while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2)) != 0) { 340 /* report first time around... */ 341 if (hsmsg == 0) { 342 device_printf(sc->mlx_dev, "controller initialisation in progress...\n"); 343 hsmsg = 1; 344 } 345 /* did we get a real message? */ 346 if (hscode == 2) { 347 hscode = mlx_fw_message(sc, hserror, hsparam1, hsparam2); 348 /* fatal initialisation error? */ 349 if (hscode != 0) { 350 return(ENXIO); 351 } 352 } 353 } 354 if (hsmsg == 1) 355 device_printf(sc->mlx_dev, "initialisation complete.\n"); 356 357 /* 358 * Allocate and connect our interrupt. 359 */ 360 rid = 0; 361 sc->mlx_irq = bus_alloc_resource_any(sc->mlx_dev, SYS_RES_IRQ, &rid, 362 RF_SHAREABLE | RF_ACTIVE); 363 if (sc->mlx_irq == NULL) { 364 device_printf(sc->mlx_dev, "can't allocate interrupt\n"); 365 return(ENXIO); 366 } 367 error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO | INTR_ENTROPY, NULL, mlx_intr, sc, &sc->mlx_intr); 368 if (error) { 369 device_printf(sc->mlx_dev, "can't set up interrupt\n"); 370 return(ENXIO); 371 } 372 373 /* 374 * Create DMA tag for mapping buffers into controller-addressable space. 375 */ 376 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */ 377 1, 0, /* align, boundary */ 378 BUS_SPACE_MAXADDR, /* lowaddr */ 379 BUS_SPACE_MAXADDR, /* highaddr */ 380 NULL, NULL, /* filter, filterarg */ 381 MAXBSIZE, MLX_NSEG, /* maxsize, nsegments */ 382 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 383 0, /* flags */ 384 busdma_lock_mutex, /* lockfunc */ 385 &Giant, /* lockarg */ 386 &sc->mlx_buffer_dmat); 387 if (error != 0) { 388 device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n"); 389 return(ENOMEM); 390 } 391 392 /* 393 * Create some initial scatter/gather mappings so we can run the probe 394 * commands. 395 */ 396 error = mlx_sglist_map(sc); 397 if (error != 0) { 398 device_printf(sc->mlx_dev, "can't make initial s/g list mapping\n"); 399 return(error); 400 } 401 402 /* 403 * We don't (yet) know where the event log is up to. 404 */ 405 sc->mlx_currevent = -1; 406 407 /* 408 * Obtain controller feature information 409 */ 410 if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) { 411 device_printf(sc->mlx_dev, "ENQUIRY2 failed\n"); 412 return(ENXIO); 413 } 414 415 /* 416 * Do quirk/feature related things. 417 */ 418 fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff; 419 switch(sc->mlx_iftype) { 420 case MLX_IFTYPE_2: 421 /* These controllers don't report the firmware version in the ENQUIRY2 response */ 422 if ((meo = mlx_enquire(sc, MLX_CMD_ENQUIRY_OLD, sizeof(struct mlx_enquiry_old), NULL)) == NULL) { 423 device_printf(sc->mlx_dev, "ENQUIRY_OLD failed\n"); 424 return(ENXIO); 425 } 426 sc->mlx_enq2->me_firmware_id = ('0' << 24) | (0 << 16) | (meo->me_fwminor << 8) | meo->me_fwmajor; 427 428 /* XXX require 2.42 or better (PCI) or 2.14 or better (EISA) */ 429 if (meo->me_fwminor < 42) { 430 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 431 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 2.42 or later\n"); 432 } 433 free(meo, M_DEVBUF); 434 break; 435 case MLX_IFTYPE_3: 436 /* XXX certify 3.52? */ 437 if (fwminor < 51) { 438 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 439 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n"); 440 } 441 break; 442 case MLX_IFTYPE_4: 443 /* XXX certify firmware versions? */ 444 if (fwminor < 6) { 445 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 446 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n"); 447 } 448 break; 449 case MLX_IFTYPE_5: 450 if (fwminor < 7) { 451 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 452 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n"); 453 } 454 break; 455 default: 456 return(ENXIO); /* should never happen */ 457 } 458 459 /* 460 * Create the final scatter/gather mappings now that we have characterised the controller. 461 */ 462 error = mlx_sglist_map(sc); 463 if (error != 0) { 464 device_printf(sc->mlx_dev, "can't make final s/g list mapping\n"); 465 return(error); 466 } 467 468 /* 469 * No user-requested background operation is in progress. 470 */ 471 sc->mlx_background = 0; 472 sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE; 473 474 /* 475 * Create the control device. 476 */ 477 sc->mlx_dev_t = make_dev(&mlx_cdevsw, device_get_unit(sc->mlx_dev), UID_ROOT, GID_OPERATOR, 478 S_IRUSR | S_IWUSR, "mlx%d", device_get_unit(sc->mlx_dev)); 479 480 /* 481 * Start the timeout routine. 482 */ 483 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 484 485 /* print a little information about the controller */ 486 mlx_describe_controller(sc); 487 488 return(0); 489 } 490 491 /******************************************************************************** 492 * Locate disk resources and attach children to them. 493 */ 494 void 495 mlx_startup(struct mlx_softc *sc) 496 { 497 struct mlx_enq_sys_drive *mes; 498 struct mlx_sysdrive *dr; 499 int i, error; 500 501 debug_called(1); 502 503 /* 504 * Scan all the system drives and attach children for those that 505 * don't currently have them. 506 */ 507 mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL); 508 if (mes == NULL) { 509 device_printf(sc->mlx_dev, "error fetching drive status\n"); 510 return; 511 } 512 513 /* iterate over drives returned */ 514 for (i = 0, dr = &sc->mlx_sysdrive[0]; 515 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 516 i++, dr++) { 517 /* are we already attached to this drive? */ 518 if (dr->ms_disk == 0) { 519 /* pick up drive information */ 520 dr->ms_size = mes[i].sd_size; 521 dr->ms_raidlevel = mes[i].sd_raidlevel & 0xf; 522 dr->ms_state = mes[i].sd_state; 523 524 /* generate geometry information */ 525 if (sc->mlx_geom == MLX_GEOM_128_32) { 526 dr->ms_heads = 128; 527 dr->ms_sectors = 32; 528 dr->ms_cylinders = dr->ms_size / (128 * 32); 529 } else { /* MLX_GEOM_255/63 */ 530 dr->ms_heads = 255; 531 dr->ms_sectors = 63; 532 dr->ms_cylinders = dr->ms_size / (255 * 63); 533 } 534 dr->ms_disk = device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1); 535 if (dr->ms_disk == 0) 536 device_printf(sc->mlx_dev, "device_add_child failed\n"); 537 device_set_ivars(dr->ms_disk, dr); 538 } 539 } 540 free(mes, M_DEVBUF); 541 if ((error = bus_generic_attach(sc->mlx_dev)) != 0) 542 device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error); 543 544 /* mark controller back up */ 545 sc->mlx_state &= ~MLX_STATE_SHUTDOWN; 546 547 /* enable interrupts */ 548 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE); 549 } 550 551 /******************************************************************************** 552 * Disconnect from the controller completely, in preparation for unload. 553 */ 554 int 555 mlx_detach(device_t dev) 556 { 557 struct mlx_softc *sc = device_get_softc(dev); 558 struct mlxd_softc *mlxd; 559 int i, s, error; 560 561 debug_called(1); 562 563 error = EBUSY; 564 s = splbio(); 565 if (sc->mlx_state & MLX_STATE_OPEN) 566 goto out; 567 568 for (i = 0; i < MLX_MAXDRIVES; i++) { 569 if (sc->mlx_sysdrive[i].ms_disk != 0) { 570 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk); 571 if (mlxd->mlxd_flags & MLXD_OPEN) { /* drive is mounted, abort detach */ 572 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n"); 573 goto out; 574 } 575 } 576 } 577 if ((error = mlx_shutdown(dev))) 578 goto out; 579 580 mlx_free(sc); 581 582 error = 0; 583 out: 584 splx(s); 585 return(error); 586 } 587 588 /******************************************************************************** 589 * Bring the controller down to a dormant state and detach all child devices. 590 * 591 * This function is called before detach, system shutdown, or before performing 592 * an operation which may add or delete system disks. (Call mlx_startup to 593 * resume normal operation.) 594 * 595 * Note that we can assume that the bioq on the controller is empty, as we won't 596 * allow shutdown if any device is open. 597 */ 598 int 599 mlx_shutdown(device_t dev) 600 { 601 struct mlx_softc *sc = device_get_softc(dev); 602 int i, s, error; 603 604 debug_called(1); 605 606 s = splbio(); 607 error = 0; 608 609 sc->mlx_state |= MLX_STATE_SHUTDOWN; 610 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 611 612 /* flush controller */ 613 device_printf(sc->mlx_dev, "flushing cache..."); 614 if (mlx_flush(sc)) { 615 printf("failed\n"); 616 } else { 617 printf("done\n"); 618 } 619 620 /* delete all our child devices */ 621 for (i = 0; i < MLX_MAXDRIVES; i++) { 622 if (sc->mlx_sysdrive[i].ms_disk != 0) { 623 if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0) 624 goto out; 625 sc->mlx_sysdrive[i].ms_disk = 0; 626 } 627 } 628 629 out: 630 splx(s); 631 return(error); 632 } 633 634 /******************************************************************************** 635 * Bring the controller to a quiescent state, ready for system suspend. 636 */ 637 int 638 mlx_suspend(device_t dev) 639 { 640 struct mlx_softc *sc = device_get_softc(dev); 641 int s; 642 643 debug_called(1); 644 645 s = splbio(); 646 sc->mlx_state |= MLX_STATE_SUSPEND; 647 648 /* flush controller */ 649 device_printf(sc->mlx_dev, "flushing cache..."); 650 printf("%s\n", mlx_flush(sc) ? "failed" : "done"); 651 652 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 653 splx(s); 654 655 return(0); 656 } 657 658 /******************************************************************************** 659 * Bring the controller back to a state ready for operation. 660 */ 661 int 662 mlx_resume(device_t dev) 663 { 664 struct mlx_softc *sc = device_get_softc(dev); 665 666 debug_called(1); 667 668 sc->mlx_state &= ~MLX_STATE_SUSPEND; 669 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE); 670 671 return(0); 672 } 673 674 /******************************************************************************* 675 * Take an interrupt, or be poked by other code to look for interrupt-worthy 676 * status. 677 */ 678 void 679 mlx_intr(void *arg) 680 { 681 struct mlx_softc *sc = (struct mlx_softc *)arg; 682 683 debug_called(1); 684 685 /* collect finished commands, queue anything waiting */ 686 mlx_done(sc); 687 }; 688 689 /******************************************************************************* 690 * Receive a buf structure from a child device and queue it on a particular 691 * disk resource, then poke the disk resource to start as much work as it can. 692 */ 693 int 694 mlx_submit_buf(struct mlx_softc *sc, mlx_bio *bp) 695 { 696 int s; 697 698 debug_called(1); 699 700 s = splbio(); 701 MLX_BIO_QINSERT(sc->mlx_bioq, bp); 702 sc->mlx_waitbufs++; 703 splx(s); 704 mlx_startio(sc); 705 return(0); 706 } 707 708 /******************************************************************************** 709 * Accept an open operation on the control device. 710 */ 711 int 712 mlx_open(struct cdev *dev, int flags, int fmt, struct thread *td) 713 { 714 int unit = minor(dev); 715 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 716 717 sc->mlx_state |= MLX_STATE_OPEN; 718 return(0); 719 } 720 721 /******************************************************************************** 722 * Accept the last close on the control device. 723 */ 724 int 725 mlx_close(struct cdev *dev, int flags, int fmt, struct thread *td) 726 { 727 int unit = minor(dev); 728 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 729 730 sc->mlx_state &= ~MLX_STATE_OPEN; 731 return (0); 732 } 733 734 /******************************************************************************** 735 * Handle controller-specific control operations. 736 */ 737 int 738 mlx_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) 739 { 740 int unit = minor(dev); 741 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 742 struct mlx_rebuild_request *rb = (struct mlx_rebuild_request *)addr; 743 struct mlx_rebuild_status *rs = (struct mlx_rebuild_status *)addr; 744 int *arg = (int *)addr; 745 struct mlx_pause *mp; 746 struct mlx_sysdrive *dr; 747 struct mlxd_softc *mlxd; 748 int i, error; 749 750 switch(cmd) { 751 /* 752 * Enumerate connected system drives; returns the first system drive's 753 * unit number if *arg is -1, or the next unit after *arg if it's 754 * a valid unit on this controller. 755 */ 756 case MLX_NEXT_CHILD: 757 /* search system drives */ 758 for (i = 0; i < MLX_MAXDRIVES; i++) { 759 /* is this one attached? */ 760 if (sc->mlx_sysdrive[i].ms_disk != 0) { 761 /* looking for the next one we come across? */ 762 if (*arg == -1) { 763 *arg = device_get_unit(sc->mlx_sysdrive[0].ms_disk); 764 return(0); 765 } 766 /* we want the one after this one */ 767 if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk)) 768 *arg = -1; 769 } 770 } 771 return(ENOENT); 772 773 /* 774 * Scan the controller to see whether new drives have appeared. 775 */ 776 case MLX_RESCAN_DRIVES: 777 mlx_startup(sc); 778 return(0); 779 780 /* 781 * Disconnect from the specified drive; it may be about to go 782 * away. 783 */ 784 case MLX_DETACH_DRIVE: /* detach one drive */ 785 786 if (((dr = mlx_findunit(sc, *arg)) == NULL) || 787 ((mlxd = device_get_softc(dr->ms_disk)) == NULL)) 788 return(ENOENT); 789 790 device_printf(dr->ms_disk, "detaching..."); 791 error = 0; 792 if (mlxd->mlxd_flags & MLXD_OPEN) { 793 error = EBUSY; 794 goto detach_out; 795 } 796 797 /* flush controller */ 798 if (mlx_flush(sc)) { 799 error = EBUSY; 800 goto detach_out; 801 } 802 803 /* nuke drive */ 804 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0) 805 goto detach_out; 806 dr->ms_disk = 0; 807 808 detach_out: 809 if (error) { 810 printf("failed\n"); 811 } else { 812 printf("done\n"); 813 } 814 return(error); 815 816 /* 817 * Pause one or more SCSI channels for a period of time, to assist 818 * in the process of hot-swapping devices. 819 * 820 * Note that at least the 3.51 firmware on the DAC960PL doesn't seem 821 * to do this right. 822 */ 823 case MLX_PAUSE_CHANNEL: /* schedule a channel pause */ 824 /* Does this command work on this firmware? */ 825 if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS)) 826 return(EOPNOTSUPP); 827 828 mp = (struct mlx_pause *)addr; 829 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) { 830 /* cancel a pending pause operation */ 831 sc->mlx_pause.mp_which = 0; 832 } else { 833 /* fix for legal channels */ 834 mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1); 835 /* check time values */ 836 if ((mp->mp_when < 0) || (mp->mp_when > 3600)) 837 return(EINVAL); 838 if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30))) 839 return(EINVAL); 840 841 /* check for a pause currently running */ 842 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) 843 return(EBUSY); 844 845 /* looks ok, go with it */ 846 sc->mlx_pause.mp_which = mp->mp_which; 847 sc->mlx_pause.mp_when = time_second + mp->mp_when; 848 sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong; 849 } 850 return(0); 851 852 /* 853 * Accept a command passthrough-style. 854 */ 855 case MLX_COMMAND: 856 return(mlx_user_command(sc, (struct mlx_usercommand *)addr)); 857 858 /* 859 * Start a rebuild on a given SCSI disk 860 */ 861 case MLX_REBUILDASYNC: 862 if (sc->mlx_background != 0) { 863 rb->rr_status = 0x0106; 864 return(EBUSY); 865 } 866 rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target); 867 switch (rb->rr_status) { 868 case 0: 869 error = 0; 870 break; 871 case 0x10000: 872 error = ENOMEM; /* couldn't set up the command */ 873 break; 874 case 0x0002: 875 error = EBUSY; 876 break; 877 case 0x0104: 878 error = EIO; 879 break; 880 case 0x0105: 881 error = ERANGE; 882 break; 883 case 0x0106: 884 error = EBUSY; 885 break; 886 default: 887 error = EINVAL; 888 break; 889 } 890 if (error == 0) 891 sc->mlx_background = MLX_BACKGROUND_REBUILD; 892 return(error); 893 894 /* 895 * Get the status of the current rebuild or consistency check. 896 */ 897 case MLX_REBUILDSTAT: 898 *rs = sc->mlx_rebuildstat; 899 return(0); 900 901 /* 902 * Return the per-controller system drive number matching the 903 * disk device number in (arg), if it happens to belong to us. 904 */ 905 case MLX_GET_SYSDRIVE: 906 error = ENOENT; 907 mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg); 908 if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) && 909 (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) { 910 error = 0; 911 *arg = mlxd->mlxd_drive - sc->mlx_sysdrive; 912 } 913 return(error); 914 915 default: 916 return(ENOTTY); 917 } 918 } 919 920 /******************************************************************************** 921 * Handle operations requested by a System Drive connected to this controller. 922 */ 923 int 924 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd, 925 caddr_t addr, int32_t flag, struct thread *td) 926 { 927 int *arg = (int *)addr; 928 int error, result; 929 930 switch(cmd) { 931 /* 932 * Return the current status of this drive. 933 */ 934 case MLXD_STATUS: 935 *arg = drive->ms_state; 936 return(0); 937 938 /* 939 * Start a background consistency check on this drive. 940 */ 941 case MLXD_CHECKASYNC: /* start a background consistency check */ 942 if (sc->mlx_background != 0) { 943 *arg = 0x0106; 944 return(EBUSY); 945 } 946 result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]); 947 switch (result) { 948 case 0: 949 error = 0; 950 break; 951 case 0x10000: 952 error = ENOMEM; /* couldn't set up the command */ 953 break; 954 case 0x0002: 955 error = EIO; 956 break; 957 case 0x0105: 958 error = ERANGE; 959 break; 960 case 0x0106: 961 error = EBUSY; 962 break; 963 default: 964 error = EINVAL; 965 break; 966 } 967 if (error == 0) 968 sc->mlx_background = MLX_BACKGROUND_CHECK; 969 *arg = result; 970 return(error); 971 972 } 973 return(ENOIOCTL); 974 } 975 976 977 /******************************************************************************** 978 ******************************************************************************** 979 Status Monitoring 980 ******************************************************************************** 981 ********************************************************************************/ 982 983 /******************************************************************************** 984 * Fire off commands to periodically check the status of connected drives. 985 */ 986 static void 987 mlx_periodic(void *data) 988 { 989 struct mlx_softc *sc = (struct mlx_softc *)data; 990 991 debug_called(1); 992 993 /* 994 * Run a bus pause? 995 */ 996 if ((sc->mlx_pause.mp_which != 0) && 997 (sc->mlx_pause.mp_when > 0) && 998 (time_second >= sc->mlx_pause.mp_when)){ 999 1000 mlx_pause_action(sc); /* pause is running */ 1001 sc->mlx_pause.mp_when = 0; 1002 sysbeep(500, hz); 1003 1004 /* 1005 * Bus pause still running? 1006 */ 1007 } else if ((sc->mlx_pause.mp_which != 0) && 1008 (sc->mlx_pause.mp_when == 0)) { 1009 1010 /* time to stop bus pause? */ 1011 if (time_second >= sc->mlx_pause.mp_howlong) { 1012 mlx_pause_action(sc); 1013 sc->mlx_pause.mp_which = 0; /* pause is complete */ 1014 sysbeep(500, hz); 1015 } else { 1016 sysbeep((time_second % 5) * 100 + 500, hz/8); 1017 } 1018 1019 /* 1020 * Run normal periodic activities? 1021 */ 1022 } else if (time_second > (sc->mlx_lastpoll + 10)) { 1023 sc->mlx_lastpoll = time_second; 1024 1025 /* 1026 * Check controller status. 1027 * 1028 * XXX Note that this may not actually launch a command in situations of high load. 1029 */ 1030 mlx_enquire(sc, (sc->mlx_iftype == MLX_IFTYPE_2) ? MLX_CMD_ENQUIRY_OLD : MLX_CMD_ENQUIRY, 1031 imax(sizeof(struct mlx_enquiry), sizeof(struct mlx_enquiry_old)), mlx_periodic_enquiry); 1032 1033 /* 1034 * Check system drive status. 1035 * 1036 * XXX This might be better left to event-driven detection, eg. I/O to an offline 1037 * drive will detect it's offline, rebuilds etc. should detect the drive is back 1038 * online. 1039 */ 1040 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES, 1041 mlx_periodic_enquiry); 1042 1043 } 1044 1045 /* get drive rebuild/check status */ 1046 /* XXX should check sc->mlx_background if this is only valid while in progress */ 1047 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild); 1048 1049 /* deal with possibly-missed interrupts and timed-out commands */ 1050 mlx_done(sc); 1051 1052 /* reschedule another poll next second or so */ 1053 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 1054 } 1055 1056 /******************************************************************************** 1057 * Handle the result of an ENQUIRY command instigated by periodic status polling. 1058 */ 1059 static void 1060 mlx_periodic_enquiry(struct mlx_command *mc) 1061 { 1062 struct mlx_softc *sc = mc->mc_sc; 1063 1064 debug_called(1); 1065 1066 /* Command completed OK? */ 1067 if (mc->mc_status != 0) { 1068 device_printf(sc->mlx_dev, "periodic enquiry failed - %s\n", mlx_diagnose_command(mc)); 1069 goto out; 1070 } 1071 1072 /* respond to command */ 1073 switch(mc->mc_mailbox[0]) { 1074 /* 1075 * This is currently a bit fruitless, as we don't know how to extract the eventlog 1076 * pointer yet. 1077 */ 1078 case MLX_CMD_ENQUIRY_OLD: 1079 { 1080 struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data; 1081 struct mlx_enquiry_old *meo = (struct mlx_enquiry_old *)mc->mc_data; 1082 int i; 1083 1084 /* convert data in-place to new format */ 1085 for (i = (sizeof(me->me_dead) / sizeof(me->me_dead[0])) - 1; i >= 0; i--) { 1086 me->me_dead[i].dd_chan = meo->me_dead[i].dd_chan; 1087 me->me_dead[i].dd_targ = meo->me_dead[i].dd_targ; 1088 } 1089 me->me_misc_flags = 0; 1090 me->me_rebuild_count = meo->me_rebuild_count; 1091 me->me_dead_count = meo->me_dead_count; 1092 me->me_critical_sd_count = meo->me_critical_sd_count; 1093 me->me_event_log_seq_num = 0; 1094 me->me_offline_sd_count = meo->me_offline_sd_count; 1095 me->me_max_commands = meo->me_max_commands; 1096 me->me_rebuild_flag = meo->me_rebuild_flag; 1097 me->me_fwmajor = meo->me_fwmajor; 1098 me->me_fwminor = meo->me_fwminor; 1099 me->me_status_flags = meo->me_status_flags; 1100 me->me_flash_age = meo->me_flash_age; 1101 for (i = (sizeof(me->me_drvsize) / sizeof(me->me_drvsize[0])) - 1; i >= 0; i--) { 1102 if (i > ((sizeof(meo->me_drvsize) / sizeof(meo->me_drvsize[0])) - 1)) { 1103 me->me_drvsize[i] = 0; /* drive beyond supported range */ 1104 } else { 1105 me->me_drvsize[i] = meo->me_drvsize[i]; 1106 } 1107 } 1108 me->me_num_sys_drvs = meo->me_num_sys_drvs; 1109 } 1110 /* FALLTHROUGH */ 1111 1112 /* 1113 * Generic controller status update. We could do more with this than just 1114 * checking the event log. 1115 */ 1116 case MLX_CMD_ENQUIRY: 1117 { 1118 struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data; 1119 1120 if (sc->mlx_currevent == -1) { 1121 /* initialise our view of the event log */ 1122 sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num; 1123 } else if ((me->me_event_log_seq_num != sc->mlx_lastevent) && !(sc->mlx_flags & MLX_EVENTLOG_BUSY)) { 1124 /* record where current events are up to */ 1125 sc->mlx_currevent = me->me_event_log_seq_num; 1126 debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent); 1127 1128 /* mark the event log as busy */ 1129 atomic_set_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY); 1130 1131 /* drain new eventlog entries */ 1132 mlx_periodic_eventlog_poll(sc); 1133 } 1134 break; 1135 } 1136 case MLX_CMD_ENQSYSDRIVE: 1137 { 1138 struct mlx_enq_sys_drive *mes = (struct mlx_enq_sys_drive *)mc->mc_data; 1139 struct mlx_sysdrive *dr; 1140 int i; 1141 1142 for (i = 0, dr = &sc->mlx_sysdrive[0]; 1143 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 1144 i++) { 1145 1146 /* has state been changed by controller? */ 1147 if (dr->ms_state != mes[i].sd_state) { 1148 switch(mes[i].sd_state) { 1149 case MLX_SYSD_OFFLINE: 1150 device_printf(dr->ms_disk, "drive offline\n"); 1151 break; 1152 case MLX_SYSD_ONLINE: 1153 device_printf(dr->ms_disk, "drive online\n"); 1154 break; 1155 case MLX_SYSD_CRITICAL: 1156 device_printf(dr->ms_disk, "drive critical\n"); 1157 break; 1158 } 1159 /* save new state */ 1160 dr->ms_state = mes[i].sd_state; 1161 } 1162 } 1163 break; 1164 } 1165 default: 1166 device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __func__, mc->mc_mailbox[0]); 1167 break; 1168 } 1169 1170 out: 1171 free(mc->mc_data, M_DEVBUF); 1172 mlx_releasecmd(mc); 1173 } 1174 1175 static void 1176 mlx_eventlog_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1177 { 1178 struct mlx_command *mc; 1179 1180 mc = (struct mlx_command *)arg; 1181 mlx_setup_dmamap(mc, segs, nsegments, error); 1182 1183 /* build the command to get one entry */ 1184 mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1, 1185 mc->mc_sc->mlx_lastevent, 0, 0, mc->mc_dataphys, 0); 1186 mc->mc_complete = mlx_periodic_eventlog_respond; 1187 mc->mc_private = mc; 1188 1189 /* start the command */ 1190 if (mlx_start(mc) != 0) { 1191 mlx_releasecmd(mc); 1192 free(mc->mc_data, M_DEVBUF); 1193 mc->mc_data = NULL; 1194 } 1195 1196 } 1197 1198 /******************************************************************************** 1199 * Instigate a poll for one event log message on (sc). 1200 * We only poll for one message at a time, to keep our command usage down. 1201 */ 1202 static void 1203 mlx_periodic_eventlog_poll(struct mlx_softc *sc) 1204 { 1205 struct mlx_command *mc; 1206 void *result = NULL; 1207 int error = 0; 1208 1209 debug_called(1); 1210 1211 /* get ourselves a command buffer */ 1212 error = 1; 1213 if ((mc = mlx_alloccmd(sc)) == NULL) 1214 goto out; 1215 1216 /* allocate the response structure */ 1217 if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF, 1218 M_NOWAIT)) == NULL) 1219 goto out; 1220 1221 /* get a command slot */ 1222 if (mlx_getslot(mc)) 1223 goto out; 1224 1225 /* map the command so the controller can see it */ 1226 mc->mc_data = result; 1227 mc->mc_length = /*sizeof(struct mlx_eventlog_entry)*/1024; 1228 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, 1229 mc->mc_length, mlx_eventlog_cb, mc, BUS_DMA_NOWAIT); 1230 1231 out: 1232 if (error != 0) { 1233 if (mc != NULL) 1234 mlx_releasecmd(mc); 1235 if ((result != NULL) && (mc->mc_data != NULL)) 1236 free(result, M_DEVBUF); 1237 } 1238 } 1239 1240 /******************************************************************************** 1241 * Handle the result of polling for a log message, generate diagnostic output. 1242 * If this wasn't the last message waiting for us, we'll go collect another. 1243 */ 1244 static char *mlx_sense_messages[] = { 1245 "because write recovery failed", 1246 "because of SCSI bus reset failure", 1247 "because of double check condition", 1248 "because it was removed", 1249 "because of gross error on SCSI chip", 1250 "because of bad tag returned from drive", 1251 "because of timeout on SCSI command", 1252 "because of reset SCSI command issued from system", 1253 "because busy or parity error count exceeded limit", 1254 "because of 'kill drive' command from system", 1255 "because of selection timeout", 1256 "due to SCSI phase sequence error", 1257 "due to unknown status" 1258 }; 1259 1260 static void 1261 mlx_periodic_eventlog_respond(struct mlx_command *mc) 1262 { 1263 struct mlx_softc *sc = mc->mc_sc; 1264 struct mlx_eventlog_entry *el = (struct mlx_eventlog_entry *)mc->mc_data; 1265 char *reason; 1266 1267 debug_called(1); 1268 1269 sc->mlx_lastevent++; /* next message... */ 1270 if (mc->mc_status == 0) { 1271 1272 /* handle event log message */ 1273 switch(el->el_type) { 1274 /* 1275 * This is the only sort of message we understand at the moment. 1276 * The tests here are probably incomplete. 1277 */ 1278 case MLX_LOGMSG_SENSE: /* sense data */ 1279 /* Mylex vendor-specific message indicating a drive was killed? */ 1280 if ((el->el_sensekey == 9) && 1281 (el->el_asc == 0x80)) { 1282 if (el->el_asq < (sizeof(mlx_sense_messages) / sizeof(mlx_sense_messages[0]))) { 1283 reason = mlx_sense_messages[el->el_asq]; 1284 } else { 1285 reason = "for unknown reason"; 1286 } 1287 device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n", 1288 el->el_channel, el->el_target, reason); 1289 } 1290 /* SCSI drive was reset? */ 1291 if ((el->el_sensekey == 6) && (el->el_asc == 0x29)) { 1292 device_printf(sc->mlx_dev, "physical drive %d:%d reset\n", 1293 el->el_channel, el->el_target); 1294 } 1295 /* SCSI drive error? */ 1296 if (!((el->el_sensekey == 0) || 1297 ((el->el_sensekey == 2) && 1298 (el->el_asc == 0x04) && 1299 ((el->el_asq == 0x01) || 1300 (el->el_asq == 0x02))))) { 1301 device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n", 1302 el->el_channel, el->el_target, el->el_sensekey, el->el_asc, el->el_asq); 1303 device_printf(sc->mlx_dev, " info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":"); 1304 } 1305 break; 1306 1307 default: 1308 device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type); 1309 break; 1310 } 1311 } else { 1312 device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc)); 1313 /* give up on all the outstanding messages, as we may have come unsynched */ 1314 sc->mlx_lastevent = sc->mlx_currevent; 1315 } 1316 1317 /* dispose of command and data */ 1318 free(mc->mc_data, M_DEVBUF); 1319 mlx_releasecmd(mc); 1320 1321 /* is there another message to obtain? */ 1322 if (sc->mlx_lastevent != sc->mlx_currevent) { 1323 mlx_periodic_eventlog_poll(sc); 1324 } else { 1325 /* clear log-busy status */ 1326 atomic_clear_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY); 1327 } 1328 } 1329 1330 /******************************************************************************** 1331 * Handle check/rebuild operations in progress. 1332 */ 1333 static void 1334 mlx_periodic_rebuild(struct mlx_command *mc) 1335 { 1336 struct mlx_softc *sc = mc->mc_sc; 1337 struct mlx_rebuild_status *mr = (struct mlx_rebuild_status *)mc->mc_data; 1338 1339 switch(mc->mc_status) { 1340 case 0: /* operation running, update stats */ 1341 sc->mlx_rebuildstat = *mr; 1342 1343 /* spontaneous rebuild/check? */ 1344 if (sc->mlx_background == 0) { 1345 sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS; 1346 device_printf(sc->mlx_dev, "background check/rebuild operation started\n"); 1347 } 1348 break; 1349 1350 case 0x0105: /* nothing running, finalise stats and report */ 1351 switch(sc->mlx_background) { 1352 case MLX_BACKGROUND_CHECK: 1353 device_printf(sc->mlx_dev, "consistency check completed\n"); /* XXX print drive? */ 1354 break; 1355 case MLX_BACKGROUND_REBUILD: 1356 device_printf(sc->mlx_dev, "drive rebuild completed\n"); /* XXX print channel/target? */ 1357 break; 1358 case MLX_BACKGROUND_SPONTANEOUS: 1359 default: 1360 /* if we have previously been non-idle, report the transition */ 1361 if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) { 1362 device_printf(sc->mlx_dev, "background check/rebuild operation completed\n"); 1363 } 1364 } 1365 sc->mlx_background = 0; 1366 sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE; 1367 break; 1368 } 1369 free(mc->mc_data, M_DEVBUF); 1370 mlx_releasecmd(mc); 1371 } 1372 1373 /******************************************************************************** 1374 ******************************************************************************** 1375 Channel Pause 1376 ******************************************************************************** 1377 ********************************************************************************/ 1378 1379 /******************************************************************************** 1380 * It's time to perform a channel pause action for (sc), either start or stop 1381 * the pause. 1382 */ 1383 static void 1384 mlx_pause_action(struct mlx_softc *sc) 1385 { 1386 struct mlx_command *mc; 1387 int failsafe, i, command; 1388 1389 /* What are we doing here? */ 1390 if (sc->mlx_pause.mp_when == 0) { 1391 command = MLX_CMD_STARTCHANNEL; 1392 failsafe = 0; 1393 1394 } else { 1395 command = MLX_CMD_STOPCHANNEL; 1396 1397 /* 1398 * Channels will always start again after the failsafe period, 1399 * which is specified in multiples of 30 seconds. 1400 * This constrains us to a maximum pause of 450 seconds. 1401 */ 1402 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30; 1403 if (failsafe > 0xf) { 1404 failsafe = 0xf; 1405 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5; 1406 } 1407 } 1408 1409 /* build commands for every channel requested */ 1410 for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) { 1411 if ((1 << i) & sc->mlx_pause.mp_which) { 1412 1413 /* get ourselves a command buffer */ 1414 if ((mc = mlx_alloccmd(sc)) == NULL) 1415 goto fail; 1416 /* get a command slot */ 1417 mc->mc_flags |= MLX_CMD_PRIORITY; 1418 if (mlx_getslot(mc)) 1419 goto fail; 1420 1421 /* build the command */ 1422 mlx_make_type2(mc, command, (failsafe << 4) | i, 0, 0, 0, 0, 0, 0, 0); 1423 mc->mc_complete = mlx_pause_done; 1424 mc->mc_private = sc; /* XXX not needed */ 1425 if (mlx_start(mc)) 1426 goto fail; 1427 /* command submitted OK */ 1428 return; 1429 1430 fail: 1431 device_printf(sc->mlx_dev, "%s failed for channel %d\n", 1432 command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", i); 1433 if (mc != NULL) 1434 mlx_releasecmd(mc); 1435 } 1436 } 1437 } 1438 1439 static void 1440 mlx_pause_done(struct mlx_command *mc) 1441 { 1442 struct mlx_softc *sc = mc->mc_sc; 1443 int command = mc->mc_mailbox[0]; 1444 int channel = mc->mc_mailbox[2] & 0xf; 1445 1446 if (mc->mc_status != 0) { 1447 device_printf(sc->mlx_dev, "%s command failed - %s\n", 1448 command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc)); 1449 } else if (command == MLX_CMD_STOPCHANNEL) { 1450 device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n", 1451 channel, (long)(sc->mlx_pause.mp_howlong - time_second)); 1452 } else { 1453 device_printf(sc->mlx_dev, "channel %d resuming\n", channel); 1454 } 1455 mlx_releasecmd(mc); 1456 } 1457 1458 /******************************************************************************** 1459 ******************************************************************************** 1460 Command Submission 1461 ******************************************************************************** 1462 ********************************************************************************/ 1463 1464 static void 1465 mlx_enquire_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1466 { 1467 struct mlx_softc *sc; 1468 struct mlx_command *mc; 1469 1470 mc = (struct mlx_command *)arg; 1471 if (error) 1472 return; 1473 1474 mlx_setup_dmamap(mc, segs, nsegments, error); 1475 1476 /* build an enquiry command */ 1477 sc = mc->mc_sc; 1478 mlx_make_type2(mc, mc->mc_command, 0, 0, 0, 0, 0, 0, mc->mc_dataphys, 0); 1479 1480 /* do we want a completion callback? */ 1481 if (mc->mc_complete != NULL) { 1482 if ((error = mlx_start(mc)) != 0) 1483 return; 1484 } else { 1485 /* run the command in either polled or wait mode */ 1486 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : 1487 mlx_poll_command(mc)) 1488 return; 1489 1490 /* command completed OK? */ 1491 if (mc->mc_status != 0) { 1492 device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n", 1493 mlx_diagnose_command(mc)); 1494 return; 1495 } 1496 } 1497 } 1498 1499 /******************************************************************************** 1500 * Perform an Enquiry command using a type-3 command buffer and a return a single 1501 * linear result buffer. If the completion function is specified, it will 1502 * be called with the completed command (and the result response will not be 1503 * valid until that point). Otherwise, the command will either be busy-waited 1504 * for (interrupts not enabled), or slept for. 1505 */ 1506 static void * 1507 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc)) 1508 { 1509 struct mlx_command *mc; 1510 void *result; 1511 int error; 1512 1513 debug_called(1); 1514 1515 /* get ourselves a command buffer */ 1516 error = 1; 1517 result = NULL; 1518 if ((mc = mlx_alloccmd(sc)) == NULL) 1519 goto out; 1520 /* allocate the response structure */ 1521 if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL) 1522 goto out; 1523 /* get a command slot */ 1524 mc->mc_flags |= MLX_CMD_PRIORITY | MLX_CMD_DATAOUT; 1525 if (mlx_getslot(mc)) 1526 goto out; 1527 1528 /* map the command so the controller can see it */ 1529 mc->mc_data = result; 1530 mc->mc_length = bufsize; 1531 mc->mc_command = command; 1532 1533 if (complete != NULL) { 1534 mc->mc_complete = complete; 1535 mc->mc_private = mc; 1536 } 1537 1538 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, 1539 mc->mc_length, mlx_enquire_cb, mc, BUS_DMA_NOWAIT); 1540 1541 out: 1542 /* we got a command, but nobody else will free it */ 1543 if ((mc != NULL) && (mc->mc_complete == NULL)) 1544 mlx_releasecmd(mc); 1545 /* we got an error, and we allocated a result */ 1546 if ((error != 0) && (result != NULL)) { 1547 free(result, M_DEVBUF); 1548 result = NULL; 1549 } 1550 return(result); 1551 } 1552 1553 1554 /******************************************************************************** 1555 * Perform a Flush command on the nominated controller. 1556 * 1557 * May be called with interrupts enabled or disabled; will not return until 1558 * the flush operation completes or fails. 1559 */ 1560 static int 1561 mlx_flush(struct mlx_softc *sc) 1562 { 1563 struct mlx_command *mc; 1564 int error; 1565 1566 debug_called(1); 1567 1568 /* get ourselves a command buffer */ 1569 error = 1; 1570 if ((mc = mlx_alloccmd(sc)) == NULL) 1571 goto out; 1572 /* get a command slot */ 1573 if (mlx_getslot(mc)) 1574 goto out; 1575 1576 /* build a flush command */ 1577 mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0); 1578 1579 /* can't assume that interrupts are going to work here, so play it safe */ 1580 if (mlx_poll_command(mc)) 1581 goto out; 1582 1583 /* command completed OK? */ 1584 if (mc->mc_status != 0) { 1585 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc)); 1586 goto out; 1587 } 1588 1589 error = 0; /* success */ 1590 out: 1591 if (mc != NULL) 1592 mlx_releasecmd(mc); 1593 return(error); 1594 } 1595 1596 /******************************************************************************** 1597 * Start a background consistency check on (drive). 1598 * 1599 * May be called with interrupts enabled or disabled; will return as soon as the 1600 * operation has started or been refused. 1601 */ 1602 static int 1603 mlx_check(struct mlx_softc *sc, int drive) 1604 { 1605 struct mlx_command *mc; 1606 int error; 1607 1608 debug_called(1); 1609 1610 /* get ourselves a command buffer */ 1611 error = 0x10000; 1612 if ((mc = mlx_alloccmd(sc)) == NULL) 1613 goto out; 1614 /* get a command slot */ 1615 if (mlx_getslot(mc)) 1616 goto out; 1617 1618 /* build a checkasync command, set the "fix it" flag */ 1619 mlx_make_type2(mc, MLX_CMD_CHECKASYNC, 0, 0, 0, 0, 0, drive | 0x80, 0, 0); 1620 1621 /* start the command and wait for it to be returned */ 1622 if (mlx_wait_command(mc)) 1623 goto out; 1624 1625 /* command completed OK? */ 1626 if (mc->mc_status != 0) { 1627 device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc)); 1628 } else { 1629 device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started"); 1630 } 1631 error = mc->mc_status; 1632 1633 out: 1634 if (mc != NULL) 1635 mlx_releasecmd(mc); 1636 return(error); 1637 } 1638 1639 /******************************************************************************** 1640 * Start a background rebuild of the physical drive at (channel),(target). 1641 * 1642 * May be called with interrupts enabled or disabled; will return as soon as the 1643 * operation has started or been refused. 1644 */ 1645 static int 1646 mlx_rebuild(struct mlx_softc *sc, int channel, int target) 1647 { 1648 struct mlx_command *mc; 1649 int error; 1650 1651 debug_called(1); 1652 1653 /* get ourselves a command buffer */ 1654 error = 0x10000; 1655 if ((mc = mlx_alloccmd(sc)) == NULL) 1656 goto out; 1657 /* get a command slot */ 1658 if (mlx_getslot(mc)) 1659 goto out; 1660 1661 /* build a checkasync command, set the "fix it" flag */ 1662 mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0); 1663 1664 /* start the command and wait for it to be returned */ 1665 if (mlx_wait_command(mc)) 1666 goto out; 1667 1668 /* command completed OK? */ 1669 if (mc->mc_status != 0) { 1670 device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc)); 1671 } else { 1672 device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target); 1673 } 1674 error = mc->mc_status; 1675 1676 out: 1677 if (mc != NULL) 1678 mlx_releasecmd(mc); 1679 return(error); 1680 } 1681 1682 /******************************************************************************** 1683 * Run the command (mc) and return when it completes. 1684 * 1685 * Interrupts need to be enabled; returns nonzero on error. 1686 */ 1687 static int 1688 mlx_wait_command(struct mlx_command *mc) 1689 { 1690 struct mlx_softc *sc = mc->mc_sc; 1691 int error, count; 1692 1693 debug_called(1); 1694 1695 mc->mc_complete = NULL; 1696 mc->mc_private = mc; /* wake us when you're done */ 1697 if ((error = mlx_start(mc)) != 0) 1698 return(error); 1699 1700 count = 0; 1701 /* XXX better timeout? */ 1702 while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) { 1703 tsleep(mc->mc_private, PRIBIO | PCATCH, "mlxwcmd", hz); 1704 } 1705 1706 if (mc->mc_status != 0) { 1707 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc)); 1708 return(EIO); 1709 } 1710 return(0); 1711 } 1712 1713 1714 /******************************************************************************** 1715 * Start the command (mc) and busy-wait for it to complete. 1716 * 1717 * Should only be used when interrupts can't be relied upon. Returns 0 on 1718 * success, nonzero on error. 1719 * Successfully completed commands are dequeued. 1720 */ 1721 static int 1722 mlx_poll_command(struct mlx_command *mc) 1723 { 1724 struct mlx_softc *sc = mc->mc_sc; 1725 int error, count, s; 1726 1727 debug_called(1); 1728 1729 mc->mc_complete = NULL; 1730 mc->mc_private = NULL; /* we will poll for it */ 1731 if ((error = mlx_start(mc)) != 0) 1732 return(error); 1733 1734 count = 0; 1735 do { 1736 /* poll for completion */ 1737 mlx_done(mc->mc_sc); 1738 1739 } while ((mc->mc_status == MLX_STATUS_BUSY) && (count++ < 15000000)); 1740 if (mc->mc_status != MLX_STATUS_BUSY) { 1741 s = splbio(); 1742 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 1743 splx(s); 1744 return(0); 1745 } 1746 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc)); 1747 return(EIO); 1748 } 1749 1750 void 1751 mlx_startio_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1752 { 1753 struct mlx_command *mc; 1754 struct mlxd_softc *mlxd; 1755 struct mlx_softc *sc; 1756 mlx_bio *bp; 1757 int blkcount; 1758 int driveno; 1759 int cmd; 1760 1761 mc = (struct mlx_command *)arg; 1762 mlx_setup_dmamap(mc, segs, nsegments, error); 1763 1764 sc = mc->mc_sc; 1765 bp = mc->mc_private; 1766 1767 if (MLX_BIO_IS_READ(bp)) { 1768 mc->mc_flags |= MLX_CMD_DATAIN; 1769 cmd = MLX_CMD_READSG; 1770 } else { 1771 mc->mc_flags |= MLX_CMD_DATAOUT; 1772 cmd = MLX_CMD_WRITESG; 1773 } 1774 1775 /* build a suitable I/O command (assumes 512-byte rounded transfers) */ 1776 mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp); 1777 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive; 1778 blkcount = (MLX_BIO_LENGTH(bp) + MLX_BLKSIZE - 1) / MLX_BLKSIZE; 1779 1780 if ((MLX_BIO_LBA(bp) + blkcount) > sc->mlx_sysdrive[driveno].ms_size) 1781 device_printf(sc->mlx_dev, 1782 "I/O beyond end of unit (%lld,%d > %lu)\n", 1783 (long long)MLX_BIO_LBA(bp), blkcount, 1784 (u_long)sc->mlx_sysdrive[driveno].ms_size); 1785 1786 /* 1787 * Build the I/O command. Note that the SG list type bits are set to zero, 1788 * denoting the format of SG list that we are using. 1789 */ 1790 if (sc->mlx_iftype == MLX_IFTYPE_2) { 1791 mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : 1792 MLX_CMD_READSG_OLD, 1793 blkcount & 0xff, /* xfer length low byte */ 1794 MLX_BIO_LBA(bp), /* physical block number */ 1795 driveno, /* target drive number */ 1796 mc->mc_sgphys, /* location of SG list */ 1797 mc->mc_nsgent & 0x3f); /* size of SG list */ 1798 } else { 1799 mlx_make_type5(mc, cmd, 1800 blkcount & 0xff, /* xfer length low byte */ 1801 (driveno << 3) | ((blkcount >> 8) & 0x07), 1802 /* target+length high 3 bits */ 1803 MLX_BIO_LBA(bp), /* physical block number */ 1804 mc->mc_sgphys, /* location of SG list */ 1805 mc->mc_nsgent & 0x3f); /* size of SG list */ 1806 } 1807 1808 /* try to give command to controller */ 1809 if (mlx_start(mc) != 0) { 1810 /* fail the command */ 1811 mc->mc_status = MLX_STATUS_WEDGED; 1812 mlx_completeio(mc); 1813 } 1814 } 1815 1816 /******************************************************************************** 1817 * Pull as much work off the softc's work queue as possible and give it to the 1818 * controller. Leave a couple of slots free for emergencies. 1819 * 1820 * Must be called at splbio or in an equivalent fashion that prevents 1821 * reentry or activity on the bioq. 1822 */ 1823 static void 1824 mlx_startio(struct mlx_softc *sc) 1825 { 1826 struct mlx_command *mc; 1827 mlx_bio *bp; 1828 int s; 1829 int error; 1830 1831 /* avoid reentrancy */ 1832 if (mlx_lock_tas(sc, MLX_LOCK_STARTING)) 1833 return; 1834 1835 /* spin until something prevents us from doing any work */ 1836 s = splbio(); 1837 for (;;) { 1838 1839 /* see if there's work to be done */ 1840 if ((bp = MLX_BIO_QFIRST(sc->mlx_bioq)) == NULL) 1841 break; 1842 /* get a command */ 1843 if ((mc = mlx_alloccmd(sc)) == NULL) 1844 break; 1845 /* get a slot for the command */ 1846 if (mlx_getslot(mc) != 0) { 1847 mlx_releasecmd(mc); 1848 break; 1849 } 1850 /* get the buf containing our work */ 1851 MLX_BIO_QREMOVE(sc->mlx_bioq, bp); 1852 sc->mlx_waitbufs--; 1853 splx(s); 1854 1855 /* connect the buf to the command */ 1856 mc->mc_complete = mlx_completeio; 1857 mc->mc_private = bp; 1858 mc->mc_data = MLX_BIO_DATA(bp); 1859 mc->mc_length = MLX_BIO_LENGTH(bp); 1860 1861 /* map the command so the controller can work with it */ 1862 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, 1863 mc->mc_length, mlx_startio_cb, mc, 0); 1864 if (error == EINPROGRESS) { 1865 break; 1866 } 1867 1868 s = splbio(); 1869 } 1870 splx(s); 1871 mlx_lock_clr(sc, MLX_LOCK_STARTING); 1872 } 1873 1874 /******************************************************************************** 1875 * Handle completion of an I/O command. 1876 */ 1877 static void 1878 mlx_completeio(struct mlx_command *mc) 1879 { 1880 struct mlx_softc *sc = mc->mc_sc; 1881 mlx_bio *bp = (mlx_bio *)mc->mc_private; 1882 struct mlxd_softc *mlxd = (struct mlxd_softc *)MLX_BIO_SOFTC(bp); 1883 1884 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */ 1885 MLX_BIO_SET_ERROR(bp, EIO); 1886 1887 switch(mc->mc_status) { 1888 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */ 1889 device_printf(mlxd->mlxd_dev, "drive offline\n"); 1890 /* should signal this with a return code */ 1891 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE; 1892 break; 1893 1894 default: /* other I/O error */ 1895 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc)); 1896 #if 0 1897 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n", 1898 MLX_BIO_LENGTH(bp), MLX_BIO_LENGTH(bp) / MLX_BLKSIZE, MLX_BIO_LBA(bp)); 1899 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " "); 1900 #endif 1901 break; 1902 } 1903 } 1904 mlx_releasecmd(mc); 1905 mlxd_intr(bp); 1906 } 1907 1908 void 1909 mlx_user_cb(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1910 { 1911 struct mlx_usercommand *mu; 1912 struct mlx_command *mc; 1913 struct mlx_dcdb *dcdb; 1914 1915 mc = (struct mlx_command *)arg; 1916 if (error) 1917 return; 1918 1919 mlx_setup_dmamap(mc, segs, nsegments, error); 1920 1921 mu = (struct mlx_usercommand *)mc->mc_private; 1922 dcdb = NULL; 1923 1924 /* 1925 * If this is a passthrough SCSI command, the DCDB is packed at the 1926 * beginning of the data area. Fix up the DCDB to point to the correct 1927 * physical address and override any bufptr supplied by the caller since 1928 * we know what it's meant to be. 1929 */ 1930 if (mc->mc_mailbox[0] == MLX_CMD_DIRECT_CDB) { 1931 dcdb = (struct mlx_dcdb *)mc->mc_data; 1932 dcdb->dcdb_physaddr = mc->mc_dataphys + sizeof(*dcdb); 1933 mu->mu_bufptr = 8; 1934 } 1935 1936 /* 1937 * If there's a data buffer, fix up the command's buffer pointer. 1938 */ 1939 if (mu->mu_datasize > 0) { 1940 mc->mc_mailbox[mu->mu_bufptr ] = mc->mc_dataphys & 0xff; 1941 mc->mc_mailbox[mu->mu_bufptr + 1] = (mc->mc_dataphys >> 8) & 0xff; 1942 mc->mc_mailbox[mu->mu_bufptr + 2] = (mc->mc_dataphys >> 16) & 0xff; 1943 mc->mc_mailbox[mu->mu_bufptr + 3] = (mc->mc_dataphys >> 24) & 0xff; 1944 } 1945 debug(0, "command fixup"); 1946 1947 /* submit the command and wait */ 1948 if (mlx_wait_command(mc) != 0) 1949 return; 1950 1951 } 1952 1953 /******************************************************************************** 1954 * Take a command from user-space and try to run it. 1955 * 1956 * XXX Note that this can't perform very much in the way of error checking, and 1957 * as such, applications _must_ be considered trustworthy. 1958 * XXX Commands using S/G for data are not supported. 1959 */ 1960 static int 1961 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu) 1962 { 1963 struct mlx_command *mc; 1964 void *kbuf; 1965 int error; 1966 1967 debug_called(0); 1968 1969 kbuf = NULL; 1970 mc = NULL; 1971 error = ENOMEM; 1972 1973 /* get ourselves a command and copy in from user space */ 1974 if ((mc = mlx_alloccmd(sc)) == NULL) 1975 return(error); 1976 bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox)); 1977 debug(0, "got command buffer"); 1978 1979 /* 1980 * if we need a buffer for data transfer, allocate one and copy in its 1981 * initial contents 1982 */ 1983 if (mu->mu_datasize > 0) { 1984 if (mu->mu_datasize > MAXPHYS) { 1985 error = EINVAL; 1986 goto out; 1987 } 1988 if (((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) || 1989 (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize))) 1990 goto out; 1991 debug(0, "got kernel buffer"); 1992 } 1993 1994 /* get a command slot */ 1995 if (mlx_getslot(mc)) 1996 goto out; 1997 debug(0, "got a slot"); 1998 1999 if (mu->mu_datasize > 0) { 2000 2001 /* range check the pointer to physical buffer address */ 2002 if ((mu->mu_bufptr < 0) || (mu->mu_bufptr > (sizeof(mu->mu_command) - 2003 sizeof(u_int32_t)))) { 2004 error = EINVAL; 2005 goto out; 2006 } 2007 } 2008 2009 /* map the command so the controller can see it */ 2010 mc->mc_data = kbuf; 2011 mc->mc_length = mu->mu_datasize; 2012 mc->mc_private = mu; 2013 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, 2014 mc->mc_length, mlx_user_cb, mc, BUS_DMA_NOWAIT); 2015 2016 /* copy out status and data */ 2017 mu->mu_status = mc->mc_status; 2018 if ((mu->mu_datasize > 0) && 2019 ((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize)))) 2020 goto out; 2021 2022 error = 0; 2023 2024 out: 2025 mlx_releasecmd(mc); 2026 if (kbuf != NULL) 2027 free(kbuf, M_DEVBUF); 2028 return(error); 2029 } 2030 2031 /******************************************************************************** 2032 ******************************************************************************** 2033 Command I/O to Controller 2034 ******************************************************************************** 2035 ********************************************************************************/ 2036 2037 /******************************************************************************** 2038 * Find a free command slot for (mc). 2039 * 2040 * Don't hand out a slot to a normal-priority command unless there are at least 2041 * 4 slots free for priority commands. 2042 */ 2043 static int 2044 mlx_getslot(struct mlx_command *mc) 2045 { 2046 struct mlx_softc *sc = mc->mc_sc; 2047 int s, slot, limit; 2048 2049 debug_called(1); 2050 2051 /* 2052 * Enforce slot-usage limit, if we have the required information. 2053 */ 2054 if (sc->mlx_enq2 != NULL) { 2055 limit = sc->mlx_enq2->me_max_commands; 2056 } else { 2057 limit = 2; 2058 } 2059 if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? limit : limit - 4)) 2060 return(EBUSY); 2061 2062 /* 2063 * Allocate an outstanding command slot 2064 * 2065 * XXX linear search is slow 2066 */ 2067 s = splbio(); 2068 for (slot = 0; slot < limit; slot++) { 2069 debug(2, "try slot %d", slot); 2070 if (sc->mlx_busycmd[slot] == NULL) 2071 break; 2072 } 2073 if (slot < limit) { 2074 sc->mlx_busycmd[slot] = mc; 2075 sc->mlx_busycmds++; 2076 } 2077 splx(s); 2078 2079 /* out of slots? */ 2080 if (slot >= limit) 2081 return(EBUSY); 2082 2083 debug(2, "got slot %d", slot); 2084 mc->mc_slot = slot; 2085 return(0); 2086 } 2087 2088 /******************************************************************************** 2089 * Map/unmap (mc)'s data in the controller's addressable space. 2090 */ 2091 static void 2092 mlx_setup_dmamap(struct mlx_command *mc, bus_dma_segment_t *segs, int nsegments, 2093 int error) 2094 { 2095 struct mlx_softc *sc = mc->mc_sc; 2096 struct mlx_sgentry *sg; 2097 int i; 2098 2099 debug_called(1); 2100 2101 /* XXX should be unnecessary */ 2102 if (sc->mlx_enq2 && (nsegments > sc->mlx_enq2->me_max_sg)) 2103 panic("MLX: too many s/g segments (%d, max %d)", nsegments, 2104 sc->mlx_enq2->me_max_sg); 2105 2106 /* get base address of s/g table */ 2107 sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG); 2108 2109 /* save s/g table information in command */ 2110 mc->mc_nsgent = nsegments; 2111 mc->mc_sgphys = sc->mlx_sgbusaddr + 2112 (mc->mc_slot * MLX_NSEG * sizeof(struct mlx_sgentry)); 2113 mc->mc_dataphys = segs[0].ds_addr; 2114 2115 /* populate s/g table */ 2116 for (i = 0; i < nsegments; i++, sg++) { 2117 sg->sg_addr = segs[i].ds_addr; 2118 sg->sg_count = segs[i].ds_len; 2119 } 2120 2121 /* Make sure the buffers are visible on the bus. */ 2122 if (mc->mc_flags & MLX_CMD_DATAIN) 2123 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, 2124 BUS_DMASYNC_PREREAD); 2125 if (mc->mc_flags & MLX_CMD_DATAOUT) 2126 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, 2127 BUS_DMASYNC_PREWRITE); 2128 } 2129 2130 static void 2131 mlx_unmapcmd(struct mlx_command *mc) 2132 { 2133 struct mlx_softc *sc = mc->mc_sc; 2134 2135 debug_called(1); 2136 2137 /* if the command involved data at all */ 2138 if (mc->mc_data != NULL) { 2139 2140 if (mc->mc_flags & MLX_CMD_DATAIN) 2141 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD); 2142 if (mc->mc_flags & MLX_CMD_DATAOUT) 2143 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE); 2144 2145 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap); 2146 } 2147 } 2148 2149 /******************************************************************************** 2150 * Try to deliver (mc) to the controller. 2151 * 2152 * Can be called at any interrupt level, with or without interrupts enabled. 2153 */ 2154 static int 2155 mlx_start(struct mlx_command *mc) 2156 { 2157 struct mlx_softc *sc = mc->mc_sc; 2158 int i, s, done; 2159 2160 debug_called(1); 2161 2162 /* save the slot number as ident so we can handle this command when complete */ 2163 mc->mc_mailbox[0x1] = mc->mc_slot; 2164 2165 /* mark the command as currently being processed */ 2166 mc->mc_status = MLX_STATUS_BUSY; 2167 2168 /* set a default 60-second timeout XXX tunable? XXX not currently used */ 2169 mc->mc_timeout = time_second + 60; 2170 2171 /* spin waiting for the mailbox */ 2172 for (i = 100000, done = 0; (i > 0) && !done; i--) { 2173 s = splbio(); 2174 if (sc->mlx_tryqueue(sc, mc)) { 2175 done = 1; 2176 /* move command to work queue */ 2177 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link); 2178 } 2179 splx(s); /* drop spl to allow completion interrupts */ 2180 } 2181 2182 /* command is enqueued */ 2183 if (done) 2184 return(0); 2185 2186 /* 2187 * We couldn't get the controller to take the command. Revoke the slot 2188 * that the command was given and return it with a bad status. 2189 */ 2190 sc->mlx_busycmd[mc->mc_slot] = NULL; 2191 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n"); 2192 mc->mc_status = MLX_STATUS_WEDGED; 2193 mlx_complete(sc); 2194 return(EIO); 2195 } 2196 2197 /******************************************************************************** 2198 * Poll the controller (sc) for completed commands. 2199 * Update command status and free slots for reuse. If any slots were freed, 2200 * new commands may be posted. 2201 * 2202 * Returns nonzero if one or more commands were completed. 2203 */ 2204 static int 2205 mlx_done(struct mlx_softc *sc) 2206 { 2207 struct mlx_command *mc; 2208 int s, result; 2209 u_int8_t slot; 2210 u_int16_t status; 2211 2212 debug_called(2); 2213 2214 result = 0; 2215 2216 /* loop collecting completed commands */ 2217 s = splbio(); 2218 for (;;) { 2219 /* poll for a completed command's identifier and status */ 2220 if (sc->mlx_findcomplete(sc, &slot, &status)) { 2221 result = 1; 2222 mc = sc->mlx_busycmd[slot]; /* find command */ 2223 if (mc != NULL) { /* paranoia */ 2224 if (mc->mc_status == MLX_STATUS_BUSY) { 2225 mc->mc_status = status; /* save status */ 2226 2227 /* free slot for reuse */ 2228 sc->mlx_busycmd[slot] = NULL; 2229 sc->mlx_busycmds--; 2230 } else { 2231 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot); 2232 } 2233 } else { 2234 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot); 2235 } 2236 } else { 2237 break; 2238 } 2239 } 2240 splx(s); 2241 2242 /* if we've completed any commands, try posting some more */ 2243 if (result) 2244 mlx_startio(sc); 2245 2246 /* handle completion and timeouts */ 2247 mlx_complete(sc); 2248 2249 return(result); 2250 } 2251 2252 /******************************************************************************** 2253 * Perform post-completion processing for commands on (sc). 2254 */ 2255 static void 2256 mlx_complete(struct mlx_softc *sc) 2257 { 2258 struct mlx_command *mc, *nc; 2259 int s, count; 2260 2261 debug_called(2); 2262 2263 /* avoid reentrancy XXX might want to signal and request a restart */ 2264 if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING)) 2265 return; 2266 2267 s = splbio(); 2268 count = 0; 2269 2270 /* scan the list of busy/done commands */ 2271 mc = TAILQ_FIRST(&sc->mlx_work); 2272 while (mc != NULL) { 2273 nc = TAILQ_NEXT(mc, mc_link); 2274 2275 /* Command has been completed in some fashion */ 2276 if (mc->mc_status != MLX_STATUS_BUSY) { 2277 2278 /* unmap the command's data buffer */ 2279 mlx_unmapcmd(mc); 2280 /* 2281 * Does the command have a completion handler? 2282 */ 2283 if (mc->mc_complete != NULL) { 2284 /* remove from list and give to handler */ 2285 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 2286 mc->mc_complete(mc); 2287 2288 /* 2289 * Is there a sleeper waiting on this command? 2290 */ 2291 } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */ 2292 2293 /* remove from list and wake up sleeper */ 2294 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 2295 wakeup_one(mc->mc_private); 2296 2297 /* 2298 * Leave the command for a caller that's polling for it. 2299 */ 2300 } else { 2301 } 2302 } 2303 mc = nc; 2304 } 2305 splx(s); 2306 2307 mlx_lock_clr(sc, MLX_LOCK_COMPLETING); 2308 } 2309 2310 /******************************************************************************** 2311 ******************************************************************************** 2312 Command Buffer Management 2313 ******************************************************************************** 2314 ********************************************************************************/ 2315 2316 /******************************************************************************** 2317 * Get a new command buffer. 2318 * 2319 * This may return NULL in low-memory cases. 2320 * 2321 * Note that using malloc() is expensive (the command buffer is << 1 page) but 2322 * necessary if we are to be a loadable module before the zone allocator is fixed. 2323 * 2324 * If possible, we recycle a command buffer that's been used before. 2325 * 2326 * XXX Note that command buffers are not cleaned out - it is the caller's 2327 * responsibility to ensure that all required fields are filled in before 2328 * using a buffer. 2329 */ 2330 static struct mlx_command * 2331 mlx_alloccmd(struct mlx_softc *sc) 2332 { 2333 struct mlx_command *mc; 2334 int error; 2335 int s; 2336 2337 debug_called(1); 2338 2339 s = splbio(); 2340 if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) 2341 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link); 2342 splx(s); 2343 2344 /* allocate a new command buffer? */ 2345 if (mc == NULL) { 2346 mc = (struct mlx_command *)malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT | M_ZERO); 2347 if (mc != NULL) { 2348 mc->mc_sc = sc; 2349 error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap); 2350 if (error) { 2351 free(mc, M_DEVBUF); 2352 return(NULL); 2353 } 2354 } 2355 } 2356 return(mc); 2357 } 2358 2359 /******************************************************************************** 2360 * Release a command buffer for recycling. 2361 * 2362 * XXX It might be a good idea to limit the number of commands we save for reuse 2363 * if it's shown that this list bloats out massively. 2364 */ 2365 static void 2366 mlx_releasecmd(struct mlx_command *mc) 2367 { 2368 int s; 2369 2370 debug_called(1); 2371 2372 s = splbio(); 2373 TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link); 2374 splx(s); 2375 } 2376 2377 /******************************************************************************** 2378 * Permanently discard a command buffer. 2379 */ 2380 static void 2381 mlx_freecmd(struct mlx_command *mc) 2382 { 2383 struct mlx_softc *sc = mc->mc_sc; 2384 2385 debug_called(1); 2386 bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap); 2387 free(mc, M_DEVBUF); 2388 } 2389 2390 2391 /******************************************************************************** 2392 ******************************************************************************** 2393 Type 3 interface accessor methods 2394 ******************************************************************************** 2395 ********************************************************************************/ 2396 2397 /******************************************************************************** 2398 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2399 * (the controller is not ready to take a command). 2400 * 2401 * Must be called at splbio or in a fashion that prevents reentry. 2402 */ 2403 static int 2404 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2405 { 2406 int i; 2407 2408 debug_called(2); 2409 2410 /* ready for our command? */ 2411 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) { 2412 /* copy mailbox data to window */ 2413 for (i = 0; i < 13; i++) 2414 MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2415 2416 /* post command */ 2417 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL); 2418 return(1); 2419 } 2420 return(0); 2421 } 2422 2423 /******************************************************************************** 2424 * See if a command has been completed, if so acknowledge its completion 2425 * and recover the slot number and status code. 2426 * 2427 * Must be called at splbio or in a fashion that prevents reentry. 2428 */ 2429 static int 2430 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2431 { 2432 2433 debug_called(2); 2434 2435 /* status available? */ 2436 if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) { 2437 *slot = MLX_V3_GET_STATUS_IDENT(sc); /* get command identifier */ 2438 *status = MLX_V3_GET_STATUS(sc); /* get status */ 2439 2440 /* acknowledge completion */ 2441 MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL); 2442 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK); 2443 return(1); 2444 } 2445 return(0); 2446 } 2447 2448 /******************************************************************************** 2449 * Enable/disable interrupts as requested. (No acknowledge required) 2450 * 2451 * Must be called at splbio or in a fashion that prevents reentry. 2452 */ 2453 static void 2454 mlx_v3_intaction(struct mlx_softc *sc, int action) 2455 { 2456 debug_called(1); 2457 2458 switch(action) { 2459 case MLX_INTACTION_DISABLE: 2460 MLX_V3_PUT_IER(sc, 0); 2461 sc->mlx_state &= ~MLX_STATE_INTEN; 2462 break; 2463 case MLX_INTACTION_ENABLE: 2464 MLX_V3_PUT_IER(sc, 1); 2465 sc->mlx_state |= MLX_STATE_INTEN; 2466 break; 2467 } 2468 } 2469 2470 /******************************************************************************** 2471 * Poll for firmware error codes during controller initialisation. 2472 * Returns 0 if initialisation is complete, 1 if still in progress but no 2473 * error has been fetched, 2 if an error has been retrieved. 2474 */ 2475 static int 2476 mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2) 2477 { 2478 u_int8_t fwerror; 2479 static int initted = 0; 2480 2481 debug_called(2); 2482 2483 /* first time around, clear any hardware completion status */ 2484 if (!initted) { 2485 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK); 2486 DELAY(1000); 2487 initted = 1; 2488 } 2489 2490 /* init in progress? */ 2491 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_INIT_BUSY)) 2492 return(0); 2493 2494 /* test error value */ 2495 fwerror = MLX_V3_GET_FWERROR(sc); 2496 if (!(fwerror & MLX_V3_FWERROR_PEND)) 2497 return(1); 2498 2499 /* mask status pending bit, fetch status */ 2500 *error = fwerror & ~MLX_V3_FWERROR_PEND; 2501 *param1 = MLX_V3_GET_FWERROR_PARAM1(sc); 2502 *param2 = MLX_V3_GET_FWERROR_PARAM2(sc); 2503 2504 /* acknowledge */ 2505 MLX_V3_PUT_FWERROR(sc, 0); 2506 2507 return(2); 2508 } 2509 2510 /******************************************************************************** 2511 ******************************************************************************** 2512 Type 4 interface accessor methods 2513 ******************************************************************************** 2514 ********************************************************************************/ 2515 2516 /******************************************************************************** 2517 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2518 * (the controller is not ready to take a command). 2519 * 2520 * Must be called at splbio or in a fashion that prevents reentry. 2521 */ 2522 static int 2523 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2524 { 2525 int i; 2526 2527 debug_called(2); 2528 2529 /* ready for our command? */ 2530 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) { 2531 /* copy mailbox data to window */ 2532 for (i = 0; i < 13; i++) 2533 MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2534 2535 /* memory-mapped controller, so issue a write barrier to ensure the mailbox is filled */ 2536 bus_space_barrier(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH, 2537 BUS_SPACE_BARRIER_WRITE); 2538 2539 /* post command */ 2540 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD); 2541 return(1); 2542 } 2543 return(0); 2544 } 2545 2546 /******************************************************************************** 2547 * See if a command has been completed, if so acknowledge its completion 2548 * and recover the slot number and status code. 2549 * 2550 * Must be called at splbio or in a fashion that prevents reentry. 2551 */ 2552 static int 2553 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2554 { 2555 2556 debug_called(2); 2557 2558 /* status available? */ 2559 if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) { 2560 *slot = MLX_V4_GET_STATUS_IDENT(sc); /* get command identifier */ 2561 *status = MLX_V4_GET_STATUS(sc); /* get status */ 2562 2563 /* acknowledge completion */ 2564 MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK); 2565 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK); 2566 return(1); 2567 } 2568 return(0); 2569 } 2570 2571 /******************************************************************************** 2572 * Enable/disable interrupts as requested. 2573 * 2574 * Must be called at splbio or in a fashion that prevents reentry. 2575 */ 2576 static void 2577 mlx_v4_intaction(struct mlx_softc *sc, int action) 2578 { 2579 debug_called(1); 2580 2581 switch(action) { 2582 case MLX_INTACTION_DISABLE: 2583 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT); 2584 sc->mlx_state &= ~MLX_STATE_INTEN; 2585 break; 2586 case MLX_INTACTION_ENABLE: 2587 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT); 2588 sc->mlx_state |= MLX_STATE_INTEN; 2589 break; 2590 } 2591 } 2592 2593 /******************************************************************************** 2594 * Poll for firmware error codes during controller initialisation. 2595 * Returns 0 if initialisation is complete, 1 if still in progress but no 2596 * error has been fetched, 2 if an error has been retrieved. 2597 */ 2598 static int 2599 mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2) 2600 { 2601 u_int8_t fwerror; 2602 static int initted = 0; 2603 2604 debug_called(2); 2605 2606 /* first time around, clear any hardware completion status */ 2607 if (!initted) { 2608 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK); 2609 DELAY(1000); 2610 initted = 1; 2611 } 2612 2613 /* init in progress? */ 2614 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_INIT_BUSY)) 2615 return(0); 2616 2617 /* test error value */ 2618 fwerror = MLX_V4_GET_FWERROR(sc); 2619 if (!(fwerror & MLX_V4_FWERROR_PEND)) 2620 return(1); 2621 2622 /* mask status pending bit, fetch status */ 2623 *error = fwerror & ~MLX_V4_FWERROR_PEND; 2624 *param1 = MLX_V4_GET_FWERROR_PARAM1(sc); 2625 *param2 = MLX_V4_GET_FWERROR_PARAM2(sc); 2626 2627 /* acknowledge */ 2628 MLX_V4_PUT_FWERROR(sc, 0); 2629 2630 return(2); 2631 } 2632 2633 /******************************************************************************** 2634 ******************************************************************************** 2635 Type 5 interface accessor methods 2636 ******************************************************************************** 2637 ********************************************************************************/ 2638 2639 /******************************************************************************** 2640 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2641 * (the controller is not ready to take a command). 2642 * 2643 * Must be called at splbio or in a fashion that prevents reentry. 2644 */ 2645 static int 2646 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2647 { 2648 int i; 2649 2650 debug_called(2); 2651 2652 /* ready for our command? */ 2653 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) { 2654 /* copy mailbox data to window */ 2655 for (i = 0; i < 13; i++) 2656 MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2657 2658 /* post command */ 2659 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD); 2660 return(1); 2661 } 2662 return(0); 2663 } 2664 2665 /******************************************************************************** 2666 * See if a command has been completed, if so acknowledge its completion 2667 * and recover the slot number and status code. 2668 * 2669 * Must be called at splbio or in a fashion that prevents reentry. 2670 */ 2671 static int 2672 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2673 { 2674 2675 debug_called(2); 2676 2677 /* status available? */ 2678 if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) { 2679 *slot = MLX_V5_GET_STATUS_IDENT(sc); /* get command identifier */ 2680 *status = MLX_V5_GET_STATUS(sc); /* get status */ 2681 2682 /* acknowledge completion */ 2683 MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK); 2684 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK); 2685 return(1); 2686 } 2687 return(0); 2688 } 2689 2690 /******************************************************************************** 2691 * Enable/disable interrupts as requested. 2692 * 2693 * Must be called at splbio or in a fashion that prevents reentry. 2694 */ 2695 static void 2696 mlx_v5_intaction(struct mlx_softc *sc, int action) 2697 { 2698 debug_called(1); 2699 2700 switch(action) { 2701 case MLX_INTACTION_DISABLE: 2702 MLX_V5_PUT_IER(sc, 0xff & MLX_V5_IER_DISINT); 2703 sc->mlx_state &= ~MLX_STATE_INTEN; 2704 break; 2705 case MLX_INTACTION_ENABLE: 2706 MLX_V5_PUT_IER(sc, 0xff & ~MLX_V5_IER_DISINT); 2707 sc->mlx_state |= MLX_STATE_INTEN; 2708 break; 2709 } 2710 } 2711 2712 /******************************************************************************** 2713 * Poll for firmware error codes during controller initialisation. 2714 * Returns 0 if initialisation is complete, 1 if still in progress but no 2715 * error has been fetched, 2 if an error has been retrieved. 2716 */ 2717 static int 2718 mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2) 2719 { 2720 u_int8_t fwerror; 2721 static int initted = 0; 2722 2723 debug_called(2); 2724 2725 /* first time around, clear any hardware completion status */ 2726 if (!initted) { 2727 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK); 2728 DELAY(1000); 2729 initted = 1; 2730 } 2731 2732 /* init in progress? */ 2733 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_INIT_DONE) 2734 return(0); 2735 2736 /* test for error value */ 2737 fwerror = MLX_V5_GET_FWERROR(sc); 2738 if (!(fwerror & MLX_V5_FWERROR_PEND)) 2739 return(1); 2740 2741 /* mask status pending bit, fetch status */ 2742 *error = fwerror & ~MLX_V5_FWERROR_PEND; 2743 *param1 = MLX_V5_GET_FWERROR_PARAM1(sc); 2744 *param2 = MLX_V5_GET_FWERROR_PARAM2(sc); 2745 2746 /* acknowledge */ 2747 MLX_V5_PUT_FWERROR(sc, 0xff); 2748 2749 return(2); 2750 } 2751 2752 /******************************************************************************** 2753 ******************************************************************************** 2754 Debugging 2755 ******************************************************************************** 2756 ********************************************************************************/ 2757 2758 /******************************************************************************** 2759 * Return a status message describing (mc) 2760 */ 2761 static char *mlx_status_messages[] = { 2762 "normal completion", /* 00 */ 2763 "irrecoverable data error", /* 01 */ 2764 "drive does not exist, or is offline", /* 02 */ 2765 "attempt to write beyond end of drive", /* 03 */ 2766 "bad data encountered", /* 04 */ 2767 "invalid log entry request", /* 05 */ 2768 "attempt to rebuild online drive", /* 06 */ 2769 "new disk failed during rebuild", /* 07 */ 2770 "invalid channel/target", /* 08 */ 2771 "rebuild/check already in progress", /* 09 */ 2772 "one or more disks are dead", /* 10 */ 2773 "invalid or non-redundant drive", /* 11 */ 2774 "channel is busy", /* 12 */ 2775 "channel is not stopped", /* 13 */ 2776 "rebuild successfully terminated", /* 14 */ 2777 "unsupported command", /* 15 */ 2778 "check condition received", /* 16 */ 2779 "device is busy", /* 17 */ 2780 "selection or command timeout", /* 18 */ 2781 "command terminated abnormally", /* 19 */ 2782 "" 2783 }; 2784 2785 static struct 2786 { 2787 int command; 2788 u_int16_t status; 2789 int msg; 2790 } mlx_messages[] = { 2791 {MLX_CMD_READSG, 0x0001, 1}, 2792 {MLX_CMD_READSG, 0x0002, 1}, 2793 {MLX_CMD_READSG, 0x0105, 3}, 2794 {MLX_CMD_READSG, 0x010c, 4}, 2795 {MLX_CMD_WRITESG, 0x0001, 1}, 2796 {MLX_CMD_WRITESG, 0x0002, 1}, 2797 {MLX_CMD_WRITESG, 0x0105, 3}, 2798 {MLX_CMD_READSG_OLD, 0x0001, 1}, 2799 {MLX_CMD_READSG_OLD, 0x0002, 1}, 2800 {MLX_CMD_READSG_OLD, 0x0105, 3}, 2801 {MLX_CMD_WRITESG_OLD, 0x0001, 1}, 2802 {MLX_CMD_WRITESG_OLD, 0x0002, 1}, 2803 {MLX_CMD_WRITESG_OLD, 0x0105, 3}, 2804 {MLX_CMD_LOGOP, 0x0105, 5}, 2805 {MLX_CMD_REBUILDASYNC, 0x0002, 6}, 2806 {MLX_CMD_REBUILDASYNC, 0x0004, 7}, 2807 {MLX_CMD_REBUILDASYNC, 0x0105, 8}, 2808 {MLX_CMD_REBUILDASYNC, 0x0106, 9}, 2809 {MLX_CMD_REBUILDASYNC, 0x0107, 14}, 2810 {MLX_CMD_CHECKASYNC, 0x0002, 10}, 2811 {MLX_CMD_CHECKASYNC, 0x0105, 11}, 2812 {MLX_CMD_CHECKASYNC, 0x0106, 9}, 2813 {MLX_CMD_STOPCHANNEL, 0x0106, 12}, 2814 {MLX_CMD_STOPCHANNEL, 0x0105, 8}, 2815 {MLX_CMD_STARTCHANNEL, 0x0005, 13}, 2816 {MLX_CMD_STARTCHANNEL, 0x0105, 8}, 2817 {MLX_CMD_DIRECT_CDB, 0x0002, 16}, 2818 {MLX_CMD_DIRECT_CDB, 0x0008, 17}, 2819 {MLX_CMD_DIRECT_CDB, 0x000e, 18}, 2820 {MLX_CMD_DIRECT_CDB, 0x000f, 19}, 2821 {MLX_CMD_DIRECT_CDB, 0x0105, 8}, 2822 2823 {0, 0x0104, 14}, 2824 {-1, 0, 0} 2825 }; 2826 2827 static char * 2828 mlx_diagnose_command(struct mlx_command *mc) 2829 { 2830 static char unkmsg[80]; 2831 int i; 2832 2833 /* look up message in table */ 2834 for (i = 0; mlx_messages[i].command != -1; i++) 2835 if (((mc->mc_mailbox[0] == mlx_messages[i].command) || (mlx_messages[i].command == 0)) && 2836 (mc->mc_status == mlx_messages[i].status)) 2837 return(mlx_status_messages[mlx_messages[i].msg]); 2838 2839 sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]); 2840 return(unkmsg); 2841 } 2842 2843 /******************************************************************************* 2844 * Print a string describing the controller (sc) 2845 */ 2846 static struct 2847 { 2848 int hwid; 2849 char *name; 2850 } mlx_controller_names[] = { 2851 {0x01, "960P/PD"}, 2852 {0x02, "960PL"}, 2853 {0x10, "960PG"}, 2854 {0x11, "960PJ"}, 2855 {0x12, "960PR"}, 2856 {0x13, "960PT"}, 2857 {0x14, "960PTL0"}, 2858 {0x15, "960PRL"}, 2859 {0x16, "960PTL1"}, 2860 {0x20, "1164PVX"}, 2861 {-1, NULL} 2862 }; 2863 2864 static void 2865 mlx_describe_controller(struct mlx_softc *sc) 2866 { 2867 static char buf[80]; 2868 char *model; 2869 int i; 2870 2871 for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) { 2872 if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) { 2873 model = mlx_controller_names[i].name; 2874 break; 2875 } 2876 } 2877 if (model == NULL) { 2878 sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff); 2879 model = buf; 2880 } 2881 device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n", 2882 model, 2883 sc->mlx_enq2->me_actual_channels, 2884 sc->mlx_enq2->me_actual_channels > 1 ? "s" : "", 2885 sc->mlx_enq2->me_firmware_id & 0xff, 2886 (sc->mlx_enq2->me_firmware_id >> 8) & 0xff, 2887 (sc->mlx_enq2->me_firmware_id >> 24) & 0xff, 2888 (sc->mlx_enq2->me_firmware_id >> 16) & 0xff, 2889 sc->mlx_enq2->me_mem_size / (1024 * 1024)); 2890 2891 if (bootverbose) { 2892 device_printf(sc->mlx_dev, " Hardware ID 0x%08x\n", sc->mlx_enq2->me_hardware_id); 2893 device_printf(sc->mlx_dev, " Firmware ID 0x%08x\n", sc->mlx_enq2->me_firmware_id); 2894 device_printf(sc->mlx_dev, " Configured/Actual channels %d/%d\n", sc->mlx_enq2->me_configured_channels, 2895 sc->mlx_enq2->me_actual_channels); 2896 device_printf(sc->mlx_dev, " Max Targets %d\n", sc->mlx_enq2->me_max_targets); 2897 device_printf(sc->mlx_dev, " Max Tags %d\n", sc->mlx_enq2->me_max_tags); 2898 device_printf(sc->mlx_dev, " Max System Drives %d\n", sc->mlx_enq2->me_max_sys_drives); 2899 device_printf(sc->mlx_dev, " Max Arms %d\n", sc->mlx_enq2->me_max_arms); 2900 device_printf(sc->mlx_dev, " Max Spans %d\n", sc->mlx_enq2->me_max_spans); 2901 device_printf(sc->mlx_dev, " DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size, 2902 sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size); 2903 device_printf(sc->mlx_dev, " DRAM type %d\n", sc->mlx_enq2->me_mem_type); 2904 device_printf(sc->mlx_dev, " Clock Speed %dns\n", sc->mlx_enq2->me_clock_speed); 2905 device_printf(sc->mlx_dev, " Hardware Speed %dns\n", sc->mlx_enq2->me_hardware_speed); 2906 device_printf(sc->mlx_dev, " Max Commands %d\n", sc->mlx_enq2->me_max_commands); 2907 device_printf(sc->mlx_dev, " Max SG Entries %d\n", sc->mlx_enq2->me_max_sg); 2908 device_printf(sc->mlx_dev, " Max DP %d\n", sc->mlx_enq2->me_max_dp); 2909 device_printf(sc->mlx_dev, " Max IOD %d\n", sc->mlx_enq2->me_max_iod); 2910 device_printf(sc->mlx_dev, " Max Comb %d\n", sc->mlx_enq2->me_max_comb); 2911 device_printf(sc->mlx_dev, " Latency %ds\n", sc->mlx_enq2->me_latency); 2912 device_printf(sc->mlx_dev, " SCSI Timeout %ds\n", sc->mlx_enq2->me_scsi_timeout); 2913 device_printf(sc->mlx_dev, " Min Free Lines %d\n", sc->mlx_enq2->me_min_freelines); 2914 device_printf(sc->mlx_dev, " Rate Constant %d\n", sc->mlx_enq2->me_rate_const); 2915 device_printf(sc->mlx_dev, " MAXBLK %d\n", sc->mlx_enq2->me_maxblk); 2916 device_printf(sc->mlx_dev, " Blocking Factor %d sectors\n", sc->mlx_enq2->me_blocking_factor); 2917 device_printf(sc->mlx_dev, " Cache Line Size %d blocks\n", sc->mlx_enq2->me_cacheline); 2918 device_printf(sc->mlx_dev, " SCSI Capability %s%dMHz, %d bit\n", 2919 sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "", 2920 (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10, 2921 8 << (sc->mlx_enq2->me_scsi_cap & 0x3)); 2922 device_printf(sc->mlx_dev, " Firmware Build Number %d\n", sc->mlx_enq2->me_firmware_build); 2923 device_printf(sc->mlx_dev, " Fault Management Type %d\n", sc->mlx_enq2->me_fault_mgmt_type); 2924 device_printf(sc->mlx_dev, " Features %b\n", sc->mlx_enq2->me_firmware_features, 2925 "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n"); 2926 2927 } 2928 } 2929 2930 /******************************************************************************* 2931 * Emit a string describing the firmware handshake status code, and return a flag 2932 * indicating whether the code represents a fatal error. 2933 * 2934 * Error code interpretations are from the Linux driver, and don't directly match 2935 * the messages printed by Mylex's BIOS. This may change if documentation on the 2936 * codes is forthcoming. 2937 */ 2938 static int 2939 mlx_fw_message(struct mlx_softc *sc, int error, int param1, int param2) 2940 { 2941 switch(error) { 2942 case 0x00: 2943 device_printf(sc->mlx_dev, "physical drive %d:%d not responding\n", param2, param1); 2944 break; 2945 case 0x08: 2946 /* we could be neater about this and give some indication when we receive more of them */ 2947 if (!(sc->mlx_flags & MLX_SPINUP_REPORTED)) { 2948 device_printf(sc->mlx_dev, "spinning up drives...\n"); 2949 sc->mlx_flags |= MLX_SPINUP_REPORTED; 2950 } 2951 break; 2952 case 0x30: 2953 device_printf(sc->mlx_dev, "configuration checksum error\n"); 2954 break; 2955 case 0x60: 2956 device_printf(sc->mlx_dev, "mirror race recovery failed\n"); 2957 break; 2958 case 0x70: 2959 device_printf(sc->mlx_dev, "mirror race recovery in progress\n"); 2960 break; 2961 case 0x90: 2962 device_printf(sc->mlx_dev, "physical drive %d:%d COD mismatch\n", param2, param1); 2963 break; 2964 case 0xa0: 2965 device_printf(sc->mlx_dev, "logical drive installation aborted\n"); 2966 break; 2967 case 0xb0: 2968 device_printf(sc->mlx_dev, "mirror race on a critical system drive\n"); 2969 break; 2970 case 0xd0: 2971 device_printf(sc->mlx_dev, "new controller configuration found\n"); 2972 break; 2973 case 0xf0: 2974 device_printf(sc->mlx_dev, "FATAL MEMORY PARITY ERROR\n"); 2975 return(1); 2976 default: 2977 device_printf(sc->mlx_dev, "unknown firmware initialisation error %02x:%02x:%02x\n", error, param1, param2); 2978 break; 2979 } 2980 return(0); 2981 } 2982 2983 /******************************************************************************** 2984 ******************************************************************************** 2985 Utility Functions 2986 ******************************************************************************** 2987 ********************************************************************************/ 2988 2989 /******************************************************************************** 2990 * Find the disk whose unit number is (unit) on this controller 2991 */ 2992 static struct mlx_sysdrive * 2993 mlx_findunit(struct mlx_softc *sc, int unit) 2994 { 2995 int i; 2996 2997 /* search system drives */ 2998 for (i = 0; i < MLX_MAXDRIVES; i++) { 2999 /* is this one attached? */ 3000 if (sc->mlx_sysdrive[i].ms_disk != 0) { 3001 /* is this the one? */ 3002 if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk)) 3003 return(&sc->mlx_sysdrive[i]); 3004 } 3005 } 3006 return(NULL); 3007 } 3008