AHI: build Alsa driver when alsa-bridge link lib is detected
[AROS.git] / workbench / devs / networks / emac / emac_init.c
blob139e51e58d748a3f11659b85e810e6616bc44de2
1 #define DEBUG 1
3 #include <asm/amcc440.h>
5 #include <aros/debug.h>
6 #include <exec/types.h>
7 #include <exec/resident.h>
8 #include <exec/io.h>
9 #include <exec/errors.h>
10 #include <exec/lists.h>
12 #include <aros/libcall.h>
13 #include <aros/symbolsets.h>
15 #include <oop/oop.h>
17 #include <devices/sana2.h>
18 #include <devices/sana2specialstats.h>
20 #include <utility/utility.h>
21 #include <utility/tagitem.h>
22 #include <utility/hooks.h>
24 #include <hidd/pci.h>
26 #include <proto/oop.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #include <proto/kernel.h>
31 #include "emac.h"
32 #include LC_LIBDEFS_FILE
35 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
37 D(bug("[EMAC ] Init()\n"));
39 if (!FindResident("pci-amcc440.hidd"))
41 D(bug("[EMAC ] Emac driver may run only on AMCC440 CPU's\n"));
42 return FALSE;
45 if (FindTask(EMAC_TASK1_NAME) != NULL)
47 D(bug("[EMAC ] Device already up and running.\n"));
48 return FALSE;
51 LIBBASE->emb_Sana2Info.HardwareType = S2WireType_Ethernet;
52 LIBBASE->emb_Sana2Info.MTU = ETH_MTU;
53 LIBBASE->emb_Sana2Info.AddrFieldSize = 8 * ETH_ADDRESSSIZE;
55 LIBBASE->emb_Pool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
57 if (LIBBASE->emb_Pool != NULL)
59 EMAC_MAL_Init(LIBBASE);
61 LIBBASE->emb_Units[0] = CreateUnit(LIBBASE, 0);
62 LIBBASE->emb_Units[1] = CreateUnit(LIBBASE, 1);
64 return TRUE;
67 return FALSE;
70 static const ULONG rx_tags[] = {
71 S2_CopyToBuff,
72 S2_CopyToBuff16
75 static const ULONG tx_tags[] = {
76 S2_CopyFromBuff,
77 S2_CopyFromBuff16,
78 S2_CopyFromBuff32
82 * Open device handles currently only one pcnet32 unit.
84 static int GM_UNIQUENAME(Open)
86 LIBBASETYPEPTR LIBBASE,
87 struct IOSana2Req* req,
88 ULONG unitnum,
89 ULONG flags
92 struct TagItem *tags;
93 struct EMACUnit *unit = NULL;
94 struct Opener *opener;
95 BYTE error=0;
96 int i;
98 D(bug("[EMAC ] OpenDevice(%d)\n", unitnum));
100 req->ios2_Req.io_Unit = NULL;
101 tags = req->ios2_BufferManagement;
103 req->ios2_BufferManagement = NULL;
105 /* Check request size */
107 if(req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
108 error = IOERR_OPENFAIL;
110 if ((error != 0) || (unitnum > 1))
112 error = IOERR_OPENFAIL;
114 else
116 unit = (struct EMACUnit *)(req->ios2_Req.io_Unit = (struct Unit *)LIBBASE->emb_Units[unitnum]);
119 /* Handle device sharing */
120 if(error == 0)
122 if(unit->eu_OpenCount != 0 && ((unit->eu_Flags & IFF_SHARED) == 0 ||
123 (flags & SANA2OPF_MINE) != 0))
124 error = IOERR_UNITBUSY;
125 else
126 unit->eu_OpenCount++;
129 if(error == 0)
131 if((flags & SANA2OPF_MINE) == 0)
132 unit->eu_Flags |= IFF_SHARED;
133 else if((flags & SANA2OPF_PROM) != 0)
134 unit->eu_Flags |= IFF_PROMISC;
136 /* Set up buffer-management structure and get hooks */
137 opener = AllocVecPooled(LIBBASE->emb_Pool, sizeof(struct Opener));
138 req->ios2_BufferManagement = (APTR)opener;
140 if(opener == NULL)
141 error = IOERR_OPENFAIL;
144 if(error == 0)
146 NEWLIST(&opener->read_port.mp_MsgList);
147 opener->read_port.mp_Flags = PA_IGNORE;
148 NEWLIST((APTR)&opener->initial_stats);
150 for(i = 0; i < 2; i++)
151 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
152 for(i = 0; i < 3; i++)
153 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
155 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
157 Disable();
158 AddTail((APTR)&unit->eu_Openers, (APTR)opener);
159 Enable();
162 if (error != 0)
163 CloseDevice((struct IORequest *)req);
164 else
165 unit->start(unit);
167 req->ios2_Req.io_Error = error;
168 return (error !=0) ? FALSE : TRUE;
171 static int GM_UNIQUENAME(Close)
173 LIBBASETYPEPTR LIBBASE,
174 struct IOSana2Req* req
177 struct EMACUnit *unit = (struct EMACUnit *)req->ios2_Req.io_Unit;
178 struct Opener *opener;
180 if (unit)
182 D(bug("[EMAC%d] CloseDevice\n", unit->eu_UnitNum));
184 unit->stop(unit);
186 opener = (APTR)req->ios2_BufferManagement;
187 if (opener != NULL)
189 Disable();
190 Remove((struct Node *)opener);
191 Enable();
192 FreeVecPooled(LIBBASE->emb_Pool, opener);
196 return TRUE;
199 ADD2INITLIB(GM_UNIQUENAME(Init),0)
200 ADD2OPENDEV(GM_UNIQUENAME(Open),0)
201 ADD2CLOSEDEV(GM_UNIQUENAME(Close),0)
203 AROS_LH1(void, beginio,
204 AROS_LHA(struct IOSana2Req *, req, A1),
205 LIBBASETYPEPTR, LIBBASE, 5, EMAC)
207 AROS_LIBFUNC_INIT
209 struct EMACUnit *unit;
211 req->ios2_Req.io_Error = 0;
212 unit = (APTR)req->ios2_Req.io_Unit;
214 if (unit)
216 D(bug("[EMAC%d] BeginIO\n", unit->eu_UnitNum));
218 if (AttemptSemaphore(&unit->eu_Lock))
220 handle_request(LIBBASE, req);
222 else
224 req->ios2_Req.io_Flags &= ~IOF_QUICK;
225 PutMsg(unit->eu_InputPort, (struct Message *)req);
229 AROS_LIBFUNC_EXIT
232 AROS_LH1(LONG, abortio,
233 AROS_LHA(struct IOSana2Req *, req, A1),
234 LIBBASETYPEPTR, LIBBASE, 6, EMAC)
236 AROS_LIBFUNC_INIT
238 struct EMACUnit *unit;
239 unit = (APTR)req->ios2_Req.io_Unit;
241 if (unit)
243 D(bug("[EMAC%d] AbortIO\n", unit->eu_UnitNum));
245 Disable();
246 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
247 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
249 Remove((struct Node *)req);
250 req->ios2_Req.io_Error = IOERR_ABORTED;
251 req->ios2_WireError = S2WERR_GENERIC_ERROR;
252 ReplyMsg((struct Message *)req);
254 Enable();
257 return 0;
259 AROS_LIBFUNC_EXIT