|
|
1.1 ! root 1: /* ! 2: * File: albaud.c ! 3: * ! 4: * Purpose: common code for various async drivers ! 5: * ! 6: * $Log: albaud.c,v $ ! 7: * Revision 1.2 93/04/14 10:24:08 root ! 8: * r75 ! 9: * ! 10: * Revision 1.1 92/04/30 08:58:54 hal ! 11: * Add asy. Remove silos from tty struct. ! 12: * ! 13: */ ! 14: ! 15: /* ! 16: * ---------------------------------------------------------------------- ! 17: * Includes. ! 18: */ ! 19: #include <sys/coherent.h> ! 20: #include <sys/ins8250.h> ! 21: ! 22: /* ! 23: * ---------------------------------------------------------------------- ! 24: * Definitions. ! 25: * Constants. ! 26: * Macros with argument lists. ! 27: * Typedefs. ! 28: * Enums. ! 29: */ ! 30: #define TESTBAUD 0x03A5 ! 31: ! 32: /* ! 33: * ---------------------------------------------------------------------- ! 34: * Functions. ! 35: * Import Functions. ! 36: * Export Functions. ! 37: * Local Functions. ! 38: */ ! 39: int uart_sense(); ! 40: ! 41: /* ! 42: * ---------------------------------------------------------------------- ! 43: * Global Data. ! 44: * Import Variables. ! 45: * Export Variables. ! 46: * Local Variables. ! 47: */ ! 48: ! 49: int albaud[] ={ ! 50: 0, /* 0 */ ! 51: 2304, /* 50 */ ! 52: 1536, /* 75 */ ! 53: 1047, /* 110 */ ! 54: 857, /* 134.5 */ ! 55: 768, /* 150 */ ! 56: 576, /* 200 */ ! 57: 384, /* 300 */ ! 58: 192, /* 600 */ ! 59: 96, /* 1200 */ ! 60: 64, /* 1800 */ ! 61: #ifdef _I386 ! 62: 48, /* 2400 */ ! 63: 24, /* 4800 */ ! 64: 12, /* 9600 */ ! 65: 6, /* 19200 */ ! 66: 3 /* 38400 */ ! 67: #else ! 68: 58, /* 2000 */ ! 69: 48, /* 2400 */ ! 70: 32, /* 3600 */ ! 71: 24, /* 4800 */ ! 72: 16, /* 7200 */ ! 73: 12, /* 9600 */ ! 74: 6, /* 19200 */ ! 75: 0, /* EXTA */ ! 76: 0 /* EXTB */ ! 77: #endif ! 78: }; ! 79: ! 80: /* ! 81: * alp_rate[] is tied to albaud[] - it gives the minimum polling ! 82: * rate for the corresponding port speed; it must be a multiple ! 83: * of 100 (system clock Hz) and >= baud/6 ! 84: */ ! 85: int alp_rate[] ={ /* baud/6 or zero */ ! 86: 0, /* 0 */ ! 87: 1*HZ, /* 50 */ ! 88: 1*HZ, /* 75 */ ! 89: 1*HZ, /* 110 */ ! 90: 1*HZ, /* 134.5 */ ! 91: 1*HZ, /* 150 */ ! 92: 1*HZ, /* 200 */ ! 93: 1*HZ, /* 300 */ ! 94: 1*HZ, /* 600 */ ! 95: 2*HZ, /* 1200 */ ! 96: 3*HZ, /* 1800 */ ! 97: #ifdef _I386 ! 98: 4*HZ, /* 2400 */ ! 99: 8*HZ, /* 4800 */ ! 100: 16*HZ, /* 9600 */ ! 101: 32*HZ, /* 19200 */ ! 102: 64*HZ /* 38400 */ ! 103: #else ! 104: 4*HZ, /* 2000 */ ! 105: 4*HZ, /* 2400 */ ! 106: 6*HZ, /* 3600 */ ! 107: 8*HZ, /* 4800 */ ! 108: 12*HZ, /* 7200 */ ! 109: 16*HZ, /* 9600 */ ! 110: 32*HZ, /* 19200 */ ! 111: 0, /* EXTA */ ! 112: 0 /* EXTB */ ! 113: #endif ! 114: }; ! 115: ! 116: /* ! 117: * ---------------------------------------------------------------------- ! 118: * Code. ! 119: */ ! 120: ! 121: /* ! 122: * uart_sense() ! 123: * ! 124: * Given port address, return what type of 8250-family chip is found there. ! 125: * ! 126: * 0 - no chip ! 127: * 1 - 8250 or 8250B ! 128: * 2 - 8250A or 16450 ! 129: * 3 - 16550 ! 130: * 4 - 16550A ! 131: * ! 132: * Only the last of these has usable on-chip FIFO. ! 133: */ ! 134: int uart_sense(port) ! 135: int port; ! 136: { ! 137: int ret = US_NONE; ! 138: unsigned ch; ! 139: short testbaud; ! 140: char lcr, dll, dlh; ! 141: ! 142: /* ! 143: * See if UART is detected at port address. ! 144: * UART should have IER = 0000 xxxx ! 145: * MCR = 000x xxxx ! 146: * IIR = xx00 xxxx ! 147: * and should be write and read back the baud rate regs. ! 148: */ ! 149: if (inb(port+IER) & 0xF0 ! 150: || inb(port+MCR) & 0xE0 ! 151: || inb(port+IIR) & 0x30) { ! 152: goto done; ! 153: } ! 154: lcr = inb(port + LCR); ! 155: outb(port+LCR, LC_DLAB); ! 156: dll = inb(port + DLL); ! 157: dlh = inb(port + DLH); ! 158: outb(port+DLL, TESTBAUD & 0xFF); ! 159: outb(port+DLH, TESTBAUD >> 8); ! 160: testbaud = inb(port+DLL) | inb(port+DLH) << 8; ! 161: outb(port+LCR, LC_CS8); ! 162: if (testbaud != TESTBAUD){ ! 163: goto done; ! 164: } else { ! 165: outb(port+LCR, LC_DLAB); ! 166: outb(port+DLL, dll); ! 167: outb(port+DLH, dlh); ! 168: outb(port+LCR, lcr); ! 169: } ! 170: ! 171: /* ! 172: * Scratch register NOT found on 8250/8250B. ! 173: */ ! 174: outb(port+SCR, 0x55); ! 175: ch = inb(port+SCR); ! 176: if (ch != 0x55) { ! 177: ret = US_8250; ! 178: } ! 179: ! 180: /* ! 181: * After trying to turn on FIFO mode, ! 182: * If IIR is 00xx xxxx, it's 8250A/16450 (no FIFO). ! 183: * If IIR is 10xx xxxx, it's 16550 (broken FIFO). ! 184: * If IIR is 11xx xxxx, it's 16550A (usable FIFO). ! 185: */ ! 186: outb(port+FCR, 0x01); ! 187: ch = inb(port+FCR); ! 188: switch (ch & 0xC0) { ! 189: case 0x00: ! 190: if (ret == US_NONE) ! 191: ret = US_16450; ! 192: break; ! 193: case 0x80: ! 194: if (ret == US_NONE) ! 195: ret = US_16550; ! 196: break; ! 197: case 0xC0: ! 198: ret = US_16550A; ! 199: break; ! 200: } ! 201: outb(port+FCR, 0x00); ! 202: done: ! 203: ! 204: switch(port){ ! 205: case 0x3F8: ! 206: printf("com1 "); ! 207: break; ! 208: case 0x2F8: ! 209: printf("com2 "); ! 210: break; ! 211: case 0x3E8: ! 212: printf("com3 "); ! 213: break; ! 214: case 0x2E8: ! 215: printf("com4 "); ! 216: break; ! 217: } ! 218: printf("port %x: ", port); ! 219: switch (ret) { ! 220: case US_NONE: ! 221: printf("no UART "); ! 222: break; ! 223: case US_8250: ! 224: printf("8250/8250B "); ! 225: break; ! 226: case US_16450: ! 227: printf("8250A/16450 "); ! 228: break; ! 229: case US_16550: ! 230: printf("16550 - no FIFO "); ! 231: break; ! 232: case US_16550A: ! 233: printf("16550A - FIFO "); ! 234: break; ! 235: } ! 236: return ret; ! 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.