Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / networks / intelpro100 / expansion.c
blobbe54870abcb4f3d9917ce62a759dbb3b87258bd6
1 /*
3 Copyright (C) 2004,2005 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 <expansion/pci.h>
26 #include <proto/exec.h>
27 #include <proto/expansion.h>
29 #include "device.h"
30 #include "pci.h"
32 #include "pci_protos.h"
33 #include "expansion_protos.h"
36 /* Private prototypes */
38 static UBYTE ByteInHook(struct BusContext *context, ULONG offset);
39 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
40 UBYTE value);
41 static UWORD LEWordInHook(struct BusContext *context, ULONG offset);
42 static ULONG LELongInHook(struct BusContext *context, ULONG offset);
43 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
44 UWORD value);
45 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
46 ULONG value);
47 static APTR AllocDMAMemHook(struct BusContext *context, UPINT size,
48 UWORD alignment);
49 static VOID FreeDMAMemHook(struct BusContext *context, APTR mem);
52 IMPORT const UWORD product_codes[];
55 static const struct TagItem unit_tags[] =
57 {IOTAG_ByteIn, (UPINT)ByteInHook},
58 {IOTAG_ByteOut, (UPINT)ByteOutHook},
59 {IOTAG_LEWordIn, (UPINT)LEWordInHook},
60 {IOTAG_LELongIn, (UPINT)LELongInHook},
61 {IOTAG_LEWordOut, (UPINT)LEWordOutHook},
62 {IOTAG_LELongOut, (UPINT)LELongOutHook},
63 {IOTAG_AllocDMAMem, (UPINT)AllocDMAMemHook},
64 {IOTAG_FreeDMAMem, (UPINT)FreeDMAMemHook},
65 {TAG_END, 0}
69 /****i* intelpro100.device/GetExpansionCount *******************************
71 * NAME
72 * GetExpansionCount -- Get the number of compatible PCI Cards.
74 * SYNOPSIS
75 * count = GetExpansionCount()
77 * ULONG GetExpansionCount();
79 ****************************************************************************
83 ULONG GetExpansionCount(struct DevBase *base)
85 ULONG count = 0;
86 struct PCIDevice *card;
88 if(base->i_pci != NULL)
90 while((card =
91 base->i_pci->FindDeviceTags(FDT_CandidateList, product_codes,
92 FDT_Index, count, TAG_END)) != NULL)
94 base->i_pci->FreeDevice(card);
95 count++;
99 return count;
104 /****i* intelpro100.device/AllocExpansionCard ******************************
106 * NAME
107 * AllocExpansionCard -- Take control of a card.
109 * SYNOPSIS
110 * context = AllocExpansionCard(index)
112 * struct BusContext *AllocExpansionCard(ULONG);
114 ****************************************************************************
118 struct BusContext *AllocExpansionCard(ULONG index, struct DevBase *base)
120 BOOL success = TRUE;
121 struct BusContext *context;
122 struct PCIDevice *card = NULL;
123 struct PCIResourceRange *io_range = NULL;
125 /* Find a compatible card */
127 context = AllocMem(sizeof(struct BusContext), MEMF_PUBLIC | MEMF_CLEAR);
128 if(context == NULL)
129 success = FALSE;
131 if(success)
133 context->card = card =
134 base->i_pci->FindDeviceTags(FDT_CandidateList, product_codes,
135 FDT_Index, index, TAG_END);
136 if(card == NULL)
137 success = FALSE;
140 if(success)
141 success = card->Lock(PCI_LOCK_EXCLUSIVE);
143 if(success)
145 context->have_card = TRUE;
146 /* card->SetEndian(PCI_MODE_REVERSE_ENDIAN);*/
147 io_range = card->GetResourceRange(BAR_NO);
148 context->io_base = io_range->BaseAddress;
149 card->FreeResourceRange(io_range);
150 context->unit_tags = unit_tags;
153 if(!success)
155 FreeExpansionCard(context, base);
156 context = NULL;
159 return context;
164 /****i* intelpro100.device/FreeExpansionCard *******************************
166 * NAME
167 * FreeExpansionCard -- Release a card.
169 * SYNOPSIS
170 * FreeExpansionCard(context)
172 * VOID FreeExpansionCard(struct BusContext *);
174 ****************************************************************************
178 VOID FreeExpansionCard(struct BusContext *context, struct DevBase *base)
180 struct PCIDevice *card;
182 if(context != NULL)
184 card = context->card;
185 if(card != NULL)
187 if(context->have_card)
188 card->Unlock();
189 base->i_pci->FreeDevice(card);
190 FreeMem(context, sizeof(struct BusContext));
194 return;
199 /****i* intelpro100.device/AddExpansionIntServer ***************************
201 * NAME
202 * AddExpansionIntServer
204 * SYNOPSIS
205 * context = AddExpansionIntServer(index)
207 * struct BusContext *AddExpansionIntServer(ULONG);
209 ****************************************************************************
213 BOOL AddExpansionIntServer(APTR card, struct Interrupt *interrupt,
214 struct DevBase *base)
216 return AddIntServer(((struct PCIDevice *)card)->MapInterrupt(),
217 interrupt);
222 /****i* intelpro100.device/RemExpansionIntServer ***************************
224 * NAME
225 * RemExpansionIntServer
227 * SYNOPSIS
228 * RemExpansionIntServer()
230 * VOID RemExpansionIntServer(ULONG);
232 ****************************************************************************
236 VOID RemExpansionIntServer(APTR card, struct Interrupt *interrupt,
237 struct DevBase *base)
239 RemIntServer(((struct PCIDevice *)card)->MapInterrupt(), interrupt);
241 return;
246 /****i* intelpro100.device/ByteInHook **************************************
248 * NAME
249 * ByteInHook
251 * SYNOPSIS
252 * value = ByteInHook(context, offset)
254 * UBYTE ByteInHook(struct BusContext *, ULONG);
256 ****************************************************************************
260 static UBYTE ByteInHook(struct BusContext *context, ULONG offset)
262 struct PCIDevice *card;
264 card = context->card;
265 return card->InWord(context->io_base + offset);
270 /****i* intelpro100.device/ByteOutHook *************************************
272 * NAME
273 * ByteOutHook
275 * SYNOPSIS
276 * ByteOutHook(context, offset, value)
278 * VOID ByteOutHook(struct BusContext *, ULONG, UBYTE);
280 ****************************************************************************
284 static VOID ByteOutHook(struct BusContext *context, ULONG offset,
285 UBYTE value)
287 struct PCIDevice *card;
289 card = context->card;
290 card->OutByte(context->io_base + offset, value);
292 return;
297 /****i* intelpro100.device/LEWordInHook ************************************
299 * NAME
300 * LEWordInHook
302 * SYNOPSIS
303 * value = LEWordInHook(context, offset)
305 * UWORD LEWordInHook(struct BusContext *, ULONG);
307 ****************************************************************************
311 static UWORD LEWordInHook(struct BusContext *context, ULONG offset)
313 struct PCIDevice *card;
315 card = context->card;
316 return BEWord(card->InWord(context->io_base + offset));
321 /****i* intelpro100.device/LELongInHook ************************************
323 * NAME
324 * LELongInHook
326 * SYNOPSIS
327 * value = LELongInHook(context, offset)
329 * ULONG LELongInHook(struct BusContext *, ULONG);
331 ****************************************************************************
335 static ULONG LELongInHook(struct BusContext *context, ULONG offset)
337 struct PCIDevice *card;
339 card = context->card;
340 return BELong(card->InLong(context->io_base + offset));
345 /****i* intelpro100.device/LEWordOutHook ***********************************
347 * NAME
348 * LEWordOutHook
350 * SYNOPSIS
351 * LEWordOutHook(context, offset, value)
353 * VOID LEWordOutHook(struct BusContext *, ULONG, UWORD);
355 ****************************************************************************
359 static VOID LEWordOutHook(struct BusContext *context, ULONG offset,
360 UWORD value)
362 struct PCIDevice *card;
364 card = context->card;
365 card->OutWord(context->io_base + offset, MakeBEWord(value));
367 return;
372 /****i* intelpro100.device/LELongOutHook ***********************************
374 * NAME
375 * LELongOutHook
377 * SYNOPSIS
378 * LELongOutHook(context, offset, value)
380 * VOID LELongOutHook(struct BusContext *, ULONG, ULONG);
382 ****************************************************************************
386 static VOID LELongOutHook(struct BusContext *context, ULONG offset,
387 ULONG value)
389 struct PCIDevice *card;
391 card = context->card;
392 card->OutLong(context->io_base + offset, MakeBELong(value));
394 return;
399 /****i* intelpro100.device/AllocDMAMemHook *********************************
401 * NAME
402 * AllocDMAMemHook
404 * SYNOPSIS
405 * mem = AllocDMAMemHook(context, size, alignment)
407 * APTR AllocDMAMemHook(struct BusContext *, UPINT, UWORD);
409 ****************************************************************************
411 * Alignment currently must be minimum of 8 bytes.
415 static APTR AllocDMAMemHook(struct BusContext *context, UPINT size,
416 UWORD alignment)
418 struct DevBase *base;
419 APTR mem = NULL, original_mem;
421 base = context->device;
422 size += 2 * sizeof(APTR) + alignment;
423 original_mem = AllocMem(size, MEMF_PUBLIC);
424 if(original_mem != NULL)
426 mem = (APTR)((UPINT)(original_mem + 2 * sizeof(APTR) + alignment - 1)
427 & ~(alignment - 1));
428 *((APTR *)mem - 1) = original_mem;
429 *((UPINT *)mem - 2) = size;
432 return mem;
437 /****i* intelpro100.device/FreeDMAMemHook **********************************
439 * NAME
440 * FreeDMAMemHook
442 * SYNOPSIS
443 * FreeDMAMemHook(context, mem)
445 * VOID FreeDMAMemHook(struct BusContext *, APTR);
447 ****************************************************************************
451 static VOID FreeDMAMemHook(struct BusContext *context, APTR mem)
453 struct DevBase *base;
455 base = context->device;
456 if(mem != NULL)
457 FreeMem(*((APTR *)mem - 1), *((UPINT *)mem - 2));
459 return;