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