3 Copyright (C) 2001-2012 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
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>
33 #include "request_protos.h"
34 #include "unit_protos.h"
37 #define KNOWN_EVENTS \
38 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
39 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
42 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
);
43 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
);
44 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
);
45 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
);
47 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
48 struct DevBase
*base
);
49 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
50 struct DevBase
*base
);
51 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
52 struct DevBase
*base
);
53 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
54 struct DevBase
*base
);
55 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
56 struct DevBase
*base
);
57 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
58 struct DevBase
*base
);
59 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
60 struct DevBase
*base
);
61 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
62 struct DevBase
*base
);
63 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
64 struct DevBase
*base
);
65 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
);
66 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
67 struct DevBase
*base
);
68 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
);
69 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
);
70 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
71 struct DevBase
*base
);
72 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
73 struct DevBase
*base
);
74 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
75 struct DevBase
*base
);
78 static const UWORD supported_commands
[] =
86 S2_ADDMULTICASTADDRESS
,
87 S2_DELMULTICASTADDRESS
,
100 S2_ADDMULTICASTADDRESSES
,
101 S2_DELMULTICASTADDRESSES
,
106 static const struct Sana2DeviceQuery sana2_info
=
119 const TEXT badmulticast_name
[] = "Bad multicasts";
120 const TEXT retries_name
[] = "Retries";
121 const TEXT fifo_underruns_name
[] = "Underruns";
124 const TEXT
*const special_stat_names
[] =
133 /****i* rhine.device/ServiceRequest ****************************************
136 * ServiceRequest -- Attempt to service a device request.
139 * ServiceRequest(request)
141 * VOID ServiceRequest(struct IORequest *);
144 * Attempts to carry out a request. The relevant unit's semaphore must
145 * be obtained before calling this function. This function releases the
146 * semaphore before returning.
162 ****************************************************************************
166 VOID
ServiceRequest(struct IOSana2Req
*request
, struct DevBase
*base
)
170 switch(request
->ios2_Req
.io_Command
)
173 complete
= CmdRead(request
, base
);
176 complete
= CmdWrite(request
, base
);
179 complete
= CmdFlush((APTR
)request
, base
);
182 complete
= CmdS2DeviceQuery(request
, base
);
184 case S2_GETSTATIONADDRESS
:
185 complete
= CmdGetStationAddress(request
, base
);
187 case S2_CONFIGINTERFACE
:
188 complete
= CmdConfigInterface(request
, base
);
190 case S2_ADDMULTICASTADDRESS
:
191 complete
= CmdAddMulticastAddresses(request
, base
);
193 case S2_DELMULTICASTADDRESS
:
194 complete
= CmdDelMulticastAddresses(request
, base
);
197 complete
= CmdWrite(request
, base
);
200 complete
= CmdBroadcast(request
, base
);
203 complete
= CmdTrackType(request
, base
);
206 complete
= CmdUntrackType(request
, base
);
208 case S2_GETTYPESTATS
:
209 complete
= CmdGetTypeStats(request
, base
);
211 case S2_GETSPECIALSTATS
:
212 complete
= CmdGetSpecialStats(request
, base
);
214 case S2_GETGLOBALSTATS
:
215 complete
= CmdGetGlobalStats(request
, base
);
218 complete
= CmdOnEvent(request
, base
);
221 complete
= CmdReadOrphan(request
, base
);
224 complete
= CmdOnline(request
, base
);
227 complete
= CmdOffline(request
, base
);
229 case NSCMD_DEVICEQUERY
:
230 complete
= CmdDeviceQuery((APTR
)request
, base
);
232 case S2_ADDMULTICASTADDRESSES
:
233 complete
= CmdAddMulticastAddresses(request
, base
);
235 case S2_DELMULTICASTADDRESSES
:
236 complete
= CmdDelMulticastAddresses(request
, base
);
239 complete
= CmdInvalid(request
, base
);
242 if(complete
&& ((request
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0))
243 ReplyMsg((APTR
)request
);
246 &((struct DevUnit
*)request
->ios2_Req
.io_Unit
)->access_lock
);
252 /****i* rhine.device/CMD_INVALID *******************************************
255 * CMD_INVALID -- Reject an invalid command.
263 * io_Error - IOERR_NOCMD.
273 ****************************************************************************
277 static BOOL
CmdInvalid(struct IOSana2Req
*request
, struct DevBase
*base
)
279 request
->ios2_Req
.io_Error
= IOERR_NOCMD
;
280 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
287 /****** rhine.device/CMD_READ **********************************************
290 * CMD_READ -- Read data.
316 ****************************************************************************
320 static BOOL
CmdRead(struct IOSana2Req
*request
, struct DevBase
*base
)
322 struct DevUnit
*unit
;
323 struct Opener
*opener
;
324 BOOL complete
= FALSE
;
326 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
328 if((unit
->flags
& UNITF_ONLINE
) != 0)
330 opener
= request
->ios2_BufferManagement
;
331 PutRequest(&opener
->read_port
, (APTR
)request
, base
);
335 request
->ios2_Req
.io_Error
= S2ERR_OUTOFSERVICE
;
336 request
->ios2_WireError
= S2WERR_UNIT_OFFLINE
;
347 /****** rhine.device/CMD_WRITE *********************************************
350 * CMD_WRITE -- Write data.
373 ****************************************************************************
377 /****** rhine.device/S2_MULTICAST ******************************************
386 * ios2_DstAddr - multicast address.
403 ****************************************************************************
407 static BOOL
CmdWrite(struct IOSana2Req
*request
, struct DevBase
*base
)
409 struct DevUnit
*unit
;
412 BOOL complete
= FALSE
;
414 /* Check request is valid */
416 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
417 if((unit
->flags
& UNITF_ONLINE
) == 0)
419 error
= S2ERR_OUTOFSERVICE
;
420 wire_error
= S2WERR_UNIT_OFFLINE
;
422 else if((request
->ios2_Req
.io_Command
== S2_MULTICAST
) &&
423 ((request
->ios2_DstAddr
[0] & 0x1) == 0))
425 error
= S2ERR_BAD_ADDRESS
;
426 wire_error
= S2WERR_BAD_MULTICAST
;
429 /* Queue request for sending */
432 PutRequest(unit
->request_ports
[WRITE_QUEUE
], (APTR
)request
, base
);
435 request
->ios2_Req
.io_Error
= error
;
436 request
->ios2_WireError
= wire_error
;
447 /****** rhine.device/CMD_FLUSH *********************************************
468 ****************************************************************************
472 static BOOL
CmdFlush(struct IORequest
*request
, struct DevBase
*base
)
474 FlushUnit((APTR
)request
->io_Unit
, EVENT_QUEUE
, IOERR_ABORTED
, base
);
481 /****** rhine.device/S2_DEVICEQUERY ****************************************
484 * S2_DEVICEQUERY -- Query device capabilities.
489 * ios2_StatData - Pointer to Sana2DeviceQuery structure.
503 ****************************************************************************
507 static BOOL
CmdS2DeviceQuery(struct IOSana2Req
*request
,
508 struct DevBase
*base
)
510 struct DevUnit
*unit
;
511 struct Sana2DeviceQuery
*info
;
512 ULONG size_available
, size
;
514 /* Copy device info */
516 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
517 info
= request
->ios2_StatData
;
518 size
= size_available
= info
->SizeAvailable
;
519 if(size
> sizeof(struct Sana2DeviceQuery
))
520 size
= sizeof(struct Sana2DeviceQuery
);
522 CopyMem(&sana2_info
, info
, size
);
523 info
->BPS
= unit
->speed
;
525 info
->SizeAvailable
= size_available
;
526 info
->SizeSupplied
= size
;
535 /****** rhine.device/S2_GETSTATIONADDDRESS *********************************
538 * S2_GETSTATIONADDDRESS
548 * ios2_SrcAddr - current address.
549 * ios2_DstAddr - default address (zero if none?).
559 ****************************************************************************
563 static BOOL
CmdGetStationAddress(struct IOSana2Req
*request
,
564 struct DevBase
*base
)
566 struct DevUnit
*unit
;
570 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
571 CopyMem(unit
->address
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
572 CopyMem(unit
->default_address
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
581 /****** rhine.device/S2_CONFIGINTERFACE ************************************
589 * ios2_SrcAddr - address to use.
594 * ios2_SrcAddr - address used.
604 ****************************************************************************
608 static BOOL
CmdConfigInterface(struct IOSana2Req
*request
,
609 struct DevBase
*base
)
611 struct DevUnit
*unit
;
615 /* Configure adapter */
617 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
618 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
620 error
= S2ERR_BAD_STATE
;
621 wire_error
= S2WERR_IS_CONFIGURED
;
623 else if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
625 error
= S2ERR_BAD_STATE
;
626 wire_error
= S2WERR_GENERIC_ERROR
;
631 CopyMem(request
->ios2_SrcAddr
, unit
->address
, ETH_ADDRESSSIZE
);
632 ConfigureAdapter(unit
, base
);
633 GoOnline(unit
, base
);
634 unit
->flags
|= UNITF_CONFIGURED
;
638 request
->ios2_Req
.io_Error
= error
;
639 request
->ios2_WireError
= wire_error
;
649 /****** rhine.device/S2_BROADCAST ******************************************
674 ****************************************************************************
678 static BOOL
CmdBroadcast(struct IOSana2Req
*request
,
679 struct DevBase
*base
)
683 /* Fill in the broadcast address as destination */
685 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
686 request
->ios2_DstAddr
[i
] = 0xff;
688 /* Queue the write as normal */
690 return CmdWrite(request
, base
);
695 /****** rhine.device/S2_TRACKTYPE ******************************************
703 * ios2_PacketType - packet type to start tracking.
717 ****************************************************************************
721 static BOOL
CmdTrackType(struct IOSana2Req
*request
,
722 struct DevBase
*base
)
724 struct DevUnit
*unit
;
725 struct Opener
*opener
;
726 ULONG packet_type
, wire_error
;
727 struct TypeTracker
*tracker
;
728 struct TypeStats
*initial_stats
;
731 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
732 packet_type
= request
->ios2_PacketType
;
733 if(packet_type
<= ETH_MTU
)
734 packet_type
= ETH_MTU
;
736 /* Get global tracker */
738 tracker
= (struct TypeTracker
*)
739 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
742 tracker
->user_count
++;
746 AllocMem(sizeof(struct TypeTracker
), MEMF_PUBLIC
| MEMF_CLEAR
);
749 tracker
->packet_type
= packet_type
;
750 tracker
->user_count
= 1;
753 AddTail((APTR
)&unit
->type_trackers
, (APTR
)tracker
);
758 /* Store initial figures for this opener */
760 opener
= request
->ios2_BufferManagement
;
761 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
764 if(initial_stats
!= NULL
)
766 error
= S2ERR_BAD_STATE
;
767 wire_error
= S2WERR_ALREADY_TRACKED
;
772 initial_stats
= AllocMem(sizeof(struct TypeStats
), MEMF_PUBLIC
);
773 if(initial_stats
== NULL
)
775 error
= S2ERR_NO_RESOURCES
;
776 wire_error
= S2WERR_GENERIC_ERROR
;
782 CopyMem(tracker
, initial_stats
, sizeof(struct TypeStats
));
783 AddTail((APTR
)&opener
->initial_stats
, (APTR
)initial_stats
);
788 request
->ios2_Req
.io_Error
= error
;
789 request
->ios2_WireError
= wire_error
;
795 /****** rhine.device/S2_UNTRACKTYPE ****************************************
803 * ios2_PacketType - packet type to stop tracking.
817 ****************************************************************************
821 static BOOL
CmdUntrackType(struct IOSana2Req
*request
,
822 struct DevBase
*base
)
824 struct DevUnit
*unit
;
825 struct Opener
*opener
;
827 struct TypeTracker
*tracker
;
828 struct TypeStats
*initial_stats
;
830 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
831 packet_type
= request
->ios2_PacketType
;
832 if(packet_type
<= ETH_MTU
)
833 packet_type
= ETH_MTU
;
835 /* Get global tracker and initial figures */
837 tracker
= (struct TypeTracker
*)
838 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
839 opener
= request
->ios2_BufferManagement
;
840 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
843 /* Decrement tracker usage and free unused structures */
845 if(initial_stats
!= NULL
)
847 if((--tracker
->user_count
) == 0)
850 Remove((APTR
)tracker
);
852 FreeMem(tracker
, sizeof(struct TypeTracker
));
855 Remove((APTR
)initial_stats
);
856 FreeMem(initial_stats
, sizeof(struct TypeStats
));
860 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
861 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
871 /****** rhine.device/S2_GETTYPESTATS ***************************************
879 * ios2_PacketType - packet type to get statistics on.
880 * ios2_StatData - pointer to a Sana2PacketTypeStats structure.
894 ****************************************************************************
898 static BOOL
CmdGetTypeStats(struct IOSana2Req
*request
,
899 struct DevBase
*base
)
901 struct DevUnit
*unit
;
902 struct Opener
*opener
;
904 struct TypeStats
*initial_stats
, *tracker
;
905 struct Sana2PacketTypeStats
*stats
;
907 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
908 packet_type
= request
->ios2_PacketType
;
910 /* Get global tracker and initial figures */
912 tracker
= FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
913 opener
= request
->ios2_BufferManagement
;
914 initial_stats
= FindTypeStats(unit
, &opener
->initial_stats
, packet_type
,
917 /* Copy and adjust figures */
919 if(initial_stats
!= NULL
)
921 stats
= request
->ios2_StatData
;
922 CopyMem(&tracker
->stats
, stats
, sizeof(struct Sana2PacketTypeStats
));
923 stats
->PacketsSent
-= initial_stats
->stats
.PacketsSent
;
924 stats
->PacketsReceived
-= initial_stats
->stats
.PacketsReceived
;
925 stats
->BytesSent
-= initial_stats
->stats
.BytesSent
;
926 stats
->BytesReceived
-= initial_stats
->stats
.BytesReceived
;
927 stats
->PacketsDropped
-= initial_stats
->stats
.PacketsDropped
;
931 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
932 request
->ios2_WireError
= S2WERR_NOT_TRACKED
;
942 /****** rhine.device/S2_GETSPECIALSTATS ************************************
950 * ios2_StatData - Pointer to Sana2SpecialStatHeader structure.
964 ****************************************************************************
968 static BOOL
CmdGetSpecialStats(struct IOSana2Req
*request
,
969 struct DevBase
*base
)
971 struct DevUnit
*unit
;
973 struct Sana2SpecialStatHeader
*header
;
974 struct Sana2SpecialStatRecord
*record
;
978 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
979 header
= request
->ios2_StatData
;
980 record
= (APTR
)(header
+ 1);
982 stat_count
= header
->RecordCountMax
;
983 if(stat_count
> STAT_COUNT
)
984 stat_count
= STAT_COUNT
;
986 for(i
= 0; i
< stat_count
; i
++)
988 record
->Type
= (S2WireType_Ethernet
<< 16) + i
;
989 record
->Count
= unit
->special_stats
[i
];
990 record
->String
= special_stat_names
[i
];
994 header
->RecordCountSupplied
= stat_count
;
1003 /****** rhine.device/S2_GETGLOBALSTATS *************************************
1011 * ios2_StatData - Pointer to Sana2DeviceStats structure.
1025 ****************************************************************************
1029 static BOOL
CmdGetGlobalStats(struct IOSana2Req
*request
,
1030 struct DevBase
*base
)
1032 struct DevUnit
*unit
;
1036 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1037 CopyMem(&unit
->stats
, request
->ios2_StatData
,
1038 sizeof(struct Sana2DeviceStats
));
1047 /****** rhine.device/S2_ONEVENT ********************************************
1069 ****************************************************************************
1073 static BOOL
CmdOnEvent(struct IOSana2Req
*request
, struct DevBase
*base
)
1075 struct DevUnit
*unit
;
1076 ULONG events
, wanted_events
;
1077 BOOL complete
= FALSE
;
1079 /* Check if we understand the event types */
1081 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1082 wanted_events
= request
->ios2_WireError
;
1083 if((wanted_events
& ~KNOWN_EVENTS
) != 0)
1085 request
->ios2_Req
.io_Error
= S2ERR_NOT_SUPPORTED
;
1086 events
= S2WERR_BAD_EVENT
;
1090 if((unit
->flags
& UNITF_ONLINE
) != 0)
1091 events
= S2EVENT_ONLINE
;
1093 events
= S2EVENT_OFFLINE
;
1095 events
&= wanted_events
;
1098 /* Reply request if a wanted event has already occurred */
1102 request
->ios2_WireError
= events
;
1106 PutRequest(unit
->request_ports
[EVENT_QUEUE
], (APTR
)request
, base
);
1115 /****** rhine.device/S2_READORPHAN *****************************************
1130 * ios2_PacketType - A copy of the packet's type field.
1145 ****************************************************************************
1149 static BOOL
CmdReadOrphan(struct IOSana2Req
*request
,
1150 struct DevBase
*base
)
1152 struct DevUnit
*unit
;
1155 BOOL complete
= FALSE
;
1157 /* Check request is valid */
1159 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1160 if((unit
->flags
& UNITF_ONLINE
) == 0)
1162 error
= S2ERR_OUTOFSERVICE
;
1163 wire_error
= S2WERR_UNIT_OFFLINE
;
1169 PutRequest(unit
->request_ports
[ADOPT_QUEUE
], (APTR
)request
, base
);
1172 request
->ios2_Req
.io_Error
= error
;
1173 request
->ios2_WireError
= wire_error
;
1184 /****** rhine.device/S2_ONLINE *********************************************
1206 ****************************************************************************
1210 static BOOL
CmdOnline(struct IOSana2Req
*request
, struct DevBase
*base
)
1212 struct DevUnit
*unit
;
1217 /* Check request is valid */
1219 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1220 if((unit
->flags
& UNITF_CONFIGURED
) == 0)
1222 error
= S2ERR_BAD_STATE
;
1223 wire_error
= S2WERR_NOT_CONFIGURED
;
1225 if((unit
->flags
& UNITF_HAVEADAPTER
) == 0)
1227 error
= S2ERR_OUTOFSERVICE
;
1228 wire_error
= S2WERR_RCVREL_HDW_ERR
;
1231 /* Clear global and special stats and put adapter back online */
1233 if((error
== 0) && ((unit
->flags
& UNITF_ONLINE
) == 0))
1235 unit
->stats
.PacketsReceived
= 0;
1236 unit
->stats
.PacketsSent
= 0;
1237 unit
->stats
.BadData
= 0;
1238 unit
->stats
.Overruns
= 0;
1239 unit
->stats
.UnknownTypesReceived
= 0;
1240 unit
->stats
.Reconfigurations
= 0;
1242 for(i
= 0; i
< STAT_COUNT
; i
++)
1243 unit
->special_stats
[i
] = 0;
1245 GoOnline(unit
, base
);
1250 request
->ios2_Req
.io_Error
= error
;
1251 request
->ios2_WireError
= wire_error
;
1257 /****** rhine.device/S2_OFFLINE ********************************************
1279 ****************************************************************************
1283 static BOOL
CmdOffline(struct IOSana2Req
*request
, struct DevBase
*base
)
1285 struct DevUnit
*unit
;
1287 /* Put adapter offline */
1289 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1290 if((unit
->flags
& UNITF_ONLINE
) != 0)
1291 GoOffline(unit
, base
);
1300 /****** rhine.device/NSCMD_DEVICEQUERY *************************************
1303 * NSCMD_DEVICEQUERY -- Query device capabilities.
1309 * io_Data - pointer to NSDeviceQueryResult structure.
1313 * io_Actual - size of structure device can handle.
1323 ****************************************************************************
1325 * Note that we have to pretend the request structure is an IOStdReq.
1329 static BOOL
CmdDeviceQuery(struct IOStdReq
*request
,
1330 struct DevBase
*base
)
1332 struct NSDeviceQueryResult
*info
;
1334 /* Set structure size twice */
1336 info
= request
->io_Data
;
1337 request
->io_Actual
= info
->SizeAvailable
=
1338 (ULONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
) + sizeof(APTR
);
1340 /* Report device details */
1342 info
->DeviceType
= NSDEVTYPE_SANA2
;
1343 info
->DeviceSubType
= 0;
1345 info
->SupportedCommands
= (APTR
)supported_commands
;
1354 /****** rhine.device/S2_ADDMULTICASTADDRESS ********************************
1357 * S2_ADDMULTICASTADDRESS
1362 * ios2_SrcAddr - multicast address.
1376 ****************************************************************************
1380 /****** rhine.device/S2_ADDMULTICASTADDRESSES ******************************
1383 * S2_ADDMULTICASTADDRESSES
1388 * ios2_SrcAddr - lower bound.
1389 * ios2_DstAddr - upper bound.
1403 ****************************************************************************
1407 static BOOL
CmdAddMulticastAddresses(struct IOSana2Req
*request
,
1408 struct DevBase
*base
)
1410 struct DevUnit
*unit
;
1411 UBYTE
*lower_bound
, *upper_bound
;
1413 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1415 lower_bound
= request
->ios2_SrcAddr
;
1416 if(request
->ios2_Req
.io_Command
== S2_ADDMULTICASTADDRESS
)
1417 upper_bound
= lower_bound
;
1419 upper_bound
= request
->ios2_DstAddr
;
1421 if(!AddMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1423 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1424 request
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
1434 /****** rhine.device/S2_DELMULTICASTADDRESS ********************************
1437 * S2_DELMULTICASTADDRESS
1442 * ios2_SrcAddr - multicast address.
1456 ****************************************************************************
1460 /****** rhine.device/S2_DELMULTICASTADDRESSES ******************************
1463 * S2_DELMULTICASTADDRESSES
1468 * ios2_SrcAddr - lower bound.
1469 * ios2_DstAddr - upper bound.
1483 ****************************************************************************
1487 static BOOL
CmdDelMulticastAddresses(struct IOSana2Req
*request
,
1488 struct DevBase
*base
)
1490 struct DevUnit
*unit
;
1491 UBYTE
*lower_bound
, *upper_bound
;
1493 unit
= (APTR
)request
->ios2_Req
.io_Unit
;
1495 lower_bound
= request
->ios2_SrcAddr
;
1496 if(request
->ios2_Req
.io_Command
== S2_DELMULTICASTADDRESS
)
1497 upper_bound
= lower_bound
;
1499 upper_bound
= request
->ios2_DstAddr
;
1501 if(!RemMulticastRange(unit
, lower_bound
, upper_bound
, base
))
1503 request
->ios2_Req
.io_Error
= S2ERR_BAD_STATE
;
1504 request
->ios2_WireError
= S2WERR_BAD_MULTICAST
;
1514 /****i* rhine.device/PutRequest ********************************************
1520 * PutRequest(port, request)
1522 * VOID PutRequest(struct MsgPort *, struct IORequest *);
1533 ****************************************************************************
1537 VOID
PutRequest(struct MsgPort
*port
, struct IORequest
*request
,
1538 struct DevBase
*base
)
1540 request
->io_Flags
&= ~IOF_QUICK
;
1541 PutMsg(port
, (APTR
)request
);