1 /* dr.c 1.6 86/12/15 */ 2 3 #include "dr.h" 4 #if NDR > 0 5 /* 6 * DRV11-W DMA interface driver. 7 * 8 * UNTESTED WITH 4.3 9 */ 10 #include "../machine/mtpr.h" 11 #include "../machine/pte.h" 12 13 #include "param.h" 14 #include "conf.h" 15 #include "dir.h" 16 #include "user.h" 17 #include "proc.h" 18 #include "map.h" 19 #include "ioctl.h" 20 #include "buf.h" 21 #include "vm.h" 22 #include "uio.h" 23 #include "kernel.h" 24 25 #include "../tahoevba/vbavar.h" 26 #include "../tahoevba/drreg.h" 27 28 #define YES 1 29 #define NO 0 30 31 struct vba_device *drinfo[NDR]; 32 struct dr_aux dr_aux[NDR]; 33 34 unsigned drminphys(); 35 int drprobe(), drintr(), drattach(), drtimo(), drrwtimo(); 36 int drstrategy(); 37 extern struct vba_device *drinfo[]; 38 static long drstd[] = { 0 }; 39 struct vba_driver drdriver = 40 { drprobe, 0, drattach, 0, drstd, "rs", drinfo }; 41 42 #define RSUNIT(dev) (minor(dev) & 7) 43 #define SPL_UP spl5 44 45 /* -------- Per-unit data -------- */ 46 47 extern struct dr_aux dr_aux[]; 48 49 #ifdef DR_DEBUG 50 long DR11 = 0; 51 #endif 52 53 drprobe(reg, vi) 54 caddr_t reg; 55 struct vba_device *vi; 56 { 57 register int br, cvec; /* must be r12, r11 */ 58 struct rsdevice *dr; 59 60 #ifdef lint 61 br = 0; cvec = br; br = cvec; 62 drintr(0); 63 #endif 64 if (badaddr(reg, 2)) 65 return (0); 66 dr = (struct rsdevice *)reg; 67 dr->dr_intvect = --vi->ui_hd->vh_lastiv; 68 #ifdef DR_DEBUG 69 printf("dprobe: Set interrupt vector %lx and init\n",dr->dr_intvec); 70 #endif 71 /* generate interrupt here for autoconfig */ 72 dr->dr_cstat = MCLR; /* init board and device */ 73 #ifdef DR_DEBUG 74 printf("drprobe: Initial status %lx\n", dr->dr_cstat); 75 #endif 76 br = 0x18, cvec = dr->dr_intvect; /* XXX */ 77 return (sizeof (struct rsdevice)); /* DR11 exist */ 78 } 79 80 /* ARGSUSED */ 81 drattach(ui) 82 struct vba_device *ui; 83 { 84 register struct dr_aux *rsd; 85 86 rsd = &dr_aux[ui->ui_unit]; 87 rsd->dr_flags = DR_PRES; /* This dr11 is present */ 88 rsd->dr_addr = (struct rsdevice *)ui->ui_addr; /* Save addr of this dr11 */ 89 rsd->dr_istat = 0; 90 rsd->dr_bycnt = 0; 91 rsd->dr_cmd = 0; 92 rsd->currenttimo = 0; 93 } 94 95 /*ARGSUSED*/ 96 dropen(dev, flag) 97 dev_t dev; 98 int flag; 99 { 100 register int unit = RSUNIT(dev); 101 register struct rsdevice *dr; 102 register struct dr_aux *rsd; 103 104 if (drinfo[unit] == 0 || !drinfo[unit]->ui_alive) 105 return (ENXIO); 106 dr = RSADDR(unit); 107 rsd = &dr_aux[unit]; 108 if (rsd->dr_flags & DR_OPEN) { 109 #ifdef DR_DEBUG 110 printf("\ndropen: dr11 unit %ld already open",unit); 111 #endif 112 return (ENXIO); /* DR11 already open */ 113 } 114 rsd->dr_flags |= DR_OPEN; /* Mark it OPEN */ 115 rsd->dr_istat = 0; /* Clear status of previous interrupt */ 116 rsd->rtimoticks = hz; /* Set read no stall timout to 1 sec */ 117 rsd->wtimoticks = hz*60; /* Set write no stall timout to 1 min */ 118 dr->dr_cstat = DR_ZERO; /* Clear function & latches */ 119 dr->dr_pulse = (RDMA | RATN); /* clear leftover attn & e-o-r flags */ 120 drtimo(dev); /* start the self kicker */ 121 return (0); 122 } 123 124 drclose (dev) 125 dev_t dev; 126 { 127 register int unit = RSUNIT(dev); 128 register struct dr_aux *dra; 129 register struct rsdevice *rs; 130 register short s; 131 132 dra = &dr_aux[unit]; 133 if ((dra->dr_flags & DR_OPEN) == 0) { 134 #ifdef DR_DEBUG 135 printf("\ndrclose: DR11 device %ld not open",unit); 136 #endif 137 return; 138 } 139 dra->dr_flags &= ~(DR_OPEN|DR_ACTV); 140 rs = dra->dr_addr; 141 s = SPL_UP(); 142 rs->dr_cstat = DR_ZERO; 143 if (dra->dr_buf.b_flags & B_BUSY) { 144 dra->dr_buf.b_flags &= ~B_BUSY; 145 wakeup((caddr_t)&dra->dr_buf.b_flags); 146 } 147 splx(s); 148 } 149 150 151 /* drread() works exactly like drwrite() except that the 152 B_READ flag is used when physio() is called 153 */ 154 drread (dev, uio) 155 dev_t dev; 156 struct uio *uio; 157 { register struct dr_aux *dra; 158 register struct buf *bp; 159 register int spl, err; 160 register int unit = RSUNIT(dev); 161 162 if (uio->uio_iov->iov_len <= 0 || /* Negative count */ 163 uio->uio_iov->iov_len & 1 || /* odd count */ 164 (int)uio->uio_iov->iov_base & 1) /* odd destination address */ 165 return (EINVAL); 166 #ifdef DR_DEBUG 167 if (DR11 & 8) 168 printf("\ndrread: (len:%ld)(base:%lx)", 169 uio->uio_iov->iov_len,(int)uio->uio_iov->iov_base); 170 #endif 171 dra = &dr_aux[RSUNIT(dev)]; 172 dra->dr_op = DR_READ; 173 bp = &dra->dr_buf; 174 bp->b_resid = 0; 175 if (dra->dr_flags & DR_NORSTALL) { 176 /* 177 * We are in no stall mode, start the timer, 178 * raise IPL so nothing can stop us once the 179 * timer's running 180 */ 181 spl = SPL_UP(); 182 timeout(drrwtimo, (caddr_t)((dra->currenttimo<<8) | unit), 183 (int)dra->rtimoticks); 184 err = physio(drstrategy, bp, dev,B_READ, drminphys, uio); 185 splx(spl); 186 if (err) 187 return (err); 188 dra->currenttimo++; /* Update current timeout number */ 189 /* Did we timeout */ 190 if (dra->dr_flags & DR_TMDM) { 191 dra->dr_flags &= ~DR_TMDM; /* Clear timeout flag */ 192 u.u_error = 0; /* Made the error ourself, ignore it */ 193 } 194 return (err); 195 } 196 return (physio(drstrategy, bp, dev,B_READ, drminphys, uio)); 197 } 198 199 drwrite(dev, uio) 200 dev_t dev; 201 struct uio *uio; 202 { register struct dr_aux *dra; 203 register struct buf *bp; 204 register int unit = RSUNIT(dev); 205 int spl, err; 206 207 if (uio->uio_iov->iov_len <= 0 || uio->uio_iov->iov_len & 1 || 208 (int)uio->uio_iov->iov_base & 1) 209 return (EINVAL); 210 #ifdef DR_DEBUG 211 if (DR11 & 4) 212 printf("\ndrwrite: (len:%ld)(base:%lx)", 213 uio->uio_iov->iov_len,(int)uio->uio_iov->iov_base); 214 #endif 215 dra = &dr_aux[RSUNIT(dev)]; 216 dra->dr_op = DR_WRITE; 217 bp = &dra->dr_buf; 218 bp->b_resid = 0; 219 if (dra->dr_flags & DR_NOWSTALL) { 220 /* 221 * We are in no stall mode, start the timer, 222 * raise IPL so nothing can stop us once the 223 * timer's running 224 */ 225 spl = SPL_UP(); 226 timeout(drrwtimo,(caddr_t)((dra->currenttimo<<8) | unit), 227 (int)dra->wtimoticks); 228 err = physio (drstrategy, bp, dev,B_WRITE, drminphys, uio); 229 splx(spl); 230 if (err) 231 return (err); 232 dra->currenttimo++; /* Update current timeout number */ 233 /* Did we timeout */ 234 if (dra->dr_flags & DR_TMDM) { 235 dra->dr_flags &= ~DR_TMDM; /* Clear timeout flag */ 236 u.u_error = 0; /* Made the error ourself, ignore it */ 237 } 238 return (err); 239 } 240 return (physio(drstrategy, bp, dev,B_WRITE, drminphys, uio)); 241 } 242 243 /* 244 * Routine used by calling program to issue commands to dr11 driver and 245 * through it to the device. 246 * It is also used to read status from the device and driver and to wait 247 * for attention interrupts. 248 * Status is returned in an 8 elements unsigned short integer array, the 249 * first two elements of the array are also used to pass arguments to 250 * drioctl() if required. 251 * The function bits to be written to the dr11 are included in the cmd 252 * argument. Even if they are not being written to the dr11 in a particular 253 * drioctl() call, they will update the copy of cmd that is stored in the 254 * driver. When drstrategy() is called, this updated copy is used if a 255 * deferred function bit write has been specified. The "side effect" of 256 * calls to the drioctl() requires that the last call prior to a read or 257 * write has an appropriate copy of the function bits in cmd if they are 258 * to be used in drstrategy(). 259 * When used as command value, the contents of data[0] is the command 260 * parameter. 261 */ 262 drioctl(dev, cmd, data) 263 dev_t dev; 264 int cmd; 265 long *data; 266 { 267 register int unit = RSUNIT(dev); 268 register struct dr_aux *dra; 269 register struct rsdevice *rsaddr = RSADDR(unit); 270 int s; 271 u_short status; 272 long temp; 273 274 #ifdef DR_DEBUG 275 if (DR11 & 0x10) 276 printf("\ndrioctl: (dev:%lx)(cmd:%lx)(data:%lx)(data[0]:%lx)", 277 dev,cmd,data,data[0]); 278 #endif 279 dra = &dr_aux[unit]; 280 dra->dr_cmd = 0; /* Fresh copy; clear all previous flags */ 281 switch (cmd) { 282 283 case DRWAIT: /* Wait for attention interrupt */ 284 #ifdef DR_DEBUG 285 printf("\ndrioctl: wait for attention interrupt"); 286 #endif 287 s = SPL_UP(); 288 /* 289 * If the attention flag in dr_flags is set, it probably 290 * means that an attention has arrived by the time a 291 * previous DMA end-of-range interrupt was serviced. If 292 * ATRX is set, we will return with out sleeping, since 293 * we have received an attention since the last call to 294 * wait on attention. This may not be appropriate for 295 * some applications. 296 */ 297 if ((dra->dr_flags & DR_ATRX) == 0) { 298 dra->dr_flags |= DR_ATWT; /* Set waiting flag */ 299 /* 300 * Enable interrupt; use pulse reg. 301 * so function bits are not changed 302 */ 303 rsaddr->dr_pulse = IENB; 304 sleep((caddr_t)&dra->dr_cmd, DRPRI); 305 } 306 splx(s); 307 break; 308 309 case DRPIOW: /* Write to p-i/o register */ 310 rsaddr->dr_data = data[0]; 311 break; 312 313 case DRPACL: /* Send pulse to device */ 314 rsaddr->dr_pulse = FCN2; 315 break; 316 317 case DRDACL: /* Defer alco pulse until go */ 318 dra->dr_cmd |= DR_DACL; 319 break; 320 321 case DRPCYL: /* Set cycle with next go */ 322 dra->dr_cmd |= DR_PCYL; 323 break; 324 325 case DRDFCN: /* Update function with next go */ 326 dra->dr_cmd |= DR_DFCN; 327 break; 328 329 case DRRATN: /* Reset attention flag */ 330 rsaddr->dr_pulse = RATN; 331 break; 332 333 case DRRDMA: /* Reset DMA e-o-r flag */ 334 rsaddr->dr_pulse = RDMA; 335 break; 336 337 case DRSFCN: /* Set function bits */ 338 temp = data[0] & DR_FMSK; 339 /* 340 * This has a very important side effect -- It clears 341 * the interrupt enable flag. That is fine for this driver, 342 * but if it is desired to leave interrupt enable at all 343 * times, it will be necessary to read the status register 344 * first to get IENB, or carry a software flag that indicates 345 * whether interrupts are set, and or this into the control 346 * register value being written. 347 */ 348 rsaddr->dr_cstat = temp; 349 break; 350 351 case DRRPER: /* Clear parity flag */ 352 rsaddr->dr_pulse = RPER; 353 break; 354 355 case DRSETRSTALL: /* Set read stall mode. */ 356 dra->dr_flags &= (~DR_NORSTALL); 357 break; 358 359 case DRSETNORSTALL: /* Set no stall read mode. */ 360 dra->dr_flags |= DR_NORSTALL; 361 break; 362 363 case DRGETRSTALL: /* Returns true if in read stall mode */ 364 data[0] = (dra->dr_flags & DR_NORSTALL)? 0 : 1; 365 break; 366 367 case DRSETRTIMEOUT: /* Set read stall timeout (1/10 secs) */ 368 if (data[0] < 1) { 369 u.u_error = EINVAL; 370 temp = 1; 371 } 372 dra->rtimoticks = (data[0] * hz )/10; 373 break; 374 375 case DRGETRTIMEOUT: /* Return read stall timeout */ 376 data[0] = ((dra->rtimoticks)*10)/hz; 377 break; 378 379 case DRSETWSTALL: /* Set write stall mode. */ 380 dra->dr_flags &= (~DR_NOWSTALL); 381 break; 382 383 case DRSETNOWSTALL: /* Set write stall mode. */ 384 dra->dr_flags |= DR_NOWSTALL; 385 break; 386 387 case DRGETWSTALL: /* Return true if in write stall mode */ 388 data[0] = (dra->dr_flags & DR_NOWSTALL)? 0 : 1; 389 break; 390 391 case DRSETWTIMEOUT: /* Set write stall timeout (1/10's) */ 392 if (data[0] < 1) { 393 u.u_error = EINVAL; 394 temp = 1; 395 } 396 dra->wtimoticks = (data[0] * hz )/10; 397 break; 398 399 case DRGETWTIMEOUT: /* Return write stall timeout */ 400 data[0] = ((dra->wtimoticks)*10)/hz; 401 break; 402 403 case DRWRITEREADY: /* Return true if can write data */ 404 data[0] = (rsaddr->dr_cstat & STTA)? 1 : 0; 405 break; 406 407 case DRREADREADY: /* Return true if data to be read */ 408 data[0] = (rsaddr->dr_cstat & STTB)? 1 : 0; 409 break; 410 411 case DRBUSY: /* Return true if device busy */ 412 /* 413 * Internally this is the DR11-W 414 * STAT C bit, but there is a bug in the Omega 500/FIFO 415 * interface board that it cannot drive this signal low 416 * for certain DR11-W ctlr such as the Ikon. We use the 417 * REDY signal of the CSR on the Ikon DR11-W instead. 418 */ 419 #ifdef notdef 420 data[0] = (rsaddr->dr_cstat & STTC)? 1 : 0; 421 #else 422 data[0] = ((rsaddr->dr_cstat & REDY)? 0 : 1); 423 #endif 424 break; 425 426 case DRRESET: /* Reset device */ 427 /* Reset DMA ATN RPER flag */ 428 rsaddr->dr_pulse = (MCLR|RDMA|RATN|RPER); 429 DELAY(0x1f000); 430 while ((rsaddr->dr_cstat & REDY) == 0) 431 sleep((caddr_t)dra, DRPRI); /* Wakeup by drtimo() */ 432 dra->dr_istat = 0; 433 dra->dr_cmd = 0; 434 dra->currenttimo = 0; 435 break; 436 437 case DR11STAT: { /* Copy back dr11 status to user */ 438 register struct dr11io *dr = (struct dr11io *)data; 439 dr->arg[0] = dra->dr_flags; 440 dr->arg[1] = rsaddr->dr_cstat; 441 dr->arg[2] = dra->dr_istat; /* Status at last interrupt */ 442 dr->arg[3] = rsaddr->dr_data; /* P-i/o input data */ 443 status = (u_short)((rsaddr->dr_addmod << 8) & 0xff00); 444 dr->arg[4] = status | (u_short)(rsaddr->dr_intvect & 0xff); 445 dr->arg[5] = rsaddr->dr_range; 446 dr->arg[6] = rsaddr->dr_rahi; 447 dr->arg[7] = rsaddr->dr_ralo; 448 break; 449 } 450 case DR11LOOP: /* Perform loopback test */ 451 /* 452 * NB: MUST HAVE LOOPBACK CABLE ATTACHED -- 453 * Test results are printed on system console 454 */ 455 if (suser()) 456 dr11loop(rsaddr, dra, unit); 457 break; 458 459 default: 460 return (EINVAL); 461 } 462 #ifdef DR_DEBUG 463 if (DR11 & 0x10) 464 printf("**** (data[0]:%lx)",data[0]); 465 #endif 466 return (0); 467 } 468 469 #define NPAT 2 470 #define DMATBL 20 471 u_short tstpat[DMATBL] = { 0xAAAA, 0x5555}; 472 long DMAin = 0; 473 474 /* 475 * Perform loopback test -- MUST HAVE LOOPBACK CABLE ATTACHED 476 * Test results are printed on system console 477 */ 478 dr11loop(dr, dra, unit) 479 struct rsdevice *dr; 480 struct dr_aux *dra; 481 int unit; 482 { 483 register long result, ix; 484 long addr, wait; 485 486 dr->dr_cstat = MCLR; /* Clear board & device, disable intr */ 487 printf("\n\t ----- DR11 unit %ld loopback test -----", unit); 488 printf("\n\t Program I/O ..."); 489 for (ix=0;ix<NPAT;ix++) { 490 dr->dr_data = tstpat[ix]; /* Write to Data out register */ 491 result = dr->dr_data & 0xFFFF; /* Read it back */ 492 if (result != tstpat[ix]) { 493 printf("Failed, expected : %lx --- actual : %lx", 494 tstpat[ix], result); 495 return; 496 } 497 } 498 printf("OK\n\t Functions & Status Bits ..."); 499 dr->dr_cstat = (FCN1 | FCN3); 500 result = dr->dr_cstat & 0xffff; /* Read them back */ 501 if ((result & (STTC | STTA)) != (STTC |STTA)) { 502 printf("Failed, expected : %lx --- actual : %lx, ISR:%lx", 503 (STTA|STTC), (result & (STTA|STTC)), result); 504 return; 505 } 506 dr->dr_cstat = FCN2; 507 result = dr->dr_cstat & 0xffff; /* Read them back */ 508 if ((result & STTB) != STTB) { 509 printf("Failed, expected : %lx --- actual : %lx, ISR:%lx", 510 STTB, (result & STTB), result); 511 return; 512 } 513 printf("OK\n\t DMA output ..."); 514 if (DMAin) 515 goto dmain; 516 /* Initialize DMA data buffer */ 517 for (ix=0; ix<DMATBL; ix++) 518 tstpat[ix] = 0xCCCC + ix; 519 tstpat[DMATBL-1] = 0xCCCC; /* Last word output */ 520 /* Setup normal DMA */ 521 addr = (long)vtoph((struct proc *)0, (unsigned)tstpat); 522 dr->dr_walo = (addr >> 1) & 0xffff; 523 dr->dr_wahi = (addr >> 17) & 0x7fff; 524 /* Set DMA range count: (number of words - 1) */ 525 dr->dr_range = DMATBL - 1; 526 /* Set address modifier code to be used for DMA access to memory */ 527 dr->dr_addmod = DRADDMOD; 528 529 /* 530 * Clear dmaf and attf to assure a clean dma start, also disable 531 * attention interrupt 532 */ 533 dr->dr_pulse = RDMA|RATN|RMSK; /* Use pulse register */ 534 dr->dr_cstat = GO|CYCL; /* GO...... */ 535 536 /* Wait for DMA complete; REDY and DMAF are true in ISR */ 537 wait = 0; 538 while ((result=(dr->dr_cstat & (REDY|DMAF))) != (REDY|DMAF)) { 539 printf("\n\tWait for DMA complete...ISR : %lx", result); 540 if (++wait > 5) { 541 printf("\n\t DMA output fails...timeout!!, ISR:%lx", 542 result); 543 return; 544 } 545 } 546 result = dr->dr_data & 0xffff; /* Read last word output */ 547 if (result != 0xCCCC) { 548 printf("\n\t Fails, expected : %lx --- actual : %lx", 549 0xCCCC, result); 550 return; 551 } 552 printf("OK\n\t DMA input ..."); 553 dmain: 554 dr->dr_data = 0x1111; /* DMA input data */ 555 /* Setup normal DMA */ 556 addr = (long)vtoph((struct proc *)0, (unsigned)tstpat); 557 dr->dr_walo = (addr >> 1) & 0xffff; 558 dr->dr_wahi = (addr >> 17) & 0x7fff; 559 dr->dr_range = DMATBL - 1; 560 dr->dr_addmod = (char)DRADDMOD; 561 dr->dr_cstat = FCN1; /* Set FCN1 in ICR to DMA in*/ 562 if ((dra->dr_flags & DR_LOOPTST) == 0) { 563 /* Use pulse reg */ 564 dr->dr_pulse = RDMA|RATN|RMSK|CYCL|GO; 565 /* Wait for DMA complete; REDY and DMAF are true in ISR */ 566 wait = 0; 567 while ((result=(dr->dr_cstat & (REDY|DMAF))) != (REDY|DMAF)) { 568 printf("\n\tWait for DMA to complete...ISR:%lx",result); 569 if (++wait > 5) { 570 printf("\n\t DMA input timeout!!, ISR:%lx", 571 result); 572 return; 573 } 574 } 575 } else { 576 /* Enable DMA e-o-r interrupt */ 577 dr->dr_pulse = IENB|RDMA|RATN|CYCL|GO; 578 /* Wait for DMA complete; DR_LOOPTST is false in dra->dr_flags*/ 579 wait = 0; 580 while (dra->dr_flags & DR_LOOPTST) { 581 result = dr->dr_cstat & 0xffff; 582 printf("\n\tWait for DMA e-o-r intr...ISR:%lx", result); 583 if (++wait > 7) { 584 printf("\n\t DMA e-o-r timeout!!, ISR:%lx", 585 result); 586 dra->dr_flags &= ~DR_LOOPTST; 587 return; 588 } 589 } 590 dra->dr_flags |= DR_LOOPTST; 591 } 592 mtpr(P1DC, tstpat); /* Purge cache */ 593 mtpr(P1DC, 0x3ff+tstpat); 594 for (ix=0; ix<DMATBL; ix++) { 595 if (tstpat[ix] != 0x1111) { 596 printf("\n\t Fails, ix:%d, expected:%x --- actual:%x", 597 ix, 0x1111, tstpat[ix]); 598 return; 599 } 600 } 601 if ((dra->dr_flags & DR_LOOPTST) == 0) { 602 dra->dr_flags |= DR_LOOPTST; 603 printf(" OK..\n\tDMA end of range interrupt..."); 604 goto dmain; 605 } 606 printf(" OK..\n\tAttention interrupt...."); 607 dr->dr_pulse = IENB|RDMA; 608 dr->dr_pulse = FCN2; 609 /* Wait for ATTN interrupt; DR_LOOPTST is false in dra->dr_flags*/ 610 wait = 0; 611 while (dra->dr_flags & DR_LOOPTST) { 612 result = dr->dr_cstat & 0xffff; 613 printf("\n\tWait for Attention intr...ISR:%lx",result); 614 if (++wait > 7) { 615 printf("\n\t Attention interrupt timeout!!, ISR:%lx", 616 result); 617 dra->dr_flags &= ~DR_LOOPTST; 618 return; 619 } 620 } 621 dra->dr_flags &= ~DR_LOOPTST; 622 printf(" OK..\n\tDone..."); 623 } 624 625 /* Reset state on Unibus reset */ 626 /*ARGSUSED*/ 627 drreset(uban) 628 int uban; 629 { 630 631 } 632 633 /* 634 * An interrupt is caused either by an error, 635 * base address overflow, or transfer complete 636 */ 637 drintr(dr11) 638 int dr11; 639 { 640 register struct dr_aux *dra = &dr_aux[dr11]; 641 register struct rsdevice *rsaddr = RSADDR(dr11); 642 register struct buf *bp; 643 register short status; 644 645 status = rsaddr->dr_cstat & 0xffff; /* get board status register */ 646 dra->dr_istat = status; 647 #ifdef DR_DEBUG 648 if (DR11 & 2) 649 printf("\ndrintr: dr11 status : %lx",status & 0xffff); 650 #endif 651 if (dra->dr_flags & DR_LOOPTST) { /* doing loopback test */ 652 dra->dr_flags &= ~DR_LOOPTST; 653 return; 654 } 655 /* 656 * Make sure this is not a stray interrupt; at least one of dmaf or attf 657 * must be set. Note that if the dr11 interrupt enable latch is reset 658 * during a hardware interrupt ack sequence, and by the we get to this 659 * point in the interrupt code it will be 0. This is done to give the 660 * programmer some control over how the two more-or-less independent 661 * interrupt sources on the board are handled. 662 * If the attention flag is set when drstrategy() is called to start a 663 * dma read or write an interrupt will be generated as soon as the 664 * strategy routine enables interrupts for dma end-of-range. This will 665 * cause execution of the interrupt routine (not necessarily bad) and 666 * will cause the interrupt enable mask to be reset (very bad since the 667 * dma end-of-range condition will not be able to generate an interrupt 668 * when it occurs) causing the dma operation to time-out (even though 669 * the dma transfer will be done successfully) or hang the process if a 670 * software time-out capability is not implemented. One way to avoid 671 * this situation is to check for a pending attention interrupt (attf 672 * set) by calling drioctl() before doing a read or a write. For the 673 * time being this driver will solve the problem by clearing the attf 674 * flag in the status register before enabling interrupts in 675 * drstrategy(). 676 * 677 * **** The IKON 10084 for which this driver is written will set both 678 * attf and dmaf if dma is terminated by an attention pulse. This will 679 * cause a wakeup(&dr_aux), which will be ignored since it is not being 680 * waited on, and an iodone(bp) which is the desired action. Some other 681 * dr11 emulators, in particular the IKON 10077 for the Multibus, donot 682 * dmaf in this case. This may require some addtional code in the inter- 683 * rupt routine to ensure that en iodone(bp) is issued when dma is term- 684 * inated by attention. 685 */ 686 bp = dra->dr_actf; 687 if ((status & (ATTF | DMAF)) == 0) { 688 printf("dr%d: stray interrupt, status=%x", dr11, status); 689 return; 690 } 691 if (status & DMAF) { /* End-of-range interrupt */ 692 dra->dr_flags |= DR_DMAX; 693 694 #ifdef DR_DEBUG 695 if (DR11 & 2) 696 printf("\ndrintr: e-o-r interrupt,cstat:%lx,dr_flags:%lx", 697 status&0xffff, dra->dr_flags & DR_ACTV); 698 #endif 699 if ((dra->dr_flags & DR_ACTV) == 0) { 700 /* We are not doing DMA !! */ 701 bp->b_flags |= B_ERROR; 702 } else { 703 if (dra->dr_op == DR_READ) 704 mtpr(P1DC, bp->b_un.b_addr); 705 dra->dr_bycnt -= bp->b_bcount; 706 if (dra->dr_bycnt >0) { 707 bp->b_un.b_addr += bp->b_bcount; 708 bp->b_bcount = (dra->dr_bycnt > NBPG) ? NBPG: 709 dra->dr_bycnt; 710 drstart(rsaddr, dra, bp); 711 return; 712 } 713 } 714 dra->dr_flags &= ~DR_ACTV; 715 wakeup((caddr_t)dra); /* Wakeup waiting in drwait() */ 716 rsaddr->dr_pulse = (RPER|RDMA|RATN); /* reset dma e-o-r flag */ 717 } 718 /* 719 * Now test for attention interrupt -- It may be set in addition to 720 * the dma e-o-r interrupt. If we get one we will issue a wakeup to 721 * the drioctl() routine which is presumable waiting for one. 722 * The program may have to monitor the attention interrupt received 723 * flag in addition to doing waits for the interrupt. Futhermore, 724 * interrupts are not enabled unless dma is in progress or drioctl() 725 * has been called to wait for attention -- this may produce some 726 * strange results if attf is set on the dr11 when a read or a write 727 * is initiated, since that will enables interrupts. 728 * **** The appropriate code for this interrupt routine will probably 729 * be rather application dependent. 730 */ 731 if (status & ATTF) { 732 dra->dr_flags |= DR_ATRX; 733 dra->dr_flags &= ~DR_ATWT; 734 rsaddr->dr_cstat = RATN; /* reset attention flag */ 735 /* 736 * Some applications which use attention to terminate 737 * dma may also want to issue an iodone() here to 738 * wakeup physio(). 739 */ 740 wakeup((caddr_t)&dra->dr_cmd); 741 } 742 } 743 744 unsigned 745 drminphys(bp) 746 struct buf *bp; 747 { 748 749 if (bp->b_bcount > 65536) 750 bp->b_bcount = 65536; 751 } 752 753 /* 754 * This routine performs the device unique operations on the DR11W 755 * it is passed as an argument to and invoked by physio 756 */ 757 drstrategy (bp) 758 register struct buf *bp; 759 { 760 register int s; 761 int unit = RSUNIT(bp->b_dev); 762 register struct rsdevice *rsaddr = RSADDR(unit); 763 register struct dr_aux *dra = &dr_aux[unit]; 764 register int ok; 765 #ifdef DR_DEBUG 766 register char *caddr; 767 long drva(); 768 #endif 769 770 if ((dra->dr_flags & DR_OPEN) == 0) { /* Device not open */ 771 bp->b_error = ENXIO; 772 bp->b_flags |= B_ERROR; 773 iodone (bp); 774 return; 775 } 776 while (dra->dr_flags & DR_ACTV) 777 /* Device is active; should never be in here... */ 778 sleep((caddr_t)&dra->dr_flags,DRPRI); 779 dra->dr_actf = bp; 780 #ifdef DR_DEBUG 781 drva(dra, bp->b_proc, bp->b_un.b_addr, bp->b_bcount); 782 #endif 783 dra->dr_oba = bp->b_un.b_addr; /* Save original addr, count */ 784 dra->dr_obc = bp->b_bcount; 785 dra->dr_bycnt = bp->b_bcount; /* Save xfer count used by drintr() */ 786 if ((((long)bp->b_un.b_addr & 0x3fffffff) >> PGSHIFT) != 787 ((((long)bp->b_un.b_addr & 0x3fffffff) + bp->b_bcount) >> PGSHIFT)) 788 bp->b_bcount = NBPG - (((long)bp->b_un.b_addr) & PGOFSET); 789 dra->dr_flags |= DR_ACTV; /* Mark active (use in intr handler) */ 790 s = SPL_UP(); 791 drstart(rsaddr,dra,bp); 792 splx(s); 793 ok = drwait(rsaddr,dra); 794 #ifdef DR_DEBUG 795 if (DR11 & 0x40) { 796 caddr = (char *)dra->dr_oba; 797 if (dra->dr_op == DR_READ) 798 printf("\nAfter read: (%lx)(%lx)", 799 caddr[0]&0xff, caddr[1]&0xff); 800 } 801 #endif 802 dra->dr_flags &= ~DR_ACTV; /* Clear active flag */ 803 bp->b_un.b_addr = dra->dr_oba; /* Restore original addr, count */ 804 bp->b_bcount = dra->dr_obc; 805 if (!ok) 806 bp->b_flags |= B_ERROR; 807 /* Mark buffer B_DONE,so physstrat() in ml/machdep.c won't sleep */ 808 iodone(bp); 809 wakeup((caddr_t)&dra->dr_flags); 810 /* 811 * Return to the calling program (physio()). Physio() will sleep 812 * until awaken by a call to iodone() in the interupt handler -- 813 * which will be called by the dispatcher when it receives dma 814 * end-of-range interrupt. 815 */ 816 } 817 818 drwait(rs, dr) 819 register struct rsdevice *rs; 820 register struct dr_aux *dr; 821 { 822 int s; 823 824 s = SPL_UP(); 825 while (dr->dr_flags & DR_ACTV) 826 sleep((caddr_t)dr, DRPRI); 827 splx(s); 828 if (dr->dr_flags & DR_TMDM) { /* DMA timed out */ 829 dr->dr_flags &= ~DR_TMDM; 830 return (0); 831 } 832 if (rs->dr_cstat & (PERR|BERR|TERR)) { 833 dr->dr_actf->b_flags |= B_ERROR; 834 return (0); 835 } 836 dr->dr_flags &= ~DR_DMAX; 837 return (1); 838 } 839 840 /* 841 * 842 * The lower 8-bit of tinfo is the minor device number, the 843 * remaining higher 8-bit is the current timout number 844 */ 845 drrwtimo(tinfo) 846 register u_long tinfo; 847 { 848 register long unit = tinfo & 0xff; 849 register struct dr_aux *dr = &dr_aux[unit]; 850 register struct rsdevice *rs = dr->dr_addr; 851 852 /* 853 * If this is not the timeout that drwrite/drread is waiting 854 * for then we should just go away 855 */ 856 if ((tinfo &~ 0xff) != (dr->currenttimo << 8)) 857 return; 858 /* Mark the device timed out */ 859 dr->dr_flags |= DR_TMDM; 860 dr->dr_flags &= ~DR_ACTV; 861 rs->dr_pulse = RMSK; /* Inihibit interrupt */ 862 rs->dr_pulse = (RPER|RDMA|RATN|IENB); /* Clear DMA logic */ 863 /* 864 * Some applications will not issue a master after dma timeout, 865 * since doing so sends an INIT H pulse to the external device, 866 * which may produce undesirable side-effects. 867 */ 868 /* Wake up process waiting in drwait() and flag the error */ 869 dr->dr_actf->b_flags |= B_ERROR; 870 wakeup((caddr_t)dr->dr_cmd); 871 } 872 873 /* 874 * Kick the driver every second 875 */ 876 drtimo(dev) 877 dev_t dev; 878 { 879 register int unit = RSUNIT(dev); 880 register struct dr_aux *dr; 881 882 dr = &dr_aux[unit]; 883 if (dr->dr_flags & DR_OPEN) 884 timeout(drtimo, (caddr_t)dev, hz); 885 wakeup((caddr_t)dr); /* Wakeup any process waiting for interrupt */ 886 } 887 888 #ifdef DR_DEBUG 889 drva(dra, p, va, bcnt) 890 struct dr_aux *dra; 891 struct proc *p; 892 char *va; 893 long bcnt; 894 { 895 register long first, last , np; 896 897 if (DR11 & 0x20) { 898 first = ((long)(vtoph(p, (unsigned)va))) >> 10; 899 last = ((long)(vtoph(p, (unsigned)va+bcnt))) >> 10; 900 np = bcnt / 0x3ff; 901 printf("\ndrva: (op:%ld)(first:%ld)(last:%ld)(np:%ld)(cnt:%ld)", 902 dra->dr_op,first,last,np,bcnt); 903 } 904 } 905 #endif 906 907 drstart(rsaddr, dra, bp) 908 register struct rsdevice *rsaddr; 909 register struct dr_aux *dra; 910 register struct buf *bp; 911 { 912 register long addr; 913 u_short go; 914 915 #ifdef DR_DEBUG 916 if (dra->dr_op == DR_READ && (DR11 & 8)) { 917 char *caddr = (char *)bp->b_un.b_addr; 918 printf("\ndrstart: READ, bcnt:%ld",bp->b_bcount); 919 printf(",(%lx)(%lx)",caddr[0]&0xff,caddr[1]&0xff); 920 } 921 #endif 922 /* we are doing raw IO, bp->b_un.b_addr is user's address */ 923 addr = (long)vtoph(bp->b_proc, (unsigned)bp->b_un.b_addr); 924 /* 925 * Set DMA address into DR11 interace registers: DR11 requires that 926 * the address be right shifted 1 bit position before it is written 927 * to the board (The board will left shift it one bit position before 928 * it places the address on the bus 929 */ 930 rsaddr->dr_walo = (addr >> 1) & 0xffff; 931 rsaddr->dr_wahi = (addr >> 17) & 0x7fff; 932 /* Set DMA range count: (number of words - 1) */ 933 rsaddr->dr_range = (bp->b_bcount >> 1) - 1; 934 /* Set address modifier code to be used for DMA access to memory */ 935 rsaddr->dr_addmod = DRADDMOD; 936 /* 937 * Now determine whether this is a read or a write. ***** This is 938 * probably only usefull for link mode operation, since dr11 doesnot 939 * controll the direction of data transfer. The C1 control input 940 * controls whether the hardware is doing a read or a write. In link 941 * mode this is controlled by function 1 latch (looped back by the 942 * cable) and could be set the program. In the general case, the dr11 943 * doesnot know in advance what the direction of transfer is - although 944 * the program and protocol logic probably is 945 */ 946 #ifdef DR_DEBUG 947 if (DR11 & 1) 948 printf( 949 "\ndrstrat: about to GO..,dr_cmd:%lx,drstat:%lx,drcnt:%ld,cdata:%lx,OP:%ld", 950 dra->dr_cmd, rsaddr->dr_cstat, rsaddr->dr_range, 951 rsaddr->dr_data, dra->dr_op); 952 #endif 953 /* 954 * Update function latches may have been done already by drioctl() if 955 * request from drioctl() 956 */ 957 if (dra->dr_cmd & DR_DFCN) { /* deferred function write */ 958 dra->dr_cmd &= ~DR_DFCN; /* Clear request */ 959 go = dra->dr_cmd & DR_FMSK; /* mask out fcn bits */ 960 rsaddr->dr_cstat = go; /* Write it to the board */ 961 } 962 /* Clear dmaf and attf to assure a clean dma start */ 963 rsaddr->dr_pulse = RATN|RDMA|RPER; 964 rsaddr->dr_cstat = IENB|GO|CYCL|dra->dr_op; /* GO...... */ 965 /* 966 * Now check for software cycle request -- usually 967 * by transmitter in link mode. 968 */ 969 if (dra->dr_cmd & DR_PCYL) { 970 dra->dr_cmd &= ~DR_PCYL; /* Clear request */ 971 rsaddr->dr_pulse = CYCL; /* Use pulse register again */ 972 } 973 /* 974 * Now check for deferred ACLO FCNT2 pulse request -- usually to tell 975 * the transmitter (via its attention) that we have enabled dma. 976 */ 977 if (dra->dr_cmd & DR_DACL) { 978 dra->dr_cmd &= ~DR_DACL; /* Clear request */ 979 rsaddr->dr_pulse = FCN2; /* Use pulse register again */ 980 } 981 } 982 #endif NDR 983