Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / workbench / devs / USB / drivers / OHCI / ohcihub.c
blobddc2ac71e1a3b75c3ec133b8a176b7cc79ac2645
1 /*
2 Copyright (C) 2006 by Michal Schulz
3 $Id$
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.
21 #define DEBUG 0
23 #include <inttypes.h>
25 #include <exec/types.h>
26 #include <exec/errors.h>
27 #include <oop/oop.h>
28 #include <usb/usb.h>
29 #include <utility/tagitem.h>
30 #include <aros/debug.h>
31 #include <aros/symbolsets.h>
33 #include <devices/timer.h>
35 #include <hidd/hidd.h>
36 #include <hidd/pci.h>
38 #include <proto/oop.h>
39 #include <proto/utility.h>
41 #include <stdio.h>
43 #include "ohci.h"
45 BOOL METHOD(OHCI, Hidd_USBHub, GetHubDescriptor)
47 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
49 if (ohci->hubDescr.bDescriptorType) {
50 CopyMem(&ohci->hubDescr, msg->descriptor, sizeof(ohci->hubDescr));
51 return TRUE;
53 else
54 return FALSE;
57 BOOL METHOD(OHCI, Hidd_USBHub, OnOff)
59 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
60 BOOL retval = FALSE;
62 D(bug("[OHCI] USBHub::OnOff(%d)\n", msg->on));
64 if (msg->on)
65 retval = OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
67 uint32_t ctl = AROS_OHCI2LONG(mmio(ohci->regs->HcControl));
68 ctl &= ~HC_CTRL_HCFS_MASK;
69 ctl |= msg->on ? HC_CTRL_HCFS_OPERATIONAL : HC_CTRL_HCFS_SUSPENDED;
70 mmio(ohci->regs->HcControl) = AROS_LONG2OHCI(ctl);
72 ohci->running = msg->on;
75 * Some OHCI Root Hub interrupts pending and the HUB has been just enabled?
76 * Go, fire up the interrupts!
78 if (msg->on && ohci->pendingRHSC)
80 ohci->pendingRHSC = 0;
81 struct Interrupt *intr;
83 Disable();
84 ForeachNode(&ohci->intList, intr)
86 Cause(intr);
88 Enable();
91 if (!msg->on)
92 retval = OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
94 return retval;
97 BOOL METHOD(OHCI, Hidd_USBHub, PortReset)
99 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
100 int i;
102 D(bug("[OHCI] Port %d reset\n", msg->portNummer));
104 mmio(ohci->regs->HcRhPortStatus[msg->portNummer-1]) = AROS_LONG2OHCI(UPS_RESET);
106 for (i=0; i < 5; i++)
108 D(bug("[OHCI] Reset: Waiting for completion\n"));
110 ohci_Delay(ohci->tr, USB_PORT_ROOT_RESET_DELAY);
111 if ((mmio(ohci->regs->HcRhPortStatus[msg->portNummer-1]) & AROS_LONG2OHCI(UPS_RESET)) == 0)
112 break;
115 if (i == 5)
116 return FALSE;
118 mmio(ohci->regs->HcRhPortStatus[msg->portNummer-1]) = AROS_LONG2OHCI(UPS_C_PORT_RESET << 16);
120 return TRUE;
123 BOOL METHOD(OHCI, Hidd_USBHub, GetHubStatus)
125 return TRUE;
128 BOOL METHOD(OHCI, Hidd_USBHub, ClearHubFeature)
131 return TRUE;
134 BOOL METHOD(OHCI, Hidd_USBHub, SetHubFeature)
136 return TRUE;
139 BOOL METHOD(OHCI, Hidd_USBHub, GetPortStatus)
141 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
142 BOOL retval = FALSE;
144 if (msg->port >= 1 && msg->port <= ohci->hubDescr.bNbrPorts)
146 uint32_t val = AROS_OHCI2LONG(mmio(ohci->regs->HcRhPortStatus[msg->port-1]));
147 msg->status->wPortStatus = AROS_WORD2LE(val);
148 msg->status->wPortChange = AROS_WORD2LE(val >> 16);
149 retval = TRUE;
152 D(bug("[OHCI] GetPortStatus: sts=%04x chg=%04x\n", AROS_LE2WORD(msg->status->wPortStatus), AROS_LE2WORD(msg->status->wPortChange)));
154 return retval;
157 BOOL METHOD(OHCI, Hidd_USBHub, ClearPortFeature)
159 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
161 D(bug("[OHCI] ClearPortFeature(). Port=%d, Feature=%08x\n", msg->port, msg->feature));
163 if (msg->port > ohci->hubDescr.bNbrPorts)
164 return FALSE;
166 switch (msg->feature)
168 case UHF_PORT_ENABLE:
169 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_CURRENT_CONNECT_STATUS);
170 break;
172 case UHF_PORT_SUSPEND:
173 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_OVERCURRENT_INDICATOR);
174 break;
176 case UHF_PORT_POWER:
177 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_LOW_SPEED);
178 break;
180 case UHF_C_PORT_CONNECTION:
181 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_C_CONNECT_STATUS << 16);
182 break;
184 case UHF_C_PORT_ENABLE:
185 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_C_PORT_ENABLED << 16);
186 break;
188 case UHF_C_PORT_SUSPEND:
189 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_C_SUSPEND << 16);
190 break;
192 case UHF_C_PORT_OVER_CURRENT:
193 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_C_OVERCURRENT_INDICATOR << 16);
194 break;
196 case UHF_C_PORT_RESET:
197 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_C_PORT_RESET << 16);
198 break;
201 switch (msg->feature)
203 case UHF_C_PORT_CONNECTION:
204 case UHF_C_PORT_ENABLE:
205 case UHF_C_PORT_SUSPEND:
206 case UHF_C_PORT_OVER_CURRENT:
207 case UHF_C_PORT_RESET:
208 if (!CheckIO((struct IORequest *)ohci->timerReq))
209 AbortIO((struct IORequest *)ohci->timerReq);
210 GetMsg(&ohci->timerPort);
211 SetSignal(0, 1 << ohci->timerPort.mp_SigBit);
213 D(bug("[OHCI] Reenabling the RHSC interrupt\n"));
214 mmio(ohci->regs->HcInterruptEnable) = mmio(ohci->regs->HcInterruptEnable) | AROS_LONG2OHCI(HC_INTR_RHSC);
215 break;
217 default:
218 break;
221 return TRUE;
224 BOOL METHOD(OHCI, Hidd_USBHub, SetPortFeature)
226 ohci_data_t *ohci = OOP_INST_DATA(cl, o);
227 int i;
229 D(bug("[OHCI] SetPortFeature(). Port=%d, Feature=%08x\n", msg->port, msg->feature));
231 if (msg->port > ohci->hubDescr.bNbrPorts)
232 return FALSE;
234 switch (msg->feature)
236 case UHF_PORT_ENABLE:
237 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_PORT_ENABLED);
238 break;
240 case UHF_PORT_SUSPEND:
241 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_SUSPEND);
242 break;
244 case UHF_PORT_POWER:
245 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_PORT_POWER);
246 break;
248 case UHF_PORT_RESET:
249 mmio(ohci->regs->HcRhPortStatus[msg->port-1]) = AROS_LONG2OHCI(UPS_RESET);
250 for (i=0; i < 5; i++)
252 ohci_Delay(ohci->tr, USB_PORT_ROOT_RESET_DELAY);
253 if ((mmio(ohci->regs->HcRhPortStatus[msg->port-1]) & AROS_LONG2OHCI(UPS_RESET)) == 0)
254 break;
256 if (i == 5)
257 return FALSE;
259 break;
262 return TRUE;
265 AROS_INTH1(OHCI_HubInterrupt, ohci_data_t *,ohci)
267 AROS_INTFUNC_INIT
269 /* Remove self from the msg queue */
270 GetMsg(&ohci->timerPort);
272 if (ohci->timerReq->tr_node.io_Error == IOERR_ABORTED)
274 D(bug("[OHCI] INTR: Abrted\n"));
275 return FALSE;
278 D(bug("[OHCI] INTR: Reenabling the RHSC interrupt\n"));
280 /* Reenable the RHSC interrupt */
281 mmio(ohci->regs->HcInterruptStatus) = AROS_LONG2OHCI(HC_INTR_RHSC);
282 mmio(ohci->regs->HcInterruptEnable) = AROS_LONG2OHCI(HC_INTR_RHSC);
284 return FALSE;
286 AROS_INTFUNC_EXIT