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,
23 #include <exec/types.h>
24 #include <expansion/pci.h>
26 #include <proto/exec.h>
27 #include <proto/expansion.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
,
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
,
45 static VOID
LELongOutHook(struct BusContext
*context
, ULONG offset
,
47 static APTR
AllocDMAMemHook(struct BusContext
*context
, UPINT size
,
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
},
69 /****i* intelpro100.device/GetExpansionCount *******************************
72 * GetExpansionCount -- Get the number of compatible PCI Cards.
75 * count = GetExpansionCount()
77 * ULONG GetExpansionCount();
79 ****************************************************************************
83 ULONG
GetExpansionCount(struct DevBase
*base
)
86 struct PCIDevice
*card
;
88 if(base
->i_pci
!= NULL
)
91 base
->i_pci
->FindDeviceTags(FDT_CandidateList
, product_codes
,
92 FDT_Index
, count
, TAG_END
)) != NULL
)
94 base
->i_pci
->FreeDevice(card
);
104 /****i* intelpro100.device/AllocExpansionCard ******************************
107 * AllocExpansionCard -- Take control of a card.
110 * context = AllocExpansionCard(index)
112 * struct BusContext *AllocExpansionCard(ULONG);
114 ****************************************************************************
118 struct BusContext
*AllocExpansionCard(ULONG index
, struct DevBase
*base
)
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
);
133 context
->card
= card
=
134 base
->i_pci
->FindDeviceTags(FDT_CandidateList
, product_codes
,
135 FDT_Index
, index
, TAG_END
);
141 success
= card
->Lock(PCI_LOCK_EXCLUSIVE
);
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
;
155 FreeExpansionCard(context
, base
);
164 /****i* intelpro100.device/FreeExpansionCard *******************************
167 * FreeExpansionCard -- Release a card.
170 * FreeExpansionCard(context)
172 * VOID FreeExpansionCard(struct BusContext *);
174 ****************************************************************************
178 VOID
FreeExpansionCard(struct BusContext
*context
, struct DevBase
*base
)
180 struct PCIDevice
*card
;
184 card
= context
->card
;
187 if(context
->have_card
)
189 base
->i_pci
->FreeDevice(card
);
190 FreeMem(context
, sizeof(struct BusContext
));
199 /****i* intelpro100.device/AddExpansionIntServer ***************************
202 * AddExpansionIntServer
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(),
222 /****i* intelpro100.device/RemExpansionIntServer ***************************
225 * RemExpansionIntServer
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
);
246 /****i* intelpro100.device/ByteInHook **************************************
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 *************************************
276 * ByteOutHook(context, offset, value)
278 * VOID ByteOutHook(struct BusContext *, ULONG, UBYTE);
280 ****************************************************************************
284 static VOID
ByteOutHook(struct BusContext
*context
, ULONG offset
,
287 struct PCIDevice
*card
;
289 card
= context
->card
;
290 card
->OutByte(context
->io_base
+ offset
, value
);
297 /****i* intelpro100.device/LEWordInHook ************************************
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 ************************************
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 ***********************************
351 * LEWordOutHook(context, offset, value)
353 * VOID LEWordOutHook(struct BusContext *, ULONG, UWORD);
355 ****************************************************************************
359 static VOID
LEWordOutHook(struct BusContext
*context
, ULONG offset
,
362 struct PCIDevice
*card
;
364 card
= context
->card
;
365 card
->OutWord(context
->io_base
+ offset
, MakeBEWord(value
));
372 /****i* intelpro100.device/LELongOutHook ***********************************
378 * LELongOutHook(context, offset, value)
380 * VOID LELongOutHook(struct BusContext *, ULONG, ULONG);
382 ****************************************************************************
386 static VOID
LELongOutHook(struct BusContext
*context
, ULONG offset
,
389 struct PCIDevice
*card
;
391 card
= context
->card
;
392 card
->OutLong(context
->io_base
+ offset
, MakeBELong(value
));
399 /****i* intelpro100.device/AllocDMAMemHook *********************************
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
,
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)
428 *((APTR
*)mem
- 1) = original_mem
;
429 *((UPINT
*)mem
- 2) = size
;
437 /****i* intelpro100.device/FreeDMAMemHook **********************************
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
;
457 FreeMem(*((APTR
*)mem
- 1), *((UPINT
*)mem
- 2));