1: /* 2: * uprobe2.c: continuation of uprobes 3: * (separated into two files because the include files overflow cpp otherwise). 4: * 5: * User-level probe routines to make devices interrupt. 6: * One per device; entered through uprobe table. 7: * Return values: 8: * ACP_NXDEV device doesn't exist 9: * ACP_IFINTR OK if device has interrupted by now 10: * ACP_EXISTS OK, not checking interrupt 11: * 12: * NOTES: 13: * Reads and writes to kmem (done by grab, stuff) 14: * are currently done a byte at a time in the kernel. 15: * Beware! 16: */ 17: 18: #include "uprobe.h" 19: #include <sys/param.h> 20: #include <sys/autoconfig.h> 21: #include <sgtty.h> 22: 23: #include <sys/dhreg.h> 24: #include <sys/dnreg.h> 25: #undef BITS7 26: #undef BITS8 27: #undef TWOSB 28: #undef PENABLE 29: #undef OPAR 30: #include <sys/dzreg.h> 31: #include <sys/klreg.h> 32: 33: #include <sys/lpreg.h> 34: #include <sys/vpreg.h> 35: 36: extern int errno; 37: 38: klprobe(addr) 39: struct dldevice *addr; 40: { 41: int i; 42: 43: stuff(grab(&(addr->dlxcsr)) | DLXCSR_TIE, &(addr->dlxcsr)); 44: for (i = 0; i < 7; i++) 45: DELAY(10000); 46: /* 47: * Leave TIE enabled; kl.c never turns it off 48: * (and this could be the console). 49: */ 50: return(ACP_IFINTR); 51: } 52: 53: 54: dzprobe(addr) 55: struct dzdevice *addr; 56: { 57: register int i; 58: 59: stuff(grab(&(addr->dzcsr)) | DZ_TIE | DZ_MSE, &(addr->dzcsr)); 60: stuff(1, &(addr->dztcr)); 61: for (i = 0; i < 7; i++) 62: DELAY(10000); 63: stuff(DZ_CLR, &(addr->dzcsr)); 64: return(ACP_IFINTR); 65: } 66: 67: 68: dhprobe(addr) 69: struct dhdevice *addr; 70: { 71: register int i; 72: 73: stuff(DH_TIE, &(addr->dhcsr)); 74: DELAY(5); 75: stuff((B9600 << 10) | (B9600 << 6) | BITS7|PENABLE, &(addr->dhlpr)); 76: stuff(-1, &(addr->dhbcr)); 77: stuff(0, &(addr->dhcar)); 78: stuff(1, &(addr->dhbar)); 79: for (i = 0; i < 7; i++) 80: DELAY(10000); 81: stuff(0, &(addr->dhcsr)); 82: return(ACP_IFINTR); 83: } 84: 85: dmprobe(addr) 86: struct dmdevice *addr; 87: { 88: stuff(grab(&(addr->dmcsr)) | DM_DONE | DM_IE, &(addr->dmcsr)); 89: DELAY(20); 90: stuff(0, &(addr->dmcsr)); 91: return(ACP_IFINTR); 92: } 93: 94: /* 95: * Try to make the first unit of a DN-11 interrupt. 96: */ 97: dnprobe(addr) 98: struct dndevice *addr; 99: { 100: stuff(DN_MINAB | DN_INTENB | DN_DONE, (&(addr->dnisr[0]))); 101: DELAY(5); 102: stuff(0, (&(addr->dnisr[0]))); 103: return(ACP_IFINTR); 104: } 105: 106: lpprobe(addr) 107: struct lpdevice *addr; 108: { 109: stuff(grab(&(addr->lpcs)) | LP_IE, &(addr->lpcs)); 110: DELAY(10); 111: stuff(0, &(addr->lpcs)); 112: return(ACP_IFINTR); 113: } 114: 115: vpprobe(addr) 116: struct vpdevice *addr; 117: { 118: #ifdef VAX 119: /* 120: * This is the way the 4.1 driver does it. 121: */ 122: errno = 0; 123: stuff(VP_IENABLE | VP_DTCINTR, (&(addr->prcsr))); 124: stuff(0, (&(addr->pbaddr))); 125: stuff(3, (&(addr->pbxaddr))); 126: stuff(01777776, (&(addr->prbcr))); 127: DELAY(10000); 128: stuff(0, (&(addr->prcsr))); 129: if (errno) 130: return(ACP_NXDEV); /* Possibly an LP csr, but no print DMA regs */ 131: else 132: return(ACP_IFINTR); 133: #else 134: errno = 0; 135: /* 136: * Use the plot csr now, to distinguish from a line printer. 137: */ 138: stuff(VP_IENABLE | VP_CLRCOM, (&(addr->plcsr))); 139: DELAY(10000); 140: /* 141: * Make sure that the DMA registers are there. 142: */ 143: grab(&(addr->plbcr)); 144: /* 145: * Write the print csr this time, to leave it in print mode. 146: */ 147: stuff(0, (&(addr->prcsr))); 148: if (errno) 149: return(ACP_NXDEV); /* Possibly an LP csr, but no plot regs */ 150: else 151: return(ACP_IFINTR); 152: #endif 153: } 154: 155: #ifdef VIRUS 156: /* 157: * Can't make the cary interrupt unless it's in fixed-wavelength mode. 158: */ 159: /*ARGSUSED*/ 160: caryprobe(addr) 161: { 162: return(ACP_EXISTS); 163: } 164: #endif