Check that unit isn't NULL before using it, which could happen if card
[AROS.git] / workbench / devs / networks / etherlink3 / pccard.c
blob4a32b8fddbb57ce07946d71e7bf21d562cd89cf2
1 /*
3 Copyright (C) 2000-2011 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 <utility/tagitem.h>
25 #include <libraries/pccard.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #include <proto/cardres.h>
30 #include <proto/pccard.h>
32 #include "device.h"
34 #include "pccard_protos.h"
35 #include "device_protos.h"
36 #include "unit_protos.h"
38 #define MAX_TUPLE_SIZE 0xff
39 #define TUPLE_BUFFER_SIZE (MAX_TUPLE_SIZE + 8)
40 #define HANDLE_PRIORITY 10
41 #define IO_WINDOW_SIZE 0x10
44 struct BusContext
46 struct DevUnit *unit;
47 struct CardHandle *card_handle;
48 UBYTE *tuple_buffer;
49 UPINT config_base;
50 UPINT io_base;
51 UWORD resource_version;
52 BOOL have_card;
56 /* Private prototypes */
58 static struct DevUnit *FindPCCardUnit(ULONG index, struct DevBase *base);
59 static struct DevUnit *CreatePCCardUnit(ULONG index,
60 struct DevBase *base);
61 static struct BusContext *AllocCard(struct DevBase *base);
62 static VOID FreeCard(struct BusContext *context, struct DevBase *base);
63 static BOOL IsCardCompatible(struct BusContext *context,
64 struct DevBase *base);
65 static BOOL InitialiseCard(struct BusContext *context,
66 struct DevBase *base);
67 static VOID CardRemovedHook(struct BusContext *context,
68 struct DevBase *base);
69 static BOOL CardInsertedHook(struct BusContext *context,
70 struct DevBase *base);
71 static VOID CardRemovedInt(REG(a1, struct BusContext *context),
72 REG(a6, APTR int_code));
73 static VOID CardInsertedInt(REG(a1, struct BusContext *context),
74 REG(a6, APTR int_code));
75 static UBYTE CardStatusInt(REG(d0, UBYTE mask),
76 REG(a1, struct BusContext *context), REG(a6, APTR int_code));
77 static UBYTE ByteInHook(struct BusContext *context, ULONG offset);
78 static ULONG LongInHook(struct BusContext *context, ULONG offset);
79 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
80 UBYTE value);
81 static VOID WordOutHook(struct BusContext *context, ULONG offset,
82 UWORD value);
83 static VOID LongOutHook(struct BusContext *context, ULONG offset,
84 ULONG value);
85 static VOID LongsInHook(struct BusContext *context, ULONG offset,
86 ULONG *buffer, ULONG count);
87 static VOID LongsOutHook(struct BusContext *context, ULONG offset,
88 const ULONG *buffer, ULONG count);
89 static VOID BEWordOutHook(struct BusContext *context, ULONG offset,
90 UWORD value);
91 static UWORD LEWordInHook(struct BusContext *context, ULONG offset);
92 static ULONG LELongInHook(struct BusContext *context, ULONG offset);
93 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
94 UWORD value);
95 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
96 ULONG value);
99 static const ULONG product_codes[] =
101 0x01010035,
102 0x0101003d,
103 0x01010562,
104 0x01010589,
109 static const struct TagItem unit_tags[] =
111 {IOTAG_ByteIn, (UPINT)ByteInHook},
112 {IOTAG_LongIn, (UPINT)LongInHook},
113 {IOTAG_ByteOut, (UPINT)ByteOutHook},
114 {IOTAG_WordOut, (UPINT)WordOutHook},
115 {IOTAG_LongOut, (UPINT)LongOutHook},
116 {IOTAG_LongsIn, (UPINT)LongsInHook},
117 {IOTAG_LongsOut, (UPINT)LongsOutHook},
118 {IOTAG_BEWordOut, (UPINT)BEWordOutHook},
119 {IOTAG_LEWordIn, (UPINT)LEWordInHook},
120 {IOTAG_LELongIn, (UPINT)LELongInHook},
121 {IOTAG_LEWordOut, (UPINT)LEWordOutHook},
122 {IOTAG_LELongOut, (UPINT)LELongOutHook},
123 {TAG_END, 0}
127 /****i* etherlink3.device/GetPCCardCount ***********************************
129 * NAME
130 * GetPCCardCount -- Get the number of compatible PC Cards.
132 * SYNOPSIS
133 * count = GetPCCardCount()
135 * ULONG GetPCCardCount();
137 ****************************************************************************
141 ULONG GetPCCardCount(struct DevBase *base)
143 ULONG count = 0;
144 struct BusContext *context;
146 if(CardResource != NULL)
148 if(FindPCCardUnit(0, base) != NULL)
149 count = 1;
150 else
152 context = AllocCard(base);
153 if(context != NULL)
155 count = 1;
156 FreeCard(context, base);
161 return count;
165 /****i* etherlink3.device/GetPCCardUnit ************************************
167 * NAME
168 * GetPCCardUnit -- Get a unit by number.
170 * SYNOPSIS
171 * unit = GetPCCardUnit(index)
173 * struct DevUnit *GetPCCardUnit(ULONG);
175 ****************************************************************************
179 struct DevUnit *GetPCCardUnit(ULONG index, struct DevBase *base)
181 struct DevUnit *unit;
183 unit = FindPCCardUnit(index, base);
185 if(unit == NULL)
187 unit = CreatePCCardUnit(index, base);
188 if(unit != NULL)
189 AddTail((APTR)&base->pccard_units, (APTR)unit);
192 return unit;
197 /****i* etherlink3.device/FindPCCardUnit ***********************************
199 * NAME
200 * FindPCCardUnit -- Find a unit by number.
202 * SYNOPSIS
203 * unit = FindPCCardUnit(unit_num)
205 * struct DevUnit *FindPCCardUnit(ULONG);
207 ****************************************************************************
211 static struct DevUnit *FindPCCardUnit(ULONG index, struct DevBase *base)
213 struct DevUnit *unit, *tail;
215 unit = (APTR)base->pccard_units.mlh_Head;
216 tail = (APTR)&base->pccard_units.mlh_Tail;
217 if(unit == tail)
218 unit = NULL;
220 return unit;
225 /****i* etherlink3.device/CreatePCCardUnit *********************************
227 * NAME
228 * CreatePCCardUnit -- Create a unit.
230 * SYNOPSIS
231 * unit = CreatePCCardUnit(index)
233 * struct DevUnit *CreatePCCardUnit(ULONG);
235 * FUNCTION
236 * Creates a new unit.
238 ****************************************************************************
242 static struct DevUnit *CreatePCCardUnit(ULONG index,
243 struct DevBase *base)
245 BOOL success = TRUE;
246 struct BusContext *context;
247 struct DevUnit *unit;
249 /* Get card from system */
251 context = AllocCard(base);
252 if(context == NULL)
253 success = FALSE;
255 /* Prepare card for use */
257 if(success)
259 if(!InitialiseCard(context, base))
260 success = FALSE;
263 /* Create device driver unit */
265 if(success)
267 context->unit = unit =
268 CreateUnit(index, context, unit_tags, SECOND_GEN,
269 PCCARD_BUS, base);
270 if(unit == NULL)
271 success = FALSE;
274 if(success)
276 if(!(WrapInt(&unit->status_int, base)
277 && WrapInt(&unit->rx_int, base)
278 && WrapInt(&unit->tx_int, base)
279 && WrapInt(&unit->tx_end_int, base)))
280 success = FALSE;
282 unit->insertion_function = (APTR)CardInsertedHook;
283 unit->removal_function = (APTR)CardRemovedHook;
286 if(!success)
288 if(context != NULL)
290 DeleteUnit(context->unit, base);
291 FreeCard(context, base);
293 unit = NULL;
296 return unit;
301 /****i* etherlink3.device/DeletePCCardUnit *********************************
303 * NAME
304 * DeletePCCardUnit -- Delete a unit.
306 * SYNOPSIS
307 * DeletePCCardUnit(unit)
309 * VOID DeletePCCardUnit(struct DevUnit *);
311 * FUNCTION
312 * Deletes a unit.
314 * INPUTS
315 * unit - Device unit (may be NULL).
317 * RESULT
318 * None.
320 ****************************************************************************
324 VOID DeletePCCardUnit(struct DevUnit *unit, struct DevBase *base)
326 struct BusContext *context;
328 if(unit != NULL)
330 UnwrapInt(&unit->tx_end_int, base);
331 UnwrapInt(&unit->tx_int, base);
332 UnwrapInt(&unit->rx_int, base);
333 UnwrapInt(&unit->status_int, base);
334 context = unit->card;
335 DeleteUnit(unit, base);
336 FreeCard(context, base);
339 return;
344 /****i* etherlink3.device/AllocCard ****************************************
346 * NAME
347 * AllocCard -- Get card from system.
349 * SYNOPSIS
350 * context = AllocCard()
352 * struct BusContext *AllocCard();
354 ****************************************************************************
358 static struct BusContext *AllocCard(struct DevBase *base)
360 BOOL success = TRUE, have_card = FALSE;
361 struct BusContext *context;
362 struct CardHandle *card_handle;
363 struct Interrupt *card_removed_int, *card_inserted_int, *card_status_int;
365 context = AllocMem(sizeof(struct BusContext), MEMF_PUBLIC | MEMF_CLEAR);
366 if(context == NULL)
367 success = FALSE;
369 if(success)
371 context->resource_version =
372 ((struct Library *)base->card_base)->lib_Version;
373 context->card_handle = card_handle =
374 AllocMem(sizeof(struct CardHandle), MEMF_PUBLIC | MEMF_CLEAR);
375 context->tuple_buffer =
376 AllocVec(TUPLE_BUFFER_SIZE, MEMF_PUBLIC);
378 if(card_handle == NULL || context->tuple_buffer == NULL)
379 success = FALSE;
382 if(success)
384 /* Set up card handle */
386 card_handle->cah_CardNode.ln_Pri = HANDLE_PRIORITY;
387 card_handle->cah_CardNode.ln_Name =
388 base->device.dd_Library.lib_Node.ln_Name;
389 card_handle->cah_CardFlags = CARDF_POSTSTATUS;
391 card_handle->cah_CardRemoved = card_removed_int =
392 AllocVec(sizeof(struct Interrupt), MEMF_PUBLIC | MEMF_CLEAR);
394 card_handle->cah_CardInserted = card_inserted_int =
395 AllocVec(sizeof(struct Interrupt), MEMF_PUBLIC | MEMF_CLEAR);
397 card_handle->cah_CardStatus = card_status_int =
398 AllocVec(sizeof(struct Interrupt), MEMF_PUBLIC | MEMF_CLEAR);
400 if(card_removed_int == NULL || card_inserted_int == NULL
401 || card_status_int == NULL)
402 success = FALSE;
405 if(success)
407 /* Try to gain access to card */
409 card_removed_int->is_Code = CardRemovedInt;
410 card_removed_int->is_Data = context;
411 card_inserted_int->is_Code = CardInsertedInt;
412 card_inserted_int->is_Data = context;
413 card_status_int->is_Code = (APTR)CardStatusInt;
414 card_status_int->is_Data = context;
416 if(!(WrapInt(card_removed_int, base)
417 && WrapInt(card_inserted_int, base)
418 && WrapInt(card_status_int, base)))
419 success = FALSE;
422 if(success)
424 if(OwnCard(card_handle) != 0)
425 success = FALSE;
428 if(success)
430 have_card = TRUE;
431 if(!IsCardCompatible(context, base))
432 success = FALSE;
435 if(!success)
437 FreeCard(context, base);
438 context = NULL;
440 return context;
445 /****i* etherlink3.device/FreeCard *****************************************
447 * NAME
448 * FreeCard -- Release a card.
450 * SYNOPSIS
451 * FreeCard(context)
453 * VOID FreeCard(struct BusContext *);
455 ****************************************************************************
459 static VOID FreeCard(struct BusContext *context, struct DevBase *base)
461 struct CardHandle *card_handle;
463 if(context != NULL)
465 card_handle = context->card_handle;
467 if(context->have_card)
469 CardMiscControl(card_handle, 0);
470 CardResetCard(card_handle);
472 ReleaseCard(card_handle, CARDF_REMOVEHANDLE);
473 UnwrapInt(card_handle->cah_CardStatus, base);
474 UnwrapInt(card_handle->cah_CardInserted, base);
475 UnwrapInt(card_handle->cah_CardRemoved, base);
477 FreeVec(card_handle->cah_CardStatus);
478 FreeVec(card_handle->cah_CardInserted);
479 FreeVec(card_handle->cah_CardRemoved);
480 FreeVec(context->tuple_buffer);
481 FreeMem(card_handle, sizeof(struct CardHandle));
483 FreeMem(context, sizeof(struct BusContext));
486 return;
491 /****i* etherlink3.device/IsCardCompatible *********************************
493 * NAME
494 * IsCardCompatible
496 * SYNOPSIS
497 * compatible = IsCardCompatible(context)
499 * BOOL IsCardCompatible(struct BusContext *);
501 ****************************************************************************
505 static BOOL IsCardCompatible(struct BusContext *context,
506 struct DevBase *base)
508 BOOL success = TRUE;
509 struct CardHandle *card_handle;
510 UBYTE *tuple_buffer;
511 const struct TagItem *tuple_tags = NULL;
512 ULONG code;
513 const ULONG *p;
514 UWORD maker = 0, product = 0;
516 card_handle = context->card_handle;
517 tuple_buffer = context->tuple_buffer;
519 /* Get card's make and model */
521 if(CopyTuple(card_handle, tuple_buffer, PCCARD_TPL_MANFID,
522 MAX_TUPLE_SIZE))
524 tuple_tags = PCCard_GetTupleInfo(tuple_buffer);
525 if(tuple_tags != NULL)
527 maker = GetTagData(PCCARD_Maker, 0, tuple_tags);
528 product = GetTagData(PCCARD_Product, 0, tuple_tags);
532 /* Check this is a card we can use */
534 code = maker << 16 | product;
535 for(success = FALSE, p = product_codes; *p != 0; p++)
536 if(*p == code)
537 success = TRUE;
538 PCCard_FreeTupleInfo(tuple_tags);
540 return success;
545 /****i* etherlink3.device/InitialiseCard ***********************************
547 * NAME
548 * InitialiseCard
550 * SYNOPSIS
551 * success = InitialiseCard(context)
553 * BOOL InitialiseCard(struct BusContext *);
555 ****************************************************************************
559 static BOOL InitialiseCard(struct BusContext *context,
560 struct DevBase *base)
562 BOOL success = TRUE;
563 struct CardHandle *card_handle;
564 struct CardMemoryMap *card_map;
565 UBYTE config_value, i, window_count, *tuple_buffer;
566 const struct TagItem *tuple_tags = NULL;
567 ULONG *io_bases, *io_lengths, io_base_offset = 0, config_base_offset;
569 /* Wake up card's I/O functionality */
571 card_handle = context->card_handle;
572 tuple_buffer = context->tuple_buffer;
573 CardMiscControl(card_handle,
574 CARD_ENABLEF_DIGAUDIO | CARD_DISABLEF_WP);
576 /* Get configuration data */
578 if(!CopyTuple(card_handle, tuple_buffer, PCCARD_TPL_CONFIG,
579 MAX_TUPLE_SIZE))
580 success = FALSE;
582 if(success)
584 PCCard_FreeTupleInfo(tuple_tags);
585 tuple_tags = PCCard_GetTupleInfo(tuple_buffer);
586 if(tuple_tags == NULL)
587 success = FALSE;
590 if(success)
592 config_base_offset = GetTagData(PCCARD_RegisterBase, 0, tuple_tags);
594 PCCard_FreeTupleInfo(tuple_tags);
595 tuple_tags = NULL;
597 /* Get IO base */
599 if(!CopyTuple(card_handle, tuple_buffer, PCCARD_TPL_CFTABLEENTRY,
600 MAX_TUPLE_SIZE))
601 success = FALSE;
604 if(success)
606 tuple_tags = PCCard_GetTupleInfo(tuple_buffer);
607 if(tuple_tags == NULL)
608 success = FALSE;
611 if(success)
613 config_value = GetTagData(PCCARD_ModeNo, 0, tuple_tags);
615 io_bases =
616 (APTR)GetTagData(PCCARD_IOWinBases, (UPINT)NULL, tuple_tags);
617 if(io_bases == NULL)
618 success = FALSE;
621 /* Find the appropriate IO window */
623 if(success)
625 io_lengths =
626 (APTR)GetTagData(PCCARD_IOWinLengths, (UPINT)NULL, tuple_tags);
628 window_count = GetTagData(PCCARD_IOWinCount, 0, tuple_tags);
630 for(i = 0; i < window_count && io_base_offset == 0; i++)
631 if(io_lengths[i] == IO_WINDOW_SIZE)
632 io_base_offset = io_bases[i];
635 PCCard_FreeTupleInfo(tuple_tags);
637 /* Configure card */
639 if(success)
641 card_map = GetCardMap();
642 context->config_base =
643 (UPINT)card_map->cmm_AttributeMemory + config_base_offset;
645 context->io_base = (UPINT)card_map->cmm_IOMemory + io_base_offset;
646 BYTEOUT(context->config_base + PCCARD_REG_COR, config_value);
647 BYTEOUT(context->config_base + PCCARD_REG_CCSR,
648 BYTEIN(context->config_base + PCCARD_REG_CCSR)
649 | PCCARD_REG_CCSRF_AUDIOENABLE);
652 return success;
657 /****i* etherlink3.device/CardRemovedHook **********************************
659 * NAME
660 * CardRemovedHook
662 * SYNOPSIS
663 * CardRemovedHook(context)
665 * VOID CardRemovedHook(struct BusContext *);
667 ****************************************************************************
671 static VOID CardRemovedHook(struct BusContext *context,
672 struct DevBase *base)
674 ReleaseCard(context->card_handle, 0);
676 return;
681 /****i* etherlink3.device/CardInsertedHook *********************************
683 * NAME
684 * CardInsertedHook
686 * SYNOPSIS
687 * success = CardInsertedHook(context)
689 * BOOL CardInsertedHook(struct BusContext *);
691 ****************************************************************************
695 static BOOL CardInsertedHook(struct BusContext *context,
696 struct DevBase *base)
698 BOOL success = TRUE;
700 success = IsCardCompatible(context, base);
702 if(success)
703 success = InitialiseCard(context, base);
705 if(success)
706 success = InitialiseAdapter(context->unit, TRUE, base);
708 if(!success)
709 ReleaseCard(context->card_handle, 0);
711 return success;
716 /****i* etherlink3.device/CardRemovedInt ***********************************
718 * NAME
719 * CardRemovedInt
721 * SYNOPSIS
722 * CardRemovedInt(unit)
724 * VOID CardRemovedInt(struct DevUnit *);
726 ****************************************************************************
730 static VOID CardRemovedInt(REG(a1, struct BusContext *context),
731 REG(a6, APTR int_code))
733 struct DevBase *base;
734 struct DevUnit *unit;
736 /* Record loss of card and get our task to call ReleaseCard() */
738 unit = context->unit;
739 if(unit != NULL)
741 base = unit->device;
742 if((unit->flags & UNITF_ONLINE) != 0)
743 unit->flags |= UNITF_WASONLINE;
744 unit->flags &= ~(UNITF_HAVEADAPTER | UNITF_ONLINE);
746 context->have_card = FALSE;
747 if(unit != NULL)
748 Signal(unit->task, unit->card_removed_signal);
750 return;
755 /****i* etherlink3.device/CardInsertedInt **********************************
757 * NAME
758 * CardInsertedInt
760 * SYNOPSIS
761 * CardInsertedInt(unit)
763 * VOID CardInsertedInt(struct DevUnit *);
765 ****************************************************************************
769 static VOID CardInsertedInt(REG(a1, struct BusContext *context),
770 REG(a6, APTR int_code))
772 struct DevBase *base;
773 struct DevUnit *unit;
775 unit = context->unit;
776 base = unit->device;
777 context->have_card = TRUE;
778 Signal(unit->task, unit->card_inserted_signal);
780 return;
785 /****i* etherlink3.device/CardStatusInt ************************************
787 * NAME
788 * CardStatusInt
790 * SYNOPSIS
791 * mask = CardStatusInt(mask, unit)
793 * UBYTE CardStatusInt(UBYTE mask, struct DevUnit *);
795 ****************************************************************************
797 * We pretend the int_code parameter goes in A6 rather than A5 because 68k
798 * GCC can't cope with A5 and we know the parameter isn't used in this case.
802 static UBYTE CardStatusInt(REG(d0, UBYTE mask),
803 REG(a1, struct BusContext *context), REG(a6, APTR int_code))
805 if(context->resource_version < 39)
807 /* Work around gayle interrupt bug */
809 *((volatile UBYTE *)0xda9000) = (mask ^ 0x2c) | 0xc0;
810 mask = 0;
813 if(context->unit != NULL)
814 StatusInt(context->unit, StatusInt);
816 return mask;
821 /****i* etherlink3.device/ByteInHook ***************************************
823 * NAME
824 * ByteInHook
826 * SYNOPSIS
827 * value = ByteInHook(context, offset)
829 * UBYTE ByteInHook(struct BusContext *, ULONG);
831 ****************************************************************************
835 static UBYTE ByteInHook(struct BusContext *context, ULONG offset)
837 return BYTEIN(context->io_base + offset);
842 /****i* etherlink3.device/LongInHook ***************************************
844 * NAME
845 * LongInHook
847 * SYNOPSIS
848 * value = LongInHook(context, offset)
850 * ULONG LongInHook(struct BusContext *, ULONG);
852 ****************************************************************************
856 static ULONG LongInHook(struct BusContext *context, ULONG offset)
858 return LONGIN(context->io_base + offset);
863 /****i* etherlink3.device/ByteOutHook **************************************
865 * NAME
866 * ByteOutHook
868 * SYNOPSIS
869 * ByteOutHook(context, offset, value)
871 * VOID ByteOutHook(struct BusContext *, ULONG, UBYTE);
873 ****************************************************************************
877 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
878 UBYTE value)
880 BYTEOUT(context->io_base + offset, value);
882 return;
887 /****i* etherlink3.device/WordOutHook **************************************
889 * NAME
890 * WordOutHook
892 * SYNOPSIS
893 * WordOutHook(context, offset, value)
895 * VOID WordOutHook(struct BusContext *, ULONG, UWORD);
897 ****************************************************************************
901 static VOID WordOutHook(struct BusContext *context, ULONG offset,
902 UWORD value)
904 WORDOUT(context->io_base + offset, value);
906 return;
911 /****i* etherlink3.device/LongOutHook **************************************
913 * NAME
914 * LongOutHook
916 * SYNOPSIS
917 * LongOutHook(context, offset, value)
919 * VOID LongOutHook(struct BusContext *, ULONG, ULONG);
921 ****************************************************************************
925 static VOID LongOutHook(struct BusContext *context, ULONG offset,
926 ULONG value)
928 LONGOUT(context->io_base + offset, value);
930 return;
935 /****i* etherlink3.device/LongsInHook **************************************
937 * NAME
938 * LongsInHook
940 * SYNOPSIS
941 * LongsInHook(context, offset, buffer, count)
943 * VOID LongsInHook(struct BusContext *, ULONG, ULONG *, ULONG);
945 ****************************************************************************
949 static VOID LongsInHook(struct BusContext *context, ULONG offset,
950 ULONG *buffer, ULONG count)
952 LONGSIN(context->io_base + offset, buffer, count);
954 return;
959 /****i* etherlink3.device/LongsOutHook *************************************
961 * NAME
962 * LongsOutHook
964 * SYNOPSIS
965 * LongsOutHook(context, offset, buffer, count)
967 * VOID LongsOutHook(struct BusContext *, ULONG, const ULONG *, ULONG);
969 ****************************************************************************
973 static VOID LongsOutHook(struct BusContext *context, ULONG offset,
974 const ULONG *buffer, ULONG count)
976 LONGSOUT(context->io_base + offset, buffer, count);
978 return;
983 /****i* etherlink3.device/BEWordOutHook ************************************
985 * NAME
986 * BEWordOutHook
988 * SYNOPSIS
989 * BEWordOutHook(context, offset, value)
991 * VOID BEWordOutHook(struct BusContext *, ULONG, UWORD);
993 ****************************************************************************
997 static VOID BEWordOutHook(struct BusContext *context, ULONG offset,
998 UWORD value)
1000 BEWORDOUT(context->io_base + offset, value);
1002 return;
1007 /****i* etherlink3.device/LEWordInHook *************************************
1009 * NAME
1010 * LEWordInHook
1012 * SYNOPSIS
1013 * value = LEWordInHook(context, offset)
1015 * UWORD LEWordInHook(struct BusContext *, ULONG);
1017 ****************************************************************************
1021 static UWORD LEWordInHook(struct BusContext *context, ULONG offset)
1023 return LEWORDIN(context->io_base + offset);
1028 /****i* etherlink3.device/LELongInHook ***************************************
1030 * NAME
1031 * LELongInHook
1033 * SYNOPSIS
1034 * value = LELongInHook(context, offset)
1036 * ULONG LELongInHook(struct BusContext *, ULONG);
1038 ****************************************************************************
1042 static ULONG LELongInHook(struct BusContext *context, ULONG offset)
1044 return LELONGIN(context->io_base + offset);
1049 /****i* etherlink3.device/LEWordOutHook ************************************
1051 * NAME
1052 * LEWordOutHook
1054 * SYNOPSIS
1055 * LEWordOutHook(context, offset, value)
1057 * VOID LEWordOutHook(struct BusContext *, ULONG, UWORD);
1059 ****************************************************************************
1063 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
1064 UWORD value)
1066 LEWORDOUT(context->io_base + offset, value);
1068 return;
1073 /****i* etherlink3.device/LELongOutHook ************************************
1075 * NAME
1076 * LELongOutHook
1078 * SYNOPSIS
1079 * LELongOutHook(context, offset, value)
1081 * VOID LELongOutHook(struct BusContext *, ULONG, ULONG);
1083 ****************************************************************************
1087 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
1088 ULONG value)
1090 LELONGOUT(context->io_base + offset, value);
1092 return;