Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / via-rhine / via-rhine_init.c
blob385bdca49f6cbb2e7d2e89cebc1d6b1f3b7f0f9f
1 /*
2 * $Id$
3 */
5 /*
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA.
22 #include <exec/types.h>
23 #include <exec/resident.h>
24 #include <exec/io.h>
25 #include <exec/errors.h>
26 #include <exec/lists.h>
28 #include <aros/libcall.h>
29 #include <aros/symbolsets.h>
31 #include <oop/oop.h>
33 #include <devices/sana2.h>
34 #include <devices/sana2specialstats.h>
36 #include <utility/utility.h>
37 #include <utility/tagitem.h>
38 #include <utility/hooks.h>
40 #include <hidd/pci.h>
42 #include <proto/oop.h>
43 #include <proto/exec.h>
44 #include <proto/utility.h>
46 #include "via-rhine.h"
47 #include "unit.h"
48 #include LC_LIBDEFS_FILE
50 AROS_UFH3(void, Enumerator,
51 AROS_UFHA(struct Hook *, hook, A0),
52 AROS_UFHA(OOP_Object *, pciDevice, A2),
53 AROS_UFHA(APTR, message, A1))
55 AROS_USERFUNC_INIT
57 D(bug("[VIA-RHINE] init.PCI_Enumerator()\n"));
59 LIBBASETYPEPTR LIBBASE = (LIBBASETYPEPTR)hook->h_Data;
61 BOOL FoundCompatNIC = FALSE;
62 IPTR DeviceID, VendorID, RevisionID, CardCapabilities;
63 OOP_GetAttr(pciDevice, aHidd_PCIDevice_VendorID, &VendorID);
64 OOP_GetAttr(pciDevice, aHidd_PCIDevice_ProductID, &DeviceID);
65 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RevisionID, &RevisionID);
66 char *CardName;
68 if (DeviceID == 0x6100)
70 FoundCompatNIC = TRUE;
71 CardCapabilities = RTLc_CanHaveMII;
72 CardName = "VIA VT86C100A Rhine-II";
74 else if (DeviceID == 0x3043)
76 FoundCompatNIC = TRUE;
77 CardCapabilities = RTLc_CanHaveMII;
78 CardName = "VIA VT3042 Rhine";
80 else if (DeviceID == 0x3065)
82 FoundCompatNIC = TRUE;
83 CardCapabilities = RTLc_CanHaveMII;
84 CardName = "VIA VT6102 Rhine-II/VT6103 Tahoe 10/100M Fast Ethernet Adapter";
86 else if (DeviceID == 0x3106)
88 FoundCompatNIC = TRUE;
89 CardCapabilities = RTLc_CanHaveMII;
90 CardName = "VIA VT6105 Rhine-III Management Adapter";
92 else if (DeviceID == 0x3053)
94 FoundCompatNIC = TRUE;
95 CardCapabilities = RTLc_CanHaveMII;
96 CardName = "VIA VT6105M Rhine-III Management Adapter";
99 if (FoundCompatNIC)
101 D(bug("[VIA-RHINE] Found %s NIC, PCI_ID %04x:%04x Rev:%d\n", CardName, VendorID, DeviceID, RevisionID));
103 struct VIARHINEUnit *unit = CreateUnit(LIBBASE, pciDevice, CardCapabilities, CardName);
104 LIBBASE->rhineb_unit = unit;
106 D(bug("%s %s NIC I/O MEM @ %08x\n", unit->rhineu_name, unit->rhineu_cardname, unit->rhineu_BaseMem));
109 AROS_USERFUNC_EXIT
112 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
114 D(bug("[VIA-RHINE] init.Init()\n"));
116 if (FindTask(VIARHINE_TASK_NAME) != NULL)
118 D(bug("[VIA-RHINE] device already up and running.\n"));
119 return FALSE;
122 LIBBASE->rhineb_Sana2Info.HardwareType = S2WireType_Ethernet;
123 LIBBASE->rhineb_Sana2Info.MTU = ETH_MTU;
124 LIBBASE->rhineb_Sana2Info.AddrFieldSize = 8 * ETH_ADDRESSSIZE;
126 LIBBASE->rhineb_pciDeviceAttrBase = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
128 if (LIBBASE->rhineb_pciDeviceAttrBase != 0)
130 D(bug("[VIA-RHINE] Got HiddPCIDeviceAttrBase\n"));
132 LIBBASE->rhineb_pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
134 if (LIBBASE->rhineb_pci)
136 D(bug("[VIA-RHINE] Got PCI object\n"));
138 struct Hook FindHook = {
139 h_Entry: (IPTR (*)())Enumerator,
140 h_Data: LIBBASE,
143 struct TagItem Requirements[] = {
144 { tHidd_PCI_VendorID, 0x1106 },
145 { TAG_DONE, 0UL }
148 HIDD_PCI_EnumDevices( LIBBASE->rhineb_pci,
149 &FindHook,
150 (struct TagItem *)&Requirements
153 if (LIBBASE->rhineb_unit)
155 return TRUE;
160 return FALSE;
163 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
165 D(bug("[VIA-RHINE] init.Expunge\n"));
167 if (LIBBASE->rhineb_unit)
169 DeleteUnit(LIBBASE, LIBBASE->rhineb_unit);
170 LIBBASE->rhineb_unit = NULL;
173 if (LIBBASE->rhineb_pciDeviceAttrBase != 0)
174 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
176 LIBBASE->rhineb_pciDeviceAttrBase = 0;
178 if (LIBBASE->rhineb_pci != NULL)
179 OOP_DisposeObject(LIBBASE->rhineb_pci);
181 return TRUE;
184 static const ULONG rx_tags[] = {
185 S2_CopyToBuff,
186 S2_CopyToBuff16
189 static const ULONG tx_tags[] = {
190 S2_CopyFromBuff,
191 S2_CopyFromBuff16,
192 S2_CopyFromBuff32
196 * Open device handles currently only one pcnet32 unit.
198 static int GM_UNIQUENAME(Open)
200 LIBBASETYPEPTR LIBBASE,
201 struct IOSana2Req* req,
202 ULONG unitnum,
203 ULONG flags
206 struct TagItem *tags;
207 struct VIARHINEUnit *unit = LIBBASE->rhineb_unit;
208 struct Opener *opener;
209 BYTE error=0;
210 int i;
212 D(bug("[VIA-RHINE] init.OpenDevice\n"));
214 req->ios2_Req.io_Unit = NULL;
215 tags = req->ios2_BufferManagement;
217 req->ios2_BufferManagement = NULL;
219 /* Check request size */
221 if(req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
222 error = IOERR_OPENFAIL;
224 /* Get the requested unit */
225 if((error == 0) && (unitnum == 0))
227 req->ios2_Req.io_Unit = (APTR)unit;
229 else error = IOERR_OPENFAIL;
231 /* Handle device sharing */
233 if(error == 0)
235 if(unit->rhineu_open_count != 0 && ((unit->rhineu_flags & IFF_SHARED) == 0 ||
236 (flags & SANA2OPF_MINE) != 0))
237 error = IOERR_UNITBUSY;
238 unit->rhineu_open_count++;
241 if(error == 0)
243 if((flags & SANA2OPF_MINE) == 0)
244 unit->rhineu_flags |= IFF_SHARED;
245 else if((flags & SANA2OPF_PROM) != 0)
246 unit->rhineu_flags |= IFF_PROMISC;
248 /* Set up buffer-management structure and get hooks */
249 opener = AllocVec(sizeof(struct Opener), MEMF_PUBLIC | MEMF_CLEAR);
250 req->ios2_BufferManagement = (APTR)opener;
252 if(opener == NULL)
253 error = IOERR_OPENFAIL;
256 if(error == 0)
258 NEWLIST(&opener->read_port.mp_MsgList);
259 opener->read_port.mp_Flags = PA_IGNORE;
260 NEWLIST((APTR)&opener->initial_stats);
262 for(i = 0; i < 2; i++)
263 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
264 for(i = 0; i < 3; i++)
265 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
267 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
269 Disable();
270 AddTail((APTR)&unit->rhineu_Openers, (APTR)opener);
271 Enable();
274 if (error != 0)
275 CloseDevice((struct IORequest *)req);
276 else
277 unit->start(unit);
279 req->ios2_Req.io_Error = error;
281 return (error !=0) ? FALSE : TRUE;
284 static int GM_UNIQUENAME(Close)
286 LIBBASETYPEPTR LIBBASE,
287 struct IOSana2Req* req
290 struct VIARHINEUnit *unit = LIBBASE->rhineb_unit;
291 struct Opener *opener;
293 D(bug("[VIA-RHINE] init.CloseDevice\n"));
295 unit->stop(unit);
297 opener = (APTR)req->ios2_BufferManagement;
298 if (opener != NULL)
300 Disable();
301 Remove((struct Node *)opener);
302 Enable();
303 FreeVec(opener);
306 return TRUE;
310 ADD2INITLIB(GM_UNIQUENAME(Init),0)
311 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge),0)
312 ADD2OPENDEV(GM_UNIQUENAME(Open),0)
313 ADD2CLOSEDEV(GM_UNIQUENAME(Close),0)
315 AROS_LH1(void, beginio,
316 AROS_LHA(struct IOSana2Req *, req, A1),
317 LIBBASETYPEPTR, LIBBASE, 5, VIARHINEDev)
319 AROS_LIBFUNC_INIT
320 struct VIARHINEUnit *dev;
322 D(bug("[VIA-RHINE] init.BeginIO\n"));
324 req->ios2_Req.io_Error = 0;
325 dev = (APTR)req->ios2_Req.io_Unit;
327 if (AttemptSemaphore(&dev->rhineu_unit_lock))
329 handle_request(LIBBASE, req);
331 else
333 req->ios2_Req.io_Flags &= ~IOF_QUICK;
334 PutMsg(dev->rhineu_input_port, (struct Message *)req);
337 AROS_LIBFUNC_EXIT
340 AROS_LH1(LONG, abortio,
341 AROS_LHA(struct IOSana2Req *, req, A1),
342 LIBBASETYPEPTR, LIBBASE, 6, VIARHINEDev)
344 AROS_LIBFUNC_INIT
346 D(bug("[VIA-RHINE] init.AbortIO\n"));
348 Disable();
349 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
350 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
352 Remove((struct Node *)req);
353 req->ios2_Req.io_Error = IOERR_ABORTED;
354 req->ios2_WireError = S2WERR_GENERIC_ERROR;
355 ReplyMsg((struct Message *)req);
357 Enable();
359 return 0;
361 AROS_LIBFUNC_EXIT