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