Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / etherlink3 / request.c
blobcffa86711f8f757a3fe7b78c3f55db04d283571a
1 /*
3 Copyright (C) 2001-2005 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 MA 02111-1307, USA.
22 #include <string.h>
24 #include <exec/types.h>
25 #include <exec/errors.h>
26 #include <exec/initializers.h>
27 #include <devices/newstyle.h>
29 #include <proto/exec.h>
30 #include <proto/utility.h>
32 #include "device.h"
34 #include "request_protos.h"
35 #include "unit_protos.h"
38 #define KNOWN_EVENTS \
39 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
40 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
43 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base);
44 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base);
45 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base);
46 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base);
47 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
48 struct DevBase *base);
49 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
50 struct DevBase *base);
51 static BOOL CmdConfigInterface(struct IOSana2Req *request,
52 struct DevBase *base);
53 static BOOL CmdBroadcast(struct IOSana2Req *request,
54 struct DevBase *base);
55 static BOOL CmdTrackType(struct IOSana2Req *request,
56 struct DevBase *base);
57 static BOOL CmdUntrackType(struct IOSana2Req *request,
58 struct DevBase *base);
59 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
60 struct DevBase *base);
61 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
62 struct DevBase *base);
63 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
64 struct DevBase *base);
65 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base);
66 static BOOL CmdReadOrphan(struct IOSana2Req *request,
67 struct DevBase *base);
68 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base);
69 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base);
70 static BOOL CmdDeviceQuery(struct IOStdReq *request,
71 struct DevBase *base);
72 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
73 struct DevBase *base);
74 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
75 struct DevBase *base);
78 static const UWORD supported_commands[] =
80 CMD_READ,
81 CMD_WRITE,
82 CMD_FLUSH,
83 S2_DEVICEQUERY,
84 S2_GETSTATIONADDRESS,
85 S2_CONFIGINTERFACE,
86 S2_ADDMULTICASTADDRESS,
87 S2_DELMULTICASTADDRESS,
88 S2_MULTICAST,
89 S2_BROADCAST,
90 S2_TRACKTYPE,
91 S2_UNTRACKTYPE,
92 S2_GETTYPESTATS,
93 S2_GETSPECIALSTATS,
94 S2_GETGLOBALSTATS,
95 S2_ONEVENT,
96 S2_READORPHAN,
97 S2_ONLINE,
98 S2_OFFLINE,
99 NSCMD_DEVICEQUERY,
100 S2_ADDMULTICASTADDRESSES,
101 S2_DELMULTICASTADDRESSES,
106 static const struct Sana2DeviceQuery sana2_info =
112 ETH_ADDRESSSIZE * 8,
113 ETH_MTU,
115 S2WireType_Ethernet
120 const TEXT badmulticast_name[] = "Bad multicasts";
121 const TEXT retries_name[] = "Retries";
122 const TEXT fifo_underruns_name[] = "Underruns";
125 static const TEXT *const special_stat_names[] =
127 badmulticast_name,
128 retries_name,
129 fifo_underruns_name
134 /****i* etherlink3.device/ServiceRequest ***********************************
136 * NAME
137 * ServiceRequest -- Attempt to service a device request.
139 * SYNOPSIS
140 * ServiceRequest(request)
142 * VOID ServiceRequest(struct IORequest *);
144 * FUNCTION
145 * Attempts to carry out a request. The relevant unit's semaphore must
146 * be obtained before calling this function. This function releases the
147 * semaphore before returning.
149 ****************************************************************************
153 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
155 BOOL complete;
157 switch(request->ios2_Req.io_Command)
159 case CMD_READ:
160 complete = CmdRead(request, base);
161 break;
162 case CMD_WRITE:
163 complete = CmdWrite(request, base);
164 break;
165 case CMD_FLUSH:
166 complete = CmdFlush((APTR)request, base);
167 break;
168 case S2_DEVICEQUERY:
169 complete = CmdS2DeviceQuery((APTR)request, base);
170 break;
171 case S2_GETSTATIONADDRESS:
172 complete = CmdGetStationAddress((APTR)request, base);
173 break;
174 case S2_CONFIGINTERFACE:
175 complete = CmdConfigInterface((APTR)request, base);
176 break;
177 case S2_ADDMULTICASTADDRESS:
178 complete = CmdAddMulticastAddresses((APTR)request, base);
179 break;
180 case S2_DELMULTICASTADDRESS:
181 complete = CmdDelMulticastAddresses((APTR)request, base);
182 break;
183 case S2_MULTICAST:
184 complete = CmdWrite((APTR)request, base);
185 break;
186 case S2_BROADCAST:
187 complete = CmdBroadcast((APTR)request, base);
188 break;
189 case S2_TRACKTYPE:
190 complete = CmdTrackType((APTR)request, base);
191 break;
192 case S2_UNTRACKTYPE:
193 complete = CmdUntrackType((APTR)request, base);
194 break;
195 case S2_GETTYPESTATS:
196 complete = CmdGetTypeStats((APTR)request, base);
197 break;
198 case S2_GETSPECIALSTATS:
199 complete = CmdGetSpecialStats((APTR)request, base);
200 break;
201 case S2_GETGLOBALSTATS:
202 complete = CmdGetGlobalStats((APTR)request, base);
203 break;
204 case S2_ONEVENT:
205 complete = CmdOnEvent((APTR)request, base);
206 break;
207 case S2_READORPHAN:
208 complete = CmdReadOrphan((APTR)request, base);
209 break;
210 case S2_ONLINE:
211 complete = CmdOnline((APTR)request, base);
212 break;
213 case S2_OFFLINE:
214 complete = CmdOffline((APTR)request, base);
215 break;
216 case NSCMD_DEVICEQUERY:
217 complete = CmdDeviceQuery((APTR)request, base);
218 break;
219 case S2_ADDMULTICASTADDRESSES:
220 complete = CmdAddMulticastAddresses((APTR)request, base);
221 break;
222 case S2_DELMULTICASTADDRESSES:
223 complete = CmdDelMulticastAddresses((APTR)request, base);
224 break;
225 default:
226 complete = CmdInvalid((APTR)request, base);
229 if(complete && (request->ios2_Req.io_Flags & IOF_QUICK) == 0)
230 ReplyMsg((APTR)request);
232 ReleaseSemaphore(&((struct DevUnit *)request->ios2_Req.io_Unit)->
233 access_lock);
234 return;
239 /****i* etherlink3.device/CMD_INVALID **************************************
241 * NAME
242 * CMD_INVALID -- Reject invalid commands.
244 * FUNCTION
246 * INPUTS
247 * None.
249 * RESULTS
250 * io_Error - IOERR_NOCMD.
252 * EXAMPLE
254 * NOTES
256 * BUGS
258 * SEE ALSO
260 ****************************************************************************
264 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
266 request->ios2_Req.io_Error = IOERR_NOCMD;
267 request->ios2_WireError = S2WERR_GENERIC_ERROR;
269 return TRUE;
274 /****** etherlink3.device/CMD_READ *****************************************
276 * NAME
277 * CMD_READ -- Read data.
279 * FUNCTION
281 * INPUTS
282 * io_Flags
283 * ios2_PacketType
284 * ios2_Data
286 * RESULTS
287 * io_Flags
288 * io_Error
289 * ios2_WireError
290 * ios2_SrcAddr
291 * ios2_DstAddr
292 * ios2_DataLength
293 * ios2_Data
295 * EXAMPLE
297 * NOTES
299 * BUGS
301 * SEE ALSO
303 ****************************************************************************
307 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
309 struct DevUnit *unit;
310 struct Opener *opener;
311 BOOL complete = FALSE;
313 unit = (APTR)request->ios2_Req.io_Unit;
315 if((unit->flags & UNITF_ONLINE) != 0)
317 opener = request->ios2_BufferManagement;
318 PutRequest(&opener->read_port, (APTR)request, base);
320 else
322 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
323 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
324 complete = TRUE;
327 /* Return */
329 return complete;
334 /****** etherlink3.device/CMD_WRITE ****************************************
336 * NAME
337 * CMD_WRITE -- Write data.
339 * FUNCTION
341 * INPUTS
342 * io_Flags
343 * ios2_DstAddr
344 * ios2_PacketType
345 * ios2_DataLength
346 * ios2_Data
348 * RESULTS
349 * io_Error
350 * ios2_WireError
352 * EXAMPLE
354 * NOTES
356 * BUGS
358 * SEE ALSO
360 ****************************************************************************
364 /****** etherlink3.device/S2_MULTICAST *************************************
366 * NAME
367 * S2_MULTICAST --
369 * FUNCTION
371 * INPUTS
372 * io_Flags
373 * ios2_DstAddr - multicast address.
374 * ios2_PacketType
375 * ios2_DataLength
376 * ios2_Data
378 * RESULTS
379 * io_Error
380 * ios2_WireError
382 * EXAMPLE
384 * NOTES
386 * BUGS
388 * SEE ALSO
390 ****************************************************************************
394 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
396 struct DevUnit *unit;
397 BYTE error = 0;
398 ULONG wire_error;
399 BOOL complete = FALSE;
401 /* Check request is valid */
403 unit = (APTR)request->ios2_Req.io_Unit;
404 if((unit->flags & UNITF_ONLINE) == 0)
406 error = S2ERR_OUTOFSERVICE;
407 wire_error = S2WERR_UNIT_OFFLINE;
409 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
410 ((request->ios2_DstAddr[0] & 0x1) == 0))
412 error = S2ERR_BAD_ADDRESS;
413 wire_error = S2WERR_BAD_MULTICAST;
416 /* Queue request for sending */
418 if(error == 0)
419 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
420 else
422 request->ios2_Req.io_Error = error;
423 request->ios2_WireError = wire_error;
424 complete = TRUE;
427 /* Return */
429 return complete;
434 /****** etherlink3.device/CMD_FLUSH ****************************************
436 * NAME
437 * CMD_FLUSH -- .
439 * FUNCTION
441 * INPUTS
442 * None.
444 * RESULTS
445 * io_Error
447 * EXAMPLE
449 * NOTES
451 * BUGS
453 * SEE ALSO
455 ****************************************************************************
459 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
461 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
463 return TRUE;
468 /****** etherlink3.device/S2_DEVICEQUERY ***********************************
470 * NAME
471 * S2_DEVICEQUERY -- Query device capabilities.
473 * FUNCTION
475 * INPUTS
476 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
478 * RESULTS
479 * io_Error
480 * ios2_WireError
482 * EXAMPLE
484 * NOTES
486 * BUGS
488 * SEE ALSO
490 ****************************************************************************
494 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
495 struct DevBase *base)
497 struct DevUnit *unit;
498 struct Sana2DeviceQuery *info;
499 ULONG size_available, size;
501 /* Copy device info */
503 unit = (APTR)request->ios2_Req.io_Unit;
504 info = request->ios2_StatData;
505 size = size_available = info->SizeAvailable;
506 if(size > sizeof(struct Sana2DeviceQuery))
507 size = sizeof(struct Sana2DeviceQuery);
509 CopyMem(&sana2_info, info, size);
510 info->BPS = unit->speed;
511 info->SizeAvailable = size_available;
512 info->SizeSupplied = size;
514 /* Return */
516 return TRUE;
521 /****** etherlink3.device/S2_GETSTATIONADDDRESS ****************************
523 * NAME
524 * S2_GETSTATIONADDDRESS --
526 * FUNCTION
528 * INPUTS
529 * None.
531 * RESULTS
532 * io_Error
533 * ios2_WireError
534 * ios2_SrcAddr - current address.
535 * ios2_DstAddr - default address (zero if none?).
537 * EXAMPLE
539 * NOTES
541 * BUGS
543 * SEE ALSO
545 ****************************************************************************
549 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
550 struct DevBase *base)
552 struct DevUnit *unit;
554 /* Copy addresses */
556 unit = (APTR)request->ios2_Req.io_Unit;
557 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
558 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
560 /* Return */
562 return TRUE;
567 /****** etherlink3.device/S2_CONFIGINTERFACE *******************************
569 * NAME
570 * S2_CONFIGINTERFACE --
572 * FUNCTION
574 * INPUTS
575 * ios2_SrcAddr - address to use.
577 * RESULTS
578 * io_Error
579 * ios2_WireError
580 * ios2_SrcAddr - address used.
582 * EXAMPLE
584 * NOTES
586 * BUGS
588 * SEE ALSO
590 ****************************************************************************
594 static BOOL CmdConfigInterface(struct IOSana2Req *request,
595 struct DevBase *base)
597 struct DevUnit *unit;
599 /* Configure adapter */
601 unit = (APTR)request->ios2_Req.io_Unit;
602 if((unit->flags & UNITF_CONFIGURED) == 0)
604 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
605 if((unit->flags & UNITF_HAVEADAPTER) != 0)
606 ConfigureAdapter(unit, base);
607 unit->flags |= UNITF_CONFIGURED;
609 else
611 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
612 request->ios2_WireError = S2WERR_IS_CONFIGURED;
615 /* Return */
617 return TRUE;
622 /****** etherlink3.device/S2_BROADCAST *************************************
624 * NAME
625 * S2_BROADCAST --
627 * FUNCTION
629 * INPUTS
630 * io_Flags
631 * ios2_PacketType
632 * ios2_DataLength
633 * ios2_Data
635 * RESULTS
636 * io_Error
637 * ios2_WireError
639 * EXAMPLE
641 * NOTES
643 * BUGS
645 * SEE ALSO
647 ****************************************************************************
651 static BOOL CmdBroadcast(struct IOSana2Req *request,
652 struct DevBase *base)
654 /* Fill in the broadcast address as destination */
656 memset(request->ios2_DstAddr, 0xff, sizeof(request->ios2_DstAddr));
658 /* Queue the write as normal */
660 return CmdWrite(request, base);
665 /****** etherlink3.device/S2_TRACKTYPE *************************************
667 * NAME
668 * S2_TRACKTYPE --
670 * FUNCTION
672 * INPUTS
673 * ios2_PacketType - packet type to start tracking.
675 * RESULTS
676 * io_Error
677 * ios2_WireError
679 * EXAMPLE
681 * NOTES
683 * BUGS
685 * SEE ALSO
687 ****************************************************************************
691 static BOOL CmdTrackType(struct IOSana2Req *request,
692 struct DevBase *base)
694 struct DevUnit *unit;
695 struct Opener *opener;
696 ULONG packet_type, wire_error;
697 struct TypeTracker *tracker;
698 struct TypeStats *initial_stats;
699 BYTE error = 0;
701 unit = (APTR)request->ios2_Req.io_Unit;
702 packet_type = request->ios2_PacketType;
704 /* Get global tracker */
706 tracker = (struct TypeTracker *)
707 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
709 if(tracker != NULL)
710 tracker->user_count++;
711 else
713 tracker =
714 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
715 if(tracker != NULL)
717 tracker->packet_type = packet_type;
718 tracker->user_count = 1;
720 Disable();
721 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
722 Enable();
726 /* Store initial figures for this opener */
728 opener = request->ios2_BufferManagement;
729 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
730 base);
732 if(initial_stats != NULL)
734 error = S2ERR_BAD_STATE;
735 wire_error = S2WERR_ALREADY_TRACKED;
738 if(error == 0)
740 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
741 if(initial_stats == NULL)
743 error = S2ERR_NO_RESOURCES;
744 wire_error = S2WERR_GENERIC_ERROR;
748 if(error == 0)
750 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
751 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
754 /* Return */
756 request->ios2_Req.io_Error = error;
757 request->ios2_WireError = wire_error;
758 return TRUE;
763 /****** etherlink3.device/S2_UNTRACKTYPE ***********************************
765 * NAME
766 * S2_UNTRACKTYPE --
768 * FUNCTION
770 * INPUTS
771 * ios2_PacketType - packet type to stop tracking.
773 * RESULTS
774 * io_Error
775 * ios2_WireError
777 * EXAMPLE
779 * NOTES
781 * BUGS
783 * SEE ALSO
785 ****************************************************************************
789 static BOOL CmdUntrackType(struct IOSana2Req *request,
790 struct DevBase *base)
792 struct DevUnit *unit;
793 struct Opener *opener;
794 ULONG packet_type;
795 struct TypeTracker *tracker;
796 struct TypeStats *initial_stats;
798 unit = (APTR)request->ios2_Req.io_Unit;
799 packet_type = request->ios2_PacketType;
801 /* Get global tracker and initial figures */
803 tracker = (struct TypeTracker *)
804 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
805 opener = request->ios2_BufferManagement;
806 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
807 base);
809 /* Decrement tracker usage and free unused structures */
811 if(initial_stats != NULL)
813 if((--tracker->user_count) == 0)
815 Disable();
816 Remove((APTR)tracker);
817 Enable();
818 FreeMem(tracker, sizeof(struct TypeTracker));
821 Remove((APTR)initial_stats);
822 FreeMem(initial_stats, sizeof(struct TypeStats));
824 else
826 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
827 request->ios2_WireError = S2WERR_NOT_TRACKED;
830 /* Return */
832 return TRUE;
837 /****** etherlink3.device/S2_GETTYPESTATS **********************************
839 * NAME
840 * S2_GETTYPESTATS --
842 * FUNCTION
844 * INPUTS
845 * ios2_PacketType - packet type to get statistics on.
846 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
848 * RESULTS
849 * io_Error
850 * ios2_WireError
852 * EXAMPLE
854 * NOTES
856 * BUGS
858 * SEE ALSO
860 ****************************************************************************
864 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
865 struct DevBase *base)
867 struct DevUnit *unit;
868 struct Opener *opener;
869 ULONG packet_type;
870 struct TypeStats *initial_stats, *tracker;
871 struct Sana2PacketTypeStats *stats;
873 unit = (APTR)request->ios2_Req.io_Unit;
874 packet_type = request->ios2_PacketType;
876 /* Get global tracker and initial figures */
878 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
879 opener = request->ios2_BufferManagement;
880 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
881 base);
883 /* Copy and adjust figures */
885 if(initial_stats != NULL)
887 stats = request->ios2_StatData;
888 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
889 stats->PacketsSent -= initial_stats->stats.PacketsSent;
890 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
891 stats->BytesSent -= initial_stats->stats.BytesSent;
892 stats->BytesReceived -= initial_stats->stats.BytesReceived;
893 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
895 else
897 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
898 request->ios2_WireError = S2WERR_NOT_TRACKED;
901 /* Return */
903 return TRUE;
908 /****** etherlink3.device/S2_GETSPECIALSTATS *******************************
910 * NAME
911 * S2_GETSPECIALSTATS --
913 * FUNCTION
915 * INPUTS
916 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
918 * RESULTS
919 * io_Error
920 * ios2_WireError
922 * EXAMPLE
924 * NOTES
926 * BUGS
928 * SEE ALSO
930 ****************************************************************************
934 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
935 struct DevBase *base)
937 struct DevUnit *unit;
938 UWORD i, stat_count;
939 struct Sana2SpecialStatHeader *header;
940 struct Sana2SpecialStatRecord *record;
942 /* Fill in stats */
944 unit = (APTR)request->ios2_Req.io_Unit;
945 header = request->ios2_StatData;
946 record = (APTR)(header + 1);
948 stat_count = header->RecordCountMax;
949 if(stat_count > STAT_COUNT)
950 stat_count = STAT_COUNT;
952 for(i = 0; i < stat_count; i++)
954 record->Type = (S2WireType_Ethernet << 16) + i;
955 record->Count = unit->special_stats[i];
956 record->String = special_stat_names[i];
957 record++;
960 header->RecordCountSupplied = stat_count;
962 /* Return */
964 return TRUE;
969 /****** etherlink3.device/S2_GETGLOBALSTATS ********************************
971 * NAME
972 * S2_GETGLOBALSTATS --
974 * FUNCTION
976 * INPUTS
977 * ios2_StatData - Pointer to Sana2DeviceStats structure.
979 * RESULTS
980 * io_Error
981 * ios2_WireError
983 * EXAMPLE
985 * NOTES
987 * BUGS
989 * SEE ALSO
991 ****************************************************************************
995 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
996 struct DevBase *base)
998 struct DevUnit *unit;
1000 /* Update and copy stats */
1002 unit = (APTR)request->ios2_Req.io_Unit;
1003 Disable();
1004 UpdateStats(unit, base);
1005 Enable();
1006 CopyMem(&unit->stats, request->ios2_StatData,
1007 sizeof(struct Sana2DeviceStats));
1009 /* Return */
1011 return TRUE;
1016 /****** etherlink3.device/S2_ONEVENT ***************************************
1018 * NAME
1019 * S2_ONEVENT --
1021 * FUNCTION
1023 * INPUTS
1024 * ios2_WireError
1026 * RESULTS
1027 * io_Error
1028 * ios2_WireError
1030 * EXAMPLE
1032 * NOTES
1034 * BUGS
1036 * SEE ALSO
1038 ****************************************************************************
1042 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1044 struct DevUnit *unit;
1045 ULONG events, wanted_events;
1046 BOOL complete = FALSE;
1048 /* Check if we understand the event types */
1050 unit = (APTR)request->ios2_Req.io_Unit;
1051 wanted_events = request->ios2_WireError;
1052 if((wanted_events & ~KNOWN_EVENTS) != 0)
1054 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1055 events = S2WERR_BAD_EVENT;
1057 else
1059 if((unit->flags & UNITF_ONLINE) != 0)
1060 events = S2EVENT_ONLINE;
1061 else
1062 events = S2EVENT_OFFLINE;
1064 events &= wanted_events;
1067 /* Reply request if a wanted event has already occurred */
1069 if(events != 0)
1071 request->ios2_WireError = events;
1072 complete = TRUE;
1074 else
1075 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1077 /* Return */
1079 return complete;
1084 /****** etherlink3.device/S2_READORPHAN ************************************
1086 * NAME
1087 * S2_READORPHAN --
1089 * FUNCTION
1091 * INPUTS
1092 * io_Flags
1093 * ios2_Data
1095 * RESULTS
1096 * io_Flags
1097 * io_Error
1098 * ios2_WireError
1099 * ios2_PacketType - A copy of the packet's type field.
1100 * ios2_SrcAddr
1101 * ios2_DstAddr
1102 * ios2_DataLength
1103 * ios2_Data
1106 * EXAMPLE
1108 * NOTES
1110 * BUGS
1112 * SEE ALSO
1114 ****************************************************************************
1118 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1119 struct DevBase *base)
1121 struct DevUnit *unit;
1122 BYTE error = 0;
1123 ULONG wire_error;
1124 BOOL complete = FALSE;
1126 /* Check request is valid */
1128 unit = (APTR)request->ios2_Req.io_Unit;
1129 if((unit->flags & UNITF_ONLINE) == 0)
1131 error = S2ERR_OUTOFSERVICE;
1132 wire_error = S2WERR_UNIT_OFFLINE;
1135 /* Queue request */
1137 if(error == 0)
1138 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1139 else
1141 request->ios2_Req.io_Error = error;
1142 request->ios2_WireError = wire_error;
1143 complete = TRUE;
1146 /* Return */
1148 return complete;
1153 /****** etherlink3.device/S2_ONLINE ****************************************
1155 * NAME
1156 * S2_ONLINE --
1158 * FUNCTION
1160 * INPUTS
1161 * None.
1163 * RESULTS
1164 * io_Error
1165 * ios2_WireError
1167 * EXAMPLE
1169 * NOTES
1171 * BUGS
1173 * SEE ALSO
1175 ****************************************************************************
1179 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1181 struct DevUnit *unit;
1182 BYTE error = 0;
1183 ULONG wire_error;
1184 UWORD i;
1186 /* Check request is valid */
1188 unit = (APTR)request->ios2_Req.io_Unit;
1189 if((unit->flags & UNITF_CONFIGURED) == 0)
1191 error = S2ERR_BAD_STATE;
1192 wire_error = S2WERR_NOT_CONFIGURED;
1194 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1196 error = S2ERR_OUTOFSERVICE;
1197 wire_error = S2WERR_RCVREL_HDW_ERR;
1200 /* Clear global and special stats and put adapter back online */
1202 if(error == 0 && (unit->flags & UNITF_ONLINE) == 0)
1204 unit->stats.PacketsReceived = 0;
1205 unit->stats.PacketsSent = 0;
1206 unit->stats.BadData = 0;
1207 unit->stats.Overruns = 0;
1208 unit->stats.UnknownTypesReceived = 0;
1209 unit->stats.Reconfigurations = 0;
1211 for(i = 0; i < STAT_COUNT; i++)
1212 unit->special_stats[i] = 0;
1214 GoOnline(unit, base);
1217 /* Return */
1219 request->ios2_Req.io_Error = error;
1220 request->ios2_WireError = wire_error;
1221 return TRUE;
1226 /****** etherlink3.device/S2_OFFLINE ***************************************
1228 * NAME
1229 * S2_OFFLINE --
1231 * FUNCTION
1233 * INPUTS
1234 * None.
1236 * RESULTS
1237 * io_Error
1238 * ios2_WireError
1240 * EXAMPLE
1242 * NOTES
1244 * BUGS
1246 * SEE ALSO
1248 ****************************************************************************
1252 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1254 struct DevUnit *unit;
1256 /* Put adapter offline */
1258 unit = (APTR)request->ios2_Req.io_Unit;
1259 if((unit->flags & UNITF_ONLINE) != 0)
1260 GoOffline(unit, base);
1262 /* Return */
1264 return TRUE;
1269 /****** etherlink3.device/NSCMD_DEVICEQUERY ********************************
1271 * NAME
1272 * NSCMD_DEVICEQUERY -- Query device capabilities.
1274 * FUNCTION
1276 * INPUTS
1277 * io_Length - ???.
1278 * io_Data - pointer to NSDeviceQueryResult structure.
1280 * RESULTS
1281 * io_Error
1282 * io_Actual - size of structure device can handle.
1284 * EXAMPLE
1286 * NOTES
1288 * BUGS
1290 * SEE ALSO
1292 ****************************************************************************
1294 * Note that we have to pretend the request structure is an IOStdReq.
1298 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1299 struct DevBase *base)
1301 struct NSDeviceQueryResult *info;
1303 /* Set structure size twice */
1305 info = request->io_Data;
1306 request->io_Actual = info->SizeAvailable =
1307 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1309 /* Report device details */
1311 info->DeviceType = NSDEVTYPE_SANA2;
1312 info->DeviceSubType = 0;
1314 info->SupportedCommands = (APTR)supported_commands;
1316 /* Return */
1318 return TRUE;
1323 /****** etherlink3.device/S2_ADDMULTICASTADDRESS ***************************
1325 * NAME
1326 * S2_ADDMULTICASTADDRESS --
1328 * FUNCTION
1330 * INPUTS
1331 * ios2_SrcAddr - multicast address.
1333 * RESULTS
1334 * io_Error
1335 * ios2_WireError
1337 * EXAMPLE
1339 * NOTES
1341 * BUGS
1343 * SEE ALSO
1345 ****************************************************************************
1349 /****** etherlink3.device/S2_ADDMULTICASTADDRESSES *************************
1351 * NAME
1352 * S2_ADDMULTICASTADDRESSES --
1354 * FUNCTION
1356 * INPUTS
1357 * ios2_SrcAddr - lower bound.
1358 * ios2_DstAddr - upper bound.
1360 * RESULTS
1361 * io_Error
1362 * ios2_WireError
1364 * EXAMPLE
1366 * NOTES
1368 * BUGS
1370 * SEE ALSO
1372 ****************************************************************************
1376 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1377 struct DevBase *base)
1379 struct DevUnit *unit;
1380 UBYTE *lower_bound, *upper_bound;
1382 unit = (APTR)request->ios2_Req.io_Unit;
1384 lower_bound = request->ios2_SrcAddr;
1385 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1386 upper_bound = lower_bound;
1387 else
1388 upper_bound = request->ios2_DstAddr;
1390 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1392 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1393 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1396 /* Return */
1398 return TRUE;
1403 /****** etherlink3.device/S2_DELMULTICASTADDRESS ***************************
1405 * NAME
1406 * S2_DELMULTICASTADDRESS --
1408 * FUNCTION
1410 * INPUTS
1411 * ios2_SrcAddr - multicast address.
1413 * RESULTS
1414 * io_Error
1415 * ios2_WireError
1417 * EXAMPLE
1419 * NOTES
1421 * BUGS
1423 * SEE ALSO
1425 ****************************************************************************
1429 /****** etherlink3.device/S2_DELMULTICASTADDRESSES *************************
1431 * NAME
1432 * S2_DELMULTICASTADDRESSES --
1434 * FUNCTION
1436 * INPUTS
1437 * ios2_SrcAddr - lower bound.
1438 * ios2_DstAddr - upper bound.
1440 * RESULTS
1441 * io_Error
1442 * ios2_WireError
1444 * EXAMPLE
1446 * NOTES
1448 * BUGS
1450 * SEE ALSO
1452 ****************************************************************************
1456 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1457 struct DevBase *base)
1459 struct DevUnit *unit;
1460 UBYTE *lower_bound, *upper_bound;
1462 unit = (APTR)request->ios2_Req.io_Unit;
1464 lower_bound = request->ios2_SrcAddr;
1465 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1466 upper_bound = lower_bound;
1467 else
1468 upper_bound = request->ios2_DstAddr;
1470 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1472 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1473 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1476 /* Return */
1478 return TRUE;
1483 /****i* etherlink3.device/PutRequest ***************************************
1485 * NAME
1486 * PutRequest -- .
1488 * SYNOPSIS
1489 * PutRequest(port, request)
1491 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1493 * FUNCTION
1495 * INPUTS
1496 * port
1497 * request
1499 * RESULT
1500 * None.
1502 * EXAMPLE
1504 * NOTES
1506 * BUGS
1508 * SEE ALSO
1510 ****************************************************************************
1514 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1515 struct DevBase *base)
1517 request->io_Flags &= ~IOF_QUICK;
1518 PutMsg(port, (APTR)request);
1520 return;