5 #include <exec/types.h>
6 #include <exec/resident.h>
8 #include <exec/ports.h>
9 #include <exec/errors.h>
10 #include <exec/lists.h>
13 #include <aros/libcall.h>
14 #include <aros/symbolsets.h>
16 #include <devices/sana2.h>
17 #include <devices/sana2specialstats.h>
18 #include <devices/newstyle.h>
19 #include <devices/timer.h>
20 #include <devices/serial.h>
21 #include <devices/timer.h>
23 #include <utility/utility.h>
24 #include <utility/tagitem.h>
25 #include <utility/hooks.h>
27 #include <proto/exec.h>
28 #include <proto/dos.h>
29 #include <proto/oop.h>
30 #include <proto/timer.h>
31 #include <proto/utility.h>
42 #include "device_protos.h"
45 VOID
PerformIO(LIBBASETYPEPTR LIBBASE
,struct IOSana2Req
*ios2
){
47 // D(bug("PerformIO Command-->"));
49 ios2
->ios2_Req
.io_Error
= 0;
51 switch (ios2
->ios2_Req
.io_Command
){
53 ReadPacket(LIBBASE
,ios2
);
57 WritePacket(LIBBASE
,ios2
);
61 DeviceQuery(LIBBASE
,ios2
);
64 case S2_GETSTATIONADDRESS
:
65 GetStationAddress(LIBBASE
,ios2
);
69 WritePacket(LIBBASE
,ios2
);
77 Offline(LIBBASE
,ios2
);
80 case S2_CONFIGINTERFACE
:
81 ConfigInterface(LIBBASE
,ios2
);
85 D(bug("Unknown Command %d\n",ios2
->ios2_Req
.io_Command
));
86 ios2
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
87 ios2
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
92 // case S2_UNTRACKTYPE:
93 // case S2_GETTYPESTATS:
94 // case S2_GETGLOBALSTATS:
96 // case S2_READORPHAN:
97 // case S2_ADDMULTICASTADDRESS:
98 // case S2_DELMULTICASTADDRESS:
100 // case S2_GETSPECIALSTATS:
105 VOID
TermIO(LIBBASETYPEPTR LIBBASE
,struct IOSana2Req
*ios2
){
106 if(!(ios2
->ios2_Req
.io_Flags
& IOF_QUICK
)){
107 ReplyMsg((struct Message
*)ios2
);
112 VOID
ConfigInterface(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
113 D(bug("ConfigInterface\n"));
114 //CopyMem(&sdu->sdu_StAddr,&ios2->ios2_SrcAddr,4);
115 //ios2->ios2_Req.io_Error = S2ERR_BAD_STATE;
116 //ios2->ios2_WireError = S2WERR_IS_CONFIGURED;
117 TermIO(LIBBASE
,ios2
);
121 VOID
GetStationAddress(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
122 D(bug("GetStationAddress\n"));
123 memset(ios2
->ios2_DstAddr
, 0, SANA2_MAX_ADDR_BYTES
);
124 memset(ios2
->ios2_SrcAddr
, 0, SANA2_MAX_ADDR_BYTES
);
125 TermIO(LIBBASE
,ios2
);
129 VOID
DeviceQuery(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
130 struct Sana2DeviceQuery
*sdq
;
131 D(bug("DeviceQuery\n"));
132 sdq
= (struct Sana2DeviceQuery
*)ios2
->ios2_StatData
;
134 sdq
->DevQueryFormat
= 0;
135 sdq
->DeviceLevel
= 0;
136 sdq
->AddrFieldSize
= 32;
139 sdq
->HardwareType
= S2WireType_PPP
;
140 sdq
->SizeSupplied
= sizeof(*sdq
);
142 TermIO(LIBBASE
,ios2
);
146 VOID
WritePacket(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
147 // D(bug("WritePacket\n"));
148 /* Make sure that we are online. */
149 if( LIBBASE
->device_up
&& Phase() == PPP_PHASE_NETWORK
&& LIBBASE
->ser
){
150 /* Make sure it's a legal length. */
151 if(ios2
->ios2_DataLength
<= PPP_MTU
){
152 /* See if our serial CMD_WRITE command is busy. If it's not, send
153 the IO request to SendPacket. */
154 if(CheckIO((struct IORequest
*)LIBBASE
->ser
->SerTx
)){
155 WaitIO((struct IORequest
*)LIBBASE
->ser
->SerTx
);
156 SendPacket(LIBBASE
, ios2
);
158 /* We'll have to queue the packet for later...*/
159 ios2
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
160 ObtainSemaphore(&LIBBASE
->sdu_ListLock
);
161 AddTail((struct List
*)&LIBBASE
->Tx_List
,(struct Node
*)ios2
);
162 ReleaseSemaphore(&LIBBASE
->sdu_ListLock
);
166 /* Sorry, the packet is too long! */
167 D(bug("WritePacket TOO LONG !\n"));
168 ios2
->ios2_Req
.io_Error
= S2ERR_MTU_EXCEEDED
;
169 ios2
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
170 TermIO(LIBBASE
,ios2
);
171 // DoEvent(LIBBASE,sdu,S2EVENT_TX);
175 /* Sorry, we're offline */
176 ios2
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
177 ios2
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
178 TermIO(LIBBASE
,ios2
);
183 VOID
SendPacket( LIBBASETYPEPTR LIBBASE
,struct IOSana2Req
*ios2
){
185 // D(bug("SendPacket lenght %d\n",ios2->ios2_DataLength));
187 if( ( Phase() == PPP_PHASE_NETWORK
) && LIBBASE
->device_up
&& LIBBASE
->ser
){
189 if( LIBBASE
->CopyFromBuffer( LIBBASE
->ser
->TxBuff
, ios2
->ios2_Data
, ios2
->ios2_DataLength
) ){
190 send_IP_packet( LIBBASE
->ser
->TxBuff
, ios2
->ios2_DataLength
);
191 LIBBASE
->BytesOut
+= ios2
->ios2_DataLength
;
193 bug( "SendPacket CopyFromBuffer FAIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
194 ios2
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
195 ios2
->ios2_WireError
= S2WERR_BUFF_ERROR
;
199 ios2
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
200 ios2
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
203 TermIO(LIBBASE
,ios2
);
208 VOID
ReadPacket(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
210 // D(bug("ReadPacket type %d ",ios2->ios2_PacketType));
212 if( ( Phase() == PPP_PHASE_NETWORK
) && LIBBASE
->device_up
&& LIBBASE
->ser
){
213 // D(bug("Add to list...\n"));
214 ObtainSemaphore(&LIBBASE
->sdu_ListLock
);
215 AddTail((struct List
*)&LIBBASE
->Rx_List
,(struct Node
*)ios2
);
216 ReleaseSemaphore(&LIBBASE
->sdu_ListLock
);
218 // D(bug("Sorry,We're offline..\n"));
219 ios2
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
220 ios2
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
221 TermIO(LIBBASE
,ios2
);
227 VOID
Online(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
229 LIBBASE
->device_up
= TRUE
;
230 TermIO(LIBBASE
,ios2
);
234 VOID
Offline(LIBBASETYPEPTR LIBBASE
, struct IOSana2Req
*ios2
){
237 Set_phase( PPP_PHASE_TERMINATE
);
238 LIBBASE
->device_up
= FALSE
;
239 TermIO(LIBBASE
,ios2
);
245 VOID
CMD_WRITE_Ready(LIBBASETYPEPTR LIBBASE
){
246 struct IOSana2Req
*ios2
;
248 /* See if we have any pending CMD_WRITE requests. */
249 ObtainSemaphore(&LIBBASE
->sdu_ListLock
);
250 ios2
= (struct IOSana2Req
*)RemHead((struct List
*)&LIBBASE
->Tx_List
);
251 ReleaseSemaphore(&LIBBASE
->sdu_ListLock
);
253 if(ios2
) SendPacket( LIBBASE
, ios2
);
258 VOID
CMD_READ_Ready(LIBBASETYPEPTR LIBBASE
, struct IOExtSer
*ioSer
){
262 ptr
= LIBBASE
->ser
->RxBuff
;
263 length
= ioSer
->IOSer
.io_Actual
;
264 bytes_received( ptr
,length
);
265 LIBBASE
->BytesIn
+= length
;
266 QueueSerRequest( LIBBASE
->ser
, PPP_MAXBUFF
);
271 // ppp.c call this if IP packet is received.
273 VOID
Incoming_IP_Packet(LIBBASETYPEPTR LIBBASE
, BYTE
*data
, ULONG length
){
274 struct IOSana2Req
*ios2
;
276 // bug("GotPacket %d bytes \n",length);
278 if(length
){ // ignore zero-length packets.
280 ObtainSemaphore(&LIBBASE
->sdu_ListLock
);
281 ios2
= (struct IOSana2Req
*)RemHead((struct List
*)&LIBBASE
->Rx_List
);
282 ReleaseSemaphore(&LIBBASE
->sdu_ListLock
);
285 if( LIBBASE
->CopyToBuffer(ios2
->ios2_Data
, data
,length
)){
286 // bug("CopyToBuffer OK\n");
287 ios2
->ios2_DataLength
= length
;
289 bug("CopyToBuffer FAIL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
290 ios2
->ios2_DataLength
= 0;
291 ios2
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
292 ios2
->ios2_WireError
= S2WERR_BUFF_ERROR
;
294 TermIO(LIBBASE
,ios2
);
296 bug( "Orphan Packet Receivet !!! %d bytes\n" , length
);