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