1 /* $NetBSD: mly.c,v 1.8 2001/11/13 07:48:46 lukem Exp $ */ 2 3 /*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran, Thor Lancelot Simon, and Eric Haszlakiewicz. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /*- 40 * Copyright (c) 2000, 2001 Michael Smith 41 * Copyright (c) 2000 BSDi 42 * All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * from FreeBSD: mly.c,v 1.8 2001/07/14 00:12:22 msmith Exp 66 */ 67 68 /* 69 * Driver for the Mylex AcceleRAID and eXtremeRAID family with v6 firmware. 70 * 71 * TODO: 72 * 73 * o Make mly->mly_btl a hash, then MLY_BTL_RESCAN becomes a SIMPLEQ. 74 * o Handle FC and multiple LUNs. 75 * o Fix mmbox usage. 76 * o Fix transfer speed fudge. 77 */ 78 79 #include <sys/cdefs.h> 80 __KERNEL_RCSID(0, "$NetBSD: mly.c,v 1.8 2001/11/13 07:48:46 lukem Exp $"); 81 82 #include <sys/param.h> 83 #include <sys/systm.h> 84 #include <sys/device.h> 85 #include <sys/kernel.h> 86 #include <sys/queue.h> 87 #include <sys/buf.h> 88 #include <sys/endian.h> 89 #include <sys/conf.h> 90 #include <sys/malloc.h> 91 #include <sys/ioctl.h> 92 #include <sys/scsiio.h> 93 #include <sys/kthread.h> 94 95 #include <uvm/uvm_extern.h> 96 97 #include <machine/bus.h> 98 99 #include <dev/scsipi/scsi_all.h> 100 #include <dev/scsipi/scsipi_all.h> 101 #include <dev/scsipi/scsiconf.h> 102 103 #include <dev/pci/pcireg.h> 104 #include <dev/pci/pcivar.h> 105 #include <dev/pci/pcidevs.h> 106 107 #include <dev/pci/mlyreg.h> 108 #include <dev/pci/mlyio.h> 109 #include <dev/pci/mlyvar.h> 110 #include <dev/pci/mly_tables.h> 111 112 static void mly_attach(struct device *, struct device *, void *); 113 static int mly_match(struct device *, struct cfdata *, void *); 114 static const struct mly_ident *mly_find_ident(struct pci_attach_args *); 115 static int mly_fwhandshake(struct mly_softc *); 116 static int mly_flush(struct mly_softc *); 117 static int mly_intr(void *); 118 static void mly_shutdown(void *); 119 120 static int mly_alloc_ccbs(struct mly_softc *); 121 static void mly_check_event(struct mly_softc *); 122 static void mly_complete_event(struct mly_softc *, struct mly_ccb *); 123 static void mly_complete_rescan(struct mly_softc *, struct mly_ccb *); 124 static int mly_dmamem_alloc(struct mly_softc *, int, bus_dmamap_t *, 125 caddr_t *, bus_addr_t *, bus_dma_segment_t *); 126 static void mly_dmamem_free(struct mly_softc *, int, bus_dmamap_t, 127 caddr_t, bus_dma_segment_t *); 128 static int mly_enable_mmbox(struct mly_softc *); 129 static void mly_fetch_event(struct mly_softc *); 130 static int mly_get_controllerinfo(struct mly_softc *); 131 static int mly_get_eventstatus(struct mly_softc *); 132 static int mly_ioctl(struct mly_softc *, struct mly_cmd_ioctl *, 133 void **, size_t, void *, size_t *); 134 static void mly_padstr(char *, const char *, int); 135 static void mly_process_event(struct mly_softc *, struct mly_event *); 136 static void mly_release_ccbs(struct mly_softc *); 137 static int mly_scan_btl(struct mly_softc *, int, int); 138 static void mly_scan_channel(struct mly_softc *, int); 139 static void mly_thread(void *); 140 static void mly_thread_create(void *); 141 142 static int mly_ccb_alloc(struct mly_softc *, struct mly_ccb **); 143 static void mly_ccb_complete(struct mly_softc *, struct mly_ccb *); 144 static void mly_ccb_enqueue(struct mly_softc *, struct mly_ccb *); 145 static void mly_ccb_free(struct mly_softc *, struct mly_ccb *); 146 static int mly_ccb_map(struct mly_softc *, struct mly_ccb *); 147 static int mly_ccb_poll(struct mly_softc *, struct mly_ccb *, int); 148 static int mly_ccb_submit(struct mly_softc *, struct mly_ccb *); 149 static void mly_ccb_unmap(struct mly_softc *, struct mly_ccb *); 150 static int mly_ccb_wait(struct mly_softc *, struct mly_ccb *, int); 151 152 static void mly_get_xfer_mode(struct mly_softc *, int, 153 struct scsipi_xfer_mode *); 154 static void mly_scsipi_complete(struct mly_softc *, struct mly_ccb *); 155 static int mly_scsipi_ioctl(struct scsipi_channel *, u_long, caddr_t, 156 int, struct proc *); 157 static void mly_scsipi_minphys(struct buf *); 158 static void mly_scsipi_request(struct scsipi_channel *, 159 scsipi_adapter_req_t, void *); 160 161 static int mly_user_command(struct mly_softc *, struct mly_user_command *); 162 static int mly_user_health(struct mly_softc *, struct mly_user_health *); 163 164 cdev_decl(mly); 165 166 extern struct cfdriver mly_cd; 167 168 struct cfattach mly_ca = { 169 sizeof(struct mly_softc), mly_match, mly_attach 170 }; 171 172 struct mly_ident { 173 u_short vendor; 174 u_short product; 175 u_short subvendor; 176 u_short subproduct; 177 int hwif; 178 const char *desc; 179 } static const mly_ident[] = { 180 { 181 PCI_VENDOR_MYLEX, 182 PCI_PRODUCT_MYLEX_EXTREMERAID, 183 PCI_VENDOR_MYLEX, 184 0x0040, 185 MLY_HWIF_STRONGARM, 186 "eXtremeRAID 2000" 187 }, 188 { 189 PCI_VENDOR_MYLEX, 190 PCI_PRODUCT_MYLEX_EXTREMERAID, 191 PCI_VENDOR_MYLEX, 192 0x0030, 193 MLY_HWIF_STRONGARM, 194 "eXtremeRAID 3000" 195 }, 196 { 197 PCI_VENDOR_MYLEX, 198 PCI_PRODUCT_MYLEX_ACCELERAID, 199 PCI_VENDOR_MYLEX, 200 0x0050, 201 MLY_HWIF_I960RX, 202 "AcceleRAID 352" 203 }, 204 { 205 PCI_VENDOR_MYLEX, 206 PCI_PRODUCT_MYLEX_ACCELERAID, 207 PCI_VENDOR_MYLEX, 208 0x0052, 209 MLY_HWIF_I960RX, 210 "AcceleRAID 170" 211 }, 212 { 213 PCI_VENDOR_MYLEX, 214 PCI_PRODUCT_MYLEX_ACCELERAID, 215 PCI_VENDOR_MYLEX, 216 0x0054, 217 MLY_HWIF_I960RX, 218 "AcceleRAID 160" 219 }, 220 }; 221 222 static void *mly_sdh; 223 224 /* 225 * Try to find a `mly_ident' entry corresponding to this board. 226 */ 227 static const struct mly_ident * 228 mly_find_ident(struct pci_attach_args *pa) 229 { 230 const struct mly_ident *mpi, *maxmpi; 231 pcireg_t reg; 232 233 mpi = mly_ident; 234 maxmpi = mpi + sizeof(mly_ident) / sizeof(mly_ident[0]); 235 236 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_I2O) 237 return (NULL); 238 239 for (; mpi < maxmpi; mpi++) { 240 if (PCI_VENDOR(pa->pa_id) != mpi->vendor || 241 PCI_PRODUCT(pa->pa_id) != mpi->product) 242 continue; 243 244 if (mpi->subvendor == 0x0000) 245 return (mpi); 246 247 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG); 248 249 if (PCI_VENDOR(reg) == mpi->subvendor && 250 PCI_PRODUCT(reg) == mpi->subproduct) 251 return (mpi); 252 } 253 254 return (NULL); 255 } 256 257 /* 258 * Match a supported board. 259 */ 260 static int 261 mly_match(struct device *parent, struct cfdata *cfdata, void *aux) 262 { 263 264 return (mly_find_ident(aux) != NULL); 265 } 266 267 /* 268 * Attach a supported board. 269 */ 270 static void 271 mly_attach(struct device *parent, struct device *self, void *aux) 272 { 273 struct pci_attach_args *pa; 274 struct mly_softc *mly; 275 struct mly_ioctl_getcontrollerinfo *mi; 276 const struct mly_ident *ident; 277 pci_chipset_tag_t pc; 278 pci_intr_handle_t ih; 279 bus_space_handle_t memh, ioh; 280 bus_space_tag_t memt, iot; 281 pcireg_t reg; 282 const char *intrstr; 283 int ior, memr, i, rv, state; 284 struct scsipi_adapter *adapt; 285 struct scsipi_channel *chan; 286 287 mly = (struct mly_softc *)self; 288 pa = aux; 289 pc = pa->pa_pc; 290 ident = mly_find_ident(pa); 291 state = 0; 292 293 mly->mly_dmat = pa->pa_dmat; 294 mly->mly_hwif = ident->hwif; 295 296 printf(": Mylex %s\n", ident->desc); 297 298 /* 299 * Map the PCI register window. 300 */ 301 memr = -1; 302 ior = -1; 303 304 for (i = 0x10; i <= 0x14; i += 4) { 305 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, i); 306 307 if (PCI_MAPREG_TYPE(reg) == PCI_MAPREG_TYPE_IO) { 308 if (ior == -1 && PCI_MAPREG_IO_SIZE(reg) != 0) 309 ior = i; 310 } else { 311 if (memr == -1 && PCI_MAPREG_MEM_SIZE(reg) != 0) 312 memr = i; 313 } 314 } 315 316 if (memr != -1) 317 if (pci_mapreg_map(pa, memr, PCI_MAPREG_TYPE_MEM, 0, 318 &memt, &memh, NULL, NULL)) 319 memr = -1; 320 if (ior != -1) 321 if (pci_mapreg_map(pa, ior, PCI_MAPREG_TYPE_IO, 0, 322 &iot, &ioh, NULL, NULL)) 323 ior = -1; 324 325 if (memr != -1) { 326 mly->mly_iot = memt; 327 mly->mly_ioh = memh; 328 } else if (ior != -1) { 329 mly->mly_iot = iot; 330 mly->mly_ioh = ioh; 331 } else { 332 printf("%s: can't map i/o or memory space\n", self->dv_xname); 333 return; 334 } 335 336 /* 337 * Enable the device. 338 */ 339 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG); 340 pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, 341 reg | PCI_COMMAND_MASTER_ENABLE); 342 343 /* 344 * Map and establish the interrupt. 345 */ 346 if (pci_intr_map(pa, &ih)) { 347 printf("%s: can't map interrupt\n", self->dv_xname); 348 return; 349 } 350 intrstr = pci_intr_string(pc, ih); 351 mly->mly_ih = pci_intr_establish(pc, ih, IPL_BIO, mly_intr, mly); 352 if (mly->mly_ih == NULL) { 353 printf("%s: can't establish interrupt", self->dv_xname); 354 if (intrstr != NULL) 355 printf(" at %s", intrstr); 356 printf("\n"); 357 return; 358 } 359 360 if (intrstr != NULL) 361 printf("%s: interrupting at %s\n", mly->mly_dv.dv_xname, 362 intrstr); 363 364 /* 365 * Take care of interface-specific tasks. 366 */ 367 switch (mly->mly_hwif) { 368 case MLY_HWIF_I960RX: 369 mly->mly_doorbell_true = 0x00; 370 mly->mly_cmd_mailbox = MLY_I960RX_COMMAND_MAILBOX; 371 mly->mly_status_mailbox = MLY_I960RX_STATUS_MAILBOX; 372 mly->mly_idbr = MLY_I960RX_IDBR; 373 mly->mly_odbr = MLY_I960RX_ODBR; 374 mly->mly_error_status = MLY_I960RX_ERROR_STATUS; 375 mly->mly_interrupt_status = MLY_I960RX_INTERRUPT_STATUS; 376 mly->mly_interrupt_mask = MLY_I960RX_INTERRUPT_MASK; 377 break; 378 379 case MLY_HWIF_STRONGARM: 380 mly->mly_doorbell_true = 0xff; 381 mly->mly_cmd_mailbox = MLY_STRONGARM_COMMAND_MAILBOX; 382 mly->mly_status_mailbox = MLY_STRONGARM_STATUS_MAILBOX; 383 mly->mly_idbr = MLY_STRONGARM_IDBR; 384 mly->mly_odbr = MLY_STRONGARM_ODBR; 385 mly->mly_error_status = MLY_STRONGARM_ERROR_STATUS; 386 mly->mly_interrupt_status = MLY_STRONGARM_INTERRUPT_STATUS; 387 mly->mly_interrupt_mask = MLY_STRONGARM_INTERRUPT_MASK; 388 break; 389 } 390 391 /* 392 * Allocate and map the scatter/gather lists. 393 */ 394 rv = mly_dmamem_alloc(mly, MLY_SGL_SIZE * MLY_MAX_CCBS, 395 &mly->mly_sg_dmamap, (caddr_t *)&mly->mly_sg, 396 &mly->mly_sg_busaddr, &mly->mly_sg_seg); 397 if (rv) { 398 printf("%s: unable to allocate S/G maps\n", 399 mly->mly_dv.dv_xname); 400 goto bad; 401 } 402 state++; 403 404 /* 405 * Allocate and map the memory mailbox. 406 */ 407 rv = mly_dmamem_alloc(mly, sizeof(struct mly_mmbox), 408 &mly->mly_mmbox_dmamap, (caddr_t *)&mly->mly_mmbox, 409 &mly->mly_mmbox_busaddr, &mly->mly_mmbox_seg); 410 if (rv) { 411 printf("%s: unable to allocate mailboxes\n", 412 mly->mly_dv.dv_xname); 413 goto bad; 414 } 415 state++; 416 417 /* 418 * Initialise per-controller queues. 419 */ 420 SLIST_INIT(&mly->mly_ccb_free); 421 SIMPLEQ_INIT(&mly->mly_ccb_queue); 422 423 /* 424 * Disable interrupts before we start talking to the controller. 425 */ 426 mly_outb(mly, mly->mly_interrupt_mask, MLY_INTERRUPT_MASK_DISABLE); 427 428 /* 429 * Wait for the controller to come ready, handshaking with the 430 * firmware if required. This is typically only necessary on 431 * platforms where the controller BIOS does not run. 432 */ 433 if (mly_fwhandshake(mly)) { 434 printf("%s: unable to bring controller online\n", 435 mly->mly_dv.dv_xname); 436 goto bad; 437 } 438 439 /* 440 * Allocate initial command buffers, obtain controller feature 441 * information, and then reallocate command buffers, since we'll 442 * know how many we want. 443 */ 444 if (mly_alloc_ccbs(mly)) { 445 printf("%s: unable to allocate CCBs\n", 446 mly->mly_dv.dv_xname); 447 goto bad; 448 } 449 state++; 450 if (mly_get_controllerinfo(mly)) { 451 printf("%s: unable to retrieve controller info\n", 452 mly->mly_dv.dv_xname); 453 goto bad; 454 } 455 mly_release_ccbs(mly); 456 if (mly_alloc_ccbs(mly)) { 457 printf("%s: unable to allocate CCBs\n", 458 mly->mly_dv.dv_xname); 459 state--; 460 goto bad; 461 } 462 463 /* 464 * Get the current event counter for health purposes, populate the 465 * initial health status buffer. 466 */ 467 if (mly_get_eventstatus(mly)) { 468 printf("%s: unable to retrieve event status\n", 469 mly->mly_dv.dv_xname); 470 goto bad; 471 } 472 473 /* 474 * Enable memory-mailbox mode. 475 */ 476 if (mly_enable_mmbox(mly)) { 477 printf("%s: unable to enable memory mailbox\n", 478 mly->mly_dv.dv_xname); 479 goto bad; 480 } 481 482 /* 483 * Print a little information about the controller. 484 */ 485 mi = mly->mly_controllerinfo; 486 487 printf("%s: %d physical channel%s, firmware %d.%02d-%d-%02d " 488 "(%02d%02d%02d%02d), %dMB RAM\n", mly->mly_dv.dv_xname, 489 mi->physical_channels_present, 490 (mi->physical_channels_present) > 1 ? "s" : "", 491 mi->fw_major, mi->fw_minor, mi->fw_turn, mi->fw_build, 492 mi->fw_century, mi->fw_year, mi->fw_month, mi->fw_day, 493 le16toh(mi->memory_size)); 494 495 /* 496 * Register our `shutdownhook'. 497 */ 498 if (mly_sdh == NULL) 499 shutdownhook_establish(mly_shutdown, NULL); 500 501 /* 502 * Clear any previous BTL information. For each bus that scsipi 503 * wants to scan, we'll receive the SCBUSIOLLSCAN ioctl and retrieve 504 * all BTL info at that point. 505 */ 506 memset(&mly->mly_btl, 0, sizeof(mly->mly_btl)); 507 508 mly->mly_nchans = mly->mly_controllerinfo->physical_channels_present + 509 mly->mly_controllerinfo->virtual_channels_present; 510 511 /* 512 * Attach to scsipi. 513 */ 514 adapt = &mly->mly_adapt; 515 memset(adapt, 0, sizeof(*adapt)); 516 adapt->adapt_dev = &mly->mly_dv; 517 adapt->adapt_nchannels = mly->mly_nchans; 518 adapt->adapt_openings = mly->mly_ncmds - MLY_CCBS_RESV; 519 adapt->adapt_max_periph = mly->mly_ncmds - MLY_CCBS_RESV; 520 adapt->adapt_request = mly_scsipi_request; 521 adapt->adapt_minphys = mly_scsipi_minphys; 522 adapt->adapt_ioctl = mly_scsipi_ioctl; 523 524 for (i = 0; i < mly->mly_nchans; i++) { 525 chan = &mly->mly_chans[i]; 526 memset(chan, 0, sizeof(*chan)); 527 chan->chan_adapter = adapt; 528 chan->chan_bustype = &scsi_bustype; 529 chan->chan_channel = i; 530 chan->chan_ntargets = MLY_MAX_TARGETS; 531 chan->chan_nluns = MLY_MAX_LUNS; 532 chan->chan_id = mly->mly_controllerparam->initiator_id; 533 chan->chan_flags = SCSIPI_CHAN_NOSETTLE; 534 config_found(&mly->mly_dv, chan, scsiprint); 535 } 536 537 /* 538 * Now enable interrupts... 539 */ 540 mly_outb(mly, mly->mly_interrupt_mask, MLY_INTERRUPT_MASK_ENABLE); 541 542 /* 543 * Finally, create our monitoring thread. 544 */ 545 kthread_create(mly_thread_create, mly); 546 547 mly->mly_state |= MLY_STATE_INITOK; 548 return; 549 550 bad: 551 if (state > 2) 552 mly_release_ccbs(mly); 553 if (state > 1) 554 mly_dmamem_free(mly, sizeof(struct mly_mmbox), 555 mly->mly_mmbox_dmamap, (caddr_t)mly->mly_mmbox, 556 &mly->mly_mmbox_seg); 557 if (state > 0) 558 mly_dmamem_free(mly, MLY_SGL_SIZE * MLY_MAX_CCBS, 559 mly->mly_sg_dmamap, (caddr_t)mly->mly_sg, 560 &mly->mly_sg_seg); 561 } 562 563 /* 564 * Scan all possible devices on the specified channel. 565 */ 566 static void 567 mly_scan_channel(struct mly_softc *mly, int bus) 568 { 569 int s, target; 570 571 for (target = 0; target < MLY_MAX_TARGETS; target++) { 572 s = splbio(); 573 if (!mly_scan_btl(mly, bus, target)) { 574 tsleep(&mly->mly_btl[bus][target], PRIBIO, "mlyscan", 575 0); 576 } 577 splx(s); 578 } 579 } 580 581 /* 582 * Shut down all configured `mly' devices. 583 */ 584 static void 585 mly_shutdown(void *cookie) 586 { 587 struct mly_softc *mly; 588 int i; 589 590 for (i = 0; i < mly_cd.cd_ndevs; i++) { 591 if ((mly = device_lookup(&mly_cd, i)) == NULL) 592 continue; 593 594 if (mly_flush(mly)) 595 printf("%s: unable to flush cache\n", 596 mly->mly_dv.dv_xname); 597 } 598 } 599 600 /* 601 * Fill in the mly_controllerinfo and mly_controllerparam fields in the 602 * softc. 603 */ 604 static int 605 mly_get_controllerinfo(struct mly_softc *mly) 606 { 607 struct mly_cmd_ioctl mci; 608 int rv; 609 610 /* 611 * Build the getcontrollerinfo ioctl and send it. 612 */ 613 memset(&mci, 0, sizeof(mci)); 614 mci.sub_ioctl = MDACIOCTL_GETCONTROLLERINFO; 615 rv = mly_ioctl(mly, &mci, (void **)&mly->mly_controllerinfo, 616 sizeof(*mly->mly_controllerinfo), NULL, NULL); 617 if (rv != 0) 618 return (rv); 619 620 /* 621 * Build the getcontrollerparameter ioctl and send it. 622 */ 623 memset(&mci, 0, sizeof(mci)); 624 mci.sub_ioctl = MDACIOCTL_GETCONTROLLERPARAMETER; 625 rv = mly_ioctl(mly, &mci, (void **)&mly->mly_controllerparam, 626 sizeof(*mly->mly_controllerparam), NULL, NULL); 627 628 return (rv); 629 } 630 631 /* 632 * Rescan a device, possibly as a consequence of getting an event which 633 * suggests that it may have changed. Must be called with interrupts 634 * blocked. 635 */ 636 static int 637 mly_scan_btl(struct mly_softc *mly, int bus, int target) 638 { 639 struct mly_ccb *mc; 640 struct mly_cmd_ioctl *mci; 641 int rv; 642 643 if (target == mly->mly_controllerparam->initiator_id) { 644 mly->mly_btl[bus][target].mb_flags = MLY_BTL_PROTECTED; 645 return (EIO); 646 } 647 648 /* Don't re-scan if a scan is already in progress. */ 649 if ((mly->mly_btl[bus][target].mb_flags & MLY_BTL_SCANNING) != 0) 650 return (EBUSY); 651 652 /* Get a command. */ 653 if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 654 return (rv); 655 656 /* Set up the data buffer. */ 657 mc->mc_data = malloc(sizeof(union mly_devinfo), 658 M_DEVBUF, M_NOWAIT); 659 memset(mc->mc_data, 0, sizeof(union mly_devinfo)); 660 661 mc->mc_flags |= MLY_CCB_DATAIN; 662 mc->mc_complete = mly_complete_rescan; 663 664 /* 665 * Build the ioctl. 666 */ 667 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 668 mci->opcode = MDACMD_IOCTL; 669 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 670 memset(&mci->param, 0, sizeof(mci->param)); 671 672 if (MLY_BUS_IS_VIRTUAL(mly, bus)) { 673 mc->mc_length = sizeof(struct mly_ioctl_getlogdevinfovalid); 674 mci->data_size = htole32(mc->mc_length); 675 mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID; 676 _lto3l(MLY_LOGADDR(0, MLY_LOGDEV_ID(mly, bus, target)), 677 mci->addr); 678 } else { 679 mc->mc_length = sizeof(struct mly_ioctl_getphysdevinfovalid); 680 mci->data_size = htole32(mc->mc_length); 681 mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID; 682 _lto3l(MLY_PHYADDR(0, bus, target, 0), mci->addr); 683 } 684 685 /* 686 * Dispatch the command. 687 */ 688 if ((rv = mly_ccb_map(mly, mc)) != 0) { 689 free(mc->mc_data, M_DEVBUF); 690 mly_ccb_free(mly, mc); 691 return(rv); 692 } 693 694 mly->mly_btl[bus][target].mb_flags |= MLY_BTL_SCANNING; 695 mly_ccb_enqueue(mly, mc); 696 return (0); 697 } 698 699 /* 700 * Handle the completion of a rescan operation. 701 */ 702 static void 703 mly_complete_rescan(struct mly_softc *mly, struct mly_ccb *mc) 704 { 705 struct mly_ioctl_getlogdevinfovalid *ldi; 706 struct mly_ioctl_getphysdevinfovalid *pdi; 707 struct mly_cmd_ioctl *mci; 708 struct mly_btl btl, *btlp; 709 struct scsipi_xfer_mode xm; 710 int bus, target, rescan; 711 u_int tmp; 712 713 mly_ccb_unmap(mly, mc); 714 715 /* 716 * Recover the bus and target from the command. We need these even 717 * in the case where we don't have a useful response. 718 */ 719 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 720 tmp = _3ltol(mci->addr); 721 rescan = 0; 722 723 if (mci->sub_ioctl == MDACIOCTL_GETLOGDEVINFOVALID) { 724 bus = MLY_LOGDEV_BUS(mly, MLY_LOGADDR_DEV(tmp)); 725 target = MLY_LOGDEV_TARGET(mly, MLY_LOGADDR_DEV(tmp)); 726 } else { 727 bus = MLY_PHYADDR_CHANNEL(tmp); 728 target = MLY_PHYADDR_TARGET(tmp); 729 } 730 731 btlp = &mly->mly_btl[bus][target]; 732 733 /* The default result is 'no device'. */ 734 memset(&btl, 0, sizeof(btl)); 735 btl.mb_flags = MLY_BTL_PROTECTED; 736 737 /* If the rescan completed OK, we have possibly-new BTL data. */ 738 if (mc->mc_status != 0) 739 goto out; 740 741 if (mc->mc_length == sizeof(*ldi)) { 742 ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data; 743 tmp = le32toh(ldi->logical_device_number); 744 745 if (MLY_LOGDEV_BUS(mly, tmp) != bus || 746 MLY_LOGDEV_TARGET(mly, tmp) != target) { 747 #ifdef MLYDEBUG 748 printf("%s: WARNING: BTL rescan (logical) for %d:%d " 749 "returned data for %d:%d instead\n", 750 mly->mly_dv.dv_xname, bus, target, 751 MLY_LOGDEV_BUS(mly, tmp), 752 MLY_LOGDEV_TARGET(mly, tmp)); 753 #endif 754 goto out; 755 } 756 757 btl.mb_flags = MLY_BTL_LOGICAL | MLY_BTL_TQING; 758 btl.mb_type = ldi->raid_level; 759 btl.mb_state = ldi->state; 760 } else if (mc->mc_length == sizeof(*pdi)) { 761 pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data; 762 763 if (pdi->channel != bus || pdi->target != target) { 764 #ifdef MLYDEBUG 765 printf("%s: WARNING: BTL rescan (physical) for %d:%d " 766 " returned data for %d:%d instead\n", 767 mly->mly_dv.dv_xname, 768 bus, target, pdi->channel, pdi->target); 769 #endif 770 goto out; 771 } 772 773 btl.mb_flags = MLY_BTL_PHYSICAL; 774 btl.mb_type = MLY_DEVICE_TYPE_PHYSICAL; 775 btl.mb_state = pdi->state; 776 btl.mb_speed = pdi->speed; 777 btl.mb_width = pdi->width; 778 779 if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED) 780 btl.mb_flags |= MLY_BTL_PROTECTED; 781 if (pdi->command_tags != 0) 782 btl.mb_flags |= MLY_BTL_TQING; 783 } else { 784 printf("%s: BTL rescan result invalid\n", mly->mly_dv.dv_xname); 785 goto out; 786 } 787 788 /* Decide whether we need to rescan the device. */ 789 if (btl.mb_flags != btlp->mb_flags || 790 btl.mb_speed != btlp->mb_speed || 791 btl.mb_width != btlp->mb_width) 792 rescan = 1; 793 794 out: 795 *btlp = btl; 796 797 if (rescan && (btl.mb_flags & MLY_BTL_PROTECTED) == 0) { 798 xm.xm_target = target; 799 mly_get_xfer_mode(mly, bus, &xm); 800 /* XXX SCSI mid-layer rescan goes here. */ 801 } 802 803 /* Wake anybody waiting on the device to be rescanned. */ 804 wakeup(btlp); 805 806 free(mc->mc_data, M_DEVBUF); 807 mly_ccb_free(mly, mc); 808 } 809 810 /* 811 * Get the current health status and set the 'next event' counter to suit. 812 */ 813 static int 814 mly_get_eventstatus(struct mly_softc *mly) 815 { 816 struct mly_cmd_ioctl mci; 817 struct mly_health_status *mh; 818 int rv; 819 820 /* Build the gethealthstatus ioctl and send it. */ 821 memset(&mci, 0, sizeof(mci)); 822 mh = NULL; 823 mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS; 824 825 rv = mly_ioctl(mly, &mci, (void **)&mh, sizeof(*mh), NULL, NULL); 826 if (rv) 827 return (rv); 828 829 /* Get the event counter. */ 830 mly->mly_event_change = le32toh(mh->change_counter); 831 mly->mly_event_waiting = le32toh(mh->next_event); 832 mly->mly_event_counter = le32toh(mh->next_event); 833 834 /* Save the health status into the memory mailbox */ 835 memcpy(&mly->mly_mmbox->mmm_health.status, mh, sizeof(*mh)); 836 837 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 838 offsetof(struct mly_mmbox, mmm_health), 839 sizeof(mly->mly_mmbox->mmm_health), 840 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 841 842 free(mh, M_DEVBUF); 843 return (0); 844 } 845 846 /* 847 * Enable memory mailbox mode. 848 */ 849 static int 850 mly_enable_mmbox(struct mly_softc *mly) 851 { 852 struct mly_cmd_ioctl mci; 853 u_int8_t *sp; 854 u_int64_t tmp; 855 int rv; 856 857 /* Build the ioctl and send it. */ 858 memset(&mci, 0, sizeof(mci)); 859 mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX; 860 861 /* Set buffer addresses. */ 862 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command); 863 mci.param.setmemorymailbox.command_mailbox_physaddr = htole64(tmp); 864 865 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status); 866 mci.param.setmemorymailbox.status_mailbox_physaddr = htole64(tmp); 867 868 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health); 869 mci.param.setmemorymailbox.health_buffer_physaddr = htole64(tmp); 870 871 /* Set buffer sizes - abuse of data_size field is revolting. */ 872 sp = (u_int8_t *)&mci.data_size; 873 sp[0] = (sizeof(union mly_cmd_packet) * MLY_MMBOX_COMMANDS) >> 10; 874 sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) >> 10; 875 mci.param.setmemorymailbox.health_buffer_size = 876 sizeof(union mly_health_region) >> 10; 877 878 rv = mly_ioctl(mly, &mci, NULL, 0, NULL, NULL); 879 if (rv) 880 return (rv); 881 882 mly->mly_state |= MLY_STATE_MMBOX_ACTIVE; 883 return (0); 884 } 885 886 /* 887 * Flush all pending I/O from the controller. 888 */ 889 static int 890 mly_flush(struct mly_softc *mly) 891 { 892 struct mly_cmd_ioctl mci; 893 894 /* Build the ioctl */ 895 memset(&mci, 0, sizeof(mci)); 896 mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA; 897 mci.param.deviceoperation.operation_device = 898 MLY_OPDEVICE_PHYSICAL_CONTROLLER; 899 900 /* Pass it off to the controller */ 901 return (mly_ioctl(mly, &mci, NULL, 0, NULL, NULL)); 902 } 903 904 /* 905 * Perform an ioctl command. 906 * 907 * If (data) is not NULL, the command requires data transfer to the 908 * controller. If (*data) is NULL the command requires data transfer from 909 * the controller, and we will allocate a buffer for it. 910 */ 911 static int 912 mly_ioctl(struct mly_softc *mly, struct mly_cmd_ioctl *ioctl, void **data, 913 size_t datasize, void *sense_buffer, 914 size_t *sense_length) 915 { 916 struct mly_ccb *mc; 917 struct mly_cmd_ioctl *mci; 918 u_int8_t status; 919 int rv; 920 921 mc = NULL; 922 if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 923 goto bad; 924 925 /* 926 * Copy the ioctl structure, but save some important fields and then 927 * fixup. 928 */ 929 mci = &mc->mc_packet->ioctl; 930 ioctl->sense_buffer_address = htole64(mci->sense_buffer_address); 931 ioctl->maximum_sense_size = mci->maximum_sense_size; 932 *mci = *ioctl; 933 mci->opcode = MDACMD_IOCTL; 934 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 935 936 /* Handle the data buffer. */ 937 if (data != NULL) { 938 if (*data == NULL) { 939 /* Allocate data buffer */ 940 mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT); 941 mc->mc_flags |= MLY_CCB_DATAIN; 942 } else { 943 mc->mc_data = *data; 944 mc->mc_flags |= MLY_CCB_DATAOUT; 945 } 946 mc->mc_length = datasize; 947 mc->mc_packet->generic.data_size = htole32(datasize); 948 } 949 950 /* Run the command. */ 951 if (datasize > 0) 952 if ((rv = mly_ccb_map(mly, mc)) != 0) 953 goto bad; 954 rv = mly_ccb_poll(mly, mc, 30000); 955 if (datasize > 0) 956 mly_ccb_unmap(mly, mc); 957 if (rv != 0) 958 goto bad; 959 960 /* Clean up and return any data. */ 961 status = mc->mc_status; 962 963 if (status != 0) 964 printf("mly_ioctl: command status %d\n", status); 965 966 if (mc->mc_sense > 0 && sense_buffer != NULL) { 967 memcpy(sense_buffer, mc->mc_packet, mc->mc_sense); 968 *sense_length = mc->mc_sense; 969 goto bad; 970 } 971 972 /* Should we return a data pointer? */ 973 if (data != NULL && *data == NULL) 974 *data = mc->mc_data; 975 976 /* Command completed OK. */ 977 rv = (status != 0 ? EIO : 0); 978 979 bad: 980 if (mc != NULL) { 981 /* Do we need to free a data buffer we allocated? */ 982 if (rv != 0 && mc->mc_data != NULL && *data == NULL) 983 free(mc->mc_data, M_DEVBUF); 984 mly_ccb_free(mly, mc); 985 } 986 987 return (rv); 988 } 989 990 /* 991 * Check for event(s) outstanding in the controller. 992 */ 993 static void 994 mly_check_event(struct mly_softc *mly) 995 { 996 997 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 998 offsetof(struct mly_mmbox, mmm_health), 999 sizeof(mly->mly_mmbox->mmm_health), 1000 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1001 1002 /* 1003 * The controller may have updated the health status information, so 1004 * check for it here. Note that the counters are all in host 1005 * memory, so this check is very cheap. Also note that we depend on 1006 * checking on completion 1007 */ 1008 if (le32toh(mly->mly_mmbox->mmm_health.status.change_counter) != 1009 mly->mly_event_change) { 1010 mly->mly_event_change = 1011 le32toh(mly->mly_mmbox->mmm_health.status.change_counter); 1012 mly->mly_event_waiting = 1013 le32toh(mly->mly_mmbox->mmm_health.status.next_event); 1014 1015 /* Wake up anyone that might be interested in this. */ 1016 wakeup(&mly->mly_event_change); 1017 } 1018 1019 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1020 offsetof(struct mly_mmbox, mmm_health), 1021 sizeof(mly->mly_mmbox->mmm_health), 1022 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1023 1024 if (mly->mly_event_counter != mly->mly_event_waiting) 1025 mly_fetch_event(mly); 1026 } 1027 1028 /* 1029 * Fetch one event from the controller. If we fail due to resource 1030 * starvation, we'll be retried the next time a command completes. 1031 */ 1032 static void 1033 mly_fetch_event(struct mly_softc *mly) 1034 { 1035 struct mly_ccb *mc; 1036 struct mly_cmd_ioctl *mci; 1037 int s; 1038 u_int32_t event; 1039 1040 /* Get a command. */ 1041 if (mly_ccb_alloc(mly, &mc)) 1042 return; 1043 1044 /* Set up the data buffer. */ 1045 mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, M_NOWAIT); 1046 memset(mc->mc_data, 0, sizeof(struct mly_event)); 1047 1048 mc->mc_length = sizeof(struct mly_event); 1049 mc->mc_flags |= MLY_CCB_DATAIN; 1050 mc->mc_complete = mly_complete_event; 1051 1052 /* 1053 * Get an event number to fetch. It's possible that we've raced 1054 * with another context for the last event, in which case there will 1055 * be no more events. 1056 */ 1057 s = splbio(); 1058 if (mly->mly_event_counter == mly->mly_event_waiting) { 1059 splx(s); 1060 free(mc->mc_data, M_DEVBUF); 1061 mly_ccb_free(mly, mc); 1062 return; 1063 } 1064 event = mly->mly_event_counter++; 1065 splx(s); 1066 1067 /* 1068 * Build the ioctl. 1069 * 1070 * At this point we are committed to sending this request, as it 1071 * will be the only one constructed for this particular event 1072 * number. 1073 */ 1074 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 1075 mci->opcode = MDACMD_IOCTL; 1076 mci->data_size = htole32(sizeof(struct mly_event)); 1077 _lto3l(MLY_PHYADDR(0, 0, (event >> 16) & 0xff, (event >> 24) & 0xff), 1078 mci->addr); 1079 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 1080 mci->sub_ioctl = MDACIOCTL_GETEVENT; 1081 mci->param.getevent.sequence_number_low = htole16(event & 0xffff); 1082 1083 /* 1084 * Submit the command. 1085 */ 1086 if (mly_ccb_map(mly, mc) != 0) 1087 goto bad; 1088 mly_ccb_enqueue(mly, mc); 1089 return; 1090 1091 bad: 1092 printf("%s: couldn't fetch event %u\n", mly->mly_dv.dv_xname, event); 1093 free(mc->mc_data, M_DEVBUF); 1094 mly_ccb_free(mly, mc); 1095 } 1096 1097 /* 1098 * Handle the completion of an event poll. 1099 */ 1100 static void 1101 mly_complete_event(struct mly_softc *mly, struct mly_ccb *mc) 1102 { 1103 struct mly_event *me; 1104 1105 me = (struct mly_event *)mc->mc_data; 1106 mly_ccb_unmap(mly, mc); 1107 mly_ccb_free(mly, mc); 1108 1109 /* If the event was successfully fetched, process it. */ 1110 if (mc->mc_status == SCSI_OK) 1111 mly_process_event(mly, me); 1112 else 1113 printf("%s: unable to fetch event; status = 0x%x\n", 1114 mly->mly_dv.dv_xname, mc->mc_status); 1115 1116 free(me, M_DEVBUF); 1117 1118 /* Check for another event. */ 1119 mly_check_event(mly); 1120 } 1121 1122 /* 1123 * Process a controller event. Called with interupts blocked (i.e., at 1124 * interrupt time). 1125 */ 1126 static void 1127 mly_process_event(struct mly_softc *mly, struct mly_event *me) 1128 { 1129 struct scsipi_sense_data *ssd; 1130 int bus, target, event, class, action; 1131 const char *fp, *tp; 1132 1133 ssd = (struct scsipi_sense_data *)&me->sense[0]; 1134 1135 /* 1136 * Errors can be reported using vendor-unique sense data. In this 1137 * case, the event code will be 0x1c (Request sense data present), 1138 * the sense key will be 0x09 (vendor specific), the MSB of the ASC 1139 * will be set, and the actual event code will be a 16-bit value 1140 * comprised of the ASCQ (low byte) and low seven bits of the ASC 1141 * (low seven bits of the high byte). 1142 */ 1143 if (le32toh(me->code) == 0x1c && 1144 (ssd->flags & SSD_KEY) == SKEY_VENDOR_UNIQUE && 1145 (ssd->add_sense_code & 0x80) != 0) { 1146 event = ((int)(ssd->add_sense_code & ~0x80) << 8) + 1147 ssd->add_sense_code_qual; 1148 } else 1149 event = le32toh(me->code); 1150 1151 /* Look up event, get codes. */ 1152 fp = mly_describe_code(mly_table_event, event); 1153 1154 /* Quiet event? */ 1155 class = fp[0]; 1156 #ifdef notyet 1157 if (isupper(class) && bootverbose) 1158 class = tolower(class); 1159 #endif 1160 1161 /* Get action code, text string. */ 1162 action = fp[1]; 1163 tp = fp + 3; 1164 1165 /* 1166 * Print some information about the event. 1167 * 1168 * This code uses a table derived from the corresponding portion of 1169 * the Linux driver, and thus the parser is very similar. 1170 */ 1171 switch (class) { 1172 case 'p': 1173 /* 1174 * Error on physical drive. 1175 */ 1176 printf("%s: physical device %d:%d %s\n", mly->mly_dv.dv_xname, 1177 me->channel, me->target, tp); 1178 if (action == 'r') 1179 mly->mly_btl[me->channel][me->target].mb_flags |= 1180 MLY_BTL_RESCAN; 1181 break; 1182 1183 case 'l': 1184 case 'm': 1185 /* 1186 * Error on logical unit, or message about logical unit. 1187 */ 1188 bus = MLY_LOGDEV_BUS(mly, me->lun); 1189 target = MLY_LOGDEV_TARGET(mly, me->lun); 1190 printf("%s: logical device %d:%d %s\n", mly->mly_dv.dv_xname, 1191 bus, target, tp); 1192 if (action == 'r') 1193 mly->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN; 1194 break; 1195 1196 case 's': 1197 /* 1198 * Report of sense data. 1199 */ 1200 if (((ssd->flags & SSD_KEY) == SKEY_NO_SENSE || 1201 (ssd->flags & SSD_KEY) == SKEY_NOT_READY) && 1202 ssd->add_sense_code == 0x04 && 1203 (ssd->add_sense_code_qual == 0x01 || 1204 ssd->add_sense_code_qual == 0x02)) { 1205 /* Ignore NO_SENSE or NOT_READY in one case */ 1206 break; 1207 } 1208 1209 /* 1210 * XXX Should translate this if SCSIVERBOSE. 1211 */ 1212 printf("%s: physical device %d:%d %s\n", mly->mly_dv.dv_xname, 1213 me->channel, me->target, tp); 1214 printf("%s: sense key %d asc %02x ascq %02x\n", 1215 mly->mly_dv.dv_xname, ssd->flags & SSD_KEY, 1216 ssd->add_sense_code, ssd->add_sense_code_qual); 1217 printf("%s: info %x%x%x%x csi %x%x%x%x\n", 1218 mly->mly_dv.dv_xname, ssd->info[0], ssd->info[1], 1219 ssd->info[2], ssd->info[3], ssd->cmd_spec_info[0], 1220 ssd->cmd_spec_info[1], ssd->cmd_spec_info[2], 1221 ssd->cmd_spec_info[3]); 1222 if (action == 'r') 1223 mly->mly_btl[me->channel][me->target].mb_flags |= 1224 MLY_BTL_RESCAN; 1225 break; 1226 1227 case 'e': 1228 printf("%s: ", mly->mly_dv.dv_xname); 1229 printf(tp, me->target, me->lun); 1230 break; 1231 1232 case 'c': 1233 printf("%s: controller %s\n", mly->mly_dv.dv_xname, tp); 1234 break; 1235 1236 case '?': 1237 printf("%s: %s - %d\n", mly->mly_dv.dv_xname, tp, event); 1238 break; 1239 1240 default: 1241 /* Probably a 'noisy' event being ignored. */ 1242 break; 1243 } 1244 } 1245 1246 /* 1247 * Create the monitoring thread. Called after the standard kernel threads 1248 * have been created. 1249 */ 1250 static void 1251 mly_thread_create(void *cookie) 1252 { 1253 struct mly_softc *mly; 1254 int rv; 1255 1256 mly = cookie; 1257 1258 rv = kthread_create1(mly_thread, mly, &mly->mly_thread, "%s", 1259 mly->mly_dv.dv_xname); 1260 if (rv != 0) 1261 printf("%s: unable to create thread (%d)\n", 1262 mly->mly_dv.dv_xname, rv); 1263 } 1264 1265 /* 1266 * Perform periodic activities. 1267 */ 1268 static void 1269 mly_thread(void *cookie) 1270 { 1271 struct mly_softc *mly; 1272 struct mly_btl *btl; 1273 int s, bus, target, done; 1274 1275 mly = (struct mly_softc *)cookie; 1276 1277 for (;;) { 1278 /* Check for new events. */ 1279 mly_check_event(mly); 1280 1281 /* Re-scan up to 1 device. */ 1282 s = splbio(); 1283 done = 0; 1284 for (bus = 0; bus < mly->mly_nchans && !done; bus++) { 1285 for (target = 0; target < MLY_MAX_TARGETS; target++) { 1286 /* Perform device rescan? */ 1287 btl = &mly->mly_btl[bus][target]; 1288 if ((btl->mb_flags & MLY_BTL_RESCAN) != 0) { 1289 btl->mb_flags ^= MLY_BTL_RESCAN; 1290 mly_scan_btl(mly, bus, target); 1291 done = 1; 1292 break; 1293 } 1294 } 1295 } 1296 splx(s); 1297 1298 /* Sleep for N seconds. */ 1299 tsleep(mly_thread, PWAIT, "mlyzzz", 1300 hz * MLY_PERIODIC_INTERVAL); 1301 } 1302 } 1303 1304 /* 1305 * Submit a command to the controller and poll on completion. Return 1306 * non-zero on timeout. 1307 */ 1308 static int 1309 mly_ccb_poll(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1310 { 1311 int rv; 1312 1313 if ((rv = mly_ccb_submit(mly, mc)) != 0) 1314 return (rv); 1315 1316 for (timo *= 10; timo != 0; timo--) { 1317 if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) 1318 break; 1319 mly_intr(mly); 1320 DELAY(100); 1321 } 1322 1323 return (timo == 0); 1324 } 1325 1326 /* 1327 * Submit a command to the controller and sleep on completion. Return 1328 * non-zero on timeout. 1329 */ 1330 static int 1331 mly_ccb_wait(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1332 { 1333 int rv, s; 1334 1335 mly_ccb_enqueue(mly, mc); 1336 1337 s = splbio(); 1338 if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) { 1339 splx(s); 1340 return (0); 1341 } 1342 rv = tsleep(mc, PRIBIO, "mlywccb", timo * hz / 1000); 1343 splx(s); 1344 1345 return (rv); 1346 } 1347 1348 /* 1349 * If a CCB is specified, enqueue it. Pull CCBs off the software queue in 1350 * the order that they were enqueued and try to submit their command blocks 1351 * to the controller for execution. 1352 */ 1353 void 1354 mly_ccb_enqueue(struct mly_softc *mly, struct mly_ccb *mc) 1355 { 1356 int s; 1357 1358 s = splbio(); 1359 1360 if (mc != NULL) 1361 SIMPLEQ_INSERT_TAIL(&mly->mly_ccb_queue, mc, mc_link.simpleq); 1362 1363 while ((mc = SIMPLEQ_FIRST(&mly->mly_ccb_queue)) != NULL) { 1364 if (mly_ccb_submit(mly, mc)) 1365 break; 1366 SIMPLEQ_REMOVE_HEAD(&mly->mly_ccb_queue, mc, mc_link.simpleq); 1367 } 1368 1369 splx(s); 1370 } 1371 1372 /* 1373 * Deliver a command to the controller. 1374 */ 1375 static int 1376 mly_ccb_submit(struct mly_softc *mly, struct mly_ccb *mc) 1377 { 1378 union mly_cmd_packet *pkt; 1379 int s, off; 1380 1381 mc->mc_packet->generic.command_id = htole16(mc->mc_slot); 1382 1383 bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1384 mc->mc_packetphys - mly->mly_pkt_busaddr, 1385 sizeof(union mly_cmd_packet), 1386 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1387 1388 s = splbio(); 1389 1390 /* 1391 * Do we have to use the hardware mailbox? 1392 */ 1393 if ((mly->mly_state & MLY_STATE_MMBOX_ACTIVE) == 0) { 1394 /* 1395 * Check to see if the controller is ready for us. 1396 */ 1397 if (mly_idbr_true(mly, MLY_HM_CMDSENT)) { 1398 splx(s); 1399 return (EBUSY); 1400 } 1401 1402 /* 1403 * It's ready, send the command. 1404 */ 1405 mly_outl(mly, mly->mly_cmd_mailbox, 1406 (u_int64_t)mc->mc_packetphys & 0xffffffff); 1407 mly_outl(mly, mly->mly_cmd_mailbox + 4, 1408 (u_int64_t)mc->mc_packetphys >> 32); 1409 mly_outb(mly, mly->mly_idbr, MLY_HM_CMDSENT); 1410 } else { 1411 pkt = &mly->mly_mmbox->mmm_command[mly->mly_mmbox_cmd_idx]; 1412 off = (caddr_t)pkt - (caddr_t)mly->mly_mmbox; 1413 1414 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1415 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1416 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1417 1418 /* Check to see if the next index is free yet. */ 1419 if (pkt->mmbox.flag != 0) { 1420 splx(s); 1421 return (EBUSY); 1422 } 1423 1424 /* Copy in new command */ 1425 memcpy(pkt->mmbox.data, mc->mc_packet->mmbox.data, 1426 sizeof(pkt->mmbox.data)); 1427 1428 /* Copy flag last. */ 1429 pkt->mmbox.flag = mc->mc_packet->mmbox.flag; 1430 1431 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1432 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1433 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1434 1435 /* Signal controller and update index. */ 1436 mly_outb(mly, mly->mly_idbr, MLY_AM_CMDSENT); 1437 mly->mly_mmbox_cmd_idx = 1438 (mly->mly_mmbox_cmd_idx + 1) % MLY_MMBOX_COMMANDS; 1439 } 1440 1441 splx(s); 1442 return (0); 1443 } 1444 1445 /* 1446 * Pick up completed commands from the controller and handle accordingly. 1447 */ 1448 int 1449 mly_intr(void *cookie) 1450 { 1451 struct mly_ccb *mc; 1452 union mly_status_packet *sp; 1453 u_int16_t slot; 1454 int forus, off; 1455 struct mly_softc *mly; 1456 1457 mly = cookie; 1458 forus = 0; 1459 1460 /* 1461 * Pick up hardware-mailbox commands. 1462 */ 1463 if (mly_odbr_true(mly, MLY_HM_STSREADY)) { 1464 slot = mly_inw(mly, mly->mly_status_mailbox); 1465 1466 if (slot < MLY_SLOT_MAX) { 1467 mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1468 mc->mc_status = 1469 mly_inb(mly, mly->mly_status_mailbox + 2); 1470 mc->mc_sense = 1471 mly_inb(mly, mly->mly_status_mailbox + 3); 1472 mc->mc_resid = 1473 mly_inl(mly, mly->mly_status_mailbox + 4); 1474 1475 mly_ccb_complete(mly, mc); 1476 } else { 1477 /* Slot 0xffff may mean "extremely bogus command". */ 1478 printf("%s: got HM completion for illegal slot %u\n", 1479 mly->mly_dv.dv_xname, slot); 1480 } 1481 1482 /* Unconditionally acknowledge status. */ 1483 mly_outb(mly, mly->mly_odbr, MLY_HM_STSREADY); 1484 mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 1485 forus = 1; 1486 } 1487 1488 /* 1489 * Pick up memory-mailbox commands. 1490 */ 1491 if (mly_odbr_true(mly, MLY_AM_STSREADY)) { 1492 for (;;) { 1493 sp = &mly->mly_mmbox->mmm_status[mly->mly_mmbox_sts_idx]; 1494 off = (caddr_t)sp - (caddr_t)mly->mly_mmbox; 1495 1496 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1497 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1498 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1499 1500 /* Check for more status. */ 1501 if (sp->mmbox.flag == 0) 1502 break; 1503 1504 /* Get slot number. */ 1505 slot = le16toh(sp->status.command_id); 1506 if (slot < MLY_SLOT_MAX) { 1507 mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1508 mc->mc_status = sp->status.status; 1509 mc->mc_sense = sp->status.sense_length; 1510 mc->mc_resid = le32toh(sp->status.residue); 1511 mly_ccb_complete(mly, mc); 1512 } else { 1513 /* 1514 * Slot 0xffff may mean "extremely bogus 1515 * command". 1516 */ 1517 printf("%s: got AM completion for illegal " 1518 "slot %u at %d\n", mly->mly_dv.dv_xname, 1519 slot, mly->mly_mmbox_sts_idx); 1520 } 1521 1522 /* Clear and move to next index. */ 1523 sp->mmbox.flag = 0; 1524 mly->mly_mmbox_sts_idx = 1525 (mly->mly_mmbox_sts_idx + 1) % MLY_MMBOX_STATUS; 1526 } 1527 1528 /* Acknowledge that we have collected status value(s). */ 1529 mly_outb(mly, mly->mly_odbr, MLY_AM_STSREADY); 1530 forus = 1; 1531 } 1532 1533 /* 1534 * Run the queue. 1535 */ 1536 if (forus && SIMPLEQ_FIRST(&mly->mly_ccb_queue) != NULL) 1537 mly_ccb_enqueue(mly, NULL); 1538 1539 return (forus); 1540 } 1541 1542 /* 1543 * Process completed commands 1544 */ 1545 static void 1546 mly_ccb_complete(struct mly_softc *mly, struct mly_ccb *mc) 1547 { 1548 void (*complete)(struct mly_softc *, struct mly_ccb *); 1549 1550 bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1551 mc->mc_packetphys - mly->mly_pkt_busaddr, 1552 sizeof(union mly_cmd_packet), 1553 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1554 1555 complete = mc->mc_complete; 1556 mc->mc_flags |= MLY_CCB_COMPLETE; 1557 1558 /* 1559 * Call completion handler or wake up sleeping consumer. 1560 */ 1561 if (complete != NULL) 1562 (*complete)(mly, mc); 1563 else 1564 wakeup(mc); 1565 } 1566 1567 /* 1568 * Allocate a command. 1569 */ 1570 int 1571 mly_ccb_alloc(struct mly_softc *mly, struct mly_ccb **mcp) 1572 { 1573 struct mly_ccb *mc; 1574 int s; 1575 1576 s = splbio(); 1577 mc = SLIST_FIRST(&mly->mly_ccb_free); 1578 if (mc != NULL) 1579 SLIST_REMOVE_HEAD(&mly->mly_ccb_free, mc_link.slist); 1580 splx(s); 1581 1582 *mcp = mc; 1583 return (mc == NULL ? EAGAIN : 0); 1584 } 1585 1586 /* 1587 * Release a command back to the freelist. 1588 */ 1589 void 1590 mly_ccb_free(struct mly_softc *mly, struct mly_ccb *mc) 1591 { 1592 int s; 1593 1594 /* 1595 * Fill in parts of the command that may cause confusion if a 1596 * consumer doesn't when we are later allocated. 1597 */ 1598 mc->mc_data = NULL; 1599 mc->mc_flags = 0; 1600 mc->mc_complete = NULL; 1601 mc->mc_private = NULL; 1602 mc->mc_packet->generic.command_control = 0; 1603 1604 /* 1605 * By default, we set up to overwrite the command packet with sense 1606 * information. 1607 */ 1608 mc->mc_packet->generic.sense_buffer_address = 1609 htole64(mc->mc_packetphys); 1610 mc->mc_packet->generic.maximum_sense_size = 1611 sizeof(union mly_cmd_packet); 1612 1613 s = splbio(); 1614 SLIST_INSERT_HEAD(&mly->mly_ccb_free, mc, mc_link.slist); 1615 splx(s); 1616 } 1617 1618 /* 1619 * Allocate and initialise command and packet structures. 1620 * 1621 * If the controller supports fewer than MLY_MAX_CCBS commands, limit our 1622 * allocation to that number. If we don't yet know how many commands the 1623 * controller supports, allocate a very small set (suitable for initialisation 1624 * purposes only). 1625 */ 1626 static int 1627 mly_alloc_ccbs(struct mly_softc *mly) 1628 { 1629 struct mly_ccb *mc; 1630 int i, rv; 1631 1632 if (mly->mly_controllerinfo == NULL) 1633 mly->mly_ncmds = MLY_CCBS_RESV; 1634 else { 1635 i = le16toh(mly->mly_controllerinfo->maximum_parallel_commands); 1636 mly->mly_ncmds = min(MLY_MAX_CCBS, i); 1637 } 1638 1639 /* 1640 * Allocate enough space for all the command packets in one chunk 1641 * and map them permanently into controller-visible space. 1642 */ 1643 rv = mly_dmamem_alloc(mly, 1644 mly->mly_ncmds * sizeof(union mly_cmd_packet), 1645 &mly->mly_pkt_dmamap, (caddr_t *)&mly->mly_pkt, 1646 &mly->mly_pkt_busaddr, &mly->mly_pkt_seg); 1647 if (rv) 1648 return (rv); 1649 1650 mly->mly_ccbs = malloc(sizeof(struct mly_ccb) * mly->mly_ncmds, 1651 M_DEVBUF, M_NOWAIT); 1652 memset(mly->mly_ccbs, 0, sizeof(struct mly_ccb) * mly->mly_ncmds); 1653 1654 for (i = 0; i < mly->mly_ncmds; i++) { 1655 mc = mly->mly_ccbs + i; 1656 mc->mc_slot = MLY_SLOT_START + i; 1657 mc->mc_packet = mly->mly_pkt + i; 1658 mc->mc_packetphys = mly->mly_pkt_busaddr + 1659 (i * sizeof(union mly_cmd_packet)); 1660 1661 rv = bus_dmamap_create(mly->mly_dmat, MLY_MAX_XFER, 1662 MLY_MAX_SEGS, MLY_MAX_XFER, 0, 1663 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 1664 &mc->mc_datamap); 1665 if (rv) { 1666 mly_release_ccbs(mly); 1667 return (rv); 1668 } 1669 1670 mly_ccb_free(mly, mc); 1671 } 1672 1673 return (0); 1674 } 1675 1676 /* 1677 * Free all the storage held by commands. 1678 * 1679 * Must be called with all commands on the free list. 1680 */ 1681 static void 1682 mly_release_ccbs(struct mly_softc *mly) 1683 { 1684 struct mly_ccb *mc; 1685 1686 /* Throw away command buffer DMA maps. */ 1687 while (mly_ccb_alloc(mly, &mc) == 0) 1688 bus_dmamap_destroy(mly->mly_dmat, mc->mc_datamap); 1689 1690 /* Release CCB storage. */ 1691 free(mly->mly_ccbs, M_DEVBUF); 1692 1693 /* Release the packet storage. */ 1694 mly_dmamem_free(mly, mly->mly_ncmds * sizeof(union mly_cmd_packet), 1695 mly->mly_pkt_dmamap, (caddr_t)mly->mly_pkt, &mly->mly_pkt_seg); 1696 } 1697 1698 /* 1699 * Map a command into controller-visible space. 1700 */ 1701 static int 1702 mly_ccb_map(struct mly_softc *mly, struct mly_ccb *mc) 1703 { 1704 struct mly_cmd_generic *gen; 1705 struct mly_sg_entry *sg; 1706 bus_dma_segment_t *ds; 1707 int flg, nseg, rv; 1708 1709 #ifdef DIAGNOSTIC 1710 /* Don't map more than once. */ 1711 if ((mc->mc_flags & MLY_CCB_MAPPED) != 0) 1712 panic("mly_ccb_map: already mapped"); 1713 mc->mc_flags |= MLY_CCB_MAPPED; 1714 1715 /* Does the command have a data buffer? */ 1716 if (mc->mc_data == NULL) 1717 panic("mly_ccb_map: no data buffer"); 1718 #endif 1719 1720 rv = bus_dmamap_load(mly->mly_dmat, mc->mc_datamap, mc->mc_data, 1721 mc->mc_length, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1722 ((mc->mc_flags & MLY_CCB_DATAIN) != 0 ? 1723 BUS_DMA_READ : BUS_DMA_WRITE)); 1724 if (rv != 0) 1725 return (rv); 1726 1727 gen = &mc->mc_packet->generic; 1728 1729 /* 1730 * Can we use the transfer structure directly? 1731 */ 1732 if ((nseg = mc->mc_datamap->dm_nsegs) <= 2) { 1733 mc->mc_sgoff = -1; 1734 sg = &gen->transfer.direct.sg[0]; 1735 } else { 1736 mc->mc_sgoff = (mc->mc_slot - MLY_SLOT_START) * 1737 MLY_MAX_SEGS; 1738 sg = mly->mly_sg + mc->mc_sgoff; 1739 gen->command_control |= MLY_CMDCTL_EXTENDED_SG_TABLE; 1740 gen->transfer.indirect.entries[0] = htole16(nseg); 1741 gen->transfer.indirect.table_physaddr[0] = 1742 htole64(mly->mly_sg_busaddr + 1743 (mc->mc_sgoff * sizeof(struct mly_sg_entry))); 1744 } 1745 1746 /* 1747 * Fill the S/G table. 1748 */ 1749 for (ds = mc->mc_datamap->dm_segs; nseg != 0; nseg--, sg++, ds++) { 1750 sg->physaddr = htole64(ds->ds_addr); 1751 sg->length = htole64(ds->ds_len); 1752 } 1753 1754 /* 1755 * Sync up the data map. 1756 */ 1757 if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1758 flg = BUS_DMASYNC_PREREAD; 1759 else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ { 1760 gen->command_control |= MLY_CMDCTL_DATA_DIRECTION; 1761 flg = BUS_DMASYNC_PREWRITE; 1762 } 1763 1764 bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1765 1766 /* 1767 * Sync up the chained S/G table, if we're using one. 1768 */ 1769 if (mc->mc_sgoff == -1) 1770 return (0); 1771 1772 bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1773 MLY_SGL_SIZE, BUS_DMASYNC_PREWRITE); 1774 1775 return (0); 1776 } 1777 1778 /* 1779 * Unmap a command from controller-visible space. 1780 */ 1781 static void 1782 mly_ccb_unmap(struct mly_softc *mly, struct mly_ccb *mc) 1783 { 1784 int flg; 1785 1786 #ifdef DIAGNOSTIC 1787 if ((mc->mc_flags & MLY_CCB_MAPPED) == 0) 1788 panic("mly_ccb_unmap: not mapped"); 1789 mc->mc_flags &= ~MLY_CCB_MAPPED; 1790 #endif 1791 1792 if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1793 flg = BUS_DMASYNC_POSTREAD; 1794 else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ 1795 flg = BUS_DMASYNC_POSTWRITE; 1796 1797 bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1798 bus_dmamap_unload(mly->mly_dmat, mc->mc_datamap); 1799 1800 if (mc->mc_sgoff == -1) 1801 return; 1802 1803 bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1804 MLY_SGL_SIZE, BUS_DMASYNC_POSTWRITE); 1805 } 1806 1807 /* 1808 * Adjust the size of each I/O before it passes to the SCSI layer. 1809 */ 1810 static void 1811 mly_scsipi_minphys(struct buf *bp) 1812 { 1813 1814 if (bp->b_bcount > MLY_MAX_XFER) 1815 bp->b_bcount = MLY_MAX_XFER; 1816 minphys(bp); 1817 } 1818 1819 /* 1820 * Start a SCSI command. 1821 */ 1822 static void 1823 mly_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1824 void *arg) 1825 { 1826 struct mly_ccb *mc; 1827 struct mly_cmd_scsi_small *ss; 1828 struct scsipi_xfer *xs; 1829 struct scsipi_periph *periph; 1830 struct mly_softc *mly; 1831 struct mly_btl *btl; 1832 int s, tmp; 1833 1834 mly = (void *)chan->chan_adapter->adapt_dev; 1835 1836 switch (req) { 1837 case ADAPTER_REQ_RUN_XFER: 1838 xs = arg; 1839 periph = xs->xs_periph; 1840 btl = &mly->mly_btl[chan->chan_channel][periph->periph_target]; 1841 s = splbio(); 1842 tmp = btl->mb_flags; 1843 splx(s); 1844 1845 /* 1846 * Check for I/O attempt to a protected or non-existant 1847 * device. 1848 */ 1849 if ((tmp & MLY_BTL_PROTECTED) != 0) { 1850 xs->error = XS_SELTIMEOUT; 1851 scsipi_done(xs); 1852 break; 1853 } 1854 1855 #ifdef DIAGNOSTIC 1856 /* XXX Increase if/when we support large SCSI commands. */ 1857 if (xs->cmdlen > MLY_CMD_SCSI_SMALL_CDB) { 1858 printf("%s: cmd too large\n", mly->mly_dv.dv_xname); 1859 xs->error = XS_DRIVER_STUFFUP; 1860 scsipi_done(xs); 1861 break; 1862 } 1863 #endif 1864 1865 if (mly_ccb_alloc(mly, &mc)) { 1866 xs->error = XS_RESOURCE_SHORTAGE; 1867 scsipi_done(xs); 1868 break; 1869 } 1870 1871 /* Build the command. */ 1872 mc->mc_data = xs->data; 1873 mc->mc_length = xs->datalen; 1874 mc->mc_complete = mly_scsipi_complete; 1875 mc->mc_private = xs; 1876 1877 /* Build the packet for the controller. */ 1878 ss = &mc->mc_packet->scsi_small; 1879 ss->opcode = MDACMD_SCSI; 1880 #ifdef notdef 1881 /* 1882 * XXX FreeBSD does this, but it doesn't fix anything, 1883 * XXX and appears potentially harmful. 1884 */ 1885 ss->command_control |= MLY_CMDCTL_DISABLE_DISCONNECT; 1886 #endif 1887 1888 ss->data_size = htole32(xs->datalen); 1889 _lto3l(MLY_PHYADDR(0, chan->chan_channel, 1890 periph->periph_target, periph->periph_lun), ss->addr); 1891 1892 if (xs->timeout < 60 * 1000) 1893 ss->timeout = xs->timeout / 1000 | 1894 MLY_TIMEOUT_SECONDS; 1895 else if (xs->timeout < 60 * 60 * 1000) 1896 ss->timeout = xs->timeout / (60 * 1000) | 1897 MLY_TIMEOUT_MINUTES; 1898 else 1899 ss->timeout = xs->timeout / (60 * 60 * 1000) | 1900 MLY_TIMEOUT_HOURS; 1901 1902 ss->maximum_sense_size = sizeof(xs->sense); 1903 ss->cdb_length = xs->cmdlen; 1904 memcpy(ss->cdb, xs->cmd, xs->cmdlen); 1905 1906 if (mc->mc_length != 0) { 1907 if ((xs->xs_control & XS_CTL_DATA_OUT) != 0) 1908 mc->mc_flags |= MLY_CCB_DATAOUT; 1909 else /* if ((xs->xs_control & XS_CTL_DATA_IN) != 0) */ 1910 mc->mc_flags |= MLY_CCB_DATAIN; 1911 1912 if (mly_ccb_map(mly, mc) != 0) { 1913 xs->error = XS_DRIVER_STUFFUP; 1914 mly_ccb_free(mly, mc); 1915 scsipi_done(xs); 1916 break; 1917 } 1918 } 1919 1920 /* 1921 * Give the command to the controller. 1922 */ 1923 if ((xs->xs_control & XS_CTL_POLL) != 0) { 1924 if (mly_ccb_poll(mly, mc, xs->timeout + 5000)) { 1925 xs->error = XS_REQUEUE; 1926 if (mc->mc_length != 0) 1927 mly_ccb_unmap(mly, mc); 1928 mly_ccb_free(mly, mc); 1929 scsipi_done(xs); 1930 } 1931 } else 1932 mly_ccb_enqueue(mly, mc); 1933 1934 break; 1935 1936 case ADAPTER_REQ_GROW_RESOURCES: 1937 /* 1938 * Not supported. 1939 */ 1940 break; 1941 1942 case ADAPTER_REQ_SET_XFER_MODE: 1943 /* 1944 * We can't change the transfer mode, but at least let 1945 * scsipi know what the adapter has negotiated. 1946 */ 1947 mly_get_xfer_mode(mly, chan->chan_channel, arg); 1948 break; 1949 } 1950 } 1951 1952 /* 1953 * Handle completion of a SCSI command. 1954 */ 1955 static void 1956 mly_scsipi_complete(struct mly_softc *mly, struct mly_ccb *mc) 1957 { 1958 struct scsipi_xfer *xs; 1959 struct scsipi_channel *chan; 1960 struct scsipi_inquiry_data *inq; 1961 struct mly_btl *btl; 1962 int target, sl, s; 1963 const char *p; 1964 1965 xs = mc->mc_private; 1966 xs->status = mc->mc_status; 1967 1968 /* 1969 * XXX The `resid' value as returned by the controller appears to be 1970 * bogus, so we always set it to zero. Is it perhaps the transfer 1971 * count? 1972 */ 1973 xs->resid = 0; /* mc->mc_resid; */ 1974 1975 if (mc->mc_length != 0) 1976 mly_ccb_unmap(mly, mc); 1977 1978 switch (mc->mc_status) { 1979 case SCSI_OK: 1980 /* 1981 * In order to report logical device type and status, we 1982 * overwrite the result of the INQUIRY command to logical 1983 * devices. 1984 */ 1985 if (xs->cmd->opcode == INQUIRY) { 1986 chan = xs->xs_periph->periph_channel; 1987 target = xs->xs_periph->periph_target; 1988 btl = &mly->mly_btl[chan->chan_channel][target]; 1989 1990 s = splbio(); 1991 if ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) { 1992 inq = (struct scsipi_inquiry_data *)xs->data; 1993 mly_padstr(inq->vendor, "MYLEX", 8); 1994 p = mly_describe_code(mly_table_device_type, 1995 btl->mb_type); 1996 mly_padstr(inq->product, p, 16); 1997 p = mly_describe_code(mly_table_device_state, 1998 btl->mb_state); 1999 mly_padstr(inq->revision, p, 4); 2000 } 2001 splx(s); 2002 } 2003 2004 xs->error = XS_NOERROR; 2005 break; 2006 2007 case SCSI_CHECK: 2008 sl = mc->mc_sense; 2009 if (sl > sizeof(xs->sense.scsi_sense)) 2010 sl = sizeof(xs->sense.scsi_sense); 2011 memcpy(&xs->sense.scsi_sense, mc->mc_packet, sl); 2012 xs->error = XS_SENSE; 2013 break; 2014 2015 case SCSI_BUSY: 2016 case SCSI_QUEUE_FULL: 2017 xs->error = XS_BUSY; 2018 break; 2019 2020 default: 2021 printf("%s: unknown SCSI status 0x%x\n", 2022 mly->mly_dv.dv_xname, xs->status); 2023 xs->error = XS_DRIVER_STUFFUP; 2024 break; 2025 } 2026 2027 mly_ccb_free(mly, mc); 2028 scsipi_done(xs); 2029 } 2030 2031 /* 2032 * Notify scsipi about a target's transfer mode. 2033 */ 2034 static void 2035 mly_get_xfer_mode(struct mly_softc *mly, int bus, struct scsipi_xfer_mode *xm) 2036 { 2037 struct mly_btl *btl; 2038 int s; 2039 2040 btl = &mly->mly_btl[bus][xm->xm_target]; 2041 xm->xm_mode = 0; 2042 2043 s = splbio(); 2044 2045 if ((btl->mb_flags & MLY_BTL_PHYSICAL) != 0) { 2046 if (btl->mb_speed == 0) { 2047 xm->xm_period = 0; 2048 xm->xm_offset = 0; 2049 } else { 2050 xm->xm_period = 12; /* XXX */ 2051 xm->xm_offset = 8; /* XXX */ 2052 xm->xm_mode |= PERIPH_CAP_SYNC; /* XXX */ 2053 } 2054 2055 switch (btl->mb_width) { 2056 case 32: 2057 xm->xm_mode = PERIPH_CAP_WIDE32; 2058 break; 2059 case 16: 2060 xm->xm_mode = PERIPH_CAP_WIDE16; 2061 break; 2062 default: 2063 xm->xm_mode = 0; 2064 break; 2065 } 2066 } else /* ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) */ { 2067 xm->xm_mode = PERIPH_CAP_WIDE16 | PERIPH_CAP_SYNC; 2068 xm->xm_period = 12; 2069 xm->xm_offset = 8; 2070 } 2071 2072 if ((btl->mb_flags & MLY_BTL_TQING) != 0) 2073 xm->xm_mode |= PERIPH_CAP_TQING; 2074 2075 splx(s); 2076 2077 scsipi_async_event(&mly->mly_chans[bus], ASYNC_EVENT_XFER_MODE, xm); 2078 } 2079 2080 /* 2081 * ioctl hook; used here only to initiate low-level rescans. 2082 */ 2083 static int 2084 mly_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, caddr_t data, 2085 int flag, struct proc *p) 2086 { 2087 struct mly_softc *mly; 2088 int rv; 2089 2090 mly = (struct mly_softc *)chan->chan_adapter->adapt_dev; 2091 2092 switch (cmd) { 2093 case SCBUSIOLLSCAN: 2094 mly_scan_channel(mly, chan->chan_channel); 2095 rv = 0; 2096 break; 2097 default: 2098 rv = ENOTTY; 2099 break; 2100 } 2101 2102 return (rv); 2103 } 2104 2105 /* 2106 * Handshake with the firmware while the card is being initialised. 2107 */ 2108 static int 2109 mly_fwhandshake(struct mly_softc *mly) 2110 { 2111 u_int8_t error, param0, param1; 2112 int spinup; 2113 2114 spinup = 0; 2115 2116 /* Set HM_STSACK and let the firmware initialise. */ 2117 mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 2118 DELAY(1000); /* too short? */ 2119 2120 /* If HM_STSACK is still true, the controller is initialising. */ 2121 if (!mly_idbr_true(mly, MLY_HM_STSACK)) 2122 return (0); 2123 2124 printf("%s: controller initialisation started\n", 2125 mly->mly_dv.dv_xname); 2126 2127 /* 2128 * Spin waiting for initialisation to finish, or for a message to be 2129 * delivered. 2130 */ 2131 while (mly_idbr_true(mly, MLY_HM_STSACK)) { 2132 /* Check for a message */ 2133 if (!mly_error_valid(mly)) 2134 continue; 2135 2136 error = mly_inb(mly, mly->mly_error_status) & ~MLY_MSG_EMPTY; 2137 param0 = mly_inb(mly, mly->mly_cmd_mailbox); 2138 param1 = mly_inb(mly, mly->mly_cmd_mailbox + 1); 2139 2140 switch (error) { 2141 case MLY_MSG_SPINUP: 2142 if (!spinup) { 2143 printf("%s: drive spinup in progress\n", 2144 mly->mly_dv.dv_xname); 2145 spinup = 1; 2146 } 2147 break; 2148 2149 case MLY_MSG_RACE_RECOVERY_FAIL: 2150 printf("%s: mirror race recovery failed - \n", 2151 mly->mly_dv.dv_xname); 2152 printf("%s: one or more drives offline\n", 2153 mly->mly_dv.dv_xname); 2154 break; 2155 2156 case MLY_MSG_RACE_IN_PROGRESS: 2157 printf("%s: mirror race recovery in progress\n", 2158 mly->mly_dv.dv_xname); 2159 break; 2160 2161 case MLY_MSG_RACE_ON_CRITICAL: 2162 printf("%s: mirror race recovery on critical drive\n", 2163 mly->mly_dv.dv_xname); 2164 break; 2165 2166 case MLY_MSG_PARITY_ERROR: 2167 printf("%s: FATAL MEMORY PARITY ERROR\n", 2168 mly->mly_dv.dv_xname); 2169 return (ENXIO); 2170 2171 default: 2172 printf("%s: unknown initialisation code 0x%x\n", 2173 mly->mly_dv.dv_xname, error); 2174 break; 2175 } 2176 } 2177 2178 return (0); 2179 } 2180 2181 /* 2182 * Space-fill a character string 2183 */ 2184 static void 2185 mly_padstr(char *dst, const char *src, int len) 2186 { 2187 2188 while (len-- > 0) { 2189 if (*src != '\0') 2190 *dst++ = *src++; 2191 else 2192 *dst++ = ' '; 2193 } 2194 } 2195 2196 /* 2197 * Allocate DMA safe memory. 2198 */ 2199 static int 2200 mly_dmamem_alloc(struct mly_softc *mly, int size, bus_dmamap_t *dmamap, 2201 caddr_t *kva, bus_addr_t *paddr, bus_dma_segment_t *seg) 2202 { 2203 int rseg, rv, state; 2204 2205 state = 0; 2206 2207 if ((rv = bus_dmamem_alloc(mly->mly_dmat, size, NBPG, 0, 2208 seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 2209 printf("%s: dmamem_alloc = %d\n", mly->mly_dv.dv_xname, rv); 2210 goto bad; 2211 } 2212 2213 state++; 2214 2215 if ((rv = bus_dmamem_map(mly->mly_dmat, seg, 1, size, kva, 2216 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 2217 printf("%s: dmamem_map = %d\n", mly->mly_dv.dv_xname, rv); 2218 goto bad; 2219 } 2220 2221 state++; 2222 2223 if ((rv = bus_dmamap_create(mly->mly_dmat, size, size, 1, 0, 2224 BUS_DMA_NOWAIT, dmamap)) != 0) { 2225 printf("%s: dmamap_create = %d\n", mly->mly_dv.dv_xname, rv); 2226 goto bad; 2227 } 2228 2229 state++; 2230 2231 if ((rv = bus_dmamap_load(mly->mly_dmat, *dmamap, *kva, size, 2232 NULL, BUS_DMA_NOWAIT)) != 0) { 2233 printf("%s: dmamap_load = %d\n", mly->mly_dv.dv_xname, rv); 2234 goto bad; 2235 } 2236 2237 *paddr = (*dmamap)->dm_segs[0].ds_addr; 2238 memset(*kva, 0, size); 2239 return (0); 2240 2241 bad: 2242 if (state > 2) 2243 bus_dmamap_destroy(mly->mly_dmat, *dmamap); 2244 if (state > 1) 2245 bus_dmamem_unmap(mly->mly_dmat, *kva, size); 2246 if (state > 0) 2247 bus_dmamem_free(mly->mly_dmat, seg, 1); 2248 2249 return (rv); 2250 } 2251 2252 /* 2253 * Free DMA safe memory. 2254 */ 2255 static void 2256 mly_dmamem_free(struct mly_softc *mly, int size, bus_dmamap_t dmamap, 2257 caddr_t kva, bus_dma_segment_t *seg) 2258 { 2259 2260 bus_dmamap_unload(mly->mly_dmat, dmamap); 2261 bus_dmamap_destroy(mly->mly_dmat, dmamap); 2262 bus_dmamem_unmap(mly->mly_dmat, kva, size); 2263 bus_dmamem_free(mly->mly_dmat, seg, 1); 2264 } 2265 2266 2267 /* 2268 * Accept an open operation on the control device. 2269 */ 2270 int 2271 mlyopen(dev_t dev, int flag, int mode, struct proc *p) 2272 { 2273 struct mly_softc *mly; 2274 2275 if ((mly = device_lookup(&mly_cd, minor(dev))) == NULL) 2276 return (ENXIO); 2277 if ((mly->mly_state & MLY_STATE_INITOK) == 0) 2278 return (ENXIO); 2279 if ((mly->mly_state & MLY_STATE_OPEN) != 0) 2280 return (EBUSY); 2281 2282 mly->mly_state |= MLY_STATE_OPEN; 2283 return (0); 2284 } 2285 2286 /* 2287 * Accept the last close on the control device. 2288 */ 2289 int 2290 mlyclose(dev_t dev, int flag, int mode, struct proc *p) 2291 { 2292 struct mly_softc *mly; 2293 2294 mly = device_lookup(&mly_cd, minor(dev)); 2295 mly->mly_state &= ~MLY_STATE_OPEN; 2296 return (0); 2297 } 2298 2299 /* 2300 * Handle control operations. 2301 */ 2302 int 2303 mlyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2304 { 2305 struct mly_softc *mly; 2306 int rv; 2307 2308 if (securelevel >= 2) 2309 return (EPERM); 2310 2311 mly = device_lookup(&mly_cd, minor(dev)); 2312 2313 switch (cmd) { 2314 case MLYIO_COMMAND: 2315 rv = mly_user_command(mly, (void *)data); 2316 break; 2317 case MLYIO_HEALTH: 2318 rv = mly_user_health(mly, (void *)data); 2319 break; 2320 default: 2321 rv = ENOTTY; 2322 break; 2323 } 2324 2325 return (rv); 2326 } 2327 2328 /* 2329 * Execute a command passed in from userspace. 2330 * 2331 * The control structure contains the actual command for the controller, as 2332 * well as the user-space data pointer and data size, and an optional sense 2333 * buffer size/pointer. On completion, the data size is adjusted to the 2334 * command residual, and the sense buffer size to the size of the returned 2335 * sense data. 2336 */ 2337 static int 2338 mly_user_command(struct mly_softc *mly, struct mly_user_command *uc) 2339 { 2340 struct mly_ccb *mc; 2341 int rv, mapped; 2342 2343 if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 2344 return (rv); 2345 2346 mapped = 0; 2347 mc->mc_data = NULL; 2348 2349 /* 2350 * Handle data size/direction. 2351 */ 2352 if ((mc->mc_length = abs(uc->DataTransferLength)) != 0) { 2353 if (mc->mc_length > MAXPHYS) { 2354 rv = EINVAL; 2355 goto out; 2356 } 2357 2358 mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_WAITOK); 2359 if (mc->mc_data == NULL) { 2360 rv = ENOMEM; 2361 goto out; 2362 } 2363 2364 if (uc->DataTransferLength > 0) { 2365 mc->mc_flags |= MLY_CCB_DATAIN; 2366 memset(mc->mc_data, 0, mc->mc_length); 2367 } 2368 2369 if (uc->DataTransferLength < 0) { 2370 mc->mc_flags |= MLY_CCB_DATAOUT; 2371 rv = copyin(uc->DataTransferBuffer, mc->mc_data, 2372 mc->mc_length); 2373 if (rv != 0) 2374 goto out; 2375 } 2376 2377 if ((rv = mly_ccb_map(mly, mc)) != 0) 2378 goto out; 2379 mapped = 1; 2380 } 2381 2382 /* Copy in the command and execute it. */ 2383 memcpy(mc->mc_packet, &uc->CommandMailbox, sizeof(uc->CommandMailbox)); 2384 2385 if ((rv = mly_ccb_wait(mly, mc, 60000)) != 0) 2386 goto out; 2387 2388 /* Return the data to userspace. */ 2389 if (uc->DataTransferLength > 0) { 2390 rv = copyout(mc->mc_data, uc->DataTransferBuffer, 2391 mc->mc_length); 2392 if (rv != 0) 2393 goto out; 2394 } 2395 2396 /* Return the sense buffer to userspace. */ 2397 if (uc->RequestSenseLength > 0 && mc->mc_sense > 0) { 2398 rv = copyout(mc->mc_packet, uc->RequestSenseBuffer, 2399 min(uc->RequestSenseLength, mc->mc_sense)); 2400 if (rv != 0) 2401 goto out; 2402 } 2403 2404 /* Return command results to userspace (caller will copy out). */ 2405 uc->DataTransferLength = mc->mc_resid; 2406 uc->RequestSenseLength = min(uc->RequestSenseLength, mc->mc_sense); 2407 uc->CommandStatus = mc->mc_status; 2408 rv = 0; 2409 2410 out: 2411 if (mapped) 2412 mly_ccb_unmap(mly, mc); 2413 if (mc->mc_data != NULL) 2414 free(mc->mc_data, M_DEVBUF); 2415 if (mc != NULL) 2416 mly_ccb_free(mly, mc); 2417 2418 return (rv); 2419 } 2420 2421 /* 2422 * Return health status to userspace. If the health change index in the 2423 * user structure does not match that currently exported by the controller, 2424 * we return the current status immediately. Otherwise, we block until 2425 * either interrupted or new status is delivered. 2426 */ 2427 static int 2428 mly_user_health(struct mly_softc *mly, struct mly_user_health *uh) 2429 { 2430 struct mly_health_status mh; 2431 int rv, s; 2432 2433 /* Fetch the current health status from userspace. */ 2434 rv = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh)); 2435 if (rv != 0) 2436 return (rv); 2437 2438 /* spin waiting for a status update */ 2439 s = splbio(); 2440 if (mly->mly_event_change == mh.change_counter) 2441 rv = tsleep(&mly->mly_event_change, PRIBIO | PCATCH, 2442 "mlyhealth", 0); 2443 splx(s); 2444 2445 if (rv == 0) { 2446 /* 2447 * Copy the controller's health status buffer out (there is 2448 * a race here if it changes again). 2449 */ 2450 rv = copyout(&mly->mly_mmbox->mmm_health.status, 2451 uh->HealthStatusBuffer, sizeof(uh->HealthStatusBuffer)); 2452 } 2453 2454 return (rv); 2455 } 2456