Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / atheros5000 / os4_device.c
blobed0575b641b99dd95dc096664cd55e27a3fd5476
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 <dos/dos.h>
28 #include <utility/utility.h>
29 #include <expansion/expansion.h>
31 #include <proto/exec.h>
32 #include <clib/alib_protos.h>
33 #include <proto/utility.h>
35 #include "device.h"
37 #include "device_protos.h"
38 #include "unit_protos.h"
39 #include "pci_protos.h"
40 #include "request_protos.h"
43 /* Private prototypes */
45 static struct DevBase *OS4DevInit(struct DevBase *dev_base, APTR seg_list,
46 struct ExecIFace *i_exec);
47 static ULONG IfaceObtain(struct Interface *self);
48 static ULONG IfaceRelease(struct Interface *self);
49 static LONG OS4DevOpen(struct Interface *self, struct IOSana2Req *request,
50 ULONG unit_num, ULONG flags);
51 static APTR OS4DevClose(struct Interface *self, struct IOSana2Req *request);
52 static APTR OS4DevExpunge(struct Interface *self);
53 static VOID OS4DevBeginIO(struct Interface *self,
54 struct IOSana2Req *request);
55 static VOID OS4DevAbortIO(struct Interface *self,
56 struct IOSana2Req *request);
57 static VOID DeleteDevice(struct DevBase *base);
58 static BOOL RXFunction(struct IOSana2Req *request, APTR buffer, ULONG size);
59 static BOOL TXFunction(APTR buffer, struct IOSana2Req *request, ULONG size);
60 static UBYTE *DMATXFunction(struct IOSana2Req *request);
61 static ULONG OS4Int(struct ExceptionContext ex_context,
62 struct ExecBase *sys_base, APTR *int_data);
65 extern const TEXT device_name[];
66 extern const TEXT version_string[];
67 extern const TEXT utility_name[];
68 extern const TEXT dos_name[];
69 extern const TEXT timer_name[];
70 extern const struct Resident rom_tag;
72 extern BOOL __check_abort_enabled;
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* atheros5000.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 base->dos_base = (APTR)OpenLibrary(dos_name, DOS_VERSION);
185 if(base->utility_base == NULL || base->expansion_base == NULL
186 || base->dos_base == NULL)
187 success = FALSE;
189 if(OpenDevice(timer_name, UNIT_VBLANK, (APTR)&base->timer_request, 0) !=
191 success = FALSE;
193 NewList((APTR)(&dev_base->pci_units));
194 base->wrapper_int_code = (APTR)OS4Int;
196 hal_dev_base = dev_base;
197 __check_abort_enabled = FALSE;
199 if(success)
201 base->i_utility =
202 (APTR)GetInterface((APTR)UtilityBase, "main", 1, NULL);
203 base->i_pci = (APTR)GetInterface(ExpansionBase, "pci", 1, NULL);
204 base->i_dos = (APTR)GetInterface((APTR)DOSBase, "main", 1, NULL);
205 base->i_timer = (APTR)GetInterface((APTR)TimerBase, "main", 1, NULL);
206 if(base->i_utility == NULL || base->i_dos == NULL
207 || base->i_timer == NULL)
208 success = FALSE;
211 if(!success)
213 DeleteDevice(base);
214 base = NULL;
217 return base;
222 /****i* atheros5000.device/IfaceObtain *************************************
224 * NAME
225 * IfaceObtain
227 * SYNOPSIS
228 * ref_count = IfaceObtain(self)
230 * ULONG IfaceObtain(struct Interface *);
232 ****************************************************************************
236 static ULONG IfaceObtain(struct Interface *self)
238 return self->Data.RefCount++;
243 /****i* atheros5000.device/IfaceRelease ************************************
245 * NAME
246 * IfaceRelease
248 * SYNOPSIS
249 * ref_count = IfaceRelease(self)
251 * ULONG IfaceRelease(struct Interface *);
253 ****************************************************************************
257 static ULONG IfaceRelease(struct Interface *self)
259 return --self->Data.RefCount;
264 /****i* atheros5000.device/OS4DevOpen **************************************
266 * NAME
267 * OS4DevOpen
269 * SYNOPSIS
270 * error = OS4DevOpen(self, request, unit_num,
271 * flags)
273 * LONG OS4DevOpen(struct Interface *, struct IOSana2Req *, ULONG,
274 * ULONG);
276 ****************************************************************************
280 static LONG OS4DevOpen(struct Interface *self, struct IOSana2Req *request,
281 ULONG unit_num, ULONG flags)
283 struct Opener *opener;
284 BYTE error;
286 error = DevOpen(request, unit_num, flags, (APTR)self->Data.LibBase);
288 /* Set up wrapper hooks to hide 68k emulation */
290 if(error == 0)
292 opener = request->ios2_BufferManagement;
293 opener->real_rx_function = opener->rx_function;
294 opener->real_tx_function = opener->tx_function;
295 opener->rx_function = (APTR)RXFunction;
296 opener->tx_function = (APTR)TXFunction;
297 if(opener->dma_tx_function != NULL)
299 opener->real_dma_tx_function = opener->dma_tx_function;
300 opener->dma_tx_function = (APTR)DMATXFunction;
304 return error;
309 /****i* atheros5000.device/OS4DevClose *************************************
311 * NAME
312 * OS4DevClose
314 * SYNOPSIS
315 * seg_list = OS4DevClose(request)
317 * APTR OS4DevClose(struct IOSana2Req *);
319 ****************************************************************************
323 static APTR OS4DevClose(struct Interface *self, struct IOSana2Req *request)
325 struct DevBase *base;
326 APTR seg_list = NULL;
328 /* Close the unit */
330 base = (APTR)self->Data.LibBase;
331 CloseUnit(request, base);
333 /* Expunge the device if a delayed expunge is pending */
335 if(base->device.dd_Library.lib_OpenCnt == 0)
337 if((base->device.dd_Library.lib_Flags & LIBF_DELEXP) != 0)
338 seg_list = OS4DevExpunge(self);
341 return seg_list;
346 /****i* atheros5000.device/OS4DevExpunge ***********************************
348 * NAME
349 * OS4DevExpunge
351 * SYNOPSIS
352 * seg_list = OS4DevExpunge()
354 * APTR OS4DevExpunge(VOID);
356 ****************************************************************************
360 static APTR OS4DevExpunge(struct Interface *self)
362 struct DevBase *base;
363 APTR seg_list;
365 base = (APTR)self->Data.LibBase;
366 if(base->device.dd_Library.lib_OpenCnt == 0)
368 seg_list = base->seg_list;
369 Remove((APTR)base);
370 DeleteDevice(base);
372 else
374 base->device.dd_Library.lib_Flags |= LIBF_DELEXP;
375 seg_list = NULL;
378 return seg_list;
383 /****i* atheros5000.device/OS4DevBeginIO ***********************************
385 * NAME
386 * OS4DevBeginIO
388 * SYNOPSIS
389 * OS4DevBeginIO(request)
391 * VOID OS4DevBeginIO(struct IORequest *);
393 ****************************************************************************
397 static VOID OS4DevBeginIO(struct Interface *self,
398 struct IOSana2Req *request)
400 /* Replace caller's cookie with our own */
402 request->ios2_Req.io_Error = 0;
403 switch(request->ios2_Req.io_Command)
405 case CMD_READ:
406 case CMD_WRITE:
407 case S2_MULTICAST:
408 case S2_BROADCAST:
409 case S2_READORPHAN:
410 request->ios2_StatData = request->ios2_Data;
411 request->ios2_Data = request;
414 /* Send request for processing */
416 DevBeginIO(request, (APTR)self->Data.LibBase);
418 return;
423 /****i* atheros5000.device/OS4DevAbortIO ***********************************
425 * NAME
426 * OS4DevAbortIO -- Try to stop a request.
428 * SYNOPSIS
429 * OS4DevAbortIO(request)
431 * VOID OS4DevAbortIO(struct IOSana2Req *);
433 ****************************************************************************
435 * Disable() used instead of a semaphore because device uses interrupts.
439 static VOID OS4DevAbortIO(struct Interface *self,
440 struct IOSana2Req *request)
442 DevAbortIO(request, (APTR)self->Data.LibBase);
444 return;
449 /****i* atheros5000.device/DeleteDevice ************************************
451 * NAME
452 * DeleteDevice
454 * SYNOPSIS
455 * DeleteDevice()
457 * VOID DeleteDevice(VOID);
459 ****************************************************************************
463 static VOID DeleteDevice(struct DevBase *base)
465 /* Close interfaces */
467 DropInterface((APTR)base->i_timer);
468 DropInterface((APTR)base->i_dos);
469 DropInterface((APTR)base->i_pci);
470 DropInterface((APTR)base->i_utility);
472 /* Close devices */
474 CloseDevice((APTR)&base->timer_request);
476 /* Close libraries */
478 if(base->dos_base != NULL)
479 CloseLibrary((APTR)base->dos_base);
480 if(base->expansion_base != NULL)
481 CloseLibrary(base->expansion_base);
482 if(base->utility_base != NULL)
483 CloseLibrary((APTR)base->utility_base);
485 /* Free device's memory */
487 DeleteLibrary((APTR)base);
489 return;
494 /****i* atheros5000.device/RXFunction **************************************
496 * NAME
497 * RXFunction
499 ****************************************************************************
503 static BOOL RXFunction(struct IOSana2Req *request, APTR buffer, ULONG size)
505 struct DevBase *base;
506 struct Opener *opener;
507 APTR cookie;
509 opener = request->ios2_BufferManagement;
510 cookie = request->ios2_StatData;
511 base = (struct DevBase *)request->ios2_Req.io_Device;
512 request->ios2_Data = cookie;
514 return EmulateTags(opener->real_rx_function,
515 ET_RegisterA0, cookie, ET_RegisterA1, buffer,
516 ET_RegisterD0, size, TAG_END);
521 /****i* atheros5000.device/TXFunction **************************************
523 * NAME
524 * TXFunction
526 ****************************************************************************
530 static BOOL TXFunction(APTR buffer, struct IOSana2Req *request, ULONG size)
532 struct DevBase *base;
533 struct Opener *opener;
534 APTR cookie;
536 opener = request->ios2_BufferManagement;
537 cookie = request->ios2_StatData;
538 base = (struct DevBase *)request->ios2_Req.io_Device;
539 request->ios2_Data = cookie;
540 return EmulateTags(opener->real_tx_function,
541 ET_RegisterA0, buffer, ET_RegisterA1, cookie,
542 ET_RegisterD0, size, TAG_END);
547 /****i* atheros5000.device/DMATXFunction ***********************************
549 * NAME
550 * DMATXFunction
552 ****************************************************************************
556 static UBYTE *DMATXFunction(struct IOSana2Req *request)
558 struct DevBase *base;
559 struct Opener *opener;
560 APTR cookie;
562 opener = request->ios2_BufferManagement;
563 cookie = request->ios2_StatData;
564 base = (struct DevBase *)request->ios2_Req.io_Device;
565 request->ios2_Data = cookie;
566 return (UBYTE *)EmulateTags(opener->real_dma_tx_function,
567 ET_RegisterA0, cookie, TAG_END);
572 /****i* atheros5000.device/OS4Int ******************************************
574 * NAME
575 * OS4Int
577 ****************************************************************************
581 static ULONG OS4Int(struct ExceptionContext ex_context,
582 struct ExecBase *sys_base, APTR *int_data)
584 BOOL (*int_code)(APTR, APTR, UBYTE);
586 int_code = int_data[0];
587 return int_code(int_data[1], int_code, 0x4);