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