1 /* $NetBSD: wds.c,v 1.26 1997/11/30 15:24:00 drochner Exp $ */ 2 3 #undef WDSDIAG 4 #ifdef DDB 5 #define integrate 6 #else 7 #define integrate static inline 8 #endif 9 10 /* 11 * XXX 12 * sense data 13 * aborts 14 * resets 15 */ 16 17 /*- 18 * Copyright (c) 1997 The NetBSD Foundation, Inc. 19 * All rights reserved. 20 * 21 * This code is derived from software contributed to The NetBSD Foundation 22 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 23 * NASA Ames Research Center. 24 * 25 * Redistribution and use in source and binary forms, with or without 26 * modification, are permitted provided that the following conditions 27 * are met: 28 * 1. Redistributions of source code must retain the above copyright 29 * notice, this list of conditions and the following disclaimer. 30 * 2. Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in the 32 * documentation and/or other materials provided with the distribution. 33 * 3. All advertising materials mentioning features or use of this software 34 * must display the following acknowledgement: 35 * This product includes software developed by the NetBSD 36 * Foundation, Inc. and its contributors. 37 * 4. Neither the name of The NetBSD Foundation nor the names of its 38 * contributors may be used to endorse or promote products derived 39 * from this software without specific prior written permission. 40 * 41 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 42 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 43 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 44 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 45 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 46 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 47 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 48 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 49 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 51 * POSSIBILITY OF SUCH DAMAGE. 52 */ 53 54 /* 55 * Copyright (c) 1994, 1995 Julian Highfield. All rights reserved. 56 * Portions copyright (c) 1994, 1996, 1997 57 * Charles M. Hannum. All rights reserved. 58 * 59 * Redistribution and use in source and binary forms, with or without 60 * modification, are permitted provided that the following conditions 61 * are met: 62 * 1. Redistributions of source code must retain the above copyright 63 * notice, this list of conditions and the following disclaimer. 64 * 2. Redistributions in binary form must reproduce the above copyright 65 * notice, this list of conditions and the following disclaimer in the 66 * documentation and/or other materials provided with the distribution. 67 * 3. All advertising materials mentioning features or use of this software 68 * must display the following acknowledgement: 69 * This product includes software developed by Julian Highfield. 70 * 4. The name of the author may not be used to endorse or promote products 71 * derived from this software without specific prior written permission. 72 * 73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 74 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 75 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 76 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 77 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 78 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 79 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 80 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 81 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 82 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 83 */ 84 85 /* 86 * This driver is for the WD7000 family of SCSI controllers: 87 * the WD7000-ASC, a bus-mastering DMA controller, 88 * the WD7000-FASST2, an -ASC with new firmware and scatter-gather, 89 * and the WD7000-ASE, which was custom manufactured for Apollo 90 * workstations and seems to include an -ASC as well as floppy 91 * and ESDI interfaces. 92 * 93 * Loosely based on Theo Deraadt's unfinished attempt. 94 */ 95 96 #include <sys/types.h> 97 #include <sys/param.h> 98 #include <sys/systm.h> 99 #include <sys/kernel.h> 100 #include <sys/errno.h> 101 #include <sys/ioctl.h> 102 #include <sys/device.h> 103 #include <sys/malloc.h> 104 #include <sys/buf.h> 105 #include <sys/proc.h> 106 #include <sys/user.h> 107 108 #include <machine/bus.h> 109 #include <machine/intr.h> 110 111 #include <dev/scsipi/scsi_all.h> 112 #include <dev/scsipi/scsipi_all.h> 113 #include <dev/scsipi/scsiconf.h> 114 115 #include <dev/isa/isavar.h> 116 #include <dev/isa/isadmavar.h> 117 118 #include <dev/isa/wdsreg.h> 119 120 #define WDS_ISA_IOSIZE 8 121 122 #ifndef DDB 123 #define Debugger() panic("should call debugger here (wds.c)") 124 #endif /* ! DDB */ 125 126 #define WDS_MAXXFER ((WDS_NSEG - 1) << PGSHIFT) 127 128 #define WDS_MBX_SIZE 16 129 130 #define WDS_SCB_MAX 32 131 #define SCB_HASH_SIZE 32 /* hash table size for phystokv */ 132 #define SCB_HASH_SHIFT 9 133 #define SCB_HASH(x) ((((long)(x))>>SCB_HASH_SHIFT) & (SCB_HASH_SIZE - 1)) 134 135 #define wds_nextmbx(wmb, mbx, mbio) \ 136 if ((wmb) == &(mbx)->mbio[WDS_MBX_SIZE - 1]) \ 137 (wmb) = &(mbx)->mbio[0]; \ 138 else \ 139 (wmb)++; 140 141 struct wds_mbx { 142 struct wds_mbx_out mbo[WDS_MBX_SIZE]; 143 struct wds_mbx_in mbi[WDS_MBX_SIZE]; 144 struct wds_mbx_out *cmbo; /* Collection Mail Box out */ 145 struct wds_mbx_out *tmbo; /* Target Mail Box out */ 146 struct wds_mbx_in *tmbi; /* Target Mail Box in */ 147 }; 148 149 struct wds_softc { 150 struct device sc_dev; 151 152 bus_space_tag_t sc_iot; 153 bus_space_handle_t sc_ioh; 154 bus_dma_tag_t sc_dmat; 155 bus_dmamap_t sc_dmamap_mbox; /* maps the mailbox */ 156 void *sc_ih; 157 158 struct wds_mbx *sc_mbx; 159 #define wmbx (sc->sc_mbx) 160 struct wds_scb *sc_scbhash[SCB_HASH_SIZE]; 161 TAILQ_HEAD(, wds_scb) sc_free_scb, sc_waiting_scb; 162 int sc_numscbs, sc_mbofull; 163 struct scsipi_link sc_link; /* prototype for subdevs */ 164 165 LIST_HEAD(, scsipi_xfer) sc_queue; 166 struct scsipi_xfer *sc_queuelast; 167 168 int sc_revision; 169 int sc_maxsegs; 170 }; 171 172 struct wds_probe_data { 173 #ifdef notyet 174 int sc_irq, sc_drq; 175 #endif 176 int sc_scsi_dev; 177 }; 178 179 integrate void 180 wds_wait __P((bus_space_tag_t, bus_space_handle_t, int, int, int)); 181 int wds_cmd __P((bus_space_tag_t, bus_space_handle_t, u_char *, int)); 182 integrate void wds_finish_scbs __P((struct wds_softc *)); 183 int wdsintr __P((void *)); 184 integrate void wds_reset_scb __P((struct wds_softc *, struct wds_scb *)); 185 void wds_free_scb __P((struct wds_softc *, struct wds_scb *)); 186 integrate int wds_init_scb __P((struct wds_softc *, struct wds_scb *)); 187 struct wds_scb *wds_get_scb __P((struct wds_softc *, int)); 188 struct wds_scb *wds_scb_phys_kv __P((struct wds_softc *, u_long)); 189 void wds_queue_scb __P((struct wds_softc *, struct wds_scb *)); 190 void wds_collect_mbo __P((struct wds_softc *)); 191 void wds_start_scbs __P((struct wds_softc *)); 192 void wds_done __P((struct wds_softc *, struct wds_scb *, u_char)); 193 int wds_find __P((bus_space_tag_t, bus_space_handle_t, struct wds_probe_data *)); 194 void wds_attach __P((struct wds_softc *, struct wds_probe_data *)); 195 void wds_init __P((struct wds_softc *, int)); 196 void wds_inquire_setup_information __P((struct wds_softc *)); 197 void wdsminphys __P((struct buf *)); 198 int wds_scsi_cmd __P((struct scsipi_xfer *)); 199 void wds_sense __P((struct wds_softc *, struct wds_scb *)); 200 int wds_poll __P((struct wds_softc *, struct scsipi_xfer *, int)); 201 int wds_ipoll __P((struct wds_softc *, struct wds_scb *, int)); 202 void wds_timeout __P((void *)); 203 int wds_create_scbs __P((struct wds_softc *, void *, size_t)); 204 void wds_enqueue __P((struct wds_softc *, struct scsipi_xfer *, int)); 205 struct scsipi_xfer *wds_dequeue __P((struct wds_softc *)); 206 207 struct scsipi_adapter wds_switch = { 208 wds_scsi_cmd, 209 wdsminphys, 210 0, 211 0, 212 }; 213 214 /* the below structure is so we have a default dev struct for our link struct */ 215 struct scsipi_device wds_dev = { 216 NULL, /* Use default error handler */ 217 NULL, /* have a queue, served by this */ 218 NULL, /* have no async handler */ 219 NULL, /* Use default 'done' routine */ 220 }; 221 222 #ifdef __BROKEN_INDIRECT_CONFIG 223 int wdsprobe __P((struct device *, void *, void *)); 224 #else 225 int wdsprobe __P((struct device *, struct cfdata *, void *)); 226 #endif 227 void wdsattach __P((struct device *, struct device *, void *)); 228 229 struct cfattach wds_ca = { 230 sizeof(struct wds_softc), wdsprobe, wdsattach 231 }; 232 233 struct cfdriver wds_cd = { 234 NULL, "wds", DV_DULL 235 }; 236 237 #define WDS_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */ 238 239 /* XXX Should put this in a better place. */ 240 #define offsetof(type, member) ((size_t)(&((type *)0)->member)) 241 242 /* 243 * Insert a scsipi_xfer into the software queue. We overload xs->free_list 244 * to avoid having to allocate additional resources (since we're used 245 * only during resource shortages anyhow. 246 */ 247 void 248 wds_enqueue(sc, xs, infront) 249 struct wds_softc *sc; 250 struct scsipi_xfer *xs; 251 int infront; 252 { 253 254 if (infront || sc->sc_queue.lh_first == NULL) { 255 if (sc->sc_queue.lh_first == NULL) 256 sc->sc_queuelast = xs; 257 LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list); 258 return; 259 } 260 261 LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list); 262 sc->sc_queuelast = xs; 263 } 264 265 /* 266 * Pull a scsipi_xfer off the front of the software queue. 267 */ 268 struct scsipi_xfer * 269 wds_dequeue(sc) 270 struct wds_softc *sc; 271 { 272 struct scsipi_xfer *xs; 273 274 xs = sc->sc_queue.lh_first; 275 LIST_REMOVE(xs, free_list); 276 277 if (sc->sc_queue.lh_first == NULL) 278 sc->sc_queuelast = NULL; 279 280 return (xs); 281 } 282 283 integrate void 284 wds_wait(iot, ioh, port, mask, val) 285 bus_space_tag_t iot; 286 bus_space_handle_t ioh; 287 int port; 288 int mask, val; 289 { 290 291 while ((bus_space_read_1(iot, ioh, port) & mask) != val) 292 ; 293 } 294 295 /* 296 * Write a command to the board's I/O ports. 297 */ 298 int 299 wds_cmd(iot, ioh, ibuf, icnt) 300 bus_space_tag_t iot; 301 bus_space_handle_t ioh; 302 u_char *ibuf; 303 int icnt; 304 { 305 u_char c; 306 307 wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY); 308 309 while (icnt--) { 310 bus_space_write_1(iot, ioh, WDS_CMD, *ibuf++); 311 wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY); 312 c = bus_space_read_1(iot, ioh, WDS_STAT); 313 if (c & WDSS_REJ) 314 return 1; 315 } 316 317 return 0; 318 } 319 320 /* 321 * Check for the presence of a WD7000 SCSI controller. 322 */ 323 int 324 wdsprobe(parent, match, aux) 325 struct device *parent; 326 #ifdef __BROKEN_INDIRECT_CONFIG 327 void *match; 328 #else 329 struct cfdata *match; 330 #endif 331 void *aux; 332 { 333 struct isa_attach_args *ia = aux; 334 bus_space_tag_t iot = ia->ia_iot; 335 bus_space_handle_t ioh; 336 struct wds_probe_data wpd; 337 int rv; 338 339 /* Disallow wildcarded i/o address. */ 340 if (ia->ia_iobase == ISACF_PORT_DEFAULT) 341 return (0); 342 343 if (bus_space_map(iot, ia->ia_iobase, WDS_ISA_IOSIZE, 0, &ioh)) 344 return (0); 345 346 rv = wds_find(iot, ioh, &wpd); 347 348 bus_space_unmap(iot, ioh, WDS_ISA_IOSIZE); 349 350 if (rv) { 351 #ifdef notyet 352 if (ia->ia_irq != -1 && ia->ia_irq != wpd.sc_irq) 353 return (0); 354 if (ia->ia_drq != -1 && ia->ia_drq != wpd.sc_drq) 355 return (0); 356 ia->ia_irq = wpd.sc_irq; 357 ia->ia_drq = wpd.sc_drq; 358 #else 359 if (ia->ia_irq == -1) 360 return (0); 361 if (ia->ia_drq == -1) 362 return (0); 363 #endif 364 ia->ia_msize = 0; 365 ia->ia_iosize = WDS_ISA_IOSIZE; 366 } 367 return (rv); 368 } 369 370 /* 371 * Attach all available units. 372 */ 373 void 374 wdsattach(parent, self, aux) 375 struct device *parent, *self; 376 void *aux; 377 { 378 struct isa_attach_args *ia = aux; 379 struct wds_softc *sc = (void *)self; 380 bus_space_tag_t iot = ia->ia_iot; 381 bus_space_handle_t ioh; 382 struct wds_probe_data wpd; 383 isa_chipset_tag_t ic = ia->ia_ic; 384 385 printf("\n"); 386 387 if (bus_space_map(iot, ia->ia_iobase, WDS_ISA_IOSIZE, 0, &ioh)) { 388 printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname); 389 return; 390 } 391 392 sc->sc_iot = iot; 393 sc->sc_ioh = ioh; 394 sc->sc_dmat = ia->ia_dmat; 395 if (!wds_find(iot, ioh, &wpd)) { 396 printf("%s: wds_find failed\n", sc->sc_dev.dv_xname); 397 return; 398 } 399 400 bus_space_write_1(iot, ioh, WDS_HCR, WDSH_DRQEN); 401 #ifdef notyet 402 if (wpd.sc_drq != -1) 403 isa_dmacascade(parent, wpd.sc_drq); 404 405 sc->sc_ih = isa_intr_establish(ic, wpd.sc_irq, IST_EDGE, IPL_BIO, 406 wdsintr, sc); 407 #else 408 if (ia->ia_drq != -1) 409 isa_dmacascade(parent, ia->ia_drq); 410 411 sc->sc_ih = isa_intr_establish(ic, ia->ia_irq, IST_EDGE, IPL_BIO, 412 wdsintr, sc); 413 #endif 414 if (sc->sc_ih == NULL) { 415 printf("%s: couldn't establish interrupt\n", 416 sc->sc_dev.dv_xname); 417 return; 418 } 419 420 wds_attach(sc, &wpd); 421 } 422 423 void 424 wds_attach(sc, wpd) 425 struct wds_softc *sc; 426 struct wds_probe_data *wpd; 427 { 428 429 TAILQ_INIT(&sc->sc_free_scb); 430 TAILQ_INIT(&sc->sc_waiting_scb); 431 LIST_INIT(&sc->sc_queue); 432 433 wds_init(sc, 0); 434 wds_inquire_setup_information(sc); 435 436 /* 437 * fill in the prototype scsipi_link. 438 */ 439 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE; 440 sc->sc_link.adapter_softc = sc; 441 sc->sc_link.scsipi_scsi.adapter_target = wpd->sc_scsi_dev; 442 sc->sc_link.adapter = &wds_switch; 443 sc->sc_link.device = &wds_dev; 444 /* XXX */ 445 /* I don't think the -ASE can handle openings > 1. */ 446 /* It gives Vendor Error 26 whenever I try it. */ 447 sc->sc_link.openings = 1; 448 sc->sc_link.scsipi_scsi.max_target = 7; 449 sc->sc_link.type = BUS_SCSI; 450 451 /* 452 * ask the adapter what subunits are present 453 */ 454 config_found(&sc->sc_dev, &sc->sc_link, scsiprint); 455 } 456 457 integrate void 458 wds_finish_scbs(sc) 459 struct wds_softc *sc; 460 { 461 struct wds_mbx_in *wmbi; 462 struct wds_scb *scb; 463 int i; 464 465 wmbi = wmbx->tmbi; 466 467 if (wmbi->stat == WDS_MBI_FREE) { 468 for (i = 0; i < WDS_MBX_SIZE; i++) { 469 if (wmbi->stat != WDS_MBI_FREE) { 470 printf("%s: mbi not in round-robin order\n", 471 sc->sc_dev.dv_xname); 472 goto AGAIN; 473 } 474 wds_nextmbx(wmbi, wmbx, mbi); 475 } 476 #ifdef WDSDIAGnot 477 printf("%s: mbi interrupt with no full mailboxes\n", 478 sc->sc_dev.dv_xname); 479 #endif 480 return; 481 } 482 483 AGAIN: 484 do { 485 scb = wds_scb_phys_kv(sc, phystol(wmbi->scb_addr)); 486 if (!scb) { 487 printf("%s: bad mbi scb pointer; skipping\n", 488 sc->sc_dev.dv_xname); 489 goto next; 490 } 491 492 #ifdef WDSDEBUG 493 if (wds_debug) { 494 u_char *cp = &scb->scsipi_cmd; 495 printf("op=%x %x %x %x %x %x\n", 496 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 497 printf("stat %x for mbi addr = 0x%08x, ", 498 wmbi->stat, wmbi); 499 printf("scb addr = 0x%x\n", scb); 500 } 501 #endif /* WDSDEBUG */ 502 503 untimeout(wds_timeout, scb); 504 wds_done(sc, scb, wmbi->stat); 505 506 next: 507 wmbi->stat = WDS_MBI_FREE; 508 wds_nextmbx(wmbi, wmbx, mbi); 509 } while (wmbi->stat != WDS_MBI_FREE); 510 511 wmbx->tmbi = wmbi; 512 } 513 514 /* 515 * Process an interrupt. 516 */ 517 int 518 wdsintr(arg) 519 void *arg; 520 { 521 struct wds_softc *sc = arg; 522 bus_space_tag_t iot = sc->sc_iot; 523 bus_space_handle_t ioh = sc->sc_ioh; 524 u_char c; 525 526 /* Was it really an interrupt from the board? */ 527 if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) == 0) 528 return 0; 529 530 /* Get the interrupt status byte. */ 531 c = bus_space_read_1(iot, ioh, WDS_IRQSTAT) & WDSI_MASK; 532 533 /* Acknowledge (which resets) the interrupt. */ 534 bus_space_write_1(iot, ioh, WDS_IRQACK, 0x00); 535 536 switch (c) { 537 case WDSI_MSVC: 538 wds_finish_scbs(sc); 539 break; 540 541 case WDSI_MFREE: 542 wds_start_scbs(sc); 543 break; 544 545 default: 546 printf("%s: unrecognized interrupt type %02x", 547 sc->sc_dev.dv_xname, c); 548 break; 549 } 550 551 return 1; 552 } 553 554 integrate void 555 wds_reset_scb(sc, scb) 556 struct wds_softc *sc; 557 struct wds_scb *scb; 558 { 559 560 scb->flags = 0; 561 } 562 563 /* 564 * Free the command structure, the outgoing mailbox and the data buffer. 565 */ 566 void 567 wds_free_scb(sc, scb) 568 struct wds_softc *sc; 569 struct wds_scb *scb; 570 { 571 int s; 572 573 s = splbio(); 574 575 wds_reset_scb(sc, scb); 576 TAILQ_INSERT_HEAD(&sc->sc_free_scb, scb, chain); 577 578 /* 579 * If there were none, wake anybody waiting for one to come free, 580 * starting with queued entries. 581 */ 582 if (scb->chain.tqe_next == 0) 583 wakeup(&sc->sc_free_scb); 584 585 splx(s); 586 } 587 588 integrate int 589 wds_init_scb(sc, scb) 590 struct wds_softc *sc; 591 struct wds_scb *scb; 592 { 593 bus_dma_tag_t dmat = sc->sc_dmat; 594 int hashnum, error; 595 596 /* 597 * XXX Should we put a DIAGNOSTIC check for multiple 598 * XXX SCB inits here? 599 */ 600 601 bzero(scb, sizeof(struct wds_scb)); 602 603 /* 604 * Create DMA maps for this SCB. 605 */ 606 error = bus_dmamap_create(dmat, sizeof(struct wds_scb), 1, 607 sizeof(struct wds_scb), 0, BUS_DMA_NOWAIT, &scb->dmamap_self); 608 if (error) { 609 printf("%s: can't create scb dmamap_self\n", 610 sc->sc_dev.dv_xname); 611 return (error); 612 } 613 614 error = bus_dmamap_create(dmat, WDS_MAXXFER, WDS_NSEG, WDS_MAXXFER, 615 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &scb->dmamap_xfer); 616 if (error) { 617 printf("%s: can't create scb dmamap_xfer\n", 618 sc->sc_dev.dv_xname); 619 bus_dmamap_destroy(dmat, scb->dmamap_self); 620 return (error); 621 } 622 623 /* 624 * Load the permanent DMA maps. 625 */ 626 error = bus_dmamap_load(dmat, scb->dmamap_self, scb, 627 sizeof(struct wds_scb), NULL, BUS_DMA_NOWAIT); 628 if (error) { 629 printf("%s: can't load scb dmamap_self\n", 630 sc->sc_dev.dv_xname); 631 bus_dmamap_destroy(dmat, scb->dmamap_self); 632 bus_dmamap_destroy(dmat, scb->dmamap_xfer); 633 return (error); 634 } 635 636 /* 637 * put in the phystokv hash table 638 * Never gets taken out. 639 */ 640 scb->hashkey = scb->dmamap_self->dm_segs[0].ds_addr; 641 hashnum = SCB_HASH(scb->hashkey); 642 scb->nexthash = sc->sc_scbhash[hashnum]; 643 sc->sc_scbhash[hashnum] = scb; 644 wds_reset_scb(sc, scb); 645 return (0); 646 } 647 648 /* 649 * Create a set of scbs and add them to the free list. 650 */ 651 int 652 wds_create_scbs(sc, mem, size) 653 struct wds_softc *sc; 654 void *mem; 655 size_t size; 656 { 657 bus_dma_segment_t seg; 658 struct wds_scb *scb; 659 int rseg, error; 660 661 if (sc->sc_numscbs >= WDS_SCB_MAX) 662 return (0); 663 664 if ((scb = mem) != NULL) 665 goto have_mem; 666 667 size = NBPG; 668 error = bus_dmamem_alloc(sc->sc_dmat, size, NBPG, 0, &seg, 1, &rseg, 669 BUS_DMA_NOWAIT); 670 if (error) { 671 printf("%s: can't allocate memory for scbs\n", 672 sc->sc_dev.dv_xname); 673 return (error); 674 } 675 676 error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, size, 677 (caddr_t *)&scb, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC); 678 if (error) { 679 printf("%s: can't map memory for scbs\n", 680 sc->sc_dev.dv_xname); 681 bus_dmamem_free(sc->sc_dmat, &seg, rseg); 682 return (error); 683 } 684 685 have_mem: 686 bzero(scb, size); 687 while (size > sizeof(struct wds_scb) && sc->sc_numscbs < WDS_SCB_MAX) { 688 error = wds_init_scb(sc, scb); 689 if (error) { 690 printf("%s: can't initialize scb\n", 691 sc->sc_dev.dv_xname); 692 return (error); 693 } 694 TAILQ_INSERT_TAIL(&sc->sc_free_scb, scb, chain); 695 (caddr_t)scb += ALIGN(sizeof(struct wds_scb)); 696 size -= ALIGN(sizeof(struct wds_scb)); 697 sc->sc_numscbs++; 698 } 699 700 return (0); 701 } 702 703 /* 704 * Get a free scb 705 * 706 * If there are none, see if we can allocate a new one. If so, put it in 707 * the hash table too otherwise either return an error or sleep. 708 */ 709 struct wds_scb * 710 wds_get_scb(sc, flags) 711 struct wds_softc *sc; 712 int flags; 713 { 714 struct wds_scb *scb; 715 int s; 716 717 s = splbio(); 718 719 /* 720 * If we can and have to, sleep waiting for one to come free 721 * but only if we can't allocate a new one. 722 */ 723 for (;;) { 724 scb = sc->sc_free_scb.tqh_first; 725 if (scb) { 726 TAILQ_REMOVE(&sc->sc_free_scb, scb, chain); 727 break; 728 } 729 if (sc->sc_numscbs < WDS_SCB_MAX) { 730 /* 731 * wds_create_scbs() might have managed to create 732 * one before it failed. If so, don't abort, 733 * just grab it and continue to hobble along. 734 */ 735 if (wds_create_scbs(sc, NULL, 0) != 0 && 736 sc->sc_free_scb.tqh_first == NULL) { 737 printf("%s: can't allocate scbs\n", 738 sc->sc_dev.dv_xname); 739 goto out; 740 } 741 continue; 742 } 743 if ((flags & SCSI_NOSLEEP) != 0) 744 goto out; 745 tsleep(&sc->sc_free_scb, PRIBIO, "wdsscb", 0); 746 } 747 748 scb->flags |= SCB_ALLOC; 749 750 out: 751 splx(s); 752 return (scb); 753 } 754 755 struct wds_scb * 756 wds_scb_phys_kv(sc, scb_phys) 757 struct wds_softc *sc; 758 u_long scb_phys; 759 { 760 int hashnum = SCB_HASH(scb_phys); 761 struct wds_scb *scb = sc->sc_scbhash[hashnum]; 762 763 while (scb) { 764 if (scb->hashkey == scb_phys) 765 break; 766 /* XXX Check to see if it matches the sense command block. */ 767 if (scb->hashkey == (scb_phys - sizeof(struct wds_cmd))) 768 break; 769 scb = scb->nexthash; 770 } 771 return (scb); 772 } 773 774 /* 775 * Queue a SCB to be sent to the controller, and send it if possible. 776 */ 777 void 778 wds_queue_scb(sc, scb) 779 struct wds_softc *sc; 780 struct wds_scb *scb; 781 { 782 783 TAILQ_INSERT_TAIL(&sc->sc_waiting_scb, scb, chain); 784 wds_start_scbs(sc); 785 } 786 787 /* 788 * Garbage collect mailboxes that are no longer in use. 789 */ 790 void 791 wds_collect_mbo(sc) 792 struct wds_softc *sc; 793 { 794 struct wds_mbx_out *wmbo; /* Mail Box Out pointer */ 795 #ifdef WDSDIAG 796 struct wds_scb *scb; 797 #endif 798 799 wmbo = wmbx->cmbo; 800 801 while (sc->sc_mbofull > 0) { 802 if (wmbo->cmd != WDS_MBO_FREE) 803 break; 804 805 #ifdef WDSDIAG 806 scb = wds_scb_phys_kv(sc, phystol(wmbo->scb_addr)); 807 scb->flags &= ~SCB_SENDING; 808 #endif 809 810 --sc->sc_mbofull; 811 wds_nextmbx(wmbo, wmbx, mbo); 812 } 813 814 wmbx->cmbo = wmbo; 815 } 816 817 /* 818 * Send as many SCBs as we have empty mailboxes for. 819 */ 820 void 821 wds_start_scbs(sc) 822 struct wds_softc *sc; 823 { 824 bus_space_tag_t iot = sc->sc_iot; 825 bus_space_handle_t ioh = sc->sc_ioh; 826 struct wds_mbx_out *wmbo; /* Mail Box Out pointer */ 827 struct wds_scb *scb; 828 u_char c; 829 830 wmbo = wmbx->tmbo; 831 832 while ((scb = sc->sc_waiting_scb.tqh_first) != NULL) { 833 if (sc->sc_mbofull >= WDS_MBX_SIZE) { 834 wds_collect_mbo(sc); 835 if (sc->sc_mbofull >= WDS_MBX_SIZE) { 836 c = WDSC_IRQMFREE; 837 wds_cmd(iot, ioh, &c, sizeof c); 838 break; 839 } 840 } 841 842 TAILQ_REMOVE(&sc->sc_waiting_scb, scb, chain); 843 #ifdef WDSDIAG 844 scb->flags |= SCB_SENDING; 845 #endif 846 847 /* Link scb to mbo. */ 848 if (scb->flags & SCB_SENSE) 849 ltophys(scb->dmamap_self->dm_segs[0].ds_addr + 850 offsetof(struct wds_scb, sense), wmbo->scb_addr); 851 else 852 ltophys(scb->dmamap_self->dm_segs[0].ds_addr + 853 offsetof(struct wds_scb, cmd), wmbo->scb_addr); 854 /* XXX What about aborts? */ 855 wmbo->cmd = WDS_MBO_START; 856 857 /* Tell the card to poll immediately. */ 858 c = WDSC_MSTART(wmbo - wmbx->mbo); 859 wds_cmd(sc->sc_iot, sc->sc_ioh, &c, sizeof c); 860 861 if ((scb->flags & SCB_POLLED) == 0) 862 timeout(wds_timeout, scb, (scb->timeout * hz) / 1000); 863 864 ++sc->sc_mbofull; 865 wds_nextmbx(wmbo, wmbx, mbo); 866 } 867 868 wmbx->tmbo = wmbo; 869 } 870 871 /* 872 * Process the result of a SCSI command. 873 */ 874 void 875 wds_done(sc, scb, stat) 876 struct wds_softc *sc; 877 struct wds_scb *scb; 878 u_char stat; 879 { 880 bus_dma_tag_t dmat = sc->sc_dmat; 881 struct scsipi_xfer *xs = scb->xs; 882 883 /* XXXXX */ 884 885 /* Don't release the SCB if it was an internal command. */ 886 if (xs == 0) { 887 scb->flags |= SCB_DONE; 888 return; 889 } 890 891 /* Sense handling. */ 892 if (xs->error == XS_SENSE) { 893 bcopy(&scb->sense_data, &xs->sense.scsi_sense, 894 sizeof (struct scsipi_sense_data)); 895 } else { 896 /* 897 * If we were a data transfer, unload the map that described 898 * the data buffer. 899 */ 900 if (xs->datalen) { 901 bus_dmamap_sync(dmat, scb->dmamap_xfer, 902 (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : 903 BUS_DMASYNC_POSTWRITE); 904 bus_dmamap_unload(dmat, scb->dmamap_xfer); 905 } 906 if (xs->error == XS_NOERROR) { 907 /* If all went well, or an error is acceptable. */ 908 if (stat == WDS_MBI_OK) { 909 /* OK, set the result */ 910 xs->resid = 0; 911 } else { 912 /* Check the mailbox status. */ 913 switch (stat) { 914 case WDS_MBI_OKERR: 915 /* 916 * SCSI error recorded in scb, 917 * counts as WDS_MBI_OK 918 */ 919 switch (scb->cmd.venderr) { 920 case 0x00: 921 printf("%s: Is this " 922 "an error?\n", 923 sc->sc_dev.dv_xname); 924 /* Experiment. */ 925 xs->error = XS_DRIVER_STUFFUP; 926 break; 927 case 0x01: 928 #if 0 929 printf("%s: OK, see SCSI " 930 "error field.\n", 931 sc->sc_dev.dv_xname); 932 #endif 933 if (scb->cmd.stat == 934 SCSI_CHECK) { 935 /* Do sense. */ 936 wds_sense(sc, scb); 937 return; 938 } else if (scb->cmd.stat == 939 SCSI_BUSY) { 940 xs->error = XS_BUSY; 941 } 942 break; 943 case 0x40: 944 #if 0 945 printf("%s: DMA underrun!\n", 946 sc->sc_dev.dv_xname); 947 #endif 948 /* 949 * Hits this if the target 950 * returns fewer that datalen 951 * bytes (eg my CD-ROM, which 952 * returns a short version 953 * string, or if DMA is 954 * turned off etc. 955 */ 956 xs->resid = 0; 957 break; 958 default: 959 printf("%s: VENDOR ERROR " 960 "%02x, scsi %02x\n", 961 sc->sc_dev.dv_xname, 962 scb->cmd.venderr, 963 scb->cmd.stat); 964 /* Experiment. */ 965 xs->error = XS_DRIVER_STUFFUP; 966 break; 967 } 968 break; 969 case WDS_MBI_ETIME: 970 /* 971 * The documentation isn't clear on 972 * what conditions might generate this, 973 * but selection timeouts are the only 974 * one I can think of. 975 */ 976 xs->error = XS_SELTIMEOUT; 977 break; 978 case WDS_MBI_ERESET: 979 case WDS_MBI_ETARCMD: 980 case WDS_MBI_ERESEL: 981 case WDS_MBI_ESEL: 982 case WDS_MBI_EABORT: 983 case WDS_MBI_ESRESET: 984 case WDS_MBI_EHRESET: 985 xs->error = XS_DRIVER_STUFFUP; 986 break; 987 } 988 } 989 } /* else sense */ 990 } /* XS_NOERROR */ 991 992 wds_free_scb(sc, scb); 993 xs->flags |= ITSDONE; 994 scsipi_done(xs); 995 996 /* 997 * If there are queue entries in the software queue, try to 998 * run the first one. We should be more or less guaranteed 999 * to succeed, since we just freed a CCB. 1000 * 1001 * NOTE: wds_scsi_cmd() relies on our calling it with 1002 * the first entry in the queue. 1003 */ 1004 if ((xs = sc->sc_queue.lh_first) != NULL) 1005 (void) wds_scsi_cmd(xs); 1006 } 1007 1008 int 1009 wds_find(iot, ioh, sc) 1010 bus_space_tag_t iot; 1011 bus_space_handle_t ioh; 1012 struct wds_probe_data *sc; 1013 { 1014 int i; 1015 1016 /* XXXXX */ 1017 1018 /* 1019 * Sending a command causes the CMDRDY bit to clear. 1020 */ 1021 for (i = 5; i; i--) { 1022 if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_RDY) != 0) 1023 break; 1024 delay(100); 1025 } 1026 if (!i) 1027 return 0; 1028 1029 bus_space_write_1(iot, ioh, WDS_CMD, WDSC_NOOP); 1030 if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_RDY) != 0) 1031 return 0; 1032 1033 bus_space_write_1(iot, ioh, WDS_HCR, WDSH_SCSIRESET|WDSH_ASCRESET); 1034 delay(10000); 1035 bus_space_write_1(iot, ioh, WDS_HCR, 0x00); 1036 delay(500000); 1037 wds_wait(iot, ioh, WDS_STAT, WDSS_RDY, WDSS_RDY); 1038 if (bus_space_read_1(iot, ioh, WDS_IRQSTAT) != 1) 1039 if (bus_space_read_1(iot, ioh, WDS_IRQSTAT) != 7) 1040 return 0; 1041 1042 for (i = 2000; i; i--) { 1043 if ((bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_RDY) != 0) 1044 break; 1045 delay(100); 1046 } 1047 if (!i) 1048 return 0; 1049 1050 if (sc) { 1051 #ifdef notyet 1052 sc->sc_irq = ...; 1053 sc->sc_drq = ...; 1054 #endif 1055 /* XXX Can we do this better? */ 1056 sc->sc_scsi_dev = 7; 1057 } 1058 1059 return 1; 1060 } 1061 1062 /* 1063 * Initialise the board and driver. 1064 */ 1065 void 1066 wds_init(sc, isreset) 1067 struct wds_softc *sc; 1068 int isreset; 1069 { 1070 bus_space_tag_t iot = sc->sc_iot; 1071 bus_space_handle_t ioh = sc->sc_ioh; 1072 bus_dma_segment_t seg; 1073 struct wds_setup init; 1074 u_char c; 1075 int i, rseg; 1076 1077 if (isreset) 1078 goto doinit; 1079 1080 /* 1081 * Allocate the mailbox. 1082 */ 1083 if (bus_dmamem_alloc(sc->sc_dmat, NBPG, NBPG, 0, &seg, 1, 1084 &rseg, BUS_DMA_NOWAIT) || 1085 bus_dmamem_map(sc->sc_dmat, &seg, rseg, NBPG, 1086 (caddr_t *)&wmbx, BUS_DMA_NOWAIT|BUS_DMAMEM_NOSYNC)) 1087 panic("wds_init: can't create or map mailbox"); 1088 1089 /* 1090 * Since DMA memory allocation is always rounded up to a 1091 * page size, create some scbs from the leftovers. 1092 */ 1093 if (wds_create_scbs(sc, ((caddr_t)wmbx) + 1094 ALIGN(sizeof(struct wds_mbx)), 1095 NBPG - ALIGN(sizeof(struct wds_mbx)))) 1096 panic("wds_init: can't create scbs"); 1097 1098 /* 1099 * Create and load the mailbox DMA map. 1100 */ 1101 if (bus_dmamap_create(sc->sc_dmat, sizeof(struct wds_mbx), 1, 1102 sizeof(struct wds_mbx), 0, BUS_DMA_NOWAIT, &sc->sc_dmamap_mbox) || 1103 bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_mbox, wmbx, 1104 sizeof(struct wds_mbx), NULL, BUS_DMA_NOWAIT)) 1105 panic("wds_ionit: can't craete or load mailbox dma map"); 1106 1107 doinit: 1108 /* 1109 * Set up initial mail box for round-robin operation. 1110 */ 1111 for (i = 0; i < WDS_MBX_SIZE; i++) { 1112 wmbx->mbo[i].cmd = WDS_MBO_FREE; 1113 wmbx->mbi[i].stat = WDS_MBI_FREE; 1114 } 1115 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0]; 1116 wmbx->tmbi = &wmbx->mbi[0]; 1117 sc->sc_mbofull = 0; 1118 1119 init.opcode = WDSC_INIT; 1120 init.scsi_id = sc->sc_link.scsipi_scsi.adapter_target; 1121 init.buson_t = 48; 1122 init.busoff_t = 24; 1123 init.xx = 0; 1124 ltophys(sc->sc_dmamap_mbox->dm_segs[0].ds_addr, init.mbaddr); 1125 init.nomb = init.nimb = WDS_MBX_SIZE; 1126 wds_cmd(iot, ioh, (u_char *)&init, sizeof init); 1127 1128 wds_wait(iot, ioh, WDS_STAT, WDSS_INIT, WDSS_INIT); 1129 1130 c = WDSC_DISUNSOL; 1131 wds_cmd(iot, ioh, &c, sizeof c); 1132 } 1133 1134 /* 1135 * Read the board's firmware revision information. 1136 */ 1137 void 1138 wds_inquire_setup_information(sc) 1139 struct wds_softc *sc; 1140 { 1141 bus_space_tag_t iot = sc->sc_iot; 1142 bus_space_handle_t ioh = sc->sc_ioh; 1143 struct wds_scb *scb; 1144 u_char *j; 1145 int s; 1146 1147 sc->sc_maxsegs = 1; 1148 1149 scb = wds_get_scb(sc, SCSI_NOSLEEP); 1150 if (scb == 0) 1151 panic("wds_inquire_setup_information: no scb available"); 1152 1153 scb->xs = NULL; 1154 scb->timeout = 40; 1155 1156 bzero(&scb->cmd, sizeof scb->cmd); 1157 scb->cmd.write = 0x80; 1158 scb->cmd.opcode = WDSX_GETFIRMREV; 1159 1160 /* Will poll card, await result. */ 1161 bus_space_write_1(iot, ioh, WDS_HCR, WDSH_DRQEN); 1162 scb->flags |= SCB_POLLED; 1163 1164 s = splbio(); 1165 wds_queue_scb(sc, scb); 1166 splx(s); 1167 1168 if (wds_ipoll(sc, scb, scb->timeout)) 1169 goto out; 1170 1171 /* Print the version number. */ 1172 printf("%s: version %x.%02x ", sc->sc_dev.dv_xname, 1173 scb->cmd.targ, scb->cmd.scb.opcode); 1174 sc->sc_revision = (scb->cmd.targ << 8) | scb->cmd.scb.opcode; 1175 /* Print out the version string. */ 1176 j = 2 + &(scb->cmd.targ); 1177 while ((*j >= 32) && (*j < 128)) { 1178 printf("%c", *j); 1179 j++; 1180 } 1181 1182 /* 1183 * Determine if we can use scatter/gather. 1184 */ 1185 if (sc->sc_revision >= 0x800) 1186 sc->sc_maxsegs = WDS_NSEG; 1187 1188 out: 1189 printf("\n"); 1190 1191 /* 1192 * Free up the resources used by this scb. 1193 */ 1194 wds_free_scb(sc, scb); 1195 } 1196 1197 void 1198 wdsminphys(bp) 1199 struct buf *bp; 1200 { 1201 1202 if (bp->b_bcount > WDS_MAXXFER) 1203 bp->b_bcount = WDS_MAXXFER; 1204 minphys(bp); 1205 } 1206 1207 /* 1208 * Send a SCSI command. 1209 */ 1210 int 1211 wds_scsi_cmd(xs) 1212 struct scsipi_xfer *xs; 1213 { 1214 struct scsipi_link *sc_link = xs->sc_link; 1215 struct wds_softc *sc = sc_link->adapter_softc; 1216 bus_dma_tag_t dmat = sc->sc_dmat; 1217 struct wds_scb *scb; 1218 struct wds_scat_gath *sg; 1219 int error, seg, flags, s; 1220 int fromqueue = 0, dontqueue = 0; 1221 #ifdef TFS 1222 struct iovec *iovp; 1223 #endif 1224 1225 if (xs->flags & SCSI_RESET) { 1226 /* XXX Fix me! */ 1227 printf("%s: reset!\n", sc->sc_dev.dv_xname); 1228 wds_init(sc, 1); 1229 return COMPLETE; 1230 } 1231 1232 s = splbio(); /* protect the queue */ 1233 1234 /* 1235 * If we're running the queue from wds_done(), we've been 1236 * called with the first queue entry as our argument. 1237 */ 1238 if (xs == sc->sc_queue.lh_first) { 1239 xs = wds_dequeue(sc); 1240 fromqueue = 1; 1241 goto get_scb; 1242 } 1243 1244 /* Polled requests can't be queued for later. */ 1245 dontqueue = xs->flags & SCSI_POLL; 1246 1247 /* 1248 * If there are jobs in the queue, run them first. 1249 */ 1250 if (sc->sc_queue.lh_first != NULL) { 1251 /* 1252 * If we can't queue, we have to abort, since 1253 * we have to preserve order. 1254 */ 1255 if (dontqueue) { 1256 splx(s); 1257 xs->error = XS_DRIVER_STUFFUP; 1258 return (TRY_AGAIN_LATER); 1259 } 1260 1261 /* 1262 * Swap with the first queue entry. 1263 */ 1264 wds_enqueue(sc, xs, 0); 1265 xs = wds_dequeue(sc); 1266 fromqueue = 1; 1267 } 1268 1269 get_scb: 1270 flags = xs->flags; 1271 if ((scb = wds_get_scb(sc, flags)) == NULL) { 1272 /* 1273 * If we can't queue, we lose. 1274 */ 1275 if (dontqueue) { 1276 splx(s); 1277 xs->error = XS_DRIVER_STUFFUP; 1278 return (TRY_AGAIN_LATER); 1279 } 1280 1281 /* 1282 * Stuff ourselves into the queue, in front 1283 * if we came off in the first place. 1284 */ 1285 wds_enqueue(sc, xs, fromqueue); 1286 splx(s); 1287 return (SUCCESSFULLY_QUEUED); 1288 } 1289 1290 splx(s); /* done playing with the queue */ 1291 1292 scb->xs = xs; 1293 scb->timeout = xs->timeout; 1294 1295 if (xs->flags & SCSI_DATA_UIO) { 1296 /* XXX Fix me! */ 1297 /* Let's not worry about UIO. There isn't any code for the * 1298 * non-SG boards anyway! */ 1299 printf("%s: UIO is untested and disabled!\n", 1300 sc->sc_dev.dv_xname); 1301 goto bad; 1302 } 1303 1304 /* Zero out the command structure. */ 1305 bzero(&scb->cmd, sizeof scb->cmd); 1306 bcopy(xs->cmd, &scb->cmd.scb, xs->cmdlen < 12 ? xs->cmdlen : 12); 1307 1308 /* Set up some of the command fields. */ 1309 scb->cmd.targ = (xs->sc_link->scsipi_scsi.target << 5) | 1310 xs->sc_link->scsipi_scsi.lun; 1311 1312 /* NOTE: cmd.write may be OK as 0x40 (disable direction checking) 1313 * on boards other than the WD-7000V-ASE. Need this for the ASE: 1314 */ 1315 scb->cmd.write = (xs->flags & SCSI_DATA_IN) ? 0x80 : 0x00; 1316 1317 if (xs->datalen) { 1318 sg = scb->scat_gath; 1319 seg = 0; 1320 #ifdef TFS 1321 if (flags & SCSI_DATA_UIO) { 1322 error = bus_Dmamap_load_uio(dmat, 1323 scb->dmamap_xfer, (struct uio *)xs->data, 1324 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : 1325 BUS_DMA_WAITOK); 1326 } else 1327 #endif /* TFS */ 1328 { 1329 error = bus_dmamap_load(dmat, 1330 scb->dmamap_xfer, xs->data, xs->datalen, NULL, 1331 (flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : 1332 BUS_DMA_WAITOK); 1333 } 1334 1335 if (error) { 1336 if (error == EFBIG) { 1337 printf("%s: wds_scsi_cmd, more than %d" 1338 " dma segments\n", 1339 sc->sc_dev.dv_xname, sc->sc_maxsegs); 1340 } else { 1341 printf("%s: wds_scsi_cmd, error %d loading" 1342 " dma map\n", 1343 sc->sc_dev.dv_xname, error); 1344 } 1345 goto bad; 1346 } 1347 1348 bus_dmamap_sync(dmat, scb->dmamap_xfer, 1349 (flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : 1350 BUS_DMASYNC_PREWRITE); 1351 1352 if (sc->sc_maxsegs > 1) { 1353 /* 1354 * Load the hardware scatter/gather map with the 1355 * contents of the DMA map. 1356 */ 1357 for (seg = 0; seg < scb->dmamap_xfer->dm_nsegs; 1358 seg++) { 1359 ltophys(scb->dmamap_xfer->dm_segs[seg].ds_addr, 1360 scb->scat_gath[seg].seg_addr); 1361 ltophys(scb->dmamap_xfer->dm_segs[seg].ds_len, 1362 scb->scat_gath[seg].seg_len); 1363 } 1364 1365 /* 1366 * Set up for scatter/gather transfer. 1367 */ 1368 scb->cmd.opcode = WDSX_SCSISG; 1369 ltophys(scb->dmamap_self->dm_segs[0].ds_addr + 1370 offsetof(struct wds_scb, scat_gath), 1371 scb->cmd.data); 1372 ltophys(scb->dmamap_self->dm_nsegs * 1373 sizeof(struct wds_scat_gath), scb->cmd.len); 1374 } else { 1375 /* 1376 * This board is an ASC or an ASE, and the 1377 * transfer has been mapped contig for us. 1378 */ 1379 scb->cmd.opcode = WDSX_SCSICMD; 1380 ltophys(scb->dmamap_xfer->dm_segs[0].ds_addr, 1381 scb->cmd.data); 1382 ltophys(scb->dmamap_xfer->dm_segs[0].ds_len, 1383 scb->cmd.len); 1384 } 1385 } else { 1386 scb->cmd.opcode = WDSX_SCSICMD; 1387 ltophys(0, scb->cmd.data); 1388 ltophys(0, scb->cmd.len); 1389 } 1390 1391 scb->cmd.stat = 0x00; 1392 scb->cmd.venderr = 0x00; 1393 ltophys(0, scb->cmd.link); 1394 1395 /* XXX Do we really want to do this? */ 1396 if (flags & SCSI_POLL) { 1397 /* Will poll card, await result. */ 1398 bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, WDSH_DRQEN); 1399 scb->flags |= SCB_POLLED; 1400 } else { 1401 /* Will send command, let interrupt routine handle result. */ 1402 bus_space_write_1(sc->sc_iot, sc->sc_ioh, WDS_HCR, 1403 WDSH_IRQEN | WDSH_DRQEN); 1404 } 1405 1406 s = splbio(); 1407 wds_queue_scb(sc, scb); 1408 splx(s); 1409 1410 if ((flags & SCSI_POLL) == 0) 1411 return SUCCESSFULLY_QUEUED; 1412 1413 if (wds_poll(sc, xs, scb->timeout)) { 1414 wds_timeout(scb); 1415 if (wds_poll(sc, xs, scb->timeout)) 1416 wds_timeout(scb); 1417 } 1418 return COMPLETE; 1419 1420 bad: 1421 xs->error = XS_DRIVER_STUFFUP; 1422 wds_free_scb(sc, scb); 1423 return COMPLETE; 1424 } 1425 1426 /* 1427 * Send a sense request. 1428 */ 1429 void 1430 wds_sense(sc, scb) 1431 struct wds_softc *sc; 1432 struct wds_scb *scb; 1433 { 1434 struct scsipi_xfer *xs = scb->xs; 1435 struct scsipi_sense *ss = (void *)&scb->sense.scb; 1436 int s; 1437 1438 /* XXXXX */ 1439 1440 /* Send sense request SCSI command. */ 1441 xs->error = XS_SENSE; 1442 scb->flags |= SCB_SENSE; 1443 1444 /* Next, setup a request sense command block */ 1445 bzero(ss, sizeof(*ss)); 1446 ss->opcode = REQUEST_SENSE; 1447 ss->byte2 = xs->sc_link->scsipi_scsi.lun << 5; 1448 ss->length = sizeof(struct scsipi_sense_data); 1449 1450 /* Set up some of the command fields. */ 1451 scb->sense.targ = scb->cmd.targ; 1452 scb->sense.write = 0x80; 1453 scb->sense.opcode = WDSX_SCSICMD; 1454 ltophys(scb->dmamap_self->dm_segs[0].ds_addr + 1455 offsetof(struct wds_scb, sense_data), scb->sense.data); 1456 ltophys(sizeof(struct scsipi_sense_data), scb->sense.len); 1457 1458 s = splbio(); 1459 wds_queue_scb(sc, scb); 1460 splx(s); 1461 1462 /* 1463 * There's no reason for us to poll here. There are two cases: 1464 * 1) If it's a polling operation, then we're called from the interrupt 1465 * handler, and we return and continue polling. 1466 * 2) If it's an interrupt-driven operation, then it gets completed 1467 * later on when the REQUEST SENSE finishes. 1468 */ 1469 } 1470 1471 /* 1472 * Poll a particular unit, looking for a particular scb 1473 */ 1474 int 1475 wds_poll(sc, xs, count) 1476 struct wds_softc *sc; 1477 struct scsipi_xfer *xs; 1478 int count; 1479 { 1480 bus_space_tag_t iot = sc->sc_iot; 1481 bus_space_handle_t ioh = sc->sc_ioh; 1482 1483 /* timeouts are in msec, so we loop in 1000 usec cycles */ 1484 while (count) { 1485 /* 1486 * If we had interrupts enabled, would we 1487 * have got an interrupt? 1488 */ 1489 if (bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) 1490 wdsintr(sc); 1491 if (xs->flags & ITSDONE) 1492 return 0; 1493 delay(1000); /* only happens in boot so ok */ 1494 count--; 1495 } 1496 return 1; 1497 } 1498 1499 /* 1500 * Poll a particular unit, looking for a particular scb 1501 */ 1502 int 1503 wds_ipoll(sc, scb, count) 1504 struct wds_softc *sc; 1505 struct wds_scb *scb; 1506 int count; 1507 { 1508 bus_space_tag_t iot = sc->sc_iot; 1509 bus_space_handle_t ioh = sc->sc_ioh; 1510 1511 /* timeouts are in msec, so we loop in 1000 usec cycles */ 1512 while (count) { 1513 /* 1514 * If we had interrupts enabled, would we 1515 * have got an interrupt? 1516 */ 1517 if (bus_space_read_1(iot, ioh, WDS_STAT) & WDSS_IRQ) 1518 wdsintr(sc); 1519 if (scb->flags & SCB_DONE) 1520 return 0; 1521 delay(1000); /* only happens in boot so ok */ 1522 count--; 1523 } 1524 return 1; 1525 } 1526 1527 void 1528 wds_timeout(arg) 1529 void *arg; 1530 { 1531 struct wds_scb *scb = arg; 1532 struct scsipi_xfer *xs = scb->xs; 1533 struct scsipi_link *sc_link = xs->sc_link; 1534 struct wds_softc *sc = sc_link->adapter_softc; 1535 int s; 1536 1537 scsi_print_addr(sc_link); 1538 printf("timed out"); 1539 1540 s = splbio(); 1541 1542 #ifdef WDSDIAG 1543 /* 1544 * If The scb's mbx is not free, then the board has gone south? 1545 */ 1546 wds_collect_mbo(sc); 1547 if (scb->flags & SCB_SENDING) { 1548 printf("%s: not taking commands!\n", sc->sc_dev.dv_xname); 1549 Debugger(); 1550 } 1551 #endif 1552 1553 /* 1554 * If it has been through before, then 1555 * a previous abort has failed, don't 1556 * try abort again 1557 */ 1558 if (scb->flags & SCB_ABORT) { 1559 /* abort timed out */ 1560 printf(" AGAIN\n"); 1561 /* XXX Must reset! */ 1562 } else { 1563 /* abort the operation that has timed out */ 1564 printf("\n"); 1565 scb->xs->error = XS_TIMEOUT; 1566 scb->timeout = WDS_ABORT_TIMEOUT; 1567 scb->flags |= SCB_ABORT; 1568 wds_queue_scb(sc, scb); 1569 } 1570 1571 splx(s); 1572 } 1573