1 /* $NetBSD: ahb.c,v 1.49 2007/10/19 11:59:41 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 9 * Simulation Facility, NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Originally written by Julian Elischer (julian@tfs.com) 42 * for TRW Financial Systems for use under the MACH(2.5) operating system. 43 * 44 * TRW Financial Systems, in accordance with their agreement with Carnegie 45 * Mellon University, makes this software available to CMU to distribute 46 * or use in any manner that they see fit as long as this message is kept with 47 * the software. For this reason TFS also grants any other persons or 48 * organisations permission to use or modify this software. 49 * 50 * TFS supplies this software to be publicly redistributed 51 * on the understanding that TFS is not responsible for the correct 52 * functioning of this software in any circumstances. 53 */ 54 55 #include <sys/cdefs.h> 56 __KERNEL_RCSID(0, "$NetBSD: ahb.c,v 1.49 2007/10/19 11:59:41 ad Exp $"); 57 58 #include "opt_ddb.h" 59 60 #undef AHBDEBUG 61 62 #include <sys/param.h> 63 #include <sys/systm.h> 64 #include <sys/kernel.h> 65 #include <sys/errno.h> 66 #include <sys/ioctl.h> 67 #include <sys/device.h> 68 #include <sys/malloc.h> 69 #include <sys/buf.h> 70 #include <sys/proc.h> 71 #include <sys/user.h> 72 73 #include <uvm/uvm_extern.h> 74 75 #include <sys/bus.h> 76 #include <sys/intr.h> 77 78 #include <dev/scsipi/scsi_all.h> 79 #include <dev/scsipi/scsipi_all.h> 80 #include <dev/scsipi/scsiconf.h> 81 82 #include <dev/eisa/eisareg.h> 83 #include <dev/eisa/eisavar.h> 84 #include <dev/eisa/eisadevs.h> 85 #include <dev/eisa/ahbreg.h> 86 87 #ifndef DDB 88 #define Debugger() panic("should call debugger here (aha1742.c)") 89 #endif /* ! DDB */ 90 91 #define AHB_ECB_MAX 32 /* store up to 32 ECBs at one time */ 92 #define ECB_HASH_SIZE 32 /* hash table size for phystokv */ 93 #define ECB_HASH_SHIFT 9 94 #define ECB_HASH(x) ((((long)(x))>>ECB_HASH_SHIFT) & (ECB_HASH_SIZE - 1)) 95 96 #define AHB_MAXXFER ((AHB_NSEG - 1) << PGSHIFT) 97 98 struct ahb_softc { 99 struct device sc_dev; 100 101 bus_space_tag_t sc_iot; 102 bus_space_handle_t sc_ioh; 103 bus_dma_tag_t sc_dmat; 104 void *sc_ih; 105 106 bus_dmamap_t sc_dmamap_ecb; /* maps the ecbs */ 107 struct ahb_ecb *sc_ecbs; /* all our ecbs */ 108 109 struct ahb_ecb *sc_ecbhash[ECB_HASH_SIZE]; 110 TAILQ_HEAD(, ahb_ecb) sc_free_ecb; 111 struct ahb_ecb *sc_immed_ecb; /* an outstanding immediete command */ 112 int sc_numecbs; 113 114 struct scsipi_adapter sc_adapter; 115 struct scsipi_channel sc_channel; 116 }; 117 118 /* 119 * Offset of an ECB from the beginning of the ECB DMA mapping. 120 */ 121 #define AHB_ECB_OFF(e) (((u_long)(e)) - ((u_long)&sc->sc_ecbs[0])) 122 123 struct ahb_probe_data { 124 int sc_irq; 125 int sc_scsi_dev; 126 }; 127 128 static void ahb_send_mbox(struct ahb_softc *, int, struct ahb_ecb *); 129 static void ahb_send_immed(struct ahb_softc *, u_int32_t, struct ahb_ecb *); 130 static int ahbintr(void *); 131 static void ahb_free_ecb(struct ahb_softc *, struct ahb_ecb *); 132 static struct ahb_ecb *ahb_get_ecb(struct ahb_softc *); 133 static struct ahb_ecb *ahb_ecb_phys_kv(struct ahb_softc *, physaddr); 134 static void ahb_done(struct ahb_softc *, struct ahb_ecb *); 135 static int ahb_find(bus_space_tag_t, bus_space_handle_t, 136 struct ahb_probe_data *); 137 static int ahb_init(struct ahb_softc *); 138 static void ahbminphys(struct buf *); 139 static void ahb_scsipi_request(struct scsipi_channel *, 140 scsipi_adapter_req_t, void *); 141 static int ahb_poll(struct ahb_softc *, struct scsipi_xfer *, int); 142 static void ahb_timeout(void *); 143 static int ahb_create_ecbs(struct ahb_softc *, struct ahb_ecb *, int); 144 145 static int ahb_init_ecb(struct ahb_softc *, struct ahb_ecb *); 146 147 static int ahbmatch(struct device *, struct cfdata *, void *); 148 static void ahbattach(struct device *, struct device *, void *); 149 150 CFATTACH_DECL(ahb, sizeof(struct ahb_softc), 151 ahbmatch, ahbattach, NULL, NULL); 152 153 #define AHB_ABORT_TIMEOUT 2000 /* time to wait for abort (mSec) */ 154 155 /* 156 * Check the slots looking for a board we recognise 157 * If we find one, note it's address (slot) and call 158 * the actual probe routine to check it out. 159 */ 160 static int 161 ahbmatch(struct device *parent, struct cfdata *match, 162 void *aux) 163 { 164 struct eisa_attach_args *ea = aux; 165 bus_space_tag_t iot = ea->ea_iot; 166 bus_space_handle_t ioh; 167 int rv; 168 169 /* must match one of our known ID strings */ 170 if (strcmp(ea->ea_idstring, "ADP0000") && 171 strcmp(ea->ea_idstring, "ADP0001") && 172 strcmp(ea->ea_idstring, "ADP0002") && 173 strcmp(ea->ea_idstring, "ADP0400")) 174 return (0); 175 176 if (bus_space_map(iot, 177 EISA_SLOT_ADDR(ea->ea_slot) + AHB_EISA_SLOT_OFFSET, AHB_EISA_IOSIZE, 178 0, &ioh)) 179 return (0); 180 181 rv = !ahb_find(iot, ioh, NULL); 182 183 bus_space_unmap(iot, ioh, AHB_EISA_IOSIZE); 184 185 return (rv); 186 } 187 188 /* 189 * Attach all the sub-devices we can find 190 */ 191 static void 192 ahbattach(struct device *parent, struct device *self, void *aux) 193 { 194 struct eisa_attach_args *ea = aux; 195 struct ahb_softc *sc = device_private(self); 196 bus_space_tag_t iot = ea->ea_iot; 197 bus_space_handle_t ioh; 198 eisa_chipset_tag_t ec = ea->ea_ec; 199 eisa_intr_handle_t ih; 200 const char *model, *intrstr; 201 struct ahb_probe_data apd; 202 struct scsipi_adapter *adapt = &sc->sc_adapter; 203 struct scsipi_channel *chan = &sc->sc_channel; 204 205 if (!strcmp(ea->ea_idstring, "ADP0000")) 206 model = EISA_PRODUCT_ADP0000; 207 else if (!strcmp(ea->ea_idstring, "ADP0001")) 208 model = EISA_PRODUCT_ADP0001; 209 else if (!strcmp(ea->ea_idstring, "ADP0002")) 210 model = EISA_PRODUCT_ADP0002; 211 else if (!strcmp(ea->ea_idstring, "ADP0400")) 212 model = EISA_PRODUCT_ADP0400; 213 else 214 model = "unknown model!"; 215 printf(": %s\n", model); 216 217 if (bus_space_map(iot, 218 EISA_SLOT_ADDR(ea->ea_slot) + AHB_EISA_SLOT_OFFSET, AHB_EISA_IOSIZE, 219 0, &ioh)) 220 panic("ahbattach: could not map I/O addresses"); 221 222 sc->sc_iot = iot; 223 sc->sc_ioh = ioh; 224 sc->sc_dmat = ea->ea_dmat; 225 if (ahb_find(iot, ioh, &apd)) 226 panic("ahbattach: ahb_find failed!"); 227 228 TAILQ_INIT(&sc->sc_free_ecb); 229 230 /* 231 * Fill in the scsipi_adapter. 232 */ 233 memset(adapt, 0, sizeof(*adapt)); 234 adapt->adapt_dev = &sc->sc_dev; 235 adapt->adapt_nchannels = 1; 236 /* adapt_openings initialized below */ 237 adapt->adapt_max_periph = 4; /* XXX arbitrary? */ 238 adapt->adapt_request = ahb_scsipi_request; 239 adapt->adapt_minphys = ahbminphys; 240 241 /* 242 * Fill in the scsipi_channel. 243 */ 244 memset(chan, 0, sizeof(*chan)); 245 chan->chan_adapter = adapt; 246 chan->chan_bustype = &scsi_bustype; 247 chan->chan_channel = 0; 248 chan->chan_ntargets = 8; 249 chan->chan_nluns = 8; 250 chan->chan_id = apd.sc_scsi_dev; 251 252 if (ahb_init(sc) != 0) { 253 /* Error during initialization! */ 254 return; 255 } 256 257 if (eisa_intr_map(ec, apd.sc_irq, &ih)) { 258 printf("%s: couldn't map interrupt (%d)\n", 259 sc->sc_dev.dv_xname, apd.sc_irq); 260 return; 261 } 262 intrstr = eisa_intr_string(ec, ih); 263 sc->sc_ih = eisa_intr_establish(ec, ih, IST_LEVEL, IPL_BIO, 264 ahbintr, sc); 265 if (sc->sc_ih == NULL) { 266 printf("%s: couldn't establish interrupt", 267 sc->sc_dev.dv_xname); 268 if (intrstr != NULL) 269 printf(" at %s", intrstr); 270 printf("\n"); 271 return; 272 } 273 if (intrstr != NULL) 274 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, 275 intrstr); 276 277 /* 278 * ask the adapter what subunits are present 279 */ 280 config_found(self, &sc->sc_channel, scsiprint); 281 } 282 283 /* 284 * Function to send a command out through a mailbox 285 */ 286 static void 287 ahb_send_mbox(struct ahb_softc *sc, int opcode, struct ahb_ecb *ecb) 288 { 289 bus_space_tag_t iot = sc->sc_iot; 290 bus_space_handle_t ioh = sc->sc_ioh; 291 int wait = 300; /* 1ms should be enough */ 292 293 while (--wait) { 294 if ((bus_space_read_1(iot, ioh, G2STAT) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) 295 == (G2STAT_MBOX_EMPTY)) 296 break; 297 delay(10); 298 } 299 if (!wait) { 300 printf("%s: board not responding\n", sc->sc_dev.dv_xname); 301 Debugger(); 302 } 303 304 /* 305 * don't know if this will work. 306 * XXX WHAT DOES THIS COMMENT MEAN?! --thorpej 307 */ 308 bus_space_write_4(iot, ioh, MBOXOUT0, 309 sc->sc_dmamap_ecb->dm_segs[0].ds_addr + AHB_ECB_OFF(ecb)); 310 bus_space_write_1(iot, ioh, ATTN, opcode | 311 ecb->xs->xs_periph->periph_target); 312 313 if ((ecb->xs->xs_control & XS_CTL_POLL) == 0) 314 callout_reset(&ecb->xs->xs_callout, 315 mstohz(ecb->timeout), ahb_timeout, ecb); 316 } 317 318 /* 319 * Function to send an immediate type command to the adapter 320 */ 321 static void 322 ahb_send_immed(struct ahb_softc *sc, u_int32_t cmd, struct ahb_ecb *ecb) 323 { 324 bus_space_tag_t iot = sc->sc_iot; 325 bus_space_handle_t ioh = sc->sc_ioh; 326 int wait = 100; /* 1 ms enough? */ 327 328 while (--wait) { 329 if ((bus_space_read_1(iot, ioh, G2STAT) & (G2STAT_BUSY | G2STAT_MBOX_EMPTY)) 330 == (G2STAT_MBOX_EMPTY)) 331 break; 332 delay(10); 333 } 334 if (!wait) { 335 printf("%s: board not responding\n", sc->sc_dev.dv_xname); 336 Debugger(); 337 } 338 339 bus_space_write_4(iot, ioh, MBOXOUT0, cmd); /* don't know this will work */ 340 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_SET_HOST_READY); 341 bus_space_write_1(iot, ioh, ATTN, OP_IMMED | 342 ecb->xs->xs_periph->periph_target); 343 344 if ((ecb->xs->xs_control & XS_CTL_POLL) == 0) 345 callout_reset(&ecb->xs->xs_callout, 346 mstohz(ecb->timeout), ahb_timeout, ecb); 347 } 348 349 /* 350 * Catch an interrupt from the adaptor 351 */ 352 static int 353 ahbintr(void *arg) 354 { 355 struct ahb_softc *sc = arg; 356 bus_space_tag_t iot = sc->sc_iot; 357 bus_space_handle_t ioh = sc->sc_ioh; 358 struct ahb_ecb *ecb; 359 u_char ahbstat; 360 u_int32_t mboxval; 361 362 #ifdef AHBDEBUG 363 printf("%s: ahbintr ", sc->sc_dev.dv_xname); 364 #endif /* AHBDEBUG */ 365 366 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0) 367 return 0; 368 369 for (;;) { 370 /* 371 * First get all the information and then 372 * acknowledge the interrupt 373 */ 374 ahbstat = bus_space_read_1(iot, ioh, G2INTST); 375 mboxval = bus_space_read_4(iot, ioh, MBOXIN0); 376 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT); 377 378 #ifdef AHBDEBUG 379 printf("status = 0x%x ", ahbstat); 380 #endif /* AHBDEBUG */ 381 382 /* 383 * Process the completed operation 384 */ 385 switch (ahbstat & G2INTST_INT_STAT) { 386 case AHB_ECB_OK: 387 case AHB_ECB_RECOVERED: 388 case AHB_ECB_ERR: 389 ecb = ahb_ecb_phys_kv(sc, mboxval); 390 if (!ecb) { 391 printf("%s: BAD ECB RETURNED!\n", 392 sc->sc_dev.dv_xname); 393 goto next; /* whatever it was, it'll timeout */ 394 } 395 break; 396 397 case AHB_IMMED_ERR: 398 ecb = sc->sc_immed_ecb; 399 sc->sc_immed_ecb = 0; 400 ecb->flags |= ECB_IMMED_FAIL; 401 break; 402 403 case AHB_IMMED_OK: 404 ecb = sc->sc_immed_ecb; 405 sc->sc_immed_ecb = 0; 406 break; 407 408 default: 409 printf("%s: unexpected interrupt %x\n", 410 sc->sc_dev.dv_xname, ahbstat); 411 goto next; 412 } 413 414 callout_stop(&ecb->xs->xs_callout); 415 ahb_done(sc, ecb); 416 417 next: 418 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) == 0) 419 return 1; 420 } 421 } 422 423 static inline void 424 ahb_reset_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb) 425 { 426 427 ecb->flags = 0; 428 } 429 430 /* 431 * A ecb (and hence a mbx-out is put onto the 432 * free list. 433 */ 434 static void 435 ahb_free_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb) 436 { 437 int s; 438 439 s = splbio(); 440 ahb_reset_ecb(sc, ecb); 441 TAILQ_INSERT_HEAD(&sc->sc_free_ecb, ecb, chain); 442 splx(s); 443 } 444 445 /* 446 * Create a set of ecbs and add them to the free list. 447 */ 448 static int 449 ahb_init_ecb(struct ahb_softc *sc, struct ahb_ecb *ecb) 450 { 451 bus_dma_tag_t dmat = sc->sc_dmat; 452 int hashnum, error; 453 454 /* 455 * Create the DMA map for this ECB. 456 */ 457 error = bus_dmamap_create(dmat, AHB_MAXXFER, AHB_NSEG, AHB_MAXXFER, 458 0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ecb->dmamap_xfer); 459 if (error) { 460 printf("%s: can't create ecb dmamap_xfer\n", 461 sc->sc_dev.dv_xname); 462 return (error); 463 } 464 465 /* 466 * put in the phystokv hash table 467 * Never gets taken out. 468 */ 469 ecb->hashkey = sc->sc_dmamap_ecb->dm_segs[0].ds_addr + 470 AHB_ECB_OFF(ecb); 471 hashnum = ECB_HASH(ecb->hashkey); 472 ecb->nexthash = sc->sc_ecbhash[hashnum]; 473 sc->sc_ecbhash[hashnum] = ecb; 474 ahb_reset_ecb(sc, ecb); 475 return (0); 476 } 477 478 static int 479 ahb_create_ecbs(struct ahb_softc *sc, struct ahb_ecb *ecbstore, int count) 480 { 481 struct ahb_ecb *ecb; 482 int i, error; 483 484 bzero(ecbstore, sizeof(struct ahb_ecb) * count); 485 for (i = 0; i < count; i++) { 486 ecb = &ecbstore[i]; 487 if ((error = ahb_init_ecb(sc, ecb)) != 0) { 488 printf("%s: unable to initialize ecb, error = %d\n", 489 sc->sc_dev.dv_xname, error); 490 goto out; 491 } 492 TAILQ_INSERT_TAIL(&sc->sc_free_ecb, ecb, chain); 493 } 494 out: 495 return (i); 496 } 497 498 /* 499 * Get a free ecb 500 * 501 * If there are none, see if we can allocate a new one. If so, put it in the 502 * hash table too otherwise either return an error or sleep. 503 */ 504 static struct ahb_ecb * 505 ahb_get_ecb(struct ahb_softc *sc) 506 { 507 struct ahb_ecb *ecb; 508 int s; 509 510 s = splbio(); 511 ecb = TAILQ_FIRST(&sc->sc_free_ecb); 512 if (ecb != NULL) { 513 TAILQ_REMOVE(&sc->sc_free_ecb, ecb, chain); 514 ecb->flags |= ECB_ALLOC; 515 } 516 splx(s); 517 return (ecb); 518 } 519 520 /* 521 * given a physical address, find the ecb that it corresponds to. 522 */ 523 static struct ahb_ecb * 524 ahb_ecb_phys_kv(struct ahb_softc *sc, physaddr ecb_phys) 525 { 526 int hashnum = ECB_HASH(ecb_phys); 527 struct ahb_ecb *ecb = sc->sc_ecbhash[hashnum]; 528 529 while (ecb) { 530 if (ecb->hashkey == ecb_phys) 531 break; 532 ecb = ecb->nexthash; 533 } 534 return ecb; 535 } 536 537 /* 538 * We have a ecb which has been processed by the adaptor, now we look to see 539 * how the operation went. 540 */ 541 static void 542 ahb_done(struct ahb_softc *sc, struct ahb_ecb *ecb) 543 { 544 bus_dma_tag_t dmat = sc->sc_dmat; 545 struct scsi_sense_data *s1, *s2; 546 struct scsipi_xfer *xs = ecb->xs; 547 548 SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("ahb_done\n")); 549 550 bus_dmamap_sync(dmat, sc->sc_dmamap_ecb, 551 AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb), 552 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 553 554 /* 555 * If we were a data transfer, unload the map that described 556 * the data buffer. 557 */ 558 if (xs->datalen) { 559 bus_dmamap_sync(dmat, ecb->dmamap_xfer, 0, 560 ecb->dmamap_xfer->dm_mapsize, 561 (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD : 562 BUS_DMASYNC_POSTWRITE); 563 bus_dmamap_unload(dmat, ecb->dmamap_xfer); 564 } 565 566 /* 567 * Otherwise, put the results of the operation 568 * into the xfer and call whoever started it 569 */ 570 if ((ecb->flags & ECB_ALLOC) == 0) { 571 printf("%s: exiting ecb not allocated!\n", sc->sc_dev.dv_xname); 572 Debugger(); 573 } 574 if (ecb->flags & ECB_IMMED) { 575 if (ecb->flags & ECB_IMMED_FAIL) 576 xs->error = XS_DRIVER_STUFFUP; 577 goto done; 578 } 579 if (xs->error == XS_NOERROR) { 580 if (ecb->ecb_status.host_stat != HS_OK) { 581 switch (ecb->ecb_status.host_stat) { 582 case HS_TIMED_OUT: /* No response */ 583 xs->error = XS_SELTIMEOUT; 584 break; 585 default: /* Other scsi protocol messes */ 586 printf("%s: host_stat %x\n", 587 sc->sc_dev.dv_xname, ecb->ecb_status.host_stat); 588 xs->error = XS_DRIVER_STUFFUP; 589 } 590 } else if (ecb->ecb_status.target_stat != SCSI_OK) { 591 switch (ecb->ecb_status.target_stat) { 592 case SCSI_CHECK: 593 s1 = &ecb->ecb_sense; 594 s2 = &xs->sense.scsi_sense; 595 *s2 = *s1; 596 xs->error = XS_SENSE; 597 break; 598 case SCSI_BUSY: 599 xs->error = XS_BUSY; 600 break; 601 default: 602 printf("%s: target_stat %x\n", 603 sc->sc_dev.dv_xname, ecb->ecb_status.target_stat); 604 xs->error = XS_DRIVER_STUFFUP; 605 } 606 } else 607 xs->resid = 0; 608 } 609 done: 610 ahb_free_ecb(sc, ecb); 611 scsipi_done(xs); 612 } 613 614 /* 615 * Start the board, ready for normal operation 616 */ 617 static int 618 ahb_find(bus_space_tag_t iot, bus_space_handle_t ioh, struct ahb_probe_data *sc) 619 { 620 u_char intdef; 621 int i, irq, busid; 622 int wait = 1000; /* 1 sec enough? */ 623 624 bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED); 625 626 #define NO_NO 1 627 #ifdef NO_NO 628 /* 629 * reset board, If it doesn't respond, assume 630 * that it's not there.. good for the probe 631 */ 632 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_HARD_RESET); 633 delay(1000); 634 bus_space_write_1(iot, ioh, G2CNTRL, 0); 635 delay(10000); 636 while (--wait) { 637 if ((bus_space_read_1(iot, ioh, G2STAT) & G2STAT_BUSY) == 0) 638 break; 639 delay(1000); 640 } 641 if (!wait) { 642 #ifdef AHBDEBUG 643 printf("ahb_find: No answer from aha1742 board\n"); 644 #endif /* AHBDEBUG */ 645 return ENXIO; 646 } 647 i = bus_space_read_1(iot, ioh, MBOXIN0); 648 if (i) { 649 printf("self test failed, val = 0x%x\n", i); 650 return EIO; 651 } 652 653 /* Set it again, just to be sure. */ 654 bus_space_write_1(iot, ioh, PORTADDR, PORTADDR_ENHANCED); 655 #endif 656 657 while (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) { 658 printf("."); 659 bus_space_write_1(iot, ioh, G2CNTRL, G2CNTRL_CLEAR_EISA_INT); 660 delay(10000); 661 } 662 663 intdef = bus_space_read_1(iot, ioh, INTDEF); 664 switch (intdef & 0x07) { 665 case INT9: 666 irq = 9; 667 break; 668 case INT10: 669 irq = 10; 670 break; 671 case INT11: 672 irq = 11; 673 break; 674 case INT12: 675 irq = 12; 676 break; 677 case INT14: 678 irq = 14; 679 break; 680 case INT15: 681 irq = 15; 682 break; 683 default: 684 printf("illegal int setting %x\n", intdef); 685 return EIO; 686 } 687 688 bus_space_write_1(iot, ioh, INTDEF, (intdef | INTEN)); /* make sure we can interrupt */ 689 690 /* who are we on the scsi bus? */ 691 busid = (bus_space_read_1(iot, ioh, SCSIDEF) & HSCSIID); 692 693 /* if we want to return data, do so now */ 694 if (sc) { 695 sc->sc_irq = irq; 696 sc->sc_scsi_dev = busid; 697 } 698 699 /* 700 * Note that we are going and return (to probe) 701 */ 702 return 0; 703 } 704 705 static int 706 ahb_init(struct ahb_softc *sc) 707 { 708 bus_dma_segment_t seg; 709 int i, error, rseg; 710 711 #define ECBSIZE (AHB_ECB_MAX * sizeof(struct ahb_ecb)) 712 713 /* 714 * Allocate the ECBs. 715 */ 716 if ((error = bus_dmamem_alloc(sc->sc_dmat, ECBSIZE, 717 PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 718 printf("%s: unable to allocate ecbs, error = %d\n", 719 sc->sc_dev.dv_xname, error); 720 return (error); 721 } 722 if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, 723 ECBSIZE, (void **)&sc->sc_ecbs, 724 BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) { 725 printf("%s: unable to map ecbs, error = %d\n", 726 sc->sc_dev.dv_xname, error); 727 return (error); 728 } 729 730 /* 731 * Create and load the DMA map used for the ecbs. 732 */ 733 if ((error = bus_dmamap_create(sc->sc_dmat, ECBSIZE, 734 1, ECBSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_dmamap_ecb)) != 0) { 735 printf("%s: unable to create ecb DMA map, error = %d\n", 736 sc->sc_dev.dv_xname, error); 737 return (error); 738 } 739 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_ecb, 740 sc->sc_ecbs, ECBSIZE, NULL, BUS_DMA_NOWAIT)) != 0) { 741 printf("%s: unable to load ecb DMA map, error = %d\n", 742 sc->sc_dev.dv_xname, error); 743 return (error); 744 } 745 746 #undef ECBSIZE 747 748 /* 749 * Initialize the ecbs. 750 */ 751 i = ahb_create_ecbs(sc, sc->sc_ecbs, AHB_ECB_MAX); 752 if (i == 0) { 753 printf("%s: unable to create ecbs\n", 754 sc->sc_dev.dv_xname); 755 return (ENOMEM); 756 } else if (i != AHB_ECB_MAX) { 757 printf("%s: WARNING: only %d of %d ecbs created\n", 758 sc->sc_dev.dv_xname, i, AHB_ECB_MAX); 759 } 760 761 sc->sc_adapter.adapt_openings = i; 762 763 return (0); 764 } 765 766 static void 767 ahbminphys(struct buf *bp) 768 { 769 770 if (bp->b_bcount > AHB_MAXXFER) 771 bp->b_bcount = AHB_MAXXFER; 772 minphys(bp); 773 } 774 775 /* 776 * start a scsi operation given the command and the data address. Also needs 777 * the unit, target and lu. 778 */ 779 static void 780 ahb_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, 781 void *arg) 782 { 783 struct scsipi_xfer *xs; 784 struct scsipi_periph *periph; 785 struct ahb_softc *sc = (void *)chan->chan_adapter->adapt_dev; 786 bus_dma_tag_t dmat = sc->sc_dmat; 787 struct ahb_ecb *ecb; 788 int error, seg, flags, s; 789 790 switch (req) { 791 case ADAPTER_REQ_RUN_XFER: 792 xs = arg; 793 periph = xs->xs_periph; 794 flags = xs->xs_control; 795 796 SC_DEBUG(periph, SCSIPI_DB2, ("ahb_scsipi_request\n")); 797 798 /* Get an ECB to use. */ 799 ecb = ahb_get_ecb(sc); 800 #ifdef DIAGNOSTIC 801 /* 802 * This should never happen as we track the resources 803 * in the mid-layer. 804 */ 805 if (ecb == NULL) { 806 scsipi_printaddr(periph); 807 printf("unable to allocate ecb\n"); 808 panic("ahb_scsipi_request"); 809 } 810 #endif 811 812 ecb->xs = xs; 813 ecb->timeout = xs->timeout; 814 815 /* 816 * If it's a reset, we need to do an 'immediate' 817 * command, and store its ecb for later 818 * if there is already an immediate waiting, 819 * then WE must wait 820 */ 821 if (flags & XS_CTL_RESET) { 822 ecb->flags |= ECB_IMMED; 823 if (sc->sc_immed_ecb) { 824 ahb_free_ecb(sc, ecb); 825 xs->error = XS_BUSY; 826 scsipi_done(xs); 827 return; 828 } 829 sc->sc_immed_ecb = ecb; 830 831 s = splbio(); 832 ahb_send_immed(sc, AHB_TARG_RESET, ecb); 833 splx(s); 834 835 if ((flags & XS_CTL_POLL) == 0) 836 return; 837 838 /* 839 * If we can't use interrupts, poll on completion 840 */ 841 if (ahb_poll(sc, xs, ecb->timeout)) 842 ahb_timeout(ecb); 843 return; 844 } 845 846 /* 847 * Put all the arguments for the xfer in the ecb 848 */ 849 if (xs->cmdlen > sizeof(ecb->scsi_cmd)) { 850 printf("%s: cmdlen %d too large for ECB\n", 851 sc->sc_dev.dv_xname, xs->cmdlen); 852 xs->error = XS_DRIVER_STUFFUP; 853 goto out_bad; 854 } 855 ecb->opcode = ECB_SCSI_OP; 856 ecb->opt1 = ECB_SES /*| ECB_DSB*/ | ECB_ARS; 857 ecb->opt2 = periph->periph_lun | ECB_NRB; 858 bcopy(xs->cmd, &ecb->scsi_cmd, 859 ecb->scsi_cmd_length = xs->cmdlen); 860 ecb->sense_ptr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr + 861 AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_sense); 862 ecb->req_sense_length = sizeof(ecb->ecb_sense); 863 ecb->status = sc->sc_dmamap_ecb->dm_segs[0].ds_addr + 864 AHB_ECB_OFF(ecb) + offsetof(struct ahb_ecb, ecb_status); 865 ecb->ecb_status.host_stat = 0x00; 866 ecb->ecb_status.target_stat = 0x00; 867 868 if (xs->datalen) { 869 /* 870 * Map the DMA transfer. 871 */ 872 #ifdef TFS 873 if (flags & XS_CTL_DATA_UIO) { 874 error = bus_dmamap_load_uio(sc->sc_dmat, 875 ecb->dmamap_xfer, (struct uio *)xs->data, 876 BUS_DMA_NOWAIT); 877 } else 878 #endif /* TFS */ 879 { 880 error = bus_dmamap_load(sc->sc_dmat, 881 ecb->dmamap_xfer, xs->data, xs->datalen, 882 NULL, BUS_DMA_NOWAIT); 883 } 884 885 switch (error) { 886 case 0: 887 break; 888 889 case ENOMEM: 890 case EAGAIN: 891 xs->error = XS_RESOURCE_SHORTAGE; 892 goto out_bad; 893 894 default: 895 xs->error = XS_DRIVER_STUFFUP; 896 printf("%s: error %d loading DMA map\n", 897 sc->sc_dev.dv_xname, error); 898 out_bad: 899 ahb_free_ecb(sc, ecb); 900 scsipi_done(xs); 901 return; 902 } 903 904 bus_dmamap_sync(dmat, ecb->dmamap_xfer, 0, 905 ecb->dmamap_xfer->dm_mapsize, 906 (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD : 907 BUS_DMASYNC_PREWRITE); 908 909 /* 910 * Load the hardware scatter/gather map with the 911 * contents of the DMA map. 912 */ 913 for (seg = 0; seg < ecb->dmamap_xfer->dm_nsegs; seg++) { 914 ecb->ahb_dma[seg].seg_addr = 915 ecb->dmamap_xfer->dm_segs[seg].ds_addr; 916 ecb->ahb_dma[seg].seg_len = 917 ecb->dmamap_xfer->dm_segs[seg].ds_len; 918 } 919 920 ecb->data_addr = sc->sc_dmamap_ecb->dm_segs[0].ds_addr + 921 AHB_ECB_OFF(ecb) + 922 offsetof(struct ahb_ecb, ahb_dma); 923 ecb->data_length = ecb->dmamap_xfer->dm_nsegs * 924 sizeof(struct ahb_dma_seg); 925 ecb->opt1 |= ECB_S_G; 926 } else { /* No data xfer, use non S/G values */ 927 ecb->data_addr = (physaddr)0; 928 ecb->data_length = 0; 929 } 930 ecb->link_addr = (physaddr)0; 931 932 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_ecb, 933 AHB_ECB_OFF(ecb), sizeof(struct ahb_ecb), 934 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 935 936 s = splbio(); 937 ahb_send_mbox(sc, OP_START_ECB, ecb); 938 splx(s); 939 940 if ((flags & XS_CTL_POLL) == 0) 941 return; 942 943 /* 944 * If we can't use interrupts, poll on completion 945 */ 946 if (ahb_poll(sc, xs, ecb->timeout)) { 947 ahb_timeout(ecb); 948 if (ahb_poll(sc, xs, ecb->timeout)) 949 ahb_timeout(ecb); 950 } 951 return; 952 953 case ADAPTER_REQ_GROW_RESOURCES: 954 /* XXX Not supported. */ 955 return; 956 957 case ADAPTER_REQ_SET_XFER_MODE: 958 /* XXX How do we do this? */ 959 return; 960 } 961 } 962 963 /* 964 * Function to poll for command completion when in poll mode 965 */ 966 static int 967 ahb_poll(struct ahb_softc *sc, struct scsipi_xfer *xs, int count) 968 { /* in msec */ 969 bus_space_tag_t iot = sc->sc_iot; 970 bus_space_handle_t ioh = sc->sc_ioh; 971 972 while (count) { 973 /* 974 * If we had interrupts enabled, would we 975 * have got an interrupt? 976 */ 977 if (bus_space_read_1(iot, ioh, G2STAT) & G2STAT_INT_PEND) 978 ahbintr(sc); 979 if (xs->xs_status & XS_STS_DONE) 980 return 0; 981 delay(1000); 982 count--; 983 } 984 return 1; 985 } 986 987 static void 988 ahb_timeout(void *arg) 989 { 990 struct ahb_ecb *ecb = arg; 991 struct scsipi_xfer *xs = ecb->xs; 992 struct scsipi_periph *periph = xs->xs_periph; 993 struct ahb_softc *sc = 994 (void *)periph->periph_channel->chan_adapter->adapt_dev; 995 int s; 996 997 scsipi_printaddr(periph); 998 printf("timed out"); 999 1000 s = splbio(); 1001 1002 if (ecb->flags & ECB_IMMED) { 1003 printf("\n"); 1004 ecb->flags |= ECB_IMMED_FAIL; 1005 /* XXX Must reset! */ 1006 } else 1007 1008 /* 1009 * If it has been through before, then 1010 * a previous abort has failed, don't 1011 * try abort again 1012 */ 1013 if (ecb->flags & ECB_ABORT) { 1014 /* abort timed out */ 1015 printf(" AGAIN\n"); 1016 /* XXX Must reset! */ 1017 } else { 1018 /* abort the operation that has timed out */ 1019 printf("\n"); 1020 ecb->xs->error = XS_TIMEOUT; 1021 ecb->timeout = AHB_ABORT_TIMEOUT; 1022 ecb->flags |= ECB_ABORT; 1023 ahb_send_mbox(sc, OP_ABORT_ECB, ecb); 1024 } 1025 1026 splx(s); 1027 } 1028