+#define NPAT 2
+#define DMATBL 20
+ushort tstpat[DMATBL] = { 0xAAAA, 0x5555};
+long DMAin = 0;
+
+dr11loop(dr,dra,unit)
+struct rsdevice *dr;
+struct dr_aux *dra;
+long unit;
+{ register long result, ix;
+ long baddr, wait;
+
+ dr->dr_cstat = MCLR; /* Clear board & device, disable intr */
+
+ /* Perform loopback test -- MUST HAVE LOOPBACK CABLE ATTACHED --
+ Test results are printed on system console */
+ printf("\n\t ----- DR11 unit %ld loopback test -----",unit);
+
+ printf("\n\t Program I/O ...");
+ for (ix=0;ix<NPAT;ix++) {
+ dr->dr_data = tstpat[ix]; /* Write to Data out register */
+ result = (dr->dr_data & 0xFFFF); /* Read it back */
+ if (result != tstpat[ix]) {
+ printf("Failed, expected : %lx --- actual : %lx",
+ tstpat[ix],result);
+ return;
+ }
+ }
+
+ printf("OK\n\t Functions & Status Bits ...");
+ dr->dr_cstat = (FCN1 | FCN3);
+ result = dr->dr_cstat & 0xffff; /* Read them back */
+ if ((result & (STTC | STTA)) != (STTC |STTA)) {
+ printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
+ (STTA|STTC),(result & (STTA|STTC)), result);
+ return;
+ }
+ dr->dr_cstat = FCN2;
+ result = dr->dr_cstat & 0xffff; /* Read them back */
+ if ((result & STTB) != STTB) {
+ printf("Failed, expected : %lx --- actual : %lx, ISR:%lx",
+ STTB,(result & STTB), result);
+ return;
+ }
+
+ printf("OK\n\t DMA output ...");
+
+ if (DMAin) goto dmain;
+
+ /* Initialize DMA data buffer */
+ for(ix=0;ix<DMATBL;ix++) tstpat[ix] = 0xCCCC + ix;
+ tstpat[DMATBL-1] = 0xCCCC; /* Last word output */
+
+ /* Setup normal DMA */
+ baddr = (long)vtoph(0,tstpat); /* Virtual --> physical */
+ dr->dr_walo = (ushort)((baddr >> 1) & 0xffff);
+ dr->dr_wahi = (ushort)((baddr >> 17) & 0x7fff);
+
+ /* Set DMA range count: (number of words - 1) */
+ dr->dr_range = (ushort)(DMATBL - 1);
+
+ /* Set address modifier code to be used for DMA access to memory */
+ dr->dr_addmod = (char)DRADDMOD;
+
+ /* Clear dmaf and attf to assure a clean dma start, also disable
+ attention interrupt
+ */
+ dr->dr_pulse = (ushort)(RDMA|RATN|RMSK); /* Use pulse register */
+ dr->dr_cstat = (GO|CYCL); /* GO...... */
+
+ /* Wait for DMA complete; REDY and DMAF are true in ISR */
+ wait = 0;
+ while ((result=(dr->dr_cstat & (REDY | DMAF))) != (REDY|DMAF)) {
+ printf("\n\tWait for DMA complete...ISR : %lx",result);
+ if (++wait > 5) {
+ printf("\n\t DMA output fails...timeout!!, ISR:%lx",
+ result);
+ return;
+ }
+ }
+
+ result = dr->dr_data & 0xffff; /* Read last word output */
+ if (result != 0xCCCC) {
+ printf("\n\t Fails, expected : %lx --- actual : %lx",
+ 0xCCCC,result);
+ return;
+ }
+
+ printf("OK\n\t DMA input ...");
+
+dmain:
+ dr->dr_data = 0x1111; /* DMA input data */
+ /* Setup normal DMA */
+ baddr = (long)vtoph(0,tstpat); /* Virtual --> physical */
+ dr->dr_walo = (ushort)((baddr >> 1) & 0xffff);
+ dr->dr_wahi = (ushort)((baddr >> 17) & 0x7fff);
+
+ /* Set DMA range count: (number of words - 1) */
+ dr->dr_range = (ushort)(DMATBL - 1);
+
+ /* Set address modifier code to be used for DMA access to memory */
+ dr->dr_addmod = (char)DRADDMOD;
+ /* Set FCN1 in ICR to DMA in*/
+ dr->dr_cstat = FCN1;
+
+ if (!(dra->dr_flags & DR_LOOPTST)) {
+ /* Use pulse reg */
+ dr->dr_pulse = (ushort)(RDMA|RATN|RMSK|CYCL|GO);
+ /* Wait for DMA complete; REDY and DMAF are true in ISR */
+ wait = 0;
+ while ((result=(dr->dr_cstat & (REDY | DMAF)))
+ != (REDY|DMAF)) {
+ printf("\n\tWait for DMA to complete...ISR:%lx",result);
+ if (++wait > 5) {
+ printf("\n\t DMA input timeout!!, ISR:%lx",
+ result);
+ return;
+ }
+ }
+ }
+ else {
+ /* Enable DMA e-o-r interrupt */
+ dr->dr_pulse = (ushort)(IENB|RDMA|RATN|CYCL|GO);
+ /* Wait for DMA complete; DR_LOOPTST is false in dra->dr_flags*/
+ wait = 0;
+ while (dra->dr_flags & DR_LOOPTST) {
+ result = dr->dr_cstat & 0xffff;
+ printf("\n\tWait for DMA e-o-r intr...ISR:%lx",result);
+ if (++wait > 7) {
+ printf("\n\t DMA e-o-r timeout!!, ISR:%lx",
+ result);
+ dra->dr_flags &= ~DR_LOOPTST;
+ return;
+ }
+ }
+ dra->dr_flags |= DR_LOOPTST;
+ }
+
+ mtpr(tstpat,P1DC); /* Purge cache */
+ mtpr((0x3ff+(long)tstpat),P1DC);
+ for(ix=0;ix<DMATBL;ix++) {
+ if (tstpat[ix] != 0x1111) {
+ printf("\n\t Fails, ix:%ld,expected : %lx --- actual : %lx",
+ ix,0x1111,tstpat[ix]);
+ return;
+ }
+ }
+ if (!(dra->dr_flags & DR_LOOPTST)) {
+ dra->dr_flags |= DR_LOOPTST;
+ printf(" OK..\n\tDMA end of range interrupt...");
+ goto dmain;
+ }
+
+
+ printf(" OK..\n\tAttention interrupt....");
+ /* Pulse FCN2 in pulse register with IENB */
+ dr->dr_pulse = (ushort)(IENB|RDMA);
+ dr->dr_pulse = (ushort)FCN2;
+
+ /* Wait for ATTN interrupt; DR_LOOPTST is false in dra->dr_flags*/
+ wait = 0;
+ while (dra->dr_flags & DR_LOOPTST) {
+ result = dr->dr_cstat & 0xffff;
+ printf("\n\tWait for Attention intr...ISR:%lx",result);
+ if (++wait > 7) {
+ printf("\n\t Attention interrupt timeout!!, ISR:%lx",
+ result);
+ dra->dr_flags &= ~DR_LOOPTST;
+ return;
+ }
+ }
+ dra->dr_flags &= ~DR_LOOPTST;
+ printf(" OK..\n\tDone...");
+}
+