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