FreeBSD/Linux Kernel Cross Reference
sys/chips/tca100.c
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 Software.Distribution@CS.CMU.EDU
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 /*
28 * HISTORY
29 * $Log: tca100.c,v $
30 * Revision 2.2 93/08/10 15:19:02 mrt
31 * Initial check-in.
32 * [93/06/09 16:00:50 jcb]
33 *
34 */
35
36 #ifndef STUB
37 #include <atm.h>
38 #else
39 #include "atm.h"
40 #endif
41
42 #if NATM > 0
43
44 #ifndef STUB
45 #include <sys/types.h>
46 #include <kern/thread.h>
47 #include <kern/lock.h>
48 #include <kern/eventcount.h>
49 #include <machine/machspl.h> /* spl definitions */
50 #include <mips/mips_cpu.h>
51 #include <vm/vm_kern.h>
52 #include <device/io_req.h>
53 #include <device/device_types.h>
54 #include <device/net_status.h>
55 #include <chips/busses.h>
56 #include <chips/nc.h>
57 #include <chips/tca100.h>
58 #include <chips/tca100_if.h>
59
60 decl_simple_lock_data(, atm_simple_lock);
61
62 #else
63 #include "stub.h"
64 #include "nc.h"
65 #include "tca100_if.h"
66 #include "tca100.h"
67
68 int atm_simple_lock;
69
70 #endif
71
72 struct bus_device *atm_info[NATM];
73
74 int atm_probe();
75 void atm_attach();
76 struct bus_driver atm_driver =
77 { atm_probe, 0, atm_attach, 0, /* csr */ 0, "atm", atm_info,
78 "", 0, /* flags */ 0 };
79
80 atm_device_t atmp[NATM] = {NULL};
81 u_int atm_open_count[NATM];
82 u_int atm_mapped[NATM];
83 u_int atm_control_mask[NATM];
84 struct evc atm_event_counter[NATM];
85
86 #define DEVICE(unit) ((unit == 0) ? NW_TCA100_1 : NW_TCA100_2)
87
88 void atm_initialize(int unit) {
89
90 atmp[unit]->creg = (CR_RX_RESET | CR_TX_RESET);
91 atmp[unit]->creg = 0;
92 atmp[unit]->rxtimerv = 0;
93 atmp[unit]->rxthresh = 1;
94 atmp[unit]->txthresh = 0;
95 atmp[unit]->sreg = 0;
96 atmp[unit]->creg = atm_control_mask[unit] = (CR_RX_ENABLE | CR_TX_ENABLE);
97 atm_open_count[unit] = 0;
98 atm_mapped[unit] = 0;
99 }
100
101 /*** Device entry points ***/
102
103 int atm_probe(vm_offset_t reg, struct bus_device *ui) {
104 int un;
105
106 un = ui->unit;
107 if (un >= NATM || check_memory(reg, 0)) {
108 return 0;
109 }
110
111 atm_info[un] = ui;
112 atmp[un] = (atm_device_t) reg;
113 nc_initialize();
114 if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED, (char *) reg,
115 &tca100_entry_table) == NW_SUCCESS &&
116 tca100_initialize(DEVICE(un)) == NW_SUCCESS) {
117 atm_initialize(un);
118 evc_init(&atm_event_counter[un]);
119 return 1;
120 } else {
121 atmp[un] = NULL;
122 (void) nc_device_unregister(DEVICE(un), NW_FAILURE);
123 return 0;
124 }
125 }
126
127 void atm_attach(struct bus_device *ui) {
128 int un;
129
130 un = ui->unit;
131 if (un >= NATM) {
132 printf("atm: stray attach\n");
133 } else {
134 atmp[un]->creg =
135 atm_control_mask[un] = CR_TX_ENABLE | CR_RX_ENABLE | RX_COUNT_INTR;
136 /*Enable ATM interrupts*/
137 }
138 }
139
140 void atm_intr(int unit, int spl_level) {
141
142 if (unit >= NATM || atmp[unit] == NULL) {
143 printf("atm: stray interrupt\n");
144 } else {
145 atmp[unit]->creg = CR_TX_ENABLE | CR_RX_ENABLE; /*Disable ATM interrupts*/
146 wbflush();
147 if (atm_mapped[unit]) {
148 splx(spl_level);
149 evc_signal(&atm_event_counter[unit]);
150 } else {
151 simple_lock(&atm_simple_lock);
152 tca100_poll(DEVICE(unit));
153 atmp[unit]->creg = atm_control_mask[unit];
154 simple_unlock(&atm_simple_lock);
155 splx(spl_level);
156 }
157 }
158 }
159
160 io_return_t atm_open(dev_t dev, int mode, io_req_t ior) {
161 int un;
162
163 un = minor(dev);
164 if (un >= NATM || atmp[un] == NULL) {
165 return D_NO_SUCH_DEVICE;
166 /*
167 } else if (atm_open_count[un] > 0 && (atm_mapped[un] || (mode & D_WRITE))) {
168 return D_ALREADY_OPEN;
169 */
170 } else {
171 atm_open_count[un]++;
172 atm_mapped[un] = ((mode & D_WRITE) != 0);
173 if (atm_mapped[un])
174 (void) nc_device_unregister(DEVICE(un), NW_NOT_SERVER);
175 return D_SUCCESS;
176 }
177 }
178
179 io_return_t atm_close(dev_t dev) {
180 int un;
181
182 un = minor(dev);
183 if (un >= NATM || atmp[un] == NULL) {
184 return D_NO_SUCH_DEVICE;
185 } else if (atm_open_count[un] == 0) {
186 return D_INVALID_OPERATION;
187 } else {
188 if (atm_mapped[un]) {
189 (void) nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED,
190 (char *) atmp[un],
191 &tca100_entry_table);
192 atm_mapped[un] = 0;
193 }
194 atm_open_count[un]--;
195 return D_SUCCESS;
196 }
197 }
198
199 unsigned int *frc = 0xbe801000;
200 char data[66000];
201
202 io_return_t atm_read(dev_t dev, io_req_t ior) {
203 unsigned int ck1, ck2;
204 int i, j;
205 char c[16];
206
207 ck1 = *frc;
208 device_read_alloc(ior, ior->io_count);
209 for (i = 0, j = 0; i < ior->io_count; i += 4096, j++)
210 c[j] = (ior->io_data)[i];
211 ck2 = *frc;
212 ((int *) ior->io_data)[0] = ck1;
213 ((int *) ior->io_data)[1] = ck2;
214 return D_SUCCESS;
215 }
216
217 io_return_t atm_write(dev_t dev, io_req_t ior) {
218 int i, j;
219 char c[16];
220 boolean_t wait;
221
222 device_write_get(ior, &wait);
223 for (i = 0, j = 0; i < ior->io_total; i += 4096, j++)
224 c[j] = (ior->io_data)[i];
225 ior->io_residual = ior->io_total - *frc;
226 return D_SUCCESS;
227 }
228
229 io_return_t atm_get_status(dev_t dev, int flavor, dev_status_t status,
230 u_int *status_count) {
231 int un;
232
233 un = minor(dev);
234 if (un >= NATM || atmp[un] == NULL) {
235 return D_NO_SUCH_DEVICE;
236 } else {
237 switch ((atm_status) flavor) {
238 case ATM_MAP_SIZE:
239 status[0] = sizeof(atm_device_s);
240 *status_count = sizeof(int);
241 return D_SUCCESS;
242 case ATM_MTU_SIZE:
243 status[0] = 65535; /*MTU size*/
244 *status_count = sizeof(int);
245 return D_SUCCESS;
246 case ATM_EVC_ID:
247 status[0] = atm_event_counter[un].ev_id;
248 *status_count = sizeof(int);
249 return D_SUCCESS;
250 case ATM_ASSIGNMENT:
251 status[0] = atm_mapped[un];
252 status[1] = atm_open_count[un];
253 *status_count = 2 * sizeof(int);
254 return D_SUCCESS;
255 default:
256 return D_INVALID_OPERATION;
257 }
258 }
259 }
260
261 io_return_t atm_set_status(dev_t dev, int flavor, dev_status_t status,
262 u_int status_count) {
263 io_return_t rc;
264 int un, s;
265 nw_pvc_t pvcp;
266 nw_plist_t pel;
267 nw_ep lep;
268
269 un = minor(dev);
270 if (un >= NATM || atmp[un] == NULL) {
271 return D_NO_SUCH_DEVICE;
272 } else switch ((atm_status) flavor) {
273 case ATM_INITIALIZE:
274 if (status_count != 0) {
275 return D_INVALID_OPERATION;
276 } else {
277 s = splsched();
278 if (nc_device_register(DEVICE(un), NW_CONNECTION_ORIENTED,
279 (char *) atmp[un],
280 &tca100_entry_table) == NW_SUCCESS &&
281 tca100_initialize(DEVICE(un)) == NW_SUCCESS) {
282 atm_initialize(un);
283 rc = D_SUCCESS;
284 } else {
285 atmp[un] = NULL;
286 (void) nc_device_unregister(DEVICE(un), NW_FAILURE);
287 rc = D_INVALID_OPERATION;
288 }
289 splx(s);
290 return rc;
291 }
292 break;
293
294 #if PERMANENT_VIRTUAL_CONNECTIONS
295 case ATM_PVC_SET:
296 pvcp = (nw_pvc_t) status;
297 if (status_count != sizeof(nw_pvc_s) || pvcp->pvc.local_ep >= MAX_EP) {
298 rc = D_INVALID_OPERATION;
299 } else if ((pel = nc_peer_allocate()) == NULL) {
300 rc = D_INVALID_OPERATION;
301 } else {
302 lep = pvcp->pvc.local_ep;
303 tct[lep].rx_sar_header = SSM | 1;
304 tct[lep].tx_atm_header = pvcp->tx_vp << ATM_VPVC_SHIFT;
305 tct[lep].tx_sar_header = 1;
306 ect[lep].state = NW_DUPLEX_ACCEPTED;
307 pel->peer = pvcp->pvc;
308 pel->next = NULL;
309 ect[lep].conn = pel;
310 if (pvcp->protocol == NW_LINE) {
311 if (nc_line_update(&pel->peer, lep) == NW_SUCCESS) {
312 ect[lep].protocol = pvcp->protocol;
313 if (nw_free_line_last == 0)
314 nw_free_line_first = lep;
315 else
316 ect[nw_free_line_last].next = lep;
317 ect[lep].previous = nw_free_line_last;
318 ect[lep].next = 0;
319 nw_free_line_last = lep;
320 rc = D_SUCCESS;
321 } else {
322 rc = D_INVALID_OPERATION;
323 }
324 } else {
325 rc = D_SUCCESS;
326 }
327 }
328 return rc;
329 #endif
330
331 default:
332 return D_INVALID_OPERATION;
333 }
334 }
335
336 int atm_mmap(dev_t dev, vm_offset_t off, int prot) {
337 int un;
338 vm_offset_t addr;
339
340 un = minor(dev);
341 if (un >= NATM || atmp[un] == NULL || !atm_mapped[un] ||
342 off >= sizeof(atm_device_s)) {
343 return -1;
344 } else {
345 return mips_btop(K1SEG_TO_PHYS( (vm_offset_t) atmp[un] ) + off );
346 }
347 }
348
349 io_return_t atm_restart(int u) {
350
351 return D_INVALID_OPERATION;
352 }
353
354 io_return_t atm_setinput(dev_t dev, ipc_port_t receive_port, int priority,
355 filter_array_t *filter, u_int filter_count) {
356
357 return D_INVALID_OPERATION;
358 }
359
360 int atm_portdeath(dev_t dev, mach_port_t port) {
361
362 return D_INVALID_OPERATION;
363 }
364
365
366 #endif NATM > 0
367
368
369
Cache object: 04645639c5aefe0ed8cf48269d19de8a
|