Annotation of XNU/iokit/Drivers/usb/drvAppleOHCI/AppleOHCI_UIM.cpp, revision 1.1.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.