|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: File: uslUIMInterface.c ! 27: ! 28: Contains: Interface between UIM and USL ! 29: ! 30: Version: Neptune 1.0 ! 31: ! 32: Copyright: � 1997-1998 by Apple Computer, Inc., all rights reserved. ! 33: ! 34: File Ownership: ! 35: ! 36: DRI: Barry Twycross ! 37: ! 38: Other Contact: xxx put other contact here xxx ! 39: ! 40: Technology: USB ! 41: ! 42: Writers: ! 43: ! 44: (DRF) Dave Falkenburg ! 45: (bwm) bruce merritt ! 46: (TC) Tom Clark ! 47: (CSS) Chas Spillar ! 48: (GG) Guillermo Gallegos ! 49: (DF) David Ferguson ! 50: (DKF) David Ferguson ! 51: (CJK) Craig Keithley ! 52: (BT) Barry Twycross ! 53: ! 54: Change History (most recent first): ! 55: ! 56: <USB81> 11/13/98 BT Delete hub device when removing bus. ! 57: <USB80> 11/11/98 DRF (CJK) Make sure to check ALL UIMs when polling before returning. ! 58: Allows us to type in Macsbug on the 3rd or 4th USB port. ! 59: <USB79> 10/22/98 BT Fix wrong status for deleted devices. ! 60: <USB78> 10/21/98 DF make probeEndpoint reentrant ! 61: <USB77> 10/5/98 BT Add root hub to probeendpoint ! 62: <USB76> 9/29/98 bwm BT: Fix UInt64 problems. ! 63: <USB75> 9/29/98 BT Use real frame timing ! 64: <USB74> 9/10/98 DF When removing a bus, clear all references to that bus. ! 65: <USB73> 9/9/98 BT Fix Isoc ! 66: <USB72> 9/9/98 BT Use correct number of frames calcing Isoc act count ! 67: <USB71> 9/3/98 BT Return immediate errors, fix param order ! 68: <USB70> 9/3/98 GG Changed Isoc interface to conform to dispatchtable interface. ! 69: <USB69> 9/1/98 BT FIx passing wrong parameter to UIM. Supermario compiler didn't ! 70: like it. ! 71: <USB68> 8/31/98 BT Add isoc pipes ! 72: <USB67> 8/25/98 BT Isoc name changes ! 73: <USB66> 8/24/98 BT Cope without #define for reserved4 ! 74: <USB65> 8/13/98 BT Add multibus support ! 75: <USB64> 8/12/98 BT Move root hub into UIM again. ! 76: <USB63> 8/12/98 DF (for BT) Finally fix fix ! 77: <USB62+> 8/12/98 DF (for BT) Finally fix fix ! 78: <USB62> 8/11/98 BT Issue bad UIM version status message ! 79: <USB61> 8/11/98 BT Fix check ! 80: <USB60> 8/11/98 BT Check UIM version ! 81: <USB59> 8/7/98 GG Tweaked interface to USL to be consistent with direction ! 82: parameter. ! 83: <USB58> 7/23/98 BT Don't corrupt flags if control failes ! 84: <USB57> 7/10/98 TC Back out previous revision - it was breaking Yosemite. ! 85: <USB56> 6/30/98 BT Move Root hub sim into UIM ! 86: <USB55> 6/24/98 DF fix problem that kept the UIM's suspend change reset proc from ! 87: being called. ! 88: <USB54> 6/14/98 DF Bad integration, left out the Check_UIM change. ! 89: <USB53> 6/14/98 DF Do a little more in USBRemoveBus, eliminate UIM moved checks ! 90: <USB52> 6/5/98 GG Changed uxbusref to USBBusRef. Changed GetFrameNumberImmediate ! 91: to return a UInt64 zero. ! 92: <USB51> 6/5/98 CSS Forgot to include Math64.h. ! 93: <USB50> 6/5/98 CSS Update to use U64Max() instead of -1 for the maximum 64 bit ! 94: value. ! 95: <USB49> 6/5/98 BT Use UIM time ! 96: <USB48> 5/20/98 BT Eliminate PB0 ! 97: <USB47> 5/5/98 GG Change Buffersize from short to unsigned long in BulkTransfer. ! 98: <USB46> 5/4/98 BT Fix pipe stall errors ! 99: <USB45> 4/30/98 BT Add real interrupt driven timer ! 100: <USB44> 4/29/98 BT Move common defines to USBpriv ! 101: <USB43> 4/28/98 BT Add bulk performance monitoring. ! 102: <USB42> 4/26/98 BT Add pipe state control ! 103: <USB41> 4/23/98 BT Add reset portsuspend change ! 104: <USB40> 4/22/98 DF Make USBAddBus return gracefully if more than one bus is ! 105: attached. ! 106: <USB39> 4/20/98 BT Add abort pipe ! 107: <USB38> 4/16/98 BT Fix unused variable ! 108: <USB37> 4/15/98 BT Add over current change reset ! 109: <USB36> 4/14/98 DF Add UIM polling for debugger support ! 110: <USB35> 4/14/98 BT Use EDDelete ! 111: <USB34> 4/9/98 BT Use USB.h ! 112: <33> 4/7/98 BT Fix act count in control transactions ! 113: <32> 4/6/98 BT Change w names ! 114: <31> 4/6/98 BT New param block names ! 115: <30> 4/2/98 BT eliminate obsolete function ! 116: <29> 3/24/98 BT Swap parameter order in open Int ED ! 117: <28> 3/18/98 BT Add reset enable change to root hub. ! 118: <27> 3/18/98 BT Add clear port enable change feature (Disabled waiting UIM ! 119: support) ! 120: <26> 3/11/98 BT Int simulation for root hub. More debugs for moving UIM. ! 121: <25> 3/5/98 BT track down changing UIM ! 122: <24> 3/5/98 BT Add interrupt pipe ! 123: <23> 2/23/98 BT Fix error recovery ! 124: <22> 2/19/98 BT Cut out call to process done Queue in UIM. ! 125: <21> 2/16/98 BT Fix calling processdone queue and timer too often. ! 126: <USB20> 2/11/98 DKF Add back in ProcessDoneQueue if we're at task time ! 127: <19> 2/8/98 BT Take out process done q in send control. ! 128: <18> 2/4/98 BT Fix uslControlPacket to have errors. Add mnore support for ! 129: usbProbe ! 130: <17> 2/2/98 BT Add bulk stuff ! 131: <16> 1/29/98 BT Use symbols for the flags fields used ! 132: <15> 1/26/98 BT Mangle names after design review, finish up ! 133: <14> 1/26/98 BT Mangle names after design review ! 134: <13> 1/26/98 BT Hack in clear enpoint stall ! 135: <12> 1/21/98 BT Change hardware status codes ! 136: <11> 1/20/98 BT Unwrapping root hub ! 137: <10> 1/19/98 BT More root hub sim ! 138: <9> 1/15/98 BT Do root hub simulation. ! 139: <8> 1/15/98 CJK Change include of USL.h to USBServicesLib.h ! 140: <7> 1/14/98 BT Implimenting Interrupt transactions ! 141: <6> 1/13/98 BT Change uslPacket to uslControlPacket ! 142: <5> 12/22/97 BT StartRootHub moving to USL ! 143: <4> 12/19/97 BT TAking out dependancy on UIM ! 144: <3> 12/19/97 BT UIM now a Shared lib ! 145: */ ! 146: ! 147: #include "../USB.h" ! 148: #include "../USBpriv.h" ! 149: //#include <Math64.h" ! 150: ! 151: #include "../uimpriv.h" ! 152: #include "uslpriv.h" ! 153: //#include "../MonaUSBPriv.h" ! 154: ! 155: ! 156: ! 157: enum{ ! 158: kSetupSent = 0x01, ! 159: kDataSent = 0x02, ! 160: kStatusSent = 0x04, ! 161: kSetupBack = 0x10, ! 162: kDataBack = 0x20, ! 163: kStatusBack = 0x40 ! 164: }; ! 165: ! 166: enum{ ! 167: kMaxBus = 16 ! 168: }; ! 169: static struct UIMPluginDispatchTable *UIMPlugIn[kMaxBus], *pending[kMaxBus]; ! 170: static USBBusRef UIMBus[kMaxBus]; ! 171: static USBDeviceRef rootHubRefs[kMaxBus]; ! 172: ! 173: ! 174: void UIMSetRootHubRef(UInt32 bus, USBDeviceRef ref) ! 175: { ! 176: if(UIMPlugIn[bus] == nil) ! 177: { ! 178: USBExpertStatus(0,"USL - Bad bus passed to root hub ref", 0); ! 179: } ! 180: else ! 181: { ! 182: rootHubRefs[bus] = ref; ! 183: } ! 184: } ! 185: ! 186: #define CHECK_UIM 0 ! 187: #if CHECK_UIM ! 188: static void checkUIMMoved(UInt32 bus, void ***UIM,void **UIM1,void **current) ! 189: { ! 190: ! 191: static void *UIMp; ! 192: ! 193: if(UIMPlugIn[bus] != nil) ! 194: { ! 195: if(UIMp == nil) ! 196: { ! 197: UIMp = (void *)UIMPlugIn[bus]; ! 198: } ! 199: else ! 200: { ! 201: if(UIMp != (void *)UIMPlugIn[bus]) ! 202: { ! 203: //DebugStr("UIM Pointer changed, tell barry, you're hosed"); ! 204: USBExpertStatus(0,"USL - UIM Pointer changed, tell barry, you're hosed", 0); ! 205: } ! 206: } ! 207: ! 208: if(*UIM == nil) ! 209: { ! 210: *UIM = (void *)*current; ! 211: *UIM1 = **UIM; ! 212: } ! 213: else ! 214: { ! 215: if(*UIM != (void *)*current) ! 216: { ! 217: //DebugStr("UIM moved, tell barry, you're hosed"); ! 218: USBExpertStatus(0,"USL - UIM moved, tell barry, you're hosed", 0); ! 219: } ! 220: ! 221: if(*UIM1 != **UIM) ! 222: { ! 223: //DebugStr("UIM 1 moved, tell barry, you're hosed"); ! 224: USBExpertStatus(0,"USL - UIM 1 moved, tell barry, you're hosed", 0); ! 225: } ! 226: } ! 227: } ! 228: else ! 229: { ! 230: SysDebugStr("Bad bus"); ! 231: USBExpertStatus(0,"USL - bad bus passed to UIM interface", bus); ! 232: } ! 233: } ! 234: #endif ! 235: ! 236: OSStatus USBAddBus( ! 237: void *regEntry, ! 238: void *UIM, /* GG to specifiy */ ! 239: USBBusRef inBus) /* from TC */ ! 240: { ! 241: ! 242: UInt32 bus= ! 243: #if CHECK_UIM ! 244: 5 ! 245: #else ! 246: 0 ! 247: #endif ! 248: ; ! 249: ! 250: regEntry = 0; /* not used */ ! 251: ! 252: printf("USBAddBus:Adding bus=%d\n",bus); ! 253: while( (UIMPlugIn[bus] != nil) || (pending[bus] != nil) ) ! 254: { ! 255: if(bus++ >= kMaxBus) ! 256: { ! 257: return(-1); ! 258: } ! 259: } ! 260: USBExpertStatus(-1, "USL - Adding bus index:", bus); ! 261: pending[bus] = UIM; ! 262: if(pending[bus]->pluginVersion != kUIMPluginTableVersion) ! 263: { ! 264: USBExpertStatus(-1, "UIM is wrong versions, bus not added", pending[bus]->pluginVersion); ! 265: pending[bus] = nil; ! 266: return(kUSBPBVersionError); ! 267: } ! 268: ! 269: ! 270: UIMBus[bus] = inBus; ! 271: ! 272: printf("USBAddBus:starting roothub\n"); ! 273: StartRootHub(bus); ! 274: printf("USBAddBus:roothub complete\n"); ! 275: return(noErr); ! 276: } ! 277: ! 278: OSStatus UIMResetRootHub(UInt32 bus) ! 279: { ! 280: if(pending[bus] == nil) ! 281: { ! 282: SysDebugStr("Bad bus for reset"); ! 283: USBExpertStatus(0,"USL - bad bus passed to reset", bus); ! 284: } ! 285: ! 286: if(pending[bus] != nil) ! 287: { ! 288: OSStatus ret; ! 289: ret = (*pending[bus]->uimResetRootHubProc)(UIMBus[bus]); ! 290: if(ret != noErr) ! 291: { ! 292: return(ret); ! 293: } ! 294: UIMPlugIn[bus] = pending[bus]; ! 295: pending[bus] = nil; ! 296: } ! 297: return(-1); ! 298: } ! 299: ! 300: OSStatus USBRemoveBus( ! 301: USBBusRef inBus) /* from TC */ ! 302: { ! 303: UInt32 bus = 0; ! 304: USBPB pb; ! 305: ! 306: while(inBus != UIMBus[bus]) ! 307: { ! 308: if(bus++ >= kMaxBus) ! 309: { ! 310: return(kUSBNotFound); ! 311: } ! 312: } ! 313: USBExpertStatus(-1, "USL - Removing bus index:", bus); ! 314: ! 315: pb.pbLength = sizeof(pb); ! 316: pb.pbVersion = kUSBCurrentHubPB; ! 317: pb.usbStatus = noErr; ! 318: pb.usbFlags = 0; ! 319: pb.usbReference = rootHubRefs[bus]; ! 320: pb.usbCompletion = kUSBNoCallBack; ! 321: ! 322: if(immediateError(USBHubDeviceRemoved(&pb))) ! 323: { ! 324: USBExpertStatus(pb.usbReference, "USL - remove bus, Failed to remove root hub", pb.usbReference); ! 325: } ! 326: USBExpertRemoveDeviceDriver(rootHubRefs[bus]); ! 327: rootHubRefs[bus] = 0; ! 328: ! 329: UIMPlugIn[bus] = nil; ! 330: UIMBus[bus] = 0; ! 331: pending[bus] = nil; ! 332: ! 333: return(noErr); ! 334: } ! 335: ! 336: void UIMPollRootHubSim(void) ! 337: { ! 338: #if CHECK_UIM ! 339: static void **UIM, *UIM1; ! 340: #endif ! 341: UInt32 bus = 0; ! 342: ! 343: for(bus = 0; bus<kMaxBus; bus++) ! 344: { ! 345: if(UIMPlugIn[bus] != nil) ! 346: { ! 347: #if CHECK_UIM ! 348: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimPollRootHubSim); ! 349: #endif ! 350: ! 351: (*UIMPlugIn[bus]->uimPollRootHubSim)(UIMBus[bus]); ! 352: } ! 353: } ! 354: } ! 355: ! 356: OSStatus USLPolledProcessDoneQueue(void) ! 357: { ! 358: #if CHECK_UIM ! 359: static void **UIM, *UIM1; ! 360: #endif ! 361: UInt32 bus = 0; ! 362: OSStatus myErr; ! 363: ! 364: for(bus = 0; bus<kMaxBus; bus++) ! 365: { ! 366: if(UIMPlugIn[bus] != nil) ! 367: { ! 368: #if CHECK_UIM ! 369: static void **UIM, *UIM1; ! 370: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimProcessDoneQueueProc); ! 371: #endif ! 372: myErr = (*UIMPlugIn[bus]->uimProcessDoneQueueProc)(); ! 373: } ! 374: } ! 375: return(noErr); ! 376: } ! 377: ! 378: ! 379: ! 380: ! 381: UInt64 UIMGetCurrentFrame(UInt32 bus) ! 382: { ! 383: #if CHECK_UIM ! 384: static void **UIM, *UIM1; ! 385: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimGetCurrentFrameNumberProc); ! 386: #endif ! 387: ! 388: if(UIMPlugIn[bus] != nil) ! 389: { ! 390: return(*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)(); ! 391: } ! 392: return(U64SetU(0)); ! 393: } ! 394: ! 395: UInt32 UIMGetAFrame(void) ! 396: { ! 397: union{ ! 398: UInt64 u; ! 399: UnsignedWide s; ! 400: }frame; ! 401: static UInt32 bus = 0; ! 402: ! 403: if(UIMPlugIn[bus] != nil) ! 404: { ! 405: frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)(); ! 406: return(frame.s.lo); ! 407: } ! 408: ! 409: for(bus = 0; bus<kMaxBus; bus++) ! 410: { ! 411: if(UIMPlugIn[bus] != nil) ! 412: { ! 413: frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)(); ! 414: return(frame.s.lo); ! 415: } ! 416: } ! 417: return(0); ! 418: } ! 419: ! 420: ! 421: OSStatus UIMControlEDCreate( ! 422: UInt32 bus, ! 423: UInt8 functionNumber, ! 424: UInt8 endpointNumber, ! 425: UInt16 maxPacketSize, ! 426: UInt8 speed) ! 427: { ! 428: #if CHECK_UIM ! 429: static void **UIM, *UIM1; ! 430: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlEndpointProc); ! 431: #endif ! 432: ! 433: if(UIMPlugIn[bus] != nil) ! 434: { ! 435: return(*UIMPlugIn[bus]->uimCreateControlEndpointProc)( ! 436: functionNumber, ! 437: endpointNumber, ! 438: maxPacketSize, ! 439: speed); ! 440: } ! 441: return(-1); ! 442: } ! 443: ! 444: OSStatus UIMInterruptEDCreate( ! 445: UInt32 bus, ! 446: UInt8 functionNumber, ! 447: UInt8 endpointNumber, ! 448: UInt16 maxPacketSize, ! 449: UInt8 speed) ! 450: { ! 451: #if CHECK_UIM ! 452: static void **UIM, *UIM1; ! 453: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptEndpointProc); ! 454: #endif ! 455: ! 456: if(UIMPlugIn[bus] != nil) ! 457: { ! 458: return(*UIMPlugIn[bus]->uimCreateInterruptEndpointProc)( ! 459: functionNumber, ! 460: endpointNumber, ! 461: speed, ! 462: maxPacketSize, ! 463: 8, // Polling rate ! 464: 0); // Reserve bandwidth?? ! 465: } ! 466: return(-1); ! 467: } ! 468: ! 469: OSStatus UIMIsocEDCreate( ! 470: UInt32 bus, ! 471: UInt8 functionNumber, ! 472: UInt8 endpointNumber, ! 473: UInt8 direction, ! 474: UInt16 maxPacketSize) ! 475: { ! 476: #if CHECK_UIM ! 477: static void **UIM, *UIM1; ! 478: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochEndpointProc); ! 479: #endif ! 480: ! 481: if(UIMPlugIn[bus] != nil) ! 482: { ! 483: return(*UIMPlugIn[bus]->uimCreateIsochEndpointProc)( ! 484: functionNumber, ! 485: endpointNumber, ! 486: maxPacketSize, ! 487: direction); ! 488: } ! 489: return(-1); ! 490: } ! 491: ! 492: ! 493: OSStatus UIMBulkEDCreate( ! 494: UInt32 bus, ! 495: UInt8 functionNumber, ! 496: UInt8 endpointNumber, ! 497: UInt8 direction, ! 498: UInt8 maxPacketSize) ! 499: { ! 500: #if CHECK_UIM ! 501: static void **UIM, *UIM1; ! 502: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkEndpointProc); ! 503: #endif ! 504: ! 505: if(UIMPlugIn[bus] != nil) ! 506: { ! 507: return(*UIMPlugIn[bus]->uimCreateBulkEndpointProc)( ! 508: functionNumber, ! 509: endpointNumber, ! 510: direction, ! 511: maxPacketSize); ! 512: } ! 513: return(-1); ! 514: } ! 515: ! 516: OSStatus UIMControlTransfer( ! 517: UInt32 bus, ! 518: UInt32 refcon, ! 519: CallBackFuncPtr handler, ! 520: UInt32 CBP, ! 521: Boolean bufferRounding, ! 522: short functionNumber, ! 523: short endpointNumber, ! 524: short bufferSize, ! 525: short direction) ! 526: { ! 527: #if CHECK_UIM ! 528: static void **UIM, *UIM1; ! 529: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlTransferProc); ! 530: #endif ! 531: ! 532: if(UIMPlugIn[bus] != nil) ! 533: { ! 534: return(*UIMPlugIn[bus]->uimCreateControlTransferProc)( ! 535: refcon, ! 536: handler, ! 537: CBP, ! 538: bufferRounding, ! 539: functionNumber, ! 540: endpointNumber, ! 541: bufferSize, ! 542: direction); ! 543: } ! 544: return(-1); ! 545: } ! 546: ! 547: #if 0 ! 548: #include "TextUtils.h" ! 549: static void AddNum(UInt8 *s1, UInt32 num) ! 550: { ! 551: UInt8 number[20]; ! 552: NumToString(num, number); ! 553: AddString(s1, number); ! 554: } ! 555: ! 556: static void AddString(UInt8 *s1, UInt8 *s2) ! 557: { ! 558: int count; ! 559: count = 255-*s1; ! 560: if(count == 0) ! 561: { ! 562: return; ! 563: } ! 564: if(count > *s2) ! 565: { ! 566: count = *s2; ! 567: } ! 568: usb_BlockMoveData(&s2[1], &s1[*s1]+1, s2[0]); ! 569: *s1+=*s2; ! 570: } ! 571: ! 572: static void DebugNum(UInt8 *str, UInt32 num, Boolean stop) ! 573: { ! 574: UInt8 strBuf[256]; ! 575: ! 576: AddString(strBuf, str); ! 577: AddString(strBuf, " : "); ! 578: AddNum(strBuf, num); ! 579: AddString(strBuf, " 100;g"); ! 580: DebugStr(strBuf); ! 581: if(stop) ! 582: { ! 583: SysDebugStr("This seems bad, tell barry about it, cmd-g to continue"); ! 584: } ! 585: } ! 586: #endif ! 587: OSStatus UIMControlEDDelete( ! 588: UInt32 bus, ! 589: short functionNumber, ! 590: short endpointNumber) ! 591: { ! 592: #if CHECK_UIM ! 593: static void **UIM, *UIM1; ! 594: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteControlEndpointProc); ! 595: #endif ! 596: ! 597: if(UIMPlugIn[bus] != nil) ! 598: { ! 599: return(*UIMPlugIn[bus]->uimDeleteControlEndpointProc)(functionNumber, endpointNumber); ! 600: } ! 601: else ! 602: { ! 603: USBExpertStatus(0,"USL -control ED delete failed", bus); ! 604: } ! 605: return(-1); ! 606: } ! 607: ! 608: OSStatus UIMEDDelete( ! 609: UInt32 bus, ! 610: short functionNumber, ! 611: short endpointNumber, ! 612: short direction) ! 613: { ! 614: #if CHECK_UIM ! 615: static void **UIM, *UIM1; ! 616: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteEndpointProc); ! 617: #endif ! 618: ! 619: if(UIMPlugIn[bus] != nil) ! 620: { ! 621: return(*UIMPlugIn[bus]->uimDeleteEndpointProc)(functionNumber, endpointNumber, direction); ! 622: } ! 623: return(-1); ! 624: } ! 625: ! 626: OSStatus UIMBulkTransfer( ! 627: UInt32 bus, ! 628: UInt32 refcon, ! 629: CallBackFuncPtr handler, ! 630: UInt32 CBP, ! 631: Boolean bufferRounding, ! 632: short functionNumber, ! 633: short endpointNumber, ! 634: UInt32 bufferSize, ! 635: short direction) ! 636: { ! 637: #if CHECK_UIM ! 638: static void **UIM, *UIM1; ! 639: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkTransferProc); ! 640: #endif ! 641: ! 642: if(UIMPlugIn[bus] != nil) ! 643: { ! 644: return(*UIMPlugIn[bus]->uimCreateBulkTransferProc)( ! 645: refcon, ! 646: handler, ! 647: CBP, ! 648: bufferRounding, ! 649: functionNumber, ! 650: endpointNumber, ! 651: bufferSize, ! 652: direction); ! 653: } ! 654: return(-1); ! 655: } ! 656: ! 657: OSStatus UIMIntTransfer( ! 658: UInt32 bus, ! 659: short functionNumber, ! 660: short endpointNumber, ! 661: UInt32 refcon, ! 662: CallBackFuncPtr handler, ! 663: UInt32 CBP, ! 664: Boolean bufferRounding, ! 665: short bufferSize) ! 666: { ! 667: #if CHECK_UIM ! 668: static void **UIM, *UIM1; ! 669: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptTransferProc); ! 670: #endif ! 671: ! 672: if(UIMPlugIn[bus] != nil) ! 673: { ! 674: return(*UIMPlugIn[bus]->uimCreateInterruptTransferProc)( ! 675: functionNumber, ! 676: endpointNumber, ! 677: refcon, ! 678: handler, ! 679: CBP, ! 680: bufferRounding, ! 681: bufferSize); ! 682: } ! 683: return(-1); ! 684: } ! 685: ! 686: OSStatus UIMIsocTransfer( ! 687: UInt32 bus, ! 688: short functionNumber, ! 689: short endpointNumber, ! 690: short direction, ! 691: UInt32 frameStart, ! 692: UInt32 refcon, ! 693: IsocCallBackFuncPtr handler, ! 694: void *buffer, ! 695: UInt32 numFrames, ! 696: USBIsocFrame *frames) ! 697: { ! 698: #if CHECK_UIM ! 699: static void **UIM, *UIM1; ! 700: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochTransferProc); ! 701: #endif ! 702: union{ ! 703: UInt64 u; ! 704: UnsignedWide s; ! 705: }startFrame; ! 706: ! 707: if(UIMPlugIn[bus] != nil) ! 708: { ! 709: startFrame.u = UIMGetCurrentFrame(bus); ! 710: startFrame.s.lo = frameStart; /* this needs to be more sophisticated */ ! 711: ! 712: return(*UIMPlugIn[bus]->uimCreateIsochTransferProc)( ! 713: functionNumber, ! 714: endpointNumber, ! 715: refcon, ! 716: direction, ! 717: handler, ! 718: startFrame.u, ! 719: (UInt32)buffer, ! 720: numFrames, ! 721: frames); ! 722: } ! 723: return(-1); ! 724: } ! 725: /* ! 726: typedef CALLBACK_API_C( OSStatus , UIMCreateIsochTransferProcPtr )( ! 727: short functionAddress, ! 728: short endpointNumber, ! 729: UInt8 direction, ! 730: short refcon, ! 731: UInt32 pIsochHandler, ! 732: UInt64 frameStart, ! 733: UInt32 pBufferStart, ! 734: UInt32 frameCount, ! 735: USBIsocFrame *pFrames, ! 736: UInt32 pStatus); ! 737: */ ! 738: OSStatus UIMClearEndPointStall( ! 739: UInt32 bus, ! 740: short functionNumber, ! 741: short endpointNumber, ! 742: short direction) ! 743: { ! 744: #if CHECK_UIM ! 745: static void **UIM, *UIM1; ! 746: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimClearEndPointStallProc); ! 747: #endif ! 748: ! 749: if(UIMPlugIn[bus] != nil) ! 750: { ! 751: return(*UIMPlugIn[bus]->uimClearEndPointStallProc)(functionNumber, endpointNumber, direction); ! 752: } ! 753: return(-1); ! 754: } ! 755: ! 756: OSStatus UIMAbortEndpoint( ! 757: UInt32 bus, ! 758: short functionNumber, ! 759: short endpointNumber, ! 760: short direction) ! 761: { ! 762: #if CHECK_UIM ! 763: static void **UIM, *UIM1; ! 764: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimAbortEndpointProc); ! 765: #endif ! 766: ! 767: if(UIMPlugIn[bus] != nil) ! 768: { ! 769: return(*UIMPlugIn[bus]->uimAbortEndpointProc)( ! 770: functionNumber, ! 771: endpointNumber, ! 772: direction); ! 773: } ! 774: return(-1); ! 775: } ! 776: ! 777: ! 778: static OSStatus doUSLStatus(OSStatus status, USBReference ref) ! 779: { ! 780: if(status != noErr) ! 781: { ! 782: if(status == EDDeleteErr) ! 783: { ! 784: status = kUSBAbortedError; ! 785: } ! 786: else if(status == bandWidthFullErr) ! 787: { ! 788: status = kUSBNoBandwidthError; ! 789: } ! 790: else if(status == returnedErr) ! 791: { ! 792: status = kUSBAbortedError; ! 793: } ! 794: else ! 795: { ! 796: if( (status > 0) && (status < 16)) ! 797: { ! 798: /* As ferg points out all host contoller errors stall the pipe */ ! 799: uslSetPipeStall(ref); ! 800: } ! 801: status = kUSBLinkErr+status; ! 802: #if 0 ! 803: if( (status == kUSBCRCErr) || ! 804: (status == kUSBBitstufErr) || ! 805: (status == kUSBDataToggleErr) || ! 806: (status == kUSBEndpointStallErr) || ! 807: (status == kUSBNotRespondingErr) || ! 808: (status == kUSBPIDCheckErr) || ! 809: (status == kUSBWrongPIDErr) ) ! 810: { ! 811: uslSetPipeStall(ref); ! 812: } ! 813: #endif ! 814: } ! 815: } ! 816: return(status); ! 817: } ! 818: ! 819: ! 820: static void intPktHandler(long refCon, OSStatus status, short shortfall) ! 821: { ! 822: USBPB *pb; ! 823: ! 824: if(refCon == 0) ! 825: { ! 826: return; ! 827: } ! 828: ! 829: pb = (void *)refCon; ! 830: ! 831: status = doUSLStatus(status, pb->usbReference); ! 832: ! 833: pb->usbStatus = status; ! 834: pb->usbActCount = pb->usbReqCount - shortfall; ! 835: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack)) ! 836: (*pb->usbCompletion)(pb); ! 837: } ! 838: ! 839: static void bulkPktHandler(long refCon, OSStatus status, short shortfall) ! 840: { ! 841: USBPB *pb; ! 842: ! 843: if(refCon == 0) ! 844: { ! 845: return; ! 846: } ! 847: ! 848: pb = (void *)refCon; ! 849: ! 850: status = doUSLStatus(status, pb->usbReference); ! 851: ! 852: pb->usbStatus = status; ! 853: if(shortfall > pb->usbReqCount) ! 854: { ! 855: pb->usbActCount = 0; ! 856: } ! 857: else ! 858: { ! 859: pb->usbActCount = pb->usbReqCount - shortfall; ! 860: } ! 861: ! 862: if(pb->usbFlags) ! 863: { ! 864: resolvePerformance(pb); ! 865: } ! 866: ! 867: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack)) ! 868: (*pb->usbCompletion)(pb); ! 869: } ! 870: ! 871: static void isocPktHandler(long refCon, OSStatus status, USBIsocFrame *pFrames) ! 872: { ! 873: USBPB *pb; ! 874: OSStatus aggregate = noErr; ! 875: UInt32 actCount = 0, frame; ! 876: ! 877: if(refCon == 0) ! 878: { ! 879: return; ! 880: } ! 881: ! 882: pb = (void *)refCon; ! 883: ! 884: actCount = 0; ! 885: for(frame = 0; frame < pb->usb.isoc.NumFrames; frame++) ! 886: { ! 887: actCount += pFrames[frame].frActCount; ! 888: if(pFrames[frame].frStatus != noErr) ! 889: { ! 890: aggregate = pFrames[frame].frStatus; ! 891: } ! 892: } ! 893: pb->usbActCount = actCount; ! 894: ! 895: if(status == noErr) ! 896: { ! 897: pb->usbStatus = aggregate; ! 898: } ! 899: else ! 900: { ! 901: pb->usbStatus = status; ! 902: } ! 903: if(pb->usbStatus != noErr) ! 904: { ! 905: pb->usbStatus = kUSBLinkErr+pb->usbStatus; ! 906: } ! 907: ! 908: if ( (pb->usbCompletion != nil) && (pb->usbCompletion != kUSBNoCallBack)) ! 909: { ! 910: (*pb->usbCompletion)(pb); ! 911: } ! 912: } ! 913: ! 914: static void ctlPktHandler(long refCon, OSStatus status, short shortfall) ! 915: { ! 916: UInt8 sent, back, todo; ! 917: USBPB *pb; ! 918: Boolean callBackTIme; ! 919: UInt32 bus; ! 920: ! 921: if(refCon == 0) ! 922: { ! 923: return; ! 924: } ! 925: ! 926: ! 927: pb = (void *)(refCon & ~1); ! 928: callBackTIme = ((refCon & 1) != 0); ! 929: ! 930: sent = (pb->reserved1 &0xf) << 4; ! 931: back = pb->reserved1 &0xf0; ! 932: todo = sent ^ back; /* thats xor */ ! 933: ! 934: if((todo & kSetupBack) != 0) ! 935: { ! 936: pb->reserved1 |= kSetupBack; ! 937: ! 938: } ! 939: else if((todo & kDataBack) != 0) ! 940: { /* This is the data transport phase, so this is the interesting one */ ! 941: pb->reserved1 |= kDataBack; ! 942: pb->usbActCount = pb->usbReqCount - shortfall; ! 943: } ! 944: else if((todo & kStatusBack) != 0) ! 945: { ! 946: pb->reserved1 |= kStatusBack; ! 947: ! 948: } ! 949: else ! 950: { ! 951: USBExpertStatus(-1, "Spare transactions, This seems to be harmless", 0); ! 952: } ! 953: ! 954: back = pb->reserved1 &0xf0; ! 955: todo = sent ^ back; /* thats xor */ ! 956: ! 957: if( (status != noErr) && (status != returnedErr) ) ! 958: { ! 959: UInt8 addr, endpt; ! 960: addr = ( (pb->usbFlags) &kUSLAddrMask) >> kUSLAddrShift; ! 961: endpt = ( (pb->usbFlags &kUSLEndpMask) >> kUSLEndpShift); ! 962: bus = ( (pb->usbFlags &kUSLBusMask) >> kUSLBusShift); ! 963: ! 964: pb->usbStatus = doUSLStatus(status, pb->usbReference); ! 965: if(endpt == 0) ! 966: { ! 967: UIMClearEndPointStall(bus, addr, endpt, 0); ! 968: } ! 969: ! 970: } ! 971: ! 972: ! 973: if( callBackTIme || (todo == 0) ) ! 974: { ! 975: if( !callBackTIme || (todo != 0) ) /* One but not the other */ ! 976: { ! 977: USBExpertStatus(-1, "UIM Interface odd completion", 0); ! 978: } ! 979: pb->usbFlags &= ~(kUSLAddrMask|kUSLEndpMask|kUSLBusMask); ! 980: ! 981: if(status == noErr) ! 982: { ! 983: if(pb->usbStatus != kUSBPending) ! 984: { ! 985: USBExpertStatus(-1, "UIM Interface odd status", 0); ! 986: } ! 987: pb->usbStatus = noErr; ! 988: } ! 989: ! 990: pb->usb.cntl.WIndex = USBToHostWord(pb->usb.cntl.WIndex); ! 991: pb->usb.cntl.WValue = USBToHostWord(pb->usb.cntl.WValue); ! 992: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack)) ! 993: (*pb->usbCompletion)(pb); ! 994: } ! 995: } ! 996: ! 997: OSStatus usbIsocPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction) ! 998: { ! 999: OSStatus err; ! 1000: ! 1001: pb->usbStatus = noErr; ! 1002: ! 1003: err = UIMIsocTransfer(bus, ! 1004: address /* address */, ! 1005: endpoint /* endpoint */, ! 1006: direction /* in or out */, ! 1007: pb->usbFrame /* starting frame */, ! 1008: (UInt32)pb /* refcon */, ! 1009: isocPktHandler, ! 1010: pb->usbBuffer /* buffer */, ! 1011: pb->usb.isoc.NumFrames, ! 1012: pb->usb.isoc.FrameList ! 1013: ); ! 1014: ! 1015: #if 0 ! 1016: if(err != noErr) ! 1017: { ! 1018: isocPktHandler((UInt32)pb, err, pb->usb.isoc.FrameList); ! 1019: } ! 1020: #else ! 1021: return(err); ! 1022: #endif ! 1023: ! 1024: } ! 1025: ! 1026: OSStatus usbIntPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction) ! 1027: { ! 1028: OSStatus err; ! 1029: direction = 0; /* Not used */ ! 1030: ! 1031: pb->usbStatus = noErr; ! 1032: kprintf("usbIntPacket:Calling UIMIntTransfer:addr=%d,ep=%d,reqcount=%d\n",address,endpoint,pb->usbReqCount); ! 1033: err = UIMIntTransfer(bus, ! 1034: address, ! 1035: endpoint, ! 1036: (UInt32)pb /* refcon */, ! 1037: intPktHandler, ! 1038: (UInt32)pb->usbBuffer /* buffer */, ! 1039: true /* short packets OK */, ! 1040: pb->usbReqCount /* buffer size */); ! 1041: kprintf("usbIntPacket:UIMTransfer returned err=%d\n",err); ! 1042: ! 1043: return(err); ! 1044: } ! 1045: ! 1046: ! 1047: OSStatus usbBulkPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction) ! 1048: { ! 1049: OSStatus err; ! 1050: ! 1051: pb->usbStatus = noErr; ! 1052: ! 1053: err = UIMBulkTransfer(bus, ! 1054: (UInt32)pb /* refcon */, ! 1055: bulkPktHandler, ! 1056: (UInt32)pb->usbBuffer /* buffer */, ! 1057: true /* short packets OK */, ! 1058: address /* address */, ! 1059: endpoint /* endpoint */, ! 1060: pb->usbReqCount /* buffer size */, ! 1061: direction /* in or out */); ! 1062: ! 1063: return(err); ! 1064: } ! 1065: ! 1066: #define kUSBSetup kUSBNone ! 1067: ! 1068: OSStatus usbControlPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint) ! 1069: { ! 1070: OSStatus err; ! 1071: short dirn; ! 1072: ! 1073: ! 1074: if( ((UInt32)pb &1) != 0) ! 1075: { ! 1076: USBExpertStatus(-1, "Missaligned PB", 0); ! 1077: } ! 1078: ! 1079: /* Remeber address and endpoint here for later */ ! 1080: pb->usbFlags |= (address << kUSLAddrShift)+(endpoint << kUSLEndpShift)+(bus << kUSLBusShift); ! 1081: ! 1082: do{ ! 1083: pb->reserved1 = 0; /* stage pointer */ ! 1084: pb->usbStatus = kUSBPending; ! 1085: pb->usbActCount = 0; ! 1086: ! 1087: pb->reserved1 |= kSetupSent; ! 1088: //kprintf("usbControlPacket:addr=%d,ep=%d\n",address,endpoint); ! 1089: err = UIMControlTransfer(bus, ! 1090: (UInt32)pb/* refcon */, ! 1091: ctlPktHandler, ! 1092: (UInt32)&pb->usb.cntl.BMRequestType /* packet */, ! 1093: true /* short packets OK */, ! 1094: address /* address */, ! 1095: endpoint /* endpoint */, ! 1096: 8 /* packet size */, ! 1097: kUSBSetup /* setup */); ! 1098: //kprintf("usbControlPacket:After first call refcon(pb)=0x%x,err=%d\n",pb,err); ! 1099: if(err != noErr) ! 1100: { ! 1101: pb->usbFlags = 0; ! 1102: USBExpertStatus(-1, "Control packet 1 error", err); ! 1103: break; ! 1104: } ! 1105: ! 1106: dirn = ((pb->usb.cntl.BMRequestType & 0x80) == 0)?kUSBOut:kUSBIn; ! 1107: if(pb->usb.cntl.reserved4 != 0) ! 1108: { ! 1109: pb->reserved1 |= kDataSent; ! 1110: err = UIMControlTransfer(bus, ! 1111: (UInt32)pb /* refcon */, ! 1112: ctlPktHandler, ! 1113: (UInt32)pb->usbBuffer /* buffer */, ! 1114: true /* short packets OK */, ! 1115: address /* address */, ! 1116: endpoint /* endpoint */, ! 1117: pb->usbReqCount /* buffer size */, ! 1118: dirn /* in or out */); ! 1119: if(err != noErr) ! 1120: { ! 1121: USBExpertStatus(-1, "Control packet 2 error", err); ! 1122: break; ! 1123: } ! 1124: //kprintf("usbControlPacket:After second(data phase)call refcon(pb)=0x%x,err=%d\n",pb,err); ! 1125: ! 1126: } ! 1127: ! 1128: dirn = kUSBOut+kUSBIn - dirn; ! 1129: ! 1130: pb->reserved1 |= kStatusSent; ! 1131: err = UIMControlTransfer(bus, ! 1132: (UInt32)pb | 1 /* refcon, with marker */, ! 1133: ctlPktHandler, ! 1134: 0 /* buffer, for no data transfer */, ! 1135: true /* short packets OK */, ! 1136: address /* address */, ! 1137: endpoint /* endpoint */, ! 1138: 0 /* buffer size */, ! 1139: dirn /* in or out */); ! 1140: ! 1141: //kprintf("usbControlPacket:After third(status phase)call refcon(pb)=0x%x,err=%d\n",(UInt32)pb | 1,err); ! 1142: if(err != noErr) ! 1143: { ! 1144: USBExpertStatus(-1, "Control packet 3 error", err); ! 1145: } ! 1146: ! 1147: }while(0); ! 1148: ! 1149: return(err); ! 1150: } ! 1151: ! 1152: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint); ! 1153: ! 1154: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint) ! 1155: { ! 1156: OSStatus err; ! 1157: UInt32 bus; ! 1158: ! 1159: if (address > 127) ! 1160: { ! 1161: if(rootHubRefs[255-address] == 0) ! 1162: { ! 1163: return(kUSBUnknownDeviceErr); ! 1164: } ! 1165: address = rootHubRefs[255-address] & 0x7f; ! 1166: } ! 1167: ! 1168: if ((bus = uslDeviceAddrToBus(address)) >= kMaxBus) ! 1169: { ! 1170: return(kUSBUnknownDeviceErr); ! 1171: } ! 1172: ! 1173: pb->usbStatus = kUSBPending; ! 1174: err = usbControlPacket(bus, pb, address, endpoint); ! 1175: ! 1176: return(err); ! 1177: } ! 1178: ! 1179: ! 1180: ! 1181: ! 1182:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.