3 #include <asm/amcc440.h>
5 #include <aros/debug.h>
6 #include <exec/types.h>
7 #include <exec/resident.h>
9 #include <exec/errors.h>
10 #include <exec/lists.h>
12 #include <aros/libcall.h>
13 #include <aros/symbolsets.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>
26 #include <proto/oop.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #include <proto/kernel.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"));
45 if (FindTask(EMAC_TASK1_NAME
) != NULL
)
47 D(bug("[EMAC ] Device already up and running.\n"));
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);
70 static const ULONG rx_tags
[] = {
75 static const ULONG tx_tags
[] = {
82 * Open device handles currently only one pcnet32 unit.
84 static int GM_UNIQUENAME(Open
)
86 LIBBASETYPEPTR LIBBASE
,
87 struct IOSana2Req
* req
,
93 struct EMACUnit
*unit
= NULL
;
94 struct Opener
*opener
;
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
;
116 unit
= (struct EMACUnit
*)(req
->ios2_Req
.io_Unit
= (struct Unit
*)LIBBASE
->emb_Units
[unitnum
]);
119 /* Handle device sharing */
122 if(unit
->eu_OpenCount
!= 0 && ((unit
->eu_Flags
& IFF_SHARED
) == 0 ||
123 (flags
& SANA2OPF_MINE
) != 0))
124 error
= IOERR_UNITBUSY
;
126 unit
->eu_OpenCount
++;
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
;
141 error
= IOERR_OPENFAIL
;
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
);
158 AddTail((APTR
)&unit
->eu_Openers
, (APTR
)opener
);
163 CloseDevice((struct IORequest
*)req
);
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
;
182 D(bug("[EMAC%d] CloseDevice\n", unit
->eu_UnitNum
));
186 opener
= (APTR
)req
->ios2_BufferManagement
;
190 Remove((struct Node
*)opener
);
192 FreeVecPooled(LIBBASE
->emb_Pool
, opener
);
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
)
209 struct EMACUnit
*unit
;
211 req
->ios2_Req
.io_Error
= 0;
212 unit
= (APTR
)req
->ios2_Req
.io_Unit
;
216 D(bug("[EMAC%d] BeginIO\n", unit
->eu_UnitNum
));
218 if (AttemptSemaphore(&unit
->eu_Lock
))
220 handle_request(LIBBASE
, req
);
224 req
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
225 PutMsg(unit
->eu_InputPort
, (struct Message
*)req
);
232 AROS_LH1(LONG
, abortio
,
233 AROS_LHA(struct IOSana2Req
*, req
, A1
),
234 LIBBASETYPEPTR
, LIBBASE
, 6, EMAC
)
238 struct EMACUnit
*unit
;
239 unit
= (APTR
)req
->ios2_Req
.io_Unit
;
243 D(bug("[EMAC%d] AbortIO\n", unit
->eu_UnitNum
));
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
);