Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / etherlink3 / os4_device.c
blob437bf891a39f10f62eba937a637dd982bfe76bf9
1 /*
3 Copyright (C) 2000-2011 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 MA 02111-1307, USA.
23 #include <exec/types.h>
24 #include <exec/resident.h>
25 #include <exec/errors.h>
26 #include <exec/emulation.h>
27 #include <utility/utility.h>
28 #include <expansion/expansion.h>
29 #include <resources/card.h>
30 #include <libraries/pccard.h>
32 #include <proto/exec.h>
33 #include <clib/alib_protos.h>
34 #include <proto/utility.h>
36 #include "device.h"
38 #include "device_protos.h"
39 #include "unit_protos.h"
40 #include "pci_protos.h"
41 #include "request_protos.h"
44 /* Private prototypes */
46 static struct DevBase *OS4DevInit(struct DevBase *dev_base, APTR seg_list,
47 struct ExecIFace *i_exec);
48 static ULONG IfaceObtain(struct Interface *self);
49 static ULONG IfaceRelease(struct Interface *self);
50 static LONG OS4DevOpen(struct Interface *self, struct IOSana2Req *request,
51 ULONG unit_num, ULONG flags);
52 static APTR OS4DevClose(struct Interface *self, struct IOSana2Req *request);
53 static APTR OS4DevExpunge(struct Interface *self);
54 static VOID OS4DevBeginIO(struct Interface *self,
55 struct IOSana2Req *request);
56 static VOID OS4DevAbortIO(struct Interface *self,
57 struct IOSana2Req *request);
58 static VOID DeleteDevice(struct DevBase *base);
59 static BOOL RXFunction(struct IOSana2Req *request, APTR buffer, ULONG size);
60 static BOOL TXFunction(APTR buffer, struct IOSana2Req *request, ULONG size);
61 static UBYTE *DMATXFunction(struct IOSana2Req *request);
62 static ULONG OS4Int(struct ExceptionContext ex_context,
63 struct ExecBase *sys_base, APTR *int_data);
66 extern const TEXT device_name[];
67 extern const TEXT version_string[];
68 extern const TEXT utility_name[];
69 extern const TEXT pccard_name[];
70 extern const TEXT card_name[];
71 extern const TEXT timer_name[];
72 extern const struct Resident rom_tag;
74 static const TEXT manager_name[] = "__device";
75 static const TEXT expansion_name[] = EXPANSIONNAME;
78 static const APTR manager_vectors[] =
80 (APTR)IfaceObtain,
81 (APTR)IfaceRelease,
82 (APTR)NULL,
83 (APTR)NULL,
84 (APTR)OS4DevOpen,
85 (APTR)OS4DevClose,
86 (APTR)OS4DevExpunge,
87 (APTR)NULL,
88 (APTR)OS4DevBeginIO,
89 (APTR)OS4DevAbortIO,
90 (APTR)-1
94 static const struct TagItem manager_tags[] =
96 {MIT_Name, (UPINT)manager_name},
97 {MIT_VectorTable, (UPINT)manager_vectors},
98 {MIT_Version, 1},
99 {TAG_END, 0}
103 static const struct TagItem *interfaces[] =
105 manager_tags,
106 NULL
110 static const struct TagItem init_tags[] =
112 {CLT_DataSize, sizeof(struct DevBase)},
113 {CLT_InitFunc, (UPINT)OS4DevInit},
114 {CLT_Interfaces, (UPINT)interfaces},
115 {TAG_END, 0}
119 const struct Resident os4_rom_tag =
121 RTC_MATCHWORD,
122 (struct Resident *)&os4_rom_tag,
123 (APTR)(&rom_tag + 1),
124 RTF_AUTOINIT | RTF_NATIVE,
125 VERSION,
126 NT_DEVICE,
128 (STRPTR)device_name,
129 (STRPTR)version_string,
130 (APTR)init_tags
134 static const ULONG rx_tags[] =
136 S2_CopyToBuff,
137 S2_CopyToBuff16,
141 static const ULONG tx_tags[] =
143 S2_CopyFromBuff,
144 S2_CopyFromBuff16,
145 S2_CopyFromBuff32
150 /****i* etherlink3.device/OS4DevInit ***************************************
152 * NAME
153 * OS4DevInit
155 * SYNOPSIS
156 * dev_base = OS4DevInit(dev_base, seg_list, i_exec)
158 * struct DevBase *OS4DevInit(struct DevBase *, APTR, ExecIFace *);
160 ****************************************************************************
164 static struct DevBase *OS4DevInit(struct DevBase *dev_base, APTR seg_list,
165 struct ExecIFace *i_exec)
167 struct DevBase *base;
168 BOOL success = TRUE;
170 dev_base->i_exec = i_exec;
171 base = dev_base;
172 base->seg_list = seg_list;
173 base->sys_base = (APTR)i_exec->Data.LibBase;
175 base->device.dd_Library.lib_Node.ln_Type = NT_DEVICE;
176 base->device.dd_Library.lib_Node.ln_Name = (TEXT *)device_name;
177 base->device.dd_Library.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
178 base->device.dd_Library.lib_Version = VERSION;
179 base->device.dd_Library.lib_Revision = REVISION;
180 base->device.dd_Library.lib_IdString = (TEXT *)version_string;
182 base->utility_base = (APTR)OpenLibrary(utility_name, UTILITY_VERSION);
183 base->expansion_base = OpenLibrary(expansion_name, EXPANSION_VERSION);
184 if(base->utility_base == NULL || base->expansion_base == NULL)
185 success = FALSE;
186 base->pccard_base = (APTR)OpenLibrary(pccard_name, PCCARD_VERSION);
187 if(base->pccard_base != NULL)
188 base->card_base = (APTR)OpenResource(card_name);
190 if(OpenDevice(timer_name, UNIT_ECLOCK, (APTR)&base->timer_request, 0) !=
192 success = FALSE;
194 NewList((APTR)(&dev_base->pci_units));
195 NewList((APTR)(&dev_base->pccard_units));
196 base->wrapper_int_code = (APTR)OS4Int;
198 if(success)
200 base->i_utility =
201 (APTR)GetInterface((APTR)UtilityBase, "main", 1, NULL);
202 base->i_pci = (APTR)GetInterface(ExpansionBase, "pci", 1, NULL);
203 if(CardResource != NULL)
205 base->i_pccard =
206 (APTR)GetInterface(PCCardBase, "main", 1, NULL);
207 base->i_card =
208 (APTR)GetInterface(CardResource, "main", 1, NULL);
209 // if(base->i_pccard == NULL || base->i_card == NULL)
210 if(base->i_card == NULL)
211 success = FALSE;
213 base->i_timer = (APTR)GetInterface((APTR)TimerBase, "main", 1, NULL);
214 if(base->i_utility == NULL || base->i_timer == NULL)
215 success = FALSE;
218 if(!success)
220 DeleteDevice(base);
221 base = NULL;
224 return base;
229 /****i* etherlink3.device/IfaceObtain **************************************
231 * NAME
232 * IfaceObtain
234 * SYNOPSIS
235 * ref_count = IfaceObtain(self)
237 * ULONG IfaceObtain(struct Interface *);
239 ****************************************************************************
243 static ULONG IfaceObtain(struct Interface *self)
245 return self->Data.RefCount++;
250 /****i* etherlink3.device/IfaceRelease *************************************
252 * NAME
253 * IfaceRelease
255 * SYNOPSIS
256 * ref_count = IfaceRelease(self)
258 * ULONG IfaceRelease(struct Interface *);
260 ****************************************************************************
264 static ULONG IfaceRelease(struct Interface *self)
266 return --self->Data.RefCount;
271 /****i* etherlink3.device/OS4DevOpen ***************************************
273 * NAME
274 * OS4DevOpen
276 * SYNOPSIS
277 * error = OS4DevOpen(self, request, unit_num,
278 * flags)
280 * LONG OS4DevOpen(struct Interface *, struct IOSana2Req *, ULONG,
281 * ULONG);
283 ****************************************************************************
287 static LONG OS4DevOpen(struct Interface *self, struct IOSana2Req *request,
288 ULONG unit_num, ULONG flags)
290 struct Opener *opener;
291 BYTE error;
293 error = DevOpen(request, unit_num, flags, (APTR)self->Data.LibBase);
295 /* Set up wrapper hooks to hide 68k emulation */
297 if(error == 0)
299 opener = request->ios2_BufferManagement;
300 opener->real_rx_function = opener->rx_function;
301 opener->real_tx_function = opener->tx_function;
302 opener->rx_function = (APTR)RXFunction;
303 opener->tx_function = (APTR)TXFunction;
304 if(opener->dma_tx_function != NULL)
306 opener->real_dma_tx_function = opener->dma_tx_function;
307 opener->dma_tx_function = (APTR)DMATXFunction;
311 return error;
316 /****i* etherlink3.device/OS4DevClose **************************************
318 * NAME
319 * OS4DevClose
321 * SYNOPSIS
322 * seg_list = OS4DevClose(request)
324 * APTR OS4DevClose(struct IOSana2Req *);
326 ****************************************************************************
330 static APTR OS4DevClose(struct Interface *self, struct IOSana2Req *request)
332 struct DevBase *base;
333 APTR seg_list = NULL;
335 /* Close the unit */
337 base = (APTR)self->Data.LibBase;
338 CloseUnit(request, base);
340 /* Expunge the device if a delayed expunge is pending */
342 if(base->device.dd_Library.lib_OpenCnt == 0)
344 if((base->device.dd_Library.lib_Flags & LIBF_DELEXP) != 0)
345 seg_list = OS4DevExpunge(self);
348 return seg_list;
353 /****i* etherlink3.device/OS4DevExpunge ************************************
355 * NAME
356 * OS4DevExpunge
358 * SYNOPSIS
359 * seg_list = OS4DevExpunge()
361 * APTR OS4DevExpunge(VOID);
363 ****************************************************************************
367 static APTR OS4DevExpunge(struct Interface *self)
369 struct DevBase *base;
370 APTR seg_list;
372 base = (APTR)self->Data.LibBase;
373 if(base->device.dd_Library.lib_OpenCnt == 0)
375 seg_list = base->seg_list;
376 Remove((APTR)base);
377 DeleteDevice(base);
379 else
381 base->device.dd_Library.lib_Flags |= LIBF_DELEXP;
382 seg_list = NULL;
385 return seg_list;
390 /****i* etherlink3.device/OS4DevBeginIO ************************************
392 * NAME
393 * OS4DevBeginIO
395 * SYNOPSIS
396 * OS4DevBeginIO(request)
398 * VOID OS4DevBeginIO(struct IORequest *);
400 ****************************************************************************
404 static VOID OS4DevBeginIO(struct Interface *self,
405 struct IOSana2Req *request)
407 /* Replace caller's cookie with our own */
409 request->ios2_Req.io_Error = 0;
410 switch(request->ios2_Req.io_Command)
412 case CMD_READ:
413 case CMD_WRITE:
414 case S2_MULTICAST:
415 case S2_BROADCAST:
416 case S2_READORPHAN:
417 request->ios2_StatData = request->ios2_Data;
418 request->ios2_Data = request;
421 /* Send request for processing */
423 DevBeginIO(request, (APTR)self->Data.LibBase);
425 return;
430 /****i* etherlink3.device/OS4DevAbortIO ************************************
432 * NAME
433 * OS4DevAbortIO -- Try to stop a request.
435 * SYNOPSIS
436 * OS4DevAbortIO(request)
438 * VOID OS4DevAbortIO(struct IOSana2Req *);
440 ****************************************************************************
444 static VOID OS4DevAbortIO(struct Interface *self,
445 struct IOSana2Req *request)
447 DevAbortIO(request, (APTR)self->Data.LibBase);
449 return;
454 /****i* etherlink3.device/DeleteDevice *************************************
456 * NAME
457 * DeleteDevice
459 * SYNOPSIS
460 * DeleteDevice()
462 * VOID DeleteDevice(VOID);
464 ****************************************************************************
468 static VOID DeleteDevice(struct DevBase *base)
470 /* Close interfaces */
472 DropInterface((APTR)base->i_timer);
473 DropInterface((APTR)base->i_card);
474 DropInterface((APTR)base->i_pccard);
475 DropInterface((APTR)base->i_pci);
476 DropInterface((APTR)base->i_utility);
478 /* Close devices */
480 CloseDevice((APTR)&base->timer_request);
482 /* Close libraries */
484 if(base->pccard_base != NULL)
485 CloseLibrary(base->pccard_base);
486 if(base->expansion_base != NULL)
487 CloseLibrary(base->expansion_base);
488 if(base->utility_base != NULL)
489 CloseLibrary((APTR)base->utility_base);
491 /* Free device's memory */
493 DeleteLibrary((APTR)base);
495 return;
500 /****i* etherlink3.device/RXFunction ***************************************
502 * NAME
503 * RXFunction
505 ****************************************************************************
509 static BOOL RXFunction(struct IOSana2Req *request, APTR buffer, ULONG size)
511 struct DevBase *base;
512 struct Opener *opener;
513 APTR cookie;
515 opener = request->ios2_BufferManagement;
516 cookie = request->ios2_StatData;
517 base = (struct DevBase *)request->ios2_Req.io_Device;
518 request->ios2_Data = cookie;
520 return EmulateTags(opener->real_rx_function,
521 ET_RegisterA0, cookie, ET_RegisterA1, buffer,
522 ET_RegisterD0, size, TAG_END);
527 /****i* etherlink3.device/TXFunction ***************************************
529 * NAME
530 * TXFunction
532 ****************************************************************************
536 static BOOL TXFunction(APTR buffer, struct IOSana2Req *request, ULONG size)
538 struct DevBase *base;
539 struct Opener *opener;
540 APTR cookie;
542 opener = request->ios2_BufferManagement;
543 cookie = request->ios2_StatData;
544 base = (struct DevBase *)request->ios2_Req.io_Device;
545 request->ios2_Data = cookie;
546 return EmulateTags(opener->real_tx_function,
547 ET_RegisterA0, buffer, ET_RegisterA1, cookie,
548 ET_RegisterD0, size, TAG_END);
553 /****i* etherlink3.device/DMATXFunction ************************************
555 * NAME
556 * DMATXFunction
558 ****************************************************************************
562 static UBYTE *DMATXFunction(struct IOSana2Req *request)
564 struct DevBase *base;
565 struct Opener *opener;
566 APTR cookie;
568 opener = request->ios2_BufferManagement;
569 cookie = request->ios2_StatData;
570 base = (struct DevBase *)request->ios2_Req.io_Device;
571 request->ios2_Data = cookie;
572 return (UBYTE *)EmulateTags(opener->real_dma_tx_function,
573 ET_RegisterA0, cookie, TAG_END);
578 /****i* etherlink3.device/OS4Int *******************************************
580 * NAME
581 * OS4Int
583 ****************************************************************************
587 static ULONG OS4Int(struct ExceptionContext ex_context,
588 struct ExecBase *sys_base, APTR *int_data)
590 BOOL (*int_code)(APTR, APTR, UBYTE);
592 int_code = int_data[0];
593 return int_code(int_data[1], int_code, 0x4);