1/* $NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $ */ 2/* NetBSD: bt.c,v 1.10 1996/05/12 23:51:54 mycroft Exp */ 3 4#undef BTDIAG 5#define integrate 6 7#define notyet /* XXX - #undef this, if this driver does actually work */ 8 9/* 10 * Copyright (c) 1994, 1996 Charles M. Hannum. All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. All advertising materials mentioning features or use of this software 21 * must display the following acknowledgement: 22 * This product includes software developed by Charles M. Hannum. 23 * 4. The name of the author may not be used to endorse or promote products 24 * derived from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * Originally written by Julian Elischer (julian@tfs.com) 40 * for TRW Financial Systems for use under the MACH(2.5) operating system. 41 * 42 * TRW Financial Systems, in accordance with their agreement with Carnegie 43 * Mellon University, makes this software available to CMU to distribute 44 * or use in any manner that they see fit as long as this message is kept with 45 * the software. For this reason TFS also grants any other persons or 46 * organisations permission to use or modify this software. 47 * 48 * TFS supplies this software to be publicly redistributed 49 * on the understanding that TFS is not responsible for the correct 50 * functioning of this software in any circumstances. 51 */ 52 53#include <sys/cdefs.h> 54__KERNEL_RCSID(0, "$NetBSD: btl.c,v 1.23 2009/11/27 03:23:04 rmind Exp $"); 55 56#include <sys/types.h> 57#include <sys/param.h> 58#include <sys/systm.h> 59#include <sys/kernel.h> 60#include <sys/errno.h> 61#include <sys/malloc.h> 62#include <sys/ioctl.h> 63#include <sys/device.h> 64#include <sys/buf.h> 65#include <sys/proc.h> 66 67#include <machine/intr.h> 68#include <machine/pio.h> 69 70#include <arc/dti/desktech.h> 71 72#include <dev/scsipi/scsi_all.h> 73#include <dev/scsipi/scsipi_all.h> 74#include <dev/scsipi/scsiconf.h> 75 76#include <dev/isa/isavar.h> 77#include <arc/dti/btlreg.h> 78#include <arc/dti/btlvar.h> 79 80#ifndef DDB 81#define Debugger() panic("should call debugger here (bt742a.c)") 82#endif /* ! DDB */ 83 84/* 85 * Mail box defs etc. 86 * these could be bigger but we need the bt_softc to fit on a single page.. 87 */ 88#define BT_MBX_SIZE 32 /* mail box size (MAX 255 MBxs) */ 89 /* don't need that many really */ 90#define BT_CCB_MAX 32 /* store up to 32 CCBs at one time */ 91#define CCB_HASH_SIZE 32 /* hash table size for phystokv */ 92#define CCB_HASH_SHIFT 9 93#define CCB_HASH(x) ((((long)(x))>>CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1)) 94 95#define bt_nextmbx(wmb, mbx, mbio) \ 96 if ((wmb) == &(mbx)->mbio[BT_MBX_SIZE - 1]) \ 97 (wmb) = &(mbx)->mbio[0]; \ 98 else \ 99 (wmb)++; 100 101struct bt_mbx { 102 struct bt_mbx_out mbo[BT_MBX_SIZE]; 103 struct bt_mbx_in mbi[BT_MBX_SIZE]; 104 struct bt_mbx_out *cmbo; /* Collection Mail Box out */ 105 struct bt_mbx_out *tmbo; /* Target Mail Box out */ 106 struct bt_mbx_in *tmbi; /* Target Mail Box in */ 107}; 108 109#define KVTOPHYS(x) (*btl_conf->bc_kvtophys)((int)(x)) 110#define PHYSTOKV(x) (*btl_conf->bc_phystokv)((int)(x)) 111 112struct bt_softc { 113 device_t sc_dev; 114 void *sc_ih; 115 116 int sc_iobase; 117 int sc_irq, sc_drq; 118 119 char sc_model[7], 120 sc_firmware[6]; 121 122 struct bt_mbx *sc_mbx; /* all our mailboxes */ 123#define wmbx (sc->sc_mbx) 124 struct bt_ccb *sc_ccbhash[CCB_HASH_SIZE]; 125 TAILQ_HEAD(, bt_ccb) sc_free_ccb, sc_waiting_ccb; 126 TAILQ_HEAD(, bt_buf) sc_free_buf; 127 int sc_numccbs, sc_mbofull; 128 int sc_numbufs; 129 int sc_scsi_dev; /* adapters scsi id */ 130 struct scsipi_link sc_link; /* prototype for devs */ 131 struct scsipi_adapter sc_adapter; 132}; 133 134#ifdef BTDEBUG 135int bt_debug = 0; 136#endif /* BTDEBUG */ 137 138int bt_cmd(int, struct bt_softc *, int, u_char *, int, u_char *); 139integrate void bt_finish_ccbs(struct bt_softc *); 140int btintr(void *); 141integrate void bt_reset_ccb(struct bt_softc *, struct bt_ccb *); 142void bt_free_ccb(struct bt_softc *, struct bt_ccb *); 143integrate void bt_init_ccb(struct bt_softc *, struct bt_ccb *); 144struct bt_ccb *bt_get_ccb(struct bt_softc *, int); 145struct bt_ccb *bt_ccb_phys_kv(struct bt_softc *, u_long); 146void bt_queue_ccb(struct bt_softc *, struct bt_ccb *); 147void bt_collect_mbo(struct bt_softc *); 148void bt_start_ccbs(struct bt_softc *); 149void bt_done(struct bt_softc *, struct bt_ccb *); 150int bt_find(struct isa_attach_args *, struct bt_softc *); 151void bt_init(struct bt_softc *); 152void bt_inquire_setup_information(struct bt_softc *); 153void btminphys(struct buf *); 154int bt_scsi_cmd(struct scsipi_xfer *); 155int bt_poll(struct bt_softc *, struct scsipi_xfer *, int); 156void bt_timeout(void *arg); 157void bt_free_buf(struct bt_softc *, struct bt_buf *); 158struct bt_buf * bt_get_buf(struct bt_softc *, int); 159 160/* the below structure is so we have a default dev struct for out link struct */ 161struct scsipi_device bt_dev = { 162 NULL, /* Use default error handler */ 163 NULL, /* have a queue, served by this */ 164 NULL, /* have no async handler */ 165 NULL, /* Use default 'done' routine */ 166}; 167 168static int btprobe(device_t, cfdata_t, void *); 169static void btattach(device_t, device_t, void *); 170 171CFATTACH_DECL_NEW(btl, sizeof(struct bt_softc), 172 btprobe, btattach, NULL, NULL); 173 174#define BT_RESET_TIMEOUT 2000 /* time to wait for reset (mSec) */ 175#define BT_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */ 176 177struct btl_config *btl_conf = NULL; 178 179/* 180 * bt_cmd(iobase, sc, icnt, ibuf, ocnt, obuf) 181 * 182 * Activate Adapter command 183 * icnt: number of args (outbound bytes including opcode) 184 * ibuf: argument buffer 185 * ocnt: number of expected returned bytes 186 * obuf: result buffer 187 * wait: number of seconds to wait for response 188 * 189 * Performs an adapter command through the ports. Not to be confused with a 190 * scsi command, which is read in via the DMA; one of the adapter commands 191 * tells it to read in a scsi command. 192 */ 193int 194bt_cmd(int iobase, struct bt_softc *sc, int icnt, int ocnt, u_char *ibuf, 195 u_char *obuf) 196{ 197 const char *name; 198 int i; 199 int wait; 200 u_char sts; 201 u_char opcode = ibuf[0]; 202 203 if (sc != NULL) 204 name = device_xname(sc->sc_dev); 205 else 206 name = "(bt probe)"; 207 208 /* 209 * Calculate a reasonable timeout for the command. 210 */ 211 switch (opcode) { 212 case BT_INQUIRE_DEVICES: 213 wait = 15 * 20000; 214 break; 215 default: 216 wait = 1 * 20000; 217 break; 218 } 219 220 /* 221 * Wait for the adapter to go idle, unless it's one of 222 * the commands which don't need this 223 */ 224 if (opcode != BT_MBO_INTR_EN) { 225 for (i = 20000; i; i--) { /* 1 sec? */ 226 sts = isa_inb(iobase + BT_STAT_PORT); 227 if (sts & BT_STAT_IDLE) 228 break; 229 delay(50); 230 } 231 if (!i) { 232 printf("%s: bt_cmd, host not idle(0x%x)\n", 233 name, sts); 234 return ENXIO; 235 } 236 } 237 /* 238 * Now that it is idle, if we expect output, preflush the 239 * queue feeding to us. 240 */ 241 if (ocnt) { 242 while ((isa_inb(iobase + BT_STAT_PORT)) & BT_STAT_DF) 243 isa_inb(iobase + BT_DATA_PORT); 244 } 245 /* 246 * Output the command and the number of arguments given 247 * for each byte, first check the port is empty. 248 */ 249 while (icnt--) { 250 for (i = wait; i; i--) { 251 sts = isa_inb(iobase + BT_STAT_PORT); 252 if (!(sts & BT_STAT_CDF)) 253 break; 254 delay(50); 255 } 256 if (!i) { 257 if (opcode != BT_INQUIRE_REVISION && 258 opcode != BT_INQUIRE_REVISION_3) 259 printf("%s: bt_cmd, cmd/data port full\n", name); 260 isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST); 261 return ENXIO; 262 } 263 isa_outb(iobase + BT_CMD_PORT, *ibuf++); 264 } 265 /* 266 * If we expect input, loop that many times, each time, 267 * looking for the data register to have valid data 268 */ 269 while (ocnt--) { 270 for (i = wait; i; i--) { 271 sts = isa_inb(iobase + BT_STAT_PORT); 272 if (sts & BT_STAT_DF) 273 break; 274 delay(50); 275 } 276 if (!i) { 277 if (opcode != BT_INQUIRE_REVISION && 278 opcode != BT_INQUIRE_REVISION_3) 279 printf("%s: bt_cmd, cmd/data port empty %d\n", 280 name, ocnt); 281 isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_SRST); 282 return ENXIO; 283 } 284 *obuf++ = isa_inb(iobase + BT_DATA_PORT); 285 } 286 /* 287 * Wait for the board to report a finished instruction. 288 * We may get an extra interrupt for the HACC signal, but this is 289 * unimportant. 290 */ 291 if (opcode != BT_MBO_INTR_EN) { 292 for (i = 20000; i; i--) { /* 1 sec? */ 293 sts = isa_inb(iobase + BT_INTR_PORT); 294 /* XXX Need to save this in the interrupt handler? */ 295 if (sts & BT_INTR_HACC) 296 break; 297 delay(50); 298 } 299 if (!i) { 300 printf("%s: bt_cmd, host not finished(0x%x)\n", 301 name, sts); 302 return ENXIO; 303 } 304 } 305 isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST); 306 return 0; 307} 308 309/* 310 * Check if the device can be found at the port given 311 * and if so, set it up ready for further work 312 * as an argument, takes the isa_device structure from 313 * autoconf.c 314 */ 315static int 316btprobe(device_t parent, cfdata_t cf, void *aux) 317{ 318 struct isa_attach_args *ia = aux; 319 320#ifdef NEWCONFIG 321 if (ia->ia_iobase == IOBASEUNK) 322 return 0; 323#endif 324 325 if (btl_conf == NULL) 326 return (0); 327 328 /* See if there is a unit at this location. */ 329 if (bt_find(ia, NULL) != 0) 330 return 0; 331 332 ia->ia_msize = 0; 333 ia->ia_iosize = 4; 334 /* IRQ and DRQ set by bt_find(). */ 335 return 1; 336} 337 338/* 339 * Attach all the sub-devices we can find 340 */ 341static void 342btattach(device_t parent, device_t self, void *aux) 343{ 344 struct isa_attach_args *ia = aux; 345 struct bt_softc *sc = device_private(self); 346 struct bt_ccb *ccb; 347 struct bt_buf *buf; 348 u_int bouncearea; 349 u_int bouncebase; 350 u_int bouncesize; 351 352 sc->sc_dev = self; 353 354 if (bt_find(ia, sc) != 0) 355 panic("btattach: bt_find of %s failed", self->dv_xname); 356 sc->sc_iobase = ia->ia_iobase; 357 358 /* 359 * create mbox area 360 */ 361 (*btl_conf->bc_bouncemem)(&bouncebase, &bouncesize); 362 bouncearea = bouncebase + sizeof(struct bt_mbx); 363 sc->sc_mbx = (struct bt_mbx *)bouncebase; 364 365 bt_inquire_setup_information(sc); 366 bt_init(sc); 367 TAILQ_INIT(&sc->sc_free_ccb); 368 TAILQ_INIT(&sc->sc_free_buf); 369 TAILQ_INIT(&sc->sc_waiting_ccb); 370 371 /* 372 * fill up with ccb's 373 */ 374 while (sc->sc_numccbs < BT_CCB_MAX) { 375 ccb = (struct bt_ccb *)bouncearea; 376 bouncearea += sizeof(struct bt_ccb); 377 bt_init_ccb(sc, ccb); 378 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); 379 sc->sc_numccbs++; 380 } 381 /* 382 * fill up with bufs's 383 */ 384 while ((bouncearea + sizeof(struct bt_buf)) < bouncebase + bouncesize) { 385 buf = (struct bt_buf *)bouncearea; 386 bouncearea += sizeof(struct bt_buf); 387 TAILQ_INSERT_HEAD(&sc->sc_free_buf, buf, chain); 388 sc->sc_numbufs++; 389 } 390 /* 391 * Fill in the adapter. 392 */ 393 sc->sc_adapter.scsipi_cmd = bt_scsi_cmd; 394 sc->sc_adapter.scsipi_minphys = btminphys; 395 /* 396 * fill in the prototype scsipi_link. 397 */ 398 sc->sc_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE; 399 sc->sc_link.adapter_softc = sc; 400 sc->sc_link.scsipi_scsi.adapter_target = sc->sc_scsi_dev; 401 sc->sc_link.adapter = &sc->sc_adapter; 402 sc->sc_link.device = &bt_dev; 403 sc->sc_link.openings = 1; 404 sc->sc_link.scsipi_scsi.max_target = 7; 405 sc->sc_link.scsipi_scsi.max_lun = 7; 406 sc->sc_link.type = BUS_SCSI; 407 408 sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE, 409 IPL_BIO, btintr, sc); 410 411 /* 412 * ask the adapter what subunits are present 413 */ 414 config_found(self, &sc->sc_link, scsiprint); 415} 416 417integrate void 418bt_finish_ccbs(struct bt_softc *sc) 419{ 420 struct bt_mbx_in *wmbi; 421 struct bt_ccb *ccb; 422 int i; 423 424 wmbi = wmbx->tmbi; 425 426 if (wmbi->stat == BT_MBI_FREE) { 427 for (i = 0; i < BT_MBX_SIZE; i++) { 428 if (wmbi->stat != BT_MBI_FREE) { 429 printf("%s: mbi not in round-robin order\n", 430 device_xname(sc->sc_dev)); 431 goto AGAIN; 432 } 433 bt_nextmbx(wmbi, wmbx, mbi); 434 } 435#ifdef BTDIAGnot 436 printf("%s: mbi interrupt with no full mailboxes\n", 437 device_xname(sc->sc_dev)); 438#endif 439 return; 440 } 441 442AGAIN: 443 do { 444 ccb = bt_ccb_phys_kv(sc, phystol(wmbi->ccb_addr)); 445 if (!ccb) { 446 printf("%s: bad mbi ccb pointer; skipping\n", 447 device_xname(sc->sc_dev)); 448 goto next; 449 } 450 451#ifdef BTDEBUG 452 if (bt_debug) { 453 u_char *cp = (u_char *) &ccb->scsi_cmd; 454 printf("op=%x %x %x %x %x %x\n", 455 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 456 printf("stat %x for mbi addr = 0x%08x, ", 457 wmbi->stat, wmbi); 458 printf("ccb addr = 0x%x\n", ccb); 459 } 460#endif /* BTDEBUG */ 461 462 switch (wmbi->stat) { 463 case BT_MBI_OK: 464 case BT_MBI_ERROR: 465 if ((ccb->flags & CCB_ABORT) != 0) { 466 /* 467 * If we already started an abort, wait for it 468 * to complete before clearing the CCB. We 469 * could instead just clear CCB_SENDING, but 470 * what if the mailbox was already received? 471 * The worst that happens here is that we clear 472 * the CCB a bit later than we need to. BFD. 473 */ 474 goto next; 475 } 476 break; 477 478 case BT_MBI_ABORT: 479 case BT_MBI_UNKNOWN: 480 /* 481 * Even if the CCB wasn't found, we clear it anyway. 482 * See preceding comment. 483 */ 484 break; 485 486 default: 487 printf("%s: bad mbi status %02x; skipping\n", 488 device_xname(sc->sc_dev), wmbi->stat); 489 goto next; 490 } 491 492 callout_stop(&ccb->xs->xs_callout); 493 bt_done(sc, ccb); 494 495 next: 496 wmbi->stat = BT_MBI_FREE; 497 bt_nextmbx(wmbi, wmbx, mbi); 498 } while (wmbi->stat != BT_MBI_FREE); 499 500 wmbx->tmbi = wmbi; 501} 502 503/* 504 * Catch an interrupt from the adaptor 505 */ 506int 507btintr(void *arg) 508{ 509 struct bt_softc *sc = arg; 510 int iobase = sc->sc_iobase; 511 u_char sts; 512 513#ifdef BTDEBUG 514 printf("%s: btintr ", device_xname(sc->sc_dev)); 515#endif /* BTDEBUG */ 516 517 /* 518 * First acknowlege the interrupt, Then if it's not telling about 519 * a completed operation just return. 520 */ 521 sts = isa_inb(iobase + BT_INTR_PORT); 522 if ((sts & BT_INTR_ANYINTR) == 0) 523 return 0; 524 isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_IRST); 525 526#ifdef BTDIAG 527 /* Make sure we clear CCB_SENDING before finishing a CCB. */ 528 bt_collect_mbo(sc); 529#endif 530 531 /* Mail box out empty? */ 532 if (sts & BT_INTR_MBOA) { 533 struct bt_toggle toggle; 534 535 toggle.cmd.opcode = BT_MBO_INTR_EN; 536 toggle.cmd.enable = 0; 537 bt_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd, 0, 538 (u_char *)0); 539 bt_start_ccbs(sc); 540 } 541 542 /* Mail box in full? */ 543 if (sts & BT_INTR_MBIF) 544 bt_finish_ccbs(sc); 545 546 return 1; 547} 548 549integrate void 550bt_reset_ccb(struct bt_softc *sc, struct bt_ccb *ccb) 551{ 552 553 ccb->flags = 0; 554} 555 556/* 557 * A ccb is put onto the free list. 558 */ 559void 560bt_free_ccb(struct bt_softc *sc, struct bt_ccb *ccb) 561{ 562 int s; 563 564 s = splbio(); 565 566 bt_reset_ccb(sc, ccb); 567 TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain); 568 569 /* 570 * If there were none, wake anybody waiting for one to come free, 571 * starting with queued entries. 572 */ 573 if (ccb->chain.tqe_next == 0) 574 wakeup(&sc->sc_free_ccb); 575 576 splx(s); 577} 578 579/* 580 * A buf is put onto the free list. 581 */ 582void 583bt_free_buf(struct bt_softc *sc, struct bt_buf *buf) 584{ 585 int s; 586 587 s = splbio(); 588 589 TAILQ_INSERT_HEAD(&sc->sc_free_buf, buf, chain); 590 sc->sc_numbufs++; 591 592 /* 593 * If there were none, wake anybody waiting for one to come free, 594 * starting with queued entries. 595 */ 596 if (buf->chain.tqe_next == 0) 597 wakeup(&sc->sc_free_buf); 598 599 splx(s); 600} 601 602integrate void 603bt_init_ccb(struct bt_softc *sc, struct bt_ccb *ccb) 604{ 605 int hashnum; 606 607 memset(ccb, 0, sizeof(struct bt_ccb)); 608 /* 609 * put in the phystokv hash table 610 * Never gets taken out. 611 */ 612 ccb->hashkey = KVTOPHYS(ccb); 613 hashnum = CCB_HASH(ccb->hashkey); 614 ccb->nexthash = sc->sc_ccbhash[hashnum]; 615 sc->sc_ccbhash[hashnum] = ccb; 616 bt_reset_ccb(sc, ccb); 617} 618 619/* 620 * Get a free ccb 621 * 622 * If there are none, either return an error or sleep. 623 */ 624struct bt_ccb * 625bt_get_ccb(struct bt_softc *sc, int nosleep) 626{ 627 struct bt_ccb *ccb; 628 int s; 629 630 s = splbio(); 631 632 /* 633 * If we can and have to, sleep waiting for one to come free. 634 */ 635 for (;;) { 636 ccb = sc->sc_free_ccb.tqh_first; 637 if (ccb) { 638 TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain); 639 break; 640 } 641 if (nosleep) 642 goto out; 643 tsleep(&sc->sc_free_ccb, PRIBIO, "btccb", 0); 644 } 645 646 ccb->flags |= CCB_ALLOC; 647 648out: 649 splx(s); 650 return ccb; 651} 652 653/* 654 * Get a free buf 655 * 656 * If there are none, either return an error or sleep. 657 */ 658struct bt_buf * 659bt_get_buf(struct bt_softc *sc, int nosleep) 660{ 661 struct bt_buf *buf; 662 int s; 663 664 s = splbio(); 665 666 /* 667 * If we can and have to, sleep waiting for one to come free. 668 */ 669 for (;;) { 670 buf = sc->sc_free_buf.tqh_first; 671 if (buf) { 672 TAILQ_REMOVE(&sc->sc_free_buf, buf, chain); 673 sc->sc_numbufs--; 674 break; 675 } 676 if (nosleep) 677 goto out; 678 tsleep(&sc->sc_free_buf, PRIBIO, "btbuf", 0); 679 } 680 681out: 682 splx(s); 683 return buf; 684} 685 686/* 687 * Given a physical address, find the ccb that it corresponds to. 688 */ 689struct bt_ccb * 690bt_ccb_phys_kv(struct bt_softc *sc, u_long ccb_phys) 691{ 692 int hashnum = CCB_HASH(ccb_phys); 693 struct bt_ccb *ccb = sc->sc_ccbhash[hashnum]; 694 695 while (ccb) { 696 if (ccb->hashkey == ccb_phys) 697 break; 698 ccb = ccb->nexthash; 699 } 700 return ccb; 701} 702 703/* 704 * Queue a CCB to be sent to the controller, and send it if possible. 705 */ 706void 707bt_queue_ccb(struct bt_softc *sc, struct bt_ccb *ccb) 708{ 709 710 TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain); 711 bt_start_ccbs(sc); 712} 713 714/* 715 * Garbage collect mailboxes that are no longer in use. 716 */ 717void 718bt_collect_mbo(struct bt_softc *sc) 719{ 720 struct bt_mbx_out *wmbo; /* Mail Box Out pointer */ 721 722 wmbo = wmbx->cmbo; 723 724 while (sc->sc_mbofull > 0) { 725 if (wmbo->cmd != BT_MBO_FREE) 726 break; 727 728#ifdef BTDIAG 729 ccb = bt_ccb_phys_kv(sc, phystol(wmbo->ccb_addr)); 730 ccb->flags &= ~CCB_SENDING; 731#endif 732 733 --sc->sc_mbofull; 734 bt_nextmbx(wmbo, wmbx, mbo); 735 } 736 737 wmbx->cmbo = wmbo; 738} 739 740/* 741 * Send as many CCBs as we have empty mailboxes for. 742 */ 743void 744bt_start_ccbs(struct bt_softc *sc) 745{ 746 int iobase = sc->sc_iobase; 747 struct bt_mbx_out *wmbo; /* Mail Box Out pointer */ 748 struct bt_ccb *ccb; 749 750 wmbo = wmbx->tmbo; 751 752 while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) { 753 if (sc->sc_mbofull >= BT_MBX_SIZE) { 754 bt_collect_mbo(sc); 755 if (sc->sc_mbofull >= BT_MBX_SIZE) { 756 struct bt_toggle toggle; 757 758 toggle.cmd.opcode = BT_MBO_INTR_EN; 759 toggle.cmd.enable = 1; 760 bt_cmd(iobase, sc, sizeof(toggle.cmd), 761 (u_char *)&toggle.cmd, 0, (u_char *)0); 762 break; 763 } 764 } 765 766 TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain); 767#ifdef BTDIAG 768 ccb->flags |= CCB_SENDING; 769#endif 770 771 /* Link ccb to mbo. */ 772 ltophys(KVTOPHYS(ccb), wmbo->ccb_addr); 773 if (ccb->flags & CCB_ABORT) 774 wmbo->cmd = BT_MBO_ABORT; 775 else 776 wmbo->cmd = BT_MBO_START; 777 778 /* Tell the card to poll immediately. */ 779 isa_outb(iobase + BT_CMD_PORT, BT_START_SCSI); 780 781 if ((ccb->xs->xs_control & XS_CTL_POLL) == 0) 782 callout_reset(&ccb->xs->xs_callout, 783 mstohz(ccb->timeout), bt_timeout, ccb); 784 785 ++sc->sc_mbofull; 786 bt_nextmbx(wmbo, wmbx, mbo); 787 } 788 789 wmbx->tmbo = wmbo; 790} 791 792/* 793 * We have a ccb which has been processed by the 794 * adaptor, now we look to see how the operation 795 * went. Wake up the owner if waiting 796 */ 797void 798bt_done(struct bt_softc *sc, struct bt_ccb *ccb) 799{ 800 struct scsi_sense_data *s1, *s2; 801 struct scsipi_xfer *xs = ccb->xs; 802 803 u_long thiskv, thisbounce; 804 int bytes_this_page, datalen; 805 struct bt_scat_gath *sg; 806 int seg; 807 808 SC_DEBUG(xs->sc_link, SDEV_DB2, ("bt_done\n")); 809 /* 810 * Otherwise, put the results of the operation 811 * into the xfer and call whoever started it 812 */ 813#ifdef BTDIAG 814 if (ccb->flags & CCB_SENDING) { 815 printf("%s: exiting ccb still in transit!\n", 816 device_xname(sc->sc_dev)); 817 Debugger(); 818 return; 819 } 820#endif 821 if ((ccb->flags & CCB_ALLOC) == 0) { 822 printf("%s: exiting ccb not allocated!\n", 823 device_xname(sc->sc_dev)); 824 Debugger(); 825 return; 826 } 827 if (xs->error == XS_NOERROR) { 828 if (ccb->host_stat != BT_OK) { 829 switch (ccb->host_stat) { 830 case BT_SEL_TIMEOUT: /* No response */ 831 xs->error = XS_SELTIMEOUT; 832 break; 833 default: /* Other scsi protocol messes */ 834 printf("%s: host_stat %x\n", 835 device_xname(sc->sc_dev), ccb->host_stat); 836 xs->error = XS_DRIVER_STUFFUP; 837 break; 838 } 839 } else if (ccb->target_stat != SCSI_OK) { 840 switch (ccb->target_stat) { 841 case SCSI_CHECK: 842 s1 = &ccb->scsi_sense; 843 s2 = &xs->sense.scsi_sense; 844 *s2 = *s1; 845 xs->error = XS_SENSE; 846 break; 847 case SCSI_BUSY: 848 xs->error = XS_BUSY; 849 break; 850 default: 851 printf("%s: target_stat %x\n", 852 device_xname(sc->sc_dev), ccb->target_stat); 853 xs->error = XS_DRIVER_STUFFUP; 854 break; 855 } 856 } else 857 xs->resid = 0; 858 } 859 860 if((datalen = xs->datalen) != 0) { 861 thiskv = (int)xs->data; 862 sg = ccb->scat_gath; 863 seg = phystol(ccb->data_length) / sizeof(struct bt_scat_gath); 864 865 while (seg) { 866 thisbounce = PHYSTOKV(phystol(sg->seg_addr)); 867 bytes_this_page = phystol(sg->seg_len); 868 if(xs->xs_control & XS_CTL_DATA_IN) { 869 memcpy((void *)thiskv, (void *)thisbounce, bytes_this_page); 870 } 871 bt_free_buf(sc, (struct bt_buf *)thisbounce); 872 thiskv += bytes_this_page; 873 datalen -= bytes_this_page; 874 875 sg++; 876 seg--; 877 } 878 } 879 880 bt_free_ccb(sc, ccb); 881 xs->xs_status |= XS_STS_DONE; 882 scsipi_done(xs); 883} 884 885/* 886 * Find the board and find it's irq/drq 887 */ 888int 889bt_find(struct isa_attach_args *ia, struct bt_softc *sc) 890{ 891 int iobase = ia->ia_iobase; 892 int i; 893 u_char sts; 894 struct bt_extended_inquire inquire; 895 struct bt_config config; 896 int irq, drq; 897 898#ifndef notyet 899 /* Check something is at the ports we need to access */ 900 sts = isa_inb(iobase + BHA_STAT_PORT); 901 if (sts == 0xFF) 902 return (0); 903#endif 904 905 /* 906 * reset board, If it doesn't respond, assume 907 * that it's not there.. good for the probe 908 */ 909 910 isa_outb(iobase + BT_CTRL_PORT, BT_CTRL_HRST | BT_CTRL_SRST); 911 912 delay(100); 913 for (i = BT_RESET_TIMEOUT; i; i--) { 914 sts = isa_inb(iobase + BT_STAT_PORT); 915 if (sts == (BT_STAT_IDLE | BT_STAT_INIT)) 916 break; 917 delay(1000); 918 } 919 if (!i) { 920#ifdef BTDEBUG 921 if (bt_debug) 922 printf("bt_find: No answer from buslogic board\n"); 923#endif /* BTDEBUG */ 924 return 1; 925 } 926 927#ifndef notyet 928 /* 929 * The BusLogic cards implement an Adaptec 1542 (aha)-compatible 930 * interface. The native bha interface is not compatible with 931 * an aha. 1542. We need to ensure that we never match an 932 * Adaptec 1542. We must also avoid sending Adaptec-compatible 933 * commands to a real bha, lest it go into 1542 emulation mode. 934 * (On an indirect bus like ISA, we should always probe for BusLogic 935 * interfaces before Adaptec interfaces). 936 */ 937 938 /* 939 * Make sure we don't match an AHA-1542A or AHA-1542B, by checking 940 * for an extended-geometry register. The 1542[AB] don't have one. 941 */ 942 sts = isa_inb(iobase + BT_EXTGEOM_PORT); 943 if (sts == 0xFF) 944 return (0); 945#endif /* notyet */ 946 947 /* 948 * Check that we actually know how to use this board. 949 */ 950 delay(1000); 951 memset(&inquire, 0, sizeof inquire); 952 inquire.cmd.opcode = BT_INQUIRE_EXTENDED; 953 inquire.cmd.len = sizeof(inquire.reply); 954 i = bt_cmd(iobase, sc, sizeof(inquire.cmd), (u_char *)&inquire.cmd, 955 sizeof(inquire.reply), (u_char *)&inquire.reply); 956 957#ifndef notyet 958 /* 959 * Some 1542Cs (CP, perhaps not CF, may depend on firmware rev) 960 * have the extended-geometry register and also respond to 961 * BHA_INQUIRE_EXTENDED. Make sure we never match such cards, 962 * by checking the size of the reply is what a BusLogic card returns. 963 */ 964 if (i) { /* XXX - this doesn't really check the size. ??? see bha.c */ 965#ifdef BTDEBUG 966 printf("bt_find: board returned %d instead of %d to %s\n", 967 i, sizeof(inquire.reply), "INQUIRE_EXTENDED"); 968#endif 969 return (0); 970 } 971 972 /* OK, we know we've found a buslogic adaptor. */ 973#endif /* notyet */ 974 975 switch (inquire.reply.bus_type) { 976 case BT_BUS_TYPE_24BIT: 977 case BT_BUS_TYPE_32BIT: 978 break; 979 case BT_BUS_TYPE_MCA: 980 /* We don't grok MicroChannel (yet). */ 981 return 1; 982 default: 983 printf("bt_find: illegal bus type %c\n", inquire.reply.bus_type); 984 return 1; 985 } 986 987 /* 988 * Assume we have a board at this stage setup DMA channel from 989 * jumpers and save int level 990 */ 991 delay(1000); 992 config.cmd.opcode = BT_INQUIRE_CONFIG; 993 bt_cmd(iobase, sc, sizeof(config.cmd), (u_char *)&config.cmd, 994 sizeof(config.reply), (u_char *)&config.reply); 995 switch (config.reply.chan) { 996 case EISADMA: 997 drq = DRQUNK; 998 break; 999 case CHAN0: 1000 drq = 0; 1001 break; 1002 case CHAN5: 1003 drq = 5; 1004 break; 1005 case CHAN6: 1006 drq = 6; 1007 break; 1008 case CHAN7: 1009 drq = 7; 1010 break; 1011 default: 1012 printf("bt_find: illegal drq setting %x\n", config.reply.chan); 1013 return 1; 1014 } 1015 1016 switch (config.reply.intr) { 1017 case INT9: 1018 irq = 9; 1019 break; 1020 case INT10: 1021 irq = 10; 1022 break; 1023 case INT11: 1024 irq = 11; 1025 break; 1026 case INT12: 1027 irq = 12; 1028 break; 1029 case INT14: 1030 irq = 14; 1031 break; 1032 case INT15: 1033 irq = 15; 1034 break; 1035 default: 1036 printf("bt_find: illegal irq setting %x\n", config.reply.intr); 1037 return 1; 1038 } 1039 1040 if (sc != NULL) { 1041 /* who are we on the scsi bus? */ 1042 sc->sc_scsi_dev = config.reply.scsi_dev; 1043 1044 sc->sc_iobase = iobase; 1045 sc->sc_irq = irq; 1046 sc->sc_drq = drq; 1047 } else { 1048 if (ia->ia_irq == IRQUNK) 1049 ia->ia_irq = irq; 1050 else if (ia->ia_irq != irq) 1051 return 1; 1052 if (ia->ia_drq == DRQUNK) 1053 ia->ia_drq = drq; 1054 else if (ia->ia_drq != drq) 1055 return 1; 1056 } 1057 1058 return 0; 1059} 1060 1061/* 1062 * Start the board, ready for normal operation 1063 */ 1064void 1065bt_init(struct bt_softc *sc) 1066{ 1067 int iobase = sc->sc_iobase; 1068 struct bt_devices devices; 1069 struct bt_setup setup; 1070 struct bt_mailbox mailbox; 1071 struct bt_period period; 1072 int i; 1073 1074 /* Enable round-robin scheme - appeared at firmware rev. 3.31. */ 1075 if (strcmp(sc->sc_firmware, "3.31") >= 0) { 1076 struct bt_toggle toggle; 1077 1078 toggle.cmd.opcode = BT_ROUND_ROBIN; 1079 toggle.cmd.enable = 1; 1080 bt_cmd(iobase, sc, sizeof(toggle.cmd), (u_char *)&toggle.cmd, 1081 0, (u_char *)0); 1082 } 1083 1084 /* Inquire Installed Devices (to force synchronous negotiation). */ 1085 devices.cmd.opcode = BT_INQUIRE_DEVICES; 1086 bt_cmd(iobase, sc, sizeof(devices.cmd), (u_char *)&devices.cmd, 1087 sizeof(devices.reply), (u_char *)&devices.reply); 1088 1089 /* Obtain setup information from. */ 1090 setup.cmd.opcode = BT_INQUIRE_SETUP; 1091 setup.cmd.len = sizeof(setup.reply); 1092 bt_cmd(iobase, sc, sizeof(setup.cmd), (u_char *)&setup.cmd, 1093 sizeof(setup.reply), (u_char *)&setup.reply); 1094 1095 printf("%s: %s, %s\n", 1096 device_xname(sc->sc_dev), 1097 setup.reply.sync_neg ? "sync" : "async", 1098 setup.reply.parity ? "parity" : "no parity"); 1099 1100 for (i = 0; i < 8; i++) 1101 period.reply.period[i] = setup.reply.sync[i].period * 5 + 20; 1102 1103 if (sc->sc_firmware[0] >= '3') { 1104 period.cmd.opcode = BT_INQUIRE_PERIOD; 1105 period.cmd.len = sizeof(period.reply); 1106 bt_cmd(iobase, sc, sizeof(period.cmd), (u_char *)&period.cmd, 1107 sizeof(period.reply), (u_char *)&period.reply); 1108 } 1109 1110 for (i = 0; i < 8; i++) { 1111 if (!setup.reply.sync[i].valid || 1112 (!setup.reply.sync[i].offset && !setup.reply.sync[i].period)) 1113 continue; 1114 printf("%s targ %d: sync, offset %d, period %dnsec\n", 1115 device_xname(sc->sc_dev), i, 1116 setup.reply.sync[i].offset, period.reply.period[i] * 10); 1117 } 1118 1119 /* 1120 * Set up initial mail box for round-robin operation. 1121 */ 1122 for (i = 0; i < BT_MBX_SIZE; i++) { 1123 wmbx->mbo[i].cmd = BT_MBO_FREE; 1124 wmbx->mbi[i].stat = BT_MBI_FREE; 1125 } 1126 wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0]; 1127 wmbx->tmbi = &wmbx->mbi[0]; 1128 sc->sc_mbofull = 0; 1129 1130 /* Initialize mail box. */ 1131 mailbox.cmd.opcode = BT_MBX_INIT_EXTENDED; 1132 mailbox.cmd.nmbx = BT_MBX_SIZE; 1133 ltophys(KVTOPHYS(wmbx), mailbox.cmd.addr); 1134 bt_cmd(iobase, sc, sizeof(mailbox.cmd), (u_char *)&mailbox.cmd, 1135 0, (u_char *)0); 1136} 1137 1138void 1139bt_inquire_setup_information(struct bt_softc *sc) 1140{ 1141 int iobase = sc->sc_iobase; 1142 struct bt_model model; 1143 struct bt_revision revision; 1144 struct bt_digit digit; 1145 char *p; 1146 1147 /* 1148 * Get the firmware revision. 1149 */ 1150 p = sc->sc_firmware; 1151 revision.cmd.opcode = BT_INQUIRE_REVISION; 1152 bt_cmd(iobase, sc, sizeof(revision.cmd), (u_char *)&revision.cmd, 1153 sizeof(revision.reply), (u_char *)&revision.reply); 1154 *p++ = revision.reply.firm_revision; 1155 *p++ = '.'; 1156 *p++ = revision.reply.firm_version; 1157 digit.cmd.opcode = BT_INQUIRE_REVISION_3; 1158 bt_cmd(iobase, sc, sizeof(digit.cmd), (u_char *)&digit.cmd, 1159 sizeof(digit.reply), (u_char *)&digit.reply); 1160 *p++ = digit.reply.digit; 1161 if (revision.reply.firm_revision >= '3' || 1162 (revision.reply.firm_revision == '3' && revision.reply.firm_version >= '3')) { 1163 digit.cmd.opcode = BT_INQUIRE_REVISION_4; 1164 bt_cmd(iobase, sc, sizeof(digit.cmd), (u_char *)&digit.cmd, 1165 sizeof(digit.reply), (u_char *)&digit.reply); 1166 *p++ = digit.reply.digit; 1167 } 1168 while (p > sc->sc_firmware && (p[-1] == ' ' || p[-1] == '\0')) 1169 p--; 1170 *p = '\0'; 1171 1172 /* 1173 * Get the model number. 1174 */ 1175 if (revision.reply.firm_revision >= '3') { 1176 p = sc->sc_model; 1177 model.cmd.opcode = BT_INQUIRE_MODEL; 1178 model.cmd.len = sizeof(model.reply); 1179 bt_cmd(iobase, sc, sizeof(model.cmd), (u_char *)&model.cmd, 1180 sizeof(model.reply), (u_char *)&model.reply); 1181 *p++ = model.reply.id[0]; 1182 *p++ = model.reply.id[1]; 1183 *p++ = model.reply.id[2]; 1184 *p++ = model.reply.id[3]; 1185 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0')) 1186 p--; 1187 *p++ = model.reply.version[0]; 1188 *p++ = model.reply.version[1]; 1189 while (p > sc->sc_model && (p[-1] == ' ' || p[-1] == '\0')) 1190 p--; 1191 *p = '\0'; 1192 } else 1193 strcpy(sc->sc_model, "542B"); 1194 1195 printf(": model BT-%s, firmware %s\n", sc->sc_model, sc->sc_firmware); 1196} 1197 1198void 1199btminphys(struct buf *bp) 1200{ 1201 1202 if (bp->b_bcount > ((BT_NSEG - 1) << PGSHIFT)) 1203 bp->b_bcount = ((BT_NSEG - 1) << PGSHIFT); 1204 minphys(bp); 1205} 1206 1207/* 1208 * start a scsi operation given the command and the data address. Also needs 1209 * the unit, target and lu. 1210 */ 1211int 1212bt_scsi_cmd(struct scsipi_xfer *xs) 1213{ 1214 struct scsipi_link *sc_link = xs->sc_link; 1215 struct bt_softc *sc = sc_link->adapter_softc; 1216 struct bt_ccb *ccb; 1217 struct bt_scat_gath *sg; 1218 int seg; /* scatter gather seg being worked on */ 1219 u_long thiskv, thisbounce; 1220 int bytes_this_page, datalen, control; 1221 int s; 1222 1223 SC_DEBUG(sc_link, SDEV_DB2, ("bt_scsi_cmd\n")); 1224 /* 1225 * get a ccb to use. If the transfer 1226 * is from a buf (possibly from interrupt time) 1227 * then we can't allow it to sleep 1228 */ 1229 control = xs->xs_control; 1230 if ((ccb = bt_get_ccb(sc, control & XS_CTL_NOSLEEP)) == NULL) { 1231 xs->error = XS_DRIVER_STUFFUP; 1232 return TRY_AGAIN_LATER; 1233 } 1234 ccb->xs = xs; 1235 ccb->timeout = xs->timeout; 1236 1237 /* 1238 * Put all the arguments for the xfer in the ccb 1239 */ 1240 if (control & XS_CTL_RESET) { 1241 ccb->opcode = BT_RESET_CCB; 1242 ccb->scsi_cmd_length = 0; 1243 } else { 1244 /* can't use S/G if zero length */ 1245 if (xs->cmdlen > sizeof(ccb->scsi_cmd)) { 1246 printf("%s: cmdlen %d too large for CCB\n", 1247 device_xname(sc->sc_dev), xs->cmdlen); 1248 xs->error = XS_DRIVER_STUFFUP; 1249 bt_free_ccb(sc, ccb); 1250 return COMPLETE; 1251 } 1252 ccb->opcode = (xs->datalen ? BT_INIT_SCAT_GATH_CCB 1253 : BT_INITIATOR_CCB); 1254 memcpy(&ccb->scsi_cmd, xs->cmd, 1255 ccb->scsi_cmd_length = xs->cmdlen); 1256 } 1257 1258 if (xs->datalen) { 1259 sg = ccb->scat_gath; 1260 seg = 0; 1261 /* 1262 * Set up the scatter-gather block. 1263 */ 1264 SC_DEBUG(sc_link, SDEV_DB4, 1265 ("%d @0x%x:- ", xs->datalen, xs->data)); 1266 1267 datalen = xs->datalen; 1268 thiskv = (int)xs->data; 1269 1270 while (datalen && seg < BT_NSEG) { 1271 1272 /* put in the base address of a buf */ 1273 thisbounce = (u_long) 1274 bt_get_buf(sc, control & XS_CTL_NOSLEEP); 1275 if(thisbounce == 0) 1276 break; 1277 ltophys(KVTOPHYS(thisbounce), sg->seg_addr); 1278 bytes_this_page = min(sizeof(struct bt_buf), datalen); 1279 if (control & XS_CTL_DATA_OUT) { 1280 memcpy((void *)thisbounce, (void *)thiskv, bytes_this_page); 1281 } 1282 thiskv += bytes_this_page; 1283 datalen -= bytes_this_page; 1284 1285 ltophys(bytes_this_page, sg->seg_len); 1286 sg++; 1287 seg++; 1288 } 1289 SC_DEBUGN(sc_link, SDEV_DB4, ("\n")); 1290 if (datalen) { 1291 printf("%s: bt_scsi_cmd, out of bufs %d of %d left.\n", 1292 device_xname(sc->sc_dev), datalen, xs->datalen); 1293 goto badbuf; 1294 } 1295 ltophys(KVTOPHYS(ccb->scat_gath), ccb->data_addr); 1296 ltophys(seg * sizeof(struct bt_scat_gath), ccb->data_length); 1297 } else { /* No data xfer, use non S/G values */ 1298 ltophys(0, ccb->data_addr); 1299 ltophys(0, ccb->data_length); 1300 } 1301 1302 ccb->data_out = 0; 1303 ccb->data_in = 0; 1304 ccb->target = sc_link->scsipi_scsi.target; 1305 ccb->lun = sc_link->scsipi_scsi.lun; 1306 ltophys(KVTOPHYS(&ccb->scsi_sense), ccb->sense_ptr); 1307 ccb->req_sense_length = sizeof(ccb->scsi_sense); 1308 ccb->host_stat = 0x00; 1309 ccb->target_stat = 0x00; 1310 ccb->link_id = 0; 1311 ltophys(0, ccb->link_addr); 1312 1313 s = splbio(); 1314 bt_queue_ccb(sc, ccb); 1315 splx(s); 1316 1317 /* 1318 * Usually return SUCCESSFULLY QUEUED 1319 */ 1320 SC_DEBUG(sc_link, SDEV_DB3, ("cmd_sent\n")); 1321 if ((control & XS_CTL_POLL) == 0) 1322 return SUCCESSFULLY_QUEUED; 1323 1324 /* 1325 * If we can't use interrupts, poll on completion 1326 */ 1327 if (bt_poll(sc, xs, ccb->timeout)) { 1328 bt_timeout(ccb); 1329 if (bt_poll(sc, xs, ccb->timeout)) 1330 bt_timeout(ccb); 1331 } 1332 return COMPLETE; 1333 1334badbuf: 1335 sg = ccb->scat_gath; 1336 while (seg) { 1337 thisbounce = PHYSTOKV(phystol(sg->seg_addr)); 1338 bt_free_buf(sc, (struct bt_buf *)thisbounce); 1339 sg++; 1340 seg--; 1341 } 1342 xs->error = XS_DRIVER_STUFFUP; 1343 bt_free_ccb(sc, ccb); 1344 return TRY_AGAIN_LATER; 1345} 1346 1347/* 1348 * Poll a particular unit, looking for a particular xs 1349 */ 1350int 1351bt_poll(struct bt_softc *sc, struct scsipi_xfer *xs, int count) 1352{ 1353 int iobase = sc->sc_iobase; 1354 1355 /* timeouts are in msec, so we loop in 1000 usec cycles */ 1356 while (count) { 1357 /* 1358 * If we had interrupts enabled, would we 1359 * have got an interrupt? 1360 */ 1361 if (isa_inb(iobase + BT_INTR_PORT) & BT_INTR_ANYINTR) 1362 btintr(sc); 1363 if (xs->xs_status & XS_STS_DONE) 1364 return 0; 1365 delay(1000); /* only happens in boot so ok */ 1366 count--; 1367 } 1368 return 1; 1369} 1370 1371void 1372bt_timeout(void *arg) 1373{ 1374 struct bt_ccb *ccb = arg; 1375 struct scsipi_xfer *xs = ccb->xs; 1376 struct scsipi_link *sc_link = xs->sc_link; 1377 struct bt_softc *sc = sc_link->adapter_softc; 1378 int s; 1379 1380 scsi_print_addr(sc_link); 1381 printf("timed out"); 1382 1383 s = splbio(); 1384 1385#ifdef BTDIAG 1386 /* 1387 * If the ccb's mbx is not free, then the board has gone Far East? 1388 */ 1389 bt_collect_mbo(sc); 1390 if (ccb->flags & CCB_SENDING) { 1391 printf("%s: not taking commands!\n", device_xname(sc->sc_dev)); 1392 Debugger(); 1393 } 1394#endif 1395 1396 /* 1397 * If it has been through before, then 1398 * a previous abort has failed, don't 1399 * try abort again 1400 */ 1401 if (ccb->flags & CCB_ABORT) { 1402 /* abort timed out */ 1403 printf(" AGAIN\n"); 1404 /* XXX Must reset! */ 1405 } else { 1406 /* abort the operation that has timed out */ 1407 printf("\n"); 1408 ccb->xs->error = XS_TIMEOUT; 1409 ccb->timeout = BT_ABORT_TIMEOUT; 1410 ccb->flags |= CCB_ABORT; 1411 bt_queue_ccb(sc, ccb); 1412 } 1413 1414 splx(s); 1415} 1416