grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / networks / sis900 / handler.c
blobcea1d5ec0ca92b5b36244557ca49e5b94e575b27
1 /*
2 * $Id$
3 */
5 /*
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19 MA 02111-1307, USA.
22 #include <string.h>
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/io.h>
27 #include <exec/ports.h>
28 #include <exec/errors.h>
30 #include <devices/sana2.h>
31 #include <devices/sana2specialstats.h>
32 #include <devices/newstyle.h>
34 #include <utility/utility.h>
35 #include <utility/tagitem.h>
36 #include <utility/hooks.h>
38 #include <proto/exec.h>
39 #include <proto/dos.h>
40 #include <proto/battclock.h>
42 #include <stdlib.h>
44 #include "sis900.h"
45 #include "unit.h"
46 #include LC_LIBDEFS_FILE
48 #define KNOWN_EVENTS \
49 (S2EVENT_ERROR | S2EVENT_TX | S2EVENT_RX | S2EVENT_ONLINE \
50 | S2EVENT_OFFLINE | S2EVENT_BUFF | S2EVENT_HARDWARE | S2EVENT_SOFTWARE)
52 static BOOL CmdInvalid(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
53 static BOOL CmdRead(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
54 static BOOL CmdWrite(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
55 static BOOL CmdFlush(LIBBASETYPEPTR LIBBASE, struct IORequest *request);
56 static BOOL CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
57 static BOOL CmdGetStationAddress(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
58 static BOOL CmdConfigInterface(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
59 static BOOL CmdBroadcast(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
60 static BOOL CmdTrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
61 static BOOL CmdUntrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
62 static BOOL CmdGetTypeStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
63 static BOOL CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
64 static BOOL CmdDeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOStdReq *request);
65 static BOOL CmdOnEvent(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
66 static BOOL CmdReadOrphan(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
67 static BOOL CmdOnline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
68 static BOOL CmdOffline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
69 static BOOL CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
70 static BOOL CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request);
72 static const UWORD supported_commands[] =
74 CMD_READ,
75 CMD_WRITE,
76 CMD_FLUSH,
77 S2_DEVICEQUERY,
78 S2_GETSTATIONADDRESS,
79 S2_CONFIGINTERFACE,
80 S2_ADDMULTICASTADDRESS,
81 S2_DELMULTICASTADDRESS,
82 S2_MULTICAST,
83 S2_BROADCAST,
84 S2_TRACKTYPE,
85 S2_UNTRACKTYPE,
86 S2_GETTYPESTATS,
87 // S2_GETSPECIALSTATS,
88 S2_GETGLOBALSTATS,
89 S2_ONEVENT,
90 S2_READORPHAN,
91 S2_ONLINE,
92 S2_OFFLINE,
93 NSCMD_DEVICEQUERY,
94 S2_ADDMULTICASTADDRESSES,
95 S2_DELMULTICASTADDRESSES,
99 void handle_request(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
101 BOOL complete;
103 switch(request->ios2_Req.io_Command)
105 case CMD_READ:
106 complete = CmdRead(LIBBASE, request);
107 break;
109 case CMD_WRITE:
110 case S2_MULTICAST:
111 complete = CmdWrite(LIBBASE, request);
112 break;
114 case CMD_FLUSH:
115 complete = CmdFlush(LIBBASE, (struct IORequest *)request);
116 break;
118 case S2_DEVICEQUERY:
119 complete = CmdS2DeviceQuery(LIBBASE, request);
120 break;
122 case S2_GETSTATIONADDRESS:
123 complete = CmdGetStationAddress(LIBBASE, request);
124 break;
126 case S2_CONFIGINTERFACE:
127 complete = CmdConfigInterface(LIBBASE, request);
128 break;
130 case S2_BROADCAST:
131 complete = CmdBroadcast(LIBBASE, request);
132 break;
134 case S2_TRACKTYPE:
135 complete = CmdTrackType(LIBBASE, request);
136 break;
138 case S2_UNTRACKTYPE:
139 complete = CmdUntrackType(LIBBASE, request);
140 break;
142 case S2_GETTYPESTATS:
143 complete = CmdGetTypeStats(LIBBASE, request);
144 break;
146 case S2_GETGLOBALSTATS:
147 complete = CmdGetGlobalStats(LIBBASE, request);
148 break;
150 case S2_ONEVENT:
151 complete = CmdOnEvent(LIBBASE, request);
152 break;
154 case S2_READORPHAN:
155 complete = CmdReadOrphan(LIBBASE, request);
156 break;
158 case S2_ONLINE:
159 complete = CmdOnline(LIBBASE, request);
160 break;
162 case S2_OFFLINE:
163 complete = CmdOffline(LIBBASE, request);
164 break;
166 case S2_ADDMULTICASTADDRESS:
167 case S2_ADDMULTICASTADDRESSES:
168 complete = CmdAddMulticastAddresses(LIBBASE, request);
169 break;
171 case S2_DELMULTICASTADDRESS:
172 case S2_DELMULTICASTADDRESSES:
173 complete = CmdDelMulticastAddresses(LIBBASE, request);
174 break;
176 case NSCMD_DEVICEQUERY:
177 complete = CmdDeviceQuery(LIBBASE, (struct IOStdReq *)request);
178 break;
180 default:
181 complete = CmdInvalid(LIBBASE, request);
184 if(complete && (request->ios2_Req.io_Flags & IOF_QUICK) == 0)
185 ReplyMsg((APTR)request);
187 ReleaseSemaphore(&((struct SiS900Unit *)request->ios2_Req.io_Unit)->sis900u_unit_lock);
190 static BOOL CmdInvalid(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
192 request->ios2_Req.io_Error = IOERR_NOCMD;
193 request->ios2_WireError = S2WERR_GENERIC_ERROR;
195 return TRUE;
198 static BOOL CmdRead(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
200 struct SiS900Unit *unit;
201 struct Opener *opener;
202 BOOL complete = FALSE;
204 unit = (APTR)request->ios2_Req.io_Unit;
206 D(bug("[%s]: S2CmdRead()\n", unit->sis900u_name));
208 if((unit->sis900u_ifflags & IFF_UP) != 0)
210 opener = request->ios2_BufferManagement;
211 request->ios2_Req.io_Flags &= ~IOF_QUICK;
212 PutMsg(&opener->read_port, (struct Message *)request);
214 else
216 request->ios2_Req.io_Error = S2ERR_OUTOFSERVICE;
217 request->ios2_WireError = S2WERR_UNIT_OFFLINE;
218 complete = TRUE;
221 /* Return */
223 return complete;
226 static BOOL CmdWrite(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
228 struct SiS900Unit *unit;
229 BYTE error = 0;
230 ULONG wire_error = S2WERR_GENERIC_ERROR;
231 BOOL complete = FALSE;
233 /* Check request is valid */
235 unit = (APTR)request->ios2_Req.io_Unit;
237 D(bug("[%s]: S2CmdWrite()\n", unit->sis900u_name));
239 if((unit->sis900u_ifflags & IFF_UP) == 0)
241 error = S2ERR_OUTOFSERVICE;
242 wire_error = S2WERR_UNIT_OFFLINE;
244 else if((request->ios2_Req.io_Command == S2_MULTICAST) &&
245 ((request->ios2_DstAddr[0] & 0x1) == 0))
247 error = S2ERR_BAD_ADDRESS;
248 wire_error = S2WERR_BAD_MULTICAST;
251 /* Queue request for sending */
253 if(error == 0) {
254 request->ios2_Req.io_Flags &= ~IOF_QUICK;
255 PutMsg(unit->sis900u_request_ports[WRITE_QUEUE], (APTR)request);
257 else
259 request->ios2_Req.io_Error = error;
260 request->ios2_WireError = wire_error;
261 complete = TRUE;
264 /* Return */
266 return complete;
269 static BOOL CmdFlush(LIBBASETYPEPTR LIBBASE, struct IORequest *request)
271 FlushUnit(LIBBASE, (APTR)request->io_Unit, EVENT_QUEUE, IOERR_ABORTED);
272 return TRUE;
275 static BOOL CmdS2DeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
277 struct SiS900Unit *unit = (APTR)request->ios2_Req.io_Unit;
278 // struct fe_priv *np = unit->sis900u_fe_priv;
279 struct Sana2DeviceQuery *info;
280 ULONG size_available, size, status;
281 int i = 0;
283 D(bug("[%s]: S2CmdDeviceQuery()\n", unit->sis900u_name));
285 /* STSOUT register is Latched on Transition, read operation updates it */
286 while (i++ < 2)
287 status = mdio_read(unit, unit->cur_phy, MII_STSOUT);
289 D(bug("[%s]: S2CmdDeviceQuery: PHY status %x\n", unit->sis900u_name, status));
291 /* Copy device info */
292 info = request->ios2_StatData;
293 size = size_available = info->SizeAvailable;
294 if(size > sizeof(struct Sana2DeviceQuery))
295 size = sizeof(struct Sana2DeviceQuery);
297 CopyMem(&unit->sis900u_Sana2Info, info, size);
299 if (status & MII_STSOUT_SPD)
300 info->BPS = 100000000;
301 else
302 info->BPS = 10000000;
304 info->MTU = unit->sis900u_mtu;
305 info->HardwareType = S2WireType_Ethernet;
306 info->SizeAvailable = size_available;
307 info->SizeSupplied = size;
309 /* Return */
311 return TRUE;
314 static BOOL CmdGetStationAddress(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
316 struct SiS900Unit *unit;
318 /* Copy addresses */
320 unit = (APTR)request->ios2_Req.io_Unit;
322 D(bug("[%s]: S2CmdGetStationAddress()\n", unit->sis900u_name));
324 CopyMem(unit->sis900u_dev_addr, request->ios2_SrcAddr, ETH_ADDRESSSIZE);
325 CopyMem(unit->sis900u_org_addr, request->ios2_DstAddr, ETH_ADDRESSSIZE);
327 /* Return */
329 return TRUE;
332 static BOOL CmdConfigInterface(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
334 struct SiS900Unit *unit;
336 /* Configure adapter */
338 unit = (APTR)request->ios2_Req.io_Unit;
340 D(bug("[%s]: S2CmdConfigInterface()\n", unit->sis900u_name));
342 if((unit->sis900u_ifflags & IFF_CONFIGURED) == 0)
344 CopyMem(request->ios2_SrcAddr, unit->sis900u_dev_addr, ETH_ADDRESSSIZE);
345 sis900func_set_mac(unit);
346 unit->sis900u_ifflags |= IFF_CONFIGURED;
348 else
350 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
351 request->ios2_WireError = S2WERR_IS_CONFIGURED;
354 /* Return */
356 return TRUE;
359 static BOOL CmdBroadcast(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
361 /* Fill in the broadcast address as destination */
363 memset(request->ios2_DstAddr, 0xff, 6);
365 /* Queue the write as normal */
367 return CmdWrite(LIBBASE, request);
370 static BOOL CmdTrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
372 struct SiS900Unit *unit;
373 struct Opener *opener;
374 ULONG packet_type, wire_error=0;
375 struct TypeTracker *tracker;
376 struct TypeStats *initial_stats;
377 BYTE error = 0;
379 unit = (APTR)request->ios2_Req.io_Unit;
381 D(bug("[%s]: S2CmdTrackType()\n", unit->sis900u_name));
383 packet_type = request->ios2_PacketType;
385 /* Get global tracker */
387 tracker = (struct TypeTracker *)
388 FindTypeStats(LIBBASE, unit, &unit->sis900u_type_trackers, packet_type);
390 if(tracker != NULL)
391 tracker->user_count++;
392 else
394 tracker =
395 AllocMem(sizeof(struct TypeTracker), MEMF_PUBLIC|MEMF_CLEAR);
396 if(tracker != NULL)
398 tracker->packet_type = packet_type;
399 tracker->user_count = 1;
401 Disable();
402 AddTail((APTR)&unit->sis900u_type_trackers, (APTR)tracker);
403 Enable();
407 /* Store initial figures for this opener */
409 opener = request->ios2_BufferManagement;
410 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
412 if(initial_stats != NULL)
414 error = S2ERR_BAD_STATE;
415 wire_error = S2WERR_ALREADY_TRACKED;
418 if(error == 0)
420 initial_stats = AllocMem(sizeof(struct TypeStats), MEMF_PUBLIC);
421 if(initial_stats == NULL)
423 error = S2ERR_NO_RESOURCES;
424 wire_error = S2WERR_GENERIC_ERROR;
428 if(error == 0)
430 CopyMem(tracker, initial_stats, sizeof(struct TypeStats));
431 AddTail((APTR)&opener->initial_stats, (APTR)initial_stats);
434 /* Return */
436 request->ios2_Req.io_Error = error;
437 request->ios2_WireError = wire_error;
438 return TRUE;
441 static BOOL CmdUntrackType(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
443 struct SiS900Unit *unit;
444 struct Opener *opener;
445 ULONG packet_type;
446 struct TypeTracker *tracker;
447 struct TypeStats *initial_stats;
449 unit = (APTR)request->ios2_Req.io_Unit;
451 D(bug("[%s]: S2CmdUntrackType()\n", unit->sis900u_name));
453 packet_type = request->ios2_PacketType;
455 /* Get global tracker and initial figures */
457 tracker = (struct TypeTracker *)
458 FindTypeStats(LIBBASE, unit, &unit->sis900u_type_trackers, packet_type);
459 opener = request->ios2_BufferManagement;
460 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
462 /* Decrement tracker usage and free unused structures */
464 if(initial_stats != NULL)
466 if((--tracker->user_count) == 0)
468 Disable();
469 Remove((APTR)tracker);
470 Enable();
471 FreeMem(tracker, sizeof(struct TypeTracker));
474 Remove((APTR)initial_stats);
475 FreeMem(initial_stats, sizeof(struct TypeStats));
477 else
479 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
480 request->ios2_WireError = S2WERR_NOT_TRACKED;
483 /* Return */
485 return TRUE;
488 static BOOL CmdGetTypeStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
490 struct SiS900Unit *unit;
491 struct Opener *opener;
492 ULONG packet_type;
493 struct TypeStats *initial_stats, *tracker;
494 struct Sana2PacketTypeStats *stats;
496 unit = (APTR)request->ios2_Req.io_Unit;
498 D(bug("[%s]: S2CmdGetTypeStats()\n", unit->sis900u_name));
500 packet_type = request->ios2_PacketType;
502 /* Get global tracker and initial figures */
504 tracker = FindTypeStats(LIBBASE, unit, &unit->sis900u_type_trackers, packet_type);
505 opener = request->ios2_BufferManagement;
506 initial_stats = FindTypeStats(LIBBASE, unit, &opener->initial_stats, packet_type);
508 /* Copy and adjust figures */
509 if(initial_stats != NULL)
511 stats = request->ios2_StatData;
512 CopyMem(&tracker->stats, stats, sizeof(struct Sana2PacketTypeStats));
513 stats->PacketsSent -= initial_stats->stats.PacketsSent;
514 stats->PacketsReceived -= initial_stats->stats.PacketsReceived;
515 stats->BytesSent -= initial_stats->stats.BytesSent;
516 stats->BytesReceived -= initial_stats->stats.BytesReceived;
517 stats->PacketsDropped -= initial_stats->stats.PacketsDropped;
519 else
521 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
522 request->ios2_WireError = S2WERR_NOT_TRACKED;
525 /* Return */
527 return TRUE;
530 static BOOL CmdGetGlobalStats(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
532 struct SiS900Unit *unit;
534 /* Update and copy stats */
536 unit = (APTR)request->ios2_Req.io_Unit;
538 D(bug("[%s]: S2CmdGetGlobalStats()\n", unit->sis900u_name));
540 CopyMem(&unit->sis900u_stats, request->ios2_StatData,
541 sizeof(struct Sana2DeviceStats));
543 /* Return */
545 return TRUE;
548 static BOOL CmdDeviceQuery(LIBBASETYPEPTR LIBBASE, struct IOStdReq *request)
550 struct NSDeviceQueryResult *info;
552 /* Set structure size twice */
554 info = request->io_Data;
555 request->io_Actual = info->SizeAvailable =
556 offsetof(struct NSDeviceQueryResult, SupportedCommands) + sizeof(APTR);
558 /* Report device details */
560 info->DeviceType = NSDEVTYPE_SANA2;
561 info->DeviceSubType = 0;
563 info->SupportedCommands = (APTR)supported_commands;
565 /* Return */
567 return TRUE;
570 static BOOL CmdOnEvent(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
572 struct SiS900Unit *unit;
573 ULONG events, wanted_events;
574 BOOL complete = FALSE;
576 /* Check if we understand the event types */
578 unit = (APTR)request->ios2_Req.io_Unit;
580 D(bug("[%s]: S2CmdOnEvent()\n", unit->sis900u_name));
582 wanted_events = request->ios2_WireError;
583 if((wanted_events & ~KNOWN_EVENTS) != 0)
585 request->ios2_Req.io_Error = S2ERR_NOT_SUPPORTED;
586 events = S2WERR_BAD_EVENT;
588 else
590 if((unit->sis900u_ifflags & IFF_UP) != 0)
591 events = S2EVENT_ONLINE;
592 else
593 events = S2EVENT_OFFLINE;
595 events &= wanted_events;
598 /* Reply request if a wanted event has already occurred */
600 if(events != 0)
602 request->ios2_WireError = events;
603 complete = TRUE;
605 else
607 request->ios2_Req.io_Flags &= ~IOF_QUICK;
608 PutMsg(unit->sis900u_request_ports[EVENT_QUEUE], (APTR)request);
611 /* Return */
613 return complete;
616 static BOOL CmdReadOrphan(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
618 struct SiS900Unit *unit;
619 BYTE error = 0;
620 ULONG wire_error;
621 BOOL complete = FALSE;
623 /* Check request is valid */
625 unit = (APTR)request->ios2_Req.io_Unit;
626 D(bug("[%s]: S2CmdReadOrphan()\n", unit->sis900u_name));
628 if((unit->sis900u_ifflags & IFF_UP) == 0)
630 error = S2ERR_OUTOFSERVICE;
631 wire_error = S2WERR_UNIT_OFFLINE;
634 /* Queue request */
636 if(error == 0)
638 request->ios2_Req.io_Flags &= ~IOF_QUICK;
639 PutMsg(unit->sis900u_request_ports[ADOPT_QUEUE], (struct Message *)request);
641 else
643 request->ios2_Req.io_Error = error;
644 request->ios2_WireError = wire_error;
645 complete = TRUE;
648 /* Return */
650 return complete;
653 static BOOL CmdOnline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
655 struct SiS900Unit *unit = (struct SiS900Unit *)request->ios2_Req.io_Unit;
656 BYTE error = 0;
657 ULONG wire_error = 0;
658 UWORD i;
660 D(bug("[%s]: S2CmdOnline()\n", unit->sis900u_name));
662 /* Check request is valid */
663 if((unit->sis900u_ifflags & IFF_CONFIGURED) == 0)
665 error = S2ERR_BAD_STATE;
666 wire_error = S2WERR_NOT_CONFIGURED;
669 /* Clear global and special stats and put adapter back online */
671 if((error == 0) && ((unit->sis900u_ifflags & IFF_UP) == 0))
673 unit->sis900u_stats.PacketsReceived = 0;
674 unit->sis900u_stats.PacketsSent = 0;
675 unit->sis900u_stats.BadData = 0;
676 unit->sis900u_stats.Overruns = 0;
677 unit->sis900u_stats.UnknownTypesReceived = 0;
678 unit->sis900u_stats.Reconfigurations = 0;
680 for(i = 0; i < SANA2_SPECIAL_STAT_COUNT; i++)
681 unit->sis900u_special_stats[i] = 0;
683 if (sis900func_open(unit))
685 error = S2ERR_OUTOFSERVICE;
686 wire_error = S2WERR_GENERIC_ERROR;
690 /* Return */
692 request->ios2_Req.io_Error = error;
693 request->ios2_WireError = wire_error;
694 return TRUE;
697 static BOOL CmdOffline(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
699 struct SiS900Unit *unit;
701 /* Put adapter offline */
703 unit = (APTR)request->ios2_Req.io_Unit;
705 D(bug("[%s]: S2CmdOffline()\n", unit->sis900u_name));
707 if((unit->sis900u_ifflags & IFF_UP) != 0)
708 sis900func_close(unit);
710 /* Return */
711 return TRUE;
714 static BOOL CmdAddMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
716 struct SiS900Unit *unit;
717 UBYTE *lower_bound, *upper_bound;
719 unit = (APTR)request->ios2_Req.io_Unit;
721 D(bug("[%s]: S2CmdAddMulticastAddresses()\n", unit->sis900u_name));
723 lower_bound = request->ios2_SrcAddr;
724 if(request->ios2_Req.io_Command == S2_ADDMULTICASTADDRESS)
725 upper_bound = lower_bound;
726 else
727 upper_bound = request->ios2_DstAddr;
729 if(!AddMulticastRange(LIBBASE, unit, lower_bound, upper_bound))
731 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
732 request->ios2_WireError = S2WERR_GENERIC_ERROR;
735 /* Return */
737 return TRUE;
740 static BOOL CmdDelMulticastAddresses(LIBBASETYPEPTR LIBBASE, struct IOSana2Req *request)
742 struct SiS900Unit *unit;
743 UBYTE *lower_bound, *upper_bound;
745 unit = (APTR)request->ios2_Req.io_Unit;
747 D(bug("[%s]: S2CmdDelMulticastAddresses()\n", unit->sis900u_name));
749 lower_bound = request->ios2_SrcAddr;
750 if(request->ios2_Req.io_Command == S2_DELMULTICASTADDRESS)
751 upper_bound = lower_bound;
752 else
753 upper_bound = request->ios2_DstAddr;
755 if(!RemMulticastRange(LIBBASE, unit, lower_bound, upper_bound))
757 request->ios2_Req.io_Error = S2ERR_BAD_STATE;
758 request->ios2_WireError = S2WERR_BAD_MULTICAST;
761 /* Return */
763 return TRUE;