revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / rhine / request.c
blob5f48042d5c014c632489a36f5e17670931c8649a
1 /*
3 Copyright (C) 2001-2012 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.
23 #include <exec/types.h>
24 #include <exec/errors.h>
25 #include <exec/initializers.h>
26 #include <devices/newstyle.h>
28 #include <proto/exec.h>
29 #include <proto/utility.h>
31 #include "device.h"
33 #include "request_protos.h"
34 #include "unit_protos.h"
37 #define KNOWN_EVENTS \
38 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
39 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
42 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base);
43 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base);
44 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base);
45 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
119 const TEXT badmulticast_name[] = "Bad multicasts";
120 const TEXT retries_name[] = "Retries";
121 const TEXT fifo_underruns_name[] = "Underruns";
124 const TEXT *const special_stat_names[] =
126 badmulticast_name,
127 retries_name,
128 fifo_underruns_name
133 /****i* rhine.device/ServiceRequest ****************************************
135 * NAME
136 * ServiceRequest -- Attempt to service a device request.
138 * SYNOPSIS
139 * ServiceRequest(request)
141 * VOID ServiceRequest(struct IORequest *);
143 * FUNCTION
144 * Attempts to carry out a request. The relevant unit's semaphore must
145 * be obtained before calling this function. This function releases the
146 * semaphore before returning.
148 * INPUTS
149 * request
151 * RESULT
152 * None.
154 * EXAMPLE
156 * NOTES
158 * BUGS
160 * SEE ALSO
162 ****************************************************************************
166 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
168 BOOL complete;
170 switch(request->ios2_Req.io_Command)
172 case CMD_READ:
173 complete = CmdRead(request, base);
174 break;
175 case CMD_WRITE:
176 complete = CmdWrite(request, base);
177 break;
178 case CMD_FLUSH:
179 complete = CmdFlush((APTR)request, base);
180 break;
181 case S2_DEVICEQUERY:
182 complete = CmdS2DeviceQuery(request, base);
183 break;
184 case S2_GETSTATIONADDRESS:
185 complete = CmdGetStationAddress(request, base);
186 break;
187 case S2_CONFIGINTERFACE:
188 complete = CmdConfigInterface(request, base);
189 break;
190 case S2_ADDMULTICASTADDRESS:
191 complete = CmdAddMulticastAddresses(request, base);
192 break;
193 case S2_DELMULTICASTADDRESS:
194 complete = CmdDelMulticastAddresses(request, base);
195 break;
196 case S2_MULTICAST:
197 complete = CmdWrite(request, base);
198 break;
199 case S2_BROADCAST:
200 complete = CmdBroadcast(request, base);
201 break;
202 case S2_TRACKTYPE:
203 complete = CmdTrackType(request, base);
204 break;
205 case S2_UNTRACKTYPE:
206 complete = CmdUntrackType(request, base);
207 break;
208 case S2_GETTYPESTATS:
209 complete = CmdGetTypeStats(request, base);
210 break;
211 case S2_GETSPECIALSTATS:
212 complete = CmdGetSpecialStats(request, base);
213 break;
214 case S2_GETGLOBALSTATS:
215 complete = CmdGetGlobalStats(request, base);
216 break;
217 case S2_ONEVENT:
218 complete = CmdOnEvent(request, base);
219 break;
220 case S2_READORPHAN:
221 complete = CmdReadOrphan(request, base);
222 break;
223 case S2_ONLINE:
224 complete = CmdOnline(request, base);
225 break;
226 case S2_OFFLINE:
227 complete = CmdOffline(request, base);
228 break;
229 case NSCMD_DEVICEQUERY:
230 complete = CmdDeviceQuery((APTR)request, base);
231 break;
232 case S2_ADDMULTICASTADDRESSES:
233 complete = CmdAddMulticastAddresses(request, base);
234 break;
235 case S2_DELMULTICASTADDRESSES:
236 complete = CmdDelMulticastAddresses(request, base);
237 break;
238 default:
239 complete = CmdInvalid(request, base);
242 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
243 ReplyMsg((APTR)request);
245 ReleaseSemaphore(
246 &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock);
247 return;
252 /****i* rhine.device/CMD_INVALID *******************************************
254 * NAME
255 * CMD_INVALID -- Reject an invalid command.
257 * FUNCTION
259 * INPUTS
260 * None.
262 * RESULTS
263 * io_Error - IOERR_NOCMD.
265 * EXAMPLE
267 * NOTES
269 * BUGS
271 * SEE ALSO
273 ****************************************************************************
277 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
279 request->ios2_Req.io_Error = IOERR_NOCMD;
280 request->ios2_WireError = S2WERR_GENERIC_ERROR;
282 return TRUE;
287 /****** rhine.device/CMD_READ **********************************************
289 * NAME
290 * CMD_READ -- Read data.
292 * FUNCTION
294 * INPUTS
295 * io_Flags
296 * ios2_PacketType
297 * ios2_Data
299 * RESULTS
300 * io_Flags
301 * io_Error
302 * ios2_WireError
303 * ios2_SrcAddr
304 * ios2_DstAddr
305 * ios2_DataLength
306 * ios2_Data
308 * EXAMPLE
310 * NOTES
312 * BUGS
314 * SEE ALSO
316 ****************************************************************************
320 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
322 struct DevUnit *unit;
323 struct Opener *opener;
324 BOOL complete = FALSE;
326 unit = (APTR)request->ios2_Req.io_Unit;
328 if((unit->flags & UNITF_ONLINE) != 0)
330 opener = request->ios2_BufferManagement;
331 PutRequest(&opener->read_port, (APTR)request, base);
333 else
335 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
336 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
337 complete = TRUE;
340 /* Return */
342 return complete;
347 /****** rhine.device/CMD_WRITE *********************************************
349 * NAME
350 * CMD_WRITE -- Write data.
352 * FUNCTION
354 * INPUTS
355 * io_Flags
356 * ios2_DstAddr
357 * ios2_PacketType
358 * ios2_DataLength
359 * ios2_Data
361 * RESULTS
362 * io_Error
363 * ios2_WireError
365 * EXAMPLE
367 * NOTES
369 * BUGS
371 * SEE ALSO
373 ****************************************************************************
377 /****** rhine.device/S2_MULTICAST ******************************************
379 * NAME
380 * S2_MULTICAST
382 * FUNCTION
384 * INPUTS
385 * io_Flags
386 * ios2_DstAddr - multicast address.
387 * ios2_PacketType
388 * ios2_DataLength
389 * ios2_Data
391 * RESULTS
392 * io_Error
393 * ios2_WireError
395 * EXAMPLE
397 * NOTES
399 * BUGS
401 * SEE ALSO
403 ****************************************************************************
407 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
409 struct DevUnit *unit;
410 BYTE error = 0;
411 ULONG wire_error;
412 BOOL complete = FALSE;
414 /* Check request is valid */
416 unit = (APTR)request->ios2_Req.io_Unit;
417 if((unit->flags & UNITF_ONLINE) == 0)
419 error = S2ERR_OUTOFSERVICE;
420 wire_error = S2WERR_UNIT_OFFLINE;
422 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
423 ((request->ios2_DstAddr[0] & 0x1) == 0))
425 error = S2ERR_BAD_ADDRESS;
426 wire_error = S2WERR_BAD_MULTICAST;
429 /* Queue request for sending */
431 if(error == 0)
432 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
433 else
435 request->ios2_Req.io_Error = error;
436 request->ios2_WireError = wire_error;
437 complete = TRUE;
440 /* Return */
442 return complete;
447 /****** rhine.device/CMD_FLUSH *********************************************
449 * NAME
450 * CMD_FLUSH
452 * FUNCTION
454 * INPUTS
455 * None.
457 * RESULTS
458 * io_Error
460 * EXAMPLE
462 * NOTES
464 * BUGS
466 * SEE ALSO
468 ****************************************************************************
472 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
474 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
476 return TRUE;
481 /****** rhine.device/S2_DEVICEQUERY ****************************************
483 * NAME
484 * S2_DEVICEQUERY -- Query device capabilities.
486 * FUNCTION
488 * INPUTS
489 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
491 * RESULTS
492 * io_Error
493 * ios2_WireError
495 * EXAMPLE
497 * NOTES
499 * BUGS
501 * SEE ALSO
503 ****************************************************************************
507 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
508 struct DevBase *base)
510 struct DevUnit *unit;
511 struct Sana2DeviceQuery *info;
512 ULONG size_available, size;
514 /* Copy device info */
516 unit = (APTR)request->ios2_Req.io_Unit;
517 info = request->ios2_StatData;
518 size = size_available = info->SizeAvailable;
519 if(size > sizeof(struct Sana2DeviceQuery))
520 size = sizeof(struct Sana2DeviceQuery);
522 CopyMem(&sana2_info, info, size);
523 info->BPS = unit->speed;
525 info->SizeAvailable = size_available;
526 info->SizeSupplied = size;
528 /* Return */
530 return TRUE;
535 /****** rhine.device/S2_GETSTATIONADDDRESS *********************************
537 * NAME
538 * S2_GETSTATIONADDDRESS
540 * FUNCTION
542 * INPUTS
543 * None.
545 * RESULTS
546 * io_Error
547 * ios2_WireError
548 * ios2_SrcAddr - current address.
549 * ios2_DstAddr - default address (zero if none?).
551 * EXAMPLE
553 * NOTES
555 * BUGS
557 * SEE ALSO
559 ****************************************************************************
563 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
564 struct DevBase *base)
566 struct DevUnit *unit;
568 /* Copy addresses */
570 unit = (APTR)request->ios2_Req.io_Unit;
571 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
572 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
574 /* Return */
576 return TRUE;
581 /****** rhine.device/S2_CONFIGINTERFACE ************************************
583 * NAME
584 * S2_CONFIGINTERFACE
586 * FUNCTION
588 * INPUTS
589 * ios2_SrcAddr - address to use.
591 * RESULTS
592 * io_Error
593 * ios2_WireError
594 * ios2_SrcAddr - address used.
596 * EXAMPLE
598 * NOTES
600 * BUGS
602 * SEE ALSO
604 ****************************************************************************
608 static BOOL CmdConfigInterface(struct IOSana2Req *request,
609 struct DevBase *base)
611 struct DevUnit *unit;
612 BYTE error = 0;
613 ULONG wire_error;
615 /* Configure adapter */
617 unit = (APTR)request->ios2_Req.io_Unit;
618 if((unit->flags & UNITF_CONFIGURED) != 0)
620 error = S2ERR_BAD_STATE;
621 wire_error = S2WERR_IS_CONFIGURED;
623 else if((unit->flags & UNITF_HAVEADAPTER) == 0)
625 error = S2ERR_BAD_STATE;
626 wire_error = S2WERR_GENERIC_ERROR;
629 if(error == 0)
631 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
632 ConfigureAdapter(unit, base);
633 GoOnline(unit, base);
634 unit->flags |= UNITF_CONFIGURED;
636 else
638 request->ios2_Req.io_Error = error;
639 request->ios2_WireError = wire_error;
642 /* Return */
644 return TRUE;
649 /****** rhine.device/S2_BROADCAST ******************************************
651 * NAME
652 * S2_BROADCAST
654 * FUNCTION
656 * INPUTS
657 * io_Flags
658 * ios2_PacketType
659 * ios2_DataLength
660 * ios2_Data
662 * RESULTS
663 * io_Error
664 * ios2_WireError
666 * EXAMPLE
668 * NOTES
670 * BUGS
672 * SEE ALSO
674 ****************************************************************************
678 static BOOL CmdBroadcast(struct IOSana2Req *request,
679 struct DevBase *base)
681 UWORD i;
683 /* Fill in the broadcast address as destination */
685 for(i = 0; i < ETH_ADDRESSSIZE; i++)
686 request->ios2_DstAddr[i] = 0xff;
688 /* Queue the write as normal */
690 return CmdWrite(request, base);
695 /****** rhine.device/S2_TRACKTYPE ******************************************
697 * NAME
698 * S2_TRACKTYPE
700 * FUNCTION
702 * INPUTS
703 * ios2_PacketType - packet type to start tracking.
705 * RESULTS
706 * io_Error
707 * ios2_WireError
709 * EXAMPLE
711 * NOTES
713 * BUGS
715 * SEE ALSO
717 ****************************************************************************
721 static BOOL CmdTrackType(struct IOSana2Req *request,
722 struct DevBase *base)
724 struct DevUnit *unit;
725 struct Opener *opener;
726 ULONG packet_type, wire_error;
727 struct TypeTracker *tracker;
728 struct TypeStats *initial_stats;
729 BYTE error = 0;
731 unit = (APTR)request->ios2_Req.io_Unit;
732 packet_type = request->ios2_PacketType;
733 if(packet_type <= ETH_MTU)
734 packet_type = ETH_MTU;
736 /* Get global tracker */
738 tracker = (struct TypeTracker *)
739 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
741 if(tracker != NULL)
742 tracker->user_count++;
743 else
745 tracker =
746 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
747 if(tracker != NULL)
749 tracker->packet_type = packet_type;
750 tracker->user_count = 1;
752 Disable();
753 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
754 Enable();
758 /* Store initial figures for this opener */
760 opener = request->ios2_BufferManagement;
761 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
762 base);
764 if(initial_stats != NULL)
766 error = S2ERR_BAD_STATE;
767 wire_error = S2WERR_ALREADY_TRACKED;
770 if(error == 0)
772 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
773 if(initial_stats == NULL)
775 error = S2ERR_NO_RESOURCES;
776 wire_error = S2WERR_GENERIC_ERROR;
780 if(error == 0)
782 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
783 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
786 /* Return */
788 request->ios2_Req.io_Error = error;
789 request->ios2_WireError = wire_error;
790 return TRUE;
795 /****** rhine.device/S2_UNTRACKTYPE ****************************************
797 * NAME
798 * S2_UNTRACKTYPE
800 * FUNCTION
802 * INPUTS
803 * ios2_PacketType - packet type to stop tracking.
805 * RESULTS
806 * io_Error
807 * ios2_WireError
809 * EXAMPLE
811 * NOTES
813 * BUGS
815 * SEE ALSO
817 ****************************************************************************
821 static BOOL CmdUntrackType(struct IOSana2Req *request,
822 struct DevBase *base)
824 struct DevUnit *unit;
825 struct Opener *opener;
826 ULONG packet_type;
827 struct TypeTracker *tracker;
828 struct TypeStats *initial_stats;
830 unit = (APTR)request->ios2_Req.io_Unit;
831 packet_type = request->ios2_PacketType;
832 if(packet_type <= ETH_MTU)
833 packet_type = ETH_MTU;
835 /* Get global tracker and initial figures */
837 tracker = (struct TypeTracker *)
838 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
839 opener = request->ios2_BufferManagement;
840 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
841 base);
843 /* Decrement tracker usage and free unused structures */
845 if(initial_stats != NULL)
847 if((--tracker->user_count) == 0)
849 Disable();
850 Remove((APTR)tracker);
851 Enable();
852 FreeMem(tracker, sizeof(struct TypeTracker));
855 Remove((APTR)initial_stats);
856 FreeMem(initial_stats, sizeof(struct TypeStats));
858 else
860 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
861 request->ios2_WireError = S2WERR_NOT_TRACKED;
864 /* Return */
866 return TRUE;
871 /****** rhine.device/S2_GETTYPESTATS ***************************************
873 * NAME
874 * S2_GETTYPESTATS
876 * FUNCTION
878 * INPUTS
879 * ios2_PacketType - packet type to get statistics on.
880 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
882 * RESULTS
883 * io_Error
884 * ios2_WireError
886 * EXAMPLE
888 * NOTES
890 * BUGS
892 * SEE ALSO
894 ****************************************************************************
898 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
899 struct DevBase *base)
901 struct DevUnit *unit;
902 struct Opener *opener;
903 ULONG packet_type;
904 struct TypeStats *initial_stats, *tracker;
905 struct Sana2PacketTypeStats *stats;
907 unit = (APTR)request->ios2_Req.io_Unit;
908 packet_type = request->ios2_PacketType;
910 /* Get global tracker and initial figures */
912 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
913 opener = request->ios2_BufferManagement;
914 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
915 base);
917 /* Copy and adjust figures */
919 if(initial_stats != NULL)
921 stats = request->ios2_StatData;
922 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
923 stats->PacketsSent -= initial_stats->stats.PacketsSent;
924 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
925 stats->BytesSent -= initial_stats->stats.BytesSent;
926 stats->BytesReceived -= initial_stats->stats.BytesReceived;
927 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
929 else
931 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
932 request->ios2_WireError = S2WERR_NOT_TRACKED;
935 /* Return */
937 return TRUE;
942 /****** rhine.device/S2_GETSPECIALSTATS ************************************
944 * NAME
945 * S2_GETSPECIALSTATS
947 * FUNCTION
949 * INPUTS
950 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
952 * RESULTS
953 * io_Error
954 * ios2_WireError
956 * EXAMPLE
958 * NOTES
960 * BUGS
962 * SEE ALSO
964 ****************************************************************************
968 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
969 struct DevBase *base)
971 struct DevUnit *unit;
972 UWORD i, stat_count;
973 struct Sana2SpecialStatHeader *header;
974 struct Sana2SpecialStatRecord *record;
976 /* Fill in stats */
978 unit = (APTR)request->ios2_Req.io_Unit;
979 header = request->ios2_StatData;
980 record = (APTR)(header + 1);
982 stat_count = header->RecordCountMax;
983 if(stat_count > STAT_COUNT)
984 stat_count = STAT_COUNT;
986 for(i = 0; i < stat_count; i++)
988 record->Type = (S2WireType_Ethernet << 16) + i;
989 record->Count = unit->special_stats[i];
990 record->String = special_stat_names[i];
991 record++;
994 header->RecordCountSupplied = stat_count;
996 /* Return */
998 return TRUE;
1003 /****** rhine.device/S2_GETGLOBALSTATS *************************************
1005 * NAME
1006 * S2_GETGLOBALSTATS
1008 * FUNCTION
1010 * INPUTS
1011 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1013 * RESULTS
1014 * io_Error
1015 * ios2_WireError
1017 * EXAMPLE
1019 * NOTES
1021 * BUGS
1023 * SEE ALSO
1025 ****************************************************************************
1029 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
1030 struct DevBase *base)
1032 struct DevUnit *unit;
1034 /* Copy stats */
1036 unit = (APTR)request->ios2_Req.io_Unit;
1037 CopyMem(&unit->stats, request->ios2_StatData,
1038 sizeof(struct Sana2DeviceStats));
1040 /* Return */
1042 return TRUE;
1047 /****** rhine.device/S2_ONEVENT ********************************************
1049 * NAME
1050 * S2_ONEVENT
1052 * FUNCTION
1054 * INPUTS
1055 * ios2_WireError
1057 * RESULTS
1058 * io_Error
1059 * ios2_WireError
1061 * EXAMPLE
1063 * NOTES
1065 * BUGS
1067 * SEE ALSO
1069 ****************************************************************************
1073 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1075 struct DevUnit *unit;
1076 ULONG events, wanted_events;
1077 BOOL complete = FALSE;
1079 /* Check if we understand the event types */
1081 unit = (APTR)request->ios2_Req.io_Unit;
1082 wanted_events = request->ios2_WireError;
1083 if((wanted_events & ~KNOWN_EVENTS) != 0)
1085 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1086 events = S2WERR_BAD_EVENT;
1088 else
1090 if((unit->flags & UNITF_ONLINE) != 0)
1091 events = S2EVENT_ONLINE;
1092 else
1093 events = S2EVENT_OFFLINE;
1095 events &= wanted_events;
1098 /* Reply request if a wanted event has already occurred */
1100 if(events != 0)
1102 request->ios2_WireError = events;
1103 complete = TRUE;
1105 else
1106 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1108 /* Return */
1110 return complete;
1115 /****** rhine.device/S2_READORPHAN *****************************************
1117 * NAME
1118 * S2_READORPHAN
1120 * FUNCTION
1122 * INPUTS
1123 * io_Flags
1124 * ios2_Data
1126 * RESULTS
1127 * io_Flags
1128 * io_Error
1129 * ios2_WireError
1130 * ios2_PacketType - A copy of the packet's type field.
1131 * ios2_SrcAddr
1132 * ios2_DstAddr
1133 * ios2_DataLength
1134 * ios2_Data
1137 * EXAMPLE
1139 * NOTES
1141 * BUGS
1143 * SEE ALSO
1145 ****************************************************************************
1149 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1150 struct DevBase *base)
1152 struct DevUnit *unit;
1153 BYTE error = 0;
1154 ULONG wire_error;
1155 BOOL complete = FALSE;
1157 /* Check request is valid */
1159 unit = (APTR)request->ios2_Req.io_Unit;
1160 if((unit->flags & UNITF_ONLINE) == 0)
1162 error = S2ERR_OUTOFSERVICE;
1163 wire_error = S2WERR_UNIT_OFFLINE;
1166 /* Queue request */
1168 if(error == 0)
1169 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1170 else
1172 request->ios2_Req.io_Error = error;
1173 request->ios2_WireError = wire_error;
1174 complete = TRUE;
1177 /* Return */
1179 return complete;
1184 /****** rhine.device/S2_ONLINE *********************************************
1186 * NAME
1187 * S2_ONLINE
1189 * FUNCTION
1191 * INPUTS
1192 * None.
1194 * RESULTS
1195 * io_Error
1196 * ios2_WireError
1198 * EXAMPLE
1200 * NOTES
1202 * BUGS
1204 * SEE ALSO
1206 ****************************************************************************
1210 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1212 struct DevUnit *unit;
1213 BYTE error = 0;
1214 ULONG wire_error;
1215 UWORD i;
1217 /* Check request is valid */
1219 unit = (APTR)request->ios2_Req.io_Unit;
1220 if((unit->flags & UNITF_CONFIGURED) == 0)
1222 error = S2ERR_BAD_STATE;
1223 wire_error = S2WERR_NOT_CONFIGURED;
1225 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1227 error = S2ERR_OUTOFSERVICE;
1228 wire_error = S2WERR_RCVREL_HDW_ERR;
1231 /* Clear global and special stats and put adapter back online */
1233 if((error == 0) && ((unit->flags & UNITF_ONLINE) == 0))
1235 unit->stats.PacketsReceived = 0;
1236 unit->stats.PacketsSent = 0;
1237 unit->stats.BadData = 0;
1238 unit->stats.Overruns = 0;
1239 unit->stats.UnknownTypesReceived = 0;
1240 unit->stats.Reconfigurations = 0;
1242 for(i = 0; i < STAT_COUNT; i++)
1243 unit->special_stats[i] = 0;
1245 GoOnline(unit, base);
1248 /* Return */
1250 request->ios2_Req.io_Error = error;
1251 request->ios2_WireError = wire_error;
1252 return TRUE;
1257 /****** rhine.device/S2_OFFLINE ********************************************
1259 * NAME
1260 * S2_OFFLINE
1262 * FUNCTION
1264 * INPUTS
1265 * None.
1267 * RESULTS
1268 * io_Error
1269 * ios2_WireError
1271 * EXAMPLE
1273 * NOTES
1275 * BUGS
1277 * SEE ALSO
1279 ****************************************************************************
1283 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1285 struct DevUnit *unit;
1287 /* Put adapter offline */
1289 unit = (APTR)request->ios2_Req.io_Unit;
1290 if((unit->flags & UNITF_ONLINE) != 0)
1291 GoOffline(unit, base);
1293 /* Return */
1295 return TRUE;
1300 /****** rhine.device/NSCMD_DEVICEQUERY *************************************
1302 * NAME
1303 * NSCMD_DEVICEQUERY -- Query device capabilities.
1305 * FUNCTION
1307 * INPUTS
1308 * io_Length - ???.
1309 * io_Data - pointer to NSDeviceQueryResult structure.
1311 * RESULTS
1312 * io_Error
1313 * io_Actual - size of structure device can handle.
1315 * EXAMPLE
1317 * NOTES
1319 * BUGS
1321 * SEE ALSO
1323 ****************************************************************************
1325 * Note that we have to pretend the request structure is an IOStdReq.
1329 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1330 struct DevBase *base)
1332 struct NSDeviceQueryResult *info;
1334 /* Set structure size twice */
1336 info = request->io_Data;
1337 request->io_Actual = info->SizeAvailable =
1338 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1340 /* Report device details */
1342 info->DeviceType = NSDEVTYPE_SANA2;
1343 info->DeviceSubType = 0;
1345 info->SupportedCommands = (APTR)supported_commands;
1347 /* Return */
1349 return TRUE;
1354 /****** rhine.device/S2_ADDMULTICASTADDRESS ********************************
1356 * NAME
1357 * S2_ADDMULTICASTADDRESS
1359 * FUNCTION
1361 * INPUTS
1362 * ios2_SrcAddr - multicast address.
1364 * RESULTS
1365 * io_Error
1366 * ios2_WireError
1368 * EXAMPLE
1370 * NOTES
1372 * BUGS
1374 * SEE ALSO
1376 ****************************************************************************
1380 /****** rhine.device/S2_ADDMULTICASTADDRESSES ******************************
1382 * NAME
1383 * S2_ADDMULTICASTADDRESSES
1385 * FUNCTION
1387 * INPUTS
1388 * ios2_SrcAddr - lower bound.
1389 * ios2_DstAddr - upper bound.
1391 * RESULTS
1392 * io_Error
1393 * ios2_WireError
1395 * EXAMPLE
1397 * NOTES
1399 * BUGS
1401 * SEE ALSO
1403 ****************************************************************************
1407 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1408 struct DevBase *base)
1410 struct DevUnit *unit;
1411 UBYTE *lower_bound, *upper_bound;
1413 unit = (APTR)request->ios2_Req.io_Unit;
1415 lower_bound = request->ios2_SrcAddr;
1416 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1417 upper_bound = lower_bound;
1418 else
1419 upper_bound = request->ios2_DstAddr;
1421 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1423 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1424 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1427 /* Return */
1429 return TRUE;
1434 /****** rhine.device/S2_DELMULTICASTADDRESS ********************************
1436 * NAME
1437 * S2_DELMULTICASTADDRESS
1439 * FUNCTION
1441 * INPUTS
1442 * ios2_SrcAddr - multicast address.
1444 * RESULTS
1445 * io_Error
1446 * ios2_WireError
1448 * EXAMPLE
1450 * NOTES
1452 * BUGS
1454 * SEE ALSO
1456 ****************************************************************************
1460 /****** rhine.device/S2_DELMULTICASTADDRESSES ******************************
1462 * NAME
1463 * S2_DELMULTICASTADDRESSES
1465 * FUNCTION
1467 * INPUTS
1468 * ios2_SrcAddr - lower bound.
1469 * ios2_DstAddr - upper bound.
1471 * RESULTS
1472 * io_Error
1473 * ios2_WireError
1475 * EXAMPLE
1477 * NOTES
1479 * BUGS
1481 * SEE ALSO
1483 ****************************************************************************
1487 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1488 struct DevBase *base)
1490 struct DevUnit *unit;
1491 UBYTE *lower_bound, *upper_bound;
1493 unit = (APTR)request->ios2_Req.io_Unit;
1495 lower_bound = request->ios2_SrcAddr;
1496 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1497 upper_bound = lower_bound;
1498 else
1499 upper_bound = request->ios2_DstAddr;
1501 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1503 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1504 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1507 /* Return */
1509 return TRUE;
1514 /****i* rhine.device/PutRequest ********************************************
1516 * NAME
1517 * PutRequest
1519 * SYNOPSIS
1520 * PutRequest(port, request)
1522 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1524 * FUNCTION
1526 * INPUTS
1527 * port
1528 * request
1530 * RESULT
1531 * None.
1533 ****************************************************************************
1537 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1538 struct DevBase *base)
1540 request->io_Flags &= ~IOF_QUICK;
1541 PutMsg(port, (APTR)request);
1543 return;