Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / nForce / nforce_init.c
blob2e281aa80e5e8bf0b268746af3df4312f20f5c2b
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 #define DEBUG 0
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/io.h>
27 #include <exec/errors.h>
28 #include <exec/lists.h>
30 #include <aros/libcall.h>
31 #include <aros/debug.h>
32 #include <aros/symbolsets.h>
34 #include <oop/oop.h>
36 #include <devices/sana2.h>
37 #include <devices/sana2specialstats.h>
39 #include <utility/utility.h>
40 #include <utility/tagitem.h>
41 #include <utility/hooks.h>
43 #include <hidd/pci.h>
45 #include <proto/oop.h>
46 #include <proto/exec.h>
47 #include <proto/utility.h>
49 #include "nforce.h"
50 #include "unit.h"
51 #include LC_LIBDEFS_FILE
53 AROS_UFH3(void, Enumerator,
54 AROS_UFHA(struct Hook *, hook, A0),
55 AROS_UFHA(OOP_Object *, pciDevice, A2),
56 AROS_UFHA(APTR, message, A1))
58 AROS_USERFUNC_INIT
60 LIBBASETYPEPTR LIBBASE = (LIBBASETYPEPTR)hook->h_Data;
62 IPTR DeviceID;
63 OOP_GetAttr(pciDevice, aHidd_PCIDevice_ProductID, &DeviceID);
65 if ((DeviceID == NFORCE_MCPNET1_ID) ||
66 (DeviceID == NFORCE_MCPNET2_ID) ||
67 (DeviceID == NFORCE_MCPNET3_ID) ||
68 (DeviceID == NFORCE_MCPNET4_ID) ||
69 (DeviceID == NFORCE_MCPNET5_ID) ||
70 (DeviceID == NFORCE_MCPNET6_ID) ||
71 (DeviceID == NFORCE_MCPNET7_ID) ||
72 (DeviceID == NFORCE_MCPNET8_ID) ||
73 (DeviceID == NFORCE_MCPNET9_ID) ||
74 (DeviceID == NFORCE_MCPNET10_ID) ||
75 (DeviceID == NFORCE_MCPNET11_ID))
77 struct NFUnit *unit = CreateUnit(LIBBASE, pciDevice);
78 LIBBASE->nf_unit = unit;
80 D(bug("[nforce] Found nForce NIC, ProductID = %04x\n", DeviceID));
81 D(bug("[nforce] nForce NIC I/O @ %08x\n", unit->nu_BaseIO));
82 D(bug("[nforce] nForce NIC MEM @ %08x\n", unit->nu_BaseMem));
85 AROS_USERFUNC_EXIT
88 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
90 D(bug("[nforce] Init()\n"));
92 if (FindTask(NFORCE_TASK_NAME) != NULL)
94 D(bug("[nforce] device already up and running.\n"));
95 return FALSE;
98 LIBBASE->nf_Sana2Info.HardwareType = S2WireType_Ethernet;
99 LIBBASE->nf_Sana2Info.MTU = ETH_MTU;
100 LIBBASE->nf_Sana2Info.AddrFieldSize = 8 * ETH_ADDRESSSIZE;
102 LIBBASE->nf_pciDeviceAttrBase = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
104 if (LIBBASE->nf_pciDeviceAttrBase != 0)
106 D(bug("[nforce] Got HiddPCIDeviceAttrBase\n"));
108 LIBBASE->nf_pci = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
110 if (LIBBASE->nf_pci)
112 D(bug("[nforce] Got PCI object\n"));
114 struct Hook FindHook = {
115 h_Entry: (IPTR (*)())Enumerator,
116 h_Data: LIBBASE,
119 struct TagItem Requirements[] = {
120 { tHidd_PCI_VendorID, 0x10de },
121 { TAG_DONE, 0UL }
124 HIDD_PCI_EnumDevices( LIBBASE->nf_pci,
125 &FindHook,
126 (struct TagItem *)&Requirements
129 if (LIBBASE->nf_unit)
131 return TRUE;
136 return FALSE;
139 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
141 D(bug("[nforce] Expunge\n"));
143 if (LIBBASE->nf_unit)
145 DeleteUnit(LIBBASE, LIBBASE->nf_unit);
146 LIBBASE->nf_unit = NULL;
149 if (LIBBASE->nf_pciDeviceAttrBase != 0)
150 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
152 LIBBASE->nf_pciDeviceAttrBase = 0;
154 if (LIBBASE->nf_pci != NULL)
155 OOP_DisposeObject(LIBBASE->nf_pci);
157 return TRUE;
160 static const ULONG rx_tags[] = {
161 S2_CopyToBuff,
162 S2_CopyToBuff16
165 static const ULONG tx_tags[] = {
166 S2_CopyFromBuff,
167 S2_CopyFromBuff16,
168 S2_CopyFromBuff32
172 * Open device handles currently only one nforce unit.
174 * It could change in future if only multiple phy support works in forcedeth.c
175 * linux driver.
177 static int GM_UNIQUENAME(Open)
179 LIBBASETYPEPTR LIBBASE,
180 struct IOSana2Req *req,
181 ULONG unitnum,
182 ULONG flags
185 struct TagItem *tags;
186 struct NFUnit *unit = LIBBASE->nf_unit;
187 struct Opener *opener;
188 BYTE error=0;
189 int i;
191 D(bug("[nforce] OpenDevice\n"));
193 LIBBASE->nf_Device.dd_Library.lib_OpenCnt++;
194 LIBBASE->nf_Device.dd_Library.lib_Flags &= ~LIBF_DELEXP;
196 req->ios2_Req.io_Unit = NULL;
197 tags = req->ios2_BufferManagement;
199 req->ios2_BufferManagement = NULL;
201 /* Check request size */
203 if(req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
204 error = IOERR_OPENFAIL;
206 /* Get the requested unit */
207 if((error == 0) && (unitnum == 0))
209 req->ios2_Req.io_Unit = (APTR)unit;
211 else error = IOERR_OPENFAIL;
213 /* Handle device sharing */
215 if(error == 0)
217 if(unit->open_count != 0 && ((unit->flags & IFF_SHARED) == 0 ||
218 (flags & SANA2OPF_MINE) != 0))
219 error = IOERR_UNITBUSY;
220 unit->open_count++;
223 if(error == 0)
225 if((flags & SANA2OPF_MINE) == 0)
226 unit->flags |= IFF_SHARED;
227 else if((flags & SANA2OPF_PROM) != 0)
228 unit->flags |= IFF_PROMISC;
230 /* Set up buffer-management structure and get hooks */
231 opener = AllocVec(sizeof(struct Opener), MEMF_PUBLIC | MEMF_CLEAR);
232 req->ios2_BufferManagement = (APTR)opener;
234 if(opener == NULL)
235 error = IOERR_OPENFAIL;
238 if(error == 0)
240 NEWLIST(&opener->read_port.mp_MsgList);
241 opener->read_port.mp_Flags = PA_IGNORE;
242 NEWLIST((APTR)&opener->initial_stats);
244 for(i = 0; i < 2; i++)
245 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
246 for(i = 0; i < 3; i++)
247 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
249 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
251 Disable();
252 AddTail((APTR)&unit->nu_Openers, (APTR)opener);
253 Enable();
256 if (error != 0)
257 CloseDevice((struct IORequest *)req);
258 else
259 unit->start(unit);
261 req->ios2_Req.io_Error = error;
263 return (error !=0) ? FALSE : TRUE;
266 static int GM_UNIQUENAME(Close)
268 LIBBASETYPEPTR LIBBASE,
269 struct IOSana2Req *req
272 struct NFUnit *unit = LIBBASE->nf_unit;
273 struct Opener *opener;
275 D(bug("[nforce] CloseDevice\n"));
277 unit->stop(unit);
279 opener = (APTR)req->ios2_BufferManagement;
280 if (opener != NULL)
282 Disable();
283 Remove((struct Node *)opener);
284 Enable();
285 FreeVec(opener);
288 return TRUE;
292 ADD2INITLIB(GM_UNIQUENAME(Init),0)
293 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge),0)
294 ADD2OPENDEV(GM_UNIQUENAME(Open),0)
295 ADD2CLOSEDEV(GM_UNIQUENAME(Close),0)
297 AROS_LH1(void, beginio,
298 AROS_LHA(struct IOSana2Req *, req, A1),
299 LIBBASETYPEPTR, LIBBASE, 5, Nforce)
301 AROS_LIBFUNC_INIT
302 struct NFUnit *dev;
304 D(bug("[nforce] BeginIO\n"));
306 req->ios2_Req.io_Error = 0;
307 dev = (APTR)req->ios2_Req.io_Unit;
309 if (AttemptSemaphore(&dev->unit_lock))
311 handle_request(LIBBASE, req);
313 else
315 req->ios2_Req.io_Flags &= ~IOF_QUICK;
316 PutMsg(dev->nu_input_port, (struct Message *)req);
319 AROS_LIBFUNC_EXIT
322 AROS_LH1(LONG, abortio,
323 AROS_LHA(struct IOSana2Req *, req, A1),
324 LIBBASETYPEPTR, LIBBASE, 6, Nforce)
326 AROS_LIBFUNC_INIT
328 D(bug("[nforce] AbortIO\n"));
330 Disable();
331 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
332 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
334 Remove((struct Node *)req);
335 req->ios2_Req.io_Error = IOERR_ABORTED;
336 req->ios2_WireError = S2WERR_GENERIC_ERROR;
337 ReplyMsg((struct Message *)req);
339 Enable();
341 return 0;
343 AROS_LIBFUNC_EXIT