|
|
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.