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/buf.h> 39 #include <sys/bus.h> 40 #include <sys/conf.h> 41 #include <sys/devicestat.h> 42 #include <sys/disk.h> 43 44 #include <machine/resource.h> 45 #include <machine/bus.h> 46 #include <machine/clock.h> 47 #include <sys/rman.h> 48 49 #include <dev/mlx/mlxio.h> 50 #include <dev/mlx/mlxvar.h> 51 #include <dev/mlx/mlxreg.h> 52 53 #if 0 54 #define debug(fmt, args...) printf("%s: " fmt "\n", __FUNCTION__ , ##args) 55 #else 56 #define debug(fmt, args...) 57 #endif 58 59 #define MLX_CDEV_MAJOR 130 60 61 static struct cdevsw mlx_cdevsw = { 62 /* open */ mlx_open, 63 /* close */ mlx_close, 64 /* read */ noread, 65 /* write */ nowrite, 66 /* ioctl */ mlx_ioctl, 67 /* poll */ nopoll, 68 /* mmap */ nommap, 69 /* strategy */ nostrategy, 70 /* name */ "mlx", 71 /* maj */ MLX_CDEV_MAJOR, 72 /* dump */ nodump, 73 /* psize */ nopsize, 74 /* flags */ 0, 75 /* bmaj */ -1 76 }; 77 78 static int cdev_registered = 0; 79 devclass_t mlx_devclass; 80 81 /* 82 * Per-interface accessor methods 83 */ 84 static int mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 85 static int mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 86 static void mlx_v3_intaction(struct mlx_softc *sc, int action); 87 88 static int mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 89 static int mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 90 static void mlx_v4_intaction(struct mlx_softc *sc, int action); 91 92 static int mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc); 93 static int mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status); 94 static void mlx_v5_intaction(struct mlx_softc *sc, int action); 95 96 /* 97 * Status monitoring 98 */ 99 static void mlx_periodic(void *data); 100 static void mlx_periodic_enquiry(struct mlx_command *mc); 101 static void mlx_periodic_eventlog_poll(struct mlx_softc *sc); 102 static void mlx_periodic_eventlog_respond(struct mlx_command *mc); 103 static void mlx_periodic_rebuild(struct mlx_command *mc); 104 105 /* 106 * Channel Pause 107 */ 108 static void mlx_pause_action(struct mlx_softc *sc); 109 static void mlx_pause_done(struct mlx_command *mc); 110 111 /* 112 * Command submission. 113 */ 114 static void *mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, 115 void (*complete)(struct mlx_command *mc)); 116 static int mlx_flush(struct mlx_softc *sc); 117 static int mlx_rebuild(struct mlx_softc *sc, int channel, int target); 118 static int mlx_wait_command(struct mlx_command *mc); 119 static int mlx_poll_command(struct mlx_command *mc); 120 static void mlx_startio(struct mlx_softc *sc); 121 static void mlx_completeio(struct mlx_command *mc); 122 static int mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu); 123 124 /* 125 * Command buffer allocation. 126 */ 127 static struct mlx_command *mlx_alloccmd(struct mlx_softc *sc); 128 static void mlx_releasecmd(struct mlx_command *mc); 129 static void mlx_freecmd(struct mlx_command *mc); 130 131 /* 132 * Command management. 133 */ 134 static int mlx_getslot(struct mlx_command *mc); 135 static void mlx_mapcmd(struct mlx_command *mc); 136 static void mlx_unmapcmd(struct mlx_command *mc); 137 static int mlx_start(struct mlx_command *mc); 138 static int mlx_done(struct mlx_softc *sc); 139 static void mlx_complete(struct mlx_softc *sc); 140 141 /* 142 * Debugging. 143 */ 144 static char *mlx_diagnose_command(struct mlx_command *mc); 145 static void mlx_describe_controller(struct mlx_softc *sc); 146 147 148 /* 149 * Utility functions. 150 */ 151 static struct mlx_sysdrive *mlx_findunit(struct mlx_softc *sc, int unit); 152 153 /******************************************************************************** 154 ******************************************************************************** 155 Public Interfaces 156 ******************************************************************************** 157 ********************************************************************************/ 158 159 /******************************************************************************** 160 * Free all of the resources associated with (sc) 161 * 162 * Should not be called if the controller is active. 163 */ 164 void 165 mlx_free(struct mlx_softc *sc) 166 { 167 struct mlx_command *mc; 168 169 debug("called"); 170 171 /* cancel status timeout */ 172 untimeout(mlx_periodic, sc, sc->mlx_timeout); 173 174 /* throw away any command buffers */ 175 while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) { 176 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link); 177 mlx_freecmd(mc); 178 } 179 180 /* destroy data-transfer DMA tag */ 181 if (sc->mlx_buffer_dmat) 182 bus_dma_tag_destroy(sc->mlx_buffer_dmat); 183 184 /* free and destroy DMA memory and tag for s/g lists */ 185 if (sc->mlx_sgtable) 186 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap); 187 if (sc->mlx_sg_dmat) 188 bus_dma_tag_destroy(sc->mlx_sg_dmat); 189 190 /* disconnect the interrupt handler */ 191 if (sc->mlx_intr) 192 bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr); 193 if (sc->mlx_irq != NULL) 194 bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq); 195 196 /* destroy the parent DMA tag */ 197 if (sc->mlx_parent_dmat) 198 bus_dma_tag_destroy(sc->mlx_parent_dmat); 199 200 /* release the register window mapping */ 201 if (sc->mlx_mem != NULL) 202 bus_release_resource(sc->mlx_dev, SYS_RES_MEMORY, 203 (sc->mlx_iftype == MLX_IFTYPE_3) ? MLX_CFG_BASE1 : MLX_CFG_BASE0, sc->mlx_mem); 204 205 /* free controller enquiry data */ 206 if (sc->mlx_enq2 != NULL) 207 free(sc->mlx_enq2, M_DEVBUF); 208 } 209 210 /******************************************************************************** 211 * Map the scatter/gather table into bus space 212 */ 213 static void 214 mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) 215 { 216 struct mlx_softc *sc = (struct mlx_softc *)arg; 217 218 debug("called"); 219 220 /* save base of s/g table's address in bus space */ 221 sc->mlx_sgbusaddr = segs->ds_addr; 222 } 223 224 static int 225 mlx_sglist_map(struct mlx_softc *sc) 226 { 227 size_t segsize; 228 int error; 229 230 debug("called"); 231 232 /* destroy any existing mappings */ 233 if (sc->mlx_sgtable) 234 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap); 235 if (sc->mlx_sg_dmat) 236 bus_dma_tag_destroy(sc->mlx_sg_dmat); 237 238 /* 239 * Create a single tag describing a region large enough to hold all of 240 * the s/g lists we will need. 241 */ 242 segsize = sizeof(struct mlx_sgentry) * MLX_NSEG * sc->mlx_maxiop; 243 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */ 244 1, 0, /* alignment, boundary */ 245 BUS_SPACE_MAXADDR, /* lowaddr */ 246 BUS_SPACE_MAXADDR, /* highaddr */ 247 NULL, NULL, /* filter, filterarg */ 248 segsize, 1, /* maxsize, nsegments */ 249 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 250 0, /* flags */ 251 &sc->mlx_sg_dmat); 252 if (error != 0) { 253 device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n"); 254 return(ENOMEM); 255 } 256 257 /* 258 * Allocate enough s/g maps for all commands and permanently map them into 259 * controller-visible space. 260 * 261 * XXX this assumes we can get enough space for all the s/g maps in one 262 * contiguous slab. We may need to switch to a more complex arrangement where 263 * we allocate in smaller chunks and keep a lookup table from slot to bus address. 264 */ 265 error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable, BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap); 266 if (error) { 267 device_printf(sc->mlx_dev, "can't allocate s/g table\n"); 268 return(ENOMEM); 269 } 270 bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable, segsize, mlx_dma_map_sg, sc, 0); 271 return(0); 272 } 273 274 /******************************************************************************** 275 * Initialise the controller and softc 276 */ 277 int 278 mlx_attach(struct mlx_softc *sc) 279 { 280 int rid, error, fwminor; 281 282 debug("called"); 283 284 /* 285 * Initialise per-controller queues. 286 */ 287 TAILQ_INIT(&sc->mlx_work); 288 TAILQ_INIT(&sc->mlx_freecmds); 289 bufq_init(&sc->mlx_bufq); 290 291 /* 292 * Select accessor methods based on controller interface type. 293 */ 294 switch(sc->mlx_iftype) { 295 case MLX_IFTYPE_3: 296 sc->mlx_tryqueue = mlx_v3_tryqueue; 297 sc->mlx_findcomplete = mlx_v3_findcomplete; 298 sc->mlx_intaction = mlx_v3_intaction; 299 break; 300 case MLX_IFTYPE_4: 301 sc->mlx_tryqueue = mlx_v4_tryqueue; 302 sc->mlx_findcomplete = mlx_v4_findcomplete; 303 sc->mlx_intaction = mlx_v4_intaction; 304 break; 305 case MLX_IFTYPE_5: 306 sc->mlx_tryqueue = mlx_v5_tryqueue; 307 sc->mlx_findcomplete = mlx_v5_findcomplete; 308 sc->mlx_intaction = mlx_v5_intaction; 309 break; 310 default: 311 device_printf(sc->mlx_dev, "attaching unsupported interface version %d\n", sc->mlx_iftype); 312 return(ENXIO); /* should never happen */ 313 } 314 315 /* disable interrupts before we start talking to the controller */ 316 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 317 318 /* 319 * Allocate and connect our interrupt. 320 */ 321 rid = 0; 322 sc->mlx_irq = bus_alloc_resource(sc->mlx_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); 323 if (sc->mlx_irq == NULL) { 324 device_printf(sc->mlx_dev, "couldn't allocate interrupt\n"); 325 mlx_free(sc); 326 return(ENXIO); 327 } 328 error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO, mlx_intr, sc, &sc->mlx_intr); 329 if (error) { 330 device_printf(sc->mlx_dev, "couldn't set up interrupt\n"); 331 mlx_free(sc); 332 return(ENXIO); 333 } 334 335 /* 336 * Create DMA tag for mapping buffers into controller-addressable space. 337 */ 338 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */ 339 1, 0, /* alignment, boundary */ 340 BUS_SPACE_MAXADDR, /* lowaddr */ 341 BUS_SPACE_MAXADDR, /* highaddr */ 342 NULL, NULL, /* filter, filterarg */ 343 MAXBSIZE, MLX_NSEG, /* maxsize, nsegments */ 344 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 345 0, /* flags */ 346 &sc->mlx_buffer_dmat); 347 if (error != 0) { 348 device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n"); 349 return(ENOMEM); 350 } 351 352 /* 353 * Create an initial set of s/g mappings. 354 */ 355 sc->mlx_maxiop = 8; 356 error = mlx_sglist_map(sc); 357 if (error != 0) { 358 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 359 return(error); 360 } 361 362 /* send an ENQUIRY2 to the controller */ 363 if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) { 364 device_printf(sc->mlx_dev, "ENQUIRY2 failed\n"); 365 return(ENXIO); 366 } 367 368 /* 369 * We don't (yet) know where the event log is up to. 370 */ 371 sc->mlx_lastevent = -1; 372 373 /* print a little information about the controller */ 374 mlx_describe_controller(sc); 375 376 /* 377 * Do quirk/feature related things. 378 */ 379 fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff; 380 switch(sc->mlx_iftype) { 381 case MLX_IFTYPE_3: 382 /* XXX certify 3.52? */ 383 if (fwminor < 51) { 384 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 385 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n"); 386 } 387 break; 388 case MLX_IFTYPE_4: 389 /* XXX certify firmware versions? */ 390 if (fwminor < 6) { 391 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 392 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n"); 393 } 394 break; 395 case MLX_IFTYPE_5: 396 if (fwminor < 7) { 397 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n"); 398 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n"); 399 } 400 break; 401 default: 402 device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype); 403 return(ENXIO); /* should never happen */ 404 } 405 406 /* 407 * Create the final set of s/g mappings now that we know how many commands 408 * the controller actually supports. 409 */ 410 sc->mlx_maxiop = sc->mlx_enq2->me_max_commands; 411 error = mlx_sglist_map(sc); 412 if (error != 0) { 413 device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n"); 414 return(error); 415 } 416 417 /* 418 * No rebuild or check is in progress. 419 */ 420 sc->mlx_rebuild = -1; 421 sc->mlx_check = -1; 422 423 /* 424 * Register the control device on first attach. 425 */ 426 if (cdev_registered++ == 0) 427 cdevsw_add(&mlx_cdevsw); 428 429 /* 430 * Start the timeout routine. 431 */ 432 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 433 434 return(0); 435 } 436 437 /******************************************************************************** 438 * Locate disk resources and attach children to them. 439 */ 440 void 441 mlx_startup(struct mlx_softc *sc) 442 { 443 struct mlx_enq_sys_drive *mes; 444 struct mlx_sysdrive *dr; 445 int i, error; 446 447 debug("called"); 448 449 /* 450 * Scan all the system drives and attach children for those that 451 * don't currently have them. 452 */ 453 mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL); 454 if (mes == NULL) { 455 device_printf(sc->mlx_dev, "error fetching drive status\n"); 456 return; 457 } 458 459 /* iterate over drives returned */ 460 for (i = 0, dr = &sc->mlx_sysdrive[0]; 461 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 462 i++, dr++) { 463 /* are we already attached to this drive? */ 464 if (dr->ms_disk == 0) { 465 /* pick up drive information */ 466 dr->ms_size = mes[i].sd_size; 467 dr->ms_raidlevel = mes[i].sd_raidlevel & 0xf; 468 dr->ms_state = mes[i].sd_state; 469 470 /* generate geometry information */ 471 if (sc->mlx_geom == MLX_GEOM_128_32) { 472 dr->ms_heads = 128; 473 dr->ms_sectors = 32; 474 dr->ms_cylinders = dr->ms_size / (128 * 32); 475 } else { /* MLX_GEOM_255/63 */ 476 dr->ms_heads = 255; 477 dr->ms_sectors = 63; 478 dr->ms_cylinders = dr->ms_size / (255 * 63); 479 } 480 dr->ms_disk = device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1); 481 if (dr->ms_disk == 0) 482 device_printf(sc->mlx_dev, "device_add_child failed\n"); 483 device_set_ivars(dr->ms_disk, dr); 484 } 485 } 486 free(mes, M_DEVBUF); 487 if ((error = bus_generic_attach(sc->mlx_dev)) != 0) 488 device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error); 489 490 /* mark controller back up */ 491 sc->mlx_state &= ~MLX_STATE_SHUTDOWN; 492 493 /* enable interrupts */ 494 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE); 495 } 496 497 /******************************************************************************** 498 * Disconnect from the controller completely, in preparation for unload. 499 */ 500 int 501 mlx_detach(device_t dev) 502 { 503 struct mlx_softc *sc = device_get_softc(dev); 504 struct mlxd_softc *mlxd; 505 int i, s, error; 506 507 debug("called"); 508 509 error = EBUSY; 510 s = splbio(); 511 if (sc->mlx_state & MLX_STATE_OPEN) 512 goto out; 513 514 for (i = 0; i < MLX_MAXDRIVES; i++) { 515 if (sc->mlx_sysdrive[i].ms_disk != 0) { 516 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk); 517 if (mlxd->mlxd_flags & MLXD_OPEN) { /* drive is mounted, abort detach */ 518 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n"); 519 goto out; 520 } 521 } 522 } 523 if ((error = mlx_shutdown(dev))) 524 goto out; 525 526 mlx_free(sc); 527 528 /* 529 * Deregister the control device on last detach. 530 */ 531 if (--cdev_registered == 0) 532 cdevsw_remove(&mlx_cdevsw); 533 error = 0; 534 out: 535 splx(s); 536 return(error); 537 } 538 539 /******************************************************************************** 540 * Bring the controller down to a dormant state and detach all child devices. 541 * 542 * This function is called before detach, system shutdown, or before performing 543 * an operation which may add or delete system disks. (Call mlx_startup to 544 * resume normal operation.) 545 * 546 * Note that we can assume that the bufq on the controller is empty, as we won't 547 * allow shutdown if any device is open. 548 */ 549 int 550 mlx_shutdown(device_t dev) 551 { 552 struct mlx_softc *sc = device_get_softc(dev); 553 int i, s, error; 554 555 debug("called"); 556 557 s = splbio(); 558 error = 0; 559 560 sc->mlx_state |= MLX_STATE_SHUTDOWN; 561 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 562 563 /* flush controller */ 564 device_printf(sc->mlx_dev, "flushing cache..."); 565 if (mlx_flush(sc)) { 566 printf("failed\n"); 567 } else { 568 printf("done\n"); 569 } 570 571 /* delete all our child devices */ 572 for (i = 0; i < MLX_MAXDRIVES; i++) { 573 if (sc->mlx_sysdrive[i].ms_disk != 0) { 574 if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0) 575 goto out; 576 sc->mlx_sysdrive[i].ms_disk = 0; 577 } 578 } 579 580 out: 581 splx(s); 582 return(error); 583 } 584 585 /******************************************************************************** 586 * Bring the controller to a quiescent state, ready for system suspend. 587 */ 588 int 589 mlx_suspend(device_t dev) 590 { 591 struct mlx_softc *sc = device_get_softc(dev); 592 int s; 593 594 debug("called"); 595 596 s = splbio(); 597 sc->mlx_state |= MLX_STATE_SUSPEND; 598 599 /* flush controller */ 600 device_printf(sc->mlx_dev, "flushing cache..."); 601 printf("%s\n", mlx_flush(sc) ? "failed" : "done"); 602 603 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE); 604 splx(s); 605 606 return(0); 607 } 608 609 /******************************************************************************** 610 * Bring the controller back to a state ready for operation. 611 */ 612 int 613 mlx_resume(device_t dev) 614 { 615 struct mlx_softc *sc = device_get_softc(dev); 616 617 debug("called"); 618 619 sc->mlx_state &= ~MLX_STATE_SUSPEND; 620 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE); 621 622 return(0); 623 } 624 625 /******************************************************************************* 626 * Take an interrupt, or be poked by other code to look for interrupt-worthy 627 * status. 628 */ 629 void 630 mlx_intr(void *arg) 631 { 632 struct mlx_softc *sc = (struct mlx_softc *)arg; 633 634 debug("called"); 635 636 /* collect finished commands, queue anything waiting */ 637 mlx_done(sc); 638 }; 639 640 /******************************************************************************* 641 * Receive a buf structure from a child device and queue it on a particular 642 * disk resource, then poke the disk resource to start as much work as it can. 643 */ 644 int 645 mlx_submit_buf(struct mlx_softc *sc, struct buf *bp) 646 { 647 int s; 648 649 debug("called"); 650 651 s = splbio(); 652 bufq_insert_tail(&sc->mlx_bufq, bp); 653 sc->mlx_waitbufs++; 654 splx(s); 655 mlx_startio(sc); 656 return(0); 657 } 658 659 /******************************************************************************** 660 * Accept an open operation on the control device. 661 */ 662 int 663 mlx_open(dev_t dev, int flags, int fmt, struct proc *p) 664 { 665 int unit = minor(dev); 666 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 667 668 sc->mlx_state |= MLX_STATE_OPEN; 669 return(0); 670 } 671 672 /******************************************************************************** 673 * Accept the last close on the control device. 674 */ 675 int 676 mlx_close(dev_t dev, int flags, int fmt, struct proc *p) 677 { 678 int unit = minor(dev); 679 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 680 681 sc->mlx_state &= ~MLX_STATE_OPEN; 682 return (0); 683 } 684 685 /******************************************************************************** 686 * Handle controller-specific control operations. 687 */ 688 int 689 mlx_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) 690 { 691 int unit = minor(dev); 692 struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit); 693 int *arg = (int *)addr; 694 struct mlx_pause *mp; 695 struct mlx_sysdrive *dr; 696 struct mlxd_softc *mlxd; 697 int i, error; 698 699 switch(cmd) { 700 /* 701 * Enumerate connected system drives; returns the first system drive's 702 * unit number if *arg is -1, or the next unit after *arg if it's 703 * a valid unit on this controller. 704 */ 705 case MLX_NEXT_CHILD: 706 /* search system drives */ 707 for (i = 0; i < MLX_MAXDRIVES; i++) { 708 /* is this one attached? */ 709 if (sc->mlx_sysdrive[i].ms_disk != 0) { 710 /* looking for the next one we come across? */ 711 if (*arg == -1) { 712 *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk); 713 return(0); 714 } 715 /* we want the one after this one */ 716 if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk)) 717 *arg = -1; 718 } 719 } 720 return(ENOENT); 721 722 /* 723 * Scan the controller to see whether new drives have appeared. 724 */ 725 case MLX_RESCAN_DRIVES: 726 mlx_startup(sc); 727 return(0); 728 729 /* 730 * Disconnect from the specified drive; it may be about to go 731 * away. 732 */ 733 case MLX_DETACH_DRIVE: /* detach one drive */ 734 735 if (((dr = mlx_findunit(sc, *arg)) == NULL) || 736 ((mlxd = device_get_softc(dr->ms_disk)) == NULL)) 737 return(ENOENT); 738 739 device_printf(dr->ms_disk, "detaching..."); 740 error = 0; 741 if (mlxd->mlxd_flags & MLXD_OPEN) { 742 error = EBUSY; 743 goto detach_out; 744 } 745 746 /* flush controller */ 747 if (mlx_flush(sc)) { 748 error = EBUSY; 749 goto detach_out; 750 } 751 752 /* nuke drive */ 753 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0) 754 goto detach_out; 755 dr->ms_disk = 0; 756 757 detach_out: 758 if (error) { 759 printf("failed\n"); 760 } else { 761 printf("done\n"); 762 } 763 return(error); 764 765 /* 766 * Pause one or more SCSI channels for a period of time, to assist 767 * in the process of hot-swapping devices. 768 * 769 * Note that at least the 3.51 firmware on the DAC960PL doesn't seem 770 * to do this right. 771 */ 772 case MLX_PAUSE_CHANNEL: /* schedule a channel pause */ 773 /* Does this command work on this firmware? */ 774 if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS)) 775 return(EOPNOTSUPP); 776 777 mp = (struct mlx_pause *)addr; 778 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) { 779 /* cancel a pending pause operation */ 780 sc->mlx_pause.mp_which = 0; 781 } else { 782 /* fix for legal channels */ 783 mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1); 784 /* check time values */ 785 if ((mp->mp_when < 0) || (mp->mp_when > 3600)) 786 return(EINVAL); 787 if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30))) 788 return(EINVAL); 789 790 /* check for a pause currently running */ 791 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) 792 return(EBUSY); 793 794 /* looks ok, go with it */ 795 sc->mlx_pause.mp_which = mp->mp_which; 796 sc->mlx_pause.mp_when = time_second + mp->mp_when; 797 sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong; 798 } 799 return(0); 800 801 /* 802 * Accept a command passthrough-style. 803 */ 804 case MLX_COMMAND: 805 return(mlx_user_command(sc, (struct mlx_usercommand *)addr)); 806 807 default: 808 return(ENOTTY); 809 } 810 } 811 812 /******************************************************************************** 813 * Handle operations requested by a System Drive connected to this controller. 814 */ 815 int 816 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd, 817 caddr_t addr, int32_t flag, struct proc *p) 818 { 819 struct mlxd_rebuild *mr = (struct mlxd_rebuild *)addr; 820 struct mlxd_rebuild_status *mp = (struct mlxd_rebuild_status *)addr; 821 int *arg = (int *)addr; 822 int error; 823 824 switch(cmd) { 825 /* 826 * Return the current status of this drive. 827 */ 828 case MLXD_STATUS: 829 *arg = drive->ms_state; 830 return(0); 831 832 /* 833 * Start a background rebuild on this drive. 834 */ 835 case MLXD_REBUILDASYNC: 836 /* XXX lock? */ 837 if (sc->mlx_rebuild >= 0) 838 return(EBUSY); 839 sc->mlx_rebuild = drive - &sc->mlx_sysdrive[0]; 840 841 switch (mlx_rebuild(sc, mr->rb_channel, mr->rb_target)) { 842 case 0: 843 drive->ms_state = MLX_SYSD_REBUILD; 844 error = 0; 845 break; 846 case 0x10000: 847 error = ENOMEM; /* couldn't set up the command */ 848 break; 849 case 0x0002: 850 case 0x0106: 851 error = EBUSY; 852 break; 853 case 0x0004: 854 error = EIO; 855 break; 856 case 0x0105: 857 error = ERANGE; 858 break; 859 default: 860 error = EINVAL; 861 break; 862 } 863 if (error != 0) 864 sc->mlx_rebuild = -1; 865 return(error); 866 867 /* 868 * Start a background consistency check on this drive. 869 */ 870 case MLXD_CHECKASYNC: /* start a background consistency check */ 871 /* XXX implement */ 872 break; 873 874 /* 875 * Get the status of the current rebuild or consistency check. 876 */ 877 case MLXD_REBUILDSTAT: 878 879 if (sc->mlx_rebuild >= 0) { /* may be a second or so out of date */ 880 mp->rs_drive = sc->mlx_rebuild; 881 mp->rs_size = sc->mlx_sysdrive[sc->mlx_rebuild].ms_size; 882 mp->rs_remaining = sc->mlx_rebuildstat; 883 return(0); 884 } else if (sc->mlx_check >= 0) { 885 /* XXX implement */ 886 } else { 887 /* XXX should return status of last completed operation? */ 888 return(EINVAL); 889 } 890 891 } 892 return(ENOIOCTL); 893 } 894 895 896 /******************************************************************************** 897 ******************************************************************************** 898 Status Monitoring 899 ******************************************************************************** 900 ********************************************************************************/ 901 902 /******************************************************************************** 903 * Fire off commands to periodically check the status of connected drives. 904 */ 905 static void 906 mlx_periodic(void *data) 907 { 908 struct mlx_softc *sc = (struct mlx_softc *)data; 909 910 debug("called"); 911 912 /* 913 * Run a bus pause? 914 */ 915 if ((sc->mlx_pause.mp_which != 0) && 916 (sc->mlx_pause.mp_when > 0) && 917 (time_second >= sc->mlx_pause.mp_when)){ 918 919 mlx_pause_action(sc); /* pause is running */ 920 sc->mlx_pause.mp_when = 0; 921 sysbeep(500, hz); 922 923 /* 924 * Bus pause still running? 925 */ 926 } else if ((sc->mlx_pause.mp_which != 0) && 927 (sc->mlx_pause.mp_when == 0)) { 928 929 /* time to stop bus pause? */ 930 if (time_second >= sc->mlx_pause.mp_howlong) { 931 mlx_pause_action(sc); 932 sc->mlx_pause.mp_which = 0; /* pause is complete */ 933 sysbeep(500, hz); 934 } else { 935 sysbeep((time_second % 5) * 100 + 500, hz/8); 936 } 937 938 /* 939 * Run normal periodic activities? 940 */ 941 } else if (time_second > (sc->mlx_lastpoll + 10)) { 942 sc->mlx_lastpoll = time_second; 943 944 /* 945 * Check controller status. 946 * 947 * XXX Note that this may not actually launch a command in situations of high load. 948 */ 949 mlx_enquire(sc, MLX_CMD_ENQUIRY, sizeof(struct mlx_enquiry), mlx_periodic_enquiry); 950 951 /* 952 * Check system drive status. 953 * 954 * XXX This might be better left to event-driven detection, eg. I/O to an offline 955 * drive will detect it's offline, rebuilds etc. should detect the drive is back 956 * online. 957 */ 958 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES, 959 mlx_periodic_enquiry); 960 961 /* 962 * Get drive rebuild/check status 963 */ 964 if (sc->mlx_rebuild >= 0) 965 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild); 966 } 967 968 /* deal with possibly-missed interrupts and timed-out commands */ 969 mlx_done(sc); 970 971 /* reschedule another poll next second or so */ 972 sc->mlx_timeout = timeout(mlx_periodic, sc, hz); 973 } 974 975 /******************************************************************************** 976 * Handle the result of an ENQUIRY command instigated by periodic status polling. 977 */ 978 static void 979 mlx_periodic_enquiry(struct mlx_command *mc) 980 { 981 struct mlx_softc *sc = mc->mc_sc; 982 983 debug("called"); 984 985 /* Command completed OK? */ 986 if (mc->mc_status != 0) { 987 device_printf(sc->mlx_dev, "periodic enquiry failed\n"); 988 goto out; 989 } 990 991 /* respond to command */ 992 switch(mc->mc_mailbox[0]) { 993 /* 994 * Generic controller status update. We could do more with this than just 995 * checking the event log. 996 */ 997 case MLX_CMD_ENQUIRY: 998 { 999 struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data; 1000 1001 if (sc->mlx_lastevent == -1) { 1002 /* initialise our view of the event log */ 1003 sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num; 1004 } else if (me->me_event_log_seq_num != sc->mlx_lastevent) { 1005 /* record where current events are up to */ 1006 sc->mlx_currevent = me->me_event_log_seq_num; 1007 device_printf(sc->mlx_dev, "event log pointer was %d, now %d\n", 1008 sc->mlx_lastevent, sc->mlx_currevent); 1009 1010 /* drain new eventlog entries */ 1011 mlx_periodic_eventlog_poll(sc); 1012 } 1013 break; 1014 } 1015 case MLX_CMD_ENQSYSDRIVE: 1016 { 1017 struct mlx_enq_sys_drive *mes = (struct mlx_enq_sys_drive *)mc->mc_data; 1018 struct mlx_sysdrive *dr; 1019 int i; 1020 1021 for (i = 0, dr = &sc->mlx_sysdrive[0]; 1022 (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 1023 i++) { 1024 1025 /* if disk is being rebuilt, we should not check it */ 1026 if (dr->ms_state == MLX_SYSD_REBUILD) { 1027 /* has state been changed by controller? */ 1028 if (dr->ms_state != mes[i].sd_state) { 1029 switch(mes[i].sd_state) { 1030 case MLX_SYSD_OFFLINE: 1031 device_printf(dr->ms_disk, "drive offline\n"); 1032 break; 1033 case MLX_SYSD_ONLINE: 1034 device_printf(dr->ms_disk, "drive online\n"); 1035 break; 1036 case MLX_SYSD_CRITICAL: 1037 device_printf(dr->ms_disk, "drive critical\n"); 1038 break; 1039 } 1040 /* save new state */ 1041 dr->ms_state = mes[i].sd_state; 1042 } 1043 } 1044 } 1045 break; 1046 } 1047 default: 1048 device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __FUNCTION__, mc->mc_mailbox[0]); 1049 break; 1050 } 1051 1052 out: 1053 free(mc->mc_data, M_DEVBUF); 1054 mlx_releasecmd(mc); 1055 } 1056 1057 /******************************************************************************** 1058 * Instigate a poll for one event log message on (sc). 1059 * We only poll for one message at a time, to keep our command usage down. 1060 */ 1061 static void 1062 mlx_periodic_eventlog_poll(struct mlx_softc *sc) 1063 { 1064 struct mlx_command *mc; 1065 void *result = NULL; 1066 int error; 1067 1068 debug("called"); 1069 1070 /* get ourselves a command buffer */ 1071 error = 1; 1072 if ((mc = mlx_alloccmd(sc)) == NULL) 1073 goto out; 1074 /* allocate the response structure */ 1075 if ((result = malloc(/*sizeof(struct mlx_eventlog_entry)*/1024, M_DEVBUF, M_NOWAIT)) == NULL) 1076 goto out; 1077 /* get a command slot */ 1078 if (mlx_getslot(mc)) 1079 goto out; 1080 1081 /* map the command so the controller can see it */ 1082 mc->mc_data = result; 1083 mc->mc_length = /*sizeof(struct mlx_eventlog_entry)*/1024; 1084 mlx_mapcmd(mc); 1085 1086 /* build the command to get one entry */ 1087 mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1, sc->mlx_lastevent, 0, 0, mc->mc_dataphys, 0); 1088 mc->mc_complete = mlx_periodic_eventlog_respond; 1089 mc->mc_private = mc; 1090 1091 /* start the command */ 1092 if ((error = mlx_start(mc)) != 0) 1093 goto out; 1094 1095 error = 0; /* success */ 1096 out: 1097 if (error != 0) { 1098 if (mc != NULL) 1099 mlx_releasecmd(mc); 1100 if (result != NULL) 1101 free(result, M_DEVBUF); 1102 } 1103 } 1104 1105 /******************************************************************************** 1106 * Handle the result of polling for a log message, generate diagnostic output. 1107 * If this wasn't the last message waiting for us, we'll go collect another. 1108 */ 1109 static char *mlx_sense_messages[] = { 1110 "because write recovery failed", 1111 "because of SCSI bus reset failure", 1112 "because of double check condition", 1113 "because it was removed", 1114 "because of gross error on SCSI chip", 1115 "because of bad tag returned from drive", 1116 "because of timeout on SCSI command", 1117 "because of reset SCSI command issued from system", 1118 "because busy or parity error count exceeded limit", 1119 "because of 'kill drive' command from system", 1120 "because of selection timeout", 1121 "due to SCSI phase sequence error", 1122 "due to unknown status" 1123 }; 1124 1125 static void 1126 mlx_periodic_eventlog_respond(struct mlx_command *mc) 1127 { 1128 struct mlx_softc *sc = mc->mc_sc; 1129 struct mlx_eventlog_entry *el = (struct mlx_eventlog_entry *)mc->mc_data; 1130 char *reason; 1131 1132 debug("called"); 1133 1134 sc->mlx_lastevent++; /* next message... */ 1135 if (mc->mc_status == 0) { 1136 1137 /* handle event log message */ 1138 switch(el->el_type) { 1139 /* 1140 * This is the only sort of message we understand at the moment. 1141 * The tests here are probably incomplete. 1142 */ 1143 case MLX_LOGMSG_SENSE: /* sense data */ 1144 /* Mylex vendor-specific message indicating a drive was killed? */ 1145 if ((el->el_sensekey == 9) && 1146 (el->el_asc == 0x80)) { 1147 if (el->el_asq < (sizeof(mlx_sense_messages) / sizeof(mlx_sense_messages[0]))) { 1148 reason = mlx_sense_messages[el->el_asq]; 1149 } else { 1150 reason = "for unknown reason"; 1151 } 1152 device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n", 1153 el->el_channel, el->el_target, reason); 1154 } 1155 /* SCSI drive was reset? */ 1156 if ((el->el_sensekey == 6) && (el->el_asc == 0x29)) { 1157 device_printf(sc->mlx_dev, "physical drive %d:%d reset\n", 1158 el->el_channel, el->el_target); 1159 } 1160 /* SCSI drive error? */ 1161 if (!((el->el_sensekey == 0) || 1162 ((el->el_sensekey == 2) && 1163 (el->el_asc == 0x04) && 1164 ((el->el_asq == 0x01) || 1165 (el->el_asq == 0x02))))) { 1166 device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n", 1167 el->el_channel, el->el_target, el->el_sensekey, el->el_asc, el->el_asq); 1168 device_printf(sc->mlx_dev, " info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":"); 1169 } 1170 break; 1171 1172 default: 1173 device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type); 1174 break; 1175 } 1176 } else { 1177 device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc)); 1178 } 1179 1180 /* dispose of command and data */ 1181 free(mc->mc_data, M_DEVBUF); 1182 mlx_releasecmd(mc); 1183 1184 /* is there another message to obtain? */ 1185 if (sc->mlx_lastevent != sc->mlx_currevent) 1186 mlx_periodic_eventlog_poll(sc); 1187 } 1188 1189 /******************************************************************************** 1190 * Handle the completion of a rebuild operation. 1191 */ 1192 static void 1193 mlx_periodic_rebuild(struct mlx_command *mc) 1194 { 1195 struct mlx_softc *sc = mc->mc_sc; 1196 struct mlx_rebuild_stat *mr = (struct mlx_rebuild_stat *)mc->mc_private; 1197 1198 switch(mc->mc_status) { 1199 case 0: /* all OK, rebuild still running */ 1200 sc->mlx_rebuildstat = mr->rb_remaining; 1201 break; 1202 1203 case 0x0105: /* rebuild/check finished */ 1204 if (sc->mlx_rebuild >= 0) { 1205 device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild completed\n"); 1206 sc->mlx_rebuild = -1; 1207 } else if (sc->mlx_check >= 0) { 1208 device_printf(sc->mlx_sysdrive[sc->mlx_check].ms_disk, "consistency check completed\n"); 1209 sc->mlx_check = -1; 1210 } else { 1211 device_printf(sc->mlx_dev, "consistency check completed\n"); 1212 } 1213 break; 1214 } 1215 free(mc->mc_data, M_DEVBUF); 1216 mlx_releasecmd(mc); 1217 } 1218 1219 /******************************************************************************** 1220 ******************************************************************************** 1221 Channel Pause 1222 ******************************************************************************** 1223 ********************************************************************************/ 1224 1225 /******************************************************************************** 1226 * It's time to perform a channel pause action for (sc), either start or stop 1227 * the pause. 1228 */ 1229 static void 1230 mlx_pause_action(struct mlx_softc *sc) 1231 { 1232 struct mlx_command *mc; 1233 int failsafe, i, command; 1234 1235 /* What are we doing here? */ 1236 if (sc->mlx_pause.mp_when == 0) { 1237 command = MLX_CMD_STARTCHANNEL; 1238 failsafe = 0; 1239 1240 } else { 1241 command = MLX_CMD_STOPCHANNEL; 1242 1243 /* 1244 * Channels will always start again after the failsafe period, 1245 * which is specified in multiples of 30 seconds. 1246 * This constrains us to a maximum pause of 450 seconds. 1247 */ 1248 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30; 1249 if (failsafe > 0xf) { 1250 failsafe = 0xf; 1251 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5; 1252 } 1253 } 1254 1255 /* build commands for every channel requested */ 1256 for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) { 1257 if ((1 << i) & sc->mlx_pause.mp_which) { 1258 1259 /* get ourselves a command buffer */ 1260 if ((mc = mlx_alloccmd(sc)) == NULL) 1261 goto fail; 1262 /* get a command slot */ 1263 mc->mc_flags |= MLX_CMD_PRIORITY; 1264 if (mlx_getslot(mc)) 1265 goto fail; 1266 1267 /* build the command */ 1268 mlx_make_type2(mc, command, (failsafe << 4) | i, 0, 0, 0, 0, 0, 0, 0); 1269 mc->mc_complete = mlx_pause_done; 1270 mc->mc_private = sc; /* XXX not needed */ 1271 if (mlx_start(mc)) 1272 goto fail; 1273 /* command submitted OK */ 1274 return; 1275 1276 fail: 1277 device_printf(sc->mlx_dev, "%s failed for channel %d\n", 1278 command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", i); 1279 if (mc != NULL) 1280 mlx_releasecmd(mc); 1281 } 1282 } 1283 } 1284 1285 static void 1286 mlx_pause_done(struct mlx_command *mc) 1287 { 1288 struct mlx_softc *sc = mc->mc_sc; 1289 int command = mc->mc_mailbox[0]; 1290 int channel = mc->mc_mailbox[2] & 0xf; 1291 1292 if (mc->mc_status != 0) { 1293 device_printf(sc->mlx_dev, "%s command failed - %s\n", 1294 command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc)); 1295 } else if (command == MLX_CMD_STOPCHANNEL) { 1296 device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n", 1297 channel, (long)(sc->mlx_pause.mp_howlong - time_second)); 1298 } else { 1299 device_printf(sc->mlx_dev, "channel %d resuming\n", channel); 1300 } 1301 mlx_releasecmd(mc); 1302 } 1303 1304 /******************************************************************************** 1305 ******************************************************************************** 1306 Command Submission 1307 ******************************************************************************** 1308 ********************************************************************************/ 1309 1310 /******************************************************************************** 1311 * Perform an Enquiry command using a type-3 command buffer and a return a single 1312 * linear result buffer. If the completion function is specified, it will 1313 * be called with the completed command (and the result response will not be 1314 * valid until that point). Otherwise, the command will either be busy-waited 1315 * for (interrupts not enabled), or slept for. 1316 */ 1317 static void * 1318 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc)) 1319 { 1320 struct mlx_command *mc; 1321 void *result; 1322 int error; 1323 1324 debug("called"); 1325 1326 /* get ourselves a command buffer */ 1327 error = 1; 1328 result = NULL; 1329 if ((mc = mlx_alloccmd(sc)) == NULL) 1330 goto out; 1331 /* allocate the response structure */ 1332 if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL) 1333 goto out; 1334 /* get a command slot */ 1335 mc->mc_flags |= MLX_CMD_PRIORITY | MLX_CMD_DATAOUT; 1336 if (mlx_getslot(mc)) 1337 goto out; 1338 1339 /* map the command so the controller can see it */ 1340 mc->mc_data = result; 1341 mc->mc_length = bufsize; 1342 mlx_mapcmd(mc); 1343 1344 /* build an enquiry command */ 1345 mlx_make_type2(mc, command, 0, 0, 0, 0, 0, 0, mc->mc_dataphys, 0); 1346 1347 /* do we want a completion callback? */ 1348 if (complete != NULL) { 1349 mc->mc_complete = complete; 1350 mc->mc_private = mc; 1351 if ((error = mlx_start(mc)) != 0) 1352 goto out; 1353 } else { 1354 /* run the command in either polled or wait mode */ 1355 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc)) 1356 goto out; 1357 1358 /* command completed OK? */ 1359 if (mc->mc_status != 0) { 1360 device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n", mlx_diagnose_command(mc)); 1361 goto out; 1362 } 1363 } 1364 error = 0; /* success */ 1365 out: 1366 /* we got a command, but nobody else will free it */ 1367 if ((complete == NULL) && (mc != NULL)) 1368 mlx_releasecmd(mc); 1369 /* we got an error, and we allocated a result */ 1370 if ((error != 0) && (result != NULL)) { 1371 free(result, M_DEVBUF); 1372 result = NULL; 1373 } 1374 return(result); 1375 } 1376 1377 1378 /******************************************************************************** 1379 * Perform a Flush command on the nominated controller. 1380 * 1381 * May be called with interrupts enabled or disabled; will not return until 1382 * the flush operation completes or fails. 1383 */ 1384 static int 1385 mlx_flush(struct mlx_softc *sc) 1386 { 1387 struct mlx_command *mc; 1388 int error; 1389 1390 debug("called"); 1391 1392 /* get ourselves a command buffer */ 1393 error = 1; 1394 if ((mc = mlx_alloccmd(sc)) == NULL) 1395 goto out; 1396 /* get a command slot */ 1397 if (mlx_getslot(mc)) 1398 goto out; 1399 1400 /* build a flush command */ 1401 mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0); 1402 1403 /* can't assume that interrupts are going to work here, so play it safe */ 1404 if (mlx_poll_command(mc)) 1405 goto out; 1406 1407 /* command completed OK? */ 1408 if (mc->mc_status != 0) { 1409 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc)); 1410 goto out; 1411 } 1412 1413 error = 0; /* success */ 1414 out: 1415 if (mc != NULL) 1416 mlx_releasecmd(mc); 1417 return(error); 1418 } 1419 1420 /******************************************************************************** 1421 * Start a background rebuild on the nominated controller/channel/target. 1422 * 1423 * May be called with interrupts enabled or disabled; will return as soon as the 1424 * operation has started or been refused. 1425 */ 1426 static int 1427 mlx_rebuild(struct mlx_softc *sc, int channel, int target) 1428 { 1429 struct mlx_command *mc; 1430 int error; 1431 1432 debug("called"); 1433 1434 /* get ourselves a command buffer */ 1435 error = 0x10000; 1436 if ((mc = mlx_alloccmd(sc)) == NULL) 1437 goto out; 1438 /* get a command slot */ 1439 if (mlx_getslot(mc)) 1440 goto out; 1441 1442 /* build a rebuild command */ 1443 mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0); 1444 1445 /* run the command in either polled or wait mode */ 1446 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc)) 1447 goto out; 1448 1449 /* command completed OK? */ 1450 if (mc->mc_status != 0) { 1451 device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc)); 1452 } else { 1453 device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild started"); 1454 } 1455 error = mc->mc_status; 1456 1457 out: 1458 if (mc != NULL) 1459 mlx_releasecmd(mc); 1460 return(error); 1461 } 1462 1463 /******************************************************************************** 1464 * Run the command (mc) and return when it completes. 1465 * 1466 * Interrupts need to be enabled; returns nonzero on error. 1467 */ 1468 static int 1469 mlx_wait_command(struct mlx_command *mc) 1470 { 1471 struct mlx_softc *sc = mc->mc_sc; 1472 int error, count; 1473 1474 debug("called"); 1475 1476 mc->mc_complete = NULL; 1477 mc->mc_private = mc; /* wake us when you're done */ 1478 if ((error = mlx_start(mc)) != 0) 1479 return(error); 1480 1481 count = 0; 1482 /* XXX better timeout? */ 1483 while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) { 1484 tsleep(mc->mc_private, PRIBIO | PCATCH, "mlxwcmd", hz); 1485 } 1486 1487 if (mc->mc_status != 0) { 1488 device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status); 1489 return(EIO); 1490 } 1491 return(0); 1492 } 1493 1494 1495 /******************************************************************************** 1496 * Start the command (mc) and busy-wait for it to complete. 1497 * 1498 * Should only be used when interrupts are not available. Returns 0 on 1499 * success, nonzero on error. 1500 * Successfully completed commands are dequeued. 1501 */ 1502 static int 1503 mlx_poll_command(struct mlx_command *mc) 1504 { 1505 struct mlx_softc *sc = mc->mc_sc; 1506 int error, count, s; 1507 1508 debug("called"); 1509 1510 mc->mc_complete = NULL; 1511 mc->mc_private = NULL; /* we will poll for it */ 1512 if ((error = mlx_start(mc)) != 0) 1513 return(error); 1514 1515 count = 0; 1516 do { 1517 /* poll for completion */ 1518 mlx_done(mc->mc_sc); 1519 } while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 10000)); 1520 if (mc->mc_status != MLX_STATUS_BUSY) { 1521 s = splbio(); 1522 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 1523 splx(s); 1524 return(0); 1525 } 1526 device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status); 1527 return(EIO); 1528 } 1529 1530 /******************************************************************************** 1531 * Pull as much work off the softc's work queue as possible and give it to the 1532 * controller. Leave a couple of slots free for emergencies. 1533 * 1534 * Must be called at splbio or in an equivalent fashion that prevents 1535 * reentry or activity on the bufq.. 1536 */ 1537 static void 1538 mlx_startio(struct mlx_softc *sc) 1539 { 1540 struct mlx_command *mc; 1541 struct mlxd_softc *mlxd; 1542 struct buf *bp; 1543 int blkcount; 1544 int driveno; 1545 int cmd; 1546 int s; 1547 1548 /* avoid reentrancy */ 1549 if (mlx_lock_tas(sc, MLX_LOCK_STARTING)) 1550 return; 1551 1552 /* spin until something prevents us from doing any work */ 1553 s = splbio(); 1554 for (;;) { 1555 1556 /* see if there's work to be done */ 1557 if ((bp = bufq_first(&sc->mlx_bufq)) == NULL) 1558 break; 1559 /* get a command */ 1560 if ((mc = mlx_alloccmd(sc)) == NULL) 1561 break; 1562 /* get a slot for the command */ 1563 if (mlx_getslot(mc) != 0) { 1564 mlx_releasecmd(mc); 1565 break; 1566 } 1567 /* get the buf containing our work */ 1568 bufq_remove(&sc->mlx_bufq, bp); 1569 sc->mlx_waitbufs--; 1570 splx(s); 1571 1572 /* connect the buf to the command */ 1573 mc->mc_complete = mlx_completeio; 1574 mc->mc_private = bp; 1575 mc->mc_data = bp->b_data; 1576 mc->mc_length = bp->b_bcount; 1577 if (bp->b_flags & B_READ) { 1578 mc->mc_flags |= MLX_CMD_DATAIN; 1579 cmd = MLX_CMD_READOLDSG; 1580 } else { 1581 mc->mc_flags |= MLX_CMD_DATAOUT; 1582 cmd = MLX_CMD_WRITEOLDSG; 1583 } 1584 1585 /* map the command so the controller can work with it */ 1586 mlx_mapcmd(mc); 1587 1588 /* build a suitable I/O command (assumes 512-byte rounded transfers) */ 1589 mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1; 1590 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive; 1591 blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE; 1592 1593 if ((bp->b_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size) 1594 device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n", 1595 bp->b_pblkno, blkcount, sc->mlx_sysdrive[driveno].ms_size); 1596 1597 /* 1598 * Build the I/O command. Note that the SG list type bits are set to zero, 1599 * denoting the format of SG list that we are using. 1600 */ 1601 mlx_make_type5(mc, cmd, 1602 blkcount & 0xff, /* xfer length low byte */ 1603 (driveno << 3) | ((blkcount >> 8) & 0x07), /* target and length high 3 bits */ 1604 bp->b_pblkno, /* physical block number */ 1605 mc->mc_sgphys, /* location of SG list */ 1606 mc->mc_nsgent & 0x3f); /* size of SG list (top 2 bits clear) */ 1607 1608 1609 /* try to give command to controller */ 1610 if (mlx_start(mc) != 0) { 1611 /* fail the command */ 1612 mc->mc_status = MLX_STATUS_WEDGED; 1613 mlx_completeio(mc); 1614 } 1615 s = splbio(); 1616 } 1617 splx(s); 1618 mlx_lock_clr(sc, MLX_LOCK_STARTING); 1619 } 1620 1621 /******************************************************************************** 1622 * Handle completion of an I/O command. 1623 */ 1624 static void 1625 mlx_completeio(struct mlx_command *mc) 1626 { 1627 struct mlx_softc *sc = mc->mc_sc; 1628 struct buf *bp = (struct buf *)mc->mc_private; 1629 struct mlxd_softc *mlxd = (struct mlxd_softc *)bp->b_dev->si_drv1; 1630 1631 if (mc->mc_status != MLX_STATUS_OK) { /* could be more verbose here? */ 1632 bp->b_error = EIO; 1633 bp->b_flags |= B_ERROR; 1634 1635 switch(mc->mc_status) { 1636 case MLX_STATUS_RDWROFFLINE: /* system drive has gone offline */ 1637 device_printf(mlxd->mlxd_dev, "drive offline\n"); 1638 /* should signal this with a return code */ 1639 mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE; 1640 break; 1641 1642 default: /* other I/O error */ 1643 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc)); 1644 #if 0 1645 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n", 1646 bp->b_bcount, bp->b_bcount / MLX_BLKSIZE, bp->b_pblkno); 1647 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " "); 1648 #endif 1649 break; 1650 } 1651 } 1652 mlx_releasecmd(mc); 1653 mlxd_intr(bp); 1654 } 1655 1656 /******************************************************************************** 1657 * Take a command from user-space and try to run it. 1658 */ 1659 static int 1660 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu) 1661 { 1662 struct mlx_command *mc; 1663 void *kbuf; 1664 int error; 1665 1666 kbuf = NULL; 1667 mc = NULL; 1668 error = ENOMEM; 1669 /* get a kernel buffer for the transfer */ 1670 if (mu->mu_datasize > 0) { 1671 if ((kbuf = malloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) 1672 goto out; 1673 if ((mu->mu_bufptr < 0) || (mu->mu_bufptr > (sizeof(mu->mu_command) < sizeof(u_int32_t)))) { 1674 error = EINVAL; 1675 goto out; 1676 } 1677 } 1678 /* get ourselves a command buffer */ 1679 if ((mc = mlx_alloccmd(sc)) == NULL) 1680 goto out; 1681 1682 /* copy the command and data */ 1683 bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox)); 1684 if ((mu->mu_datasize > 0) && ((error = copyin(mu->mu_buf, kbuf, mu->mu_datasize)))) 1685 goto out; 1686 1687 /* get a command slot */ 1688 if (mlx_getslot(mc)) 1689 goto out; 1690 1691 /* map the command so the controller can see it */ 1692 mc->mc_data = kbuf; 1693 mc->mc_length = mu->mu_datasize; 1694 mlx_mapcmd(mc); 1695 1696 /* if there's a data buffer, fix up the command */ 1697 if (mu->mu_datasize > 0) { 1698 mc->mc_mailbox[mu->mu_bufptr ] = mc->mc_length & 0xff; 1699 mc->mc_mailbox[mu->mu_bufptr + 1] = (mc->mc_length >> 8) & 0xff; 1700 mc->mc_mailbox[mu->mu_bufptr + 2] = (mc->mc_length >> 16) & 0xff; 1701 mc->mc_mailbox[mu->mu_bufptr + 3] = (mc->mc_length >> 24) & 0xff; 1702 } 1703 1704 /* submit the command and wait */ 1705 if ((error = mlx_wait_command(mc)) != 0) 1706 goto out; 1707 1708 /* copy out status and data */ 1709 mu->mu_status = mc->mc_status; 1710 if ((mu->mu_datasize > 0) && ((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize)))) 1711 goto out; 1712 error = 0; 1713 1714 out: 1715 mlx_releasecmd(mc); 1716 if (kbuf != NULL) 1717 free(kbuf, M_DEVBUF); 1718 return(error); 1719 } 1720 1721 /******************************************************************************** 1722 ******************************************************************************** 1723 Command I/O to Controller 1724 ******************************************************************************** 1725 ********************************************************************************/ 1726 1727 /******************************************************************************** 1728 * Find a free command slot for (mc). 1729 * 1730 * Don't hand out a slot to a normal-priority command unless there are at least 1731 * 4 slots free for priority commands. 1732 */ 1733 static int 1734 mlx_getslot(struct mlx_command *mc) 1735 { 1736 struct mlx_softc *sc = mc->mc_sc; 1737 int s, slot; 1738 1739 debug("called mc %p sc %p", mc, sc); 1740 1741 /* enforce slot-usage limit */ 1742 if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? 1743 sc->mlx_maxiop : sc->mlx_maxiop - 4)) 1744 return(EBUSY); 1745 1746 /* 1747 * Allocate an outstanding command slot 1748 * 1749 * XXX linear search is slow 1750 */ 1751 s = splbio(); 1752 for (slot = 0; slot < sc->mlx_maxiop; slot++) { 1753 debug("try slot %d", slot); 1754 if (sc->mlx_busycmd[slot] == NULL) 1755 break; 1756 } 1757 if (slot < sc->mlx_maxiop) { 1758 sc->mlx_busycmd[slot] = mc; 1759 sc->mlx_busycmds++; 1760 } 1761 splx(s); 1762 1763 /* out of slots? */ 1764 if (slot >= sc->mlx_maxiop) 1765 return(EBUSY); 1766 1767 debug("got slot %d", slot); 1768 mc->mc_slot = slot; 1769 return(0); 1770 } 1771 1772 /******************************************************************************** 1773 * Map/unmap (mc)'s data in the controller's addressable space. 1774 */ 1775 static void 1776 mlx_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error) 1777 { 1778 struct mlx_command *mc = (struct mlx_command *)arg; 1779 struct mlx_softc *sc = mc->mc_sc; 1780 struct mlx_sgentry *sg; 1781 int i; 1782 1783 debug("called"); 1784 1785 /* get base address of s/g table */ 1786 sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG); 1787 1788 /* save s/g table information in command */ 1789 mc->mc_nsgent = nsegments; 1790 mc->mc_sgphys = sc->mlx_sgbusaddr + (mc->mc_slot * MLX_NSEG * sizeof(struct mlx_sgentry)); 1791 mc->mc_dataphys = segs[0].ds_addr; 1792 1793 /* populate s/g table */ 1794 for (i = 0; i < nsegments; i++, sg++) { 1795 sg->sg_addr = segs[i].ds_addr; 1796 sg->sg_count = segs[i].ds_len; 1797 } 1798 } 1799 1800 static void 1801 mlx_mapcmd(struct mlx_command *mc) 1802 { 1803 struct mlx_softc *sc = mc->mc_sc; 1804 1805 debug("called"); 1806 1807 /* if the command involves data at all */ 1808 if (mc->mc_data != NULL) { 1809 1810 /* map the data buffer into bus space and build the s/g list */ 1811 bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, mc->mc_length, 1812 mlx_setup_dmamap, mc, 0); 1813 if (mc->mc_flags & MLX_CMD_DATAIN) 1814 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREREAD); 1815 if (mc->mc_flags & MLX_CMD_DATAOUT) 1816 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREWRITE); 1817 } 1818 } 1819 1820 static void 1821 mlx_unmapcmd(struct mlx_command *mc) 1822 { 1823 struct mlx_softc *sc = mc->mc_sc; 1824 1825 debug("called"); 1826 1827 /* if the command involved data at all */ 1828 if (mc->mc_data != NULL) { 1829 1830 if (mc->mc_flags & MLX_CMD_DATAIN) 1831 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD); 1832 if (mc->mc_flags & MLX_CMD_DATAOUT) 1833 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE); 1834 1835 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap); 1836 } 1837 } 1838 1839 /******************************************************************************** 1840 * Try to deliver (mc) to the controller. 1841 * 1842 * Can be called at any interrupt level, with or without interrupts enabled. 1843 */ 1844 static int 1845 mlx_start(struct mlx_command *mc) 1846 { 1847 struct mlx_softc *sc = mc->mc_sc; 1848 int i, s, done; 1849 1850 debug("called"); 1851 1852 /* save the slot number as ident so we can handle this command when complete */ 1853 mc->mc_mailbox[0x1] = mc->mc_slot; 1854 1855 /* mark the command as currently being processed */ 1856 mc->mc_status = MLX_STATUS_BUSY; 1857 1858 /* set a default 60-second timeout XXX tunable? XXX not currently used */ 1859 mc->mc_timeout = time_second + 60; 1860 1861 /* spin waiting for the mailbox */ 1862 for (i = 100000, done = 0; (i > 0) && !done; i--) { 1863 s = splbio(); 1864 if (sc->mlx_tryqueue(sc, mc)) { 1865 done = 1; 1866 /* move command to work queue */ 1867 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link); 1868 } 1869 splx(s); /* drop spl to allow completion interrupts */ 1870 } 1871 1872 /* command is enqueued */ 1873 if (done) 1874 return(0); 1875 1876 /* 1877 * We couldn't get the controller to take the command. Revoke the slot 1878 * that the command was given and return it with a bad status. 1879 */ 1880 sc->mlx_busycmd[mc->mc_slot] = NULL; 1881 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n"); 1882 mc->mc_status = MLX_STATUS_WEDGED; 1883 mlx_complete(sc); 1884 return(EIO); 1885 } 1886 1887 /******************************************************************************** 1888 * Poll the controller (sc) for completed commands. 1889 * Update command status and free slots for reuse. If any slots were freed, 1890 * new commands may be posted. 1891 * 1892 * Returns nonzero if one or more commands were completed. 1893 */ 1894 static int 1895 mlx_done(struct mlx_softc *sc) 1896 { 1897 struct mlx_command *mc; 1898 int s, result; 1899 u_int8_t slot; 1900 u_int16_t status; 1901 1902 debug("called"); 1903 1904 result = 0; 1905 1906 /* loop collecting completed commands */ 1907 s = splbio(); 1908 for (;;) { 1909 /* poll for a completed command's identifier and status */ 1910 if (sc->mlx_findcomplete(sc, &slot, &status)) { 1911 result = 1; 1912 mc = sc->mlx_busycmd[slot]; /* find command */ 1913 if (mc != NULL) { /* paranoia */ 1914 if (mc->mc_status == MLX_STATUS_BUSY) { 1915 mc->mc_status = status; /* save status */ 1916 1917 /* free slot for reuse */ 1918 sc->mlx_busycmd[slot] = NULL; 1919 sc->mlx_busycmds--; 1920 } else { 1921 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot); 1922 } 1923 } else { 1924 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot); 1925 } 1926 } else { 1927 break; 1928 } 1929 } 1930 1931 /* if we've completed any commands, try posting some more */ 1932 if (result) 1933 mlx_startio(sc); 1934 1935 /* handle completion and timeouts */ 1936 mlx_complete(sc); 1937 1938 return(result); 1939 } 1940 1941 /******************************************************************************** 1942 * Perform post-completion processing for commands on (sc). 1943 */ 1944 static void 1945 mlx_complete(struct mlx_softc *sc) 1946 { 1947 struct mlx_command *mc, *nc; 1948 int s, count; 1949 1950 debug("called"); 1951 1952 /* avoid reentrancy XXX might want to signal and request a restart */ 1953 if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING)) 1954 return; 1955 1956 s = splbio(); 1957 count = 0; 1958 1959 /* scan the list of busy/done commands */ 1960 mc = TAILQ_FIRST(&sc->mlx_work); 1961 while (mc != NULL) { 1962 nc = TAILQ_NEXT(mc, mc_link); 1963 1964 /* Command has been completed in some fashion */ 1965 if (mc->mc_status != MLX_STATUS_BUSY) { 1966 1967 /* unmap the command's data buffer */ 1968 mlx_unmapcmd(mc); 1969 /* 1970 * Does the command have a completion handler? 1971 */ 1972 if (mc->mc_complete != NULL) { 1973 /* remove from list and give to handler */ 1974 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 1975 mc->mc_complete(mc); 1976 1977 /* 1978 * Is there a sleeper waiting on this command? 1979 */ 1980 } else if (mc->mc_private != NULL) { /* sleeping caller wants to know about it */ 1981 1982 /* remove from list and wake up sleeper */ 1983 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link); 1984 wakeup_one(mc->mc_private); 1985 1986 /* 1987 * Leave the command for a caller that's polling for it. 1988 */ 1989 } else { 1990 } 1991 } 1992 mc = nc; 1993 } 1994 splx(s); 1995 1996 mlx_lock_clr(sc, MLX_LOCK_COMPLETING); 1997 } 1998 1999 /******************************************************************************** 2000 ******************************************************************************** 2001 Command Buffer Management 2002 ******************************************************************************** 2003 ********************************************************************************/ 2004 2005 /******************************************************************************** 2006 * Get a new command buffer. 2007 * 2008 * This may return NULL in low-memory cases. 2009 * 2010 * Note that using malloc() is expensive (the command buffer is << 1 page) but 2011 * necessary if we are to be a loadable module before the zone allocator is fixed. 2012 * 2013 * If possible, we recycle a command buffer that's been used before. 2014 * 2015 * XXX Note that command buffers are not cleaned out - it is the caller's 2016 * responsibility to ensure that all required fields are filled in before 2017 * using a buffer. 2018 */ 2019 static struct mlx_command * 2020 mlx_alloccmd(struct mlx_softc *sc) 2021 { 2022 struct mlx_command *mc; 2023 int error; 2024 int s; 2025 2026 debug("called"); 2027 2028 s = splbio(); 2029 if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) 2030 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link); 2031 splx(s); 2032 2033 /* allocate a new command buffer? */ 2034 if (mc == NULL) { 2035 mc = (struct mlx_command *)malloc(sizeof(*mc), M_DEVBUF, M_NOWAIT); 2036 if (mc != NULL) { 2037 bzero(mc, sizeof(*mc)); 2038 mc->mc_sc = sc; 2039 error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap); 2040 if (error) { 2041 free(mc, M_DEVBUF); 2042 return(NULL); 2043 } 2044 } 2045 } 2046 return(mc); 2047 } 2048 2049 /******************************************************************************** 2050 * Release a command buffer for recycling. 2051 * 2052 * XXX It might be a good idea to limit the number of commands we save for reuse 2053 * if it's shown that this list bloats out massively. 2054 */ 2055 static void 2056 mlx_releasecmd(struct mlx_command *mc) 2057 { 2058 int s; 2059 2060 debug("called"); 2061 2062 s = splbio(); 2063 TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link); 2064 splx(s); 2065 } 2066 2067 /******************************************************************************** 2068 * Permanently discard a command buffer. 2069 */ 2070 static void 2071 mlx_freecmd(struct mlx_command *mc) 2072 { 2073 struct mlx_softc *sc = mc->mc_sc; 2074 2075 debug("called"); 2076 2077 bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap); 2078 free(mc, M_DEVBUF); 2079 } 2080 2081 2082 /******************************************************************************** 2083 ******************************************************************************** 2084 Type 3 interface accessor methods 2085 ******************************************************************************** 2086 ********************************************************************************/ 2087 2088 /******************************************************************************** 2089 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2090 * (the controller is not ready to take a command). 2091 * 2092 * Must be called at splbio or in a fashion that prevents reentry. 2093 */ 2094 static int 2095 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2096 { 2097 int i; 2098 2099 debug("called"); 2100 2101 /* ready for our command? */ 2102 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) { 2103 /* copy mailbox data to window */ 2104 for (i = 0; i < 13; i++) 2105 MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2106 2107 /* post command */ 2108 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL); 2109 return(1); 2110 } 2111 return(0); 2112 } 2113 2114 /******************************************************************************** 2115 * See if a command has been completed, if so acknowledge its completion 2116 * and recover the slot number and status code. 2117 * 2118 * Must be called at splbio or in a fashion that prevents reentry. 2119 */ 2120 static int 2121 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2122 { 2123 2124 debug("called"); 2125 2126 /* status available? */ 2127 if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) { 2128 *slot = MLX_V3_GET_STATUS_IDENT(sc); /* get command identifier */ 2129 *status = MLX_V3_GET_STATUS(sc); /* get status */ 2130 2131 /* acknowledge completion */ 2132 MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL); 2133 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK); 2134 return(1); 2135 } 2136 return(0); 2137 } 2138 2139 /******************************************************************************** 2140 * Enable/disable interrupts as requested. (No acknowledge required) 2141 * 2142 * Must be called at splbio or in a fashion that prevents reentry. 2143 */ 2144 static void 2145 mlx_v3_intaction(struct mlx_softc *sc, int action) 2146 { 2147 debug("called"); 2148 2149 switch(action) { 2150 case MLX_INTACTION_DISABLE: 2151 MLX_V3_PUT_IER(sc, 0); 2152 sc->mlx_state &= ~MLX_STATE_INTEN; 2153 break; 2154 case MLX_INTACTION_ENABLE: 2155 MLX_V3_PUT_IER(sc, 1); 2156 sc->mlx_state |= MLX_STATE_INTEN; 2157 break; 2158 } 2159 } 2160 2161 2162 /******************************************************************************** 2163 ******************************************************************************** 2164 Type 4 interface accessor methods 2165 ******************************************************************************** 2166 ********************************************************************************/ 2167 2168 /******************************************************************************** 2169 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2170 * (the controller is not ready to take a command). 2171 * 2172 * Must be called at splbio or in a fashion that prevents reentry. 2173 */ 2174 static int 2175 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2176 { 2177 int i; 2178 2179 debug("called"); 2180 2181 /* ready for our command? */ 2182 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) { 2183 /* copy mailbox data to window */ 2184 for (i = 0; i < 13; i++) 2185 MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2186 2187 /* post command */ 2188 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD); 2189 return(1); 2190 } 2191 return(0); 2192 } 2193 2194 /******************************************************************************** 2195 * See if a command has been completed, if so acknowledge its completion 2196 * and recover the slot number and status code. 2197 * 2198 * Must be called at splbio or in a fashion that prevents reentry. 2199 */ 2200 static int 2201 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2202 { 2203 2204 debug("called"); 2205 2206 /* status available? */ 2207 if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) { 2208 *slot = MLX_V4_GET_STATUS_IDENT(sc); /* get command identifier */ 2209 *status = MLX_V4_GET_STATUS(sc); /* get status */ 2210 2211 /* acknowledge completion */ 2212 MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK); 2213 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK); 2214 return(1); 2215 } 2216 return(0); 2217 } 2218 2219 /******************************************************************************** 2220 * Enable/disable interrupts as requested. 2221 * 2222 * Must be called at splbio or in a fashion that prevents reentry. 2223 */ 2224 static void 2225 mlx_v4_intaction(struct mlx_softc *sc, int action) 2226 { 2227 debug("called"); 2228 2229 switch(action) { 2230 case MLX_INTACTION_DISABLE: 2231 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT); 2232 sc->mlx_state &= ~MLX_STATE_INTEN; 2233 break; 2234 case MLX_INTACTION_ENABLE: 2235 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT); 2236 sc->mlx_state |= MLX_STATE_INTEN; 2237 break; 2238 } 2239 } 2240 2241 2242 /******************************************************************************** 2243 ******************************************************************************** 2244 Type 5 interface accessor methods 2245 ******************************************************************************** 2246 ********************************************************************************/ 2247 2248 /******************************************************************************** 2249 * Try to give (mc) to the controller. Returns 1 if successful, 0 on failure 2250 * (the controller is not ready to take a command). 2251 * 2252 * Must be called at splbio or in a fashion that prevents reentry. 2253 */ 2254 static int 2255 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc) 2256 { 2257 int i; 2258 2259 debug("called"); 2260 2261 /* ready for our command? */ 2262 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) { 2263 /* copy mailbox data to window */ 2264 for (i = 0; i < 13; i++) 2265 MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]); 2266 2267 /* post command */ 2268 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD); 2269 return(1); 2270 } 2271 return(0); 2272 } 2273 2274 /******************************************************************************** 2275 * See if a command has been completed, if so acknowledge its completion 2276 * and recover the slot number and status code. 2277 * 2278 * Must be called at splbio or in a fashion that prevents reentry. 2279 */ 2280 static int 2281 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status) 2282 { 2283 2284 debug("called"); 2285 2286 /* status available? */ 2287 if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) { 2288 *slot = MLX_V5_GET_STATUS_IDENT(sc); /* get command identifier */ 2289 *status = MLX_V5_GET_STATUS(sc); /* get status */ 2290 2291 /* acknowledge completion */ 2292 MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK); 2293 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK); 2294 return(1); 2295 } 2296 return(0); 2297 } 2298 2299 /******************************************************************************** 2300 * Enable/disable interrupts as requested. 2301 * 2302 * Must be called at splbio or in a fashion that prevents reentry. 2303 */ 2304 static void 2305 mlx_v5_intaction(struct mlx_softc *sc, int action) 2306 { 2307 debug("called"); 2308 2309 switch(action) { 2310 case MLX_INTACTION_DISABLE: 2311 MLX_V5_PUT_IER(sc, MLX_V5_IER_DISINT); 2312 sc->mlx_state &= ~MLX_STATE_INTEN; 2313 break; 2314 case MLX_INTACTION_ENABLE: 2315 MLX_V5_PUT_IER(sc, 0); 2316 sc->mlx_state |= MLX_STATE_INTEN; 2317 break; 2318 } 2319 } 2320 2321 2322 /******************************************************************************** 2323 ******************************************************************************** 2324 Debugging 2325 ******************************************************************************** 2326 ********************************************************************************/ 2327 2328 /******************************************************************************** 2329 * Return a status message describing (mc) 2330 */ 2331 static char *mlx_status_messages[] = { 2332 "normal completion", /* 00 */ 2333 "irrecoverable data error", /* 01 */ 2334 "drive does not exist, or is offline", /* 02 */ 2335 "attempt to write beyond end of drive", /* 03 */ 2336 "bad data encountered", /* 04 */ 2337 "invalid log entry request", /* 05 */ 2338 "attempt to rebuild online drive", /* 06 */ 2339 "new disk failed during rebuild", /* 07 */ 2340 "invalid channel/target", /* 08 */ 2341 "rebuild/check already in progress", /* 09 */ 2342 "one or more disks are dead", /* 10 */ 2343 "invalid or non-redundant drive", /* 11 */ 2344 "channel is busy", /* 12 */ 2345 "channel is not stopped", /* 13 */ 2346 }; 2347 2348 static struct 2349 { 2350 int command; 2351 u_int16_t status; 2352 int msg; 2353 } mlx_messages[] = { 2354 {MLX_CMD_READOLDSG, 0x0001, 1}, 2355 {MLX_CMD_READOLDSG, 0x0002, 1}, 2356 {MLX_CMD_READOLDSG, 0x0105, 3}, 2357 {MLX_CMD_READOLDSG, 0x010c, 4}, 2358 {MLX_CMD_WRITEOLDSG, 0x0001, 1}, 2359 {MLX_CMD_WRITEOLDSG, 0x0002, 1}, 2360 {MLX_CMD_WRITEOLDSG, 0x0105, 3}, 2361 {MLX_CMD_LOGOP, 0x0105, 5}, 2362 {MLX_CMD_REBUILDASYNC, 0x0002, 6}, 2363 {MLX_CMD_REBUILDASYNC, 0x0004, 7}, 2364 {MLX_CMD_REBUILDASYNC, 0x0105, 8}, 2365 {MLX_CMD_REBUILDASYNC, 0x0106, 9}, 2366 {MLX_CMD_CHECKASYNC, 0x0002, 10}, 2367 {MLX_CMD_CHECKASYNC, 0x0105, 11}, 2368 {MLX_CMD_CHECKASYNC, 0x0106, 9}, 2369 {MLX_CMD_STOPCHANNEL, 0x0106, 12}, 2370 {MLX_CMD_STOPCHANNEL, 0x0105, 8}, 2371 {MLX_CMD_STARTCHANNEL, 0x0005, 13}, 2372 {MLX_CMD_STARTCHANNEL, 0x0105, 8}, 2373 {-1, 0, 0} 2374 }; 2375 2376 static char * 2377 mlx_diagnose_command(struct mlx_command *mc) 2378 { 2379 static char unkmsg[80]; 2380 int i; 2381 2382 /* look up message in table */ 2383 for (i = 0; mlx_messages[i].command != -1; i++) 2384 if ((mc->mc_mailbox[0] == mlx_messages[i].command) && 2385 (mc->mc_status == mlx_messages[i].status)) 2386 return(mlx_status_messages[mlx_messages[i].msg]); 2387 2388 sprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]); 2389 return(unkmsg); 2390 } 2391 2392 /******************************************************************************* 2393 * Return a string describing the controller (hwid) 2394 */ 2395 static struct 2396 { 2397 int hwid; 2398 char *name; 2399 } mlx_controller_names[] = { 2400 {0x01, "960P/PD"}, 2401 {0x02, "960PL"}, 2402 {0x10, "960PG"}, 2403 {0x11, "960PJ"}, 2404 {0x12, "960PR"}, 2405 {0x13, "960PT"}, 2406 {0x14, "960PTL0"}, 2407 {0x15, "960PRL"}, 2408 {0x16, "960PTL1"}, 2409 {0x20, "1164PVX"}, 2410 {-1, NULL} 2411 }; 2412 2413 static void 2414 mlx_describe_controller(struct mlx_softc *sc) 2415 { 2416 static char buf[80]; 2417 char *model; 2418 int i; 2419 2420 for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) { 2421 if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) { 2422 model = mlx_controller_names[i].name; 2423 break; 2424 } 2425 } 2426 if (model == NULL) { 2427 sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff); 2428 model = buf; 2429 } 2430 device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%d, %dMB RAM\n", 2431 model, 2432 sc->mlx_enq2->me_actual_channels, 2433 sc->mlx_enq2->me_actual_channels > 1 ? "s" : "", 2434 sc->mlx_enq2->me_firmware_id & 0xff, 2435 (sc->mlx_enq2->me_firmware_id >> 8) & 0xff, 2436 (sc->mlx_enq2->me_firmware_id >> 24) & 0xff, 2437 (sc->mlx_enq2->me_firmware_id >> 16) & 0xff, 2438 sc->mlx_enq2->me_mem_size / (1024 * 1024)); 2439 2440 if (bootverbose) { 2441 device_printf(sc->mlx_dev, " Hardware ID 0x%08x\n", sc->mlx_enq2->me_hardware_id); 2442 device_printf(sc->mlx_dev, " Firmware ID 0x%08x\n", sc->mlx_enq2->me_firmware_id); 2443 device_printf(sc->mlx_dev, " Configured/Actual channels %d/%d\n", sc->mlx_enq2->me_configured_channels, 2444 sc->mlx_enq2->me_actual_channels); 2445 device_printf(sc->mlx_dev, " Max Targets %d\n", sc->mlx_enq2->me_max_targets); 2446 device_printf(sc->mlx_dev, " Max Tags %d\n", sc->mlx_enq2->me_max_tags); 2447 device_printf(sc->mlx_dev, " Max System Drives %d\n", sc->mlx_enq2->me_max_sys_drives); 2448 device_printf(sc->mlx_dev, " Max Arms %d\n", sc->mlx_enq2->me_max_arms); 2449 device_printf(sc->mlx_dev, " Max Spans %d\n", sc->mlx_enq2->me_max_spans); 2450 device_printf(sc->mlx_dev, " DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size, 2451 sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size); 2452 device_printf(sc->mlx_dev, " DRAM type %d\n", sc->mlx_enq2->me_mem_type); 2453 device_printf(sc->mlx_dev, " Clock Speed %dns\n", sc->mlx_enq2->me_clock_speed); 2454 device_printf(sc->mlx_dev, " Hardware Speed %dns\n", sc->mlx_enq2->me_hardware_speed); 2455 device_printf(sc->mlx_dev, " Max Commands %d\n", sc->mlx_enq2->me_max_commands); 2456 device_printf(sc->mlx_dev, " Max SG Entries %d\n", sc->mlx_enq2->me_max_sg); 2457 device_printf(sc->mlx_dev, " Max DP %d\n", sc->mlx_enq2->me_max_dp); 2458 device_printf(sc->mlx_dev, " Max IOD %d\n", sc->mlx_enq2->me_max_iod); 2459 device_printf(sc->mlx_dev, " Max Comb %d\n", sc->mlx_enq2->me_max_comb); 2460 device_printf(sc->mlx_dev, " Latency %ds\n", sc->mlx_enq2->me_latency); 2461 device_printf(sc->mlx_dev, " SCSI Timeout %ds\n", sc->mlx_enq2->me_scsi_timeout); 2462 device_printf(sc->mlx_dev, " Min Free Lines %d\n", sc->mlx_enq2->me_min_freelines); 2463 device_printf(sc->mlx_dev, " Rate Constant %d\n", sc->mlx_enq2->me_rate_const); 2464 device_printf(sc->mlx_dev, " MAXBLK %d\n", sc->mlx_enq2->me_maxblk); 2465 device_printf(sc->mlx_dev, " Blocking Factor %d sectors\n", sc->mlx_enq2->me_blocking_factor); 2466 device_printf(sc->mlx_dev, " Cache Line Size %d blocks\n", sc->mlx_enq2->me_cacheline); 2467 device_printf(sc->mlx_dev, " SCSI Capability %s%dMHz, %d bit\n", 2468 sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "", 2469 (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10, 2470 8 << (sc->mlx_enq2->me_scsi_cap & 0x3)); 2471 device_printf(sc->mlx_dev, " Firmware Build Number %d\n", sc->mlx_enq2->me_firmware_build); 2472 device_printf(sc->mlx_dev, " Fault Management Type %d\n", sc->mlx_enq2->me_fault_mgmt_type); 2473 device_printf(sc->mlx_dev, " Features %b\n", sc->mlx_enq2->me_firmware_features, 2474 "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n"); 2475 2476 } 2477 } 2478 2479 /******************************************************************************** 2480 ******************************************************************************** 2481 Utility Functions 2482 ******************************************************************************** 2483 ********************************************************************************/ 2484 2485 /******************************************************************************** 2486 * Find the disk whose unit number is (unit) on this controller 2487 */ 2488 static struct mlx_sysdrive * 2489 mlx_findunit(struct mlx_softc *sc, int unit) 2490 { 2491 int i; 2492 2493 /* search system drives */ 2494 for (i = 0; i < MLX_MAXDRIVES; i++) { 2495 /* is this one attached? */ 2496 if (sc->mlx_sysdrive[i].ms_disk != 0) { 2497 /* is this the one? */ 2498 if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk)) 2499 return(&sc->mlx_sysdrive[i]); 2500 } 2501 } 2502 return(NULL); 2503 } 2504