|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
24: *
25: * HISTORY
26: *
27: */
28:
29:
30: #include "AppleOHCI.h"
31: #include <libkern/OSByteOrder.h>
32:
33: #define nil (0)
34: #define DEBUGGING_LEVEL 0 // 1 = low; 2 = high; 3 = extreme
35:
36: #define super IOUSBController
37: #define self this
38:
39: void AppleOHCI::pollInterrupts(IOUSBCompletionAction safeAction)
40: {
41: register OHCIRegistersPtr pOHCIRegisters;
42: register UInt32 activeInterrupts;
43: register UInt32 interruptEnable;
44:
45: pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
46:
47: interruptEnable = OSSwapInt32(pOHCIRegisters->hcInterruptEnable);
48:
49: activeInterrupts = interruptEnable &
50: OSSwapInt32(pOHCIRegisters->hcInterruptStatus);
51:
52: if ((interruptEnable & kOHCIHcInterrupt_MIE) && (activeInterrupts != 0))
53: {
54: /*
55: * SchedulingOverrun Interrupt
56: */
57: if (activeInterrupts & kOHCIHcInterrupt_SO)
58: {
59: pOHCIUIMData->errors.scheduleOverrun++;
60: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_SO);
61: IOSync();
62:
63: #if (DEBUGGING_LEVEL > 0)
64: IOLog("<SchedulingOverrun Interrupt>\n");
65: #endif
66: }
67: /*
68: * WritebackDoneHead Interrupt
69: */
70: if (activeInterrupts & kOHCIHcInterrupt_WDH)
71: {
72: UIMProcessDoneQueue(safeAction);
73:
74: #if (DEBUGGING_LEVEL > 0)
75: IOLog("<WritebackDoneHead Interrupt>\n");
76: #endif
77: }
78: /*
79: * StartofFrame Interrupt
80: */
81: if (activeInterrupts & kOHCIHcInterrupt_SF)
82: {
83: // Clear the interrrupt
84: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_SF);
85:
86: // and mask it off so it doesn't happen again.
87: // will have to be turned on manually to happen again.
88: pOHCIRegisters->hcInterruptDisable = OSSwapInt32(kOHCIHcInterrupt_SF);
89:
90: #if (DEBUGGING_LEVEL > 0)
91: IOLog("<Frame Interrupt>\n");
92: #endif
93: // FIXME? ERIC performCommand(ROOT_HUB_FRAME, (void *)0);
94: }
95: /*
96: * ResumeDetected Interrupt
97: */
98: if (activeInterrupts & kOHCIHcInterrupt_RD)
99: {
100: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_RD);
101: #if (DEBUGGING_LEVEL > 0)
102: IOLog("<ResumeDetected Interrupt>\n");
103: #endif
104: }
105: /*
106: * Unrecoverable Error Interrupt
107: */
108: if (activeInterrupts & kOHCIHcInterrupt_UE)
109: {
110: pOHCIUIMData->errors.unrecoverableError++;
111: // Let's do a SW reset to recover from this condition.
112: // We could make sure all OCHI registers and in-memory
113: // data structures are valid, too.
114: pOHCIRegisters->hcCommandStatus = OSSwapInt32
115: (kOHCIHcCommandStatus_HCR);
116: delay(10 * MICROSECOND);
117: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_UE);
118: // zzzz - note I'm leaving the Control/Bulk list processing off
119: // for now. FIXME? ERIC
120:
121: pOHCIRegisters->hcControl = OSSwapInt32
122: ((kOHCIFunctionalState_Operational << kOHCIHcControl_HCFSPhase)
123: | kOHCIHcControl_PLE);
124:
125: #if (DEBUGGING_LEVEL > 0)
126: IOLog("<Unrecoverable Error Interrupt>\n");
127: #endif
128: }
129: /*
130: * FrameNumberOverflow Interrupt
131: */
132: if (activeInterrupts & kOHCIHcInterrupt_FNO)
133: {
134: // not really an error, but close enough
135: pOHCIUIMData->errors.frameNumberOverflow++;
136: if ((OSReadLittleInt16 (pOHCIUIMData->pHCCA, 0x80)
137: & kOHCIFmNumberMask) < kOHCIBit15)
138: {
139: pOHCIUIMData->frameNumber += kOHCIFrameOverflowBit;
140: }
141: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_FNO);
142: #if (DEBUGGING_LEVEL > 0)
143: IOLog("<FrameNumberOverflow Interrupt>\n");
144: #endif
145: }
146: /*
147: * RootHubStatusChange Interrupt
148: */
149: if (activeInterrupts & kOHCIHcInterrupt_RHSC)
150: {
151: // Clear status change.
152: pOHCIRegisters->hcInterruptStatus =
153: OSSwapInt32(kOHCIHcInterrupt_RHSC);
154:
155: #if (DEBUGGING_LEVEL > 0)
156: IOLog("<RHSC Interrupt>\n");
157: #endif
158:
159: UIMRootHubStatusChange();
160: }
161: /*
162: * OwnershipChange Interrupt
163: */
164: if (activeInterrupts & kOHCIHcInterrupt_OC)
165: {
166: // well, we certainly weren't expecting this!
167: pOHCIUIMData->errors.ownershipChange++;
168: pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_OC);
169:
170: #if (DEBUGGING_LEVEL > 0)
171: IOLog("<OwnershipChange Interrupt>\n");
172: #endif
173: }
174: }
175: }
176:
177: void AppleOHCI::OHCIUIMInterruptHandler(OSObject *owner,
178: IOInterruptEventSource * /*source*/,
179: int /*count*/)
180: {
181: register AppleOHCI *controller = (AppleOHCI *) owner;
182:
183: if (!controller)
184: return;
185: // Finish pending transactions first.
186: controller->finishPending();
187: controller->pollInterrupts();
188: }
189:
190: extern void print_td(OHCIGeneralTransferDescriptorPtr x);
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.