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