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