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