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