revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / prometheus / board.c
blob5dbd643c16692c605b784ce90d6af93e655ef9a8
1 /*
2 Copyright © 2005-2016, The AROS Development Team. All rights reserved.
3 $Id$
4 */
7 #include <exec/types.h>
8 #include <utility/tagitem.h>
9 #include <libraries/prometheus.h>
11 #include <proto/exec.h>
12 #include <proto/kernel.h>
13 #include <proto/utility.h>
14 #include <proto/oop.h>
16 #include "prometheus_intern.h"
18 #define KernelBase (base->kernelBase)
20 /* Private prototypes */
22 static const struct TagItem map_tag_list[] =
24 {PRM_Vendor, aoHidd_PCIDevice_VendorID},
25 {PRM_Device, aoHidd_PCIDevice_ProductID},
26 {PRM_Revision, aoHidd_PCIDevice_RevisionID},
27 {PRM_Class, aoHidd_PCIDevice_Class},
28 {PRM_SubClass, aoHidd_PCIDevice_SubClass},
29 {PRM_MemoryAddr0, aoHidd_PCIDevice_Base0},
30 {PRM_MemoryAddr1, aoHidd_PCIDevice_Base1},
31 {PRM_MemoryAddr2, aoHidd_PCIDevice_Base2},
32 {PRM_MemoryAddr3, aoHidd_PCIDevice_Base3},
33 {PRM_MemoryAddr4, aoHidd_PCIDevice_Base4},
34 {PRM_MemoryAddr5, aoHidd_PCIDevice_Base5},
35 {PRM_ROM_Address, aoHidd_PCIDevice_RomBase},
36 {PRM_MemorySize0, aoHidd_PCIDevice_Size0},
37 {PRM_MemorySize1, aoHidd_PCIDevice_Size1},
38 {PRM_MemorySize2, aoHidd_PCIDevice_Size2},
39 {PRM_MemorySize3, aoHidd_PCIDevice_Size3},
40 {PRM_MemorySize4, aoHidd_PCIDevice_Size4},
41 {PRM_MemorySize5, aoHidd_PCIDevice_Size5},
42 {PRM_ROM_Size, aoHidd_PCIDevice_RomSize},
43 {PRM_SlotNumber, aoHidd_PCIDevice_Dev},
44 {PRM_FunctionNumber, aoHidd_PCIDevice_Sub},
45 {TAG_END, 0}
48 static const struct Node foreign_owner =
50 .ln_Name = "AROS"
53 static UPINT GetOwner(struct LibBase *base, PCIBoard *board)
55 const struct Node *owner = board->owner;
57 if (!owner)
60 * The board is not owned via prometheus.library API.
61 * But it could be owned via some other API. In this case
62 * we supply own struct Node.
64 IPTR aros_owner;
66 OOP_GetAttr(board->aros_board, aHidd_PCIDevice_Owner, &aros_owner);
67 if (aros_owner)
68 owner = &foreign_owner;
71 return (UPINT)owner;
74 /***************************************************************************
76 NAME */
77 AROS_LH2(PCIBoard *, Prm_FindBoardTagList,
79 /* SYNOPSIS */
80 AROS_LHA(PCIBoard *, previous, A0),
81 AROS_LHA(struct TagItem *, tag_list, A1),
83 /* LOCATION */
84 struct Library *, PrometheusBase, 5, Prometheus)
86 /* FUNCTION
87 Find the board whose properties match the given set
88 of attributes.
90 INPUTS
91 previous - an opaque pointer to previously found board,
92 or NULL to start the search from the beginning
93 tag_list - a pointer to a taglist specifying attributes to
94 match against. If NULL, then all boards will be
95 considered matching.
97 RESULT
98 A pointer to next matching board object or NULL if the search
99 has ended and there is no more match.
101 NOTES
102 You can search for boards with some specific owner using
103 PRM_BoardOwner tag. However note that in AROS prometheus.library
104 is a wrapper on top of native object-oriented framework. This
105 framework uses different concept of device ownership, and
106 prometheus.library cannot determine correct owner value for devices
107 locked using those APIs. Those devices are treated as having the
108 same owner named "AROS", however in reality their owners will be
109 different.
111 ***************************************************************************/
113 AROS_LIBFUNC_INIT
115 struct LibBase *base = (APTR)PrometheusBase;
116 Tag tag, aros_tag;
117 struct TagItem *temp_tag_list;
118 struct TagItem *tag_item;
119 struct PCIBoard *board, *tail;
120 BOOL success = FALSE;
121 UPINT board_data;
123 if(previous != NULL)
124 board = (APTR)previous->node.mln_Succ;
125 else
126 board = (APTR)base->boards.mlh_Head;
127 tail = (APTR)&base->boards.mlh_Tail;
129 while(board != tail && !success)
131 /* Check if the current board matches all requirements */
133 temp_tag_list = tag_list;
134 success = TRUE;
135 while((tag_item = NextTagItem(&temp_tag_list)) != NULL)
137 tag = tag_item->ti_Tag;
139 switch (tag)
141 case PRM_BoardOwner:
142 board_data = GetOwner(base, board);
143 break;
145 default:
146 aros_tag = GetTagData(tag, TAG_DONE, (struct TagItem *)map_tag_list);
147 if (aros_tag != TAG_DONE)
148 OOP_GetAttr(board->aros_board, base->pcidevice_attr_base + aros_tag,
149 &board_data);
150 else
151 success = FALSE;
152 break;
155 if(board_data != tag_item->ti_Data)
156 success = FALSE;
159 if(!success)
160 board = (APTR)board->node.mln_Succ;
163 if(!success)
164 board = NULL;
166 return board;
168 AROS_LIBFUNC_EXIT
171 /***************************************************************************
173 NAME */
174 AROS_LH2(ULONG, Prm_GetBoardAttrsTagList,
176 /* SYNOPSIS */
177 AROS_LHA(PCIBoard *, board, A0),
178 AROS_LHA(struct TagItem *, tag_list, A1),
180 /* LOCATION */
181 struct Library *, PrometheusBase, 6, Prometheus)
183 /* FUNCTION
184 Returns information about the board according to the
185 specified taglist.
187 INPUTS
188 board - an opaque pointer to board object to query
189 tag_list - a list of attributes to query. ti_Data for
190 every tag should be a pointer to IPTR storage
191 where the data will be written. For unrecognized
192 tags a value of 0 will be returned. Tags with
193 ti_Data set to NULL will be skipped.
195 RESULT
196 Number of successfully processed tags.
198 NOTES
199 AROS implementation of prometheus.library is a wrapper on top of
200 object-oriented driver stack. Software can use either
201 prometheus.library, or some other wrapper API (like openpci.library)
202 or HIDD object-oriented API directly. Concept of device ownership
203 is different across different APIs, so this method returns correct
204 device owner only if the device was locked using prometheus.library's
205 Prm_SetBoardAttrsTagList() function. If device's owner uses another
206 API, prometheus.library will specify "AROS" default name.
208 ***************************************************************************/
210 AROS_LIBFUNC_INIT
212 struct LibBase *base = (APTR)PrometheusBase;
213 ULONG count = 0;
214 Tag aros_tag;
215 UPINT *tag_data_ptr;
216 struct TagItem *tag_item;
218 while((tag_item = NextTagItem(&tag_list)) != NULL)
220 if (!tag_item->ti_Data)
221 continue;
223 if(tag_item->ti_Tag == PRM_BoardOwner)
225 tag_data_ptr = (UPINT *)tag_item->ti_Data;
226 *tag_data_ptr = GetOwner(base, board);
227 count++;
229 else
231 aros_tag = GetTagData(tag_item->ti_Tag, TAG_DONE, (struct TagItem *)map_tag_list);
232 if(aros_tag != TAG_DONE)
234 OOP_GetAttr(board->aros_board,
235 base->pcidevice_attr_base + aros_tag,
236 (IPTR *)tag_item->ti_Data);
237 count++;
242 return count;
244 AROS_LIBFUNC_EXIT
249 /***************************************************************************
251 NAME */
252 AROS_LH2(ULONG, Prm_SetBoardAttrsTagList,
254 /* SYNOPSIS */
255 AROS_LHA(PCIBoard *, board, A0),
256 AROS_LHA(struct TagItem *, tag_list, A1),
258 /* LOCATION */
259 struct Library *, PrometheusBase, 13, Prometheus)
261 /* FUNCTION
263 INPUTS
265 RESULT
267 ***************************************************************************/
269 AROS_LIBFUNC_INIT
271 struct LibBase *base = (struct LibBase *)PrometheusBase;
272 ULONG count = 0;
273 struct Node *new_owner;
274 struct TagItem *tag_item;
276 tag_item = FindTagItem(PRM_BoardOwner, tag_list);
277 if(tag_item != NULL)
279 new_owner = (APTR)tag_item->ti_Data;
281 if (new_owner)
283 CONST_STRPTR new_str = new_owner->ln_Name;
284 CONST_STRPTR old_str;
286 /* Just in case. We cannot specify NULL owner to PCIDevice::Obtain() */
287 if (!new_str)
288 new_str = base->lib_header.lib_Node.ln_Name;
290 old_str = HIDD_PCIDevice_Obtain(board->aros_board, new_str);
291 if (!old_str)
293 board->owner = new_owner;
294 count++;
297 else if (board->owner)
299 HIDD_PCIDevice_Release(board->aros_board);
300 board->owner = NULL;
301 count++;
305 return count;
307 AROS_LIBFUNC_EXIT
312 /***************************************************************************
314 NAME */
315 AROS_LH2(UBYTE, Prm_ReadConfigByte,
317 /* SYNOPSIS */
318 AROS_LHA(PCIBoard *, board, A0),
319 AROS_LHA(UBYTE, offset, D0),
321 /* LOCATION */
322 struct Library *, PrometheusBase, 9, Prometheus)
324 /* FUNCTION
326 INPUTS
328 RESULT
330 ***************************************************************************/
332 AROS_LIBFUNC_INIT
334 struct LibBase *base = (struct LibBase *)PrometheusBase;
336 return HIDD_PCIDevice_ReadConfigByte(board->aros_board, offset);
338 AROS_LIBFUNC_EXIT
343 /***************************************************************************
345 NAME */
346 AROS_LH3(VOID, Prm_WriteConfigByte,
348 /* SYNOPSIS */
349 AROS_LHA(PCIBoard *, board, A0),
350 AROS_LHA(UBYTE, data, D0),
351 AROS_LHA(UBYTE, offset, D1),
353 /* LOCATION */
354 struct Library *, PrometheusBase, 12, Prometheus)
356 /* FUNCTION
358 INPUTS
360 RESULT
362 ***************************************************************************/
364 AROS_LIBFUNC_INIT
366 struct LibBase *base = (struct LibBase *)PrometheusBase;
368 HIDD_PCIDevice_WriteConfigByte(board->aros_board, offset, data);
370 AROS_LIBFUNC_EXIT
375 /***************************************************************************
377 NAME */
378 AROS_LH2(UWORD, Prm_ReadConfigWord,
380 /* SYNOPSIS */
381 AROS_LHA(PCIBoard *, board, A0),
382 AROS_LHA(UBYTE, offset, D0),
384 /* LOCATION */
385 struct Library *, PrometheusBase, 8, Prometheus)
387 /* FUNCTION
389 INPUTS
391 RESULT
393 ***************************************************************************/
395 AROS_LIBFUNC_INIT
397 struct LibBase *base = (struct LibBase *)PrometheusBase;
399 return HIDD_PCIDevice_ReadConfigWord(board->aros_board, offset & ~0x1);
401 AROS_LIBFUNC_EXIT
406 /***************************************************************************
408 NAME */
409 AROS_LH3(VOID, Prm_WriteConfigWord,
411 /* SYNOPSIS */
412 AROS_LHA(PCIBoard *, board, A0),
413 AROS_LHA(UWORD, data, D0),
414 AROS_LHA(UBYTE, offset, D1),
416 /* LOCATION */
417 struct Library *, PrometheusBase, 11, Prometheus)
419 /* FUNCTION
421 INPUTS
423 RESULT
425 ***************************************************************************/
427 AROS_LIBFUNC_INIT
429 struct LibBase *base = (struct LibBase *)PrometheusBase;
431 HIDD_PCIDevice_WriteConfigWord(board->aros_board, offset & ~0x1, data);
433 AROS_LIBFUNC_EXIT
438 /***************************************************************************
440 NAME */
441 AROS_LH2(ULONG, Prm_ReadConfigLong,
443 /* SYNOPSIS */
444 AROS_LHA(PCIBoard *, board, A0),
445 AROS_LHA(UBYTE, offset, D0),
447 /* LOCATION */
448 struct Library *, PrometheusBase, 7, Prometheus)
450 /* FUNCTION
452 INPUTS
454 RESULT
456 ***************************************************************************/
458 AROS_LIBFUNC_INIT
460 struct LibBase *base = (struct LibBase *)PrometheusBase;
462 return HIDD_PCIDevice_ReadConfigLong(board->aros_board, offset & ~0x3);
464 AROS_LIBFUNC_EXIT
469 /***************************************************************************
471 NAME */
472 AROS_LH3(VOID, Prm_WriteConfigLong,
474 /* SYNOPSIS */
475 AROS_LHA(PCIBoard *, board, A0),
476 AROS_LHA(ULONG, data, D0),
477 AROS_LHA(UBYTE, offset, D1),
479 /* LOCATION */
480 struct Library *, PrometheusBase, 10, Prometheus)
482 /* FUNCTION
484 INPUTS
486 RESULT
488 ***************************************************************************/
490 AROS_LIBFUNC_INIT
492 struct LibBase *base = (struct LibBase *)PrometheusBase;
494 HIDD_PCIDevice_WriteConfigLong(board->aros_board, offset & ~0x3, data);
496 AROS_LIBFUNC_EXIT
501 /***************************************************************************
503 NAME */
504 AROS_LH2(BOOL, Prm_AddIntServer,
506 /* SYNOPSIS */
507 AROS_LHA(PCIBoard *, board, A0),
508 AROS_LHA(struct Interrupt *, interrupt, A1),
510 /* LOCATION */
511 struct Library *, PrometheusBase, 14, Prometheus)
513 /* FUNCTION
515 INPUTS
517 RESULT
519 ***************************************************************************/
521 AROS_LIBFUNC_INIT
523 struct LibBase *base = (APTR)PrometheusBase;
524 BOOL success = FALSE;
526 /* Add AROS int to system */
527 if (board)
528 success = HIDD_PCIDevice_AddInterrupt(board->aros_board, interrupt);
530 return success;
532 AROS_LIBFUNC_EXIT
537 /***************************************************************************
539 NAME */
540 AROS_LH2(VOID, Prm_RemIntServer,
542 /* SYNOPSIS */
543 AROS_LHA(PCIBoard *, board, A0),
544 AROS_LHA(struct Interrupt *, interrupt, A1),
546 /* LOCATION */
547 struct Library *, PrometheusBase, 15, Prometheus)
549 /* FUNCTION
551 INPUTS
553 RESULT
555 ***************************************************************************/
557 AROS_LIBFUNC_INIT
559 struct LibBase *base = (APTR)PrometheusBase;
561 if(board != NULL)
562 HIDD_PCIDevice_RemoveInterrupt(board->aros_board, interrupt);
564 AROS_LIBFUNC_EXIT
569 /***************************************************************************
571 NAME */
572 AROS_LH1(APTR, Prm_AllocDMABuffer,
574 /* SYNOPSIS */
575 AROS_LHA(ULONG, size, D0),
577 /* LOCATION */
578 struct Library *, PrometheusBase, 16, Prometheus)
580 /* FUNCTION
581 Allocate memory region accessible by PCI DMA.
583 INPUTS
584 size - Size of the region to allocate. NULL is safe
585 input, in this case the function fails.
587 RESULT
588 A pointer to allocated region or NULL upon failure.
589 The region will always be LONG-aligned.
591 ***************************************************************************/
593 AROS_LIBFUNC_INIT
596 * This should be OK for any "direct" PCI bus.
597 * Note that this also relies on AllocMem()'s ability to return
598 * NULL when zero size is given.
600 return AllocMem(size, MEMF_31BIT);
602 AROS_LIBFUNC_EXIT
607 /***************************************************************************
609 NAME */
610 AROS_LH2(VOID, Prm_FreeDMABuffer,
612 /* SYNOPSIS */
613 AROS_LHA(APTR, buffer, A0),
614 AROS_LHA(ULONG, size, D0),
616 /* LOCATION */
617 struct Library *, PrometheusBase, 17, Prometheus)
619 /* FUNCTION
620 Free memory buffer allocated by Prm_AllocDMABuffer().
622 INPUTS
623 buffer - a pointer to a buffer to free. NULL is a safe value,
624 in this case the function does nothing.
625 size - size of the buffer. Zero is a safe value, in this case
626 the function does nothing.
628 RESULT
629 None.
631 ***************************************************************************/
633 AROS_LIBFUNC_INIT
636 * Note that this relies on FreeMem()'s ability to ignore
637 * zero buffer or size.
639 FreeMem(buffer, size);
641 AROS_LIBFUNC_EXIT
646 /***************************************************************************
648 NAME */
649 AROS_LH1(APTR, Prm_GetPhysicalAddr,
651 /* SYNOPSIS */
652 AROS_LHA(APTR, address, D0),
654 /* LOCATION */
655 struct Library *, PrometheusBase, 18, Prometheus)
657 /* FUNCTION
659 INPUTS
661 RESULT
663 ***************************************************************************/
665 AROS_LIBFUNC_INIT
667 struct LibBase *base = (struct LibBase *)PrometheusBase;
669 /* This should be OK for any "direct" PCI bus */
670 return KrnVirtualToPhysical(address);
672 AROS_LIBFUNC_EXIT