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

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * HISTORY
        !            26:  *
        !            27:  */
        !            28: 
        !            29: #include <libkern/OSByteOrder.h>
        !            30: #include <IOKit/IOMemoryCursor.h>
        !            31: 
        !            32: #include "AppleOHCI.h"
        !            33: #include <IOKit/usb/USB.h>
        !            34: 
        !            35: #define DEBUGGING_LEVEL 0      // 1 = low; 2 = high; 3 = extreme
        !            36: #define DEBUGLOG kprintf
        !            37: #define nil (0)
        !            38: 
        !            39: #define super IOUSBController
        !            40: #define self this
        !            41: 
        !            42: #define NUM_BUFFER_PAGES       9   // 54
        !            43: #define NUM_TDS                        255 // 1500
        !            44: #define NUM_EDS                        256 // 1500
        !            45: #define NUM_ITDS               192 // 1300
        !            46: 
        !            47: // TDs  per page == 85
        !            48: // EDs  per page == 128
        !            49: // ITDs per page == 64
        !            50: 
        !            51: static int GetEDType(OHCIEndpointDescriptorPtr pED);
        !            52: static void ProcessCompletedITD (OHCIIsochTransferDescriptorPtr pITD, IOReturn status);
        !            53: extern void print_td(OHCIGeneralTransferDescriptorPtr pTD);
        !            54: extern void print_itd(OHCIIsochTransferDescriptorPtr x);
        !            55: 
        !            56: static IOReturn TranslateStatusToUSBError(UInt32 status);
        !            57: 
        !            58: OSDefineMetaClassAndStructors(AppleOHCI, IOUSBController)
        !            59: 
        !            60: bool AppleOHCI::init(OSDictionary * propTable)
        !            61: {
        !            62:     if (!super::init(propTable))  return false;
        !            63: 
        !            64:     _intLock = IOLockAlloc();
        !            65:     if (!_intLock)
        !            66:         return(false);
        !            67: 
        !            68:     pOHCIUIMData = (OHCIUIMDataPtr) IOMalloc(sizeof(OHCIUIMData));
        !            69:     if (!pOHCIUIMData)
        !            70:     {
        !            71:         IOLog("%s: Unable to allocate memory (1)\n", getName());
        !            72:         return(false);
        !            73:     }
        !            74:     bzero( pOHCIUIMData, sizeof(OHCIUIMData));
        !            75:         
        !            76:     return (true);
        !            77: }
        !            78: 
        !            79: void AppleOHCI::SetVendorInfo(void)
        !            80: {
        !            81:     OSData             *vendProp, *deviceProp, *revisionProp;
        !            82: 
        !            83:     // get this chips vendID, deviceID, revisionID
        !            84:     vendProp     = (OSData *) _device->getProperty( "vendor-id" );
        !            85:     if (vendProp)
        !            86:         _vendorID = *((UInt32 *) vendProp->getBytesNoCopy());
        !            87:     deviceProp   = (OSData *) _device->getProperty( "device-id" );
        !            88:     if (deviceProp)
        !            89:         _deviceID   = *((UInt32 *) deviceProp->getBytesNoCopy());
        !            90:     revisionProp = (OSData *) _device->getProperty( "revision-id" );
        !            91:     if (revisionProp)
        !            92:         _revisionID = *((UInt32 *) revisionProp->getBytesNoCopy());
        !            93: }
        !            94: 
        !            95: IOReturn AppleOHCI::UIMInitialize(IOService * provider)
        !            96: {
        !            97:     /* UInt16          ivalue, ivalue2; */
        !            98:     IOReturn           err = 0;
        !            99:     OHCIRegistersPtr   pOHCIRegisters;
        !           100:     UInt32             lvalue;
        !           101: 
        !           102: #if (DEBUGGING_LEVEL > 0)
        !           103:     IOLog("%s: initializing UIM\n", getName());
        !           104: #endif
        !           105: 
        !           106:     _device = OSDynamicCast(IOPCIDevice, provider);
        !           107:     if(_device == NULL)
        !           108:         return kIOReturnBadArgument;
        !           109: 
        !           110:     do {
        !           111: 
        !           112:         if (!(_deviceBase = provider->mapDeviceMemoryWithIndex(0)))
        !           113:         {
        !           114:             IOLog("%s: unable to get device memory\n", getName());
        !           115:             break;
        !           116:         }
        !           117: 
        !           118:         IOLog("%s: config @ %lx (%lx)\n", getName(),
        !           119:               _deviceBase->getVirtualAddress(),
        !           120:               _deviceBase->getPhysicalAddress());
        !           121: 
        !           122:         SetVendorInfo();
        !           123: 
        !           124:         interruptSource = IOInterruptEventSource::
        !           125:             interruptEventSource(this, &OHCIUIMInterruptHandler, _device);
        !           126:         if (!interruptSource
        !           127:         || (_workLoop->addEventSource(interruptSource) != kIOReturnSuccess))
        !           128:             continue;
        !           129: 
        !           130:         _genCursor =
        !           131:             IONaturalMemoryCursor::withSpecification(PAGE_SIZE, PAGE_SIZE);
        !           132:         if(!_genCursor)
        !           133:             continue;
        !           134: 
        !           135:         _isoCursor =
        !           136:             IONaturalMemoryCursor::withSpecification(kUSBMaxIsocFrameReqCount, 
        !           137:                                                        kUSBMaxIsocFrameReqCount);
        !           138:         if(!_isoCursor)
        !           139:             continue;
        !           140: 
        !           141:         /*
        !           142:          * Initialize my data and the hardware
        !           143:          */
        !           144:         pOHCIUIMData->errataBits = GetErrataBits(_vendorID, _deviceID, _revisionID);
        !           145: 
        !           146: #if (DEBUGGING_LEVEL > 0)
        !           147:         IOLog("%s: errata bits=%lx\n", getName(), pOHCIUIMData->errataBits);
        !           148: #endif
        !           149:         pOHCIUIMData->pageSize = PAGE_SIZE;
        !           150:         pOHCIUIMData->pOHCIRegisters = pOHCIRegisters =
        !           151:             (OHCIRegistersPtr) _deviceBase->getVirtualAddress();
        !           152: 
        !           153: #if (DEBUGGING_LEVEL > 2)
        !           154:         dumpRegs();
        !           155: #endif
        !           156:         
        !           157:         // enable the card
        !           158:         lvalue = _device->configRead32(cwCommand);
        !           159:         _device->configWrite32(cwCommand, (lvalue & 0xffff0000) |
        !           160:                               (cwCommandEnableBusMaster |
        !           161:                                cwCommandEnableMemorySpace));
        !           162: 
        !           163:         // Allocate TDs, EDs; FIXME get real numbers to use, CPU specific.
        !           164:         if ((err = OHCIUIMAllocateMemory(NUM_TDS, NUM_EDS, NUM_ITDS)))
        !           165:             continue;
        !           166: 
        !           167:         pOHCIRegisters->hcControlCurrentED = 0;
        !           168:         pOHCIRegisters->hcControlHeadED = 0;
        !           169:         pOHCIRegisters->hcDoneHead = 0;
        !           170:         IOSync();
        !           171: 
        !           172:         // Set up HCCA.
        !           173:         IOPhysicalAddress physAddr;
        !           174:         pOHCIUIMData->pHCCA = (Ptr) IOMallocContiguous(kHCCAsize, kHCCAalignment, &physAddr);
        !           175:         if (!pOHCIUIMData->pHCCA)
        !           176:         {
        !           177:             IOLog("%s: Unable to allocate memory (2)\n", getName());
        !           178:             err = kIOReturnNoMemory;
        !           179:             continue;
        !           180:         }
        !           181: 
        !           182:         OSWriteLittleInt32(&pOHCIRegisters->hcHCCA, 0, physAddr);
        !           183:         IOSync();
        !           184: 
        !           185:         // Set the HC to write the donehead to the HCCA, and enable interrupts
        !           186:         pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_WDH);
        !           187:         IOSync();
        !           188: 
        !           189:        // Enable the interrupt delivery.
        !           190:        _workLoop->enableAllInterrupts();
        !           191: 
        !           192:         // Initialize the Root Hub registers
        !           193:         OHCIRootHubPower(1 /* kOn */);
        !           194:         IOSync();
        !           195:         pOHCIUIMData->rootHubFuncAddress = 1;
        !           196: 
        !           197:         // set up Interrupt transfer tree
        !           198:         if ((err = OHCIUIMIsochronousInitialize()))    continue;
        !           199:         if ((err = OHCIUIMInterruptInitialize()))      continue;
        !           200:         if ((err = OHCIUIMBulkInitialize()))           continue;
        !           201:         if ((err = OHCIUIMControlInitialize()))                continue;
        !           202: 
        !           203:         // Set up hcFmInterval.
        !           204:         UInt32 hcFSMPS;                                // in register hcFmInterval
        !           205:         UInt32 hcFI;                                   // in register hcFmInterval
        !           206:         UInt32 hcPS;                                   // in register hcPeriodicStart
        !           207: 
        !           208:         hcFI = OSReadLittleInt32(&pOHCIRegisters->hcFmInterval, 0) & kOHCIHcFmInterval_FI;
        !           209:         // this formula is from the OHCI spec, section 5.4
        !           210:         hcFSMPS = ((((hcFI-kOHCIMax_OverHead) * 6)/7) << kOHCIHcFmInterval_FSMPSPhase);
        !           211:         hcPS = (hcFI * 9) / 10;                        // per spec- 90%
        !           212:         OSWriteLittleInt32(&pOHCIRegisters->hcFmInterval, 0, hcFI | hcFSMPS);
        !           213:         OSWriteLittleInt32(&pOHCIRegisters->hcPeriodicStart, 0, hcPS);
        !           214: 
        !           215:         IOSync();
        !           216: 
        !           217: 
        !           218:         // Just so we all start from the same place, reset the OHCI.
        !           219:         pOHCIRegisters->hcControl =
        !           220:             OSSwapInt32 ((kOHCIFunctionalState_Reset
        !           221:                                  << kOHCIHcControl_HCFSPhase));
        !           222:         IOSync();
        !           223: 
        !           224:         // Set OHCI to operational state and enable processing of control list.
        !           225:         pOHCIRegisters->hcControl =
        !           226:             OSSwapInt32 ((kOHCIFunctionalState_Operational
        !           227:                                  << kOHCIHcControl_HCFSPhase)
        !           228:                                 | kOHCIHcControl_CLE | kOHCIHcControl_BLE
        !           229:                                 | kOHCIHcControl_PLE | kOHCIHcControl_IE);
        !           230:         IOSync();
        !           231: 
        !           232:         pOHCIRegisters->hcInterruptEnable =
        !           233:             OSSwapInt32 (kOHCIHcInterrupt_MIE | kOHCIDefaultInterrupts);
        !           234:         IOSync();
        !           235:         
        !           236:         if (pOHCIUIMData->errataBits & kErrataLSHSOpti)
        !           237:             OptiLSHSFix();
        !           238:             
        !           239: //naga  (*pOHCIUIMData->interruptEnabler)(pOHCIUIMData->interruptSetMember, nil);
        !           240: 
        !           241:         return(kIOReturnSuccess);
        !           242: 
        !           243:     } while (false);
        !           244: 
        !           245:     IOLog("%s: Error occurred (%d)\n", getName(), err);
        !           246:     UIMFinalize();
        !           247: 
        !           248:     if (interruptSource) interruptSource->release();
        !           249: 
        !           250:     return(err);
        !           251: }
        !           252: 
        !           253: IOReturn AppleOHCI::UIMFinalize(void)
        !           254: {
        !           255:     OHCIRegistersPtr            pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           256: 
        !           257: 
        !           258:     IOLog ("UIMFinalize (shutting down HW)\n");
        !           259: 
        !           260:     // Disable All OHCI Interrupts
        !           261:     pOHCIRegisters->hcInterruptDisable = kOHCIHcInterrupt_MIE;
        !           262:     IOSync();
        !           263:     
        !           264:     // Place the USB bus into the Reset State
        !           265:     pOHCIRegisters->hcControl = OSSwapInt32((kOHCIFunctionalState_Reset
        !           266:                                               << kOHCIHcControl_HCFSPhase));
        !           267:     IOSync();
        !           268: 
        !           269:     //  need to wait at least 1ms here
        !           270:     IOSleep(2);
        !           271: 
        !           272:     // Take away the controllers ability be a bus master.
        !           273:     _device->configWrite32(cwCommand, cwCommandEnableMemorySpace);
        !           274: 
        !           275:     // Clear all Processing Registers
        !           276:     pOHCIRegisters->hcHCCA = 0;
        !           277:     pOHCIRegisters->hcPeriodCurrentED = 0;
        !           278:     pOHCIRegisters->hcControlHeadED = 0;
        !           279:     pOHCIRegisters->hcControlCurrentED = 0;
        !           280:     pOHCIRegisters->hcBulkHeadED = 0;
        !           281:     pOHCIRegisters->hcBulkCurrentED = 0;
        !           282:     pOHCIRegisters->hcDoneHead = 0;
        !           283:     IOSync();
        !           284: 
        !           285:     // turn off the global power
        !           286:     // FIXME check for per-port vs. Global power control
        !           287:     OHCIRootHubPower(0 /* kOff */);
        !           288:     IOSync();
        !           289: 
        !           290:     //status = OHCIUIMFinalizeOHCIUIMData ((OHCIUIMDataPtr) pOHCIUIMData);
        !           291: 
        !           292:     IOLog("OHCIUIMFinalize Exit\n");
        !           293: 
        !           294:     return(kIOReturnSuccess);
        !           295: }
        !           296: 
        !           297: /*
        !           298:  * got an error on a TD with no completion routine.
        !           299:  * Search for a later TD on the same end point which does have one,
        !           300:  * so we can tell upper layes of the error.
        !           301:  */
        !           302: void AppleOHCI::doCallback(OHCIGeneralTransferDescriptorPtr nextTD,
        !           303:                            UInt32                          transferStatus,
        !           304:                            UInt32                          bufferSizeRemaining)
        !           305: {
        !           306:     OHCIGeneralTransferDescriptorPtr    pCurrentTD;
        !           307:     OHCIEndpointDescriptorPtr           pED;
        !           308:     UInt32                              PhysAddr;
        !           309: 
        !           310:     pED = (OHCIEndpointDescriptorPtr) nextTD->pEndpoint;
        !           311: 
        !           312:     PhysAddr = (UInt32) OSSwapInt32(pED->tdQueueHeadPtr) & kOHCIHeadPMask;
        !           313:     nextTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress(PhysAddr);
        !           314: 
        !           315:     pCurrentTD = nextTD;
        !           316:     if(pCurrentTD == nil) {
        !           317:         IOLog("No transfer descriptors in AppleOHCI::doCallback!\n");
        !           318:        return;
        !           319:     }
        !           320:     while (pCurrentTD->pLogicalNext != nil)
        !           321:     {
        !           322:         bufferSizeRemaining += findBufferRemaining (pCurrentTD);
        !           323: 
        !           324:         // make sure this TD won't be added to any future buffer
        !           325:        // remaining calculations
        !           326:         pCurrentTD->currentBufferPtr = 0;
        !           327: 
        !           328:         //ERICif (pCurrentTD->preparationID)
        !           329:         //ERIC    CheckpointIO(pCurrentTD->preparationID, nil);
        !           330:         // make sure we don't try to do another CheckpointIO later
        !           331:         //ERICpCurrentTD->preparationID = nil;
        !           332: 
        !           333:         if (pCurrentTD->completion.action != nil)
        !           334:         {
        !           335:             IOUSBCompletion completion;
        !           336:             // zero out callback first then call it
        !           337:             completion = pCurrentTD->completion;
        !           338:             pCurrentTD->completion.action = nil;
        !           339:             complete(completion,
        !           340:                      TranslateStatusToUSBError(transferStatus),
        !           341:                      bufferSizeRemaining);
        !           342:             bufferSizeRemaining = 0;
        !           343:             return;
        !           344:         }
        !           345: 
        !           346:         pCurrentTD = pCurrentTD->pLogicalNext;
        !           347:     }
        !           348: }
        !           349: 
        !           350: // FIXME add page size to param list
        !           351: UInt32 AppleOHCI::findBufferRemaining (OHCIGeneralTransferDescriptorPtr pCurrentTD)
        !           352: {
        !           353:     UInt32                      pageSize;
        !           354:     UInt32                      pageMask;
        !           355:     UInt32                      bufferSizeRemaining;
        !           356: 
        !           357: 
        !           358:     pageSize = pOHCIUIMData->pageSize;
        !           359:     pageMask = ~(pageSize - 1);
        !           360: 
        !           361:     if (pCurrentTD->currentBufferPtr == 0)
        !           362:     {
        !           363:         bufferSizeRemaining = 0;
        !           364:     }
        !           365:     else if ((OSSwapInt32(pCurrentTD->bufferEnd) & (pageMask)) ==
        !           366:              (OSSwapInt32(pCurrentTD->currentBufferPtr)& (pageMask)))
        !           367:     {
        !           368:         // we're on the same page
        !           369:         bufferSizeRemaining =
        !           370:         (OSSwapInt32 (pCurrentTD->bufferEnd) & ~pageMask) -
        !           371:         (OSSwapInt32 (pCurrentTD->currentBufferPtr) & ~pageMask) + 1;
        !           372:     }
        !           373:     else
        !           374:     {
        !           375:         bufferSizeRemaining =
        !           376:         ((OSSwapInt32(pCurrentTD->bufferEnd) & ~pageMask) + 1)  +
        !           377:         (pageSize - (OSSwapInt32(pCurrentTD->currentBufferPtr) & ~pageMask));
        !           378:     }
        !           379: 
        !           380:     return (bufferSizeRemaining);
        !           381: }
        !           382: 
        !           383: 
        !           384: IOReturn AppleOHCI::OHCIUIMControlInitialize(void)
        !           385: {
        !           386:     OHCIRegistersPtr            pOHCIRegisters;
        !           387:     OHCIEndpointDescriptorPtr   pED, pED2;
        !           388: 
        !           389: 
        !           390:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           391: 
        !           392:     // Create ED mark it skipped and assign it to ControlTail
        !           393:     pED = OHCIUIMAllocateED();
        !           394:     pED->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           395:     pED->nextED = 0;   // End of list
        !           396: 
        !           397:     pOHCIUIMData->pControlTail = (UInt32) pED;
        !           398: 
        !           399:     // Create ED mark it skipped and assign it to control head
        !           400:     pED2 = OHCIUIMAllocateED();
        !           401:     pED2->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           402:     pOHCIUIMData->pControlHead = (UInt32) pED2;
        !           403:     pOHCIRegisters->hcControlHeadED = OSSwapInt32 ((UInt32) pED2->pPhysical);
        !           404: 
        !           405:     // have bulk head ED point to Control tail ED
        !           406:     pED2->nextED = OSSwapInt32 ((UInt32) pED->pPhysical);
        !           407:     pED2->pLogicalNext = pED;
        !           408:     return (kIOReturnSuccess);
        !           409: }
        !           410: 
        !           411: IOReturn AppleOHCI::OHCIUIMBulkInitialize (void)
        !           412: {
        !           413:     OHCIRegistersPtr            pOHCIRegisters;
        !           414:     OHCIEndpointDescriptorPtr   pED, pED2;
        !           415: 
        !           416:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           417: 
        !           418:     // Create ED mark it skipped and assign it to bulkTail
        !           419:     pED = OHCIUIMAllocateED();
        !           420:     pED->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           421:     pED->nextED = 0;   // End of list
        !           422:     pOHCIUIMData->pBulkTail = (UInt32) pED;
        !           423: 
        !           424:     // Create ED mark it skipped and assign it to bulk head
        !           425:     pED2 = OHCIUIMAllocateED();
        !           426:     pED2->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           427:     pOHCIUIMData->pBulkHead = (UInt32) pED2;
        !           428:     pOHCIRegisters->hcBulkHeadED = OSSwapInt32 ((UInt32) pED2->pPhysical);
        !           429: 
        !           430:     // have bulk head ED point to Bulk tail ED
        !           431:     pED2->nextED = OSSwapInt32 ((UInt32) pED->pPhysical);
        !           432:     pED2->pLogicalNext = pED;
        !           433:     return (kIOReturnSuccess);
        !           434: 
        !           435: }
        !           436: 
        !           437: IOReturn AppleOHCI::OHCIUIMIsochronousInitialize(void)
        !           438: {
        !           439:     OHCIRegistersPtr            pOHCIRegisters;
        !           440:     OHCIEndpointDescriptorPtr   pED, pED2;
        !           441: 
        !           442: 
        !           443:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           444: 
        !           445:     // Create ED mark it skipped and assign it to isoch Tail
        !           446:     pED = OHCIUIMAllocateED();
        !           447:     pED->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           448:     pED->nextED = 0;   // End of list
        !           449:     pOHCIUIMData->pIsochTail = (UInt32) pED;
        !           450: 
        !           451:     // Create ED mark it skipped and assign it to isoch head
        !           452:     pED2 = OHCIUIMAllocateED();
        !           453:     pED2->flags = OSSwapInt32 (kOHCIEDControl_K);
        !           454:     pOHCIUIMData->pIsochHead = (UInt32) pED2;
        !           455: 
        !           456: 
        !           457:     // have iso head ED point to iso tail ED
        !           458:     pED2->nextED = OSSwapInt32 ((UInt32) pED->pPhysical);
        !           459:     pED2->pLogicalNext = pED;
        !           460:     pOHCIUIMData->isochBandwidthAvail = kUSBMaxIsocFrameReqCount;
        !           461: 
        !           462:     return (kIOReturnSuccess);
        !           463: }
        !           464: 
        !           465: //Initializes the HCCA Interrupt list with statically
        !           466: //disabled ED's to form the Interrupt polling queues
        !           467: IOReturn AppleOHCI::OHCIUIMInterruptInitialize (void)
        !           468: {
        !           469:     OHCIRegistersPtr            pOHCIRegisters;
        !           470:     OHCIIntHeadPtr              pInterruptHead;
        !           471:     IOReturn                    status = 0;
        !           472:     UInt32                      dummyControl;
        !           473:     int                         i, p, q, z;
        !           474:     OHCIEndpointDescriptorPtr   pED, pIsochHead;
        !           475: 
        !           476: 
        !           477:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !           478:     pInterruptHead = pOHCIUIMData->pInterruptHead;
        !           479: 
        !           480:     // create UInt32 with same dword0 for use with searching and
        !           481:     // tracking, skip should be set, and open area should be marked
        !           482:     dummyControl = kOHCIEDControl_K;
        !           483:     dummyControl |= 0;   //should be kOHCIFakeED
        !           484:     dummyControl = OSSwapInt32 (dummyControl);
        !           485:     pIsochHead = (OHCIEndpointDescriptorPtr) pOHCIUIMData->pIsochHead;
        !           486: 
        !           487:     // do 31 times
        !           488:     // change to 65 and make isoch head the last one.?????
        !           489:     for (i = 0; i < 63; i++)
        !           490:     {
        !           491:         // allocate Endpoint descriptor
        !           492:         pED = OHCIUIMAllocateED();
        !           493:         if (pED == nil)
        !           494:         {
        !           495:             return (kIOReturnNoMemory);
        !           496:         }
        !           497:         // mark skipped,some how mark as a False endpoint zzzzz
        !           498:         else
        !           499:         {
        !           500:             pED->flags = dummyControl;
        !           501:             pED->nextED = 0;   // End of list
        !           502:             pInterruptHead[i].pHead = pED;
        !           503:             pInterruptHead[i].pHeadPhysical = pED->pPhysical;
        !           504:             pInterruptHead[i].nodeBandwidth = 0;
        !           505:         }
        !           506: 
        !           507:         if (i < 32)
        !           508:             ((UInt32 *)pOHCIUIMData->pHCCA)[i] =
        !           509:                 (UInt32) OSSwapInt32 ((UInt32) pInterruptHead[i].pHeadPhysical);
        !           510:     }
        !           511: 
        !           512:     p = 0;
        !           513:     q = 32;
        !           514:     // FIXME? ERIC
        !           515:     for (i = 0; i < (32 +16 + 8 + 4 + 2); i++)
        !           516:     {
        !           517:         if (i < q/2+p)
        !           518:             z = i + q;
        !           519:         else
        !           520:             z = i + q/2;
        !           521:         if (i == p+q-1)
        !           522:         {
        !           523:             p = p + q;
        !           524:             q = q/2;
        !           525:         }
        !           526:         // point endpoint descriptor to corresponding 8ms descriptor
        !           527:         pED = pInterruptHead[i].pHead;
        !           528:         pED->nextED =  OSSwapInt32 (pInterruptHead[z].pHeadPhysical);
        !           529:         pED->pLogicalNext = pInterruptHead[z].pHead;
        !           530:         pInterruptHead[i].pTail = (OHCIEndpointDescriptorPtr) pED->pLogicalNext;
        !           531:     }
        !           532:     i = 62;
        !           533:     pED = pInterruptHead[i].pHead;
        !           534:     pED->nextED = OSSwapInt32 (pIsochHead->pPhysical);
        !           535:     pED->pLogicalNext = pOHCIUIMData->pIsochHead;
        !           536:     pInterruptHead[i].pTail = (OHCIEndpointDescriptorPtr) pED->pLogicalNext;
        !           537: 
        !           538:     // point Isochronous head to last endpoint
        !           539:     return (status);
        !           540: }
        !           541: 
        !           542: ////////////////////////////////////////////////////////////////////////////////
        !           543: //
        !           544: //             UInt32 OHCIUIMGetLogicalAddress
        !           545: //             Given the physical address, return the virtual address
        !           546: //
        !           547: 
        !           548: UInt32 AppleOHCI::OHCIUIMGetLogicalAddress (UInt32 pPhysicalAddress)
        !           549: {
        !           550:     OHCIPhysicalLogicalPtr             pPhysicalLogical;
        !           551:     UInt32                             LogicalAddress = nil;
        !           552: 
        !           553:     if (pPhysicalAddress == 0)
        !           554:         return(0);
        !           555: 
        !           556:     pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !           557: 
        !           558:     while (pPhysicalLogical != nil) {
        !           559:         if (pPhysicalAddress <= pPhysicalLogical->PhysicalEnd
        !           560:             && pPhysicalAddress >= pPhysicalLogical->PhysicalStart)
        !           561:         {
        !           562:             LogicalAddress = pPhysicalLogical->LogicalStart +
        !           563:             (pPhysicalAddress - pPhysicalLogical->PhysicalStart);
        !           564:             pPhysicalLogical = nil;
        !           565:         } else {
        !           566:             pPhysicalLogical = (OHCIPhysicalLogicalPtr) pPhysicalLogical->pNext;
        !           567:         }
        !           568:     }
        !           569: 
        !           570:     if ( LogicalAddress == nil)
        !           571:         IOLog("OHCIUIM: LogicalAddress(0x%lx) == nil !\n", pPhysicalAddress);
        !           572: 
        !           573:     return (LogicalAddress);
        !           574: 
        !           575: }
        !           576: 
        !           577: 
        !           578: UInt32 AppleOHCI::OHCIUIMGetPhysicalAddress(UInt32     LogicalAddress,
        !           579:                                             UInt32     count)
        !           580: {
        !           581:     OHCIPhysicalLogicalPtr     pPhysicalLogical;
        !           582:     UInt32                     PhysicalAddress = nil;
        !           583: 
        !           584:     if (LogicalAddress == 0)
        !           585:         return(0);
        !           586: 
        !           587:     pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !           588: 
        !           589:     while (pPhysicalLogical != nil) {
        !           590:         if (LogicalAddress <= pPhysicalLogical->LogicalEnd
        !           591:             && LogicalAddress >= pPhysicalLogical->LogicalStart)
        !           592:         {
        !           593:             PhysicalAddress = pPhysicalLogical->PhysicalStart
        !           594:             + (LogicalAddress - pPhysicalLogical->LogicalStart);
        !           595:             pPhysicalLogical = nil;
        !           596:         } else {
        !           597:             pPhysicalLogical = pPhysicalLogical->pNext;
        !           598:         }
        !           599:     }
        !           600: 
        !           601:     if (PhysicalAddress == nil)
        !           602:         PhysicalAddress = OHCIUIMCreatePhysicalAddress(LogicalAddress, count);
        !           603: 
        !           604:     return (PhysicalAddress);
        !           605: }
        !           606: 
        !           607: /*
        !           608:  * OHCIUIMCreatePhysicalAddress:
        !           609:  * Currently this function only creates a one entry OHCIPhysicalLogical
        !           610:  * entry.  This is because it is assuming contiguous memory.  
        !           611:  *
        !           612:  */
        !           613: UInt32 AppleOHCI::OHCIUIMCreatePhysicalAddress(UInt32 pLogicalAddress,
        !           614:                                                UInt32 count)
        !           615: 
        !           616: {
        !           617:     UInt32                             pageSize;
        !           618:     OHCIPhysicalLogicalPtr             pPhysicalLogical;
        !           619:     OHCIPhysicalLogicalPtr             p;
        !           620: 
        !           621:     pPhysicalLogical = pOHCIUIMData->pPhysicalLogical;
        !           622:     pageSize = pOHCIUIMData->pageSize;
        !           623: 
        !           624:     // zzz do we deallocate this?
        !           625:     p = (OHCIPhysicalLogicalPtr) IOMalloc(sizeof (OHCIPhysicalLogical));
        !           626: 
        !           627:     p->LogicalStart =  pLogicalAddress;
        !           628:     p->PhysicalStart = kvtophys((vm_offset_t)pLogicalAddress);
        !           629:     p->LogicalEnd = p->LogicalStart + count * pageSize-1;
        !           630:     p->PhysicalEnd = p->PhysicalStart + count * pageSize-1;
        !           631:     p->pNext = pOHCIUIMData->pPhysicalLogical;
        !           632: 
        !           633:     pOHCIUIMData->pPhysicalLogical = p;
        !           634: 
        !           635:     return (p->PhysicalStart);
        !           636: }
        !           637: 
        !           638: //Allocate
        !           639: IOReturn AppleOHCI::OHCIUIMAllocateMemory (int num_of_TDs,
        !           640:                                            int num_of_EDs,
        !           641:                                            int num_of_ITDs)
        !           642: {
        !           643:     Ptr                                 p;
        !           644:     UInt32                              physical;
        !           645:     int                                 tdsPerPage, pagesTD,
        !           646:                                        edsPerPage, pagesED,
        !           647:                                        itdsPerPage, pagesITD;
        !           648:     UInt32                              pageSize;
        !           649:     OHCIEndpointDescriptorPtr           FreeED, FreeEDCurrent;
        !           650:     OHCIGeneralTransferDescriptorPtr    FreeTD, FreeTDCurrent;
        !           651:     OHCIIsochTransferDescriptorPtr      FreeITD, FreeITDCurrent;
        !           652:     int                                 i,j;
        !           653: 
        !           654: 
        !           655:     pageSize = pOHCIUIMData->pageSize;
        !           656: 
        !           657:     tdsPerPage = pageSize / sizeof (OHCIGeneralTransferDescriptor);
        !           658:     pagesTD = (num_of_TDs + (tdsPerPage - 1)) / tdsPerPage;
        !           659:     edsPerPage = pageSize / sizeof (OHCIEndpointDescriptor);
        !           660:     pagesED = (num_of_EDs + (edsPerPage - 1)) / edsPerPage;
        !           661:     itdsPerPage = pageSize / sizeof (OHCIIsochTransferDescriptor);
        !           662:     pagesITD = (num_of_ITDs + (itdsPerPage - 1)) / itdsPerPage;
        !           663: 
        !           664:     p = (Ptr)IOMalloc( (pagesED + pagesTD + pagesITD + 1) * pageSize);
        !           665:     
        !           666:     if (!p)
        !           667:         return(kIOReturnNoMemory);
        !           668: 
        !           669:     for(i=0; i<(pagesED + pagesTD + pagesITD + 1) * pageSize/4; i++)
        !           670:        ((UInt32 *)p)[i] = 0x12345678;
        !           671: //    bzero(p, ((pagesED + pagesTD + pagesITD + 1) * pageSize));
        !           672: 
        !           673:     pOHCIUIMData->pDataAllocation = p;
        !           674:     // page align and 16 byte align (page align automagically
        !           675:     // makes it 16 byte aligned)
        !           676:     p = (Ptr) (((UInt32) p + (pageSize - 1)) & ~(pageSize - 1));
        !           677:     //bzero(p, ((pagesED) * pageSize));
        !           678: 
        !           679:     
        !           680:     // create a list of unused ED's, filling in Virtual address,
        !           681:     // physicaladdress and virtual next physical next.
        !           682:     FreeED = (OHCIEndpointDescriptorPtr) p;
        !           683:     FreeEDCurrent = FreeED;
        !           684:     pOHCIUIMData->pFreeED = FreeED;
        !           685: 
        !           686:     for (i = 0 ; i < pagesED ; i++)
        !           687:     {
        !           688:         physical = kvtophys(FreeEDCurrent);
        !           689:         for (j = 0; j < edsPerPage; j++)
        !           690:         {
        !           691:             // create EDs
        !           692:             FreeEDCurrent[j].pPhysical =
        !           693:                physical + (j * sizeof (OHCIEndpointDescriptor));
        !           694:             FreeEDCurrent[j].pLogicalNext = (&FreeEDCurrent[j+1]);
        !           695:         }
        !           696:         if (i != (pagesED - 1))
        !           697:         {
        !           698:             FreeEDCurrent[j-1].pLogicalNext = ((UInt32) FreeEDCurrent + pageSize);
        !           699:         }
        !           700:         else
        !           701:         {
        !           702:             FreeEDCurrent[j-1].pLogicalNext = nil;
        !           703:             pOHCIUIMData->pLastFreeED = &FreeEDCurrent[j-1];
        !           704:         }
        !           705: 
        !           706:         // goto next page
        !           707:         FreeEDCurrent = (OHCIEndpointDescriptorPtr)
        !           708:                                ((UInt32) FreeEDCurrent + pageSize);
        !           709:         //physical += pageSize;
        !           710:     }
        !           711: 
        !           712:     FreeTD = (OHCIGeneralTransferDescriptorPtr) FreeEDCurrent;
        !           713:     FreeTDCurrent = FreeTD;
        !           714:     pOHCIUIMData->pFreeTD = FreeTD;
        !           715:     for (i = 0; i < pagesTD; i++)
        !           716:     {
        !           717:         physical = OHCIUIMGetPhysicalAddress((UInt32) FreeTDCurrent, 1);
        !           718:         for (j = 0; j < tdsPerPage; j++)
        !           719:         {
        !           720:             //create TDs
        !           721:             FreeTDCurrent[j].pPhysical =
        !           722:                physical + (j * sizeof (OHCIGeneralTransferDescriptor));
        !           723:             FreeTDCurrent[j].pLogicalNext = (UInt32) (&FreeTDCurrent[j+1]);
        !           724:         }
        !           725:         if (i != (pagesTD - 1))
        !           726:         {
        !           727:             FreeTDCurrent[j-1].pLogicalNext = ((UInt32) FreeTDCurrent + pageSize);
        !           728:         }
        !           729:         else
        !           730:         {
        !           731:             FreeTDCurrent[j-1].pLogicalNext = nil;
        !           732:             pOHCIUIMData->pLastFreeTD = &FreeTDCurrent[j-1];
        !           733:         }
        !           734: 
        !           735:         // goto next page
        !           736:         FreeTDCurrent = (OHCIGeneralTransferDescriptorPtr)
        !           737:                ((UInt32) FreeTDCurrent + pageSize);
        !           738:         //physical += pageSize;
        !           739:     }
        !           740: 
        !           741:    // set up freeitd queue
        !           742:     FreeITD = (OHCIIsochTransferDescriptorPtr) FreeTDCurrent;
        !           743:     FreeITDCurrent = FreeITD;
        !           744:     pOHCIUIMData->pFreeITD = FreeITD;
        !           745:     for (i = 0; i < pagesITD; i++)
        !           746:     {
        !           747:         //physical = kvtophys(FreeITDCurrent);
        !           748:         physical = OHCIUIMGetPhysicalAddress((UInt32) FreeITDCurrent, 1);
        !           749:         for (j = 0; j < itdsPerPage; j++)
        !           750:         {
        !           751:             // create TDs
        !           752:             FreeITDCurrent[j].pPhysical =
        !           753:                physical + (j * sizeof (OHCIIsochTransferDescriptor));
        !           754:             FreeITDCurrent[j].pLogicalNext = (&FreeITDCurrent[j+1]);
        !           755:         }
        !           756:         if (i != (pagesITD - 1))
        !           757:         {
        !           758:             FreeITDCurrent[j-1].pLogicalNext =
        !           759:                (OHCIIsochTransferDescriptorPtr)((UInt32) FreeITDCurrent + pageSize);
        !           760:         }
        !           761:         else
        !           762:         {
        !           763:             FreeITDCurrent[j-1].pLogicalNext = nil;
        !           764:             pOHCIUIMData->pLastFreeITD = &FreeITDCurrent[j-1];
        !           765:         }
        !           766: 
        !           767:         // goto next page
        !           768:         FreeITDCurrent = (OHCIIsochTransferDescriptorPtr)
        !           769:                                        ((UInt32) FreeITDCurrent + pageSize);
        !           770:         //physical += pageSize;
        !           771:     }
        !           772:     
        !           773:     // create a list of unused buffers?????
        !           774: 
        !           775:     return (kIOReturnSuccess);
        !           776: }
        !           777: 
        !           778: OHCIIsochTransferDescriptorPtr AppleOHCI::OHCIUIMAllocateITD(void)
        !           779: {
        !           780:     OHCIIsochTransferDescriptorPtr temp;
        !           781: 
        !           782:     // pop a TD off of FreeTD list
        !           783:     // if FreeTD == NIL return nil
        !           784:     // should we check if ED is full and if not access that????
        !           785:     temp = pOHCIUIMData->pFreeITD;
        !           786: 
        !           787:     if (temp != nil)
        !           788:     {
        !           789:         pOHCIUIMData->pFreeITD = temp->pLogicalNext;
        !           790:     }
        !           791:     else
        !           792:     {
        !           793:         IOLog("%s: Out of Isoch Transfer Descriptors!\n", getName());
        !           794:        return nil;
        !           795:     }
        !           796: 
        !           797:     temp->pLogicalNext = nil;
        !           798: 
        !           799:     return (temp);
        !           800: }
        !           801: 
        !           802: OHCIGeneralTransferDescriptorPtr AppleOHCI::OHCIUIMAllocateTD(void)
        !           803: 
        !           804: {
        !           805:     OHCIGeneralTransferDescriptorPtr freeTD;
        !           806: 
        !           807:     // pop a TD off of FreeTD list
        !           808:     //if FreeTD == NIL return nil
        !           809:     // should we check if ED is full and if not access that????
        !           810:     freeTD = pOHCIUIMData->pFreeTD;
        !           811: 
        !           812:     if (freeTD == nil)
        !           813:     {
        !           814:         int j;
        !           815:         int tdsPerPage;
        !           816:         UInt32 physical;
        !           817:         OHCIGeneralTransferDescriptorPtr FreeTDCurrent;
        !           818:         UInt8 * p = (UInt8 *)IOMallocAligned(pOHCIUIMData->pageSize,
        !           819:                                         pOHCIUIMData->pageSize);
        !           820:         if(p == NULL) {
        !           821:             IOLog("%s: Out of Transfer Descriptors!\n", getName());
        !           822:             return NULL;
        !           823:         }
        !           824: 
        !           825:         //bzero(p, pOHCIUIMData->pageSize);
        !           826: 
        !           827:         tdsPerPage = pOHCIUIMData->pageSize / sizeof (OHCIGeneralTransferDescriptor);
        !           828:         pOHCIUIMData->pFreeTD = FreeTDCurrent = (OHCIGeneralTransferDescriptorPtr)p;
        !           829:         physical = OHCIUIMGetPhysicalAddress((UInt32) FreeTDCurrent, 1);
        !           830:         for (j = 0; j < tdsPerPage-1; j++)
        !           831:         {
        !           832:             //create TDs
        !           833:             FreeTDCurrent[j].pPhysical =
        !           834:                 physical + (j * sizeof (OHCIGeneralTransferDescriptor));
        !           835:             FreeTDCurrent[j].pLogicalNext = &FreeTDCurrent[j+1];
        !           836:         }
        !           837:         FreeTDCurrent[j].pPhysical =
        !           838:             physical + (j * sizeof (OHCIGeneralTransferDescriptor));
        !           839:         FreeTDCurrent[j].pLogicalNext = nil;
        !           840:         pOHCIUIMData->pLastFreeTD = &FreeTDCurrent[j];
        !           841:         freeTD = pOHCIUIMData->pFreeTD;
        !           842:     }
        !           843:     pOHCIUIMData->pFreeTD = freeTD->pLogicalNext;
        !           844:     freeTD->pLogicalNext = nil;
        !           845:     return (freeTD);
        !           846: }
        !           847: 
        !           848: OHCIEndpointDescriptorPtr AppleOHCI::OHCIUIMAllocateED(void)
        !           849: {
        !           850:     OHCIEndpointDescriptorPtr freeED;
        !           851: 
        !           852:     // Pop a ED off the FreeED list
        !           853:     // If FreeED == nil return Error
        !           854:     freeED = pOHCIUIMData->pFreeED;
        !           855: 
        !           856:     if (freeED == nil)
        !           857:     {
        !           858:        int j;
        !           859:        int edsPerPage;
        !           860:         UInt32 physical;
        !           861:         OHCIEndpointDescriptorPtr FreeEDCurrent;
        !           862:         UInt8 * p = (UInt8 *)IOMallocAligned(pOHCIUIMData->pageSize,
        !           863:                                        pOHCIUIMData->pageSize);
        !           864:         if(p == NULL)
        !           865:         {
        !           866:             IOLog("%s: Out of Endpoint Descriptors!\n", getName());
        !           867:             return NULL;
        !           868:         }
        !           869: 
        !           870:        //bzero(p, pOHCIUIMData->pageSize);
        !           871: 
        !           872:         edsPerPage = pOHCIUIMData->pageSize / sizeof (OHCIEndpointDescriptor);
        !           873:         physical = kvtophys((vm_offset_t)p);
        !           874:         pOHCIUIMData->pFreeED = FreeEDCurrent = (OHCIEndpointDescriptorPtr)p;
        !           875:         for (j = 0; j < edsPerPage-1; j++)
        !           876:         {
        !           877:             // create EDs
        !           878:             FreeEDCurrent[j].pPhysical =
        !           879:                 physical + (j * sizeof (OHCIEndpointDescriptor));
        !           880:             FreeEDCurrent[j].pLogicalNext = (&FreeEDCurrent[j+1]);
        !           881:         }
        !           882:         FreeEDCurrent[j].pPhysical =
        !           883:             physical + (j * sizeof (OHCIEndpointDescriptor));
        !           884:         FreeEDCurrent[j].pLogicalNext = nil;
        !           885:         pOHCIUIMData->pLastFreeED = &FreeEDCurrent[j];
        !           886:         freeED = pOHCIUIMData->pFreeED;
        !           887:     }
        !           888:     pOHCIUIMData->pFreeED = (OHCIEndpointDescriptorPtr) freeED->pLogicalNext;
        !           889:     freeED->pLogicalNext = nil;
        !           890:     return (freeED);
        !           891: }
        !           892: 
        !           893: IOReturn AppleOHCI::OHCIUIMDeallocateITD (OHCIIsochTransferDescriptorPtr pTD)
        !           894: {
        !           895:     UInt32             physical;
        !           896: 
        !           897:     // zero out all unnecessary fields
        !           898:     physical = pTD->pPhysical;
        !           899:     //bzero(pTD, sizeof(*pTD));
        !           900:     pTD->pLogicalNext = NULL;
        !           901:     pTD->pPhysical = physical;
        !           902:     if (pOHCIUIMData->pFreeITD)
        !           903:     {
        !           904:         pOHCIUIMData->pLastFreeITD->pLogicalNext = pTD;
        !           905:         pOHCIUIMData->pLastFreeITD = pTD;
        !           906:     }
        !           907:     else
        !           908:     {
        !           909:         // list is currently empty
        !           910:         pOHCIUIMData->pLastFreeITD = pTD;
        !           911:         pOHCIUIMData->pFreeITD = pTD;
        !           912:     }
        !           913:     return (kIOReturnSuccess);
        !           914: }
        !           915: 
        !           916: 
        !           917: IOReturn AppleOHCI::OHCIUIMDeallocateTD (OHCIGeneralTransferDescriptorPtr pTD)
        !           918: {
        !           919:     UInt32             physical;
        !           920: 
        !           921:     //zero out all unnecessary fields
        !           922:     physical = pTD->pPhysical;
        !           923:     //bzero(pTD, sizeof(*pTD));
        !           924:     pTD->pLogicalNext = nil;
        !           925:     pTD->pPhysical = physical;
        !           926: 
        !           927:     if (pOHCIUIMData->pFreeTD){
        !           928:         pOHCIUIMData->pLastFreeTD->pLogicalNext = pTD;
        !           929:         pOHCIUIMData->pLastFreeTD = pTD;
        !           930:     } else {
        !           931:         // list is currently empty
        !           932:         pOHCIUIMData->pLastFreeTD = pTD;
        !           933:         pOHCIUIMData->pFreeTD = pTD;
        !           934:     }
        !           935:     return (kIOReturnSuccess);
        !           936: }
        !           937: 
        !           938: IOReturn AppleOHCI::OHCIUIMDeallocateED (OHCIEndpointDescriptorPtr pED)
        !           939: {
        !           940:     UInt32             physical;
        !           941: 
        !           942:     //zero out all unnecessary fields
        !           943:     physical = pED->pPhysical;
        !           944:     //bzero(pED, sizeof(*pED));
        !           945:     pED->pPhysical = physical;
        !           946:     pED->pLogicalNext = nil;
        !           947: 
        !           948:     if (pOHCIUIMData->pFreeED){
        !           949:         pOHCIUIMData->pLastFreeED->pLogicalNext = pED;
        !           950:         pOHCIUIMData->pLastFreeED = pED;
        !           951:     } else {
        !           952:         // list is currently empty
        !           953:         pOHCIUIMData->pLastFreeED = pED;
        !           954:         pOHCIUIMData->pFreeED = pED;
        !           955:     }
        !           956:     return (kIOReturnSuccess);
        !           957: }
        !           958: 
        !           959: int GetEDType(OHCIEndpointDescriptorPtr pED)
        !           960: {
        !           961:     return ((OSSwapInt32(pED->flags) & kOHCIEDControl_F)
        !           962:                                                     >> kOHCIEDControl_FPhase);
        !           963: }
        !           964: 
        !           965: 
        !           966: IOReturn AppleOHCI::RemoveAllTDs (OHCIEndpointDescriptorPtr pED)
        !           967: {
        !           968:     RemoveTDs(pED);
        !           969: 
        !           970:     if (GetEDType(pED) == kOHCIEDFormatGeneralTD) {
        !           971:         // remove the last "dummy" TD
        !           972:         OHCIUIMDeallocateTD(
        !           973:                             (OHCIGeneralTransferDescriptorPtr) pED->pLogicalTailP);
        !           974:     }
        !           975:     else
        !           976:     {
        !           977:         OHCIUIMDeallocateITD(
        !           978:                              (OHCIIsochTransferDescriptorPtr) pED->pLogicalTailP);
        !           979:     }
        !           980:     pED->pLogicalTailP = nil;
        !           981: 
        !           982:     return (0);
        !           983: }
        !           984: 
        !           985: 
        !           986: //removes all but the last of the TDs
        !           987: IOReturn AppleOHCI::RemoveTDs(OHCIEndpointDescriptorPtr pED)
        !           988: {
        !           989:     OHCIGeneralTransferDescriptorPtr   pCurrentTD, lastTD;
        !           990:     UInt32                             bufferSizeRemaining = 0;
        !           991:     OHCIIsochTransferDescriptorPtr     pITD, pITDLast;
        !           992:        
        !           993:     if (GetEDType(pED) == kOHCIEDFormatGeneralTD)
        !           994:     {
        !           995:         //process and deallocate GTD's
        !           996:         pCurrentTD = (OHCIGeneralTransferDescriptorPtr)
        !           997:                (OSSwapInt32(pED->tdQueueHeadPtr) & kOHCIHeadPMask);
        !           998:         pCurrentTD = (OHCIGeneralTransferDescriptorPtr)
        !           999:                             OHCIUIMGetLogicalAddress ((UInt32) pCurrentTD);
        !          1000: 
        !          1001:         lastTD = (OHCIGeneralTransferDescriptorPtr) pED->pLogicalTailP;
        !          1002:         pED->pLogicalHeadP = pED->pLogicalTailP;
        !          1003: 
        !          1004:         while (pCurrentTD != lastTD)
        !          1005:         {
        !          1006:             if (pCurrentTD == nil)
        !          1007:                 return (-1);
        !          1008: 
        !          1009:             //take out TD from list
        !          1010:             pED->tdQueueHeadPtr = pCurrentTD->nextTD;
        !          1011:             pED->pLogicalHeadP = pCurrentTD->pLogicalNext;     
        !          1012: 
        !          1013:             bufferSizeRemaining += findBufferRemaining(pCurrentTD);
        !          1014: 
        !          1015:             if (pCurrentTD->completion.action != nil)
        !          1016:             {
        !          1017:                 IOUSBCompletion completion;
        !          1018:                 // zero out callback first then call it
        !          1019:                 completion = pCurrentTD->completion;
        !          1020:                 pCurrentTD->completion.action = nil;
        !          1021:                 complete(completion,
        !          1022:                          kIOReturnAborted,
        !          1023:                          bufferSizeRemaining);
        !          1024:                 bufferSizeRemaining = 0;
        !          1025:             }
        !          1026: 
        !          1027:             OHCIUIMDeallocateTD(pCurrentTD);
        !          1028:             pCurrentTD = (OHCIGeneralTransferDescriptorPtr) pED->pLogicalHeadP;                
        !          1029:         }              
        !          1030:     }
        !          1031:     else
        !          1032:     {
        !          1033:         UInt32 phys;
        !          1034:         phys = (OSReadLittleInt32(&pED->tdQueueHeadPtr, 0) & kOHCIHeadPMask);
        !          1035:         pITD = (OHCIIsochTransferDescriptorPtr)
        !          1036:                                 OHCIUIMGetLogicalAddress (phys);
        !          1037:         pITDLast = (OHCIIsochTransferDescriptorPtr)pED->pLogicalTailP;
        !          1038: 
        !          1039:         while (pITD != pITDLast)
        !          1040:         {
        !          1041:             OHCIIsochTransferDescriptorPtr pPrevITD;
        !          1042:             if (pITD == nil)
        !          1043:                 return (-1);
        !          1044:             ProcessCompletedITD (pITD, kIOReturnAborted);
        !          1045:             pPrevITD = pITD;
        !          1046:             pITD = pITD->pLogicalNext;
        !          1047:             // deallocate td
        !          1048:             OHCIUIMDeallocateITD(pPrevITD);
        !          1049:         }
        !          1050:     }
        !          1051: 
        !          1052:     return (0);
        !          1053: }
        !          1054: 
        !          1055: void ProcessCompletedITD (OHCIIsochTransferDescriptorPtr pITD, IOReturn status)
        !          1056: {
        !          1057: 
        !          1058:     IOUSBIsocFrame *   pFrames;
        !          1059:     int                        i;
        !          1060:     int                        frameCount;
        !          1061: 
        !          1062:     //print_itd(pITD); 
        !          1063:     pFrames = pITD->pIsocFrame;
        !          1064:     frameCount = (OSReadLittleInt32(&pITD->flags, 0) & kOHCIITDControl_FC) >> 
        !          1065:                                                        kOHCIITDControl_FCPhase;
        !          1066:     for (i=0; i <= frameCount; i++)
        !          1067:     {
        !          1068:         UInt16 offset = OSReadLittleInt16(&pITD->offset[i], 0);
        !          1069:         if ( ((offset & kOHCIITDPSW_CCNA) >> kOHCIITDPSW_CCNAPhase) ==
        !          1070:                                        kOHCIITDOffsetConditionNotAccessed)
        !          1071:         {
        !          1072:             pFrames[pITD->frameNum + i].frActCount = 0;
        !          1073:             pFrames[pITD->frameNum + i].frStatus =
        !          1074:                 kOHCIITDConditionNotAccessedReturn;
        !          1075:         }
        !          1076:         else
        !          1077:         {
        !          1078:             pFrames[pITD->frameNum + i].frStatus =
        !          1079:             (offset & kOHCIITDPSW_CC) >> kOHCIITDOffset_CCPhase;
        !          1080:             // Successful isoch transmit sets the size field to zero,
        !          1081:             // successful receive sets size to actual packet size received.
        !          1082:             if(kIOReturnSuccess == pFrames[pITD->frameNum + i].frStatus &&
        !          1083:                                        pITD->pType == kOHCIIsochronousOutType)
        !          1084:                 pFrames[pITD->frameNum + i].frActCount =
        !          1085:                     pFrames[pITD->frameNum + i].frReqCount;
        !          1086:             else
        !          1087:                 pFrames[pITD->frameNum + i].frActCount =
        !          1088:                         offset & kOHCIITDPSW_Size;
        !          1089:         }
        !          1090:     }
        !          1091:     // call callback
        !          1092:     if (pITD->completion.action)
        !          1093:     {
        !          1094:         IOUSBIsocCompletionAction pHandler;
        !          1095:         pHandler = pITD->completion.action;
        !          1096:         pITD->completion.action = nil;
        !          1097:         //zero out handler first than call it
        !          1098:         (*pHandler) (pITD->completion.target,  pITD->completion.parameter,
        !          1099:                                                        status, pFrames);
        !          1100:     }
        !          1101: }
        !          1102: 
        !          1103: 
        !          1104: IOReturn
        !          1105: AppleOHCI::DoDoneQueueProcessing(OHCIGeneralTransferDescriptorPtr pHCDoneTD,
        !          1106:                                  IOUSBCompletionAction safeAction)
        !          1107: {
        !          1108:     UInt32                             control, transferStatus;
        !          1109:     long                               bufferSizeRemaining;
        !          1110:     OHCIGeneralTransferDescriptorPtr   prevTD, nextTD;
        !          1111:     UInt32                             PhysAddr;
        !          1112:     UInt32                             pageSize;
        !          1113:     UInt32                             pageMask;
        !          1114:     OHCIEndpointDescriptorPtr          tempED;
        !          1115:     OHCIRegistersPtr                   pOHCIRegisters;
        !          1116:     OHCIIsochTransferDescriptorPtr     pITD;
        !          1117: 
        !          1118:     pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1119: 
        !          1120:     if(pHCDoneTD == nil)
        !          1121:         /* This should not happen */
        !          1122:         return(kIOReturnSuccess);
        !          1123: 
        !          1124:     pageSize = pOHCIUIMData->pageSize;
        !          1125:     pageMask = ~(pageSize - 1);
        !          1126: 
        !          1127:     /* Reverse the done queue use only the virtual Address fields */
        !          1128:     prevTD = 0;
        !          1129:     while (pHCDoneTD != nil)
        !          1130:     {
        !          1131:         PhysAddr = OSSwapInt32(pHCDoneTD->nextTD) & kOHCIHeadPMask;
        !          1132:         nextTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress(PhysAddr);
        !          1133:         pHCDoneTD->pLogicalNext = prevTD;
        !          1134:         prevTD = pHCDoneTD;
        !          1135:         pHCDoneTD = nextTD;
        !          1136:     }
        !          1137:     pHCDoneTD = prevTD;        /* New qHead */
        !          1138: 
        !          1139:     while (pHCDoneTD != nil)
        !          1140:     {
        !          1141: #if (DEBUGGING_LEVEL > 2)
        !          1142:         DEBUGLOG("\tdone queue: processing..."); print_td(pHCDoneTD);
        !          1143: #endif
        !          1144:         IOReturn errStatus;
        !          1145:         // find the next one
        !          1146:         nextTD = pHCDoneTD->pLogicalNext;
        !          1147: 
        !          1148:         control = OSSwapInt32(pHCDoneTD->flags);
        !          1149:         transferStatus = (control & kOHCIGTDControl_CC)
        !          1150:             >> kOHCIGTDControl_CCPhase;
        !          1151:         errStatus = TranslateStatusToUSBError(transferStatus);
        !          1152:         if (pOHCIUIMData->OptiOn && (pHCDoneTD->pType == kOHCIOptiLSBug))
        !          1153:         {
        !          1154:             // clear any bad errors
        !          1155:             tempED = (OHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;
        !          1156:             pHCDoneTD->flags = pHCDoneTD->flags
        !          1157:                 & OSSwapInt32(kOHCIGTDClearErrorMask);
        !          1158:             tempED->tdQueueHeadPtr &=  OSSwapInt32(kOHCIHeadPMask);
        !          1159:             pHCDoneTD->nextTD = tempED->tdQueueTailPtr & OSSwapInt32(kOHCIHeadPMask);
        !          1160:             tempED->tdQueueTailPtr = OSSwapInt32(pHCDoneTD->pPhysical);
        !          1161:             pOHCIRegisters->hcCommandStatus =
        !          1162:                 OSSwapInt32 (kOHCIHcCommandStatus_CLF);
        !          1163: 
        !          1164:             // For CMD Buffer Underrun Errata
        !          1165:         }
        !          1166:         else if ((transferStatus == kOHCIGTDConditionBufferUnderrun) &&
        !          1167:                  (pHCDoneTD->pType == kOHCIBulkTransferOutType) &&
        !          1168:                  (pOHCIUIMData->errataBits & kErrataRetryBufferUnderruns))
        !          1169:         {
        !          1170:             tempED = (OHCIEndpointDescriptorPtr) pHCDoneTD->pEndpoint;
        !          1171:             pHCDoneTD->flags = pHCDoneTD->flags
        !          1172:                 & OSSwapInt32(kOHCIGTDClearErrorMask);
        !          1173:             pHCDoneTD->nextTD = tempED->tdQueueHeadPtr & OSSwapInt32(kOHCIHeadPMask);
        !          1174:             pHCDoneTD->pLogicalNext = (OHCIGeneralTransferDescriptorPtr)
        !          1175:                OHCIUIMGetLogicalAddress (OSSwapInt32(tempED->tdQueueHeadPtr)
        !          1176:                                                 & kOHCIHeadPMask);
        !          1177: 
        !          1178:             tempED->tdQueueHeadPtr = OSSwapInt32(pHCDoneTD->pPhysical)
        !          1179:                 | (tempED->tdQueueHeadPtr & OSSwapInt32( kOHCIEDToggleBitMask));
        !          1180:             pOHCIRegisters->hcCommandStatus =
        !          1181:                 OSSwapInt32(kOHCIHcCommandStatus_BLF);
        !          1182: 
        !          1183:         }
        !          1184:         else if (pHCDoneTD->pType == kOHCIIsochronousInType ||
        !          1185:                                pHCDoneTD->pType == kOHCIIsochronousOutType)
        !          1186:         {
        !          1187:             // cast to a isoc type
        !          1188:             pITD = (OHCIIsochTransferDescriptorPtr) pHCDoneTD;
        !          1189:             ProcessCompletedITD(pITD, errStatus);
        !          1190:             // deallocate td
        !          1191:             OHCIUIMDeallocateITD(pITD);
        !          1192:         }
        !          1193:         else
        !          1194:         {
        !          1195:             bufferSizeRemaining = findBufferRemaining (pHCDoneTD);
        !          1196:             if (pHCDoneTD->completion.action != nil)
        !          1197:             {
        !          1198:                 IOUSBCompletion completion;
        !          1199:                 completion = pHCDoneTD->completion;
        !          1200:                 if(!safeAction || (safeAction == completion.action)) {
        !          1201:                     // zero out callback first then call it
        !          1202:                     pHCDoneTD->completion.action = nil;
        !          1203:                     complete(completion, errStatus, bufferSizeRemaining);
        !          1204:                     OHCIUIMDeallocateTD(pHCDoneTD);
        !          1205:                 }
        !          1206:                 else {
        !          1207:                     if(_pendingHead)
        !          1208:                         _pendingTail->pLogicalNext = pHCDoneTD;
        !          1209:                     else
        !          1210:                         _pendingHead = pHCDoneTD;
        !          1211:                     _pendingTail = pHCDoneTD;
        !          1212:                 }
        !          1213:             }
        !          1214:             else if (errStatus != kIOReturnSuccess) {
        !          1215:                 doCallback(pHCDoneTD, errStatus, bufferSizeRemaining);
        !          1216:                 OHCIUIMDeallocateTD(pHCDoneTD);
        !          1217:             }
        !          1218:         }
        !          1219:         pHCDoneTD = nextTD;    /* New qHead */
        !          1220:     }
        !          1221: 
        !          1222:     return(kIOReturnSuccess);
        !          1223: }
        !          1224: 
        !          1225: 
        !          1226: 
        !          1227: 
        !          1228: void AppleOHCI::UIMProcessDoneQueue(IOUSBCompletionAction safeAction)
        !          1229: {
        !          1230:     OHCIRegistersPtr           pOHCIRegisters = pOHCIUIMData->pOHCIRegisters;
        !          1231:     UInt32                             interruptStatus;
        !          1232:     UInt32                             PhysAddr;
        !          1233:     OHCIGeneralTransferDescriptorPtr   pHCDoneTD;
        !          1234: 
        !          1235: 
        !          1236:     // check if the OHCI has written the DoneHead yet
        !          1237:     interruptStatus = OSSwapInt32(pOHCIRegisters->hcInterruptStatus);
        !          1238:     if( (interruptStatus & kOHCIHcInterrupt_WDH) == 0)
        !          1239:     {  
        !          1240:         return;
        !          1241:     }
        !          1242: 
        !          1243:     // get the pointer to the list (logical address)
        !          1244:     PhysAddr = (UInt32) OSSwapInt32(*(UInt32 *)(pOHCIUIMData->pHCCA + 0x84));
        !          1245:     PhysAddr &= kOHCIHeadPMask; // mask off interrupt bits
        !          1246:     pHCDoneTD = (OHCIGeneralTransferDescriptorPtr) OHCIUIMGetLogicalAddress(PhysAddr);
        !          1247:     // write to 0 to the HCCA DoneHead ptr so we won't look at it anymore.
        !          1248:     *(UInt32 *)(pOHCIUIMData->pHCCA + 0x84) = 0L;
        !          1249: 
        !          1250:     // Since we have a copy of the queue to process, we can let the host update it again.
        !          1251:     pOHCIRegisters->hcInterruptStatus = OSSwapInt32(kOHCIHcInterrupt_WDH);
        !          1252: 
        !          1253:     DoDoneQueueProcessing(pHCDoneTD, safeAction);
        !          1254:     return;
        !          1255: }
        !          1256: 
        !          1257: void AppleOHCI::finishPending()
        !          1258: {
        !          1259:     while(_pendingHead) {
        !          1260:         OHCIGeneralTransferDescriptorPtr next = _pendingHead->pLogicalNext;
        !          1261:         long bufferSizeRemaining = findBufferRemaining (_pendingHead);
        !          1262:         UInt32 transferStatus = (OSReadLittleInt32(&_pendingHead->flags, 0) &
        !          1263:                 kOHCIGTDControl_CC) >> kOHCIGTDControl_CCPhase;
        !          1264: 
        !          1265:         IOUSBCompletion completion;
        !          1266:         // zero out callback first then call it
        !          1267:         completion = _pendingHead->completion;
        !          1268:         _pendingHead->completion.action = nil;
        !          1269:         complete(completion,
        !          1270:                 TranslateStatusToUSBError(transferStatus),
        !          1271:                 bufferSizeRemaining);
        !          1272:         OHCIUIMDeallocateTD(_pendingHead);
        !          1273:         _pendingHead = next;
        !          1274:     }
        !          1275: }
        !          1276: 
        !          1277: UInt32 AppleOHCI::GetBandwidthAvailable()
        !          1278: {
        !          1279:     return pOHCIUIMData->isochBandwidthAvail;
        !          1280: }
        !          1281: 
        !          1282: UInt64 AppleOHCI::GetFrameNumber()
        !          1283: {
        !          1284: 
        !          1285:     UInt64     bigFrameNumber;
        !          1286:     UInt16     framenumber16;
        !          1287: 
        !          1288:     framenumber16 = OSReadLittleInt16(pOHCIUIMData->pHCCA, 0x80);
        !          1289:     bigFrameNumber = pOHCIUIMData->frameNumber + framenumber16;
        !          1290:     return bigFrameNumber;
        !          1291: }
        !          1292: 
        !          1293: UInt32 AppleOHCI::GetFrameNumber32()
        !          1294: {
        !          1295:     UInt16     framenumber16;
        !          1296:     UInt32     largishFrameNumber;
        !          1297:     framenumber16 = OSReadLittleInt16(pOHCIUIMData->pHCCA, 0x80);
        !          1298:     largishFrameNumber = ((UInt32)pOHCIUIMData->frameNumber) + framenumber16;
        !          1299:     return largishFrameNumber;
        !          1300: }
        !          1301: 
        !          1302: 
        !          1303: // #ifdef DEBUG
        !          1304: void AppleOHCI::dumpRegs(void)
        !          1305: {
        !          1306:     UInt32             lvalue;
        !          1307:     
        !          1308: #if 0
        !          1309:     /*device->*/configRead16(cwVendorID, &ivalue);
        !          1310:     /*device->*/configRead16(cwDeviceID, &ivalue);
        !          1311:     IOLog("OHCI: cwVendorID=%x  cwDeviceID=%x\n", ivalue, ivalue2);
        !          1312: #else
        !          1313:     lvalue = _device->configRead32(cwVendorID);
        !          1314:     IOLog("OHCI: cwVendorID=%lx\n", lvalue);
        !          1315: #endif
        !          1316:     lvalue = _device->configRead32(clClassCodeAndRevID);
        !          1317:     IOLog("OHCI: clClassCodeAndRevID=%lx\n", lvalue);
        !          1318:     lvalue = _device->configRead32(clHeaderAndLatency);
        !          1319:     IOLog("OHCI: clHeaderAndLatency=%lx\n", lvalue);
        !          1320:     lvalue = _device->configRead32(clBaseAddressZero);
        !          1321:     IOLog("OHCI: clBaseAddressZero=%lx\n", lvalue);
        !          1322:     lvalue = _device->configRead32(clBaseAddressOne);
        !          1323:     IOLog("OHCI: clBaseAddressOne=%lx\n", lvalue);
        !          1324:     lvalue = _device->configRead32(clExpansionRomAddr);
        !          1325:     IOLog("OHCI: clExpansionRomAddr=%lx\n", lvalue);
        !          1326:     lvalue = _device->configRead32(clLatGntIntPinLine);
        !          1327:     IOLog("OHCI: clLatGntIntPinLine=%lx\n", lvalue);
        !          1328:     lvalue = _device->configRead32(clLatGntIntPinLine+4);
        !          1329:     IOLog("OHCI: clLatGntIntPinLine+4=%lx\n", lvalue);
        !          1330:     lvalue = _device->configRead32(cwCommand);
        !          1331:     IOLog("OHCI: cwCommand=%lx\n", lvalue & 0x0000ffff);
        !          1332:     IOLog("OHCI: cwStatus=%lx\n", lvalue & 0xffff0000);
        !          1333: 
        !          1334:     lvalue = _device->configRead32(cwCommand);
        !          1335:     _device->configWrite32(cwCommand, lvalue);
        !          1336:     _device->configWrite32(cwCommand, (lvalue & 0xffff0000) |
        !          1337:                           (cwCommandEnableBusMaster |
        !          1338:                            cwCommandEnableMemorySpace));
        !          1339:     lvalue = _device->configRead32(cwCommand);
        !          1340:     IOLog("OHCI: cwCommand=%lx\n", lvalue & 0x0000ffff);
        !          1341:     IOLog("OHCI: cwStatus=%lx\n", lvalue & 0xffff0000);
        !          1342: 
        !          1343:     IOLog("OHCI: HcRevision=%lx\n",
        !          1344:           OSSwapInt32((pOHCIUIMData->pOHCIRegisters)->hcRevision));
        !          1345:     IOLog("      HcControl=%lx\n",
        !          1346:           OSSwapInt32((pOHCIUIMData->pOHCIRegisters)->hcControl));
        !          1347:     IOLog("      HcFmInterval=%lx\n",
        !          1348:           OSSwapInt32((pOHCIUIMData->pOHCIRegisters)->hcFmInterval));
        !          1349:     IOLog("      hcRhDescriptorA=%lx\n",
        !          1350:           OSSwapInt32((pOHCIUIMData->pOHCIRegisters)->hcRhDescriptorA));
        !          1351:     IOLog("      hcRhDescriptorB=%lx\n",
        !          1352:           OSSwapInt32((pOHCIUIMData->pOHCIRegisters)->hcRhDescriptorB));
        !          1353: }
        !          1354: // #endif /* DEBUG */
        !          1355: 
        !          1356: IOReturn TranslateStatusToUSBError(UInt32 status)
        !          1357: {
        !          1358:     static const UInt32 statusToErrorMap[] = {
        !          1359:         /* OHCI Error */     /* USB Error */
        !          1360:         /*  0 */               kIOReturnSuccess,
        !          1361:         /*  1 */               kIOUSBPipeStalled, //kUSBCRCErr,
        !          1362:         /*  2 */               kIOUSBPipeStalled, //kUSBBitstufErr,
        !          1363:         /*  3 */               kIOUSBPipeStalled, //kUSBDataToggleErr,
        !          1364:         /*  4 */               kIOUSBPipeStalled, //kUSBEndpointStallErr,
        !          1365:         /*  5 */               kIOReturnNotResponding, //kUSBNotRespondingErr,
        !          1366:         /*  6 */               kIOUSBPipeStalled, //kUSBPIDCheckErr,
        !          1367:         /*  7 */               kIOUSBPipeStalled, //kUSBWrongPIDErr,
        !          1368:         /*  8 */               kIOReturnOverrun,
        !          1369:         /*  9 */               kIOReturnUnderrun,
        !          1370:         /* 10 */               kIOReturnError, //kUSBRes1Err,
        !          1371:         /* 11 */               kIOReturnError, //kUSBRes2Err,
        !          1372:         /* 12 */               kIOReturnDMAError, //kUSBBufOvrRunErr,
        !          1373:         /* 13 */               kIOReturnDMAError, //kUSBBufUnderRunErr
        !          1374:     };
        !          1375: 
        !          1376:     if (status > 13) return(kIOReturnInternalError);
        !          1377:     return(statusToErrorMap[status]);
        !          1378: }

unix.superglobalmegacorp.com

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