2 Copyright (C) 2005 Neil Cafferkey
7 #include <exec/types.h>
8 #include <utility/tagitem.h>
9 #include <libraries/prometheus.h>
11 #include <proto/exec.h>
12 #include <proto/utility.h>
13 #include <proto/oop.h>
15 #include "prometheus_intern.h"
18 /* Private prototypes */
20 static VOID
WrapperIRQ(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*hw_info
);
23 static const struct TagItem map_tag_list
[] =
25 {PRM_Vendor
, aoHidd_PCIDevice_VendorID
},
26 {PRM_Device
, aoHidd_PCIDevice_ProductID
},
27 {PRM_Revision
, aoHidd_PCIDevice_RevisionID
},
28 {PRM_Class
, aoHidd_PCIDevice_Class
},
29 {PRM_SubClass
, aoHidd_PCIDevice_SubClass
},
30 {PRM_MemoryAddr0
, aoHidd_PCIDevice_Base0
},
31 {PRM_MemoryAddr1
, aoHidd_PCIDevice_Base1
},
32 {PRM_MemoryAddr2
, aoHidd_PCIDevice_Base2
},
33 {PRM_MemoryAddr3
, aoHidd_PCIDevice_Base3
},
34 {PRM_MemoryAddr4
, aoHidd_PCIDevice_Base4
},
35 {PRM_MemoryAddr5
, aoHidd_PCIDevice_Base5
},
36 {PRM_ROM_Address
, aoHidd_PCIDevice_RomBase
},
37 {PRM_MemorySize0
, aoHidd_PCIDevice_Size0
},
38 {PRM_MemorySize1
, aoHidd_PCIDevice_Size1
},
39 {PRM_MemorySize2
, aoHidd_PCIDevice_Size2
},
40 {PRM_MemorySize3
, aoHidd_PCIDevice_Size3
},
41 {PRM_MemorySize4
, aoHidd_PCIDevice_Size4
},
42 {PRM_MemorySize5
, aoHidd_PCIDevice_Size5
},
43 {PRM_ROM_Size
, aoHidd_PCIDevice_RomSize
},
44 {PRM_SlotNumber
, aoHidd_PCIDevice_Dev
},
45 {PRM_FunctionNumber
, aoHidd_PCIDevice_Sub
},
50 /***************************************************************************
53 AROS_LH2(PCIBoard
*, Prm_FindBoardTagList
,
56 AROS_LHA(PCIBoard
*, previous
, A0
),
57 AROS_LHA(struct TagItem
*, tag_list
, A1
),
60 struct Library
*, PrometheusBase
, 5, Prometheus
)
68 ***************************************************************************/
72 struct LibBase
*base
= (APTR
)PrometheusBase
;
74 const struct TagItem
*temp_tag_list
;
75 struct TagItem
*tag_item
;
76 struct PCIBoard
*board
, *tail
;
81 board
= (APTR
)previous
->node
.mln_Succ
;
83 board
= (APTR
)base
->boards
.mlh_Head
;
84 tail
= (APTR
)&base
->boards
.mlh_Tail
;
86 while(board
!= tail
&& !success
)
88 /* Check if the current board matches all requirements */
90 temp_tag_list
= tag_list
;
92 while((tag_item
= NextTagItem(&temp_tag_list
)) != NULL
)
94 tag
= tag_item
->ti_Tag
;
95 aros_tag
= GetTagData(tag
, TAG_DONE
, (const struct TagItem
*)map_tag_list
);
96 if(aros_tag
!= TAG_DONE
)
98 OOP_GetAttr(board
->aros_board
,
99 base
->pcidevice_attr_base
+ aros_tag
, (IPTR
*)&board_data
);
101 else if(tag
== PRM_BoardOwner
)
102 board_data
= (UPINT
)board
->owner
;
104 if(board_data
!= tag_item
->ti_Data
)
109 board
= (APTR
)board
->node
.mln_Succ
;
122 /***************************************************************************
125 AROS_LH2(ULONG
, Prm_GetBoardAttrsTagList
,
128 AROS_LHA(PCIBoard
*, board
, A0
),
129 AROS_LHA(struct TagItem
*, tag_list
, A1
),
132 struct Library
*, PrometheusBase
, 6, Prometheus
)
140 ***************************************************************************/
144 struct LibBase
*base
= (APTR
)PrometheusBase
;
148 struct TagItem
*tag_item
;
150 while((tag_item
= NextTagItem((const struct TagItem
**)&tag_list
)) != NULL
)
152 if(tag_item
->ti_Tag
== PRM_BoardOwner
)
154 tag_data_ptr
= (UPINT
*)tag_item
->ti_Data
;
155 *tag_data_ptr
= (UPINT
)board
->owner
;
160 aros_tag
= GetTagData(tag_item
->ti_Tag
, TAG_DONE
, map_tag_list
);
161 if(aros_tag
!= TAG_DONE
)
163 OOP_GetAttr(board
->aros_board
,
164 base
->pcidevice_attr_base
+ aros_tag
,
165 (IPTR
*)tag_item
->ti_Data
);
178 /***************************************************************************
181 AROS_LH2(ULONG
, Prm_SetBoardAttrsTagList
,
184 AROS_LHA(PCIBoard
*, board
, A0
),
185 AROS_LHA(struct TagItem
*, tag_list
, A1
),
188 struct Library
*, PrometheusBase
, 13, Prometheus
)
196 ***************************************************************************/
202 struct TagItem
*tag_item
;
204 tag_item
= FindTagItem(PRM_BoardOwner
, tag_list
);
207 new_owner
= (APTR
)tag_item
->ti_Data
;
208 if(new_owner
!= NULL
&& board
->owner
== NULL
209 || new_owner
== NULL
&& board
->owner
!= NULL
)
211 board
->owner
= new_owner
;
223 /***************************************************************************
226 AROS_LH2(UBYTE
, Prm_ReadConfigByte
,
229 AROS_LHA(PCIBoard
*, board
, A0
),
230 AROS_LHA(UBYTE
, offset
, D0
),
233 struct Library
*, PrometheusBase
, 9, Prometheus
)
241 ***************************************************************************/
245 struct pHidd_PCIDevice_ReadConfigByte message
;
248 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigByte
);
249 message
.reg
= offset
;
251 return (UBYTE
)OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
258 /***************************************************************************
261 AROS_LH3(VOID
, Prm_WriteConfigByte
,
264 AROS_LHA(PCIBoard
*, board
, A0
),
265 AROS_LHA(UBYTE
, data
, D0
),
266 AROS_LHA(UBYTE
, offset
, D1
),
269 struct Library
*, PrometheusBase
, 12, Prometheus
)
277 ***************************************************************************/
281 struct pHidd_PCIDevice_WriteConfigByte message
;
284 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigByte
);
285 message
.reg
= offset
;
288 OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
295 /***************************************************************************
298 AROS_LH2(UWORD
, Prm_ReadConfigWord
,
301 AROS_LHA(PCIBoard
*, board
, A0
),
302 AROS_LHA(UBYTE
, offset
, D0
),
305 struct Library
*, PrometheusBase
, 8, Prometheus
)
313 ***************************************************************************/
317 struct pHidd_PCIDevice_ReadConfigWord message
;
320 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigWord
);
321 message
.reg
= offset
& ~0x1;
323 return (UWORD
)OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
330 /***************************************************************************
333 AROS_LH3(VOID
, Prm_WriteConfigWord
,
336 AROS_LHA(PCIBoard
*, board
, A0
),
337 AROS_LHA(UWORD
, data
, D0
),
338 AROS_LHA(UBYTE
, offset
, D1
),
341 struct Library
*, PrometheusBase
, 11, Prometheus
)
349 ***************************************************************************/
353 struct pHidd_PCIDevice_WriteConfigWord message
;
356 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigWord
);
357 message
.reg
= offset
& ~0x1;
360 OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
367 /***************************************************************************
370 AROS_LH2(ULONG
, Prm_ReadConfigLong
,
373 AROS_LHA(PCIBoard
*, board
, A0
),
374 AROS_LHA(UBYTE
, offset
, D0
),
377 struct Library
*, PrometheusBase
, 7, Prometheus
)
385 ***************************************************************************/
389 struct pHidd_PCIDevice_ReadConfigLong message
;
392 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_ReadConfigLong
);
393 message
.reg
= offset
& ~0x3;
395 return (ULONG
)OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
402 /***************************************************************************
405 AROS_LH3(VOID
, Prm_WriteConfigLong
,
408 AROS_LHA(PCIBoard
*, board
, A0
),
409 AROS_LHA(ULONG
, data
, D0
),
410 AROS_LHA(UBYTE
, offset
, D1
),
413 struct Library
*, PrometheusBase
, 10, Prometheus
)
421 ***************************************************************************/
425 struct pHidd_PCIDevice_WriteConfigLong message
;
428 OOP_GetMethodID(IID_Hidd_PCIDevice
, moHidd_PCIDevice_WriteConfigLong
);
429 message
.reg
= offset
& ~0x3;
432 OOP_DoMethod(board
->aros_board
, (OOP_Msg
)&message
);
439 /***************************************************************************
442 AROS_LH2(BOOL
, Prm_AddIntServer
,
445 AROS_LHA(PCIBoard
*, board
, A0
),
446 AROS_LHA(struct Interrupt
*, interrupt
, A1
),
449 struct Library
*, PrometheusBase
, 14, Prometheus
)
457 ***************************************************************************/
461 struct LibBase
*base
= (APTR
)PrometheusBase
;
463 HIDDT_IRQ_Handler
*aros_irq
;
466 /* Allocate AROS int structure */
468 if(board
== NULL
|| board
->aros_irq
!= NULL
)
474 AllocMem(sizeof(HIDDT_IRQ_Handler
), MEMF_PUBLIC
| MEMF_CLEAR
);
479 /* Add AROS int to system */
483 OOP_GetAttr(board
->aros_board
,
484 base
->pcidevice_attr_base
+ aoHidd_PCIDevice_INTLine
, (IPTR
*)&int_no
);
485 board
->aros_irq
= aros_irq
;
486 aros_irq
->h_Node
.ln_Name
= interrupt
->is_Node
.ln_Name
;
487 aros_irq
->h_Code
= WrapperIRQ
;
488 aros_irq
->h_Data
= interrupt
;
490 success
= HIDD_IRQ_AddHandler(base
->irq_hidd
, aros_irq
, int_no
);
500 /***************************************************************************
503 AROS_LH2(VOID
, Prm_RemIntServer
,
506 AROS_LHA(PCIBoard
*, board
, A0
),
507 AROS_LHA(struct Interrupt
*, interrupt
, A1
),
510 struct Library
*, PrometheusBase
, 15, Prometheus
)
518 ***************************************************************************/
522 struct LibBase
*base
= (APTR
)PrometheusBase
;
526 HIDD_IRQ_RemHandler(base
->irq_hidd
, board
->aros_irq
);
527 FreeMem(board
->aros_irq
, sizeof(HIDDT_IRQ_Handler
));
528 board
->aros_irq
= NULL
;
538 /***************************************************************************
541 AROS_LH1(APTR
, Prm_AllocDMABuffer
,
544 AROS_LHA(ULONG
, size
, D0
),
547 struct Library
*, PrometheusBase
, 16, Prometheus
)
555 ***************************************************************************/
562 buffer
= AllocMem(size
, MEMF_PUBLIC
);
573 /***************************************************************************
576 AROS_LH2(VOID
, Prm_FreeDMABuffer
,
579 AROS_LHA(APTR
, buffer
, A0
),
580 AROS_LHA(ULONG
, size
, D0
),
583 struct Library
*, PrometheusBase
, 17, Prometheus
)
591 ***************************************************************************/
595 if(buffer
!= NULL
&& size
!= 0)
596 FreeMem(buffer
, size
);
605 /***************************************************************************
608 AROS_LH1(APTR
, Prm_GetPhysicalAddr
,
611 AROS_LHA(APTR
, address
, D0
),
614 struct Library
*, PrometheusBase
, 18, Prometheus
)
622 ***************************************************************************/
633 static VOID
WrapperIRQ(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*hw_info
)
635 struct Interrupt
*interrupt
;
637 interrupt
= (struct Interrupt
*)irq
->h_Data
;
638 AROS_UFC2(BOOL
, interrupt
->is_Code
,
639 AROS_UFCA(APTR
, interrupt
->is_Data
, A1
),
640 AROS_UFCA(APTR
, interrupt
->is_Code
, A5
));