Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / devs / networks / prism2 / request.c
blob601b917cb15291ac56823656bdc66e715957ea6a
1 /*
3 File: request.c
4 Author: Neil Cafferkey
5 Copyright (C) 2001-2006 Neil Cafferkey
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA.
25 #include <exec/types.h>
26 #include <exec/errors.h>
27 #include <exec/initializers.h>
28 #include <devices/newstyle.h>
30 #include <proto/exec.h>
31 #include <proto/utility.h>
33 #include "device.h"
35 #include "request_protos.h"
36 #include "unit_protos.h"
39 #define KNOWN_EVENTS \
40 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
41 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
44 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base);
45 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base);
46 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base);
47 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base);
48 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
49 struct DevBase *base);
50 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
51 struct DevBase *base);
52 static BOOL CmdConfigInterface(struct IOSana2Req *request,
53 struct DevBase *base);
54 static BOOL CmdBroadcast(struct IOSana2Req *request,
55 struct DevBase *base);
56 static BOOL CmdTrackType(struct IOSana2Req *request,
57 struct DevBase *base);
58 static BOOL CmdUntrackType(struct IOSana2Req *request,
59 struct DevBase *base);
60 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
61 struct DevBase *base);
62 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
63 struct DevBase *base);
64 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
65 struct DevBase *base);
66 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base);
67 static BOOL CmdReadOrphan(struct IOSana2Req *request,
68 struct DevBase *base);
69 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base);
70 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base);
71 static BOOL CmdDeviceQuery(struct IOStdReq *request,
72 struct DevBase *base);
73 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
74 struct DevBase *base);
75 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
76 struct DevBase *base);
77 static BOOL CmdGetSignalQuality(struct IOSana2Req *request,
78 struct DevBase *base);
81 static const UWORD supported_commands[] =
83 CMD_READ,
84 CMD_WRITE,
85 CMD_FLUSH,
86 S2_DEVICEQUERY,
87 S2_GETSTATIONADDRESS,
88 S2_CONFIGINTERFACE,
89 S2_ADDMULTICASTADDRESS,
90 S2_DELMULTICASTADDRESS,
91 S2_MULTICAST,
92 S2_BROADCAST,
93 S2_TRACKTYPE,
94 S2_UNTRACKTYPE,
95 S2_GETTYPESTATS,
96 S2_GETSPECIALSTATS,
97 S2_GETGLOBALSTATS,
98 S2_ONEVENT,
99 S2_READORPHAN,
100 S2_ONLINE,
101 S2_OFFLINE,
102 NSCMD_DEVICEQUERY,
103 S2_ADDMULTICASTADDRESSES,
104 S2_DELMULTICASTADDRESSES,
105 P2_GETSIGNALQUALITY,
110 static const struct Sana2DeviceQuery sana2_info =
116 ETH_ADDRESSSIZE * 8,
117 ETH_MTU,
119 S2WireType_Ethernet
123 const TEXT badmulticast_name[] = "Bad multicasts";
124 const TEXT retries_name[] = "Retries";
125 const TEXT fifo_underruns_name[] = "Underruns";
128 const TEXT *const special_stat_names[] =
130 badmulticast_name,
131 retries_name,
132 fifo_underruns_name
137 /****i* prism2.device/ServiceRequest ***************************************
139 * NAME
140 * ServiceRequest -- Attempt to service a device request.
142 * SYNOPSIS
143 * ServiceRequest(request)
145 * VOID ServiceRequest(struct IORequest *);
147 * FUNCTION
148 * Attempts to carry out a request. The relevant unit's semaphore must
149 * be obtained before calling this function. This function releases the
150 * semaphore before returning.
152 * INPUTS
153 * request
155 * RESULT
156 * None.
158 * EXAMPLE
160 * NOTES
162 * BUGS
164 * SEE ALSO
166 ****************************************************************************
170 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
172 BOOL complete;
174 switch(request->ios2_Req.io_Command)
176 case CMD_READ:
177 complete = CmdRead(request, base);
178 break;
179 case CMD_WRITE:
180 complete = CmdWrite(request, base);
181 break;
182 case CMD_FLUSH:
183 complete = CmdFlush((APTR)request, base);
184 break;
185 case S2_DEVICEQUERY:
186 complete = CmdS2DeviceQuery(request, base);
187 break;
188 case S2_GETSTATIONADDRESS:
189 complete = CmdGetStationAddress(request, base);
190 break;
191 case S2_CONFIGINTERFACE:
192 complete = CmdConfigInterface(request, base);
193 break;
194 case S2_ADDMULTICASTADDRESS:
195 complete = CmdAddMulticastAddresses(request, base);
196 break;
197 case S2_DELMULTICASTADDRESS:
198 complete = CmdDelMulticastAddresses(request, base);
199 break;
200 case S2_MULTICAST:
201 complete = CmdWrite(request, base);
202 break;
203 case S2_BROADCAST:
204 complete = CmdBroadcast(request, base);
205 break;
206 case S2_TRACKTYPE:
207 complete = CmdTrackType(request, base);
208 break;
209 case S2_UNTRACKTYPE:
210 complete = CmdUntrackType(request, base);
211 break;
212 case S2_GETTYPESTATS:
213 complete = CmdGetTypeStats(request, base);
214 break;
215 case S2_GETSPECIALSTATS:
216 complete = CmdGetSpecialStats(request, base);
217 break;
218 case S2_GETGLOBALSTATS:
219 complete = CmdGetGlobalStats(request, base);
220 break;
221 case S2_ONEVENT:
222 complete = CmdOnEvent(request, base);
223 break;
224 case S2_READORPHAN:
225 complete = CmdReadOrphan(request, base);
226 break;
227 case S2_ONLINE:
228 complete = CmdOnline(request, base);
229 break;
230 case S2_OFFLINE:
231 complete = CmdOffline(request, base);
232 break;
233 case NSCMD_DEVICEQUERY:
234 complete = CmdDeviceQuery((APTR)request, base);
235 break;
236 case S2_ADDMULTICASTADDRESSES:
237 complete = CmdAddMulticastAddresses(request, base);
238 break;
239 case S2_DELMULTICASTADDRESSES:
240 complete = CmdDelMulticastAddresses(request, base);
241 break;
242 case P2_GETSIGNALQUALITY:
243 complete = CmdGetSignalQuality(request, base);
244 break;
245 default:
246 complete = CmdInvalid(request, base);
249 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
250 ReplyMsg((APTR)request);
252 ReleaseSemaphore(
253 &((struct DevUnit *)request->ios2_Req.io_Unit)->access_lock);
254 return;
259 /****i* prism2.device/CMD_INVALID ******************************************
261 * NAME
262 * CMD_INVALID -- Reject an invalid command.
264 * FUNCTION
266 * INPUTS
267 * None.
269 * RESULTS
270 * io_Error - IOERR_NOCMD.
272 * EXAMPLE
274 * NOTES
276 * BUGS
278 * SEE ALSO
280 ****************************************************************************
284 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
286 request->ios2_Req.io_Error = IOERR_NOCMD;
287 request->ios2_WireError = S2WERR_GENERIC_ERROR;
289 return TRUE;
294 /****** prism2.device/CMD_READ *********************************************
296 * NAME
297 * CMD_READ -- Read data.
299 * FUNCTION
301 * INPUTS
302 * io_Flags
303 * ios2_PacketType
304 * ios2_Data
306 * RESULTS
307 * io_Flags
308 * io_Error
309 * ios2_WireError
310 * ios2_SrcAddr
311 * ios2_DstAddr
312 * ios2_DataLength
313 * ios2_Data
315 * EXAMPLE
317 * NOTES
319 * BUGS
321 * SEE ALSO
323 ****************************************************************************
327 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
329 struct DevUnit *unit;
330 struct Opener *opener;
331 BOOL complete = FALSE;
333 unit = (APTR)request->ios2_Req.io_Unit;
335 if((unit->flags & UNITF_ONLINE) != 0)
337 opener = request->ios2_BufferManagement;
338 PutRequest(&opener->read_port, (APTR)request, base);
340 else
342 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
343 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
344 complete = TRUE;
347 /* Return */
349 return complete;
354 /****** prism2.device/CMD_WRITE ********************************************
356 * NAME
357 * CMD_WRITE -- Write data.
359 * FUNCTION
361 * INPUTS
362 * io_Flags
363 * ios2_DstAddr
364 * ios2_PacketType
365 * ios2_DataLength
366 * ios2_Data
368 * RESULTS
369 * io_Error
370 * ios2_WireError
372 * EXAMPLE
374 * NOTES
376 * BUGS
378 * SEE ALSO
380 ****************************************************************************
384 /****** prism2.device/S2_MULTICAST *****************************************
386 * NAME
387 * S2_MULTICAST
389 * FUNCTION
391 * INPUTS
392 * io_Flags
393 * ios2_DstAddr - multicast address.
394 * ios2_PacketType
395 * ios2_DataLength
396 * ios2_Data
398 * RESULTS
399 * io_Error
400 * ios2_WireError
402 * EXAMPLE
404 * NOTES
406 * BUGS
408 * SEE ALSO
410 ****************************************************************************
414 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
416 struct DevUnit *unit;
417 BYTE error = 0;
418 ULONG wire_error;
419 BOOL complete = FALSE;
421 /* Check request is valid */
423 unit = (APTR)request->ios2_Req.io_Unit;
424 if((unit->flags & UNITF_ONLINE) == 0)
426 error = S2ERR_OUTOFSERVICE;
427 wire_error = S2WERR_UNIT_OFFLINE;
429 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
430 ((request->ios2_DstAddr[0] & 0x1) == 0))
432 error = S2ERR_BAD_ADDRESS;
433 wire_error = S2WERR_BAD_MULTICAST;
436 /* Queue request for sending */
438 if(error == 0)
439 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
440 else
442 request->ios2_Req.io_Error = error;
443 request->ios2_WireError = wire_error;
444 complete = TRUE;
447 /* Return */
449 return complete;
454 /****** prism2.device/CMD_FLUSH ********************************************
456 * NAME
457 * CMD_FLUSH
459 * FUNCTION
461 * INPUTS
462 * None.
464 * RESULTS
465 * io_Error
467 * EXAMPLE
469 * NOTES
471 * BUGS
473 * SEE ALSO
475 ****************************************************************************
479 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
481 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
483 return TRUE;
488 /****** prism2.device/S2_DEVICEQUERY ***************************************
490 * NAME
491 * S2_DEVICEQUERY -- Query device capabilities.
493 * FUNCTION
495 * INPUTS
496 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
498 * RESULTS
499 * io_Error
500 * ios2_WireError
502 * EXAMPLE
504 * NOTES
506 * BUGS
508 * SEE ALSO
510 ****************************************************************************
514 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
515 struct DevBase *base)
517 struct DevUnit *unit;
518 struct Sana2DeviceQuery *info;
519 ULONG size_available, size;
521 /* Copy device info */
523 unit = (APTR)request->ios2_Req.io_Unit;
524 info = request->ios2_StatData;
525 size = size_available = info->SizeAvailable;
526 if(size > sizeof(struct Sana2DeviceQuery))
527 size = sizeof(struct Sana2DeviceQuery);
529 CopyMem(&sana2_info, info, size);
530 info->BPS = unit->speed;
532 info->SizeAvailable = size_available;
533 info->SizeSupplied = size;
535 /* Return */
537 return TRUE;
542 /****** prism2.device/S2_GETSTATIONADDDRESS ********************************
544 * NAME
545 * S2_GETSTATIONADDDRESS
547 * FUNCTION
549 * INPUTS
550 * None.
552 * RESULTS
553 * io_Error
554 * ios2_WireError
555 * ios2_SrcAddr - current address.
556 * ios2_DstAddr - default address (zero if none?).
558 * EXAMPLE
560 * NOTES
562 * BUGS
564 * SEE ALSO
566 ****************************************************************************
570 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
571 struct DevBase *base)
573 struct DevUnit *unit;
575 /* Copy addresses */
577 unit = (APTR)request->ios2_Req.io_Unit;
578 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
579 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
581 /* Return */
583 return TRUE;
588 /****** prism2.device/S2_CONFIGINTERFACE ***********************************
590 * NAME
591 * S2_CONFIGINTERFACE
593 * FUNCTION
595 * INPUTS
596 * ios2_SrcAddr - address to use.
598 * RESULTS
599 * io_Error
600 * ios2_WireError
601 * ios2_SrcAddr - address used.
603 * EXAMPLE
605 * NOTES
607 * BUGS
609 * SEE ALSO
611 ****************************************************************************
615 static BOOL CmdConfigInterface(struct IOSana2Req *request,
616 struct DevBase *base)
618 struct DevUnit *unit;
619 BYTE error = 0;
620 ULONG wire_error;
622 /* Configure adapter */
624 unit = (APTR)request->ios2_Req.io_Unit;
625 if((unit->flags & UNITF_CONFIGURED) != 0)
627 error = S2ERR_BAD_STATE;
628 wire_error = S2WERR_IS_CONFIGURED;
630 else if((unit->flags & UNITF_HAVEADAPTER) == 0)
632 error = S2ERR_BAD_STATE;
633 wire_error = S2WERR_GENERIC_ERROR;
636 if(error == 0)
638 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
639 ConfigureAdapter(unit, base);
640 GoOnline(unit, base);
641 unit->flags |= UNITF_CONFIGURED;
643 else
645 request->ios2_Req.io_Error = error;
646 request->ios2_WireError = S2WERR_IS_CONFIGURED;
649 /* Return */
651 return TRUE;
656 /****** prism2.device/S2_BROADCAST *****************************************
658 * NAME
659 * S2_BROADCAST
661 * FUNCTION
663 * INPUTS
664 * io_Flags
665 * ios2_PacketType
666 * ios2_DataLength
667 * ios2_Data
669 * RESULTS
670 * io_Error
671 * ios2_WireError
673 * EXAMPLE
675 * NOTES
677 * BUGS
679 * SEE ALSO
681 ****************************************************************************
685 static BOOL CmdBroadcast(struct IOSana2Req *request,
686 struct DevBase *base)
688 /* Fill in the broadcast address as destination */
690 *((ULONG *)request->ios2_DstAddr) = 0xffffffff;
691 *((UWORD *)(request->ios2_DstAddr + 4)) = 0xffff;
693 /* Queue the write as normal */
695 return CmdWrite(request, base);
700 /****** prism2.device/S2_TRACKTYPE *****************************************
702 * NAME
703 * S2_TRACKTYPE
705 * FUNCTION
707 * INPUTS
708 * ios2_PacketType - packet type to start tracking.
710 * RESULTS
711 * io_Error
712 * ios2_WireError
714 * EXAMPLE
716 * NOTES
718 * BUGS
720 * SEE ALSO
722 ****************************************************************************
726 static BOOL CmdTrackType(struct IOSana2Req *request,
727 struct DevBase *base)
729 struct DevUnit *unit;
730 struct Opener *opener;
731 ULONG packet_type, wire_error;
732 struct TypeTracker *tracker;
733 struct TypeStats *initial_stats;
734 BYTE error = 0;
736 unit = (APTR)request->ios2_Req.io_Unit;
737 packet_type = request->ios2_PacketType;
738 if(packet_type <= ETH_MTU)
739 packet_type = ETH_MTU;
741 /* Get global tracker */
743 tracker = (struct TypeTracker *)
744 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
746 if(tracker != NULL)
747 tracker->user_count++;
748 else
750 tracker =
751 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
752 if(tracker != NULL)
754 tracker->packet_type = packet_type;
755 tracker->user_count = 1;
757 Disable();
758 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
759 Enable();
763 /* Store initial figures for this opener */
765 opener = request->ios2_BufferManagement;
766 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
767 base);
769 if(initial_stats != NULL)
771 error = S2ERR_BAD_STATE;
772 wire_error = S2WERR_ALREADY_TRACKED;
775 if(error == 0)
777 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
778 if(initial_stats == NULL)
780 error = S2ERR_NO_RESOURCES;
781 wire_error = S2WERR_GENERIC_ERROR;
785 if(error == 0)
787 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
788 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
791 /* Return */
793 request->ios2_Req.io_Error = error;
794 request->ios2_WireError = wire_error;
795 return TRUE;
800 /****** prism2.device/S2_UNTRACKTYPE ***************************************
802 * NAME
803 * S2_UNTRACKTYPE
805 * FUNCTION
807 * INPUTS
808 * ios2_PacketType - packet type to stop tracking.
810 * RESULTS
811 * io_Error
812 * ios2_WireError
814 * EXAMPLE
816 * NOTES
818 * BUGS
820 * SEE ALSO
822 ****************************************************************************
826 static BOOL CmdUntrackType(struct IOSana2Req *request,
827 struct DevBase *base)
829 struct DevUnit *unit;
830 struct Opener *opener;
831 ULONG packet_type;
832 struct TypeTracker *tracker;
833 struct TypeStats *initial_stats;
835 unit = (APTR)request->ios2_Req.io_Unit;
836 packet_type = request->ios2_PacketType;
837 if(packet_type <= ETH_MTU)
838 packet_type = ETH_MTU;
840 /* Get global tracker and initial figures */
842 tracker = (struct TypeTracker *)
843 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
844 opener = request->ios2_BufferManagement;
845 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
846 base);
848 /* Decrement tracker usage and free unused structures */
850 if(initial_stats != NULL)
852 if((--tracker->user_count) == 0)
854 Disable();
855 Remove((APTR)tracker);
856 Enable();
857 FreeMem(tracker, sizeof(struct TypeTracker));
860 Remove((APTR)initial_stats);
861 FreeMem(initial_stats, sizeof(struct TypeStats));
863 else
865 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
866 request->ios2_WireError = S2WERR_NOT_TRACKED;
869 /* Return */
871 return TRUE;
876 /****** prism2.device/S2_GETTYPESTATS **************************************
878 * NAME
879 * S2_GETTYPESTATS
881 * FUNCTION
883 * INPUTS
884 * ios2_PacketType - packet type to get statistics on.
885 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
887 * RESULTS
888 * io_Error
889 * ios2_WireError
891 * EXAMPLE
893 * NOTES
895 * BUGS
897 * SEE ALSO
899 ****************************************************************************
903 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
904 struct DevBase *base)
906 struct DevUnit *unit;
907 struct Opener *opener;
908 ULONG packet_type;
909 struct TypeStats *initial_stats, *tracker;
910 struct Sana2PacketTypeStats *stats;
912 unit = (APTR)request->ios2_Req.io_Unit;
913 packet_type = request->ios2_PacketType;
915 /* Get global tracker and initial figures */
917 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
918 opener = request->ios2_BufferManagement;
919 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
920 base);
922 /* Copy and adjust figures */
924 if(initial_stats != NULL)
926 stats = request->ios2_StatData;
927 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
928 stats->PacketsSent -= initial_stats->stats.PacketsSent;
929 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
930 stats->BytesSent -= initial_stats->stats.BytesSent;
931 stats->BytesReceived -= initial_stats->stats.BytesReceived;
932 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
934 else
936 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
937 request->ios2_WireError = S2WERR_NOT_TRACKED;
940 /* Return */
942 return TRUE;
947 /****** prism2.device/S2_GETSPECIALSTATS ***********************************
949 * NAME
950 * S2_GETSPECIALSTATS
952 * FUNCTION
954 * INPUTS
955 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
957 * RESULTS
958 * io_Error
959 * ios2_WireError
961 * EXAMPLE
963 * NOTES
965 * BUGS
967 * SEE ALSO
969 ****************************************************************************
973 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
974 struct DevBase *base)
976 struct DevUnit *unit;
977 UWORD i, stat_count;
978 struct Sana2SpecialStatHeader *header;
979 struct Sana2SpecialStatRecord *record;
981 /* Fill in stats */
983 unit = (APTR)request->ios2_Req.io_Unit;
984 header = request->ios2_StatData;
985 record = (APTR)(header + 1);
987 stat_count = header->RecordCountMax;
988 if(stat_count > STAT_COUNT)
989 stat_count = STAT_COUNT;
991 for(i = 0; i < stat_count; i++)
993 record->Type = (S2WireType_Ethernet << 16) + i;
994 record->Count = unit->special_stats[i];
995 record->String = special_stat_names[i];
996 record++;
999 header->RecordCountSupplied = stat_count;
1001 /* Return */
1003 return TRUE;
1008 /****** prism2.device/S2_GETGLOBALSTATS ************************************
1010 * NAME
1011 * S2_GETGLOBALSTATS
1013 * FUNCTION
1015 * INPUTS
1016 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1018 * RESULTS
1019 * io_Error
1020 * ios2_WireError
1022 * EXAMPLE
1024 * NOTES
1026 * BUGS
1028 * SEE ALSO
1030 ****************************************************************************
1034 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
1035 struct DevBase *base)
1037 struct DevUnit *unit;
1039 /* Update and copy stats */
1041 unit = (APTR)request->ios2_Req.io_Unit;
1042 if((unit->flags & UNITF_ONLINE) != 0)
1043 UpdateStats(unit, base);
1044 CopyMem(&unit->stats, request->ios2_StatData,
1045 sizeof(struct Sana2DeviceStats));
1047 /* Return */
1049 return TRUE;
1054 /****** prism2.device/S2_ONEVENT *******************************************
1056 * NAME
1057 * S2_ONEVENT
1059 * FUNCTION
1061 * INPUTS
1062 * ios2_WireError
1064 * RESULTS
1065 * io_Error
1066 * ios2_WireError
1068 * EXAMPLE
1070 * NOTES
1072 * BUGS
1074 * SEE ALSO
1076 ****************************************************************************
1080 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
1082 struct DevUnit *unit;
1083 ULONG events, wanted_events;
1084 BOOL complete = FALSE;
1086 /* Check if we understand the event types */
1088 unit = (APTR)request->ios2_Req.io_Unit;
1089 wanted_events = request->ios2_WireError;
1090 if((wanted_events & ~KNOWN_EVENTS) != 0)
1092 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
1093 events = S2WERR_BAD_EVENT;
1095 else
1097 if((unit->flags & UNITF_ONLINE) != 0)
1098 events = S2EVENT_ONLINE;
1099 else
1100 events = S2EVENT_OFFLINE;
1102 events &= wanted_events;
1105 /* Reply request if a wanted event has already occurred */
1107 if(events != 0)
1109 request->ios2_WireError = events;
1110 complete = TRUE;
1112 else
1113 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
1115 /* Return */
1117 return complete;
1122 /****** prism2.device/S2_READORPHAN ****************************************
1124 * NAME
1125 * S2_READORPHAN
1127 * FUNCTION
1129 * INPUTS
1130 * io_Flags
1131 * ios2_Data
1133 * RESULTS
1134 * io_Flags
1135 * io_Error
1136 * ios2_WireError
1137 * ios2_PacketType - A copy of the packet's type field.
1138 * ios2_SrcAddr
1139 * ios2_DstAddr
1140 * ios2_DataLength
1141 * ios2_Data
1144 * EXAMPLE
1146 * NOTES
1148 * BUGS
1150 * SEE ALSO
1152 ****************************************************************************
1156 static BOOL CmdReadOrphan(struct IOSana2Req *request,
1157 struct DevBase *base)
1159 struct DevUnit *unit;
1160 BYTE error = 0;
1161 ULONG wire_error;
1162 BOOL complete = FALSE;
1164 /* Check request is valid */
1166 unit = (APTR)request->ios2_Req.io_Unit;
1167 if((unit->flags & UNITF_ONLINE) == 0)
1169 error = S2ERR_OUTOFSERVICE;
1170 wire_error = S2WERR_UNIT_OFFLINE;
1173 /* Queue request */
1175 if(error == 0)
1176 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
1177 else
1179 request->ios2_Req.io_Error = error;
1180 request->ios2_WireError = wire_error;
1181 complete = TRUE;
1184 /* Return */
1186 return complete;
1191 /****** prism2.device/S2_ONLINE ********************************************
1193 * NAME
1194 * S2_ONLINE
1196 * FUNCTION
1198 * INPUTS
1199 * None.
1201 * RESULTS
1202 * io_Error
1203 * ios2_WireError
1205 * EXAMPLE
1207 * NOTES
1209 * BUGS
1211 * SEE ALSO
1213 ****************************************************************************
1217 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
1219 struct DevUnit *unit;
1220 BYTE error = 0;
1221 ULONG wire_error;
1222 UWORD i;
1224 /* Check request is valid */
1226 unit = (APTR)request->ios2_Req.io_Unit;
1227 if((unit->flags & UNITF_CONFIGURED) == 0)
1229 error = S2ERR_BAD_STATE;
1230 wire_error = S2WERR_NOT_CONFIGURED;
1232 if((unit->flags & UNITF_HAVEADAPTER) == 0)
1234 error = S2ERR_OUTOFSERVICE;
1235 wire_error = S2WERR_RCVREL_HDW_ERR;
1238 /* Clear global and special stats and put adapter back online */
1240 if((error == 0) && ((unit->flags & UNITF_ONLINE) == 0))
1242 unit->stats.PacketsReceived = 0;
1243 unit->stats.PacketsSent = 0;
1244 unit->stats.BadData = 0;
1245 unit->stats.Overruns = 0;
1246 unit->stats.UnknownTypesReceived = 0;
1247 unit->stats.Reconfigurations = 0;
1249 for(i = 0; i < STAT_COUNT; i++)
1250 unit->special_stats[i] = 0;
1252 GoOnline(unit, base);
1255 /* Return */
1257 request->ios2_Req.io_Error = error;
1258 request->ios2_WireError = wire_error;
1259 return TRUE;
1264 /****** prism2.device/S2_OFFLINE *******************************************
1266 * NAME
1267 * S2_OFFLINE
1269 * FUNCTION
1271 * INPUTS
1272 * None.
1274 * RESULTS
1275 * io_Error
1276 * ios2_WireError
1278 * EXAMPLE
1280 * NOTES
1282 * BUGS
1284 * SEE ALSO
1286 ****************************************************************************
1290 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
1292 struct DevUnit *unit;
1294 /* Put adapter offline */
1296 unit = (APTR)request->ios2_Req.io_Unit;
1297 if((unit->flags & UNITF_ONLINE) != 0)
1298 GoOffline(unit, base);
1300 /* Return */
1302 return TRUE;
1307 /****** prism2.device/NSCMD_DEVICEQUERY ************************************
1309 * NAME
1310 * NSCMD_DEVICEQUERY -- Query device capabilities.
1312 * FUNCTION
1314 * INPUTS
1315 * io_Length - ???.
1316 * io_Data - pointer to NSDeviceQueryResult structure.
1318 * RESULTS
1319 * io_Error
1320 * io_Actual - size of structure device can handle.
1322 * EXAMPLE
1324 * NOTES
1326 * BUGS
1328 * SEE ALSO
1330 ****************************************************************************
1332 * Note that we have to pretend the request structure is an IOStdReq.
1336 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1337 struct DevBase *base)
1339 struct NSDeviceQueryResult *info;
1341 /* Set structure size twice */
1343 info = request->io_Data;
1344 request->io_Actual = info->SizeAvailable =
1345 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1347 /* Report device details */
1349 info->DeviceType = NSDEVTYPE_SANA2;
1350 info->DeviceSubType = 0;
1352 info->SupportedCommands = (APTR)supported_commands;
1354 /* Return */
1356 return TRUE;
1361 /****** prism2.device/S2_ADDMULTICASTADDRESS *******************************
1363 * NAME
1364 * S2_ADDMULTICASTADDRESS
1366 * FUNCTION
1368 * INPUTS
1369 * ios2_SrcAddr - multicast address.
1371 * RESULTS
1372 * io_Error
1373 * ios2_WireError
1375 * EXAMPLE
1377 * NOTES
1379 * BUGS
1381 * SEE ALSO
1383 ****************************************************************************
1387 /****** prism2.device/S2_ADDMULTICASTADDRESSES *****************************
1389 * NAME
1390 * S2_ADDMULTICASTADDRESSES
1392 * FUNCTION
1394 * INPUTS
1395 * ios2_SrcAddr - lower bound.
1396 * ios2_DstAddr - upper bound.
1398 * RESULTS
1399 * io_Error
1400 * ios2_WireError
1402 * EXAMPLE
1404 * NOTES
1406 * BUGS
1408 * SEE ALSO
1410 ****************************************************************************
1414 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1415 struct DevBase *base)
1417 struct DevUnit *unit;
1418 UBYTE *lower_bound, *upper_bound;
1420 unit = (APTR)request->ios2_Req.io_Unit;
1422 lower_bound = request->ios2_SrcAddr;
1423 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1424 upper_bound = lower_bound;
1425 else
1426 upper_bound = request->ios2_DstAddr;
1428 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1430 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1431 request->ios2_WireError = S2WERR_GENERIC_ERROR;
1434 /* Return */
1436 return TRUE;
1441 /****** prism2.device/S2_DELMULTICASTADDRESS *******************************
1443 * NAME
1444 * S2_DELMULTICASTADDRESS
1446 * FUNCTION
1448 * INPUTS
1449 * ios2_SrcAddr - multicast address.
1451 * RESULTS
1452 * io_Error
1453 * ios2_WireError
1455 * EXAMPLE
1457 * NOTES
1459 * BUGS
1461 * SEE ALSO
1463 ****************************************************************************
1467 /****** prism2.device/S2_DELMULTICASTADDRESSES *****************************
1469 * NAME
1470 * S2_DELMULTICASTADDRESSES
1472 * FUNCTION
1474 * INPUTS
1475 * ios2_SrcAddr - lower bound.
1476 * ios2_DstAddr - upper bound.
1478 * RESULTS
1479 * io_Error
1480 * ios2_WireError
1482 * EXAMPLE
1484 * NOTES
1486 * BUGS
1488 * SEE ALSO
1490 ****************************************************************************
1494 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1495 struct DevBase *base)
1497 struct DevUnit *unit;
1498 UBYTE *lower_bound, *upper_bound;
1500 unit = (APTR)request->ios2_Req.io_Unit;
1502 lower_bound = request->ios2_SrcAddr;
1503 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1504 upper_bound = lower_bound;
1505 else
1506 upper_bound = request->ios2_DstAddr;
1508 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1510 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
1511 request->ios2_WireError = S2WERR_BAD_MULTICAST;
1514 /* Return */
1516 return TRUE;
1521 /****** prism2.device/P2_GETSIGNALQUALITY **********************************
1523 * NAME
1524 * P2_GETSIGNALQUALITY -- Get signal quality statistics.
1526 * FUNCTION
1527 * This command fills in the supplied Sana2SignalQuality structure with
1528 * current signal and noise levels. The unit for these figures is dBm.
1529 * Typically, they are negative values.
1531 * INPUTS
1532 * ios2_StatData - Pointer to Sana2SignalQuality structure.
1534 * RESULTS
1535 * io_Error - Zero if successful; non-zero otherwise.
1536 * ios2_WireError - More specific error code.
1538 ****************************************************************************
1542 static BOOL CmdGetSignalQuality(struct IOSana2Req *request,
1543 struct DevBase *base)
1545 struct DevUnit *unit;
1547 /* Update and copy stats */
1549 unit = (APTR)request->ios2_Req.io_Unit;
1550 if((unit->flags & UNITF_ONLINE) != 0)
1552 if((unit->flags & UNITF_ONLINE) != 0)
1553 UpdateSignalQuality(unit, base);
1554 CopyMem(&unit->signal_quality, request->ios2_StatData,
1555 sizeof(struct Sana2SignalQuality));
1557 else
1559 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
1560 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
1564 /* Return */
1566 return TRUE;
1571 /****i* prism2.device/PutRequest *******************************************
1573 * NAME
1574 * PutRequest
1576 * SYNOPSIS
1577 * PutRequest(port, request)
1579 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1581 * FUNCTION
1583 * INPUTS
1584 * port
1585 * request
1587 * RESULT
1588 * None.
1590 ****************************************************************************
1594 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1595 struct DevBase *base)
1597 request->io_Flags &= ~IOF_QUICK;
1598 PutMsg(port, (APTR)request);
1600 return;