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