Annotation of XNU/iokit/Drivers/usb/drvAppleOHCI/AppleOHCI_UIM.cpp, revision 1.1

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 <libkern/OSByteOrder.h>
        !            31: 
        !            32: #include "AppleOHCI.h"
        !            33: #include <IOKit/IOMemoryDescriptor.h>
        !            34: #include <IOKit/IOMemoryCursor.h>
        !            35: 
        !            36: #define DEBUGGING_LEVEL 0      // 1 = low; 2 = high; 3 = extreme
        !            37: #define DEBUGLOG IOLog
        !            38: #define nil (0)
        !            39: #define kP_UIMName ""
        !            40: 
        !            41: #if DEBUGGING_LEVEL > 0
        !            42: #define USBExpertStatusLevel(a, b, c, d) DEBUGLOG("UIM: %s 0x%lx\n", c, (UInt32)(d))
        !            43: #else
        !            44: #define USBExpertStatusLevel(a, b, c, d)
        !            45: #endif
        !            46: 
        !            47: #define super IOUSBController
        !            48: 
        !            49: void print_td(OHCIGeneralTransferDescriptorPtr x);
        !            50: void print_itd(OHCIIsochTransferDescriptorPtr x);
        !            51: void print_ed(OHCIEndpointDescriptorPtr x);
        !            52: void print_isoc_ed(OHCIEndpointDescriptorPtr x);
        !            53: void print_list(OHCIEndpointDescriptorPtr pListHead,
        !            54:                 OHCIEndpointDescriptorPtr pListTail);
        !            55: void print_control_list(OHCIUIMDataPtr pData);
        !            56: void print_bulk_list(OHCIUIMDataPtr pData);
        !            57: void print_int_list(OHCIUIMDataPtr pData);
        !            58: 
        !            59: static inline OHCIEDFormat
        !            60: GetEDType(OHCIEndpointDescriptorPtr pED)
        !            61: {
        !            62:     return ((OSReadLittleInt32(&pED->flags, 0) & kOHCIEDControl_F) >>
        !            63:                                                kOHCIEDControl_FPhase);
        !            64: }
        !            65: 
        !            66: IOReturn AppleOHCI::UIMCreateGeneralTransfer(
        !            67:             OHCIEndpointDescriptorPtr          queue,
        !            68:             IOUSBCompletion                    completion,
        !            69:             IOMemoryDescriptor *               CBP,
        !            70:             UInt32                             bufferSize,
        !            71:             UInt32                             flags,
        !            72:             UInt32                             type,
        !            73:             UInt32                             kickBits)
        !            74: {
        !            75:     OHCIRegistersPtr                   pOHCIRegisters;
        !            76:     OHCIGeneralTransferDescriptorPtr   pOHCIGeneralTransferDescriptor,
        !            77:                                         newOHCIGeneralTransferDescriptor;
        !            78:     IOReturn                           status = kIOReturnSuccess;
        !            79:     IOPhysicalSegment                          physicalAddresses[2];   
        !            80:     IOByteCount                                transferOffset;
        !            81:     UInt32                             pageSize;
        !            82:     UInt32                             pageCount;
        !            83: 
        !            84:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !            85:     pageSize = pOHCIUIMData->pageSize;
        !            86: 
        !            87:     // Handy for debugging transfer lists
        !            88:     flags |= (kOHCIGTDConditionNotAccessed << kOHCIGTDControl_CCPhase);
        !            89: 
        !            90: // FERG DEBUG
        !            91: // uncomment the next line to force the data to be put in TD list, but not be processed
        !            92: // this is handy for using USBProber/Macsbug to look at TD's to see if they're OK.
        !            93: // pEDQueue->dWord0 |= OSSwapInt32 (kOHCIEDControl_K);
        !            94: // FERG DEBUG
        !            95:     if (bufferSize != 0)
        !            96:     {
        !            97:         transferOffset = 0;
        !            98:         while (transferOffset < bufferSize)
        !            99:         {
        !           100:             if(pOHCIUIMData->errataBits & kErrataOnlySinglePageTransfers)
        !           101:                 pageCount = _genCursor->getPhysicalSegments(CBP, transferOffset, physicalAddresses, 1);
        !           102:             else
        !           103:                 pageCount = _genCursor->getPhysicalSegments(CBP, transferOffset, physicalAddresses, 2);
        !           104:             newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !           105:             if (newOHCIGeneralTransferDescriptor == nil) {
        !           106:                 status = kIOReturnNoMemory;
        !           107:                 break;
        !           108:             }
        !           109:             pOHCIGeneralTransferDescriptor = 
        !           110:                (OHCIGeneralTransferDescriptorPtr)queue->pLogicalTailP;
        !           111:             OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->flags, 0, flags);
        !           112:             OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->currentBufferPtr, 0,
        !           113:                 physicalAddresses[0].location);
        !           114:             OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->nextTD, 0,
        !           115:                newOHCIGeneralTransferDescriptor->pPhysical);
        !           116:             if (pageCount == 2) {
        !           117:                 OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->bufferEnd, 0,
        !           118:                         physicalAddresses[1].location + physicalAddresses[1].length - 1);
        !           119:                 transferOffset += physicalAddresses[1].length;
        !           120:             }
        !           121:             else
        !           122:                 OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->bufferEnd, 0,
        !           123:                         physicalAddresses[0].location + physicalAddresses[0].length - 1);
        !           124: 
        !           125:             pOHCIGeneralTransferDescriptor->pLogicalNext =
        !           126:                 newOHCIGeneralTransferDescriptor;
        !           127:             pOHCIGeneralTransferDescriptor->pEndpoint = queue;
        !           128:             pOHCIGeneralTransferDescriptor->pType = type;
        !           129:             transferOffset += physicalAddresses[0].length;
        !           130: 
        !           131:             // only supply a callback when the entire buffer has been
        !           132:             // transfered.
        !           133:             if (transferOffset >= bufferSize)
        !           134:                 pOHCIGeneralTransferDescriptor->completion = completion;
        !           135:             else
        !           136:                 pOHCIGeneralTransferDescriptor->completion.action = nil;
        !           137:             queue->tdQueueTailPtr = pOHCIGeneralTransferDescriptor->nextTD;
        !           138:             queue->pLogicalTailP =
        !           139:                 newOHCIGeneralTransferDescriptor;
        !           140:             OSWriteLittleInt32(&pOHCIRegisters->hcCommandStatus, 0, kickBits);
        !           141:         }
        !           142:     }
        !           143:     else
        !           144:     {
        !           145:         newOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !           146:         // last in queue is dummy descriptor. Fill it in then add new dummy
        !           147:         pOHCIGeneralTransferDescriptor =
        !           148:             (OHCIGeneralTransferDescriptorPtr) queue->pLogicalTailP;
        !           149: 
        !           150:         OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->flags, 0, flags);
        !           151:         OSWriteLittleInt32(&pOHCIGeneralTransferDescriptor->nextTD, 0,
        !           152:             newOHCIGeneralTransferDescriptor->pPhysical);
        !           153:         pOHCIGeneralTransferDescriptor->pLogicalNext =
        !           154:             newOHCIGeneralTransferDescriptor;
        !           155:         pOHCIGeneralTransferDescriptor->pEndpoint = queue;
        !           156:         pOHCIGeneralTransferDescriptor->pType = type;
        !           157: 
        !           158:         /* for zero sized buffers */
        !           159:         pOHCIGeneralTransferDescriptor->currentBufferPtr = 0;
        !           160:         pOHCIGeneralTransferDescriptor->bufferEnd = 0;
        !           161:         pOHCIGeneralTransferDescriptor->completion = completion;
        !           162: 
        !           163:         /* Make new descriptor the tail */
        !           164:         queue->tdQueueTailPtr = pOHCIGeneralTransferDescriptor->nextTD;
        !           165:         queue->pLogicalTailP = newOHCIGeneralTransferDescriptor;
        !           166:         OSWriteLittleInt32(&pOHCIRegisters->hcCommandStatus, 0, kickBits);
        !           167:     }
        !           168: 
        !           169: #if (DEBUGGING_LEVEL > 0)
        !           170:     print_td(pOHCIGeneralTransferDescriptor);
        !           171:     DEBUGLOG("UIMCreateGeneralTransfer: returning status=%d\n", status);
        !           172: #endif
        !           173:     return (status);
        !           174: }
        !           175: 
        !           176: IOReturn AppleOHCI::UIMCreateControlEndpoint(
        !           177:             UInt8                              functionAddress,
        !           178:             UInt8                              endpointNumber,
        !           179:             UInt16                             maxPacketSize,
        !           180:             UInt8                              speed)
        !           181: {
        !           182:     OHCIEndpointDescriptorPtr  pOHCIEndpointDescriptor, pED;
        !           183: 
        !           184: #if (DEBUGGING_LEVEL > 0)
        !           185:     DEBUGLOG("%s: UIMCreateControlEndpoint(%d, %d, %d, %d)\n", getName(),
        !           186:           functionAddress, endpointNumber, maxPacketSize, speed);
        !           187: #endif
        !           188:     if (pOHCIUIMData->rootHubFuncAddress == functionAddress)
        !           189:     {
        !           190:         return(kIOReturnSuccess);
        !           191:     }
        !           192:         
        !           193:     pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlHead;
        !           194:     if ((speed == kOHCIEDSpeedFull) && pOHCIUIMData->OptiOn)
        !           195:         pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !           196: 
        !           197:     pOHCIEndpointDescriptor = AddEmptyEndPoint(functionAddress,
        !           198:                                                endpointNumber,
        !           199:                                                maxPacketSize,
        !           200:                                                speed,
        !           201:                                                kOHCIEDDirectionTD,
        !           202:                                                pED,
        !           203:                                                kOHCIEDFormatGeneralTD);
        !           204: 
        !           205: #if (DEBUGGING_LEVEL > 2)
        !           206:     if ((speed == kOHCIEDSpeedFull) && pOHCIUIMData->OptiOn)
        !           207:         print_bulk_list(pOHCIUIMData);
        !           208:     else
        !           209:        print_control_list(pOHCIUIMData);
        !           210: #endif
        !           211: 
        !           212:     if (pOHCIEndpointDescriptor == nil)
        !           213:         return(-1);  //FIXME
        !           214:     return (kIOReturnSuccess);
        !           215: }
        !           216: 
        !           217: 
        !           218: IOReturn AppleOHCI::UIMCreateControlTransfer(
        !           219:             short                              functionAddress,
        !           220:             short                              endpointNumber,
        !           221:             IOUSBCompletion                    completion,
        !           222:             IOMemoryDescriptor *               CBP,
        !           223:             bool                               bufferRounding,
        !           224:             UInt32                             bufferSize,
        !           225:             short                              direction)
        !           226: {
        !           227:     UInt32                             myBufferRounding;
        !           228:     UInt32                             myDirection;
        !           229:     UInt32                             myToggle;
        !           230:     OHCIEndpointDescriptorPtr          pEDQueue, pEDDummy;
        !           231:     IOReturn                           status;
        !           232: 
        !           233: #if (DEBUGGING_LEVEL > 0)
        !           234:     DEBUGLOG("\tCrntlTx: adr=%d:%d cbp=%lx:%lx br=%s cback=[%lx:%lx] dir=%d)\n",
        !           235:           functionAddress, endpointNumber, CBP, bufferSize,
        !           236:           bufferRounding?"YES":"NO",
        !           237:              (UInt32)completion.target, (UInt32)completion.parameter, direction);
        !           238: #endif
        !           239: 
        !           240:     if (direction == kUSBOut)
        !           241:     {
        !           242:         direction = kOHCIGTDPIDOut;
        !           243:     }
        !           244:     else if (direction == kUSBIn)
        !           245:     {
        !           246:         direction = kOHCIGTDPIDIn;
        !           247:     }
        !           248:     else
        !           249:     {
        !           250:         direction = kOHCIGTDPIDSetup;
        !           251:     }
        !           252:     // search for endpoint descriptor
        !           253: 
        !           254:     pEDQueue = FindControlEndpoint(functionAddress, endpointNumber, &pEDDummy);
        !           255:     if (pEDQueue == nil)
        !           256:     {
        !           257:         IOLog("UIMCreateControlTransfer: Could not find endpoint\n");
        !           258:         return(kIOUSBEndpointNotFound);
        !           259:     }
        !           260:     myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !           261:     myDirection = (UInt32) direction << kOHCIDirectionOffset;
        !           262:     myToggle = kOHCIBit25;     /* Take data toggle from TD */
        !           263:     if (direction != 0)
        !           264:     {
        !           265:         /* Setup uses Data 0, data status use Data1 */
        !           266:         myToggle |= kOHCIBit24;        /* use Data1 */
        !           267:     }
        !           268: 
        !           269:     status = UIMCreateGeneralTransfer(pEDQueue, completion, CBP, bufferSize,
        !           270:        myBufferRounding | myDirection | myToggle, kOHCIControlSetupType, kOHCIHcCommandStatus_CLF);
        !           271: 
        !           272: #if (DEBUGGING_LEVEL > 2)
        !           273:     print_ed(pEDQueue);
        !           274: #endif
        !           275: 
        !           276:     return (status);
        !           277: }
        !           278: 
        !           279: IOReturn AppleOHCI::UIMCreateControlTransfer(
        !           280:             short                              functionAddress,
        !           281:             short                              endpointNumber,
        !           282:             IOUSBCompletion                    completion,
        !           283:             void *                             CBP,
        !           284:             bool                               bufferRounding,
        !           285:             UInt32                             bufferSize,
        !           286:             short                              direction)
        !           287: {
        !           288:     IOMemoryDescriptor *               desc = NULL;
        !           289:     IODirection                                descDirection;
        !           290:     IOReturn                           status;
        !           291: 
        !           292: #if (DEBUGGING_LEVEL > 0)
        !           293:     DEBUGLOG("\tCrntlTx: adr=%d:%d cbp=%lx:%lx br=%s cback=[%lx:%lx] dir=%d)\n",
        !           294:           functionAddress, endpointNumber, CBP, bufferSize,
        !           295:           bufferRounding?"YES":"NO",
        !           296:              (UInt32)completion.target, (UInt32)completion.parameter, direction);
        !           297: #endif
        !           298:     if (direction == kUSBOut)
        !           299:     {
        !           300:         descDirection = kIODirectionOut;
        !           301:     }
        !           302:     else if (direction == kUSBIn)
        !           303:     {
        !           304:         descDirection = kIODirectionIn;
        !           305:     }
        !           306:     else
        !           307:     {
        !           308:         descDirection = kIODirectionOut;
        !           309:     }
        !           310:     if(bufferSize != 0) {
        !           311:         desc = IOMemoryDescriptor::withAddress(CBP, bufferSize, descDirection);
        !           312:         if(!desc)
        !           313:             return(kIOReturnNoMemory);
        !           314:     }
        !           315: 
        !           316:     status = UIMCreateControlTransfer(functionAddress, endpointNumber, completion,
        !           317:                desc, bufferRounding, bufferSize, direction);
        !           318: 
        !           319:     if(desc)
        !           320:         desc->release();
        !           321: 
        !           322:     return (status);
        !           323: }
        !           324: 
        !           325: /* Not implemented - use UIMAbortEndpoint
        !           326: IOReturn AppleOHCI::UIMAbortControlEndpoint(void);
        !           327: IOReturn AppleOHCI::UIMEnableControlEndpoint(void);
        !           328: IOReturn AppleOHCI::UIMDisableControlEndpoint(void);
        !           329: */
        !           330: 
        !           331: // Bulk
        !           332: IOReturn AppleOHCI::UIMCreateBulkEndpoint(
        !           333:             UInt8                              functionAddress,
        !           334:             UInt8                              endpointNumber,
        !           335:             UInt8                              direction,
        !           336:             UInt8                              speed,
        !           337:             UInt8                              maxPacketSize)
        !           338: {
        !           339:     OHCIEndpointDescriptorPtr  pOHCIEndpointDescriptor, pED;
        !           340: 
        !           341: 
        !           342: #if (DEBUGGING_LEVEL > 0)
        !           343:     DEBUGLOG("%s: UIMCreateBulkEndpoint(adr=%d:%d, max=%d, dir=%d)\n", getName(),
        !           344:           functionAddress, endpointNumber, maxPacketSize, direction);
        !           345: #endif
        !           346:     
        !           347:     if (direction == kUSBOut)
        !           348:             direction = kOHCIEDDirectionOut;
        !           349:     else if (direction == kUSBIn)
        !           350:             direction = kOHCIEDDirectionIn;
        !           351:     else
        !           352:             direction = kOHCIEDDirectionTD;
        !           353: 
        !           354:     pED = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !           355:     pOHCIEndpointDescriptor = AddEmptyEndPoint (functionAddress,
        !           356:                                                 endpointNumber,
        !           357:                                                 maxPacketSize,
        !           358:                                                 speed,
        !           359:                                                 direction,
        !           360:                                                 pED,
        !           361:                                                 kOHCIEDFormatGeneralTD);
        !           362:     if (pOHCIEndpointDescriptor == nil)
        !           363:         return(kIOReturnNoMemory);
        !           364: 
        !           365:     return (kIOReturnSuccess);
        !           366: }
        !           367: 
        !           368: IOReturn AppleOHCI::UIMCreateBulkTransfer(
        !           369:             short                              functionAddress,
        !           370:             short                              endpointNumber,
        !           371:             IOUSBCompletion                    completion,
        !           372:             IOMemoryDescriptor *               CBP,
        !           373:             bool                               bufferRounding,
        !           374:             UInt32                             bufferSize,
        !           375:             short                              direction)
        !           376: {
        !           377:     IOReturn                           status = kIOReturnSuccess;
        !           378:     UInt32                             myBufferRounding;
        !           379:     UInt32                             TDDirection;
        !           380:     UInt32                             kickBits;
        !           381:     OHCIEndpointDescriptorPtr          pEDQueue, pEDDummy;
        !           382: 
        !           383: #if (DEBUGGING_LEVEL > 0)
        !           384:     DEBUGLOG("\tBulkTx: adr=%d:%d cbp=%lx:%x br=%s cback=[%lx:%lx:%lx] dir=%d)\n",
        !           385:        functionAddress, endpointNumber, CBP, bufferSize, bufferRounding?"YES":"NO", 
        !           386:        (UInt32)completion.action, (UInt32)completion.target, (UInt32)completion.parameter, direction);
        !           387: #endif
        !           388: 
        !           389:     if (direction == kUSBOut)
        !           390:         direction = kOHCIEDDirectionOut;
        !           391:     else if (direction == kUSBIn)
        !           392:         direction = kOHCIEDDirectionIn;
        !           393:     else
        !           394:         direction = kOHCIEDDirectionTD;
        !           395: 
        !           396:     // search for endpoint descriptor
        !           397:     pEDQueue =
        !           398:         FindBulkEndpoint(functionAddress, endpointNumber, direction, &pEDDummy);
        !           399: 
        !           400:     if (!pEDQueue)
        !           401:     {
        !           402:         IOLog("UIMCreateBulkTransfer: Could not find endpoint\n");
        !           403:         return (kIOUSBEndpointNotFound);
        !           404:     }
        !           405: 
        !           406:     myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !           407:     TDDirection = (UInt32) direction << kOHCIDirectionOffset;
        !           408:     kickBits = kOHCIHcCommandStatus_BLF;
        !           409:     if ( pOHCIUIMData->OptiOn)
        !           410:         kickBits |= kOHCIHcCommandStatus_CLF;          
        !           411: 
        !           412:     status = UIMCreateGeneralTransfer(pEDQueue, completion, CBP, bufferSize,
        !           413:        myBufferRounding | TDDirection, kOHCIBulkTransferOutType, kickBits);
        !           414: 
        !           415: #if (DEBUGGING_LEVEL > 2)
        !           416:     print_bulk_list(pOHCIUIMData);
        !           417: #endif
        !           418: 
        !           419:     return (status);
        !           420: }
        !           421: 
        !           422: // Interrupt
        !           423: IOReturn AppleOHCI::UIMCreateInterruptEndpoint(
        !           424:             short                              functionAddress,
        !           425:             short                              endpointNumber,
        !           426:             UInt8                              direction,
        !           427:             short                              speed,
        !           428:             UInt16                             maxPacketSize,
        !           429:             short                              pollingRate)
        !           430: {
        !           431:     OHCIEndpointDescriptorPtr          pOHCIEndpointDescriptor;
        !           432:     OHCIEndpointDescriptorPtr          pED;
        !           433:     OHCIIntHeadPtr                     pInterruptHead;
        !           434:     int                                        offset;
        !           435: 
        !           436: 
        !           437: #if (DEBUGGING_LEVEL > 0)
        !           438:     DEBUGLOG("%s: UIMCreateInterruptEndpoint (%d, %d, %s, %d, %d)\n", getName(),
        !           439:           functionAddress, endpointNumber, speed ? "lo" : "hi", maxPacketSize,
        !           440:           pollingRate);
        !           441: #endif
        !           442: 
        !           443:     if (pOHCIUIMData->rootHubFuncAddress == functionAddress)
        !           444:     {
        !           445:         return(kIOReturnSuccess);
        !           446:     }
        !           447: 
        !           448:     if (direction == kUSBOut)
        !           449:             direction = kOHCIEDDirectionOut;
        !           450:     else if (direction == kUSBIn)
        !           451:             direction = kOHCIEDDirectionIn;
        !           452:     else
        !           453:             direction = kOHCIEDDirectionTD;
        !           454: 
        !           455:     pInterruptHead = pOHCIUIMData->pInterruptHead;
        !           456: 
        !           457: ///ZZZZz  opti bug fix!!!!
        !           458:     if (pOHCIUIMData->OptiOn)
        !           459:             if (speed == kOHCIEDSpeedFull)
        !           460:                     if (pollingRate >= 8)
        !           461:                             pollingRate = 7;
        !           462: 
        !           463:     // Do we have room?? if so return with offset equal to location
        !           464:     if (DetermineInterruptOffset(pollingRate, maxPacketSize, &offset) == false)
        !           465:         return(kIOReturnNoBandwidth);
        !           466: 
        !           467: #if (DEBUGGING_LEVEL > 0)
        !           468:     DEBUGLOG("%s: UIMCreateInterruptEndpoint: offset = %d\n", getName(), offset);
        !           469: #endif
        !           470:     pED = (OHCIEndpointDescriptorPtr) pInterruptHead[offset].pHead;
        !           471:     pOHCIEndpointDescriptor = AddEmptyEndPoint (functionAddress, endpointNumber, 
        !           472:                        maxPacketSize, speed, direction, pED, kOHCIEDFormatGeneralTD);
        !           473:     if (nil == pOHCIEndpointDescriptor)
        !           474:             return(-1);
        !           475: 
        !           476:     pInterruptHead[offset].nodeBandwidth += maxPacketSize;
        !           477: 
        !           478: #if (DEBUGGING_LEVEL > 2)
        !           479:     print_int_list(pOHCIUIMData);
        !           480: #endif
        !           481: 
        !           482:     return (kIOReturnSuccess);
        !           483: }
        !           484: 
        !           485: IOReturn AppleOHCI::UIMCreateInterruptTransfer(
        !           486:             short                              functionAddress,
        !           487:             short                              endpointNumber,
        !           488:             IOUSBCompletion                    completion,
        !           489:             IOMemoryDescriptor *               CBP,
        !           490:             bool                               bufferRounding,
        !           491:             UInt32                             bufferSize,
        !           492:             short                              direction)
        !           493: {
        !           494:     IOReturn                           status = kIOReturnSuccess;
        !           495:     UInt32                             myBufferRounding;
        !           496:     UInt32                             myDirection;
        !           497:     UInt32                             myToggle;
        !           498:     OHCIEndpointDescriptorPtr          pEDQueue, temp;
        !           499:     OHCIIntHeadPtr                     pInterruptHead;
        !           500: 
        !           501: #if (DEBUGGING_LEVEL > 0)
        !           502:     DEBUGLOG("\tIntTx: adr=%d:%d cbp=%lx:%lx br=%s cback=[%lx:%lx:%lx])\n", functionAddress, endpointNumber, CBP, bufferSize, bufferRounding?"YES":"NO", (UInt32)completion.action, (UInt32)completion.target, (UInt32)completion.parameter);
        !           503: #endif
        !           504: 
        !           505:     if (pOHCIUIMData->rootHubFuncAddress == functionAddress)
        !           506:     {
        !           507:         SimulateRootHubInt(endpointNumber, CBP, bufferSize, completion);
        !           508:         return(kIOReturnSuccess);
        !           509:     }
        !           510: 
        !           511:     if (direction == kUSBOut)
        !           512:         direction = kOHCIEDDirectionOut;
        !           513:     else if (direction == kUSBIn)
        !           514:         direction = kOHCIEDDirectionIn;
        !           515:     else
        !           516:         direction = kOHCIEDDirectionTD;
        !           517: 
        !           518:     pInterruptHead = pOHCIUIMData->pInterruptHead;
        !           519: 
        !           520:     pEDQueue = FindInterruptEndpoint(functionAddress, endpointNumber,
        !           521:                                                        direction,&temp);
        !           522:     if (pEDQueue != nil)
        !           523:     {
        !           524:         myBufferRounding = (UInt32) bufferRounding << kOHCIBufferRoundingOffset;
        !           525:         myToggle = 0;  /* Take data toggle from Endpoint Descriptor */
        !           526: 
        !           527:         myDirection = (UInt32) direction << kOHCIDirectionOffset;
        !           528: 
        !           529:         status = UIMCreateGeneralTransfer(pEDQueue, completion, CBP, bufferSize,
        !           530:             myBufferRounding | myDirection | myToggle, kOHCIInterruptInType, 0);
        !           531:     }
        !           532:     else
        !           533:     {
        !           534:         IOLog("UIMCreateInterruptTransfer: Could not find endpoint\n");
        !           535:         status = kIOUSBEndpointNotFound;
        !           536:     }
        !           537: #if (DEBUGGING_LEVEL > 0)
        !           538:     DEBUGLOG("UIMCreateInterruptTransfer: returning status=%d\n", status);
        !           539: #endif
        !           540:     return (status);
        !           541: }
        !           542: 
        !           543: // Isoch
        !           544: IOReturn AppleOHCI::UIMCreateIsochEndpoint(
        !           545:             short                              functionAddress,
        !           546:             short                              endpointNumber,
        !           547:             UInt32                             maxPacketSize,
        !           548:             UInt8                              direction)
        !           549: {
        !           550:     OHCIEndpointDescriptorPtr  pOHCIEndpointDescriptor, pED;
        !           551:     UInt32                     curMaxPacketSize;
        !           552:     UInt32                     xtraRequest;
        !           553:     UInt32                     edFlags;
        !           554: 
        !           555: 
        !           556:     if (direction == kUSBOut)
        !           557:         direction = kOHCIEDDirectionOut;
        !           558:     else if (direction == kUSBIn)
        !           559:         direction = kOHCIEDDirectionIn;
        !           560:     else
        !           561:         direction = kOHCIEDDirectionTD;
        !           562: 
        !           563:     pED = FindIsochronousEndpoint(functionAddress, endpointNumber, direction, nil);
        !           564:     if (pED) {
        !           565:         // this is the case where we have already created this endpoint, and now we are adjusting the maxPacketSize
        !           566:         USBExpertStatusLevel (3, 123456789,
        !           567:                kP_UIMName"IsochEDCreate- Endpoint already exists, checking maxPacketSize ",
        !           568:                maxPacketSize);
        !           569:         edFlags = OSReadLittleInt32(&pED->flags, 0);
        !           570:         curMaxPacketSize = ( edFlags & kOHCIEDControl_MPS) >> kOHCIEDControl_MPSPhase;
        !           571:         if (maxPacketSize == curMaxPacketSize) {
        !           572:             USBExpertStatusLevel (3, 123456789,
        !           573:                kP_UIMName"IsochEDCreate- maxPacketSize the same, no change ",
        !           574:                maxPacketSize);
        !           575:             return kIOReturnSuccess;
        !           576:         }
        !           577:         if (maxPacketSize > curMaxPacketSize) {
        !           578:             // client is trying to get more bandwidth
        !           579:             xtraRequest = maxPacketSize - curMaxPacketSize;
        !           580:             if (xtraRequest > pOHCIUIMData->isochBandwidthAvail)
        !           581:             {
        !           582:                 USBExpertStatusLevel (3, 123456789,
        !           583:                        kP_UIMName"IsochEDCreate- out of bandwidth, request (extra) = ",
        !           584:                        xtraRequest);
        !           585:                 USBExpertStatusLevel (3, 123456789,
        !           586:                        kP_UIMName"IsochEDCreate- available = ",
        !           587:                        pOHCIUIMData->isochBandwidthAvail);
        !           588:                 return kIOReturnNoBandwidth;
        !           589:             }
        !           590:             pOHCIUIMData->isochBandwidthAvail -= xtraRequest;
        !           591:         }
        !           592:         else {
        !           593:             // client is trying to return some bandwidth
        !           594:             xtraRequest = curMaxPacketSize - maxPacketSize;
        !           595:             USBExpertStatusLevel (3, 123456789,
        !           596:                kP_UIMName"IsochEDCreate- returning some bandwidth: ",
        !           597:                xtraRequest);
        !           598:             pOHCIUIMData->isochBandwidthAvail += xtraRequest;
        !           599:             USBExpertStatusLevel (3, 123456789,
        !           600:                kP_UIMName"IsochEDCreate- new available = ",
        !           601:                pOHCIUIMData->isochBandwidthAvail);
        !           602:         }
        !           603:         // update the maxPacketSize field in the endpoint
        !           604:         edFlags &= ~kOHCIEDControl_MPS;                                        // strip out old MPS
        !           605:         edFlags |= (maxPacketSize << kOHCIEDControl_MPSPhase);
        !           606:         OSWriteLittleInt32(&pED->flags, 0, edFlags);
        !           607:         return kIOReturnSuccess;
        !           608:     }
        !           609: 
        !           610:     if (maxPacketSize > pOHCIUIMData->isochBandwidthAvail) {
        !           611:         USBExpertStatusLevel (3, 123456789,
        !           612:                kP_UIMName"Isoch Endpoint create- no bandwidth, request = ",
        !           613:                maxPacketSize);
        !           614:         USBExpertStatusLevel (3, 123456789,
        !           615:                kP_UIMName"Isoch Endpoint create- available = ",
        !           616:                pOHCIUIMData->isochBandwidthAvail);
        !           617:         return kIOReturnNoBandwidth;
        !           618:     }
        !           619: 
        !           620:     pOHCIUIMData->isochBandwidthAvail -= maxPacketSize;
        !           621:     pED = pOHCIUIMData->pIsochHead;
        !           622:     pOHCIEndpointDescriptor = AddEmptyEndPoint(functionAddress, endpointNumber,
        !           623:        maxPacketSize, kOHCIEDSpeedFull, direction, pED, kOHCIEDFormatIsochronousTD);
        !           624:     if (pOHCIEndpointDescriptor == nil) {
        !           625:         pOHCIUIMData->isochBandwidthAvail += maxPacketSize;
        !           626:         return(kIOReturnNoMemory);
        !           627:     }
        !           628: 
        !           629:     USBExpertStatusLevel (5, 123456789,
        !           630:        kP_UIMName"Isoch Endpoint create- success, bandwidth used = ",
        !           631:        maxPacketSize);
        !           632:     USBExpertStatusLevel (5, 123456789, 
        !           633:        kP_UIMName"Isoch Endpoint create- success, new available = ",
        !           634:        pOHCIUIMData->isochBandwidthAvail);
        !           635:     return (kIOReturnSuccess);
        !           636: }
        !           637: 
        !           638: 
        !           639: IOReturn AppleOHCI::UIMCreateIsochTransfer(
        !           640:             short                              functionAddress,
        !           641:             short                              endpointNumber,
        !           642:             IOUSBIsocCompletion                        completion,
        !           643:             UInt8                              direction,
        !           644:             UInt64                             frameNumberStart,
        !           645:             IOMemoryDescriptor *               pBuffer,
        !           646:             UInt32                             frameCount,
        !           647:             IOUSBIsocFrame                     *pFrames)
        !           648: {
        !           649:     IOReturn                           status = kIOReturnSuccess;
        !           650:     OHCIIsochTransferDescriptorPtr     pTailITD = nil;
        !           651:     OHCIIsochTransferDescriptorPtr     pNewITD = nil;
        !           652:     OHCIIsochTransferDescriptorPtr     pTempITD = nil;
        !           653:     UInt32                             i;
        !           654:     UInt32                             curFrameInRequest = 0;
        !           655:     UInt32                             bufferSize = 0;
        !           656:     UInt32                             pageOffset = 0;
        !           657:     UInt32                             curFrameLength;
        !           658:     UInt32                             lastPhysical = 0;
        !           659:     OHCIEndpointDescriptorPtr          pED;
        !           660:     UInt32                             curFrameInTD = 0;
        !           661:     UInt16                             frameNumber = (UInt16) frameNumberStart;
        !           662:     UInt64                             curFrameNumber = GetFrameNumber();
        !           663:     UInt64                             frameDiff;
        !           664:     UInt64                             maxOffset = (UInt64)(0x00007FF0);
        !           665:     UInt32                             diff32;
        !           666: 
        !           667:     UInt32                             itdFlags = 0;
        !           668:     UInt32                             numSegs = 0;
        !           669:     UInt32                             physPageStart = 0;
        !           670:     UInt32                             physPageEnd = 0;
        !           671:     UInt32                             pageSelectMask = 0;
        !           672:     bool                               needNewITD;
        !           673:     IOPhysicalSegment                  segs[2];
        !           674:     UInt32                             tdType;
        !           675:     IOByteCount                                transferOffset;
        !           676: #if 0
        !           677:     AbsoluteTime                                               startTime = UpTime();
        !           678:     Duration                                                   elapsedTime;
        !           679: #endif
        !           680: 
        !           681:     if ((frameCount == 0) || (frameCount > 1000))
        !           682:     {
        !           683:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- bad frameCount", kIOReturnBadArgument);
        !           684:         return kIOReturnBadArgument;
        !           685:     }
        !           686: 
        !           687:     if (direction == kUSBOut) {
        !           688:         direction = kOHCIEDDirectionOut;
        !           689:         tdType = kOHCIIsochronousOutType;
        !           690:     }
        !           691:     else if (direction == kUSBIn) {
        !           692:         direction = kOHCIEDDirectionIn;
        !           693:         tdType = kOHCIIsochronousInType;
        !           694:     }
        !           695:     else
        !           696:         return kIOReturnInternalError;
        !           697: 
        !           698:     pED = FindIsochronousEndpoint(functionAddress, endpointNumber, direction, nil);
        !           699: 
        !           700:     if (!pED)
        !           701:     {
        !           702:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- endpoint not found, err:", kIOUSBEndpointNotFound);
        !           703:         return kIOUSBEndpointNotFound;
        !           704:     }
        !           705: 
        !           706:     if (frameNumberStart <= curFrameNumber)
        !           707:     {
        !           708:         if (frameNumberStart < (curFrameNumber - maxOffset))
        !           709:         {
        !           710:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- frameNumberStart:", (UInt32)frameNumberStart);
        !           711:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- curFrameNumber:", (UInt32)curFrameNumber);
        !           712:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- request frame WAY too old, err:", kIOReturnIsoTooOld);
        !           713:             return kIOReturnIsoTooOld;
        !           714:         }
        !           715:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- WARNING! curframe later than requested, expect some notSent errors!", 0);
        !           716:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- frameNumberStart:", (UInt32)frameNumberStart);
        !           717:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- curFrameNumber:", (UInt32)curFrameNumber);
        !           718:         USBExpertStatusLevel (3, 123456789, kP_UIMName"USBIsocFrame Ptr:", (UInt32)pFrames);
        !           719:         USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- First ITD:", (UInt32)pED->pLogicalTailP);
        !           720:     } else {                                   // frameNumberStart > curFrameNumber
        !           721:         if (frameNumberStart > (curFrameNumber + maxOffset))
        !           722:         {
        !           723:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- frameNumberStart:", (UInt32)frameNumberStart);
        !           724:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- curFrameNumber:", (UInt32)curFrameNumber);
        !           725:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch transfer- request frame too far ahead, err:", kIOReturnIsoTooNew);
        !           726:             return kIOReturnIsoTooNew;
        !           727:         }
        !           728:         frameDiff = frameNumberStart - curFrameNumber;
        !           729:         diff32 = (UInt32)frameDiff;
        !           730:         if (diff32 < 2)
        !           731:         {
        !           732:             USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer- WARNING! - frameNumberStart less than 2 ms.", diff32);
        !           733:             USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer- frameNumberStart:", (UInt32)frameNumberStart);
        !           734:             USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer- curFrameNumber:", (UInt32)curFrameNumber);
        !           735:         }
        !           736:     }
        !           737: 
        !           738:     //
        !           739:     //  Get the total size of buffer
        !           740:     //
        !           741:     for ( i = 0; i< frameCount; i++)
        !           742:     {
        !           743:         if (pFrames[i].frReqCount > kUSBMaxIsocFrameReqCount)
        !           744:         {
        !           745:             USBExpertStatusLevel (3, 123456789, kP_UIMName"Isoch frame too big:", pFrames[i].frReqCount);
        !           746:             return kIOReturnBadArgument;
        !           747:         }
        !           748:         bufferSize += pFrames[i].frReqCount;
        !           749:     }
        !           750: 
        !           751:     if (direction == kOHCIEDDirectionIn)
        !           752:         USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer in, buffer:",
        !           753:                               (UInt32)pBuffer);
        !           754:     else
        !           755:         USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer out, buffer:",
        !           756:                               (UInt32)pBuffer);
        !           757:     USBExpertStatusLevel (5, 123456789, kP_UIMName"Isoch transfer total length:",
        !           758:                           bufferSize);
        !           759: 
        !           760:     //
        !           761:     // go ahead and make sure we can grab at least ONE TD, before we lock the buffer   
        !           762:     //
        !           763:     pNewITD = OHCIUIMAllocateITD();
        !           764:     if (pNewITD == nil)
        !           765:     {
        !           766:         return kIOReturnNoMemory;
        !           767:     }
        !           768: 
        !           769:     if (!bufferSize) {
        !           770:        // Set up suitable dummy info
        !           771:         numSegs = 1;
        !           772:         segs[0].location = segs[0].length = 0;
        !           773:        pageOffset = 0;
        !           774:     }
        !           775:     pTailITD = (OHCIIsochTransferDescriptorPtr)pED->pLogicalTailP;     // start with the unused TD on the tail of the list
        !           776:     OSWriteLittleInt32(&pTailITD->nextTD, 0, pNewITD->pPhysical);      // link in the new ITD
        !           777:     pTailITD->pLogicalNext = pNewITD;
        !           778: 
        !           779:     needNewITD = false;
        !           780:     transferOffset = 0;
        !           781:     while (curFrameInRequest < frameCount) {
        !           782:         // Get physical segments for next frame
        !           783:         if(!needNewITD && bufferSize) {
        !           784:             numSegs = _isoCursor->getPhysicalSegments(pBuffer, transferOffset,
        !           785:                                        segs, 2, pFrames[curFrameInRequest].frReqCount);
        !           786: #if 0
        !           787:             IOLog("F%ld (%d): numSegs = %ld, (0x%lx, 0x%lx), (0x%lx, 0x%lx)\n", curFrameInRequest,
        !           788:                 pFrames[curFrameInRequest].frReqCount, numSegs, segs[0].location, segs[0].length,
        !           789:                     segs[1].location, segs[1].length);
        !           790: #endif
        !           791:             pageOffset = segs[0].location & kOHCIPageOffsetMask;
        !           792:             transferOffset += segs[0].length;
        !           793:             if(numSegs == 2)
        !           794:                 transferOffset += segs[1].length;
        !           795:         }
        !           796: 
        !           797:         if (curFrameInTD == 0) {
        !           798:             // set up counters which get reinitialized with each TD
        !           799:             physPageStart = segs[0].location & kOHCIPageMask;  // for calculating real 13 bit offsets
        !           800:             pageSelectMask = 0;                                        // First frame always starts on first page
        !           801:             needNewITD = false;
        !           802: 
        !           803:             // set up the header of the TD - itdFlags will be stored into flags later
        !           804:             itdFlags = (UInt16)(curFrameInRequest + frameNumber);
        !           805:             pTailITD->pIsocFrame = pFrames;            // so we can get back to our info later
        !           806:             pTailITD->frameNum = curFrameInRequest;    // our own index into the above array
        !           807:             pTailITD->pType = tdType;                  // So interrupt handler knows TD type.
        !           808:             OSWriteLittleInt32(&pTailITD->bufferPage0, 0,  physPageStart);
        !           809:         }
        !           810:         else if ((segs[0].location & kOHCIPageMask) != physPageStart) {
        !           811:             // pageSelectMask is set if we've already used our one allowed page cross.
        !           812:             if(pageSelectMask && 
        !           813:                (((segs[0].location & kOHCIPageMask) != physPageEnd) || numSegs == 2)) {
        !           814:                 // Need new ITD for this
        !           815:                 needNewITD = true;
        !           816:                 continue;
        !           817:             }
        !           818:             pageSelectMask = kOHCIPageSize;    // ie. set bit 13
        !           819:             physPageEnd = segs[numSegs-1].location & kOHCIPageMask;
        !           820:         }
        !           821:         curFrameLength = pFrames[curFrameInRequest].frReqCount;
        !           822:         if ((curFrameInTD > 7) || needNewITD) {
        !           823:             // we need to start a new TD
        !           824:             needNewITD = true; // To simplify test at top of loop.
        !           825:             itdFlags |= (curFrameInTD-1) << kOHCIITDControl_FCPhase;
        !           826:             OSWriteLittleInt32(&pTailITD->bufferEnd, 0, lastPhysical);
        !           827:             curFrameInTD = 0;
        !           828:             pNewITD = OHCIUIMAllocateITD();
        !           829:             if (pNewITD == nil) {
        !           830:                 status = kIOReturnNoMemory;
        !           831:                break;
        !           832:             }
        !           833:             // Handy for debugging transfer lists
        !           834:             itdFlags |= (kOHCIGTDConditionNotAccessed << kOHCIGTDControl_CCPhase);
        !           835:             OSWriteLittleInt32(&pTailITD->flags, 0, itdFlags);
        !           836:             pTailITD->completion.action = NULL;
        !           837:             pTailITD = pTailITD->pLogicalNext;         // this is the "old" pNewTD
        !           838:             OSWriteLittleInt32(&pTailITD->nextTD, 0, pNewITD->pPhysical);      // link to the "new" pNewTD
        !           839:             pTailITD->pLogicalNext = pNewITD;
        !           840:             continue;          // start over
        !           841:         }
        !           842:         //
        !           843:         // at this point we know we have a frame which will fit into the current TD
        !           844:         //
        !           845:         // calculate the buffer offset for the beginning of this frame
        !           846:         OSWriteLittleInt16(&pTailITD->offset[curFrameInTD], 0,
        !           847:             pageOffset |               // offset
        !           848:             pageSelectMask |           // offset from BP0 or BufferEnd
        !           849:             (kOHCIITDOffsetConditionNotAccessed << kOHCIITDOffset_CCPhase));   // mark as unused
        !           850: 
        !           851:         // adjust counters and calculate the physical offset of the end of the frame for the next time around the loop
        !           852:         curFrameInRequest++;
        !           853:         curFrameInTD++;
        !           854:         lastPhysical = segs[numSegs-1].location + segs[numSegs-1].length - 1;
        !           855:     }                  
        !           856: 
        !           857:     if (status != kIOReturnSuccess)
        !           858:     {
        !           859:         // unlink the TDs, unlock the buffer, and return the status
        !           860:         pNewITD = pTailITD->pLogicalNext;      // point to the "old" pNewTD, which will also get deallocated
        !           861:         pTempITD = (OHCIIsochTransferDescriptorPtr)pED->pLogicalTailP;
        !           862:         pTailITD = pTempITD->pLogicalNext;     // don't deallocate the real tail!
        !           863:         pTempITD->pLogicalNext = nil;          // just to make sure
        !           864:         pTempITD->nextTD = nil;                        // just to make sure
        !           865:         while (pTailITD != pNewITD)
        !           866:         {
        !           867:             pTempITD = pTailITD;
        !           868:             pTailITD = pTailITD->pLogicalNext;
        !           869:             OHCIUIMDeallocateITD(pTempITD);
        !           870:         }
        !           871:     }
        !           872:     else
        !           873:     {
        !           874:         // we have good status, so let's kick off the machine
        !           875:         // we need to tidy up the last TD, which is not yet complete
        !           876:         itdFlags |= (curFrameInTD-1) << kOHCIITDControl_FCPhase;
        !           877:         OSWriteLittleInt32(&pTailITD->flags, 0, itdFlags);
        !           878:         OSWriteLittleInt32(&pTailITD->bufferEnd, 0, lastPhysical);
        !           879:         pTailITD->completion = completion;
        !           880:         //print_itd(pTailITD);
        !           881:         // Make new descriptor the tail
        !           882:         pED->pLogicalTailP = pNewITD;
        !           883:         OSWriteLittleInt32(&pED->tdQueueTailPtr, 0, pNewITD->pPhysical);
        !           884:     }
        !           885: 
        !           886: #if 0
        !           887:     elapsedTime = AbsoluteDeltaToDuration(UpTime(), startTime);
        !           888:     if ((elapsedTime > 0) || (elapsedTime < -700))     // measured in milliseconds or more than 700 microseconds to queue everything
        !           889:     {
        !           890:         USBExpertStatusLevel (4, 123456789, kP_UIMName"Isoch WARNING! > 1 ms (or getting close): ", elapsedTime);
        !           891:         USBExpertStatusLevel (4, 123456789, kP_UIMName"Isoch transfer frame count: ", frameCount);
        !           892:         USBExpertStatusLevel (4, 123456789, kP_UIMName"Isoch transfer buffer size: ", bufferSize);
        !           893:     }
        !           894: #endif
        !           895:     //print_isoc_ed(pED);
        !           896: 
        !           897:     return status;
        !           898: 
        !           899: }
        !           900: 
        !           901: IOReturn AppleOHCI::UIMAbortEndpoint(
        !           902:             short                              functionAddress,
        !           903:             short                              endpointNumber,
        !           904:             short                              direction)
        !           905: {
        !           906:     OHCIRegistersPtr           pOHCIRegisters;
        !           907:     OHCIEndpointDescriptorPtr  pED;
        !           908:     OHCIEndpointDescriptorPtr  pEDQueueBack;
        !           909:     UInt32                     something, controlMask;
        !           910: 
        !           911:     if (functionAddress == 0)
        !           912:     {
        !           913:         IOLog("UIMAbortEndpoint: Error: operation on root hub\n");
        !           914:         return(kIOReturnSuccess);
        !           915:     }
        !           916: 
        !           917:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           918: 
        !           919:     if (direction == kUSBOut)
        !           920:         direction = kOHCIEDDirectionOut;
        !           921:     else if (direction == kUSBIn)
        !           922:         direction = kOHCIEDDirectionIn;
        !           923:     else
        !           924:         direction = kOHCIEDDirectionTD;
        !           925:     
        !           926:     //search for endpoint descriptor
        !           927:     pED = FindEndpoint (functionAddress,
        !           928:                         endpointNumber,
        !           929:                         direction,
        !           930:                         &pEDQueueBack,
        !           931:                         &controlMask);
        !           932:     if (!pED)
        !           933:     {
        !           934:         IOLog("UIMAbortEndpoint: Error: Could not find endpoint\n");
        !           935:         return (kIOUSBEndpointNotFound);
        !           936:     }
        !           937: 
        !           938:     pED->flags |= OSSwapInt32(kOHCIEDControl_K);       // mark the ED as skipped
        !           939: 
        !           940:     // poll for interrupt  zzzzz turn into real interrupt
        !           941:     pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_SF);
        !           942:     IOSleep(1);
        !           943:     something = OSSwapInt32(pOHCIRegisters->hcInterruptStatus)
        !           944:                                                & kOHCIInterruptSOFMask;
        !           945: 
        !           946:     if (!something)
        !           947:     {
        !           948:         /* This should have been set, just in case wait another ms */
        !           949:         IOSleep(1);
        !           950:     }
        !           951: 
        !           952:     RemoveTDs(pED);
        !           953: 
        !           954:     pED->flags &= ~OSSwapInt32(kOHCIEDControl_K);      // activate ED again
        !           955: 
        !           956: 
        !           957:     return (kIOReturnSuccess);
        !           958: }
        !           959: 
        !           960: IOReturn AppleOHCI::UIMDeleteEndpoint(
        !           961:             short                              functionAddress,
        !           962:             short                              endpointNumber,
        !           963:             short                              direction)
        !           964: {
        !           965:     OHCIRegistersPtr           pOHCIRegisters;
        !           966:     OHCIEndpointDescriptorPtr  pED;
        !           967:     OHCIEndpointDescriptorPtr  pEDQueueBack;
        !           968:     UInt32                     hcControl;
        !           969:     UInt32                     something, controlMask;
        !           970:     // UInt32                  edDirection;
        !           971: 
        !           972: 
        !           973: #if 0
        !           974:     if (functionAddress == 0)
        !           975:     {
        !           976:         IOLog("UIMDeleteEndpoint: Error: operation on root hub\n");
        !           977:         return(kIOReturnSuccess);
        !           978:     }
        !           979: #endif
        !           980: 
        !           981:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           982: 
        !           983:     if (direction == kUSBOut)
        !           984:         direction = kOHCIEDDirectionOut;
        !           985:     else if (direction == kUSBIn)
        !           986:         direction = kOHCIEDDirectionIn;
        !           987:     else
        !           988:         direction = kOHCIEDDirectionTD;
        !           989: 
        !           990:     //search for endpoint descriptor
        !           991:     pED = FindEndpoint (functionAddress,
        !           992:                         endpointNumber,
        !           993:                         direction,
        !           994:                         &pEDQueueBack,
        !           995:                         &controlMask);
        !           996:     if (!pED)
        !           997:     {
        !           998:         DEBUGLOG("UIMDeleteEndpoint: Error: Could not find endpoint\n");
        !           999:         return (kIOUSBEndpointNotFound);
        !          1000:     }
        !          1001:     
        !          1002:     // Remove Endpoint
        !          1003:     //mark sKipped
        !          1004:     pED->flags |= OSSwapInt32(kOHCIEDControl_K);
        !          1005:     // edDirection = OSSwapInt32(pED->dWord0) & kOHCIEndpointDirectionMask;
        !          1006:     // remove pointer wraps
        !          1007:     pEDQueueBack->nextED = pED->nextED;
        !          1008:     pEDQueueBack->pLogicalNext = pED->pLogicalNext;
        !          1009: 
        !          1010:     // clear some bit in hcControl
        !          1011:     hcControl = OSSwapInt32(pOHCIRegisters->hcControl);        
        !          1012:     hcControl &= ~controlMask;
        !          1013:     hcControl &= OHCIBitRange(0, 10);
        !          1014: 
        !          1015:     pOHCIRegisters->hcControl = OSSwapInt32(hcControl);
        !          1016: 
        !          1017:     // poll for interrupt  zzzzz turn into real interrupt
        !          1018:     pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_SF);
        !          1019:     IOSleep(1);
        !          1020:     something = OSSwapInt32(pOHCIRegisters->hcInterruptStatus)
        !          1021:                                                & kOHCIInterruptSOFMask;
        !          1022:     if (!something)
        !          1023:     {
        !          1024:         /* This should have been set, just in case wait another ms */
        !          1025:         IOSleep(1);
        !          1026:     }
        !          1027:     // restart hcControl
        !          1028:     hcControl |= controlMask;
        !          1029:     pOHCIRegisters->hcControl = OSSwapInt32(hcControl);
        !          1030: 
        !          1031: #if (DEBUGGING_LEVEL > 0)
        !          1032:     DEBUGLOG("UIMDeleteEndpoint: pED=%lx hcControl=%lx SOF int?=%s\n",
        !          1033:           (UInt32)pED, hcControl, something?"yes":"no");
        !          1034: #endif
        !          1035:     if (GetEDType(pED) == kOHCIEDFormatIsochronousTD)
        !          1036:     {
        !          1037:         UInt32 maxPacketSize = (OSReadLittleInt32(&pED->flags, 0) & kOHCIEDControl_MPS) >>
        !          1038:                                                                             kOHCIEDControl_MPSPhase;
        !          1039:         pOHCIUIMData->isochBandwidthAvail += maxPacketSize;
        !          1040:         USBExpertStatusLevel (5, 123456789,
        !          1041:             kP_UIMName"Isoch Endpoint delete- bandwidth returned = ", maxPacketSize);
        !          1042:         USBExpertStatusLevel (5, 123456789,
        !          1043:             kP_UIMName"Isoch Endpoint delete- new available = ", pOHCIUIMData->isochBandwidthAvail);
        !          1044:     }
        !          1045:     RemoveAllTDs(pED);
        !          1046: 
        !          1047:     pED->nextED = nil;
        !          1048: 
        !          1049:     //deallocate ED
        !          1050:     OHCIUIMDeallocateED(pED);
        !          1051: #if (DEBUGGING_LEVEL > 2)
        !          1052:         print_bulk_list(pOHCIUIMData);
        !          1053:         print_control_list(pOHCIUIMData);
        !          1054: #endif
        !          1055:     return (kIOReturnSuccess);
        !          1056: }
        !          1057: 
        !          1058: void AppleOHCI::ReturnTransactions(
        !          1059:             OHCIGeneralTransferDescriptor      *transaction,
        !          1060:             UInt32                             tail)
        !          1061: {
        !          1062:     UInt32                          physicalAddress;
        !          1063:     OHCIGeneralTransferDescriptor   *nextTransaction;
        !          1064: 
        !          1065:     while(transaction->pPhysical != tail)
        !          1066:     {
        !          1067:         if (transaction->completion.action != nil) {
        !          1068:             IOUSBCompletion completion;
        !          1069:             // zero out callback first then call it
        !          1070:             completion = transaction->completion;
        !          1071:             transaction->completion.action = nil;
        !          1072:             complete(completion, kIOUSBPipeStalled, 0);
        !          1073:         }
        !          1074:         /* walk the physically-addressed list */
        !          1075:         physicalAddress =
        !          1076:                OSSwapInt32(transaction->nextTD) & kOHCIHeadPMask;
        !          1077:         nextTransaction = (OHCIGeneralTransferDescriptorPtr)
        !          1078:                             OHCIUIMGetLogicalAddress (physicalAddress);
        !          1079:         OHCIUIMDeallocateTD(transaction);
        !          1080:         transaction = nextTransaction;
        !          1081:         if(transaction == nil)
        !          1082:         {
        !          1083:             IOLog("returnTransactions: Return queue broken");
        !          1084:             break;
        !          1085:         }
        !          1086:     }
        !          1087: }
        !          1088: 
        !          1089: IOReturn AppleOHCI::UIMClearEndpointStall(
        !          1090:             short                              functionAddress,
        !          1091:             short                              endpointNumber,
        !          1092:             short                              direction)
        !          1093: {
        !          1094:     OHCIRegistersPtr                   pOHCIRegisters;
        !          1095:     OHCIEndpointDescriptorPtr          pEDQueueBack, pED;
        !          1096:     OHCIGeneralTransferDescriptor      *transaction;
        !          1097:     UInt32                             tail, controlMask;
        !          1098: 
        !          1099: 
        !          1100: #if DEBUGGING_LEVEL > 0
        !          1101:     DEBUGLOG("%s: clearing endpoint %d:%d stall\n", getName(), functionAddress, endpointNumber);
        !          1102: #endif
        !          1103:     
        !          1104:     if (pOHCIUIMData->rootHubFuncAddress == functionAddress)
        !          1105:     {
        !          1106:         IOLog("UIMDeleteEndpoint: Error: operation on root hub\n");
        !          1107:         return(kIOReturnSuccess);
        !          1108:     }
        !          1109: 
        !          1110:     if (direction == kUSBOut)
        !          1111:         direction = kOHCIEDDirectionOut;
        !          1112:     else if (direction == kUSBIn)
        !          1113:         direction = kOHCIEDDirectionIn;
        !          1114:     else
        !          1115:         direction = kOHCIEDDirectionTD;
        !          1116: 
        !          1117:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1118: 
        !          1119:     transaction = nil;
        !          1120:     tail = nil;
        !          1121:     //search for endpoint descriptor
        !          1122:     pED = FindEndpoint (functionAddress,
        !          1123:                         endpointNumber,
        !          1124:                         direction,
        !          1125:                         &pEDQueueBack,
        !          1126:                         &controlMask);
        !          1127:     if (!pED)
        !          1128:     {
        !          1129:         IOLog("UIMDeleteEndpoint: Error: Could not find endpoint\n");
        !          1130:         return (kIOUSBEndpointNotFound);
        !          1131:     }
        !          1132: 
        !          1133:     if (pED != nil)
        !          1134:     {
        !          1135:         tail = OSSwapInt32(pED->tdQueueTailPtr);
        !          1136:         transaction = (OHCIGeneralTransferDescriptor *)
        !          1137:             OHCIUIMGetLogicalAddress(OSSwapInt32(pED->tdQueueHeadPtr) & kOHCIHeadPMask);
        !          1138:         /* unlink all transactions at once (this also clears the halted bit) */
        !          1139:         pED->tdQueueHeadPtr = pED->tdQueueTailPtr;
        !          1140:         pED->pLogicalHeadP = pED->pLogicalTailP;
        !          1141:     }  
        !          1142: 
        !          1143:     if (transaction != nil)
        !          1144:     {
        !          1145:         ReturnTransactions(transaction, tail);
        !          1146:     }
        !          1147:     return (kIOReturnSuccess);
        !          1148: }
        !          1149: 
        !          1150: OHCIEndpointDescriptorPtr AppleOHCI::AddEmptyEndPoint(
        !          1151:         UInt8                                          functionAddress,
        !          1152:         UInt8                                          endpointNumber,
        !          1153:         UInt16                                         maxPacketSize,
        !          1154:         UInt8                                          speed,
        !          1155:         UInt8                                          direction,
        !          1156:         OHCIEndpointDescriptorPtr                      pED,
        !          1157:         OHCIEDFormat                                   format)
        !          1158: {
        !          1159:     UInt32                             myFunctionAddress,
        !          1160:                                        myEndpointNumber,
        !          1161:                                        myEndpointDirection,
        !          1162:                                        myMaxPacketSize,
        !          1163:                                        mySpeed,
        !          1164:                                        myFormat;
        !          1165:     OHCIEndpointDescriptorPtr          pOHCIEndpointDescriptor;
        !          1166:     OHCIGeneralTransferDescriptorPtr   pOHCIGeneralTransferDescriptor;
        !          1167:     OHCIIsochTransferDescriptorPtr     pITD;
        !          1168: 
        !          1169:     
        !          1170:     pOHCIEndpointDescriptor = (OHCIEndpointDescriptorPtr) OHCIUIMAllocateED();
        !          1171:     myFunctionAddress = ((UInt32) functionAddress) << kOHCIEDControl_FAPhase;
        !          1172:     myEndpointNumber = ((UInt32) endpointNumber) << kOHCIEDControl_ENPhase;
        !          1173:     myEndpointDirection = ((UInt32) direction) << kOHCIEDControl_DPhase;
        !          1174:     mySpeed = ((UInt32) speed) << kOHCIEDControl_SPhase;
        !          1175:     myMaxPacketSize = ((UInt32) maxPacketSize) << kOHCIEDControl_MPSPhase;
        !          1176:     myFormat = ((UInt32) format) << kOHCIEDControl_FPhase;
        !          1177:     pOHCIEndpointDescriptor->flags =
        !          1178:         OSSwapInt32(myFunctionAddress
        !          1179:                      | myEndpointNumber
        !          1180:                      | myEndpointDirection
        !          1181:                      | myMaxPacketSize
        !          1182:                      | mySpeed
        !          1183:                      | myFormat);
        !          1184: 
        !          1185:     if (format == kOHCIEDFormatGeneralTD)
        !          1186:     {
        !          1187:         pOHCIGeneralTransferDescriptor = OHCIUIMAllocateTD();
        !          1188: 
        !          1189:         /* These were previously nil */
        !          1190:         pOHCIEndpointDescriptor->tdQueueTailPtr =
        !          1191:             OSSwapInt32( pOHCIGeneralTransferDescriptor->pPhysical);
        !          1192:         pOHCIEndpointDescriptor->tdQueueHeadPtr =
        !          1193:             OSSwapInt32( pOHCIGeneralTransferDescriptor->pPhysical);
        !          1194:         pOHCIEndpointDescriptor->pLogicalTailP =
        !          1195:             pOHCIGeneralTransferDescriptor;
        !          1196:         pOHCIEndpointDescriptor->pLogicalHeadP =
        !          1197:             pOHCIGeneralTransferDescriptor;
        !          1198:     }
        !          1199:     else
        !          1200:     {
        !          1201:         pITD = OHCIUIMAllocateITD();
        !          1202: 
        !          1203:         /* These were previously nil */
        !          1204:         pOHCIEndpointDescriptor->tdQueueTailPtr =
        !          1205:             OSSwapInt32( pITD->pPhysical);
        !          1206:         pOHCIEndpointDescriptor->tdQueueHeadPtr =
        !          1207:             OSSwapInt32( pITD->pPhysical);
        !          1208:         pOHCIEndpointDescriptor->pLogicalTailP = pITD;
        !          1209:         pOHCIEndpointDescriptor->pLogicalHeadP = pITD;         
        !          1210: 
        !          1211:     }
        !          1212: 
        !          1213:     pOHCIEndpointDescriptor->nextED = pED->nextED;
        !          1214:     pOHCIEndpointDescriptor->pLogicalNext = pED->pLogicalNext;
        !          1215:     pED->pLogicalNext = pOHCIEndpointDescriptor;
        !          1216:     pED->nextED = OSSwapInt32(pOHCIEndpointDescriptor->pPhysical);
        !          1217: 
        !          1218:     return (pOHCIEndpointDescriptor);
        !          1219: }
        !          1220: 
        !          1221: OHCIEndpointDescriptorPtr AppleOHCI::FindControlEndpoint (
        !          1222:        short                                           functionNumber, 
        !          1223:        short                                           endpointNumber, 
        !          1224:        OHCIEndpointDescriptorPtr                       *pEDBack)
        !          1225: {
        !          1226:     UInt32                     unique;
        !          1227:     OHCIEndpointDescriptorPtr  pEDQueue;
        !          1228:     OHCIEndpointDescriptorPtr  pEDQueueBack;
        !          1229: 
        !          1230:        
        !          1231:     // search for endpoint descriptor
        !          1232:     unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset)
        !          1233:                                        | ((UInt32) functionNumber));
        !          1234:     pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pControlHead;
        !          1235:     pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pLogicalNext;
        !          1236: 
        !          1237:     while ((UInt32) pEDQueue != pOHCIUIMData->pControlTail)
        !          1238:     {
        !          1239:         if ((OSSwapInt32(pEDQueue->flags) & kUniqueNumNoDirMask) == unique)
        !          1240:         {
        !          1241:             *pEDBack = pEDQueueBack;
        !          1242:             return (pEDQueue);
        !          1243:         }
        !          1244:         else
        !          1245:         {
        !          1246:             pEDQueueBack = pEDQueue;
        !          1247:             pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pLogicalNext;
        !          1248:         }
        !          1249:     }
        !          1250:     if (pOHCIUIMData->OptiOn)
        !          1251:     {
        !          1252:         pEDQueue = FindBulkEndpoint (functionNumber, endpointNumber,
        !          1253:                                      kOHCIEDDirectionTD, &pEDQueueBack);
        !          1254:         *pEDBack = pEDQueueBack;
        !          1255:         return (pEDQueue);
        !          1256:     }
        !          1257:     return (nil);
        !          1258: }
        !          1259: 
        !          1260: 
        !          1261: OHCIEndpointDescriptorPtr AppleOHCI::FindBulkEndpoint (
        !          1262:        short                                           functionNumber, 
        !          1263:        short                                           endpointNumber,
        !          1264:        short                                           direction,
        !          1265:        OHCIEndpointDescriptorPtr                       *pEDBack)
        !          1266: {
        !          1267: 
        !          1268:     UInt32                     unique;
        !          1269:     UInt32                     myEndpointDirection;
        !          1270:     OHCIEndpointDescriptorPtr  pEDQueue;
        !          1271:     OHCIEndpointDescriptorPtr  pEDQueueBack;
        !          1272: 
        !          1273: 
        !          1274:     // search for endpoint descriptor
        !          1275:     myEndpointDirection = ((UInt32) direction) << kOHCIEndpointDirectionOffset;
        !          1276:     unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset)
        !          1277:                        | ((UInt32) functionNumber) | myEndpointDirection);
        !          1278:     pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pBulkHead;
        !          1279:     pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pLogicalNext;
        !          1280: 
        !          1281:     while (((UInt32) pEDQueue) != pOHCIUIMData->pBulkTail )
        !          1282:     {
        !          1283:         if ((OSSwapInt32(pEDQueue->flags) & kUniqueNumMask) == unique)
        !          1284:         {
        !          1285:             *pEDBack = pEDQueueBack;
        !          1286:             return (pEDQueue);
        !          1287:         }
        !          1288:         else
        !          1289:         {
        !          1290:             pEDQueueBack = pEDQueue;
        !          1291:             pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pLogicalNext;
        !          1292:         }
        !          1293:     }
        !          1294:     return (nil);
        !          1295: }
        !          1296: 
        !          1297: 
        !          1298: OHCIEndpointDescriptorPtr AppleOHCI::FindEndpoint (
        !          1299:        short                                           functionNumber, 
        !          1300:        short                                           endpointNumber,
        !          1301:        short                                           direction, 
        !          1302:        OHCIEndpointDescriptorPtr                       *pEDQueueBack, 
        !          1303:        UInt32                                          *controlMask)
        !          1304: {
        !          1305:     OHCIEndpointDescriptorPtr pED, pEDBack;
        !          1306: 
        !          1307:     pED = FindControlEndpoint (functionNumber, endpointNumber, &pEDBack);
        !          1308:     if (pED != nil)
        !          1309:     {
        !          1310:         *pEDQueueBack = pEDBack;
        !          1311:         *controlMask = kOHCIHcControl_CLE;
        !          1312:         return (pED);
        !          1313:     }
        !          1314: 
        !          1315:     pED = FindBulkEndpoint(functionNumber, endpointNumber, direction, &pEDBack);
        !          1316:     if (pED != nil)
        !          1317:     {
        !          1318:         *pEDQueueBack = pEDBack;
        !          1319: 
        !          1320:         *controlMask = kOHCIHcControl_BLE;
        !          1321:         //zzzz Opti Bug
        !          1322:         if(pOHCIUIMData->OptiOn)
        !          1323:             *controlMask = kOHCIHcControl_CLE;
        !          1324:         return (pED);
        !          1325:     }
        !          1326: 
        !          1327:     pED = FindInterruptEndpoint(functionNumber, endpointNumber, direction,
        !          1328:        &pEDBack);
        !          1329:     if (pED != nil)
        !          1330:     {
        !          1331:         *pEDQueueBack = pEDBack;
        !          1332:         *controlMask = 0;
        !          1333:         return (pED);  
        !          1334:     }
        !          1335: 
        !          1336:     pED = FindIsochronousEndpoint(functionNumber, endpointNumber,
        !          1337:                                   direction, &pEDBack);
        !          1338:     *pEDQueueBack = pEDBack;
        !          1339:     *controlMask = 0;
        !          1340:     return (pED);      
        !          1341: }
        !          1342: 
        !          1343: 
        !          1344: OHCIEndpointDescriptorPtr AppleOHCI::FindIsochronousEndpoint(
        !          1345:        short                                           functionNumber,
        !          1346:        short                                           endpointNumber,
        !          1347:        short                                           direction, 
        !          1348:        OHCIEndpointDescriptorPtr                       *pEDBack)
        !          1349: {
        !          1350:     UInt32                     myEndpointDirection;
        !          1351:     UInt32                     unique;
        !          1352:     OHCIEndpointDescriptorPtr  pEDQueue, pEDQueueBack;
        !          1353: 
        !          1354:     // search for endpoint descriptor
        !          1355:     myEndpointDirection = ((UInt32) direction) << kOHCIEndpointDirectionOffset;
        !          1356:     unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEndpointNumberOffset)
        !          1357:                        | ((UInt32) functionNumber) | myEndpointDirection);
        !          1358: 
        !          1359:     pEDQueueBack = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead;
        !          1360:     pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueueBack->pLogicalNext;
        !          1361:     while (((UInt32) pEDQueue) != pOHCIUIMData->pIsochTail )
        !          1362:     {
        !          1363:         if ((OSSwapInt32(pEDQueue->flags) & kUniqueNumMask) == unique)
        !          1364:         {
        !          1365:             if(pEDBack)
        !          1366:                 *pEDBack = pEDQueueBack;
        !          1367:             return (pEDQueue);
        !          1368:         }
        !          1369:         else
        !          1370:         {
        !          1371:             pEDQueueBack = pEDQueue;
        !          1372:             pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pLogicalNext;
        !          1373:         }
        !          1374:     }
        !          1375:     return (nil);
        !          1376: }
        !          1377: 
        !          1378: 
        !          1379: OHCIEndpointDescriptorPtr AppleOHCI::FindInterruptEndpoint(
        !          1380:        short                                   functionNumber,
        !          1381:        short                                   endpointNumber,
        !          1382:         short                                  direction,
        !          1383:        OHCIEndpointDescriptorPtr               *pEDBack)
        !          1384: {
        !          1385:     OHCIRegistersPtr                   pOHCIRegisters;
        !          1386:     UInt32                             myEndpointDirection;
        !          1387:     UInt32                             unique;
        !          1388:     OHCIEndpointDescriptorPtr          pEDQueue;
        !          1389:     OHCIIntHeadPtr                     pInterruptHead;
        !          1390:     int                                        i;
        !          1391:     UInt32                             temp;
        !          1392:     
        !          1393:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1394:     pInterruptHead = pOHCIUIMData->pInterruptHead;
        !          1395: 
        !          1396:     //search for endpoint descriptor
        !          1397:     myEndpointDirection = ((UInt32) direction) << kOHCIEndpointDirectionOffset;
        !          1398:     unique = (UInt32) ((((UInt32) endpointNumber) << kOHCIEDControl_ENPhase)
        !          1399:                        | (((UInt32) functionNumber) << kOHCIEDControl_FAPhase)
        !          1400:                        | myEndpointDirection);
        !          1401: 
        !          1402:     for (i = 0; i < 63; i++)
        !          1403:     {
        !          1404:         pEDQueue = pInterruptHead[i].pHead;
        !          1405:         *pEDBack = pEDQueue;
        !          1406:         // BT do this first, or you find the dummy endpoint
        !          1407:         // all this is hanging off. It matches 0,0
        !          1408:         pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pLogicalNext;
        !          1409:         while (pEDQueue != pInterruptHead[i].pTail)
        !          1410:         {
        !          1411:             temp = (OSSwapInt32(pEDQueue->flags)) & kUniqueNumMask;
        !          1412: 
        !          1413:             if ( temp == unique)
        !          1414:             {
        !          1415:                 return(pEDQueue);
        !          1416:             }
        !          1417:             *pEDBack = pEDQueue;
        !          1418:             pEDQueue = (OHCIEndpointDescriptorPtr) pEDQueue->pLogicalNext;
        !          1419:         }
        !          1420:     }
        !          1421:     return(nil);
        !          1422: }
        !          1423: 
        !          1424: bool AppleOHCI::DetermineInterruptOffset(
        !          1425:     UInt32          pollingRate,
        !          1426:     UInt32          /* reserveBandwidth */,
        !          1427:     int             *offset)
        !          1428: {
        !          1429:     int num;
        !          1430:     OHCIRegistersPtr            pOHCIRegisters;
        !          1431: 
        !          1432:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1433: 
        !          1434:     num = OSSwapInt32(pOHCIRegisters->hcFmNumber)&kOHCIFmNumberMask;
        !          1435:     if (pollingRate <  1)
        !          1436:         //error condition
        !          1437:         return(false);
        !          1438:     else if(pollingRate < 2)
        !          1439:         *offset = 62;
        !          1440:     else if(pollingRate < 4)
        !          1441:         *offset = (num%2) + 60;
        !          1442:     else if(pollingRate < 8)
        !          1443:         *offset = (num%4) + 56;
        !          1444:     else if(pollingRate < 16)
        !          1445:         *offset = (num%8) + 48;
        !          1446:     else if(pollingRate < 32)
        !          1447:         *offset = (num%16) + 32;
        !          1448:     else
        !          1449:         *offset = (num%32) + 0;
        !          1450:     return (true);
        !          1451: }
        !          1452: 
        !          1453: static char *cc_errors[] = {
        !          1454:     "NO ERROR",                        /* 0 */
        !          1455:     "CRC",                     /* 0 */
        !          1456:     "BIT STUFFING",            /* 0 */
        !          1457:     "DATA TOGGLE MISMATCH",    /* 0 */
        !          1458:     "STALL",                   /* 0 */
        !          1459:     "DEVICE NOT RESPONDING",   /* 0 */
        !          1460:     "PID CHECK FAILURE",       /* 0 */
        !          1461:     "UNEXPECTED PID",          /* 0 */
        !          1462:     "DATA OVERRUN",            /* 0 */
        !          1463:     "DATA UNDERRUN",           /* 0 */
        !          1464:     "??",                      /* reserved */
        !          1465:     "??",                      /* reserved */
        !          1466:     "BUFFER OVERRUN",          /* 0 */
        !          1467:     "BUFFER UNDERRUN",         /* 0 */
        !          1468:     "NOT ACCESSED A",          /* not processed yet */
        !          1469:     "NOT ACCESSED B"           /* not processed yet */
        !          1470: };
        !          1471: 
        !          1472: void print_td(OHCIGeneralTransferDescriptorPtr pTD)
        !          1473: {
        !          1474:     UInt32 w0, dir, err;
        !          1475: 
        !          1476:     if (pTD == 0) return;
        !          1477: 
        !          1478:     w0 = OSSwapInt32(pTD->flags);
        !          1479:     dir = (w0 & kOHCIGTDControl_DP) >> kOHCIGTDControl_DPPhase;
        !          1480:     err = (w0 & kOHCIGTDControl_CC) >> kOHCIGTDControl_CCPhase;
        !          1481:     DEBUGLOG("\tTD(0x%08lx->0x%08lx) dir=%s cc=%s errc=%ld t=%ld rd=%s: c=0x%08lx cbp=0x%08lx, next=0x%08lx, bend=0x%08lx\n",
        !          1482:        (UInt32)pTD, pTD->pPhysical,
        !          1483:        dir == 0 ? "SETUP" : (dir==2?"IN":"OUT"),
        !          1484:        cc_errors[err],
        !          1485:        (w0 & kOHCIGTDControl_EC) >> kOHCIGTDControl_ECPhase,
        !          1486:        (w0 & kOHCIGTDControl_T)  >> kOHCIGTDControl_TPhase,
        !          1487:        (w0 & kOHCIGTDControl_R)?"yes":"no",
        !          1488:        OSSwapInt32(pTD->flags),
        !          1489:        OSSwapInt32(pTD->currentBufferPtr),
        !          1490:        OSSwapInt32(pTD->nextTD),
        !          1491:        OSSwapInt32(pTD->bufferEnd));
        !          1492: }
        !          1493: 
        !          1494: void print_itd(OHCIIsochTransferDescriptorPtr pTD)
        !          1495: {
        !          1496:     UInt32 w0, err;
        !          1497:     int i;
        !          1498:     if (pTD == 0) return;
        !          1499: 
        !          1500:     w0 = OSReadLittleInt32(&pTD->flags, 0);
        !          1501:     err = (w0 & kOHCIITDControl_CC) >> kOHCIITDControl_CCPhase;
        !          1502:     DEBUGLOG("\tTD(0x%08lx->0x%08lx) cc=%s fc=%ld sf=0x%lx c=0x%08lx bp0=0x%08lx, next=0x%08lx, bend=0x%08lx\n",
        !          1503:         (UInt32)pTD, pTD->pPhysical,
        !          1504:         cc_errors[err],
        !          1505:         (w0 & kOHCIITDControl_FC) >> kOHCIITDControl_FCPhase,
        !          1506:         (w0 & kOHCIITDControl_SF)  >> kOHCIITDControl_SFPhase,
        !          1507:         w0,
        !          1508:         OSSwapInt32(pTD->bufferPage0),
        !          1509:         OSSwapInt32(pTD->nextTD),
        !          1510:         OSSwapInt32(pTD->bufferEnd));
        !          1511:     for(i=0; i<8; i++) {
        !          1512:        DEBUGLOG("Offset/PSW %d = 0x%x\n", i, OSReadLittleInt16(&pTD->offset[i], 0));
        !          1513:     }
        !          1514:     DEBUGLOG("frames = 0x%lx, FrameNumber %ld\n", (UInt32)pTD->pIsocFrame, pTD->frameNum);
        !          1515: }
        !          1516: 
        !          1517: void print_ed(OHCIEndpointDescriptorPtr pED)
        !          1518: {
        !          1519:     OHCIGeneralTransferDescriptorPtr   pTD;
        !          1520:     UInt32 w0;
        !          1521: 
        !          1522: 
        !          1523:     if (pED == 0) {
        !          1524:        kprintf("Null ED\n");
        !          1525:        return;
        !          1526:     }
        !          1527:     w0 = OSSwapInt32(pED->flags);
        !          1528: 
        !          1529:     if ((w0 & kOHCIEDControl_K) == 0 /*noskip*/)
        !          1530:     {
        !          1531:         DEBUGLOG("ED(0x%08lx->0x%08lx) %ld:%ld d=%ld s=%s sk=%s i=%s max=%ld : c=0x%08lx tail=0x%08lx, head=0x%08lx, next=0x%08lx\n",
        !          1532:               (UInt32)pED, (UInt32)pED->pPhysical,
        !          1533:               (w0 & kOHCIEDControl_FA) >> kOHCIEDControl_FAPhase,
        !          1534:               (w0 & kOHCIEDControl_EN) >> kOHCIEDControl_ENPhase,
        !          1535:               (w0 & kOHCIEDControl_D)  >> kOHCIEDControl_DPhase,
        !          1536:               w0 & kOHCIEDControl_S?"low":"hi",
        !          1537:               w0 & kOHCIEDControl_K?"yes":"no",
        !          1538:               w0 & kOHCIEDControl_F?"yes":"no",
        !          1539:               (w0 & kOHCIEDControl_MPS) >> kOHCIEDControl_MPSPhase,
        !          1540:               OSSwapInt32(pED->flags),
        !          1541:               OSSwapInt32(pED->tdQueueTailPtr),
        !          1542:               OSSwapInt32(pED->tdQueueHeadPtr),
        !          1543:               OSSwapInt32(pED->nextED));
        !          1544: 
        !          1545:         //pTD = (OHCIGeneralTransferDescriptorPtr) pED->pVirtualHeadP;
        !          1546:        pTD = (OHCIGeneralTransferDescriptorPtr)
        !          1547:            (OSSwapInt32(pED->tdQueueHeadPtr) & kOHCINextEndpointDescriptor_nextED);
        !          1548:         
        !          1549:         while (pTD != 0)
        !          1550:         {
        !          1551:             DEBUGLOG("\t");
        !          1552:             print_td(pTD);
        !          1553:             pTD = pTD->pLogicalNext;
        !          1554:         }
        !          1555:     }
        !          1556: }
        !          1557: 
        !          1558: void print_isoc_ed(OHCIEndpointDescriptorPtr pED)
        !          1559: {
        !          1560:     OHCIIsochTransferDescriptorPtr     pTD;
        !          1561:     UInt32 w0;
        !          1562: 
        !          1563: 
        !          1564:     if (pED == 0) {
        !          1565:         kprintf("Null ED\n");
        !          1566:         return;
        !          1567:     }
        !          1568:     w0 = OSSwapInt32(pED->flags);
        !          1569: 
        !          1570:     if ((w0 & kOHCIEDControl_K) == 0 /*noskip*/)
        !          1571:     {
        !          1572:         DEBUGLOG("ED(0x%08lx->0x%08lx) %ld:%ld d=%ld s=%s sk=%s i=%s max=%ld : c=0x%08lx tail=0x%08lx, head=0x%08lx, next=0x%08lx\n",
        !          1573:               (UInt32)pED, (UInt32)pED->pPhysical,
        !          1574:               (w0 & kOHCIEDControl_FA) >> kOHCIEDControl_FAPhase,
        !          1575:               (w0 & kOHCIEDControl_EN) >> kOHCIEDControl_ENPhase,
        !          1576:               (w0 & kOHCIEDControl_D)  >> kOHCIEDControl_DPhase,
        !          1577:               w0 & kOHCIEDControl_S?"low":"hi",
        !          1578:               w0 & kOHCIEDControl_K?"yes":"no",
        !          1579:               w0 & kOHCIEDControl_F?"yes":"no",
        !          1580:               (w0 & kOHCIEDControl_MPS) >> kOHCIEDControl_MPSPhase,
        !          1581:               OSSwapInt32(pED->flags),
        !          1582:               OSSwapInt32(pED->tdQueueTailPtr),
        !          1583:               OSSwapInt32(pED->tdQueueHeadPtr),
        !          1584:               OSSwapInt32(pED->nextED));
        !          1585: 
        !          1586:         pTD = (OHCIIsochTransferDescriptorPtr) pED->pLogicalHeadP;
        !          1587:         while (pTD != 0)
        !          1588:         {
        !          1589:             DEBUGLOG("\t");
        !          1590:             print_itd(pTD);
        !          1591:             pTD = pTD->pLogicalNext;
        !          1592:         }
        !          1593:     }
        !          1594: }
        !          1595: 
        !          1596: void print_list(OHCIEndpointDescriptorPtr pListHead,
        !          1597:                 OHCIEndpointDescriptorPtr pListTail)
        !          1598: {
        !          1599:     OHCIEndpointDescriptorPtr          pED, pEDTail;
        !          1600: 
        !          1601: 
        !          1602:     pED = (OHCIEndpointDescriptorPtr) pListHead;
        !          1603:     pEDTail = (OHCIEndpointDescriptorPtr) pListTail;
        !          1604: 
        !          1605:     while (pED != pEDTail)
        !          1606:     {
        !          1607:         print_ed(pED);
        !          1608:         pED = (OHCIEndpointDescriptorPtr) pED->pLogicalNext;
        !          1609:     }
        !          1610:     print_ed(pEDTail);
        !          1611: }
        !          1612: 
        !          1613: void print_control_list(OHCIUIMDataPtr pData)
        !          1614: {
        !          1615:     DEBUGLOG("Control List: h/w head = 0x%lx\n",
        !          1616:        OSReadLittleInt32(&pData->pOHCIRegisters->hcControlHeadED, 0));
        !          1617:     print_list((OHCIEndpointDescriptorPtr) pData->pControlHead,
        !          1618:                (OHCIEndpointDescriptorPtr) pData->pControlTail);
        !          1619: }
        !          1620: 
        !          1621: void print_bulk_list(OHCIUIMDataPtr pData)
        !          1622: {
        !          1623:     DEBUGLOG("Bulk List:\n");
        !          1624:     DEBUGLOG("Bulk List: h/w head = 0x%lx\n",
        !          1625:        OSReadLittleInt32(&pData->pOHCIRegisters->hcBulkHeadED, 0));
        !          1626:     print_list((OHCIEndpointDescriptorPtr) pData->pBulkHead,
        !          1627:                (OHCIEndpointDescriptorPtr) pData->pBulkTail);
        !          1628: }
        !          1629: 
        !          1630: void print_int_list(OHCIUIMDataPtr pData)
        !          1631: {
        !          1632:     OHCIIntHeadPtr     pInterruptHead = pData->pInterruptHead;
        !          1633:     int                        i;
        !          1634:     UInt32             w0;
        !          1635:     OHCIEndpointDescriptorPtr pED;
        !          1636: 
        !          1637: 
        !          1638:     DEBUGLOG("Interrupt List:\n");
        !          1639:     for (i = 0; i < 63; i++)
        !          1640:     {
        !          1641:         pED = (OHCIEndpointDescriptorPtr) pInterruptHead[i].pHead->pLogicalNext;
        !          1642:         w0 = OSSwapInt32(pED->flags);
        !          1643: 
        !          1644:         if ((w0 & kOHCIEDControl_K) == 0 /*noskip*/)
        !          1645:         {
        !          1646:             DEBUGLOG("%d:", i);
        !          1647:             print_ed(pED);
        !          1648:         }
        !          1649:     }
        !          1650: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.