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