1 /* $NetBSD: if_de.c,v 1.14 2002/10/02 16:52:26 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 5 * Copyright (c) 2000 Ludd, University of Lule}, Sweden. 6 * All rights reserved. 7 * 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by the University of 20 * California, Berkeley and its contributors. 21 * 4. Neither the name of the University nor the names of its contributors 22 * may be used to endorse or promote products derived from this software 23 * without specific prior written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)if_de.c 7.12 (Berkeley) 12/16/90 38 */ 39 40 /* 41 * DEC DEUNA interface 42 * 43 * Lou Salkind 44 * New York University 45 * 46 * Rewritten by Ragge 30 April 2000 to match new world. 47 * 48 * TODO: 49 * timeout routine (get statistics) 50 */ 51 52 #include <sys/cdefs.h> 53 __KERNEL_RCSID(0, "$NetBSD: if_de.c,v 1.14 2002/10/02 16:52:26 thorpej Exp $"); 54 55 #include "opt_inet.h" 56 #include "bpfilter.h" 57 58 #include <sys/param.h> 59 #include <sys/systm.h> 60 #include <sys/mbuf.h> 61 #include <sys/buf.h> 62 #include <sys/protosw.h> 63 #include <sys/socket.h> 64 #include <sys/ioctl.h> 65 #include <sys/errno.h> 66 #include <sys/syslog.h> 67 #include <sys/device.h> 68 69 #include <net/if.h> 70 #include <net/if_ether.h> 71 #include <net/if_dl.h> 72 73 #ifdef INET 74 #include <netinet/in.h> 75 #include <netinet/if_inarp.h> 76 #endif 77 78 #if NBPFILTER > 0 79 #include <net/bpf.h> 80 #include <net/bpfdesc.h> 81 #endif 82 83 #include <machine/bus.h> 84 85 #include <dev/qbus/ubavar.h> 86 #include <dev/qbus/if_dereg.h> 87 #include <dev/qbus/if_uba.h> 88 89 #include "ioconf.h" 90 91 /* 92 * Be careful with transmit/receive buffers, each entry steals 4 map 93 * registers, and there is only 496 on one unibus... 94 */ 95 #define NRCV 7 /* number of receive buffers (must be > 1) */ 96 #define NXMT 3 /* number of transmit buffers */ 97 98 /* 99 * Structure containing the elements that must be in DMA-safe memory. 100 */ 101 struct de_cdata { 102 /* the following structures are always mapped in */ 103 struct de_pcbb dc_pcbb; /* port control block */ 104 struct de_ring dc_xrent[NXMT]; /* transmit ring entrys */ 105 struct de_ring dc_rrent[NRCV]; /* receive ring entrys */ 106 struct de_udbbuf dc_udbbuf; /* UNIBUS data buffer */ 107 /* end mapped area */ 108 }; 109 110 /* 111 * Ethernet software status per interface. 112 * 113 * Each interface is referenced by a network interface structure, 114 * ds_if, which the routing code uses to locate the interface. 115 * This structure contains the output queue for the interface, its address, ... 116 * We also have, for each interface, a UBA interface structure, which 117 * contains information about the UNIBUS resources held by the interface: 118 * map registers, buffered data paths, etc. Information is cached in this 119 * structure for use by the if_uba.c routines in running the interface 120 * efficiently. 121 */ 122 struct de_softc { 123 struct device sc_dev; /* Configuration common part */ 124 struct evcnt sc_intrcnt; /* Interrupt counting */ 125 struct ethercom sc_ec; /* Ethernet common part */ 126 #define sc_if sc_ec.ec_if /* network-visible interface */ 127 bus_space_tag_t sc_iot; 128 bus_addr_t sc_ioh; 129 bus_dma_tag_t sc_dmat; 130 int sc_flags; 131 #define DSF_MAPPED 1 132 struct ubinfo sc_ui; 133 struct de_cdata *sc_dedata; /* Control structure */ 134 struct de_cdata *sc_pdedata; /* Bus-mapped control structure */ 135 struct ifubinfo sc_ifuba; /* UNIBUS resources */ 136 struct ifrw sc_ifr[NRCV]; /* UNIBUS receive buffer maps */ 137 struct ifxmt sc_ifw[NXMT]; /* UNIBUS receive buffer maps */ 138 139 int sc_xindex; /* UNA index into transmit chain */ 140 int sc_rindex; /* UNA index into receive chain */ 141 int sc_xfree; /* index for next transmit buffer */ 142 int sc_nxmit; /* # of transmits in progress */ 143 void *sc_sh; /* shutdownhook cookie */ 144 }; 145 146 static int dematch(struct device *, struct cfdata *, void *); 147 static void deattach(struct device *, struct device *, void *); 148 static void dewait(struct de_softc *, char *); 149 static int deinit(struct ifnet *); 150 static int deioctl(struct ifnet *, u_long, caddr_t); 151 static void dereset(struct device *); 152 static void destop(struct ifnet *, int); 153 static void destart(struct ifnet *); 154 static void derecv(struct de_softc *); 155 static void deintr(void *); 156 static void deshutdown(void *); 157 158 CFATTACH_DECL(de, sizeof(struct de_softc), 159 dematch, deattach, NULL, NULL); 160 161 #define DE_WCSR(csr, val) \ 162 bus_space_write_2(sc->sc_iot, sc->sc_ioh, csr, val) 163 #define DE_WLOW(val) \ 164 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0, val) 165 #define DE_WHIGH(val) \ 166 bus_space_write_1(sc->sc_iot, sc->sc_ioh, DE_PCSR0 + 1, val) 167 #define DE_RCSR(csr) \ 168 bus_space_read_2(sc->sc_iot, sc->sc_ioh, csr) 169 170 #define LOWORD(x) ((int)(x) & 0xffff) 171 #define HIWORD(x) (((int)(x) >> 16) & 0x3) 172 /* 173 * Interface exists: make available by filling in network interface 174 * record. System will initialize the interface when it is ready 175 * to accept packets. We get the ethernet address here. 176 */ 177 void 178 deattach(struct device *parent, struct device *self, void *aux) 179 { 180 struct uba_attach_args *ua = aux; 181 struct de_softc *sc = (struct de_softc *)self; 182 struct ifnet *ifp = &sc->sc_if; 183 u_int8_t myaddr[ETHER_ADDR_LEN]; 184 int csr1, error; 185 char *c; 186 187 sc->sc_iot = ua->ua_iot; 188 sc->sc_ioh = ua->ua_ioh; 189 sc->sc_dmat = ua->ua_dmat; 190 191 /* 192 * What kind of a board is this? 193 * The error bits 4-6 in pcsr1 are a device id as long as 194 * the high byte is zero. 195 */ 196 csr1 = DE_RCSR(DE_PCSR1); 197 if (csr1 & 0xff60) 198 c = "broken"; 199 else if (csr1 & 0x10) 200 c = "delua"; 201 else 202 c = "deuna"; 203 204 /* 205 * Reset the board and temporarily map 206 * the pcbb buffer onto the Unibus. 207 */ 208 DE_WCSR(DE_PCSR0, 0); /* reset INTE */ 209 DELAY(100); 210 DE_WCSR(DE_PCSR0, PCSR0_RSET); 211 dewait(sc, "reset"); 212 213 sc->sc_ui.ui_size = sizeof(struct de_cdata); 214 if ((error = ubmemalloc((struct uba_softc *)parent, &sc->sc_ui, 0))) 215 return printf(": failed ubmemalloc(), error = %d\n", error); 216 sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr; 217 218 /* 219 * Tell the DEUNA about our PCB 220 */ 221 DE_WCSR(DE_PCSR2, LOWORD(sc->sc_ui.ui_baddr)); 222 DE_WCSR(DE_PCSR3, HIWORD(sc->sc_ui.ui_baddr)); 223 DE_WLOW(CMD_GETPCBB); 224 dewait(sc, "pcbb"); 225 226 sc->sc_dedata->dc_pcbb.pcbb0 = FC_RDPHYAD; 227 DE_WLOW(CMD_GETCMD); 228 dewait(sc, "read addr "); 229 230 bcopy((caddr_t)&sc->sc_dedata->dc_pcbb.pcbb2, myaddr, sizeof (myaddr)); 231 printf("\n%s: %s, hardware address %s\n", sc->sc_dev.dv_xname, c, 232 ether_sprintf(myaddr)); 233 234 uba_intr_establish(ua->ua_icookie, ua->ua_cvec, deintr, sc, 235 &sc->sc_intrcnt); 236 uba_reset_establish(dereset, &sc->sc_dev); 237 evcnt_attach_dynamic(&sc->sc_intrcnt, EVCNT_TYPE_INTR, ua->ua_evcnt, 238 sc->sc_dev.dv_xname, "intr"); 239 240 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 241 ifp->if_softc = sc; 242 ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI; 243 ifp->if_ioctl = deioctl; 244 ifp->if_start = destart; 245 ifp->if_init = deinit; 246 ifp->if_stop = destop; 247 IFQ_SET_READY(&ifp->if_snd); 248 249 if_attach(ifp); 250 ether_ifattach(ifp, myaddr); 251 ubmemfree((struct uba_softc *)parent, &sc->sc_ui); 252 253 sc->sc_sh = shutdownhook_establish(deshutdown, sc); 254 } 255 256 void 257 destop(struct ifnet *ifp, int a) 258 { 259 struct de_softc *sc = ifp->if_softc; 260 261 DE_WLOW(0); 262 DELAY(5000); 263 DE_WLOW(PCSR0_RSET); 264 } 265 266 267 /* 268 * Reset of interface after UNIBUS reset. 269 */ 270 void 271 dereset(struct device *dev) 272 { 273 struct de_softc *sc = (void *)dev; 274 275 sc->sc_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 276 sc->sc_flags &= ~DSF_MAPPED; 277 sc->sc_pdedata = NULL; /* All mappings lost */ 278 DE_WCSR(DE_PCSR0, PCSR0_RSET); 279 dewait(sc, "reset"); 280 deinit(&sc->sc_if); 281 } 282 283 /* 284 * Initialization of interface; clear recorded pending 285 * operations, and reinitialize UNIBUS usage. 286 */ 287 int 288 deinit(struct ifnet *ifp) 289 { 290 struct de_softc *sc = ifp->if_softc; 291 struct de_cdata *dc, *pdc; 292 struct ifrw *ifrw; 293 struct ifxmt *ifxp; 294 struct de_ring *rp; 295 int s, error; 296 297 if (ifp->if_flags & IFF_RUNNING) 298 return 0; 299 if ((sc->sc_flags & DSF_MAPPED) == 0) { 300 if (if_ubaminit(&sc->sc_ifuba, (void *)sc->sc_dev.dv_parent, 301 MCLBYTES, sc->sc_ifr, NRCV, sc->sc_ifw, NXMT)) { 302 printf("%s: can't initialize\n", sc->sc_dev.dv_xname); 303 ifp->if_flags &= ~IFF_UP; 304 return 0; 305 } 306 sc->sc_ui.ui_size = sizeof(struct de_cdata); 307 if ((error = ubmemalloc((void *)sc->sc_dev.dv_parent, 308 &sc->sc_ui, 0))) { 309 printf(": unable to ubmemalloc(), error = %d\n", error); 310 return 0; 311 } 312 sc->sc_pdedata = (struct de_cdata *)sc->sc_ui.ui_baddr; 313 sc->sc_dedata = (struct de_cdata *)sc->sc_ui.ui_vaddr; 314 sc->sc_flags |= DSF_MAPPED; 315 } 316 317 /* 318 * Tell the DEUNA about our PCB 319 */ 320 DE_WCSR(DE_PCSR2, LOWORD(sc->sc_pdedata)); 321 DE_WCSR(DE_PCSR3, HIWORD(sc->sc_pdedata)); 322 DE_WLOW(0); /* reset INTE */ 323 DELAY(500); 324 DE_WLOW(CMD_GETPCBB); 325 dewait(sc, "pcbb"); 326 327 dc = sc->sc_dedata; 328 pdc = sc->sc_pdedata; 329 /* set the transmit and receive ring header addresses */ 330 dc->dc_pcbb.pcbb0 = FC_WTRING; 331 dc->dc_pcbb.pcbb2 = LOWORD(&pdc->dc_udbbuf); 332 dc->dc_pcbb.pcbb4 = HIWORD(&pdc->dc_udbbuf); 333 334 dc->dc_udbbuf.b_tdrbl = LOWORD(&pdc->dc_xrent[0]); 335 dc->dc_udbbuf.b_tdrbh = HIWORD(&pdc->dc_xrent[0]); 336 dc->dc_udbbuf.b_telen = sizeof (struct de_ring) / sizeof(u_int16_t); 337 dc->dc_udbbuf.b_trlen = NXMT; 338 dc->dc_udbbuf.b_rdrbl = LOWORD(&pdc->dc_rrent[0]); 339 dc->dc_udbbuf.b_rdrbh = HIWORD(&pdc->dc_rrent[0]); 340 dc->dc_udbbuf.b_relen = sizeof (struct de_ring) / sizeof(u_int16_t); 341 dc->dc_udbbuf.b_rrlen = NRCV; 342 343 DE_WLOW(CMD_GETCMD); 344 dewait(sc, "wtring"); 345 346 sc->sc_dedata->dc_pcbb.pcbb0 = FC_WTMODE; 347 sc->sc_dedata->dc_pcbb.pcbb2 = MOD_TPAD|MOD_HDX|MOD_DRDC|MOD_ENAL; 348 DE_WLOW(CMD_GETCMD); 349 dewait(sc, "wtmode"); 350 351 /* set up the receive and transmit ring entries */ 352 ifxp = &sc->sc_ifw[0]; 353 for (rp = &dc->dc_xrent[0]; rp < &dc->dc_xrent[NXMT]; rp++) { 354 rp->r_segbl = LOWORD(ifxp->ifw_info); 355 rp->r_segbh = HIWORD(ifxp->ifw_info); 356 rp->r_flags = 0; 357 ifxp++; 358 } 359 ifrw = &sc->sc_ifr[0]; 360 for (rp = &dc->dc_rrent[0]; rp < &dc->dc_rrent[NRCV]; rp++) { 361 rp->r_slen = MCLBYTES - 2; 362 rp->r_segbl = LOWORD(ifrw->ifrw_info); 363 rp->r_segbh = HIWORD(ifrw->ifrw_info); 364 rp->r_flags = RFLG_OWN; 365 ifrw++; 366 } 367 368 /* start up the board (rah rah) */ 369 s = splnet(); 370 sc->sc_rindex = sc->sc_xindex = sc->sc_xfree = sc->sc_nxmit = 0; 371 sc->sc_if.if_flags |= IFF_RUNNING; 372 DE_WLOW(PCSR0_INTE); /* avoid interlock */ 373 destart(&sc->sc_if); /* queue output packets */ 374 DE_WLOW(CMD_START|PCSR0_INTE); 375 splx(s); 376 return 0; 377 } 378 379 /* 380 * Setup output on interface. 381 * Get another datagram to send off of the interface queue, 382 * and map it to the interface before starting the output. 383 * Must be called from ipl >= our interrupt level. 384 */ 385 void 386 destart(struct ifnet *ifp) 387 { 388 struct de_softc *sc = ifp->if_softc; 389 struct de_cdata *dc; 390 struct de_ring *rp; 391 struct mbuf *m; 392 int nxmit, len; 393 394 /* 395 * the following test is necessary, since 396 * the code is not reentrant and we have 397 * multiple transmission buffers. 398 */ 399 if (sc->sc_if.if_flags & IFF_OACTIVE) 400 return; 401 dc = sc->sc_dedata; 402 for (nxmit = sc->sc_nxmit; nxmit < NXMT; nxmit++) { 403 IFQ_DEQUEUE(&ifp->if_snd, m); 404 if (m == 0) 405 break; 406 407 rp = &dc->dc_xrent[sc->sc_xfree]; 408 if (rp->r_flags & XFLG_OWN) 409 panic("deuna xmit in progress"); 410 #if NBPFILTER > 0 411 if (ifp->if_bpf) 412 bpf_mtap(ifp->if_bpf, m); 413 #endif 414 415 len = if_ubaput(&sc->sc_ifuba, &sc->sc_ifw[sc->sc_xfree], m); 416 rp->r_slen = len; 417 rp->r_tdrerr = 0; 418 rp->r_flags = XFLG_STP|XFLG_ENP|XFLG_OWN; 419 420 sc->sc_xfree++; 421 if (sc->sc_xfree == NXMT) 422 sc->sc_xfree = 0; 423 } 424 if (sc->sc_nxmit != nxmit) { 425 sc->sc_nxmit = nxmit; 426 if (ifp->if_flags & IFF_RUNNING) 427 DE_WLOW(PCSR0_INTE|CMD_PDMD); 428 } 429 } 430 431 /* 432 * Command done interrupt. 433 */ 434 void 435 deintr(void *arg) 436 { 437 struct ifxmt *ifxp; 438 struct de_cdata *dc; 439 struct de_softc *sc = arg; 440 struct de_ring *rp; 441 short csr0; 442 443 /* save flags right away - clear out interrupt bits */ 444 csr0 = DE_RCSR(DE_PCSR0); 445 DE_WHIGH(csr0 >> 8); 446 447 448 sc->sc_if.if_flags |= IFF_OACTIVE; /* prevent entering destart */ 449 /* 450 * if receive, put receive buffer on mbuf 451 * and hang the request again 452 */ 453 derecv(sc); 454 455 /* 456 * Poll transmit ring and check status. 457 * Be careful about loopback requests. 458 * Then free buffer space and check for 459 * more transmit requests. 460 */ 461 dc = sc->sc_dedata; 462 for ( ; sc->sc_nxmit > 0; sc->sc_nxmit--) { 463 rp = &dc->dc_xrent[sc->sc_xindex]; 464 if (rp->r_flags & XFLG_OWN) 465 break; 466 467 sc->sc_if.if_opackets++; 468 ifxp = &sc->sc_ifw[sc->sc_xindex]; 469 /* check for unusual conditions */ 470 if (rp->r_flags & (XFLG_ERRS|XFLG_MTCH|XFLG_ONE|XFLG_MORE)) { 471 if (rp->r_flags & XFLG_ERRS) { 472 /* output error */ 473 sc->sc_if.if_oerrors++; 474 } else if (rp->r_flags & XFLG_ONE) { 475 /* one collision */ 476 sc->sc_if.if_collisions++; 477 } else if (rp->r_flags & XFLG_MORE) { 478 /* more than one collision */ 479 sc->sc_if.if_collisions += 2; /* guess */ 480 } 481 } 482 if_ubaend(&sc->sc_ifuba, ifxp); 483 /* check if next transmit buffer also finished */ 484 sc->sc_xindex++; 485 if (sc->sc_xindex == NXMT) 486 sc->sc_xindex = 0; 487 } 488 sc->sc_if.if_flags &= ~IFF_OACTIVE; 489 destart(&sc->sc_if); 490 491 if (csr0 & PCSR0_RCBI) { 492 DE_WLOW(PCSR0_INTE|CMD_PDMD); 493 } 494 } 495 496 /* 497 * Ethernet interface receiver interface. 498 * If input error just drop packet. 499 * Otherwise purge input buffered data path and examine 500 * packet to determine type. If can't determine length 501 * from type, then have to drop packet. Othewise decapsulate 502 * packet based on type and pass to type specific higher-level 503 * input routine. 504 */ 505 void 506 derecv(struct de_softc *sc) 507 { 508 struct ifnet *ifp = &sc->sc_if; 509 struct de_ring *rp; 510 struct de_cdata *dc; 511 struct mbuf *m; 512 int len; 513 514 dc = sc->sc_dedata; 515 rp = &dc->dc_rrent[sc->sc_rindex]; 516 while ((rp->r_flags & RFLG_OWN) == 0) { 517 sc->sc_if.if_ipackets++; 518 len = (rp->r_lenerr&RERR_MLEN) - ETHER_CRC_LEN; 519 /* check for errors */ 520 if ((rp->r_flags & (RFLG_ERRS|RFLG_FRAM|RFLG_OFLO|RFLG_CRC)) || 521 (rp->r_lenerr & (RERR_BUFL|RERR_UBTO))) { 522 sc->sc_if.if_ierrors++; 523 goto next; 524 } 525 m = if_ubaget(&sc->sc_ifuba, &sc->sc_ifr[sc->sc_rindex], 526 ifp, len); 527 if (m == 0) { 528 sc->sc_if.if_ierrors++; 529 goto next; 530 } 531 #if NBPFILTER > 0 532 if (ifp->if_bpf) 533 bpf_mtap(ifp->if_bpf, m); 534 #endif 535 536 (*ifp->if_input)(ifp, m); 537 538 /* hang the receive buffer again */ 539 next: rp->r_lenerr = 0; 540 rp->r_flags = RFLG_OWN; 541 542 /* check next receive buffer */ 543 sc->sc_rindex++; 544 if (sc->sc_rindex == NRCV) 545 sc->sc_rindex = 0; 546 rp = &dc->dc_rrent[sc->sc_rindex]; 547 } 548 } 549 550 /* 551 * Process an ioctl request. 552 */ 553 int 554 deioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 555 { 556 int s, error = 0; 557 558 s = splnet(); 559 560 error = ether_ioctl(ifp, cmd, data); 561 if (error == ENETRESET) 562 error = 0; 563 564 splx(s); 565 return (error); 566 } 567 568 /* 569 * Await completion of the named function 570 * and check for errors. 571 */ 572 void 573 dewait(struct de_softc *sc, char *fn) 574 { 575 int csr0; 576 577 while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) 578 ; 579 csr0 = DE_RCSR(DE_PCSR0); 580 DE_WHIGH(csr0 >> 8); 581 if (csr0 & PCSR0_PCEI) { 582 char bits[64]; 583 printf("%s: %s failed, csr0=%s ", sc->sc_dev.dv_xname, fn, 584 bitmask_snprintf(csr0, PCSR0_BITS, bits, sizeof(bits))); 585 printf("csr1=%s\n", bitmask_snprintf(DE_RCSR(DE_PCSR1), 586 PCSR1_BITS, bits, sizeof(bits))); 587 } 588 } 589 590 int 591 dematch(struct device *parent, struct cfdata *cf, void *aux) 592 { 593 struct uba_attach_args *ua = aux; 594 struct de_softc ssc; 595 struct de_softc *sc = &ssc; 596 int i; 597 598 sc->sc_iot = ua->ua_iot; 599 sc->sc_ioh = ua->ua_ioh; 600 /* 601 * Make sure self-test is finished before we screw with the board. 602 * Self-test on a DELUA can take 15 seconds (argh). 603 */ 604 for (i = 0; 605 (i < 160) && 606 (DE_RCSR(DE_PCSR0) & PCSR0_FATI) == 0 && 607 (DE_RCSR(DE_PCSR1) & PCSR1_STMASK) == STAT_RESET; 608 ++i) 609 DELAY(50000); 610 if (((DE_RCSR(DE_PCSR0) & PCSR0_FATI) != 0) || 611 (((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_READY) && 612 ((DE_RCSR(DE_PCSR1) & PCSR1_STMASK) != STAT_RUN))) 613 return(0); 614 615 DE_WCSR(DE_PCSR0, 0); 616 DELAY(5000); 617 DE_WCSR(DE_PCSR0, PCSR0_RSET); 618 while ((DE_RCSR(DE_PCSR0) & PCSR0_INTR) == 0) 619 ; 620 /* make board interrupt by executing a GETPCBB command */ 621 DE_WCSR(DE_PCSR0, PCSR0_INTE); 622 DE_WCSR(DE_PCSR2, 0); 623 DE_WCSR(DE_PCSR3, 0); 624 DE_WCSR(DE_PCSR0, PCSR0_INTE|CMD_GETPCBB); 625 DELAY(50000); 626 627 return 1; 628 } 629 630 void 631 deshutdown(void *arg) 632 { 633 struct de_softc *sc = arg; 634 635 DE_WCSR(DE_PCSR0, 0); 636 DELAY(1000); 637 DE_WCSR(DE_PCSR0, PCSR0_RSET); 638 dewait(sc, "shutdown"); 639 } 640