Allow multiple volumes with the same name if their creation dates differ.
[AROS.git] / workbench / devs / networks / sis900 / sis900_init.c
bloba4c3ddff72a6d3750cb3f3be6081e919b9ca2fe5
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 <stdio.h>
48 #include "sis900.h"
49 #include "unit.h"
50 #include LC_LIBDEFS_FILE
52 AROS_UFH3(void, PCI_Enumerator,
53 AROS_UFHA(struct Hook *, hook, A0),
54 AROS_UFHA(OOP_Object *, pciDevice, A2),
55 AROS_UFHA(APTR, message, A1))
57 AROS_USERFUNC_INIT
59 D(bug("[SiS900] PCI_Enumerator()\n"));
61 LIBBASETYPEPTR LIBBASE = (LIBBASETYPEPTR)hook->h_Data;
63 BOOL FoundCompatNIC = FALSE;
64 IPTR DeviceID, VendorID, RevisionID;
65 char *CardName, *CardChipName;
66 struct SiS900Unit *unit;
68 OOP_GetAttr(pciDevice, aHidd_PCIDevice_VendorID, &VendorID);
69 OOP_GetAttr(pciDevice, aHidd_PCIDevice_ProductID, &DeviceID);
70 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RevisionID, &RevisionID);
72 if ((DeviceID == 0x0900))
74 FoundCompatNIC = TRUE;
75 CardName = "SiS 900 PCI Fast Ethernet";
76 CardChipName = "SiS900";
78 else if ((DeviceID == 0x7016))
80 FoundCompatNIC = TRUE;
81 CardName = "SiS 7016 PCI Fast Ethernet";
82 CardChipName = "SiS7016";
85 if (FoundCompatNIC)
87 D(bug("[SiS900] PCI_Enumerator: Found %s NIC, PCI_ID %04x:%04x Rev:%d\n", CardName, VendorID, DeviceID, RevisionID));
89 if ((unit = CreateUnit(LIBBASE, pciDevice, CardName, CardChipName)))
91 AddTail(&LIBBASE->sis900b_Units, (struct Node *)&unit->sis900u_Node);
93 else
95 D(bug("[SIS900] PCI_Enumerator: Failed to create unit!\n"));
96 return;
99 D(bug("[%s] PCI_Enumerator: %s NIC I/O MEM @ %08x\n", unit->sis900u_name, unit->sis900u_rtl_chipname, unit->sis900u_BaseMem));
102 AROS_USERFUNC_EXIT
105 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
107 D(bug("[SiS900] Init()\n"));
109 UBYTE tmpbuff[100];
110 sprintf((char *)tmpbuff, SiS900_TASK_NAME, "sis900.0");
112 if (FindTask(tmpbuff) != NULL)
114 D(bug("[SiS900] device already up and running.\n"));
115 return FALSE;
118 NEWLIST(&LIBBASE->sis900b_Units);
120 LIBBASE->sis900b_PCIDeviceAttrBase = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
122 if (LIBBASE->sis900b_PCIDeviceAttrBase != 0)
124 D(bug("[SiS900] HiddPCIDeviceAttrBase @ %p\n", LIBBASE->sis900b_PCIDeviceAttrBase));
126 LIBBASE->sis900b_PCI = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
128 if (LIBBASE->sis900b_PCI)
130 D(bug("[SiS900] PCI Subsystem HIDD object @ %p\n", LIBBASE->sis900b_PCI));
132 struct Hook FindHook = {
133 h_Entry: (IPTR (*)())PCI_Enumerator,
134 h_Data: LIBBASE,
137 struct TagItem Requirements[] = {
138 { tHidd_PCI_VendorID, 0x1039 },
139 { TAG_DONE, 0UL }
142 HIDD_PCI_EnumDevices(LIBBASE->sis900b_PCI,
143 &FindHook,
144 (struct TagItem *)&Requirements
147 if (!(IsListEmpty(&LIBBASE->sis900b_Units)))
149 return TRUE;
154 return FALSE;
157 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
159 D(bug("[SiS900] Expunge()\n"));
161 struct SiS900Unit *unit_current, *unit_tmp;
163 if (!(IsListEmpty(&LIBBASE->sis900b_Units)))
165 ForeachNodeSafe(&LIBBASE->sis900b_Units, unit_current, unit_tmp)
167 DeleteUnit(LIBBASE, unit_current);
171 if (LIBBASE->sis900b_PCIDeviceAttrBase != 0)
172 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
174 LIBBASE->sis900b_PCIDeviceAttrBase = 0;
176 if (LIBBASE->sis900b_PCI != NULL)
177 OOP_DisposeObject(LIBBASE->sis900b_PCI);
179 return TRUE;
182 static const ULONG rx_tags[] = {
183 S2_CopyToBuff,
184 S2_CopyToBuff16
187 static const ULONG tx_tags[] = {
188 S2_CopyFromBuff,
189 S2_CopyFromBuff16,
190 S2_CopyFromBuff32
194 * Open device handles currently only one sis900 unit.
196 static int GM_UNIQUENAME(Open)
198 LIBBASETYPEPTR LIBBASE,
199 struct IOSana2Req* req,
200 ULONG unitnum,
201 ULONG flags
204 struct TagItem *tags;
205 struct SiS900Unit *unit = NULL, *unit_current;
206 struct Opener *opener;
207 BYTE error=0;
208 int i;
210 if (!(IsListEmpty(&LIBBASE->sis900b_Units)))
212 ForeachNode(&LIBBASE->sis900b_Units, unit_current)
214 if (unit_current->sis900u_UnitNum == unitnum)
215 unit = unit_current;
219 D(bug("[SiS900] OpenDevice(%d)\n", unitnum));
221 if (unit != NULL)
223 D(bug("[SiS900] OpenDevice: Unit %d @ %p\n", unitnum, unit));
224 req->ios2_Req.io_Unit = NULL;
225 tags = req->ios2_BufferManagement;
227 req->ios2_BufferManagement = NULL;
229 /* Check request size */
230 if (req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
231 error = IOERR_OPENFAIL;
233 /* Get the requested unit */
234 if (error == 0)
236 req->ios2_Req.io_Unit = (APTR)unit;
239 /* Handle device sharing */
240 if (error == 0)
242 if(unit->sis900u_open_count != 0 && ((unit->sis900u_ifflags & IFF_SHARED) == 0 ||
243 (flags & SANA2OPF_MINE) != 0))
244 error = IOERR_UNITBUSY;
245 unit->sis900u_open_count++;
248 if (error == 0)
250 if((flags & SANA2OPF_MINE) == 0)
251 unit->sis900u_ifflags |= IFF_SHARED;
252 else if((flags & SANA2OPF_PROM) != 0)
253 unit->sis900u_ifflags |= IFF_PROMISC;
255 /* Set up buffer-management structure and get hooks */
256 opener = AllocVec(sizeof(struct Opener), MEMF_PUBLIC | MEMF_CLEAR);
257 req->ios2_BufferManagement = (APTR)opener;
259 if(opener == NULL)
260 error = IOERR_OPENFAIL;
263 if (error == 0)
265 NEWLIST(&opener->read_port.mp_MsgList);
266 opener->read_port.mp_Flags = PA_IGNORE;
267 NEWLIST((APTR)&opener->initial_stats);
269 for(i = 0; i < 2; i++)
270 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
271 for(i = 0; i < 3; i++)
272 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
274 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
276 Disable();
277 AddTail((APTR)&unit->sis900u_Openers, (APTR)opener);
278 Enable();
281 if (error != 0)
282 CloseDevice((struct IORequest *)req);
283 else
284 sis900func_open(unit);
287 else
289 D(bug("[SiS900] OpenDevice: Invalid Unit! (unitno = %d)\n", unitnum));
290 error = IOERR_OPENFAIL;
293 req->ios2_Req.io_Error = error;
295 return (error !=0) ? FALSE : TRUE;
298 static int GM_UNIQUENAME(Close)
300 LIBBASETYPEPTR LIBBASE,
301 struct IOSana2Req* req
304 struct SiS900Unit *unit = (struct SiS900Unit *)req->ios2_Req.io_Unit;
305 struct Opener *opener;
307 D(bug("[SiS900] CloseDevice(unit @ %p, unitno %d)\n", unit, unit->sis900u_UnitNum));
309 sis900func_close(unit);
311 opener = (APTR)req->ios2_BufferManagement;
312 if (opener != NULL)
314 Disable();
315 Remove((struct Node *)opener);
316 Enable();
317 FreeVec(opener);
320 return TRUE;
324 ADD2INITLIB(GM_UNIQUENAME(Init),0)
325 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge),0)
326 ADD2OPENDEV(GM_UNIQUENAME(Open),0)
327 ADD2CLOSEDEV(GM_UNIQUENAME(Close),0)
329 AROS_LH1(void, beginio,
330 AROS_LHA(struct IOSana2Req *, req, A1),
331 LIBBASETYPEPTR, LIBBASE, 5, SiS900Dev)
333 AROS_LIBFUNC_INIT
334 struct SiS900Unit *unit;
336 D(bug("[SiS900] BeginIO()\n"));
338 req->ios2_Req.io_Error = 0;
339 unit = (APTR)req->ios2_Req.io_Unit;
341 if (AttemptSemaphore(&unit->sis900u_unit_lock))
343 handle_request(LIBBASE, req);
345 else
347 req->ios2_Req.io_Flags &= ~IOF_QUICK;
348 PutMsg(unit->sis900u_input_port, (struct Message *)req);
351 AROS_LIBFUNC_EXIT
354 AROS_LH1(LONG, abortio,
355 AROS_LHA(struct IOSana2Req *, req, A1),
356 LIBBASETYPEPTR, LIBBASE, 6, SiS900Dev)
358 AROS_LIBFUNC_INIT
360 D(bug("[SiS900] AbortIO()\n"));
362 Disable();
363 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
364 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
366 Remove((struct Node *)req);
367 req->ios2_Req.io_Error = IOERR_ABORTED;
368 req->ios2_WireError = S2WERR_GENERIC_ERROR;
369 ReplyMsg((struct Message *)req);
371 Enable();
373 return 0;
375 AROS_LIBFUNC_EXIT