|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.