|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1992 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: ! 27: #ifndef STUB ! 28: #include <atm.h> ! 29: #else ! 30: #include "atm.h" ! 31: #endif ! 32: ! 33: #if NATM > 0 ! 34: ! 35: #ifndef STUB ! 36: #include <sys/types.h> ! 37: #include <kern/thread.h> ! 38: #include <kern/lock.h> ! 39: #include <kern/eventcount.h> ! 40: #include <machine/machspl.h> /* spl definitions */ ! 41: #include <mips/mips_cpu.h> ! 42: #include <vm/vm_kern.h> ! 43: #include <device/io_req.h> ! 44: #include <device/device_types.h> ! 45: #include <device/net_status.h> ! 46: #include <chips/busses.h> ! 47: #include <chips/nc.h> ! 48: #include <chips/tca100.h> ! 49: #include <chips/tca100_if.h> ! 50: ! 51: decl_simple_lock_data(, atm_simple_lock); ! 52: ! 53: #else ! 54: #include "stub.h" ! 55: #include "nc.h" ! 56: #include "tca100_if.h" ! 57: #include "tca100.h" ! 58: ! 59: int atm_simple_lock; ! 60: ! 61: #endif ! 62: ! 63: struct bus_device *atm_info[NATM]; ! 64: ! 65: int atm_probe(); ! 66: void atm_attach(); ! 67: struct bus_driver atm_driver = ! 68: { atm_probe, 0, atm_attach, 0, /* csr */ 0, "atm", atm_info, ! 69: "", 0, /* flags */ 0 }; ! 70: ! 71: atm_device_t atmp[NATM] = {NULL}; ! 72: u_int atm_open_count[NATM]; ! 73: u_int atm_mapped[NATM]; ! 74: u_int atm_control_mask[NATM]; ! 75: struct evc atm_event_counter[NATM]; ! 76: ! 77: #define DEVICE(unit) ((unit == 0) ? NW_TCA100_1 : NW_TCA100_2) ! 78: ! 79: void atm_initialize(int unit) { ! 80: ! 81: atmp[unit]->creg = (CR_RX_RESET | CR_TX_RESET); ! 82: atmp[unit]->creg = 0; ! 83: atmp[unit]->rxtimerv = 0; ! 84: atmp[unit]->rxthresh = 1; ! 85: atmp[unit]->txthresh = 0; ! 86: atmp[unit]->sreg = 0; ! 87: atmp[unit]->creg = atm_control_mask[unit] = (CR_RX_ENABLE | CR_TX_ENABLE); ! 88: atm_open_count[unit] = 0; ! 89: atm_mapped[unit] = 0; ! 90: } ! 91: ! 92: /*** Device entry points ***/ ! 93: ! 94: int atm_probe(vm_offset_t reg, struct bus_device *ui) { ! 95: int un; ! 96: ! 97: un = ui->unit; ! 98: if (un >= NATM || check_memory(reg, 0)) { ! 99: return 0; ! 100: } ! 101: ! 102: atm_info[un] = ui; ! 103: atmp[un] = (atm_device_t) reg; ! 104: nc_initialize(); ! 105: if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, (char *) reg, ! 106: &tca100_entry_table) == NW_SUCCESS && ! 107: tca100_initialize(DEVICE(un)) == NW_SUCCESS) { ! 108: atm_initialize(un); ! 109: evc_init(&atm_event_counter[un]); ! 110: return 1; ! 111: } else { ! 112: atmp[un] = NULL; ! 113: (void) nc_device_unregister(DEVICE(un), NW_FAILURE); ! 114: return 0; ! 115: } ! 116: } ! 117: ! 118: void atm_attach(struct bus_device *ui) { ! 119: int un; ! 120: ! 121: un = ui->unit; ! 122: if (un >= NATM) { ! 123: printf("atm: stray attach\n"); ! 124: } else { ! 125: atmp[un]->creg = ! 126: atm_control_mask[un] = CR_TX_ENABLE | CR_RX_ENABLE | RX_COUNT_INTR; ! 127: /*Enable ATM interrupts*/ ! 128: } ! 129: } ! 130: ! 131: void atm_intr(int unit, int spl_level) { ! 132: ! 133: if (unit >= NATM || atmp[unit] == NULL) { ! 134: printf("atm: stray interrupt\n"); ! 135: } else { ! 136: atmp[unit]->creg = CR_TX_ENABLE | CR_RX_ENABLE; /*Disable ATM interrupts*/ ! 137: wbflush(); ! 138: if (atm_mapped[unit]) { ! 139: splx(spl_level); ! 140: evc_signal(&atm_event_counter[unit]); ! 141: } else { ! 142: simple_lock(&atm_simple_lock); ! 143: tca100_poll(DEVICE(unit)); ! 144: atmp[unit]->creg = atm_control_mask[unit]; ! 145: simple_unlock(&atm_simple_lock); ! 146: splx(spl_level); ! 147: } ! 148: } ! 149: } ! 150: ! 151: io_return_t atm_open(dev_t dev, int mode, io_req_t ior) { ! 152: int un; ! 153: ! 154: un = minor(dev); ! 155: if (un >= NATM || atmp[un] == NULL) { ! 156: return D_NO_SUCH_DEVICE; ! 157: /* ! 158: } else if (atm_open_count[un] > 0 && (atm_mapped[un] || (mode & D_WRITE))) { ! 159: return D_ALREADY_OPEN; ! 160: */ ! 161: } else { ! 162: atm_open_count[un]++; ! 163: atm_mapped[un] = ((mode & D_WRITE) != 0); ! 164: if (atm_mapped[un]) ! 165: (void) nc_device_unregister(DEVICE(un), NW_NOT_SERVER); ! 166: return D_SUCCESS; ! 167: } ! 168: } ! 169: ! 170: io_return_t atm_close(dev_t dev) { ! 171: int un; ! 172: ! 173: un = minor(dev); ! 174: if (un >= NATM || atmp[un] == NULL) { ! 175: return D_NO_SUCH_DEVICE; ! 176: } else if (atm_open_count[un] == 0) { ! 177: return D_INVALID_OPERATION; ! 178: } else { ! 179: if (atm_mapped[un]) { ! 180: (void) nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, ! 181: (char *) atmp[un], ! 182: &tca100_entry_table); ! 183: atm_mapped[un] = 0; ! 184: } ! 185: atm_open_count[un]--; ! 186: return D_SUCCESS; ! 187: } ! 188: } ! 189: ! 190: unsigned int *frc = 0xbe801000; ! 191: char data[66000]; ! 192: ! 193: io_return_t atm_read(dev_t dev, io_req_t ior) { ! 194: unsigned int ck1, ck2; ! 195: int i, j; ! 196: char c[16]; ! 197: ! 198: ck1 = *frc; ! 199: device_read_alloc(ior, ior->io_count); ! 200: for (i = 0, j = 0; i < ior->io_count; i += 4096, j++) ! 201: c[j] = (ior->io_data)[i]; ! 202: ck2 = *frc; ! 203: ((int *) ior->io_data)[0] = ck1; ! 204: ((int *) ior->io_data)[1] = ck2; ! 205: return D_SUCCESS; ! 206: } ! 207: ! 208: io_return_t atm_write(dev_t dev, io_req_t ior) { ! 209: int i, j; ! 210: char c[16]; ! 211: boolean_t wait; ! 212: ! 213: device_write_get(ior, &wait); ! 214: for (i = 0, j = 0; i < ior->io_total; i += 4096, j++) ! 215: c[j] = (ior->io_data)[i]; ! 216: ior->io_residual = ior->io_total - *frc; ! 217: return D_SUCCESS; ! 218: } ! 219: ! 220: io_return_t atm_get_status(dev_t dev, int flavor, dev_status_t status, ! 221: u_int *status_count) { ! 222: int un; ! 223: ! 224: un = minor(dev); ! 225: if (un >= NATM || atmp[un] == NULL) { ! 226: return D_NO_SUCH_DEVICE; ! 227: } else { ! 228: switch ((atm_status) flavor) { ! 229: case ATM_MAP_SIZE: ! 230: status[0] = sizeof(atm_device_s); ! 231: *status_count = sizeof(int); ! 232: return D_SUCCESS; ! 233: case ATM_MTU_SIZE: ! 234: status[0] = 65535; /*MTU size*/ ! 235: *status_count = sizeof(int); ! 236: return D_SUCCESS; ! 237: case ATM_EVC_ID: ! 238: status[0] = atm_event_counter[un].ev_id; ! 239: *status_count = sizeof(int); ! 240: return D_SUCCESS; ! 241: case ATM_ASSIGNMENT: ! 242: status[0] = atm_mapped[un]; ! 243: status[1] = atm_open_count[un]; ! 244: *status_count = 2 * sizeof(int); ! 245: return D_SUCCESS; ! 246: default: ! 247: return D_INVALID_OPERATION; ! 248: } ! 249: } ! 250: } ! 251: ! 252: io_return_t atm_set_status(dev_t dev, int flavor, dev_status_t status, ! 253: u_int status_count) { ! 254: io_return_t rc; ! 255: int un, s; ! 256: nw_pvc_t pvcp; ! 257: nw_plist_t pel; ! 258: nw_ep lep; ! 259: ! 260: un = minor(dev); ! 261: if (un >= NATM || atmp[un] == NULL) { ! 262: return D_NO_SUCH_DEVICE; ! 263: } else switch ((atm_status) flavor) { ! 264: case ATM_INITIALIZE: ! 265: if (status_count != 0) { ! 266: return D_INVALID_OPERATION; ! 267: } else { ! 268: s = splsched(); ! 269: if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, ! 270: (char *) atmp[un], ! 271: &tca100_entry_table) == NW_SUCCESS && ! 272: tca100_initialize(DEVICE(un)) == NW_SUCCESS) { ! 273: atm_initialize(un); ! 274: rc = D_SUCCESS; ! 275: } else { ! 276: atmp[un] = NULL; ! 277: (void) nc_device_unregister(DEVICE(un), NW_FAILURE); ! 278: rc = D_INVALID_OPERATION; ! 279: } ! 280: splx(s); ! 281: return rc; ! 282: } ! 283: break; ! 284: ! 285: #if PERMANENT_VIRTUAL_CONNECTIONS ! 286: case ATM_PVC_SET: ! 287: pvcp = (nw_pvc_t) status; ! 288: if (status_count != sizeof(nw_pvc_s) || pvcp->pvc.local_ep >= MAX_EP) { ! 289: rc = D_INVALID_OPERATION; ! 290: } else if ((pel = nc_peer_allocate()) == NULL) { ! 291: rc = D_INVALID_OPERATION; ! 292: } else { ! 293: lep = pvcp->pvc.local_ep; ! 294: tct[lep].rx_sar_header = SSM | 1; ! 295: tct[lep].tx_atm_header = pvcp->tx_vp << ATM_VPVC_SHIFT; ! 296: tct[lep].tx_sar_header = 1; ! 297: ect[lep].state = NW_DUPLEX_ACCEPTED; ! 298: pel->peer = pvcp->pvc; ! 299: pel->next = NULL; ! 300: ect[lep].conn = pel; ! 301: if (pvcp->protocol == NW_LINE) { ! 302: if (nc_line_update(&pel->peer, lep) == NW_SUCCESS) { ! 303: ect[lep].protocol = pvcp->protocol; ! 304: if (nw_free_line_last == 0) ! 305: nw_free_line_first = lep; ! 306: else ! 307: ect[nw_free_line_last].next = lep; ! 308: ect[lep].previous = nw_free_line_last; ! 309: ect[lep].next = 0; ! 310: nw_free_line_last = lep; ! 311: rc = D_SUCCESS; ! 312: } else { ! 313: rc = D_INVALID_OPERATION; ! 314: } ! 315: } else { ! 316: rc = D_SUCCESS; ! 317: } ! 318: } ! 319: return rc; ! 320: #endif ! 321: ! 322: default: ! 323: return D_INVALID_OPERATION; ! 324: } ! 325: } ! 326: ! 327: int atm_mmap(dev_t dev, vm_offset_t off, int prot) { ! 328: int un; ! 329: vm_offset_t addr; ! 330: ! 331: un = minor(dev); ! 332: if (un >= NATM || atmp[un] == NULL || !atm_mapped[un] || ! 333: off >= sizeof(atm_device_s)) { ! 334: return -1; ! 335: } else { ! 336: return mips_btop(K1SEG_TO_PHYS( (vm_offset_t) atmp[un] ) + off ); ! 337: } ! 338: } ! 339: ! 340: io_return_t atm_restart(int u) { ! 341: ! 342: return D_INVALID_OPERATION; ! 343: } ! 344: ! 345: io_return_t atm_setinput(dev_t dev, ipc_port_t receive_port, int priority, ! 346: filter_array_t *filter, u_int filter_count) { ! 347: ! 348: return D_INVALID_OPERATION; ! 349: } ! 350: ! 351: int atm_portdeath(dev_t dev, mach_port_t port) { ! 352: ! 353: return D_INVALID_OPERATION; ! 354: } ! 355: ! 356: ! 357: #endif NATM > 0 ! 358: ! 359: ! 360:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.