From f07a4c844da9f0ecae5bbee1ab94be56505f26f7 Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Tue, 25 Feb 1997 21:28:37 +0000 Subject: Initial source --- chips/tca100.c | 360 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 360 insertions(+) create mode 100644 chips/tca100.c (limited to 'chips/tca100.c') diff --git a/chips/tca100.c b/chips/tca100.c new file mode 100644 index 0000000..7ad4fec --- /dev/null +++ b/chips/tca100.c @@ -0,0 +1,360 @@ +/* + * Mach Operating System + * Copyright (c) 1992 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef STUB +#include +#else +#include "atm.h" +#endif + +#if NATM > 0 + +#ifndef STUB +#include +#include +#include +#include +#include /* spl definitions */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +decl_simple_lock_data(, atm_simple_lock); + +#else +#include "stub.h" +#include "nc.h" +#include "tca100_if.h" +#include "tca100.h" + +int atm_simple_lock; + +#endif + +struct bus_device *atm_info[NATM]; + +int atm_probe(); +void atm_attach(); +struct bus_driver atm_driver = + { atm_probe, 0, atm_attach, 0, /* csr */ 0, "atm", atm_info, + "", 0, /* flags */ 0 }; + +atm_device_t atmp[NATM] = {NULL}; +u_int atm_open_count[NATM]; +u_int atm_mapped[NATM]; +u_int atm_control_mask[NATM]; +struct evc atm_event_counter[NATM]; + +#define DEVICE(unit) ((unit == 0) ? NW_TCA100_1 : NW_TCA100_2) + +void atm_initialize(int unit) { + + atmp[unit]->creg = (CR_RX_RESET | CR_TX_RESET); + atmp[unit]->creg = 0; + atmp[unit]->rxtimerv = 0; + atmp[unit]->rxthresh = 1; + atmp[unit]->txthresh = 0; + atmp[unit]->sreg = 0; + atmp[unit]->creg = atm_control_mask[unit] = (CR_RX_ENABLE | CR_TX_ENABLE); + atm_open_count[unit] = 0; + atm_mapped[unit] = 0; +} + +/*** Device entry points ***/ + +int atm_probe(vm_offset_t reg, struct bus_device *ui) { + int un; + + un = ui->unit; + if (un >= NATM || check_memory(reg, 0)) { + return 0; + } + + atm_info[un] = ui; + atmp[un] = (atm_device_t) reg; + nc_initialize(); + if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, (char *) reg, + &tca100_entry_table) == NW_SUCCESS && + tca100_initialize(DEVICE(un)) == NW_SUCCESS) { + atm_initialize(un); + evc_init(&atm_event_counter[un]); + return 1; + } else { + atmp[un] = NULL; + (void) nc_device_unregister(DEVICE(un), NW_FAILURE); + return 0; + } +} + +void atm_attach(struct bus_device *ui) { + int un; + + un = ui->unit; + if (un >= NATM) { + printf("atm: stray attach\n"); + } else { + atmp[un]->creg = + atm_control_mask[un] = CR_TX_ENABLE | CR_RX_ENABLE | RX_COUNT_INTR; + /*Enable ATM interrupts*/ + } +} + +void atm_intr(int unit, int spl_level) { + + if (unit >= NATM || atmp[unit] == NULL) { + printf("atm: stray interrupt\n"); + } else { + atmp[unit]->creg = CR_TX_ENABLE | CR_RX_ENABLE; /*Disable ATM interrupts*/ + wbflush(); + if (atm_mapped[unit]) { + splx(spl_level); + evc_signal(&atm_event_counter[unit]); + } else { + simple_lock(&atm_simple_lock); + tca100_poll(DEVICE(unit)); + atmp[unit]->creg = atm_control_mask[unit]; + simple_unlock(&atm_simple_lock); + splx(spl_level); + } + } +} + +io_return_t atm_open(dev_t dev, int mode, io_req_t ior) { + int un; + + un = minor(dev); + if (un >= NATM || atmp[un] == NULL) { + return D_NO_SUCH_DEVICE; +/* + } else if (atm_open_count[un] > 0 && (atm_mapped[un] || (mode & D_WRITE))) { + return D_ALREADY_OPEN; +*/ + } else { + atm_open_count[un]++; + atm_mapped[un] = ((mode & D_WRITE) != 0); + if (atm_mapped[un]) + (void) nc_device_unregister(DEVICE(un), NW_NOT_SERVER); + return D_SUCCESS; + } +} + +io_return_t atm_close(dev_t dev) { + int un; + + un = minor(dev); + if (un >= NATM || atmp[un] == NULL) { + return D_NO_SUCH_DEVICE; + } else if (atm_open_count[un] == 0) { + return D_INVALID_OPERATION; + } else { + if (atm_mapped[un]) { + (void) nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, + (char *) atmp[un], + &tca100_entry_table); + atm_mapped[un] = 0; + } + atm_open_count[un]--; + return D_SUCCESS; + } +} + +unsigned int *frc = 0xbe801000; +char data[66000]; + +io_return_t atm_read(dev_t dev, io_req_t ior) { + unsigned int ck1, ck2; + int i, j; + char c[16]; + + ck1 = *frc; + device_read_alloc(ior, ior->io_count); + for (i = 0, j = 0; i < ior->io_count; i += 4096, j++) + c[j] = (ior->io_data)[i]; + ck2 = *frc; + ((int *) ior->io_data)[0] = ck1; + ((int *) ior->io_data)[1] = ck2; + return D_SUCCESS; +} + +io_return_t atm_write(dev_t dev, io_req_t ior) { + int i, j; + char c[16]; + boolean_t wait; + + device_write_get(ior, &wait); + for (i = 0, j = 0; i < ior->io_total; i += 4096, j++) + c[j] = (ior->io_data)[i]; + ior->io_residual = ior->io_total - *frc; + return D_SUCCESS; +} + +io_return_t atm_get_status(dev_t dev, int flavor, dev_status_t status, + u_int *status_count) { + int un; + + un = minor(dev); + if (un >= NATM || atmp[un] == NULL) { + return D_NO_SUCH_DEVICE; + } else { + switch ((atm_status) flavor) { + case ATM_MAP_SIZE: + status[0] = sizeof(atm_device_s); + *status_count = sizeof(int); + return D_SUCCESS; + case ATM_MTU_SIZE: + status[0] = 65535; /*MTU size*/ + *status_count = sizeof(int); + return D_SUCCESS; + case ATM_EVC_ID: + status[0] = atm_event_counter[un].ev_id; + *status_count = sizeof(int); + return D_SUCCESS; + case ATM_ASSIGNMENT: + status[0] = atm_mapped[un]; + status[1] = atm_open_count[un]; + *status_count = 2 * sizeof(int); + return D_SUCCESS; + default: + return D_INVALID_OPERATION; + } + } +} + +io_return_t atm_set_status(dev_t dev, int flavor, dev_status_t status, + u_int status_count) { + io_return_t rc; + int un, s; + nw_pvc_t pvcp; + nw_plist_t pel; + nw_ep lep; + + un = minor(dev); + if (un >= NATM || atmp[un] == NULL) { + return D_NO_SUCH_DEVICE; + } else switch ((atm_status) flavor) { + case ATM_INITIALIZE: + if (status_count != 0) { + return D_INVALID_OPERATION; + } else { + s = splsched(); + if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, + (char *) atmp[un], + &tca100_entry_table) == NW_SUCCESS && + tca100_initialize(DEVICE(un)) == NW_SUCCESS) { + atm_initialize(un); + rc = D_SUCCESS; + } else { + atmp[un] = NULL; + (void) nc_device_unregister(DEVICE(un), NW_FAILURE); + rc = D_INVALID_OPERATION; + } + splx(s); + return rc; + } + break; + +#if PERMANENT_VIRTUAL_CONNECTIONS + case ATM_PVC_SET: + pvcp = (nw_pvc_t) status; + if (status_count != sizeof(nw_pvc_s) || pvcp->pvc.local_ep >= MAX_EP) { + rc = D_INVALID_OPERATION; + } else if ((pel = nc_peer_allocate()) == NULL) { + rc = D_INVALID_OPERATION; + } else { + lep = pvcp->pvc.local_ep; + tct[lep].rx_sar_header = SSM | 1; + tct[lep].tx_atm_header = pvcp->tx_vp << ATM_VPVC_SHIFT; + tct[lep].tx_sar_header = 1; + ect[lep].state = NW_DUPLEX_ACCEPTED; + pel->peer = pvcp->pvc; + pel->next = NULL; + ect[lep].conn = pel; + if (pvcp->protocol == NW_LINE) { + if (nc_line_update(&pel->peer, lep) == NW_SUCCESS) { + ect[lep].protocol = pvcp->protocol; + if (nw_free_line_last == 0) + nw_free_line_first = lep; + else + ect[nw_free_line_last].next = lep; + ect[lep].previous = nw_free_line_last; + ect[lep].next = 0; + nw_free_line_last = lep; + rc = D_SUCCESS; + } else { + rc = D_INVALID_OPERATION; + } + } else { + rc = D_SUCCESS; + } + } + return rc; +#endif + + default: + return D_INVALID_OPERATION; + } +} + +int atm_mmap(dev_t dev, vm_offset_t off, int prot) { + int un; + vm_offset_t addr; + + un = minor(dev); + if (un >= NATM || atmp[un] == NULL || !atm_mapped[un] || + off >= sizeof(atm_device_s)) { + return -1; + } else { + return mips_btop(K1SEG_TO_PHYS( (vm_offset_t) atmp[un] ) + off ); + } +} + +io_return_t atm_restart(int u) { + + return D_INVALID_OPERATION; +} + +io_return_t atm_setinput(dev_t dev, ipc_port_t receive_port, int priority, + filter_array_t *filter, u_int filter_count) { + + return D_INVALID_OPERATION; +} + +int atm_portdeath(dev_t dev, mach_port_t port) { + + return D_INVALID_OPERATION; +} + + +#endif NATM > 0 + + + -- cgit v1.2.3