Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / intelpro100 / request.c
blob316db04a70e4cc889ec195b6f6acd8f270972004
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,
105 static const struct Sana2DeviceQuery sana2_info =
111 ETH_ADDRESSSIZE * 8,
112 ETH_MTU,
114 S2WireType_Ethernet
117 const TEXT badmulticast_name[] = "Bad multicasts";
118 const TEXT retries_name[] = "Retries";
119 const TEXT fifo_underruns_name[] = "Underruns";
121 const TEXT *const special_stat_names[] =
123 badmulticast_name,
124 retries_name,
125 fifo_underruns_name
130 /****i* intelpro100.device/ServiceRequest **********************************
132 * NAME
133 * ServiceRequest -- Attempt to service a device request.
135 * SYNOPSIS
136 * ServiceRequest(request)
138 * VOID ServiceRequest(struct IORequest *);
140 * FUNCTION
141 * Attempts to carry out a request. The relevant unit's semaphore must
142 * be obtained before calling this function. This function releases the
143 * semaphore before returning.
145 * INPUTS
146 * request - The request to service.
148 * RESULT
149 * None.
151 ****************************************************************************
155 VOID ServiceRequest(struct IOSana2Req *request, struct DevBase *base)
157 BOOL complete;
159 switch(request->ios2_Req.io_Command)
161 case CMD_READ:
162 complete = CmdRead(request, base);
163 break;
164 case CMD_WRITE:
165 complete = CmdWrite(request, base);
166 break;
167 case CMD_FLUSH:
168 complete = CmdFlush((APTR)request, base);
169 break;
170 case S2_DEVICEQUERY:
171 complete = CmdS2DeviceQuery((APTR)request, base);
172 break;
173 case S2_GETSTATIONADDRESS:
174 complete = CmdGetStationAddress((APTR)request, base);
175 break;
176 case S2_CONFIGINTERFACE:
177 complete = CmdConfigInterface((APTR)request, base);
178 break;
179 case S2_ADDMULTICASTADDRESS:
180 complete = CmdAddMulticastAddresses((APTR)request, base);
181 break;
182 case S2_DELMULTICASTADDRESS:
183 complete = CmdDelMulticastAddresses((APTR)request, base);
184 break;
185 case S2_MULTICAST:
186 complete = CmdWrite((APTR)request, base);
187 break;
188 case S2_BROADCAST:
189 complete = CmdBroadcast((APTR)request, base);
190 break;
191 case S2_TRACKTYPE:
192 complete = CmdTrackType((APTR)request, base);
193 break;
194 case S2_UNTRACKTYPE:
195 complete = CmdUntrackType((APTR)request, base);
196 break;
197 case S2_GETTYPESTATS:
198 complete = CmdGetTypeStats((APTR)request, base);
199 break;
200 case S2_GETSPECIALSTATS:
201 complete = CmdGetSpecialStats((APTR)request, base);
202 break;
203 case S2_GETGLOBALSTATS:
204 complete = CmdGetGlobalStats((APTR)request, base);
205 break;
206 case S2_ONEVENT:
207 complete = CmdOnEvent((APTR)request, base);
208 break;
209 case S2_READORPHAN:
210 complete = CmdReadOrphan((APTR)request, base);
211 break;
212 case S2_ONLINE:
213 complete = CmdOnline((APTR)request, base);
214 break;
215 case S2_OFFLINE:
216 complete = CmdOffline((APTR)request, base);
217 break;
218 case NSCMD_DEVICEQUERY:
219 complete = CmdDeviceQuery((APTR)request, base);
220 break;
221 case S2_ADDMULTICASTADDRESSES:
222 complete = CmdAddMulticastAddresses((APTR)request, base);
223 break;
224 case S2_DELMULTICASTADDRESSES:
225 complete = CmdDelMulticastAddresses((APTR)request, base);
226 break;
227 default:
228 complete = CmdInvalid((APTR)request, base);
231 if(complete && ((request->ios2_Req.io_Flags & IOF_QUICK) == 0))
232 ReplyMsg((APTR)request);
234 ReleaseSemaphore(&((struct DevUnit *)request->ios2_Req.io_Unit)->
235 access_lock);
236 return;
241 /****i* intelpro100.device/CMD_INVALID *************************************
243 * NAME
244 * CMD_INVALID -- Reject invalid commands.
246 * FUNCTION
247 * See SANA-II documentation.
249 ****************************************************************************
253 static BOOL CmdInvalid(struct IOSana2Req *request, struct DevBase *base)
255 request->ios2_Req.io_Error = IOERR_NOCMD;
256 request->ios2_WireError = S2WERR_GENERIC_ERROR;
258 return TRUE;
263 /****** intelpro100.device/CMD_READ ****************************************
265 * NAME
266 * CMD_READ -- Read data.
268 * FUNCTION
269 * See SANA-II documentation.
271 ****************************************************************************
275 static BOOL CmdRead(struct IOSana2Req *request, struct DevBase *base)
277 struct DevUnit *unit;
278 struct Opener *opener;
279 BOOL complete = FALSE;
281 unit = (APTR)request->ios2_Req.io_Unit;
283 if((unit->flags & UNITF_ONLINE) != 0)
285 opener = request->ios2_BufferManagement;
286 PutRequest(&opener->read_port, (APTR)request, base);
288 else
290 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
291 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
292 complete = TRUE;
295 /* Return */
297 return complete;
302 /****** intelpro100.device/CMD_WRITE ***************************************
304 * NAME
305 * CMD_WRITE -- Write data.
307 * FUNCTION
308 * See SANA-II documentation.
310 ****************************************************************************
314 /****** intelpro100.device/S2_MULTICAST ************************************
316 * NAME
317 * S2_MULTICAST
319 * FUNCTION
320 * See SANA-II documentation.
322 ****************************************************************************
326 static BOOL CmdWrite(struct IOSana2Req *request, struct DevBase *base)
328 struct DevUnit *unit;
329 BYTE error = 0;
330 ULONG wire_error;
331 BOOL complete = FALSE;
333 /* Check request is valid */
335 unit = (APTR)request->ios2_Req.io_Unit;
336 if((unit->flags & UNITF_ONLINE) == 0)
338 error = S2ERR_OUTOFSERVICE;
339 wire_error = S2WERR_UNIT_OFFLINE;
341 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
342 ((request->ios2_DstAddr[0] & 0x1) == 0))
344 error = S2ERR_BAD_ADDRESS;
345 wire_error = S2WERR_BAD_MULTICAST;
348 /* Queue request for sending */
350 if(error == 0)
351 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
352 else
354 request->ios2_Req.io_Error = error;
355 request->ios2_WireError = wire_error;
356 complete = TRUE;
359 /* Return */
361 return complete;
366 /****** intelpro100.device/CMD_FLUSH ***************************************
368 * NAME
369 * CMD_FLUSH
371 * FUNCTION
372 * See SANA-II documentation.
374 ****************************************************************************
378 static BOOL CmdFlush(struct IORequest *request, struct DevBase *base)
380 FlushUnit((APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED, base);
382 return TRUE;
387 /****** intelpro100.device/S2_DEVICEQUERY **********************************
389 * NAME
390 * S2_DEVICEQUERY -- Query device capabilities.
392 * FUNCTION
393 * See SANA-II documentation.
395 ****************************************************************************
399 static BOOL CmdS2DeviceQuery(struct IOSana2Req *request,
400 struct DevBase *base)
402 struct DevUnit *unit;
403 struct Sana2DeviceQuery *info;
404 ULONG size_available, size;
406 /* Copy device info */
408 unit = (APTR)request->ios2_Req.io_Unit;
409 info = request->ios2_StatData;
410 size = size_available = info->SizeAvailable;
411 if(size > sizeof(struct Sana2DeviceQuery))
412 size = sizeof(struct Sana2DeviceQuery);
414 CopyMem(&sana2_info, info, size);
415 info->BPS = unit->speed;
417 info->SizeAvailable = size_available;
418 info->SizeSupplied = size;
420 /* Return */
422 return TRUE;
427 /****** intelpro100.device/S2_GETSTATIONADDDRESS ***************************
429 * NAME
430 * S2_GETSTATIONADDDRESS
432 * FUNCTION
433 * See SANA-II documentation.
435 ****************************************************************************
439 static BOOL CmdGetStationAddress(struct IOSana2Req *request,
440 struct DevBase *base)
442 struct DevUnit *unit;
444 /* Copy addresses */
446 unit = (APTR)request->ios2_Req.io_Unit;
447 CopyMem(unit->address, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
448 CopyMem(unit->default_address, request->ios2_DstAddr, ETH_ADDRESSSIZE);
450 /* Return */
452 return TRUE;
457 /****** intelpro100.device/S2_CONFIGINTERFACE ******************************
459 * NAME
460 * S2_CONFIGINTERFACE --
462 * FUNCTION
463 * See SANA-II documentation.
465 ****************************************************************************
469 static BOOL CmdConfigInterface(struct IOSana2Req *request,
470 struct DevBase *base)
472 struct DevUnit *unit;
474 /* Configure adapter */
476 unit = (APTR)request->ios2_Req.io_Unit;
477 if((unit->flags & UNITF_CONFIGURED) == 0)
479 CopyMem(request->ios2_SrcAddr, unit->address, ETH_ADDRESSSIZE);
480 if((unit->flags & UNITF_HAVEADAPTER) != 0)
481 ConfigureAdapter(unit, base);
482 unit->flags |= UNITF_CONFIGURED;
484 else
486 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
487 request->ios2_WireError = S2WERR_IS_CONFIGURED;
490 /* Return */
492 return TRUE;
497 /****** intelpro100.device/S2_BROADCAST ************************************
499 * NAME
500 * S2_BROADCAST
502 * FUNCTION
503 * See SANA-II documentation.
505 ****************************************************************************
509 static BOOL CmdBroadcast(struct IOSana2Req *request,
510 struct DevBase *base)
512 /* Fill in the broadcast address as destination */
514 memset(request->ios2_DstAddr, 0xff, 6);
516 /* Queue the write as normal */
518 return CmdWrite(request, base);
523 /****** intelpro100.device/S2_TRACKTYPE ************************************
525 * NAME
526 * S2_TRACKTYPE
528 * FUNCTION
529 * See SANA-II documentation.
531 ****************************************************************************
535 static BOOL CmdTrackType(struct IOSana2Req *request,
536 struct DevBase *base)
538 struct DevUnit *unit;
539 struct Opener *opener;
540 ULONG packet_type, wire_error;
541 struct TypeTracker *tracker;
542 struct TypeStats *initial_stats;
543 BYTE error = 0;
545 unit = (APTR)request->ios2_Req.io_Unit;
546 packet_type = request->ios2_PacketType;
548 /* Get global tracker */
550 tracker = (struct TypeTracker *)
551 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
553 if(tracker != NULL)
554 tracker->user_count++;
555 else
557 tracker =
558 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC | MEMF_CLEAR);
559 if(tracker != NULL)
561 tracker->packet_type = packet_type;
562 tracker->user_count = 1;
564 Disable();
565 AddTail((APTR)&unit->type_trackers, (APTR)tracker);
566 Enable();
570 /* Store initial figures for this opener */
572 opener = request->ios2_BufferManagement;
573 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
574 base);
576 if(initial_stats != NULL)
578 error = S2ERR_BAD_STATE;
579 wire_error = S2WERR_ALREADY_TRACKED;
582 if(error == 0)
584 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
585 if(initial_stats == NULL)
587 error = S2ERR_NO_RESOURCES;
588 wire_error = S2WERR_GENERIC_ERROR;
592 if(error == 0)
594 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
595 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
598 /* Return */
600 request->ios2_Req.io_Error = error;
601 request->ios2_WireError = wire_error;
602 return TRUE;
607 /****** intelpro100.device/S2_UNTRACKTYPE **********************************
609 * NAME
610 * S2_UNTRACKTYPE
612 * FUNCTION
613 * See SANA-II documentation.
615 ****************************************************************************
619 static BOOL CmdUntrackType(struct IOSana2Req *request,
620 struct DevBase *base)
622 struct DevUnit *unit;
623 struct Opener *opener;
624 ULONG packet_type;
625 struct TypeTracker *tracker;
626 struct TypeStats *initial_stats;
628 unit = (APTR)request->ios2_Req.io_Unit;
629 packet_type = request->ios2_PacketType;
631 /* Get global tracker and initial figures */
633 tracker = (struct TypeTracker *)
634 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
635 opener = request->ios2_BufferManagement;
636 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
637 base);
639 /* Decrement tracker usage and free unused structures */
641 if(initial_stats != NULL)
643 if((--tracker->user_count) == 0)
645 Disable();
646 Remove((APTR)tracker);
647 Enable();
648 FreeMem(tracker, sizeof(struct TypeTracker));
651 Remove((APTR)initial_stats);
652 FreeMem(initial_stats, sizeof(struct TypeStats));
654 else
656 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
657 request->ios2_WireError = S2WERR_NOT_TRACKED;
660 /* Return */
662 return TRUE;
667 /****** intelpro100.device/S2_GETTYPESTATS *********************************
669 * NAME
670 * S2_GETTYPESTATS
672 * FUNCTION
673 * See SANA-II documentation.
675 ****************************************************************************
679 static BOOL CmdGetTypeStats(struct IOSana2Req *request,
680 struct DevBase *base)
682 struct DevUnit *unit;
683 struct Opener *opener;
684 ULONG packet_type;
685 struct TypeStats *initial_stats, *tracker;
686 struct Sana2PacketTypeStats *stats;
688 unit = (APTR)request->ios2_Req.io_Unit;
689 packet_type = request->ios2_PacketType;
691 /* Get global tracker and initial figures */
693 tracker = FindTypeStats(unit, &unit->type_trackers, packet_type, base);
694 opener = request->ios2_BufferManagement;
695 initial_stats = FindTypeStats(unit, &opener->initial_stats, packet_type,
696 base);
698 /* Copy and adjust figures */
700 if(initial_stats != NULL)
702 stats = request->ios2_StatData;
703 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
704 stats->PacketsSent -= initial_stats->stats.PacketsSent;
705 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
706 stats->BytesSent -= initial_stats->stats.BytesSent;
707 stats->BytesReceived -= initial_stats->stats.BytesReceived;
708 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
710 else
712 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
713 request->ios2_WireError = S2WERR_NOT_TRACKED;
716 /* Return */
718 return TRUE;
723 /****** intelpro100.device/S2_GETSPECIALSTATS ******************************
725 * NAME
726 * S2_GETSPECIALSTATS
728 * FUNCTION
729 * See SANA-II documentation.
731 ****************************************************************************
735 static BOOL CmdGetSpecialStats(struct IOSana2Req *request,
736 struct DevBase *base)
738 struct DevUnit *unit;
739 UWORD i, stat_count;
740 struct Sana2SpecialStatHeader *header;
741 struct Sana2SpecialStatRecord *record;
743 /* Update and fill in stats */
745 unit = (APTR)request->ios2_Req.io_Unit;
746 if((unit->flags & UNITF_ONLINE) != 0)
748 Disable();
749 UpdateStats(unit, base);
750 Enable();
753 header = request->ios2_StatData;
754 record = (APTR)(header + 1);
756 stat_count = header->RecordCountMax;
757 if(stat_count > SPECIAL_STAT_COUNT)
758 stat_count = SPECIAL_STAT_COUNT;
760 for(i = 0; i < stat_count; i++)
762 record->Type = (S2WireType_Ethernet << 16) + i;
763 record->Count = unit->special_stats[i];
764 record->String = special_stat_names[i];
765 record++;
768 header->RecordCountSupplied = stat_count;
770 /* Return */
772 return TRUE;
777 /****** intelpro100.device/S2_GETGLOBALSTATS *******************************
779 * NAME
780 * S2_GETGLOBALSTATS
782 * FUNCTION
783 * See SANA-II documentation.
785 ****************************************************************************
789 static BOOL CmdGetGlobalStats(struct IOSana2Req *request,
790 struct DevBase *base)
792 struct DevUnit *unit;
794 /* Update and copy stats */
796 unit = (APTR)request->ios2_Req.io_Unit;
797 if((unit->flags & UNITF_ONLINE) != 0)
799 Disable();
800 UpdateStats(unit, base);
801 Enable();
803 CopyMem(&unit->stats, request->ios2_StatData,
804 sizeof(struct Sana2DeviceStats));
806 /* Return */
808 return TRUE;
813 /****** intelpro100.device/S2_ONEVENT **************************************
815 * NAME
816 * S2_ONEVENT --
818 * FUNCTION
819 * See SANA-II documentation.
821 ****************************************************************************
825 static BOOL CmdOnEvent(struct IOSana2Req *request, struct DevBase *base)
827 struct DevUnit *unit;
828 ULONG events, wanted_events;
829 BOOL complete = FALSE;
831 /* Check if we understand the event types */
833 unit = (APTR)request->ios2_Req.io_Unit;
834 wanted_events = request->ios2_WireError;
835 if((wanted_events & ~KNOWN_EVENTS) != 0)
837 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
838 events = S2WERR_BAD_EVENT;
840 else
842 if((unit->flags & UNITF_ONLINE) != 0)
843 events = S2EVENT_ONLINE;
844 else
845 events = S2EVENT_OFFLINE;
847 events &= wanted_events;
850 /* Reply request if a wanted event has already occurred */
852 if(events != 0)
854 request->ios2_WireError = events;
855 complete = TRUE;
857 else
858 PutRequest(unit->request_ports[EVENT_QUEUE], (APTR)request, base);
860 /* Return */
862 return complete;
867 /****** intelpro100.device/S2_READORPHAN ***********************************
869 * NAME
870 * S2_READORPHAN
872 * FUNCTION
873 * See SANA-II documentation.
875 ****************************************************************************
879 static BOOL CmdReadOrphan(struct IOSana2Req *request,
880 struct DevBase *base)
882 struct DevUnit *unit;
883 BYTE error = 0;
884 ULONG wire_error;
885 BOOL complete = FALSE;
887 /* Check request is valid */
889 unit = (APTR)request->ios2_Req.io_Unit;
890 if((unit->flags & UNITF_ONLINE) == 0)
892 error = S2ERR_OUTOFSERVICE;
893 wire_error = S2WERR_UNIT_OFFLINE;
896 /* Queue request */
898 if(error == 0)
899 PutRequest(unit->request_ports[ADOPT_QUEUE], (APTR)request, base);
900 else
902 request->ios2_Req.io_Error = error;
903 request->ios2_WireError = wire_error;
904 complete = TRUE;
907 /* Return */
909 return complete;
914 /****** intelpro100.device/S2_ONLINE ***************************************
916 * NAME
917 * S2_ONLINE
919 * FUNCTION
920 * See SANA-II documentation.
922 ****************************************************************************
926 static BOOL CmdOnline(struct IOSana2Req *request, struct DevBase *base)
928 struct DevUnit *unit;
929 BYTE error = 0;
930 ULONG wire_error;
931 UWORD i;
933 /* Check request is valid */
935 unit = (APTR)request->ios2_Req.io_Unit;
936 if((unit->flags & UNITF_CONFIGURED) == 0)
938 error = S2ERR_BAD_STATE;
939 wire_error = S2WERR_NOT_CONFIGURED;
941 if((unit->flags & UNITF_HAVEADAPTER) == 0)
943 error = S2ERR_OUTOFSERVICE;
944 wire_error = S2WERR_RCVREL_HDW_ERR;
947 /* Clear global and special stats and put adapter back online */
949 if((error == 0) && ((unit->flags & UNITF_ONLINE) == 0))
951 UpdateStats(unit, base);
952 unit->stats.PacketsReceived = 0;
953 unit->stats.PacketsSent = 0;
954 unit->stats.BadData = 0;
955 unit->stats.Overruns = 0;
956 unit->stats.UnknownTypesReceived = 0;
957 unit->stats.Reconfigurations = 0;
959 for(i = 0; i < SPECIAL_STAT_COUNT; i++)
960 unit->special_stats[i] = 0;
962 GoOnline(unit, base);
965 /* Return */
967 request->ios2_Req.io_Error = error;
968 request->ios2_WireError = wire_error;
969 return TRUE;
974 /****** intelpro100.device/S2_OFFLINE **************************************
976 * NAME
977 * S2_OFFLINE
979 * FUNCTION
980 * See SANA-II documentation.
982 ****************************************************************************
986 static BOOL CmdOffline(struct IOSana2Req *request, struct DevBase *base)
988 struct DevUnit *unit;
990 /* Put adapter offline */
992 unit = (APTR)request->ios2_Req.io_Unit;
993 if((unit->flags & UNITF_ONLINE) != 0)
994 GoOffline(unit, base);
996 /* Return */
998 return TRUE;
1003 /****** intelpro100.device/NSCMD_DEVICEQUERY *******************************
1005 * NAME
1006 * NSCMD_DEVICEQUERY -- Query device capabilities.
1008 * FUNCTION
1009 * See New-style Device documentation.
1011 ****************************************************************************
1013 * Note that we have to pretend the request structure is an IOStdReq.
1017 static BOOL CmdDeviceQuery(struct IOStdReq *request,
1018 struct DevBase *base)
1020 struct NSDeviceQueryResult *info;
1022 /* Set structure size twice */
1024 info = request->io_Data;
1025 request->io_Actual = info->SizeAvailable =
1026 (ULONG)OFFSET(NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
1028 /* Report device details */
1030 info->DeviceType = NSDEVTYPE_SANA2;
1031 info->DeviceSubType = 0;
1033 info->SupportedCommands = (APTR)supported_commands;
1035 /* Return */
1037 return TRUE;
1042 /****** intelpro100.device/S2_ADDMULTICASTADDRESS **************************
1044 * NAME
1045 * S2_ADDMULTICASTADDRESS
1047 * FUNCTION
1048 * See SANA-II documentation.
1050 ****************************************************************************
1054 /****** intelpro100.device/S2_ADDMULTICASTADDRESSES ************************
1056 * NAME
1057 * S2_ADDMULTICASTADDRESSES
1059 * FUNCTION
1060 * See SANA-II documentation.
1062 ****************************************************************************
1066 static BOOL CmdAddMulticastAddresses(struct IOSana2Req *request,
1067 struct DevBase *base)
1069 struct DevUnit *unit;
1070 BYTE error = 0;
1071 ULONG wire_error;
1072 BOOL complete = FALSE;
1073 UBYTE *lower_bound, *upper_bound;
1075 unit = (APTR)request->ios2_Req.io_Unit;
1077 lower_bound = request->ios2_SrcAddr;
1078 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
1079 upper_bound = lower_bound;
1080 else
1081 upper_bound = request->ios2_DstAddr;
1083 if(!AddMulticastRange(unit, lower_bound, upper_bound, base))
1085 error = S2ERR_NO_RESOURCES;
1086 wire_error = S2WERR_GENERIC_ERROR;
1089 /* Update hardware filter if unit is online */
1091 if(error == 0 && (unit->flags & UNITF_ONLINE) != 0
1092 && (unit->flags & UNITF_PROM) == 0)
1094 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
1096 else
1098 request->ios2_Req.io_Error = error;
1099 request->ios2_WireError = wire_error;
1100 complete = TRUE;
1103 /* Return */
1105 return complete;
1110 /****** intelpro100.device/S2_DELMULTICASTADDRESS **************************
1112 * NAME
1113 * S2_DELMULTICASTADDRESS
1115 * FUNCTION
1116 * See SANA-II documentation.
1118 ****************************************************************************
1122 /****** intelpro100.device/S2_DELMULTICASTADDRESSES ************************
1124 * NAME
1125 * S2_DELMULTICASTADDRESSES
1127 * FUNCTION
1128 * See SANA-II documentation.
1130 ****************************************************************************
1134 static BOOL CmdDelMulticastAddresses(struct IOSana2Req *request,
1135 struct DevBase *base)
1137 struct DevUnit *unit;
1138 BYTE error = 0;
1139 ULONG wire_error;
1140 BOOL complete = FALSE;
1141 UBYTE *lower_bound, *upper_bound;
1143 unit = (APTR)request->ios2_Req.io_Unit;
1145 lower_bound = request->ios2_SrcAddr;
1146 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
1147 upper_bound = lower_bound;
1148 else
1149 upper_bound = request->ios2_DstAddr;
1151 if(!RemMulticastRange(unit, lower_bound, upper_bound, base))
1153 error = S2ERR_BAD_STATE;
1154 wire_error = S2WERR_BAD_MULTICAST;
1157 /* Update hardware filter if unit is online */
1159 if(error == 0 && (unit->flags & UNITF_ONLINE) != 0
1160 && (unit->flags & UNITF_PROM) == 0)
1162 PutRequest(unit->request_ports[WRITE_QUEUE], (APTR)request, base);
1164 else
1166 request->ios2_Req.io_Error = error;
1167 request->ios2_WireError = wire_error;
1168 complete = TRUE;
1171 /* Return */
1173 return complete;
1178 /****i* intelpro100.device/PutRequest **************************************
1180 * NAME
1181 * PutRequest
1183 * SYNOPSIS
1184 * PutRequest(port, request)
1186 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1188 ****************************************************************************
1192 VOID PutRequest(struct MsgPort *port, struct IORequest *request,
1193 struct DevBase *base)
1195 request->io_Flags &= ~IOF_QUICK;
1196 PutMsg(port, (APTR)request);
1198 return;