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,
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>
33 #include "isa_protos.h"
34 #include "unit_protos.h"
40 struct ISAPNP_Device
*card
;
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
,
59 static VOID
WordOutHook(struct BusContext
*context
, ULONG offset
,
61 static VOID
LongOutHook(struct BusContext
*context
, ULONG offset
,
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
,
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
,
73 static VOID
LELongOutHook(struct BusContext
*context
, ULONG offset
,
77 static const UWORD product_codes
[] =
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
},
108 /****i* etherlink3.device/GetISACount **************************************
111 * GetISACount -- Get the number of compatible ISA cards.
114 * count = GetISACount()
116 * ULONG GetISACount();
118 ****************************************************************************
122 ULONG
GetISACount(struct DevBase
*base
)
125 struct ISAPNP_Device
*card
= NULL
;
127 while((card
= ISAPNP_FindDevice(card
, -1, -1, -1)) != NULL
)
129 if(IsCardCompatible(card
, base
))
138 /****i* etherlink3.device/GetISAUnit ***************************************
141 * GetISAUnit -- Get a unit by number.
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
);
161 card
= CreateISAUnit(index
, base
);
165 AddTail((APTR
)&base
->isa_units
, (APTR
)unit
);
174 /****i* etherlink3.device/FindISAUnit **************************************
177 * FindISAUnit -- Find an existing unit by number.
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
;
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
)
201 unit
= (APTR
)unit
->node
.mln_Succ
;
212 /****i* etherlink3.device/CreateISAUnit ************************************
215 * CreateISAUnit -- Create an ISA unit.
218 * unit = CreateISAUnit(index)
220 * struct DevUnit *CreateISAUnit(ULONG);
223 * Creates a new ISA unit.
225 ****************************************************************************
229 struct DevUnit
*CreateISAUnit(ULONG index
, struct DevBase
*base
)
232 struct BusContext
*context
;
233 struct DevUnit
*unit
;
234 UWORD generation
, id
, i
;
235 UPINT io_base
, id_port
;
237 context
= AllocCard(index
, base
);
243 #if 0 /* Stuff below is for non-PnP only? */
245 /* Send initialisation ID sequence */
247 id_port
= 0xef0100; /* !!! */
252 for(i
= 0; i
< 0xff; i
++)
254 BYTEOUT(id_port
, (UBYTE
)id
);
256 if ((id
& 0x100) != 0)
260 /* Activate adapter */
262 BYTEOUT(id_port
, 0xff);
265 generation
= FIRST_GEN
;
271 generation
= SECOND_GEN
;
272 unit
= CreateUnit(unit_num
, NULL
, io_base
, generation
, ISA_BUS
, base
);
280 AddIntServer(x
, &unit
->status_int
);
284 DeleteISAUnit(unit
, base
);
293 /****i* etherlink3.device/DeleteISAUnit ************************************
296 * DeleteISAUnit -- Delete a unit.
299 * DeleteISAUnit(unit)
301 * VOID DeleteISAUnit(struct DevUnit *);
307 * unit - Device unit (can be NULL).
312 ****************************************************************************
316 VOID
DeleteISAUnit(struct DevUnit
*unit
, struct DevBase
*base
)
320 RemIntServer(x
, &unit
->status_int
);
321 DeleteUnit(unit
, base
);
329 /****i* etherlink3.device/AllocCard ****************************************
332 * AllocCard -- Get card from system.
335 * context = AllocCard(index)
337 * struct BusContext *AllocCard(ULONG);
339 ****************************************************************************
343 static struct BusContext
*AllocCard(ULONG index
, struct DevBase
*base
)
346 struct BusContext
*context
;
347 struct ISAPNP_Device
*card
= NULL
;
350 /* Find a compatible card */
352 card
= AllocMem(sizeof(struct BusContext
), MEMF_PUBLIC
| MEMF_CLEAR
);
360 card
= ISAPNP_FindDevice(card
, -1, -1, -1);
361 if(IsCardCompatible(card
, base
))
364 context
->card
= card
;
367 /* Get base address */
377 context
->lock
= ISAPNP_LockDevices(ISAPNP_LOCKF_NONE
, card
);
378 if(context
->lock
== NULL
)
384 FreeCard(context
, base
);
392 /****i* etherlink3.device/FreeCard *****************************************
395 * FreeCard -- Release a card
400 * VOID FreeCard(struct BusContext *);
402 ****************************************************************************
406 static VOID
FreeCard(struct BusContext
*context
, struct DevBase
*base
)
408 struct ISAPNP_Device
*card
= NULL
;
414 ISAPNP_UnlockDevices(context
->lock
);
416 FreeMem(context
, sizeof(struct BusContext
));
424 /****i* etherlink3.device/IsCardCompatible *********************************
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
;
445 id
= (APTR
)card
->isapnpd_IDs
.mlh_Head
;
446 tail
= (APTR
)&card
->isapnpd_IDs
.mlh_Tail
;
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
)
461 id
= (APTR
)id
->isapnpid_MinNode
.mln_Succ
;
469 /****i* etherlink3.device/ByteInHook ***************************************
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 ***************************************
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 **************************************
517 * ByteOutHook(context, offset, value)
519 * VOID ByteOutHook(struct BusContext *, ULONG, UBYTE);
521 ****************************************************************************
525 static VOID
ByteOutHook(struct BusContext
*context
, ULONG offset
,
528 BYTEOUT(context
->io_base
+ offset
, value
);
535 /****i* etherlink3.device/WordOutHook **************************************
541 * WordOutHook(context, offset, value)
543 * VOID WordOutHook(struct BusContext *, ULONG, UWORD);
545 ****************************************************************************
549 static VOID
WordOutHook(struct BusContext
*context
, ULONG offset
,
552 WORDOUT(context
->io_base
+ offset
, value
);
559 /****i* etherlink3.device/LongOutHook **************************************
565 * LongOutHook(context, offset, value)
567 * VOID LongOutHook(struct BusContext *, ULONG, ULONG);
569 ****************************************************************************
573 static VOID
LongOutHook(struct BusContext
*context
, ULONG offset
,
576 LONGOUT(context
->io_base
+ offset
, value
);
583 /****i* etherlink3.device/LongsInHook **************************************
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
);
607 /****i* etherlink3.device/LongsOutHook *************************************
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
);
631 /****i* etherlink3.device/BEWordOutHook ************************************
637 * BEWordOutHook(context, offset, value)
639 * VOID BEWordOutHook(struct BusContext *, ULONG, UWORD);
641 ****************************************************************************
645 static VOID
BEWordOutHook(struct BusContext
*context
, ULONG offset
,
648 BEWORDOUT(context
->io_base
+ offset
, value
);
655 /****i* etherlink3.device/LEWordInHook *************************************
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 ***************************************
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 ************************************
703 * LEWordOutHook(context, offset, value)
705 * VOID LEWordOutHook(struct BusContext *, ULONG, UWORD);
707 ****************************************************************************
711 static VOID
LEWordOutHook(struct BusContext
*context
, ULONG offset
,
714 LEWORDOUT(context
->io_base
+ offset
, value
);
721 /****i* etherlink3.device/LELongOutHook ************************************
727 * LELongOutHook(context, offset, value)
729 * VOID LELongOutHook(struct BusContext *, ULONG, ULONG);
731 ****************************************************************************
735 static VOID
LELongOutHook(struct BusContext
*context
, ULONG offset
,
738 LELONGOUT(context
->io_base
+ offset
, value
);