- Fixes to OS wrappers to allow extra mask parameter for PCCard status
[AROS.git] / workbench / devs / networks / etherlink3 / isa.c
blobd9c9f7efa776c96e2aeb88209277d7569d693cb7
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/utility.h>*/
25 #include <libraries/isapnp.h>
27 #include <proto/exec.h>
28 #include <proto/utility.h>
29 #include <proto/isapnp.h>
31 #include "device.h"
33 #include "isa_protos.h"
34 #include "unit_protos.h"
37 struct BusContext
39 struct DevUnit *unit;
40 struct ISAPNP_Device *card;
41 UPINT io_base;
42 APTR lock;
46 /* Private prototypes */
48 static struct DevUnit *FindISAUnit(ULONG index, struct DevBase *base);
49 static struct DevUnit *CreateISAUnit(ULONG index, struct DevBase *base);
50 static struct BusContext *AllocCard(ULONG index, struct DevBase *base);
51 static VOID FreeCard(struct BusContext *card, struct DevBase *base);
52 static BOOL IsCardCompatible(struct ISAPNP_Device *card,
53 struct DevBase *base);
54 /*static BOOL InitialiseCard(struct BusContext *card, struct DevBase *base);*/
55 static UBYTE ByteInHook(struct BusContext *context, ULONG offset);
56 static ULONG LongInHook(struct BusContext *context, ULONG offset);
57 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
58 UBYTE value);
59 static VOID WordOutHook(struct BusContext *context, ULONG offset,
60 UWORD value);
61 static VOID LongOutHook(struct BusContext *context, ULONG offset,
62 ULONG value);
63 static VOID LongsInHook(struct BusContext *context, ULONG offset,
64 ULONG *buffer, ULONG count);
65 static VOID LongsOutHook(struct BusContext *context, ULONG offset,
66 const ULONG *buffer, ULONG count);
67 static VOID BEWordOutHook(struct BusContext *context, ULONG offset,
68 UWORD value);
69 static UWORD LEWordInHook(struct BusContext *context, ULONG offset);
70 static ULONG LELongInHook(struct BusContext *context, ULONG offset);
71 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
72 UWORD value);
73 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
74 ULONG value);
77 static const UWORD product_codes[] =
79 0x6d50, 0x5090,
80 0x6d50, 0x5091,
81 0x6d50, 0x5094,
82 0x6d50, 0x5095,
83 0x6d50, 0x5098,
84 /* 'PNP', 0x80f7,
85 'PNP', 0x80f8,*/
90 static const struct TagItem unit_tags[] =
92 {IOTAG_ByteIn, (UPINT)ByteInHook},
93 {IOTAG_LongIn, (UPINT)LongInHook},
94 {IOTAG_ByteOut, (UPINT)ByteOutHook},
95 {IOTAG_WordOut, (UPINT)WordOutHook},
96 {IOTAG_LongOut, (UPINT)LongOutHook},
97 {IOTAG_LongsIn, (UPINT)LongsInHook},
98 {IOTAG_LongsOut, (UPINT)LongsOutHook},
99 {IOTAG_BEWordOut, (UPINT)BEWordOutHook},
100 {IOTAG_LEWordIn, (UPINT)LEWordInHook},
101 {IOTAG_LELongIn, (UPINT)LELongInHook},
102 {IOTAG_LEWordOut, (UPINT)LEWordOutHook},
103 {IOTAG_LELongOut, (UPINT)LELongOutHook},
104 {TAG_END, 0}
108 /****i* etherlink3.device/GetISACount **************************************
110 * NAME
111 * GetISACount -- Get the number of compatible ISA cards.
113 * SYNOPSIS
114 * count = GetISACount()
116 * ULONG GetISACount();
118 ****************************************************************************
122 ULONG GetISACount(struct DevBase *base)
124 ULONG count = 0;
125 struct ISAPNP_Device *card = NULL;
127 while((card = ISAPNP_FindDevice(card, -1, -1, -1)) != NULL)
129 if(IsCardCompatible(card, base))
130 count++;
133 return count;
138 /****i* etherlink3.device/GetISAUnit ***************************************
140 * NAME
141 * GetISAUnit -- Get a unit by number.
143 * SYNOPSIS
144 * unit = GetISAUnit(index)
146 * struct DevUnit *GetISAUnit(ULONG);
148 ****************************************************************************
152 struct DevUnit *GetISAUnit(ULONG index, struct DevBase *base)
154 struct DevUnit *unit;
155 struct BusContext *card;
157 unit = FindISAUnit(index, base);
159 if(unit == NULL)
161 card = CreateISAUnit(index, base);
162 if(card != NULL)
164 unit = card->unit;
165 AddTail((APTR)&base->isa_units, (APTR)unit);
169 return unit;
174 /****i* etherlink3.device/FindISAUnit **************************************
176 * NAME
177 * FindISAUnit -- Find an existing unit by number.
179 * SYNOPSIS
180 * unit = FindISAUnit(index)
182 * struct DevUnit *FindISAUnit(ULONG);
184 ****************************************************************************
188 static struct DevUnit *FindISAUnit(ULONG index, struct DevBase *base)
190 struct DevUnit *unit, *tail;
191 BOOL found = FALSE;
193 unit = (APTR)base->isa_units.mlh_Head;
194 tail = (APTR)&base->isa_units.mlh_Tail;
196 while(unit != tail && !found)
198 if(unit->index == index)
199 found = TRUE;
200 else
201 unit = (APTR)unit->node.mln_Succ;
204 if(!found)
205 unit = NULL;
207 return unit;
212 /****i* etherlink3.device/CreateISAUnit ************************************
214 * NAME
215 * CreateISAUnit -- Create an ISA unit.
217 * SYNOPSIS
218 * unit = CreateISAUnit(index)
220 * struct DevUnit *CreateISAUnit(ULONG);
222 * FUNCTION
223 * Creates a new ISA unit.
225 ****************************************************************************
229 struct DevUnit *CreateISAUnit(ULONG index, struct DevBase *base)
231 BOOL success = TRUE;
232 struct BusContext *context;
233 struct DevUnit *unit;
234 UWORD generation, id, i;
235 UPINT io_base, id_port;
237 context = AllocCard(index, base);
238 if(context == NULL)
239 success = FALSE;
243 #if 0 /* Stuff below is for non-PnP only? */
245 /* Send initialisation ID sequence */
247 id_port = 0xef0100; /* !!! */
248 BYTEOUT(id_port, 0);
249 BYTEOUT(id_port, 0);
251 id = 0xff;
252 for(i = 0; i < 0xff; i++)
254 BYTEOUT(id_port, (UBYTE)id);
255 id <<= 1;
256 if ((id & 0x100) != 0)
257 id ^= 0xcf;
260 /* Activate adapter */
262 BYTEOUT(id_port, 0xff);
264 io_base = 0xef0300;
265 generation = FIRST_GEN;
266 #endif
269 if(success)
271 generation = SECOND_GEN;
272 unit = CreateUnit(unit_num, NULL, io_base, generation, ISA_BUS, base);
273 if(unit == NULL)
274 success = FALSE;
277 /* Add interrupt */
279 if(success)
280 AddIntServer(x, &unit->status_int);
282 if(!success)
284 DeleteISAUnit(unit, base);
285 unit = NULL;
288 return unit;
293 /****i* etherlink3.device/DeleteISAUnit ************************************
295 * NAME
296 * DeleteISAUnit -- Delete a unit.
298 * SYNOPSIS
299 * DeleteISAUnit(unit)
301 * VOID DeleteISAUnit(struct DevUnit *);
303 * FUNCTION
304 * Deletes a unit.
306 * INPUTS
307 * unit - Device unit (can be NULL).
309 * RESULT
310 * None.
312 ****************************************************************************
316 VOID DeleteISAUnit(struct DevUnit *unit, struct DevBase *base)
318 if(unit != NULL)
320 RemIntServer(x, &unit->status_int);
321 DeleteUnit(unit, base);
324 return;
329 /****i* etherlink3.device/AllocCard ****************************************
331 * NAME
332 * AllocCard -- Get card from system.
334 * SYNOPSIS
335 * context = AllocCard(index)
337 * struct BusContext *AllocCard(ULONG);
339 ****************************************************************************
343 static struct BusContext *AllocCard(ULONG index, struct DevBase *base)
345 BOOL success = TRUE;
346 struct BusContext *context;
347 struct ISAPNP_Device *card = NULL;
348 ULONG i;
350 /* Find a compatible card */
352 card = AllocMem(sizeof(struct BusContext), MEMF_PUBLIC | MEMF_CLEAR);
353 if(card == NULL)
354 success = FALSE;
356 if(success)
358 while(i <= index)
360 card = ISAPNP_FindDevice(card, -1, -1, -1);
361 if(IsCardCompatible(card, base))
362 i++;
364 context->card = card;
367 /* Get base address */
369 if(success)
373 /* Lock card */
375 if(success)
377 context->lock = ISAPNP_LockDevices(ISAPNP_LOCKF_NONE, card);
378 if(context->lock == NULL)
379 success = FALSE;
382 if(!success)
384 FreeCard(context, base);
387 return card;
392 /****i* etherlink3.device/FreeCard *****************************************
394 * NAME
395 * FreeCard -- Release a card
397 * SYNOPSIS
398 * FreeCard(context)
400 * VOID FreeCard(struct BusContext *);
402 ****************************************************************************
406 static VOID FreeCard(struct BusContext *context, struct DevBase *base)
408 struct ISAPNP_Device *card = NULL;
410 if(context != NULL)
412 /* Unlock card */
414 ISAPNP_UnlockDevices(context->lock);
416 FreeMem(context, sizeof(struct BusContext));
419 return;
424 /****i* etherlink3.device/IsCardCompatible *********************************
426 * NAME
427 * IsCardCompatible
429 * SYNOPSIS
430 * compatible = IsCardCompatible(card)
432 * BOOL IsCardCompatible(struct ISAPNP_Device *);
434 ****************************************************************************
438 static BOOL IsCardCompatible(struct ISAPNP_Device *card,
439 struct DevBase *base)
441 struct ISAPNP_Identifier *id, *tail;
442 BOOL compatible = FALSE;
443 const UWORD *p;
445 id = (APTR)card->isapnpd_IDs.mlh_Head;
446 tail = (APTR)&card->isapnpd_IDs.mlh_Tail;
448 while(id != tail)
450 vendor_id =
451 ISAPNP_MAKE_ID(id->isapnpid_Vendor[0], id->isapnpid_Vendor[1],
452 id->isapnpid_Vendor[2]);
453 product_id = id->isapnpid_ProductID;
455 for(p = product_codes; p[0] != 0; p += 2)
457 if(p[0] == vendor_id && p[1] == product_id)
458 compatible = TRUE;
461 id = (APTR)id->isapnpid_MinNode.mln_Succ;
464 return compatible;
469 /****i* etherlink3.device/ByteInHook ***************************************
471 * NAME
472 * ByteInHook
474 * SYNOPSIS
475 * value = ByteInHook(context, offset)
477 * UBYTE ByteInHook(struct BusContext *, ULONG);
479 ****************************************************************************
483 static UBYTE ByteInHook(struct BusContext *context, ULONG offset)
485 return BYTEIN(context->io_base + offset);
490 /****i* etherlink3.device/LongInHook ***************************************
492 * NAME
493 * LongInHook
495 * SYNOPSIS
496 * value = LongInHook(context, offset)
498 * ULONG LongInHook(struct BusContext *, ULONG);
500 ****************************************************************************
504 static ULONG LongInHook(struct BusContext *context, ULONG offset)
506 return LONGIN(context->io_base + offset);
511 /****i* etherlink3.device/ByteOutHook **************************************
513 * NAME
514 * ByteOutHook
516 * SYNOPSIS
517 * ByteOutHook(context, offset, value)
519 * VOID ByteOutHook(struct BusContext *, ULONG, UBYTE);
521 ****************************************************************************
525 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
526 UBYTE value)
528 BYTEOUT(context->io_base + offset, value);
530 return;
535 /****i* etherlink3.device/WordOutHook **************************************
537 * NAME
538 * WordOutHook
540 * SYNOPSIS
541 * WordOutHook(context, offset, value)
543 * VOID WordOutHook(struct BusContext *, ULONG, UWORD);
545 ****************************************************************************
549 static VOID WordOutHook(struct BusContext *context, ULONG offset,
550 UWORD value)
552 WORDOUT(context->io_base + offset, value);
554 return;
559 /****i* etherlink3.device/LongOutHook **************************************
561 * NAME
562 * LongOutHook
564 * SYNOPSIS
565 * LongOutHook(context, offset, value)
567 * VOID LongOutHook(struct BusContext *, ULONG, ULONG);
569 ****************************************************************************
573 static VOID LongOutHook(struct BusContext *context, ULONG offset,
574 ULONG value)
576 LONGOUT(context->io_base + offset, value);
578 return;
583 /****i* etherlink3.device/LongsInHook **************************************
585 * NAME
586 * LongsInHook
588 * SYNOPSIS
589 * LongsInHook(context, offset, buffer, count)
591 * VOID LongsInHook(struct BusContext *, ULONG, ULONG *, ULONG);
593 ****************************************************************************
597 static VOID LongsInHook(struct BusContext *context, ULONG offset,
598 ULONG *buffer, ULONG count)
600 LONGSIN(context->io_base + offset, buffer, count);
602 return;
607 /****i* etherlink3.device/LongsOutHook *************************************
609 * NAME
610 * LongsOutHook
612 * SYNOPSIS
613 * LongsOutHook(context, offset, buffer, count)
615 * VOID LongsOutHook(struct BusContext *, ULONG, const ULONG *, ULONG);
617 ****************************************************************************
621 static VOID LongsOutHook(struct BusContext *context, ULONG offset,
622 const ULONG *buffer, ULONG count)
624 LONGSOUT(context->io_base + offset, buffer, count);
626 return;
631 /****i* etherlink3.device/BEWordOutHook ************************************
633 * NAME
634 * BEWordOutHook
636 * SYNOPSIS
637 * BEWordOutHook(context, offset, value)
639 * VOID BEWordOutHook(struct BusContext *, ULONG, UWORD);
641 ****************************************************************************
645 static VOID BEWordOutHook(struct BusContext *context, ULONG offset,
646 UWORD value)
648 BEWORDOUT(context->io_base + offset, value);
650 return;
655 /****i* etherlink3.device/LEWordInHook *************************************
657 * NAME
658 * LEWordInHook
660 * SYNOPSIS
661 * value = LEWordInHook(context, offset)
663 * UWORD LEWordInHook(struct BusContext *, ULONG);
665 ****************************************************************************
669 static UWORD LEWordInHook(struct BusContext *context, ULONG offset)
671 return LEWORDIN(context->io_base + offset);
676 /****i* etherlink3.device/LELongInHook ***************************************
678 * NAME
679 * LELongInHook
681 * SYNOPSIS
682 * value = LELongInHook(context, offset)
684 * ULONG LELongInHook(struct BusContext *, ULONG);
686 ****************************************************************************
690 static ULONG LELongInHook(struct BusContext *context, ULONG offset)
692 return LELONGIN(context->io_base + offset);
697 /****i* etherlink3.device/LEWordOutHook ************************************
699 * NAME
700 * LEWordOutHook
702 * SYNOPSIS
703 * LEWordOutHook(context, offset, value)
705 * VOID LEWordOutHook(struct BusContext *, ULONG, UWORD);
707 ****************************************************************************
711 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
712 UWORD value)
714 LEWORDOUT(context->io_base + offset, value);
716 return;
721 /****i* etherlink3.device/LELongOutHook ************************************
723 * NAME
724 * LELongOutHook
726 * SYNOPSIS
727 * LELongOutHook(context, offset, value)
729 * VOID LELongOutHook(struct BusContext *, ULONG, ULONG);
731 ****************************************************************************
735 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
736 ULONG value)
738 LELONGOUT(context->io_base + offset, value);
740 return;