13static void addToHcEndpointList(u8 type,
UsbdHcED_t *ed)
15 ed->m_next = memPool->m_hcEdBuf[type].m_next;
16 memPool->m_hcEdBuf[type].m_next = ed;
19static void removeHcEdFromList(
int type,
const UsbdHcED_t *hcEd)
24 prev = &memPool->m_hcEdBuf[type];
25 for ( pos = prev->m_next; pos && pos != hcEd; prev = pos, pos = pos->m_next )
30 prev->m_next = pos->m_next;
38 u32 *interruptBandwidthSchedulingValues;
44 int packetSizeForScheduling;
47 maxPacketSize = endpDesc->wMaxPacketSizeLB + (endpDesc->wMaxPacketSizeHB << 8);
48 interruptBandwidthSchedulingValues = memPool->m_interruptBandwidthSchedulingValues;
49 if ( endpDesc->bInterval >= 0x20u )
55 else if ( endpDesc->bInterval >= 0x10u )
61 else if ( endpDesc->bInterval >= 8u )
67 else if ( endpDesc->bInterval >= 4u )
73 else if ( endpDesc->bInterval >= 2u )
92 for ( i = 0; i < waitLow; i += 1 )
99 value_ptr1 = &interruptBandwidthSchedulingValues[i];
100 for ( j = 0; j < waitHigh; j += 1 )
102 valueSum += *value_ptr1;
103 value_ptr1 += waitLow;
105 if ( schedulingIndex < 0 || valueSum < maxValueSum )
108 maxValueSum = valueSum;
111 endpType += schedulingIndex;
113 packetSizeForScheduling = maxPacketSize + 13;
114 if ( maxPacketSize >= 65 )
115 packetSizeForScheduling = 77;
116 ep->m_schedulingIndex = schedulingIndex;
117 ep->m_waitHigh = waitHigh;
118 ep->m_waitLow = waitLow;
119 ep->m_packetSizeForScheduling = packetSizeForScheduling;
120 if ( isLowSpeedDevice )
121 packetSizeForScheduling *= 8;
122 value_ptr2 = &interruptBandwidthSchedulingValues[schedulingIndex];
123 for ( i = 0; i < waitHigh; i += 1 )
125 *value_ptr2 += packetSizeForScheduling;
126 value_ptr2 += waitLow;
131static void removeEndpointFromQueue(
const UsbdEndpoint_t *ep,
int isLowSpeedDevice)
136 value_ptr = &memPool->m_interruptBandwidthSchedulingValues[ep->m_schedulingIndex];
137 for ( i = 0; i < ep->m_waitHigh; i += 1 )
139 *value_ptr -= (ep->m_packetSizeForScheduling * (isLowSpeedDevice ? 8 : 1));
140 if ( (
int)*value_ptr < 0 )
142 value_ptr += ep->m_waitLow;
154 newEp = allocEndpointForDevice(dev, alignFlag);
157 dbg_printf(
"ran out of endpoints\n");
165 hcMaxPktSize = endpDesc->wMaxPacketSizeLB + (endpDesc->wMaxPacketSizeHB << 8);
166 switch ( endpDesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK )
168 case USB_ENDPOINT_XFER_CONTROL:
170 endpType = TYPE_CONTROL;
173 case USB_ENDPOINT_XFER_ISOC:
175 endpType = TYPE_ISOCHRON;
179 cleanUpFunc(dev, newEp);
180 dbg_printf(
"Open ISOC EP: no TDs left\n");
186 case USB_ENDPOINT_XFER_BULK:
188 endpType = TYPE_BULK;
189 if ( (endpDesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN )
193 case USB_ENDPOINT_XFER_INT:
195 endpType = setupBandwidthInterruptScheduling(newEp, endpDesc, dev->m_isLowSpeedDevice);
197 "opening INT endpoint (%d - %p), interval %d, list %d\n", newEp->m_id, newEp, endpDesc->bInterval, endpType);
198 if ( (endpDesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN )
205 if ( !alignFlag && hcMaxPktSize > 62 )
209 flags = (hcMaxPktSize << 16) & 0x7FF0000;
210 if ( endpType == TYPE_ISOCHRON )
212 if ( dev->m_isLowSpeedDevice )
214 flags |= ((endpDesc->bEndpointAddress & 0x1F) << 7)
215 | ((endpDesc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN ? HCED_DIR_IN : HCED_DIR_OUT);
216 newEp->m_hcEd->m_hcArea.asu32 = flags | (dev->m_functionAddress & 0x7F);
220 newEp->m_hcEd->m_hcArea.asu32 = 0x80000;
221 newEp->m_hcEd->m_hcArea.asu32 |= dev->m_isLowSpeedDevice ? HCED_SPEED : 0;
222 endpType = TYPE_CONTROL;
224 newEp->m_endpointType = endpType;
231 dbg_printf(
"Ran out of TDs\n");
232 cleanUpFunc(dev, newEp);
235 newEp->m_hcEd->m_tdHead = td;
236 newEp->m_hcEd->m_tdTail = td;
237 addToHcEndpointList(endpType & 0xFF, newEp->m_hcEd);
248 if ( ep->m_endpointType == TYPE_ISOCHRON )
250 for ( i = 0; i < usbConfig.m_maxIsoTransfDesc; i += 1 )
252 if ( memPool->m_hcIsoTdToIoReqLUT[i] && memPool->m_hcIsoTdToIoReqLUT[i]->m_correspEndpoint == ep )
254 freeIoRequest(memPool->m_hcIsoTdToIoReqLUT[i]);
255 memPool->m_hcIsoTdToIoReqLUT[i] = NULL;
256 freeIsoTd(&memPool->m_hcIsoTdBuf[i]);
260 hcEd->m_tdTail = NULL;
264 for ( i = 0; i < usbConfig.m_maxTransfDesc; i += 1 )
266 if ( memPool->m_hcTdToIoReqLUT[i] && memPool->m_hcTdToIoReqLUT[i]->m_correspEndpoint == ep )
268 freeIoRequest(memPool->m_hcTdToIoReqLUT[i]);
269 memPool->m_hcTdToIoReqLUT[i] = NULL;
270 freeTd(&memPool->m_hcTdBuf[i]);
273 freeTd(hcEd->m_tdTail);
274 hcEd->m_tdTail = NULL;
276 hcEd->m_tdHead = NULL;
277 for ( req = ep->m_ioReqListStart; req; req = ep->m_ioReqListStart )
280 req->m_next->m_prev = req->m_prev;
282 ep->m_ioReqListEnd = req->m_prev;
284 req->m_prev->m_next = req->m_next;
286 ep->m_ioReqListStart = req->m_next;
289 removeEndpointFromQueue(ep, ep->m_correspDevice->m_isLowSpeedDevice);
290 if ( ep->m_inTdQueue != NOTIN_QUEUE )
292 if ( ep->m_busyNext )
293 ep->m_busyNext->m_busyPrev = ep->m_busyPrev;
295 memPool->m_tdQueueEnd = ep->m_busyPrev;
296 if ( ep->m_busyPrev )
297 ep->m_busyPrev->m_busyNext = ep->m_busyNext;
299 memPool->m_tdQueueStart = ep->m_busyNext;
300 ep->m_inTdQueue = NOTIN_QUEUE;
302 ep->m_prev = memPool->m_freeEpListEnd;
303 if ( memPool->m_freeEpListEnd )
304 memPool->m_freeEpListEnd->m_next = ep;
306 memPool->m_freeEpListStart = ep;
308 memPool->m_freeEpListEnd = ep;
313 ep->m_hcEd->m_hcArea.stru.m_hcArea |= HCED_SKIP;
314 removeHcEdFromList(ep->m_endpointType, ep->m_hcEd);
316 ep->m_next->m_prev = ep->m_prev;
318 dev->m_endpointListEnd = ep->m_prev;
320 ep->m_prev->m_next = ep->m_next;
322 dev->m_endpointListStart = ep->m_next;
323 ep->m_correspDevice = NULL;
324 addTimerCallback(&ep->m_timer, (TimerCallback)killEndpoint, ep, 200);