1 /* $NetBSD: mly.c,v 1.9 2002/01/14 13:23:36 tsutsui 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.9 2002/01/14 13:23:36 tsutsui 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|M_ZERO); 659 660 mc->mc_flags |= MLY_CCB_DATAIN; 661 mc->mc_complete = mly_complete_rescan; 662 663 /* 664 * Build the ioctl. 665 */ 666 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 667 mci->opcode = MDACMD_IOCTL; 668 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 669 memset(&mci->param, 0, sizeof(mci->param)); 670 671 if (MLY_BUS_IS_VIRTUAL(mly, bus)) { 672 mc->mc_length = sizeof(struct mly_ioctl_getlogdevinfovalid); 673 mci->data_size = htole32(mc->mc_length); 674 mci->sub_ioctl = MDACIOCTL_GETLOGDEVINFOVALID; 675 _lto3l(MLY_LOGADDR(0, MLY_LOGDEV_ID(mly, bus, target)), 676 mci->addr); 677 } else { 678 mc->mc_length = sizeof(struct mly_ioctl_getphysdevinfovalid); 679 mci->data_size = htole32(mc->mc_length); 680 mci->sub_ioctl = MDACIOCTL_GETPHYSDEVINFOVALID; 681 _lto3l(MLY_PHYADDR(0, bus, target, 0), mci->addr); 682 } 683 684 /* 685 * Dispatch the command. 686 */ 687 if ((rv = mly_ccb_map(mly, mc)) != 0) { 688 free(mc->mc_data, M_DEVBUF); 689 mly_ccb_free(mly, mc); 690 return(rv); 691 } 692 693 mly->mly_btl[bus][target].mb_flags |= MLY_BTL_SCANNING; 694 mly_ccb_enqueue(mly, mc); 695 return (0); 696 } 697 698 /* 699 * Handle the completion of a rescan operation. 700 */ 701 static void 702 mly_complete_rescan(struct mly_softc *mly, struct mly_ccb *mc) 703 { 704 struct mly_ioctl_getlogdevinfovalid *ldi; 705 struct mly_ioctl_getphysdevinfovalid *pdi; 706 struct mly_cmd_ioctl *mci; 707 struct mly_btl btl, *btlp; 708 struct scsipi_xfer_mode xm; 709 int bus, target, rescan; 710 u_int tmp; 711 712 mly_ccb_unmap(mly, mc); 713 714 /* 715 * Recover the bus and target from the command. We need these even 716 * in the case where we don't have a useful response. 717 */ 718 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 719 tmp = _3ltol(mci->addr); 720 rescan = 0; 721 722 if (mci->sub_ioctl == MDACIOCTL_GETLOGDEVINFOVALID) { 723 bus = MLY_LOGDEV_BUS(mly, MLY_LOGADDR_DEV(tmp)); 724 target = MLY_LOGDEV_TARGET(mly, MLY_LOGADDR_DEV(tmp)); 725 } else { 726 bus = MLY_PHYADDR_CHANNEL(tmp); 727 target = MLY_PHYADDR_TARGET(tmp); 728 } 729 730 btlp = &mly->mly_btl[bus][target]; 731 732 /* The default result is 'no device'. */ 733 memset(&btl, 0, sizeof(btl)); 734 btl.mb_flags = MLY_BTL_PROTECTED; 735 736 /* If the rescan completed OK, we have possibly-new BTL data. */ 737 if (mc->mc_status != 0) 738 goto out; 739 740 if (mc->mc_length == sizeof(*ldi)) { 741 ldi = (struct mly_ioctl_getlogdevinfovalid *)mc->mc_data; 742 tmp = le32toh(ldi->logical_device_number); 743 744 if (MLY_LOGDEV_BUS(mly, tmp) != bus || 745 MLY_LOGDEV_TARGET(mly, tmp) != target) { 746 #ifdef MLYDEBUG 747 printf("%s: WARNING: BTL rescan (logical) for %d:%d " 748 "returned data for %d:%d instead\n", 749 mly->mly_dv.dv_xname, bus, target, 750 MLY_LOGDEV_BUS(mly, tmp), 751 MLY_LOGDEV_TARGET(mly, tmp)); 752 #endif 753 goto out; 754 } 755 756 btl.mb_flags = MLY_BTL_LOGICAL | MLY_BTL_TQING; 757 btl.mb_type = ldi->raid_level; 758 btl.mb_state = ldi->state; 759 } else if (mc->mc_length == sizeof(*pdi)) { 760 pdi = (struct mly_ioctl_getphysdevinfovalid *)mc->mc_data; 761 762 if (pdi->channel != bus || pdi->target != target) { 763 #ifdef MLYDEBUG 764 printf("%s: WARNING: BTL rescan (physical) for %d:%d " 765 " returned data for %d:%d instead\n", 766 mly->mly_dv.dv_xname, 767 bus, target, pdi->channel, pdi->target); 768 #endif 769 goto out; 770 } 771 772 btl.mb_flags = MLY_BTL_PHYSICAL; 773 btl.mb_type = MLY_DEVICE_TYPE_PHYSICAL; 774 btl.mb_state = pdi->state; 775 btl.mb_speed = pdi->speed; 776 btl.mb_width = pdi->width; 777 778 if (pdi->state != MLY_DEVICE_STATE_UNCONFIGURED) 779 btl.mb_flags |= MLY_BTL_PROTECTED; 780 if (pdi->command_tags != 0) 781 btl.mb_flags |= MLY_BTL_TQING; 782 } else { 783 printf("%s: BTL rescan result invalid\n", mly->mly_dv.dv_xname); 784 goto out; 785 } 786 787 /* Decide whether we need to rescan the device. */ 788 if (btl.mb_flags != btlp->mb_flags || 789 btl.mb_speed != btlp->mb_speed || 790 btl.mb_width != btlp->mb_width) 791 rescan = 1; 792 793 out: 794 *btlp = btl; 795 796 if (rescan && (btl.mb_flags & MLY_BTL_PROTECTED) == 0) { 797 xm.xm_target = target; 798 mly_get_xfer_mode(mly, bus, &xm); 799 /* XXX SCSI mid-layer rescan goes here. */ 800 } 801 802 /* Wake anybody waiting on the device to be rescanned. */ 803 wakeup(btlp); 804 805 free(mc->mc_data, M_DEVBUF); 806 mly_ccb_free(mly, mc); 807 } 808 809 /* 810 * Get the current health status and set the 'next event' counter to suit. 811 */ 812 static int 813 mly_get_eventstatus(struct mly_softc *mly) 814 { 815 struct mly_cmd_ioctl mci; 816 struct mly_health_status *mh; 817 int rv; 818 819 /* Build the gethealthstatus ioctl and send it. */ 820 memset(&mci, 0, sizeof(mci)); 821 mh = NULL; 822 mci.sub_ioctl = MDACIOCTL_GETHEALTHSTATUS; 823 824 rv = mly_ioctl(mly, &mci, (void **)&mh, sizeof(*mh), NULL, NULL); 825 if (rv) 826 return (rv); 827 828 /* Get the event counter. */ 829 mly->mly_event_change = le32toh(mh->change_counter); 830 mly->mly_event_waiting = le32toh(mh->next_event); 831 mly->mly_event_counter = le32toh(mh->next_event); 832 833 /* Save the health status into the memory mailbox */ 834 memcpy(&mly->mly_mmbox->mmm_health.status, mh, sizeof(*mh)); 835 836 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 837 offsetof(struct mly_mmbox, mmm_health), 838 sizeof(mly->mly_mmbox->mmm_health), 839 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 840 841 free(mh, M_DEVBUF); 842 return (0); 843 } 844 845 /* 846 * Enable memory mailbox mode. 847 */ 848 static int 849 mly_enable_mmbox(struct mly_softc *mly) 850 { 851 struct mly_cmd_ioctl mci; 852 u_int8_t *sp; 853 u_int64_t tmp; 854 int rv; 855 856 /* Build the ioctl and send it. */ 857 memset(&mci, 0, sizeof(mci)); 858 mci.sub_ioctl = MDACIOCTL_SETMEMORYMAILBOX; 859 860 /* Set buffer addresses. */ 861 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_command); 862 mci.param.setmemorymailbox.command_mailbox_physaddr = htole64(tmp); 863 864 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_status); 865 mci.param.setmemorymailbox.status_mailbox_physaddr = htole64(tmp); 866 867 tmp = mly->mly_mmbox_busaddr + offsetof(struct mly_mmbox, mmm_health); 868 mci.param.setmemorymailbox.health_buffer_physaddr = htole64(tmp); 869 870 /* Set buffer sizes - abuse of data_size field is revolting. */ 871 sp = (u_int8_t *)&mci.data_size; 872 sp[0] = (sizeof(union mly_cmd_packet) * MLY_MMBOX_COMMANDS) >> 10; 873 sp[1] = (sizeof(union mly_status_packet) * MLY_MMBOX_STATUS) >> 10; 874 mci.param.setmemorymailbox.health_buffer_size = 875 sizeof(union mly_health_region) >> 10; 876 877 rv = mly_ioctl(mly, &mci, NULL, 0, NULL, NULL); 878 if (rv) 879 return (rv); 880 881 mly->mly_state |= MLY_STATE_MMBOX_ACTIVE; 882 return (0); 883 } 884 885 /* 886 * Flush all pending I/O from the controller. 887 */ 888 static int 889 mly_flush(struct mly_softc *mly) 890 { 891 struct mly_cmd_ioctl mci; 892 893 /* Build the ioctl */ 894 memset(&mci, 0, sizeof(mci)); 895 mci.sub_ioctl = MDACIOCTL_FLUSHDEVICEDATA; 896 mci.param.deviceoperation.operation_device = 897 MLY_OPDEVICE_PHYSICAL_CONTROLLER; 898 899 /* Pass it off to the controller */ 900 return (mly_ioctl(mly, &mci, NULL, 0, NULL, NULL)); 901 } 902 903 /* 904 * Perform an ioctl command. 905 * 906 * If (data) is not NULL, the command requires data transfer to the 907 * controller. If (*data) is NULL the command requires data transfer from 908 * the controller, and we will allocate a buffer for it. 909 */ 910 static int 911 mly_ioctl(struct mly_softc *mly, struct mly_cmd_ioctl *ioctl, void **data, 912 size_t datasize, void *sense_buffer, 913 size_t *sense_length) 914 { 915 struct mly_ccb *mc; 916 struct mly_cmd_ioctl *mci; 917 u_int8_t status; 918 int rv; 919 920 mc = NULL; 921 if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 922 goto bad; 923 924 /* 925 * Copy the ioctl structure, but save some important fields and then 926 * fixup. 927 */ 928 mci = &mc->mc_packet->ioctl; 929 ioctl->sense_buffer_address = htole64(mci->sense_buffer_address); 930 ioctl->maximum_sense_size = mci->maximum_sense_size; 931 *mci = *ioctl; 932 mci->opcode = MDACMD_IOCTL; 933 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 934 935 /* Handle the data buffer. */ 936 if (data != NULL) { 937 if (*data == NULL) { 938 /* Allocate data buffer */ 939 mc->mc_data = malloc(datasize, M_DEVBUF, M_NOWAIT); 940 mc->mc_flags |= MLY_CCB_DATAIN; 941 } else { 942 mc->mc_data = *data; 943 mc->mc_flags |= MLY_CCB_DATAOUT; 944 } 945 mc->mc_length = datasize; 946 mc->mc_packet->generic.data_size = htole32(datasize); 947 } 948 949 /* Run the command. */ 950 if (datasize > 0) 951 if ((rv = mly_ccb_map(mly, mc)) != 0) 952 goto bad; 953 rv = mly_ccb_poll(mly, mc, 30000); 954 if (datasize > 0) 955 mly_ccb_unmap(mly, mc); 956 if (rv != 0) 957 goto bad; 958 959 /* Clean up and return any data. */ 960 status = mc->mc_status; 961 962 if (status != 0) 963 printf("mly_ioctl: command status %d\n", status); 964 965 if (mc->mc_sense > 0 && sense_buffer != NULL) { 966 memcpy(sense_buffer, mc->mc_packet, mc->mc_sense); 967 *sense_length = mc->mc_sense; 968 goto bad; 969 } 970 971 /* Should we return a data pointer? */ 972 if (data != NULL && *data == NULL) 973 *data = mc->mc_data; 974 975 /* Command completed OK. */ 976 rv = (status != 0 ? EIO : 0); 977 978 bad: 979 if (mc != NULL) { 980 /* Do we need to free a data buffer we allocated? */ 981 if (rv != 0 && mc->mc_data != NULL && *data == NULL) 982 free(mc->mc_data, M_DEVBUF); 983 mly_ccb_free(mly, mc); 984 } 985 986 return (rv); 987 } 988 989 /* 990 * Check for event(s) outstanding in the controller. 991 */ 992 static void 993 mly_check_event(struct mly_softc *mly) 994 { 995 996 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 997 offsetof(struct mly_mmbox, mmm_health), 998 sizeof(mly->mly_mmbox->mmm_health), 999 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1000 1001 /* 1002 * The controller may have updated the health status information, so 1003 * check for it here. Note that the counters are all in host 1004 * memory, so this check is very cheap. Also note that we depend on 1005 * checking on completion 1006 */ 1007 if (le32toh(mly->mly_mmbox->mmm_health.status.change_counter) != 1008 mly->mly_event_change) { 1009 mly->mly_event_change = 1010 le32toh(mly->mly_mmbox->mmm_health.status.change_counter); 1011 mly->mly_event_waiting = 1012 le32toh(mly->mly_mmbox->mmm_health.status.next_event); 1013 1014 /* Wake up anyone that might be interested in this. */ 1015 wakeup(&mly->mly_event_change); 1016 } 1017 1018 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1019 offsetof(struct mly_mmbox, mmm_health), 1020 sizeof(mly->mly_mmbox->mmm_health), 1021 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1022 1023 if (mly->mly_event_counter != mly->mly_event_waiting) 1024 mly_fetch_event(mly); 1025 } 1026 1027 /* 1028 * Fetch one event from the controller. If we fail due to resource 1029 * starvation, we'll be retried the next time a command completes. 1030 */ 1031 static void 1032 mly_fetch_event(struct mly_softc *mly) 1033 { 1034 struct mly_ccb *mc; 1035 struct mly_cmd_ioctl *mci; 1036 int s; 1037 u_int32_t event; 1038 1039 /* Get a command. */ 1040 if (mly_ccb_alloc(mly, &mc)) 1041 return; 1042 1043 /* Set up the data buffer. */ 1044 mc->mc_data = malloc(sizeof(struct mly_event), M_DEVBUF, 1045 M_NOWAIT|M_ZERO); 1046 1047 mc->mc_length = sizeof(struct mly_event); 1048 mc->mc_flags |= MLY_CCB_DATAIN; 1049 mc->mc_complete = mly_complete_event; 1050 1051 /* 1052 * Get an event number to fetch. It's possible that we've raced 1053 * with another context for the last event, in which case there will 1054 * be no more events. 1055 */ 1056 s = splbio(); 1057 if (mly->mly_event_counter == mly->mly_event_waiting) { 1058 splx(s); 1059 free(mc->mc_data, M_DEVBUF); 1060 mly_ccb_free(mly, mc); 1061 return; 1062 } 1063 event = mly->mly_event_counter++; 1064 splx(s); 1065 1066 /* 1067 * Build the ioctl. 1068 * 1069 * At this point we are committed to sending this request, as it 1070 * will be the only one constructed for this particular event 1071 * number. 1072 */ 1073 mci = (struct mly_cmd_ioctl *)&mc->mc_packet->ioctl; 1074 mci->opcode = MDACMD_IOCTL; 1075 mci->data_size = htole32(sizeof(struct mly_event)); 1076 _lto3l(MLY_PHYADDR(0, 0, (event >> 16) & 0xff, (event >> 24) & 0xff), 1077 mci->addr); 1078 mci->timeout = 30 | MLY_TIMEOUT_SECONDS; 1079 mci->sub_ioctl = MDACIOCTL_GETEVENT; 1080 mci->param.getevent.sequence_number_low = htole16(event & 0xffff); 1081 1082 /* 1083 * Submit the command. 1084 */ 1085 if (mly_ccb_map(mly, mc) != 0) 1086 goto bad; 1087 mly_ccb_enqueue(mly, mc); 1088 return; 1089 1090 bad: 1091 printf("%s: couldn't fetch event %u\n", mly->mly_dv.dv_xname, event); 1092 free(mc->mc_data, M_DEVBUF); 1093 mly_ccb_free(mly, mc); 1094 } 1095 1096 /* 1097 * Handle the completion of an event poll. 1098 */ 1099 static void 1100 mly_complete_event(struct mly_softc *mly, struct mly_ccb *mc) 1101 { 1102 struct mly_event *me; 1103 1104 me = (struct mly_event *)mc->mc_data; 1105 mly_ccb_unmap(mly, mc); 1106 mly_ccb_free(mly, mc); 1107 1108 /* If the event was successfully fetched, process it. */ 1109 if (mc->mc_status == SCSI_OK) 1110 mly_process_event(mly, me); 1111 else 1112 printf("%s: unable to fetch event; status = 0x%x\n", 1113 mly->mly_dv.dv_xname, mc->mc_status); 1114 1115 free(me, M_DEVBUF); 1116 1117 /* Check for another event. */ 1118 mly_check_event(mly); 1119 } 1120 1121 /* 1122 * Process a controller event. Called with interupts blocked (i.e., at 1123 * interrupt time). 1124 */ 1125 static void 1126 mly_process_event(struct mly_softc *mly, struct mly_event *me) 1127 { 1128 struct scsipi_sense_data *ssd; 1129 int bus, target, event, class, action; 1130 const char *fp, *tp; 1131 1132 ssd = (struct scsipi_sense_data *)&me->sense[0]; 1133 1134 /* 1135 * Errors can be reported using vendor-unique sense data. In this 1136 * case, the event code will be 0x1c (Request sense data present), 1137 * the sense key will be 0x09 (vendor specific), the MSB of the ASC 1138 * will be set, and the actual event code will be a 16-bit value 1139 * comprised of the ASCQ (low byte) and low seven bits of the ASC 1140 * (low seven bits of the high byte). 1141 */ 1142 if (le32toh(me->code) == 0x1c && 1143 (ssd->flags & SSD_KEY) == SKEY_VENDOR_UNIQUE && 1144 (ssd->add_sense_code & 0x80) != 0) { 1145 event = ((int)(ssd->add_sense_code & ~0x80) << 8) + 1146 ssd->add_sense_code_qual; 1147 } else 1148 event = le32toh(me->code); 1149 1150 /* Look up event, get codes. */ 1151 fp = mly_describe_code(mly_table_event, event); 1152 1153 /* Quiet event? */ 1154 class = fp[0]; 1155 #ifdef notyet 1156 if (isupper(class) && bootverbose) 1157 class = tolower(class); 1158 #endif 1159 1160 /* Get action code, text string. */ 1161 action = fp[1]; 1162 tp = fp + 3; 1163 1164 /* 1165 * Print some information about the event. 1166 * 1167 * This code uses a table derived from the corresponding portion of 1168 * the Linux driver, and thus the parser is very similar. 1169 */ 1170 switch (class) { 1171 case 'p': 1172 /* 1173 * Error on physical drive. 1174 */ 1175 printf("%s: physical device %d:%d %s\n", mly->mly_dv.dv_xname, 1176 me->channel, me->target, tp); 1177 if (action == 'r') 1178 mly->mly_btl[me->channel][me->target].mb_flags |= 1179 MLY_BTL_RESCAN; 1180 break; 1181 1182 case 'l': 1183 case 'm': 1184 /* 1185 * Error on logical unit, or message about logical unit. 1186 */ 1187 bus = MLY_LOGDEV_BUS(mly, me->lun); 1188 target = MLY_LOGDEV_TARGET(mly, me->lun); 1189 printf("%s: logical device %d:%d %s\n", mly->mly_dv.dv_xname, 1190 bus, target, tp); 1191 if (action == 'r') 1192 mly->mly_btl[bus][target].mb_flags |= MLY_BTL_RESCAN; 1193 break; 1194 1195 case 's': 1196 /* 1197 * Report of sense data. 1198 */ 1199 if (((ssd->flags & SSD_KEY) == SKEY_NO_SENSE || 1200 (ssd->flags & SSD_KEY) == SKEY_NOT_READY) && 1201 ssd->add_sense_code == 0x04 && 1202 (ssd->add_sense_code_qual == 0x01 || 1203 ssd->add_sense_code_qual == 0x02)) { 1204 /* Ignore NO_SENSE or NOT_READY in one case */ 1205 break; 1206 } 1207 1208 /* 1209 * XXX Should translate this if SCSIVERBOSE. 1210 */ 1211 printf("%s: physical device %d:%d %s\n", mly->mly_dv.dv_xname, 1212 me->channel, me->target, tp); 1213 printf("%s: sense key %d asc %02x ascq %02x\n", 1214 mly->mly_dv.dv_xname, ssd->flags & SSD_KEY, 1215 ssd->add_sense_code, ssd->add_sense_code_qual); 1216 printf("%s: info %x%x%x%x csi %x%x%x%x\n", 1217 mly->mly_dv.dv_xname, ssd->info[0], ssd->info[1], 1218 ssd->info[2], ssd->info[3], ssd->cmd_spec_info[0], 1219 ssd->cmd_spec_info[1], ssd->cmd_spec_info[2], 1220 ssd->cmd_spec_info[3]); 1221 if (action == 'r') 1222 mly->mly_btl[me->channel][me->target].mb_flags |= 1223 MLY_BTL_RESCAN; 1224 break; 1225 1226 case 'e': 1227 printf("%s: ", mly->mly_dv.dv_xname); 1228 printf(tp, me->target, me->lun); 1229 break; 1230 1231 case 'c': 1232 printf("%s: controller %s\n", mly->mly_dv.dv_xname, tp); 1233 break; 1234 1235 case '?': 1236 printf("%s: %s - %d\n", mly->mly_dv.dv_xname, tp, event); 1237 break; 1238 1239 default: 1240 /* Probably a 'noisy' event being ignored. */ 1241 break; 1242 } 1243 } 1244 1245 /* 1246 * Create the monitoring thread. Called after the standard kernel threads 1247 * have been created. 1248 */ 1249 static void 1250 mly_thread_create(void *cookie) 1251 { 1252 struct mly_softc *mly; 1253 int rv; 1254 1255 mly = cookie; 1256 1257 rv = kthread_create1(mly_thread, mly, &mly->mly_thread, "%s", 1258 mly->mly_dv.dv_xname); 1259 if (rv != 0) 1260 printf("%s: unable to create thread (%d)\n", 1261 mly->mly_dv.dv_xname, rv); 1262 } 1263 1264 /* 1265 * Perform periodic activities. 1266 */ 1267 static void 1268 mly_thread(void *cookie) 1269 { 1270 struct mly_softc *mly; 1271 struct mly_btl *btl; 1272 int s, bus, target, done; 1273 1274 mly = (struct mly_softc *)cookie; 1275 1276 for (;;) { 1277 /* Check for new events. */ 1278 mly_check_event(mly); 1279 1280 /* Re-scan up to 1 device. */ 1281 s = splbio(); 1282 done = 0; 1283 for (bus = 0; bus < mly->mly_nchans && !done; bus++) { 1284 for (target = 0; target < MLY_MAX_TARGETS; target++) { 1285 /* Perform device rescan? */ 1286 btl = &mly->mly_btl[bus][target]; 1287 if ((btl->mb_flags & MLY_BTL_RESCAN) != 0) { 1288 btl->mb_flags ^= MLY_BTL_RESCAN; 1289 mly_scan_btl(mly, bus, target); 1290 done = 1; 1291 break; 1292 } 1293 } 1294 } 1295 splx(s); 1296 1297 /* Sleep for N seconds. */ 1298 tsleep(mly_thread, PWAIT, "mlyzzz", 1299 hz * MLY_PERIODIC_INTERVAL); 1300 } 1301 } 1302 1303 /* 1304 * Submit a command to the controller and poll on completion. Return 1305 * non-zero on timeout. 1306 */ 1307 static int 1308 mly_ccb_poll(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1309 { 1310 int rv; 1311 1312 if ((rv = mly_ccb_submit(mly, mc)) != 0) 1313 return (rv); 1314 1315 for (timo *= 10; timo != 0; timo--) { 1316 if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) 1317 break; 1318 mly_intr(mly); 1319 DELAY(100); 1320 } 1321 1322 return (timo == 0); 1323 } 1324 1325 /* 1326 * Submit a command to the controller and sleep on completion. Return 1327 * non-zero on timeout. 1328 */ 1329 static int 1330 mly_ccb_wait(struct mly_softc *mly, struct mly_ccb *mc, int timo) 1331 { 1332 int rv, s; 1333 1334 mly_ccb_enqueue(mly, mc); 1335 1336 s = splbio(); 1337 if ((mc->mc_flags & MLY_CCB_COMPLETE) != 0) { 1338 splx(s); 1339 return (0); 1340 } 1341 rv = tsleep(mc, PRIBIO, "mlywccb", timo * hz / 1000); 1342 splx(s); 1343 1344 return (rv); 1345 } 1346 1347 /* 1348 * If a CCB is specified, enqueue it. Pull CCBs off the software queue in 1349 * the order that they were enqueued and try to submit their command blocks 1350 * to the controller for execution. 1351 */ 1352 void 1353 mly_ccb_enqueue(struct mly_softc *mly, struct mly_ccb *mc) 1354 { 1355 int s; 1356 1357 s = splbio(); 1358 1359 if (mc != NULL) 1360 SIMPLEQ_INSERT_TAIL(&mly->mly_ccb_queue, mc, mc_link.simpleq); 1361 1362 while ((mc = SIMPLEQ_FIRST(&mly->mly_ccb_queue)) != NULL) { 1363 if (mly_ccb_submit(mly, mc)) 1364 break; 1365 SIMPLEQ_REMOVE_HEAD(&mly->mly_ccb_queue, mc, mc_link.simpleq); 1366 } 1367 1368 splx(s); 1369 } 1370 1371 /* 1372 * Deliver a command to the controller. 1373 */ 1374 static int 1375 mly_ccb_submit(struct mly_softc *mly, struct mly_ccb *mc) 1376 { 1377 union mly_cmd_packet *pkt; 1378 int s, off; 1379 1380 mc->mc_packet->generic.command_id = htole16(mc->mc_slot); 1381 1382 bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1383 mc->mc_packetphys - mly->mly_pkt_busaddr, 1384 sizeof(union mly_cmd_packet), 1385 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1386 1387 s = splbio(); 1388 1389 /* 1390 * Do we have to use the hardware mailbox? 1391 */ 1392 if ((mly->mly_state & MLY_STATE_MMBOX_ACTIVE) == 0) { 1393 /* 1394 * Check to see if the controller is ready for us. 1395 */ 1396 if (mly_idbr_true(mly, MLY_HM_CMDSENT)) { 1397 splx(s); 1398 return (EBUSY); 1399 } 1400 1401 /* 1402 * It's ready, send the command. 1403 */ 1404 mly_outl(mly, mly->mly_cmd_mailbox, 1405 (u_int64_t)mc->mc_packetphys & 0xffffffff); 1406 mly_outl(mly, mly->mly_cmd_mailbox + 4, 1407 (u_int64_t)mc->mc_packetphys >> 32); 1408 mly_outb(mly, mly->mly_idbr, MLY_HM_CMDSENT); 1409 } else { 1410 pkt = &mly->mly_mmbox->mmm_command[mly->mly_mmbox_cmd_idx]; 1411 off = (caddr_t)pkt - (caddr_t)mly->mly_mmbox; 1412 1413 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1414 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1415 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1416 1417 /* Check to see if the next index is free yet. */ 1418 if (pkt->mmbox.flag != 0) { 1419 splx(s); 1420 return (EBUSY); 1421 } 1422 1423 /* Copy in new command */ 1424 memcpy(pkt->mmbox.data, mc->mc_packet->mmbox.data, 1425 sizeof(pkt->mmbox.data)); 1426 1427 /* Copy flag last. */ 1428 pkt->mmbox.flag = mc->mc_packet->mmbox.flag; 1429 1430 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1431 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1432 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1433 1434 /* Signal controller and update index. */ 1435 mly_outb(mly, mly->mly_idbr, MLY_AM_CMDSENT); 1436 mly->mly_mmbox_cmd_idx = 1437 (mly->mly_mmbox_cmd_idx + 1) % MLY_MMBOX_COMMANDS; 1438 } 1439 1440 splx(s); 1441 return (0); 1442 } 1443 1444 /* 1445 * Pick up completed commands from the controller and handle accordingly. 1446 */ 1447 int 1448 mly_intr(void *cookie) 1449 { 1450 struct mly_ccb *mc; 1451 union mly_status_packet *sp; 1452 u_int16_t slot; 1453 int forus, off; 1454 struct mly_softc *mly; 1455 1456 mly = cookie; 1457 forus = 0; 1458 1459 /* 1460 * Pick up hardware-mailbox commands. 1461 */ 1462 if (mly_odbr_true(mly, MLY_HM_STSREADY)) { 1463 slot = mly_inw(mly, mly->mly_status_mailbox); 1464 1465 if (slot < MLY_SLOT_MAX) { 1466 mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1467 mc->mc_status = 1468 mly_inb(mly, mly->mly_status_mailbox + 2); 1469 mc->mc_sense = 1470 mly_inb(mly, mly->mly_status_mailbox + 3); 1471 mc->mc_resid = 1472 mly_inl(mly, mly->mly_status_mailbox + 4); 1473 1474 mly_ccb_complete(mly, mc); 1475 } else { 1476 /* Slot 0xffff may mean "extremely bogus command". */ 1477 printf("%s: got HM completion for illegal slot %u\n", 1478 mly->mly_dv.dv_xname, slot); 1479 } 1480 1481 /* Unconditionally acknowledge status. */ 1482 mly_outb(mly, mly->mly_odbr, MLY_HM_STSREADY); 1483 mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 1484 forus = 1; 1485 } 1486 1487 /* 1488 * Pick up memory-mailbox commands. 1489 */ 1490 if (mly_odbr_true(mly, MLY_AM_STSREADY)) { 1491 for (;;) { 1492 sp = &mly->mly_mmbox->mmm_status[mly->mly_mmbox_sts_idx]; 1493 off = (caddr_t)sp - (caddr_t)mly->mly_mmbox; 1494 1495 bus_dmamap_sync(mly->mly_dmat, mly->mly_mmbox_dmamap, 1496 off, sizeof(mly->mly_mmbox->mmm_command[0]), 1497 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1498 1499 /* Check for more status. */ 1500 if (sp->mmbox.flag == 0) 1501 break; 1502 1503 /* Get slot number. */ 1504 slot = le16toh(sp->status.command_id); 1505 if (slot < MLY_SLOT_MAX) { 1506 mc = mly->mly_ccbs + (slot - MLY_SLOT_START); 1507 mc->mc_status = sp->status.status; 1508 mc->mc_sense = sp->status.sense_length; 1509 mc->mc_resid = le32toh(sp->status.residue); 1510 mly_ccb_complete(mly, mc); 1511 } else { 1512 /* 1513 * Slot 0xffff may mean "extremely bogus 1514 * command". 1515 */ 1516 printf("%s: got AM completion for illegal " 1517 "slot %u at %d\n", mly->mly_dv.dv_xname, 1518 slot, mly->mly_mmbox_sts_idx); 1519 } 1520 1521 /* Clear and move to next index. */ 1522 sp->mmbox.flag = 0; 1523 mly->mly_mmbox_sts_idx = 1524 (mly->mly_mmbox_sts_idx + 1) % MLY_MMBOX_STATUS; 1525 } 1526 1527 /* Acknowledge that we have collected status value(s). */ 1528 mly_outb(mly, mly->mly_odbr, MLY_AM_STSREADY); 1529 forus = 1; 1530 } 1531 1532 /* 1533 * Run the queue. 1534 */ 1535 if (forus && SIMPLEQ_FIRST(&mly->mly_ccb_queue) != NULL) 1536 mly_ccb_enqueue(mly, NULL); 1537 1538 return (forus); 1539 } 1540 1541 /* 1542 * Process completed commands 1543 */ 1544 static void 1545 mly_ccb_complete(struct mly_softc *mly, struct mly_ccb *mc) 1546 { 1547 void (*complete)(struct mly_softc *, struct mly_ccb *); 1548 1549 bus_dmamap_sync(mly->mly_dmat, mly->mly_pkt_dmamap, 1550 mc->mc_packetphys - mly->mly_pkt_busaddr, 1551 sizeof(union mly_cmd_packet), 1552 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1553 1554 complete = mc->mc_complete; 1555 mc->mc_flags |= MLY_CCB_COMPLETE; 1556 1557 /* 1558 * Call completion handler or wake up sleeping consumer. 1559 */ 1560 if (complete != NULL) 1561 (*complete)(mly, mc); 1562 else 1563 wakeup(mc); 1564 } 1565 1566 /* 1567 * Allocate a command. 1568 */ 1569 int 1570 mly_ccb_alloc(struct mly_softc *mly, struct mly_ccb **mcp) 1571 { 1572 struct mly_ccb *mc; 1573 int s; 1574 1575 s = splbio(); 1576 mc = SLIST_FIRST(&mly->mly_ccb_free); 1577 if (mc != NULL) 1578 SLIST_REMOVE_HEAD(&mly->mly_ccb_free, mc_link.slist); 1579 splx(s); 1580 1581 *mcp = mc; 1582 return (mc == NULL ? EAGAIN : 0); 1583 } 1584 1585 /* 1586 * Release a command back to the freelist. 1587 */ 1588 void 1589 mly_ccb_free(struct mly_softc *mly, struct mly_ccb *mc) 1590 { 1591 int s; 1592 1593 /* 1594 * Fill in parts of the command that may cause confusion if a 1595 * consumer doesn't when we are later allocated. 1596 */ 1597 mc->mc_data = NULL; 1598 mc->mc_flags = 0; 1599 mc->mc_complete = NULL; 1600 mc->mc_private = NULL; 1601 mc->mc_packet->generic.command_control = 0; 1602 1603 /* 1604 * By default, we set up to overwrite the command packet with sense 1605 * information. 1606 */ 1607 mc->mc_packet->generic.sense_buffer_address = 1608 htole64(mc->mc_packetphys); 1609 mc->mc_packet->generic.maximum_sense_size = 1610 sizeof(union mly_cmd_packet); 1611 1612 s = splbio(); 1613 SLIST_INSERT_HEAD(&mly->mly_ccb_free, mc, mc_link.slist); 1614 splx(s); 1615 } 1616 1617 /* 1618 * Allocate and initialise command and packet structures. 1619 * 1620 * If the controller supports fewer than MLY_MAX_CCBS commands, limit our 1621 * allocation to that number. If we don't yet know how many commands the 1622 * controller supports, allocate a very small set (suitable for initialisation 1623 * purposes only). 1624 */ 1625 static int 1626 mly_alloc_ccbs(struct mly_softc *mly) 1627 { 1628 struct mly_ccb *mc; 1629 int i, rv; 1630 1631 if (mly->mly_controllerinfo == NULL) 1632 mly->mly_ncmds = MLY_CCBS_RESV; 1633 else { 1634 i = le16toh(mly->mly_controllerinfo->maximum_parallel_commands); 1635 mly->mly_ncmds = min(MLY_MAX_CCBS, i); 1636 } 1637 1638 /* 1639 * Allocate enough space for all the command packets in one chunk 1640 * and map them permanently into controller-visible space. 1641 */ 1642 rv = mly_dmamem_alloc(mly, 1643 mly->mly_ncmds * sizeof(union mly_cmd_packet), 1644 &mly->mly_pkt_dmamap, (caddr_t *)&mly->mly_pkt, 1645 &mly->mly_pkt_busaddr, &mly->mly_pkt_seg); 1646 if (rv) 1647 return (rv); 1648 1649 mly->mly_ccbs = malloc(sizeof(struct mly_ccb) * mly->mly_ncmds, 1650 M_DEVBUF, M_NOWAIT|M_ZERO); 1651 1652 for (i = 0; i < mly->mly_ncmds; i++) { 1653 mc = mly->mly_ccbs + i; 1654 mc->mc_slot = MLY_SLOT_START + i; 1655 mc->mc_packet = mly->mly_pkt + i; 1656 mc->mc_packetphys = mly->mly_pkt_busaddr + 1657 (i * sizeof(union mly_cmd_packet)); 1658 1659 rv = bus_dmamap_create(mly->mly_dmat, MLY_MAX_XFER, 1660 MLY_MAX_SEGS, MLY_MAX_XFER, 0, 1661 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 1662 &mc->mc_datamap); 1663 if (rv) { 1664 mly_release_ccbs(mly); 1665 return (rv); 1666 } 1667 1668 mly_ccb_free(mly, mc); 1669 } 1670 1671 return (0); 1672 } 1673 1674 /* 1675 * Free all the storage held by commands. 1676 * 1677 * Must be called with all commands on the free list. 1678 */ 1679 static void 1680 mly_release_ccbs(struct mly_softc *mly) 1681 { 1682 struct mly_ccb *mc; 1683 1684 /* Throw away command buffer DMA maps. */ 1685 while (mly_ccb_alloc(mly, &mc) == 0) 1686 bus_dmamap_destroy(mly->mly_dmat, mc->mc_datamap); 1687 1688 /* Release CCB storage. */ 1689 free(mly->mly_ccbs, M_DEVBUF); 1690 1691 /* Release the packet storage. */ 1692 mly_dmamem_free(mly, mly->mly_ncmds * sizeof(union mly_cmd_packet), 1693 mly->mly_pkt_dmamap, (caddr_t)mly->mly_pkt, &mly->mly_pkt_seg); 1694 } 1695 1696 /* 1697 * Map a command into controller-visible space. 1698 */ 1699 static int 1700 mly_ccb_map(struct mly_softc *mly, struct mly_ccb *mc) 1701 { 1702 struct mly_cmd_generic *gen; 1703 struct mly_sg_entry *sg; 1704 bus_dma_segment_t *ds; 1705 int flg, nseg, rv; 1706 1707 #ifdef DIAGNOSTIC 1708 /* Don't map more than once. */ 1709 if ((mc->mc_flags & MLY_CCB_MAPPED) != 0) 1710 panic("mly_ccb_map: already mapped"); 1711 mc->mc_flags |= MLY_CCB_MAPPED; 1712 1713 /* Does the command have a data buffer? */ 1714 if (mc->mc_data == NULL) 1715 panic("mly_ccb_map: no data buffer"); 1716 #endif 1717 1718 rv = bus_dmamap_load(mly->mly_dmat, mc->mc_datamap, mc->mc_data, 1719 mc->mc_length, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING | 1720 ((mc->mc_flags & MLY_CCB_DATAIN) != 0 ? 1721 BUS_DMA_READ : BUS_DMA_WRITE)); 1722 if (rv != 0) 1723 return (rv); 1724 1725 gen = &mc->mc_packet->generic; 1726 1727 /* 1728 * Can we use the transfer structure directly? 1729 */ 1730 if ((nseg = mc->mc_datamap->dm_nsegs) <= 2) { 1731 mc->mc_sgoff = -1; 1732 sg = &gen->transfer.direct.sg[0]; 1733 } else { 1734 mc->mc_sgoff = (mc->mc_slot - MLY_SLOT_START) * 1735 MLY_MAX_SEGS; 1736 sg = mly->mly_sg + mc->mc_sgoff; 1737 gen->command_control |= MLY_CMDCTL_EXTENDED_SG_TABLE; 1738 gen->transfer.indirect.entries[0] = htole16(nseg); 1739 gen->transfer.indirect.table_physaddr[0] = 1740 htole64(mly->mly_sg_busaddr + 1741 (mc->mc_sgoff * sizeof(struct mly_sg_entry))); 1742 } 1743 1744 /* 1745 * Fill the S/G table. 1746 */ 1747 for (ds = mc->mc_datamap->dm_segs; nseg != 0; nseg--, sg++, ds++) { 1748 sg->physaddr = htole64(ds->ds_addr); 1749 sg->length = htole64(ds->ds_len); 1750 } 1751 1752 /* 1753 * Sync up the data map. 1754 */ 1755 if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1756 flg = BUS_DMASYNC_PREREAD; 1757 else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ { 1758 gen->command_control |= MLY_CMDCTL_DATA_DIRECTION; 1759 flg = BUS_DMASYNC_PREWRITE; 1760 } 1761 1762 bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1763 1764 /* 1765 * Sync up the chained S/G table, if we're using one. 1766 */ 1767 if (mc->mc_sgoff == -1) 1768 return (0); 1769 1770 bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1771 MLY_SGL_SIZE, BUS_DMASYNC_PREWRITE); 1772 1773 return (0); 1774 } 1775 1776 /* 1777 * Unmap a command from controller-visible space. 1778 */ 1779 static void 1780 mly_ccb_unmap(struct mly_softc *mly, struct mly_ccb *mc) 1781 { 1782 int flg; 1783 1784 #ifdef DIAGNOSTIC 1785 if ((mc->mc_flags & MLY_CCB_MAPPED) == 0) 1786 panic("mly_ccb_unmap: not mapped"); 1787 mc->mc_flags &= ~MLY_CCB_MAPPED; 1788 #endif 1789 1790 if ((mc->mc_flags & MLY_CCB_DATAIN) != 0) 1791 flg = BUS_DMASYNC_POSTREAD; 1792 else /* if ((mc->mc_flags & MLY_CCB_DATAOUT) != 0) */ 1793 flg = BUS_DMASYNC_POSTWRITE; 1794 1795 bus_dmamap_sync(mly->mly_dmat, mc->mc_datamap, 0, mc->mc_length, flg); 1796 bus_dmamap_unload(mly->mly_dmat, mc->mc_datamap); 1797 1798 if (mc->mc_sgoff == -1) 1799 return; 1800 1801 bus_dmamap_sync(mly->mly_dmat, mly->mly_sg_dmamap, mc->mc_sgoff, 1802 MLY_SGL_SIZE, BUS_DMASYNC_POSTWRITE); 1803 } 1804 1805 /* 1806 * Adjust the size of each I/O before it passes to the SCSI layer. 1807 */ 1808 static void 1809 mly_scsipi_minphys(struct buf *bp) 1810 { 1811 1812 if (bp->b_bcount > MLY_MAX_XFER) 1813 bp->b_bcount = MLY_MAX_XFER; 1814 minphys(bp); 1815 } 1816 1817 /* 1818 * Start a SCSI command. 1819 */ 1820 static void 1821 mly_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 1822 void *arg) 1823 { 1824 struct mly_ccb *mc; 1825 struct mly_cmd_scsi_small *ss; 1826 struct scsipi_xfer *xs; 1827 struct scsipi_periph *periph; 1828 struct mly_softc *mly; 1829 struct mly_btl *btl; 1830 int s, tmp; 1831 1832 mly = (void *)chan->chan_adapter->adapt_dev; 1833 1834 switch (req) { 1835 case ADAPTER_REQ_RUN_XFER: 1836 xs = arg; 1837 periph = xs->xs_periph; 1838 btl = &mly->mly_btl[chan->chan_channel][periph->periph_target]; 1839 s = splbio(); 1840 tmp = btl->mb_flags; 1841 splx(s); 1842 1843 /* 1844 * Check for I/O attempt to a protected or non-existant 1845 * device. 1846 */ 1847 if ((tmp & MLY_BTL_PROTECTED) != 0) { 1848 xs->error = XS_SELTIMEOUT; 1849 scsipi_done(xs); 1850 break; 1851 } 1852 1853 #ifdef DIAGNOSTIC 1854 /* XXX Increase if/when we support large SCSI commands. */ 1855 if (xs->cmdlen > MLY_CMD_SCSI_SMALL_CDB) { 1856 printf("%s: cmd too large\n", mly->mly_dv.dv_xname); 1857 xs->error = XS_DRIVER_STUFFUP; 1858 scsipi_done(xs); 1859 break; 1860 } 1861 #endif 1862 1863 if (mly_ccb_alloc(mly, &mc)) { 1864 xs->error = XS_RESOURCE_SHORTAGE; 1865 scsipi_done(xs); 1866 break; 1867 } 1868 1869 /* Build the command. */ 1870 mc->mc_data = xs->data; 1871 mc->mc_length = xs->datalen; 1872 mc->mc_complete = mly_scsipi_complete; 1873 mc->mc_private = xs; 1874 1875 /* Build the packet for the controller. */ 1876 ss = &mc->mc_packet->scsi_small; 1877 ss->opcode = MDACMD_SCSI; 1878 #ifdef notdef 1879 /* 1880 * XXX FreeBSD does this, but it doesn't fix anything, 1881 * XXX and appears potentially harmful. 1882 */ 1883 ss->command_control |= MLY_CMDCTL_DISABLE_DISCONNECT; 1884 #endif 1885 1886 ss->data_size = htole32(xs->datalen); 1887 _lto3l(MLY_PHYADDR(0, chan->chan_channel, 1888 periph->periph_target, periph->periph_lun), ss->addr); 1889 1890 if (xs->timeout < 60 * 1000) 1891 ss->timeout = xs->timeout / 1000 | 1892 MLY_TIMEOUT_SECONDS; 1893 else if (xs->timeout < 60 * 60 * 1000) 1894 ss->timeout = xs->timeout / (60 * 1000) | 1895 MLY_TIMEOUT_MINUTES; 1896 else 1897 ss->timeout = xs->timeout / (60 * 60 * 1000) | 1898 MLY_TIMEOUT_HOURS; 1899 1900 ss->maximum_sense_size = sizeof(xs->sense); 1901 ss->cdb_length = xs->cmdlen; 1902 memcpy(ss->cdb, xs->cmd, xs->cmdlen); 1903 1904 if (mc->mc_length != 0) { 1905 if ((xs->xs_control & XS_CTL_DATA_OUT) != 0) 1906 mc->mc_flags |= MLY_CCB_DATAOUT; 1907 else /* if ((xs->xs_control & XS_CTL_DATA_IN) != 0) */ 1908 mc->mc_flags |= MLY_CCB_DATAIN; 1909 1910 if (mly_ccb_map(mly, mc) != 0) { 1911 xs->error = XS_DRIVER_STUFFUP; 1912 mly_ccb_free(mly, mc); 1913 scsipi_done(xs); 1914 break; 1915 } 1916 } 1917 1918 /* 1919 * Give the command to the controller. 1920 */ 1921 if ((xs->xs_control & XS_CTL_POLL) != 0) { 1922 if (mly_ccb_poll(mly, mc, xs->timeout + 5000)) { 1923 xs->error = XS_REQUEUE; 1924 if (mc->mc_length != 0) 1925 mly_ccb_unmap(mly, mc); 1926 mly_ccb_free(mly, mc); 1927 scsipi_done(xs); 1928 } 1929 } else 1930 mly_ccb_enqueue(mly, mc); 1931 1932 break; 1933 1934 case ADAPTER_REQ_GROW_RESOURCES: 1935 /* 1936 * Not supported. 1937 */ 1938 break; 1939 1940 case ADAPTER_REQ_SET_XFER_MODE: 1941 /* 1942 * We can't change the transfer mode, but at least let 1943 * scsipi know what the adapter has negotiated. 1944 */ 1945 mly_get_xfer_mode(mly, chan->chan_channel, arg); 1946 break; 1947 } 1948 } 1949 1950 /* 1951 * Handle completion of a SCSI command. 1952 */ 1953 static void 1954 mly_scsipi_complete(struct mly_softc *mly, struct mly_ccb *mc) 1955 { 1956 struct scsipi_xfer *xs; 1957 struct scsipi_channel *chan; 1958 struct scsipi_inquiry_data *inq; 1959 struct mly_btl *btl; 1960 int target, sl, s; 1961 const char *p; 1962 1963 xs = mc->mc_private; 1964 xs->status = mc->mc_status; 1965 1966 /* 1967 * XXX The `resid' value as returned by the controller appears to be 1968 * bogus, so we always set it to zero. Is it perhaps the transfer 1969 * count? 1970 */ 1971 xs->resid = 0; /* mc->mc_resid; */ 1972 1973 if (mc->mc_length != 0) 1974 mly_ccb_unmap(mly, mc); 1975 1976 switch (mc->mc_status) { 1977 case SCSI_OK: 1978 /* 1979 * In order to report logical device type and status, we 1980 * overwrite the result of the INQUIRY command to logical 1981 * devices. 1982 */ 1983 if (xs->cmd->opcode == INQUIRY) { 1984 chan = xs->xs_periph->periph_channel; 1985 target = xs->xs_periph->periph_target; 1986 btl = &mly->mly_btl[chan->chan_channel][target]; 1987 1988 s = splbio(); 1989 if ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) { 1990 inq = (struct scsipi_inquiry_data *)xs->data; 1991 mly_padstr(inq->vendor, "MYLEX", 8); 1992 p = mly_describe_code(mly_table_device_type, 1993 btl->mb_type); 1994 mly_padstr(inq->product, p, 16); 1995 p = mly_describe_code(mly_table_device_state, 1996 btl->mb_state); 1997 mly_padstr(inq->revision, p, 4); 1998 } 1999 splx(s); 2000 } 2001 2002 xs->error = XS_NOERROR; 2003 break; 2004 2005 case SCSI_CHECK: 2006 sl = mc->mc_sense; 2007 if (sl > sizeof(xs->sense.scsi_sense)) 2008 sl = sizeof(xs->sense.scsi_sense); 2009 memcpy(&xs->sense.scsi_sense, mc->mc_packet, sl); 2010 xs->error = XS_SENSE; 2011 break; 2012 2013 case SCSI_BUSY: 2014 case SCSI_QUEUE_FULL: 2015 xs->error = XS_BUSY; 2016 break; 2017 2018 default: 2019 printf("%s: unknown SCSI status 0x%x\n", 2020 mly->mly_dv.dv_xname, xs->status); 2021 xs->error = XS_DRIVER_STUFFUP; 2022 break; 2023 } 2024 2025 mly_ccb_free(mly, mc); 2026 scsipi_done(xs); 2027 } 2028 2029 /* 2030 * Notify scsipi about a target's transfer mode. 2031 */ 2032 static void 2033 mly_get_xfer_mode(struct mly_softc *mly, int bus, struct scsipi_xfer_mode *xm) 2034 { 2035 struct mly_btl *btl; 2036 int s; 2037 2038 btl = &mly->mly_btl[bus][xm->xm_target]; 2039 xm->xm_mode = 0; 2040 2041 s = splbio(); 2042 2043 if ((btl->mb_flags & MLY_BTL_PHYSICAL) != 0) { 2044 if (btl->mb_speed == 0) { 2045 xm->xm_period = 0; 2046 xm->xm_offset = 0; 2047 } else { 2048 xm->xm_period = 12; /* XXX */ 2049 xm->xm_offset = 8; /* XXX */ 2050 xm->xm_mode |= PERIPH_CAP_SYNC; /* XXX */ 2051 } 2052 2053 switch (btl->mb_width) { 2054 case 32: 2055 xm->xm_mode = PERIPH_CAP_WIDE32; 2056 break; 2057 case 16: 2058 xm->xm_mode = PERIPH_CAP_WIDE16; 2059 break; 2060 default: 2061 xm->xm_mode = 0; 2062 break; 2063 } 2064 } else /* ((btl->mb_flags & MLY_BTL_LOGICAL) != 0) */ { 2065 xm->xm_mode = PERIPH_CAP_WIDE16 | PERIPH_CAP_SYNC; 2066 xm->xm_period = 12; 2067 xm->xm_offset = 8; 2068 } 2069 2070 if ((btl->mb_flags & MLY_BTL_TQING) != 0) 2071 xm->xm_mode |= PERIPH_CAP_TQING; 2072 2073 splx(s); 2074 2075 scsipi_async_event(&mly->mly_chans[bus], ASYNC_EVENT_XFER_MODE, xm); 2076 } 2077 2078 /* 2079 * ioctl hook; used here only to initiate low-level rescans. 2080 */ 2081 static int 2082 mly_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, caddr_t data, 2083 int flag, struct proc *p) 2084 { 2085 struct mly_softc *mly; 2086 int rv; 2087 2088 mly = (struct mly_softc *)chan->chan_adapter->adapt_dev; 2089 2090 switch (cmd) { 2091 case SCBUSIOLLSCAN: 2092 mly_scan_channel(mly, chan->chan_channel); 2093 rv = 0; 2094 break; 2095 default: 2096 rv = ENOTTY; 2097 break; 2098 } 2099 2100 return (rv); 2101 } 2102 2103 /* 2104 * Handshake with the firmware while the card is being initialised. 2105 */ 2106 static int 2107 mly_fwhandshake(struct mly_softc *mly) 2108 { 2109 u_int8_t error, param0, param1; 2110 int spinup; 2111 2112 spinup = 0; 2113 2114 /* Set HM_STSACK and let the firmware initialise. */ 2115 mly_outb(mly, mly->mly_idbr, MLY_HM_STSACK); 2116 DELAY(1000); /* too short? */ 2117 2118 /* If HM_STSACK is still true, the controller is initialising. */ 2119 if (!mly_idbr_true(mly, MLY_HM_STSACK)) 2120 return (0); 2121 2122 printf("%s: controller initialisation started\n", 2123 mly->mly_dv.dv_xname); 2124 2125 /* 2126 * Spin waiting for initialisation to finish, or for a message to be 2127 * delivered. 2128 */ 2129 while (mly_idbr_true(mly, MLY_HM_STSACK)) { 2130 /* Check for a message */ 2131 if (!mly_error_valid(mly)) 2132 continue; 2133 2134 error = mly_inb(mly, mly->mly_error_status) & ~MLY_MSG_EMPTY; 2135 param0 = mly_inb(mly, mly->mly_cmd_mailbox); 2136 param1 = mly_inb(mly, mly->mly_cmd_mailbox + 1); 2137 2138 switch (error) { 2139 case MLY_MSG_SPINUP: 2140 if (!spinup) { 2141 printf("%s: drive spinup in progress\n", 2142 mly->mly_dv.dv_xname); 2143 spinup = 1; 2144 } 2145 break; 2146 2147 case MLY_MSG_RACE_RECOVERY_FAIL: 2148 printf("%s: mirror race recovery failed - \n", 2149 mly->mly_dv.dv_xname); 2150 printf("%s: one or more drives offline\n", 2151 mly->mly_dv.dv_xname); 2152 break; 2153 2154 case MLY_MSG_RACE_IN_PROGRESS: 2155 printf("%s: mirror race recovery in progress\n", 2156 mly->mly_dv.dv_xname); 2157 break; 2158 2159 case MLY_MSG_RACE_ON_CRITICAL: 2160 printf("%s: mirror race recovery on critical drive\n", 2161 mly->mly_dv.dv_xname); 2162 break; 2163 2164 case MLY_MSG_PARITY_ERROR: 2165 printf("%s: FATAL MEMORY PARITY ERROR\n", 2166 mly->mly_dv.dv_xname); 2167 return (ENXIO); 2168 2169 default: 2170 printf("%s: unknown initialisation code 0x%x\n", 2171 mly->mly_dv.dv_xname, error); 2172 break; 2173 } 2174 } 2175 2176 return (0); 2177 } 2178 2179 /* 2180 * Space-fill a character string 2181 */ 2182 static void 2183 mly_padstr(char *dst, const char *src, int len) 2184 { 2185 2186 while (len-- > 0) { 2187 if (*src != '\0') 2188 *dst++ = *src++; 2189 else 2190 *dst++ = ' '; 2191 } 2192 } 2193 2194 /* 2195 * Allocate DMA safe memory. 2196 */ 2197 static int 2198 mly_dmamem_alloc(struct mly_softc *mly, int size, bus_dmamap_t *dmamap, 2199 caddr_t *kva, bus_addr_t *paddr, bus_dma_segment_t *seg) 2200 { 2201 int rseg, rv, state; 2202 2203 state = 0; 2204 2205 if ((rv = bus_dmamem_alloc(mly->mly_dmat, size, NBPG, 0, 2206 seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 2207 printf("%s: dmamem_alloc = %d\n", mly->mly_dv.dv_xname, rv); 2208 goto bad; 2209 } 2210 2211 state++; 2212 2213 if ((rv = bus_dmamem_map(mly->mly_dmat, seg, 1, size, kva, 2214 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 2215 printf("%s: dmamem_map = %d\n", mly->mly_dv.dv_xname, rv); 2216 goto bad; 2217 } 2218 2219 state++; 2220 2221 if ((rv = bus_dmamap_create(mly->mly_dmat, size, size, 1, 0, 2222 BUS_DMA_NOWAIT, dmamap)) != 0) { 2223 printf("%s: dmamap_create = %d\n", mly->mly_dv.dv_xname, rv); 2224 goto bad; 2225 } 2226 2227 state++; 2228 2229 if ((rv = bus_dmamap_load(mly->mly_dmat, *dmamap, *kva, size, 2230 NULL, BUS_DMA_NOWAIT)) != 0) { 2231 printf("%s: dmamap_load = %d\n", mly->mly_dv.dv_xname, rv); 2232 goto bad; 2233 } 2234 2235 *paddr = (*dmamap)->dm_segs[0].ds_addr; 2236 memset(*kva, 0, size); 2237 return (0); 2238 2239 bad: 2240 if (state > 2) 2241 bus_dmamap_destroy(mly->mly_dmat, *dmamap); 2242 if (state > 1) 2243 bus_dmamem_unmap(mly->mly_dmat, *kva, size); 2244 if (state > 0) 2245 bus_dmamem_free(mly->mly_dmat, seg, 1); 2246 2247 return (rv); 2248 } 2249 2250 /* 2251 * Free DMA safe memory. 2252 */ 2253 static void 2254 mly_dmamem_free(struct mly_softc *mly, int size, bus_dmamap_t dmamap, 2255 caddr_t kva, bus_dma_segment_t *seg) 2256 { 2257 2258 bus_dmamap_unload(mly->mly_dmat, dmamap); 2259 bus_dmamap_destroy(mly->mly_dmat, dmamap); 2260 bus_dmamem_unmap(mly->mly_dmat, kva, size); 2261 bus_dmamem_free(mly->mly_dmat, seg, 1); 2262 } 2263 2264 2265 /* 2266 * Accept an open operation on the control device. 2267 */ 2268 int 2269 mlyopen(dev_t dev, int flag, int mode, struct proc *p) 2270 { 2271 struct mly_softc *mly; 2272 2273 if ((mly = device_lookup(&mly_cd, minor(dev))) == NULL) 2274 return (ENXIO); 2275 if ((mly->mly_state & MLY_STATE_INITOK) == 0) 2276 return (ENXIO); 2277 if ((mly->mly_state & MLY_STATE_OPEN) != 0) 2278 return (EBUSY); 2279 2280 mly->mly_state |= MLY_STATE_OPEN; 2281 return (0); 2282 } 2283 2284 /* 2285 * Accept the last close on the control device. 2286 */ 2287 int 2288 mlyclose(dev_t dev, int flag, int mode, struct proc *p) 2289 { 2290 struct mly_softc *mly; 2291 2292 mly = device_lookup(&mly_cd, minor(dev)); 2293 mly->mly_state &= ~MLY_STATE_OPEN; 2294 return (0); 2295 } 2296 2297 /* 2298 * Handle control operations. 2299 */ 2300 int 2301 mlyioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 2302 { 2303 struct mly_softc *mly; 2304 int rv; 2305 2306 if (securelevel >= 2) 2307 return (EPERM); 2308 2309 mly = device_lookup(&mly_cd, minor(dev)); 2310 2311 switch (cmd) { 2312 case MLYIO_COMMAND: 2313 rv = mly_user_command(mly, (void *)data); 2314 break; 2315 case MLYIO_HEALTH: 2316 rv = mly_user_health(mly, (void *)data); 2317 break; 2318 default: 2319 rv = ENOTTY; 2320 break; 2321 } 2322 2323 return (rv); 2324 } 2325 2326 /* 2327 * Execute a command passed in from userspace. 2328 * 2329 * The control structure contains the actual command for the controller, as 2330 * well as the user-space data pointer and data size, and an optional sense 2331 * buffer size/pointer. On completion, the data size is adjusted to the 2332 * command residual, and the sense buffer size to the size of the returned 2333 * sense data. 2334 */ 2335 static int 2336 mly_user_command(struct mly_softc *mly, struct mly_user_command *uc) 2337 { 2338 struct mly_ccb *mc; 2339 int rv, mapped; 2340 2341 if ((rv = mly_ccb_alloc(mly, &mc)) != 0) 2342 return (rv); 2343 2344 mapped = 0; 2345 mc->mc_data = NULL; 2346 2347 /* 2348 * Handle data size/direction. 2349 */ 2350 if ((mc->mc_length = abs(uc->DataTransferLength)) != 0) { 2351 if (mc->mc_length > MAXPHYS) { 2352 rv = EINVAL; 2353 goto out; 2354 } 2355 2356 mc->mc_data = malloc(mc->mc_length, M_DEVBUF, M_WAITOK); 2357 if (mc->mc_data == NULL) { 2358 rv = ENOMEM; 2359 goto out; 2360 } 2361 2362 if (uc->DataTransferLength > 0) { 2363 mc->mc_flags |= MLY_CCB_DATAIN; 2364 memset(mc->mc_data, 0, mc->mc_length); 2365 } 2366 2367 if (uc->DataTransferLength < 0) { 2368 mc->mc_flags |= MLY_CCB_DATAOUT; 2369 rv = copyin(uc->DataTransferBuffer, mc->mc_data, 2370 mc->mc_length); 2371 if (rv != 0) 2372 goto out; 2373 } 2374 2375 if ((rv = mly_ccb_map(mly, mc)) != 0) 2376 goto out; 2377 mapped = 1; 2378 } 2379 2380 /* Copy in the command and execute it. */ 2381 memcpy(mc->mc_packet, &uc->CommandMailbox, sizeof(uc->CommandMailbox)); 2382 2383 if ((rv = mly_ccb_wait(mly, mc, 60000)) != 0) 2384 goto out; 2385 2386 /* Return the data to userspace. */ 2387 if (uc->DataTransferLength > 0) { 2388 rv = copyout(mc->mc_data, uc->DataTransferBuffer, 2389 mc->mc_length); 2390 if (rv != 0) 2391 goto out; 2392 } 2393 2394 /* Return the sense buffer to userspace. */ 2395 if (uc->RequestSenseLength > 0 && mc->mc_sense > 0) { 2396 rv = copyout(mc->mc_packet, uc->RequestSenseBuffer, 2397 min(uc->RequestSenseLength, mc->mc_sense)); 2398 if (rv != 0) 2399 goto out; 2400 } 2401 2402 /* Return command results to userspace (caller will copy out). */ 2403 uc->DataTransferLength = mc->mc_resid; 2404 uc->RequestSenseLength = min(uc->RequestSenseLength, mc->mc_sense); 2405 uc->CommandStatus = mc->mc_status; 2406 rv = 0; 2407 2408 out: 2409 if (mapped) 2410 mly_ccb_unmap(mly, mc); 2411 if (mc->mc_data != NULL) 2412 free(mc->mc_data, M_DEVBUF); 2413 if (mc != NULL) 2414 mly_ccb_free(mly, mc); 2415 2416 return (rv); 2417 } 2418 2419 /* 2420 * Return health status to userspace. If the health change index in the 2421 * user structure does not match that currently exported by the controller, 2422 * we return the current status immediately. Otherwise, we block until 2423 * either interrupted or new status is delivered. 2424 */ 2425 static int 2426 mly_user_health(struct mly_softc *mly, struct mly_user_health *uh) 2427 { 2428 struct mly_health_status mh; 2429 int rv, s; 2430 2431 /* Fetch the current health status from userspace. */ 2432 rv = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh)); 2433 if (rv != 0) 2434 return (rv); 2435 2436 /* spin waiting for a status update */ 2437 s = splbio(); 2438 if (mly->mly_event_change == mh.change_counter) 2439 rv = tsleep(&mly->mly_event_change, PRIBIO | PCATCH, 2440 "mlyhealth", 0); 2441 splx(s); 2442 2443 if (rv == 0) { 2444 /* 2445 * Copy the controller's health status buffer out (there is 2446 * a race here if it changes again). 2447 */ 2448 rv = copyout(&mly->mly_mmbox->mmm_health.status, 2449 uh->HealthStatusBuffer, sizeof(uh->HealthStatusBuffer)); 2450 } 2451 2452 return (rv); 2453 } 2454