Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / devs / networks / intelpro100 / request.c
blob3bb25777ac6fc354dcbea869ddd7eb386c6bfa0a
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.
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 /* Fill in the broadcast address as destination */
513 *((ULONG *)request->ios2_DstAddr) = 0xffffffff;
514 *((UWORD *)(request->ios2_DstAddr + 4)) = 0xffff;
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;