revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / intelpro100 / request.c
blobc83aad711adde9935a7acf9808b9193d430aad0f
1 /*
3 Copyright (C) 2001-2017 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);
46 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
47 struct DevBase *base);
48 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
49 struct DevBase *base);
50 static BOOL CmdConfigInterface(struct IOSana2Req *request,
51 struct DevBase *base);
52 static BOOL CmdBroadcast(struct IOSana2Req *request,
53 struct DevBase *base);
54 static BOOL CmdTrackType(struct IOSana2Req *request,
55 struct DevBase *base);
56 static BOOL CmdUntrackType(struct IOSana2Req *request,
57 struct DevBase *base);
58 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
59 struct DevBase *base);
60 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
61 struct DevBase *base);
62 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
63 struct DevBase *base);
64 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base);
65 static BOOL CmdReadOrphan(struct IOSana2Req *request,
66 struct DevBase *base);
67 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base);
68 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base);
69 static BOOL CmdDeviceQuery(struct IOStdReq *request,
70 struct DevBase *base);
71 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
72 struct DevBase *base);
73 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
74 struct DevBase *base);
77 static const UWORD supported_commands[] =
79 CMD_READ,
80 CMD_WRITE,
81 CMD_FLUSH,
82 S2_DEVICEQUERY,
83 S2_GETSTATIONADDRESS,
84 S2_CONFIGINTERFACE,
85 S2_ADDMULTICASTADDRESS,
86 S2_DELMULTICASTADDRESS,
87 S2_MULTICAST,
88 S2_BROADCAST,
89 S2_TRACKTYPE,
90 S2_UNTRACKTYPE,
91 S2_GETTYPESTATS,
92 S2_GETSPECIALSTATS,
93 S2_GETGLOBALSTATS,
94 S2_ONEVENT,
95 S2_READORPHAN,
96 S2_ONLINE,
97 S2_OFFLINE,
98 NSCMD_DEVICEQUERY,
99 S2_ADDMULTICASTADDRESSES,
100 S2_DELMULTICASTADDRESSES,
104 static const struct Sana2DeviceQuery sana2_info =
110 ETH_ADDRESSSIZE * 8,
111 ETH_MTU,
113 S2WireType_Ethernet
116 const TEXT badmulticast_name[] = "Bad multicasts";
117 const TEXT retries_name[] = "Retries";
118 const TEXT fifo_underruns_name[] = "Underruns";
120 const TEXT *const special_stat_names[] =
122 badmulticast_name,
123 retries_name,
124 fifo_underruns_name
129 /****i* intelpro100.device/ServiceRequest **********************************
131 * NAME
132 * ServiceRequest -- Attempt to service a device request.
134 * SYNOPSIS
135 * ServiceRequest(request)
137 * VOID ServiceRequest(struct IORequest *);
139 * FUNCTION
140 * Attempts to carry out a request. The relevant unit's semaphore must
141 * be obtained before calling this function. This function releases the
142 * semaphore before returning.
144 * INPUTS
145 * request - The request to service.
147 * RESULT
148 * None.
150 ****************************************************************************
154 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
156 BOOL complete;
158 switch(request->ios2_Req.io_Command)
160 case CMD_READ:
161 complete = CmdRead(request, base);
162 break;
163 case CMD_WRITE:
164 complete = CmdWrite(request, base);
165 break;
166 case CMD_FLUSH:
167 complete = CmdFlush((APTR)request, base);
168 break;
169 case S2_DEVICEQUERY:
170 complete = CmdS2DeviceQuery((APTR)request, base);
171 break;
172 case S2_GETSTATIONADDRESS:
173 complete = CmdGetStationAddress((APTR)request, base);
174 break;
175 case S2_CONFIGINTERFACE:
176 complete = CmdConfigInterface((APTR)request, base);
177 break;
178 case S2_ADDMULTICASTADDRESS:
179 complete = CmdAddMulticastAddresses((APTR)request, base);
180 break;
181 case S2_DELMULTICASTADDRESS:
182 complete = CmdDelMulticastAddresses((APTR)request, base);
183 break;
184 case S2_MULTICAST:
185 complete = CmdWrite((APTR)request, base);
186 break;
187 case S2_BROADCAST:
188 complete = CmdBroadcast((APTR)request, base);
189 break;
190 case S2_TRACKTYPE:
191 complete = CmdTrackType((APTR)request, base);
192 break;
193 case S2_UNTRACKTYPE:
194 complete = CmdUntrackType((APTR)request, base);
195 break;
196 case S2_GETTYPESTATS:
197 complete = CmdGetTypeStats((APTR)request, base);
198 break;
199 case S2_GETSPECIALSTATS:
200 complete = CmdGetSpecialStats((APTR)request, base);
201 break;
202 case S2_GETGLOBALSTATS:
203 complete = CmdGetGlobalStats((APTR)request, base);
204 break;
205 case S2_ONEVENT:
206 complete = CmdOnEvent((APTR)request, base);
207 break;
208 case S2_READORPHAN:
209 complete = CmdReadOrphan((APTR)request, base);
210 break;
211 case S2_ONLINE:
212 complete = CmdOnline((APTR)request, base);
213 break;
214 case S2_OFFLINE:
215 complete = CmdOffline((APTR)request, base);
216 break;
217 case NSCMD_DEVICEQUERY:
218 complete = CmdDeviceQuery((APTR)request, base);
219 break;
220 case S2_ADDMULTICASTADDRESSES:
221 complete = CmdAddMulticastAddresses((APTR)request, base);
222 break;
223 case S2_DELMULTICASTADDRESSES:
224 complete = CmdDelMulticastAddresses((APTR)request, base);
225 break;
226 default:
227 complete = CmdInvalid((APTR)request, base);
230 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
231 ReplyMsg((APTR)request);
233 ReleaseSemaphore(&((struct DevUnit *)request->ios2_Req.io_Unit)->
234 access_lock);
235 return;
240 /****i* intelpro100.device/CMD_INVALID *************************************
242 * NAME
243 * CMD_INVALID -- Reject invalid commands.
245 * FUNCTION
246 * See SANA-II documentation.
248 ****************************************************************************
252 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
254 request->ios2_Req.io_Error = IOERR_NOCMD;
255 request->ios2_WireError = S2WERR_GENERIC_ERROR;
257 return TRUE;
262 /****** intelpro100.device/CMD_READ ****************************************
264 * NAME
265 * CMD_READ -- Read data.
267 * FUNCTION
268 * See SANA-II documentation.
270 ****************************************************************************
274 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
276 struct DevUnit *unit;
277 struct Opener *opener;
278 BOOL complete = FALSE;
280 unit = (APTR)request->ios2_Req.io_Unit;
282 if((unit->flags & UNITF_ONLINE) != 0)
284 opener = request->ios2_BufferManagement;
285 PutRequest(&opener->read_port, (APTR)request, base);
287 else
289 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
290 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
291 complete = TRUE;
294 /* Return */
296 return complete;
301 /****** intelpro100.device/CMD_WRITE ***************************************
303 * NAME
304 * CMD_WRITE -- Write data.
306 * FUNCTION
307 * See SANA-II documentation.
309 ****************************************************************************
313 /****** intelpro100.device/S2_MULTICAST ************************************
315 * NAME
316 * S2_MULTICAST
318 * FUNCTION
319 * See SANA-II documentation.
321 ****************************************************************************
325 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
327 struct DevUnit *unit;
328 BYTE error = 0;
329 ULONG wire_error;
330 BOOL complete = FALSE;
332 /* Check request is valid */
334 unit = (APTR)request->ios2_Req.io_Unit;
335 if((unit->flags & UNITF_ONLINE) == 0)
337 error = S2ERR_OUTOFSERVICE;
338 wire_error = S2WERR_UNIT_OFFLINE;
340 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
341 ((request->ios2_DstAddr[0] & 0x1) == 0))
343 error = S2ERR_BAD_ADDRESS;
344 wire_error = S2WERR_BAD_MULTICAST;
347 /* Queue request for sending */
349 if(error == 0)
350 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
351 else
353 request->ios2_Req.io_Error = error;
354 request->ios2_WireError = wire_error;
355 complete = TRUE;
358 /* Return */
360 return complete;
365 /****** intelpro100.device/CMD_FLUSH ***************************************
367 * NAME
368 * CMD_FLUSH
370 * FUNCTION
371 * See SANA-II documentation.
373 ****************************************************************************
377 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
379 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
381 return TRUE;
386 /****** intelpro100.device/S2_DEVICEQUERY **********************************
388 * NAME
389 * S2_DEVICEQUERY -- Query device capabilities.
391 * FUNCTION
392 * See SANA-II documentation.
394 ****************************************************************************
398 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
399 struct DevBase *base)
401 struct DevUnit *unit;
402 struct Sana2DeviceQuery *info;
403 ULONG size_available, size;
405 /* Copy device info */
407 unit = (APTR)request->ios2_Req.io_Unit;
408 info = request->ios2_StatData;
409 size = size_available = info->SizeAvailable;
410 if(size > sizeof(struct Sana2DeviceQuery))
411 size = sizeof(struct Sana2DeviceQuery);
413 CopyMem(&sana2_info, info, size);
414 info->BPS = unit->speed;
416 info->SizeAvailable = size_available;
417 info->SizeSupplied = size;
419 /* Return */
421 return TRUE;
426 /****** intelpro100.device/S2_GETSTATIONADDDRESS ***************************
428 * NAME
429 * S2_GETSTATIONADDDRESS
431 * FUNCTION
432 * See SANA-II documentation.
434 ****************************************************************************
438 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
439 struct DevBase *base)
441 struct DevUnit *unit;
443 /* Copy addresses */
445 unit = (APTR)request->ios2_Req.io_Unit;
446 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
447 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
449 /* Return */
451 return TRUE;
456 /****** intelpro100.device/S2_CONFIGINTERFACE ******************************
458 * NAME
459 * S2_CONFIGINTERFACE --
461 * FUNCTION
462 * See SANA-II documentation.
464 ****************************************************************************
468 static BOOL CmdConfigInterface(struct IOSana2Req *request,
469 struct DevBase *base)
471 struct DevUnit *unit;
473 /* Configure adapter */
475 unit = (APTR)request->ios2_Req.io_Unit;
476 if((unit->flags & UNITF_CONFIGURED) == 0)
478 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
479 if((unit->flags & UNITF_HAVEADAPTER) != 0)
480 ConfigureAdapter(unit, base);
481 unit->flags |= UNITF_CONFIGURED;
483 else
485 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
486 request->ios2_WireError = S2WERR_IS_CONFIGURED;
489 /* Return */
491 return TRUE;
496 /****** intelpro100.device/S2_BROADCAST ************************************
498 * NAME
499 * S2_BROADCAST
501 * FUNCTION
502 * See SANA-II documentation.
504 ****************************************************************************
508 static BOOL CmdBroadcast(struct IOSana2Req *request,
509 struct DevBase *base)
511 UWORD i;
513 /* Fill in the broadcast address as destination */
515 for(i = 0; i < ETH_ADDRESSSIZE; i++)
516 request->ios2_DstAddr[i] = 0xff;
518 /* Queue the write as normal */
520 return CmdWrite(request, base);
525 /****** intelpro100.device/S2_TRACKTYPE ************************************
527 * NAME
528 * S2_TRACKTYPE
530 * FUNCTION
531 * See SANA-II documentation.
533 ****************************************************************************
537 static BOOL CmdTrackType(struct IOSana2Req *request,
538 struct DevBase *base)
540 struct DevUnit *unit;
541 struct Opener *opener;
542 ULONG packet_type, wire_error;
543 struct TypeTracker *tracker;
544 struct TypeStats *initial_stats;
545 BYTE error = 0;
547 unit = (APTR)request->ios2_Req.io_Unit;
548 packet_type = request->ios2_PacketType;
550 /* Get global tracker */
552 tracker = (struct TypeTracker *)
553 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
555 if(tracker != NULL)
556 tracker->user_count++;
557 else
559 tracker =
560 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
561 if(tracker != NULL)
563 tracker->packet_type = packet_type;
564 tracker->user_count = 1;
566 Disable();
567 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
568 Enable();
572 /* Store initial figures for this opener */
574 opener = request->ios2_BufferManagement;
575 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
576 base);
578 if(initial_stats != NULL)
580 error = S2ERR_BAD_STATE;
581 wire_error = S2WERR_ALREADY_TRACKED;
584 if(error == 0)
586 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
587 if(initial_stats == NULL)
589 error = S2ERR_NO_RESOURCES;
590 wire_error = S2WERR_GENERIC_ERROR;
594 if(error == 0)
596 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
597 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
600 /* Return */
602 request->ios2_Req.io_Error = error;
603 request->ios2_WireError = wire_error;
604 return TRUE;
609 /****** intelpro100.device/S2_UNTRACKTYPE **********************************
611 * NAME
612 * S2_UNTRACKTYPE
614 * FUNCTION
615 * See SANA-II documentation.
617 ****************************************************************************
621 static BOOL CmdUntrackType(struct IOSana2Req *request,
622 struct DevBase *base)
624 struct DevUnit *unit;
625 struct Opener *opener;
626 ULONG packet_type;
627 struct TypeTracker *tracker;
628 struct TypeStats *initial_stats;
630 unit = (APTR)request->ios2_Req.io_Unit;
631 packet_type = request->ios2_PacketType;
633 /* Get global tracker and initial figures */
635 tracker = (struct TypeTracker *)
636 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
637 opener = request->ios2_BufferManagement;
638 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
639 base);
641 /* Decrement tracker usage and free unused structures */
643 if(initial_stats != NULL)
645 if((--tracker->user_count) == 0)
647 Disable();
648 Remove((APTR)tracker);
649 Enable();
650 FreeMem(tracker, sizeof(struct TypeTracker));
653 Remove((APTR)initial_stats);
654 FreeMem(initial_stats, sizeof(struct TypeStats));
656 else
658 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
659 request->ios2_WireError = S2WERR_NOT_TRACKED;
662 /* Return */
664 return TRUE;
669 /****** intelpro100.device/S2_GETTYPESTATS *********************************
671 * NAME
672 * S2_GETTYPESTATS
674 * FUNCTION
675 * See SANA-II documentation.
677 ****************************************************************************
681 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
682 struct DevBase *base)
684 struct DevUnit *unit;
685 struct Opener *opener;
686 ULONG packet_type;
687 struct TypeStats *initial_stats, *tracker;
688 struct Sana2PacketTypeStats *stats;
690 unit = (APTR)request->ios2_Req.io_Unit;
691 packet_type = request->ios2_PacketType;
693 /* Get global tracker and initial figures */
695 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
696 opener = request->ios2_BufferManagement;
697 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
698 base);
700 /* Copy and adjust figures */
702 if(initial_stats != NULL)
704 stats = request->ios2_StatData;
705 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
706 stats->PacketsSent -= initial_stats->stats.PacketsSent;
707 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
708 stats->BytesSent -= initial_stats->stats.BytesSent;
709 stats->BytesReceived -= initial_stats->stats.BytesReceived;
710 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
712 else
714 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
715 request->ios2_WireError = S2WERR_NOT_TRACKED;
718 /* Return */
720 return TRUE;
725 /****** intelpro100.device/S2_GETSPECIALSTATS ******************************
727 * NAME
728 * S2_GETSPECIALSTATS
730 * FUNCTION
731 * See SANA-II documentation.
733 ****************************************************************************
737 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
738 struct DevBase *base)
740 struct DevUnit *unit;
741 UWORD i, stat_count;
742 struct Sana2SpecialStatHeader *header;
743 struct Sana2SpecialStatRecord *record;
745 /* Update and fill in stats */
747 unit = (APTR)request->ios2_Req.io_Unit;
748 if((unit->flags & UNITF_ONLINE) != 0)
750 Disable();
751 UpdateStats(unit, base);
752 Enable();
755 header = request->ios2_StatData;
756 record = (APTR)(header + 1);
758 stat_count = header->RecordCountMax;
759 if(stat_count > SPECIAL_STAT_COUNT)
760 stat_count = SPECIAL_STAT_COUNT;
762 for(i = 0; i < stat_count; i++)
764 record->Type = (S2WireType_Ethernet << 16) + i;
765 record->Count = unit->special_stats[i];
766 record->String = special_stat_names[i];
767 record++;
770 header->RecordCountSupplied = stat_count;
772 /* Return */
774 return TRUE;
779 /****** intelpro100.device/S2_GETGLOBALSTATS *******************************
781 * NAME
782 * S2_GETGLOBALSTATS
784 * FUNCTION
785 * See SANA-II documentation.
787 ****************************************************************************
791 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
792 struct DevBase *base)
794 struct DevUnit *unit;
796 /* Update and copy stats */
798 unit = (APTR)request->ios2_Req.io_Unit;
799 if((unit->flags & UNITF_ONLINE) != 0)
801 Disable();
802 UpdateStats(unit, base);
803 Enable();
805 CopyMem(&unit->stats, request->ios2_StatData,
806 sizeof(struct Sana2DeviceStats));
808 /* Return */
810 return TRUE;
815 /****** intelpro100.device/S2_ONEVENT **************************************
817 * NAME
818 * S2_ONEVENT --
820 * FUNCTION
821 * See SANA-II documentation.
823 ****************************************************************************
827 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
829 struct DevUnit *unit;
830 ULONG events, wanted_events;
831 BOOL complete = FALSE;
833 /* Check if we understand the event types */
835 unit = (APTR)request->ios2_Req.io_Unit;
836 wanted_events = request->ios2_WireError;
837 if((wanted_events & ~KNOWN_EVENTS) != 0)
839 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
840 events = S2WERR_BAD_EVENT;
842 else
844 if((unit->flags & UNITF_ONLINE) != 0)
845 events = S2EVENT_ONLINE;
846 else
847 events = S2EVENT_OFFLINE;
849 events &= wanted_events;
852 /* Reply request if a wanted event has already occurred */
854 if(events != 0)
856 request->ios2_WireError = events;
857 complete = TRUE;
859 else
860 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
862 /* Return */
864 return complete;
869 /****** intelpro100.device/S2_READORPHAN ***********************************
871 * NAME
872 * S2_READORPHAN
874 * FUNCTION
875 * See SANA-II documentation.
877 ****************************************************************************
881 static BOOL CmdReadOrphan(struct IOSana2Req *request,
882 struct DevBase *base)
884 struct DevUnit *unit;
885 BYTE error = 0;
886 ULONG wire_error;
887 BOOL complete = FALSE;
889 /* Check request is valid */
891 unit = (APTR)request->ios2_Req.io_Unit;
892 if((unit->flags & UNITF_ONLINE) == 0)
894 error = S2ERR_OUTOFSERVICE;
895 wire_error = S2WERR_UNIT_OFFLINE;
898 /* Queue request */
900 if(error == 0)
901 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
902 else
904 request->ios2_Req.io_Error = error;
905 request->ios2_WireError = wire_error;
906 complete = TRUE;
909 /* Return */
911 return complete;
916 /****** intelpro100.device/S2_ONLINE ***************************************
918 * NAME
919 * S2_ONLINE
921 * FUNCTION
922 * See SANA-II documentation.
924 ****************************************************************************
928 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
930 struct DevUnit *unit;
931 BYTE error = 0;
932 ULONG wire_error;
933 UWORD i;
935 /* Check request is valid */
937 unit = (APTR)request->ios2_Req.io_Unit;
938 if((unit->flags & UNITF_CONFIGURED) == 0)
940 error = S2ERR_BAD_STATE;
941 wire_error = S2WERR_NOT_CONFIGURED;
943 if((unit->flags & UNITF_HAVEADAPTER) == 0)
945 error = S2ERR_OUTOFSERVICE;
946 wire_error = S2WERR_RCVREL_HDW_ERR;
949 /* Clear global and special stats and put adapter back online */
951 if(error == 0 && (unit->flags & UNITF_ONLINE) == 0)
953 UpdateStats(unit, base);
954 unit->stats.PacketsReceived = 0;
955 unit->stats.PacketsSent = 0;
956 unit->stats.BadData = 0;
957 unit->stats.Overruns = 0;
958 unit->stats.UnknownTypesReceived = 0;
959 unit->stats.Reconfigurations = 0;
961 for(i = 0; i < SPECIAL_STAT_COUNT; i++)
962 unit->special_stats[i] = 0;
964 GoOnline(unit, base);
967 /* Return */
969 request->ios2_Req.io_Error = error;
970 request->ios2_WireError = wire_error;
971 return TRUE;
976 /****** intelpro100.device/S2_OFFLINE **************************************
978 * NAME
979 * S2_OFFLINE
981 * FUNCTION
982 * See SANA-II documentation.
984 ****************************************************************************
988 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
990 struct DevUnit *unit;
992 /* Put adapter offline */
994 unit = (APTR)request->ios2_Req.io_Unit;
995 if((unit->flags & UNITF_ONLINE) != 0)
996 GoOffline(unit, base);
998 /* Return */
1000 return TRUE;
1005 /****** intelpro100.device/NSCMD_DEVICEQUERY *******************************
1007 * NAME
1008 * NSCMD_DEVICEQUERY -- Query device capabilities.
1010 * FUNCTION
1011 * See New-style Device documentation.
1013 ****************************************************************************
1015 * Note that we have to pretend the request structure is an IOStdReq.
1019 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1020 struct DevBase *base)
1022 struct NSDeviceQueryResult *info;
1024 /* Set structure size twice */
1026 info = request->io_Data;
1027 request->io_Actual = info->SizeAvailable =
1028 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1030 /* Report device details */
1032 info->DeviceType = NSDEVTYPE_SANA2;
1033 info->DeviceSubType = 0;
1035 info->SupportedCommands = (APTR)supported_commands;
1037 /* Return */
1039 return TRUE;
1044 /****** intelpro100.device/S2_ADDMULTICASTADDRESS **************************
1046 * NAME
1047 * S2_ADDMULTICASTADDRESS
1049 * FUNCTION
1050 * See SANA-II documentation.
1052 ****************************************************************************
1056 /****** intelpro100.device/S2_ADDMULTICASTADDRESSES ************************
1058 * NAME
1059 * S2_ADDMULTICASTADDRESSES
1061 * FUNCTION
1062 * See SANA-II documentation.
1064 ****************************************************************************
1068 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1069 struct DevBase *base)
1071 struct DevUnit *unit;
1072 BYTE error = 0;
1073 ULONG wire_error;
1074 BOOL complete = FALSE;
1075 UBYTE *lower_bound, *upper_bound;
1077 unit = (APTR)request->ios2_Req.io_Unit;
1079 lower_bound = request->ios2_SrcAddr;
1080 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1081 upper_bound = lower_bound;
1082 else
1083 upper_bound = request->ios2_DstAddr;
1085 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1087 error = S2ERR_NO_RESOURCES;
1088 wire_error = S2WERR_GENERIC_ERROR;
1091 /* Update hardware filter if unit is online */
1093 if(error == 0 && (unit->flags & UNITF_ONLINE) != 0
1094 && (unit->flags & UNITF_PROM) == 0)
1096 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
1098 else
1100 request->ios2_Req.io_Error = error;
1101 request->ios2_WireError = wire_error;
1102 complete = TRUE;
1105 /* Return */
1107 return complete;
1112 /****** intelpro100.device/S2_DELMULTICASTADDRESS **************************
1114 * NAME
1115 * S2_DELMULTICASTADDRESS
1117 * FUNCTION
1118 * See SANA-II documentation.
1120 ****************************************************************************
1124 /****** intelpro100.device/S2_DELMULTICASTADDRESSES ************************
1126 * NAME
1127 * S2_DELMULTICASTADDRESSES
1129 * FUNCTION
1130 * See SANA-II documentation.
1132 ****************************************************************************
1136 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1137 struct DevBase *base)
1139 struct DevUnit *unit;
1140 BYTE error = 0;
1141 ULONG wire_error;
1142 BOOL complete = FALSE;
1143 UBYTE *lower_bound, *upper_bound;
1145 unit = (APTR)request->ios2_Req.io_Unit;
1147 lower_bound = request->ios2_SrcAddr;
1148 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1149 upper_bound = lower_bound;
1150 else
1151 upper_bound = request->ios2_DstAddr;
1153 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1155 error = S2ERR_BAD_STATE;
1156 wire_error = S2WERR_BAD_MULTICAST;
1159 /* Update hardware filter if unit is online */
1161 if(error == 0 && (unit->flags & UNITF_ONLINE) != 0
1162 && (unit->flags & UNITF_PROM) == 0)
1164 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
1166 else
1168 request->ios2_Req.io_Error = error;
1169 request->ios2_WireError = wire_error;
1170 complete = TRUE;
1173 /* Return */
1175 return complete;
1180 /****i* intelpro100.device/PutRequest **************************************
1182 * NAME
1183 * PutRequest
1185 * SYNOPSIS
1186 * PutRequest(port, request)
1188 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1190 ****************************************************************************
1194 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1195 struct DevBase *base)
1197 request->io_Flags &= ~IOF_QUICK;
1198 PutMsg(port, (APTR)request);
1200 return;