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