2 Copyright (C) 2006 by Michal Schulz
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include <aros/symbolsets.h>
26 #include <hidd/hidd.h>
33 #include <proto/exec.h>
34 #include <proto/oop.h>
35 #include <aros/debug.h>
40 #define SD(x) (&LIBBASE->sd)
43 AROS_UFH3(void, Enumerator
,
44 AROS_UFHA(struct Hook
*, hook
, A0
),
45 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
46 AROS_UFHA(APTR
, message
, A1
))
50 ohci_registers_t
*regs
;
52 struct timerequest
*tr
= ohci_CreateTimer();
55 if (counter
== MAX_OHCI_DEVICES
)
58 LIBBASETYPE
*LIBBASE
= (LIBBASETYPE
*)hook
->h_Data
;
60 struct TagItem attrs
[] = {
61 { aHidd_PCIDevice_isMEM
, TRUE
},
62 { aHidd_PCIDevice_isMaster
, TRUE
},
66 OOP_SetAttrs(pciDevice
, (struct TagItem
*)attrs
);
67 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, &LIBBASE
->sd
.ramBase
[counter
]);
68 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (void *)&LIBBASE
->sd
.pciDriver
[counter
]);
69 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_INTLine
, &tmp
);
71 LIBBASE
->sd
.irqNum
[counter
] = tmp
;
72 LIBBASE
->sd
.pciDevice
[counter
] = pciDevice
;
74 regs
= (ohci_registers_t
*)LIBBASE
->sd
.ramBase
[counter
];
76 LIBBASE
->sd
.numPorts
[counter
] = HC_RHA_GET_NDP(AROS_OHCI2LONG(mmio(regs
->HcRhDescriptorA
)));
78 D(bug("[OHCI] %d-port Device %d @ %08x with MMIO @ %08x\n", LIBBASE
->sd
.numPorts
[counter
], counter
+ 1, pciDevice
, LIBBASE
->sd
.ramBase
[counter
]));
80 uint32_t ctrl
= AROS_OHCI2LONG(mmio(regs
->HcControl
));
81 if (ctrl
& HC_CTRL_IR
)
83 D(bug("[OHCI] Performing BIOS handoff\n"));
84 int delay
= 500; /* 0.5 second */
85 mmio(regs
->HcInterruptEnable
) = AROS_LONG2OHCI(HC_INTR_OC
);
86 mmio(regs
->HcCommandStatus
) = AROS_LONG2OHCI(HC_CS_OCR
);
89 while ((delay
> 0) && AROS_OHCI2LONG(mmio(regs
->HcControl
) & HC_CTRL_IR
))
95 D(bug("[OHCI] BIOS handoff failed!\n"));
97 mmio(regs
->HcControl
) = AROS_LONG2OHCI(ctrl
& HC_CTRL_RWC
);
100 /* Disable all interrupts */
101 mmio(regs
->HcInterruptDisable
) = AROS_LONG2OHCI(0xffffffff);
102 mmio(regs
->HcInterruptStatus
) = AROS_LONG2OHCI(0xffffffff);
104 LIBBASE
->sd
.numDevices
= ++counter
;
106 ohci_DeleteTimer(tr
);
112 static int OHCI_Init(LIBBASETYPEPTR LIBBASE
)
114 D(bug("[OHCI] OHCI_Init()\n"));
116 LIBBASE
->sd
.usb
= OOP_NewObject(NULL
, (STRPTR
)CLID_Hidd_USB
, NULL
);
118 NEWLIST(&LIBBASE
->sd
.tdList
);
119 InitSemaphore(&LIBBASE
->sd
.tdLock
);
121 if (!LIBBASE
->sd
.usb
)
123 bug("[OHCI] Cannot create the instance of base USB class\n");
127 if ((LIBBASE
->sd
.pci
=OOP_NewObject(NULL
, (STRPTR
)CLID_Hidd_PCI
, NULL
)))
129 struct TagItem tags
[] = {
130 { tHidd_PCI_Class
, PCI_BASE_CLASS_SERIAL
},
131 { tHidd_PCI_SubClass
, PCI_SUB_CLASS_USB
},
132 { tHidd_PCI_Interface
, PCI_INTERFACE_OHCI
},
136 struct OOP_ABDescr attrbases
[] = {
137 { (STRPTR
)IID_Hidd
, &HiddAttrBase
},
138 { (STRPTR
)IID_Hidd_PCIDevice
, &HiddPCIDeviceAttrBase
},
139 { (STRPTR
)IID_Hidd_USBDevice
, &HiddUSBDeviceAttrBase
},
140 { (STRPTR
)IID_Hidd_USBHub
, &HiddUSBHubAttrBase
},
141 { (STRPTR
)IID_Hidd_USBDrv
, &HiddUSBDrvAttrBase
},
145 struct Hook FindHook
= {
146 h_Entry
: (IPTR (*)())Enumerator
,
150 OOP_ObtainAttrBases(attrbases
);
152 D(bug("[OHCI] Searching for OHCI devices...\n"));
154 HIDD_PCI_EnumDevices(LIBBASE
->sd
.pci
, &FindHook
, (struct TagItem
*)&tags
);
156 D(bug("[OHCI] Done. OHCI devices found: %d\n", LIBBASE
->sd
.numDevices
));
158 if (LIBBASE
->sd
.numDevices
> 0)
160 LIBBASE
->sd
.memPool
= CreatePool(MEMF_CLEAR
| MEMF_PUBLIC
| MEMF_SEM_PROTECTED
, 8192, 4096);
162 if (LIBBASE
->sd
.memPool
)
171 static int OHCI_Expunge(LIBBASETYPEPTR LIBBASE
)
173 struct OOP_ABDescr attrbases
[] = {
174 { (STRPTR
)IID_Hidd
, &HiddAttrBase
},
175 { (STRPTR
)IID_Hidd_PCIDevice
, &HiddPCIDeviceAttrBase
},
176 { (STRPTR
)IID_Hidd_USBDevice
, &HiddUSBDeviceAttrBase
},
177 { (STRPTR
)IID_Hidd_USBHub
, &HiddUSBHubAttrBase
},
178 { (STRPTR
)IID_Hidd_USBDrv
, &HiddUSBDrvAttrBase
},
182 OOP_ReleaseAttrBases(attrbases
);
187 ADD2INITLIB(OHCI_Init
, 0)
188 ADD2EXPUNGELIB(OHCI_Expunge
, 0)
189 ADD2LIBS((STRPTR
)"usb.hidd", 0, static struct Library
*, __usbbase
)