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