|
|
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: This file was created 12/1/98 by Adam Wang to make a duplicate hub driver ! 27: for the root hub as well as the keyboard's built-in hub. This is a duplicate ! 28: of HubClassDriver.c except some name changes simulate the way CFM handles ! 29: global data ! 30: */ ! 31: ! 32: #include "../USB.h" ! 33: ! 34: #include "hub.h" ! 35: #include "../driverservices.h" ! 36: ! 37: ! 38: enum{ /* States the hub driver can be in */ ! 39: kNormal = 0, ! 40: kDead, ! 41: kDeviceZero, ! 42: kDeadDeviceZero, ! 43: kSetAddress, ! 44: kSetAddressFailed ! 45: }; ! 46: ! 47: enum{ ! 48: kHubIsCompound = 0x040 // Hub decriptor characteristics ! 49: }; ! 50: ! 51: enum{ ! 52: kMaxPorts = 4, // Initial allocation of ports, can be expanded ! 53: kInitialRetries = 4 ! 54: }; ! 55: ! 56: ! 57: ! 58: typedef struct{ ! 59: UInt16 status; ! 60: UInt16 change; ! 61: } HubStatus; ! 62: ! 63: ! 64: typedef struct{ ! 65: UInt32 (*handler)(USBPB *pb); ! 66: UInt32 bit; ! 67: UInt32 clearFeature; ! 68: }portStatusChangeVector; ! 69: ! 70: ! 71: static UInt32 defDoNothingChangeHandler(USBPB *pb); ! 72: static UInt32 deadConnectionChangeHandler(USBPB *pb); ! 73: static UInt32 defOverCrntChangeHandler(USBPB *pb); ! 74: static UInt32 defResetChangeHandler(USBPB *pb); ! 75: static UInt32 defSuspendChangeHandler(USBPB *pb); ! 76: static UInt32 defEndableChangeHandler(USBPB *pb); ! 77: static UInt32 defConnectionChangeHandler(USBPB *pb); ! 78: static OSStatus HubAreWeFinishedYet(void); ! 79: static OSStatus killHub(USBDeviceRef device); ! 80: ! 81: static portStatusChangeVector defaultPortVectors[]={ ! 82: {defOverCrntChangeHandler, kHubPortOverCurrent, kUSBHubPortOverCurrentChangeFeature}, ! 83: {defResetChangeHandler, kHubPortBeingReset, kUSBHubPortResetChangeFeature}, ! 84: {defSuspendChangeHandler, kHubPortSuspend, kUSBHubPortSuspendChangeFeature}, ! 85: {defEndableChangeHandler, kHubPortEnabled, kUSBHubPortEnableChangeFeature}, ! 86: {defConnectionChangeHandler, kHubPortConnection, kUSBHubPortConnectionChangeFeature}, ! 87: }; ! 88: ! 89: enum{ ! 90: numChangeHandlers = sizeof(defaultPortVectors)/sizeof(portStatusChangeVector), ! 91: ! 92: ! 93: kVectorContinueImmed = 0, ! 94: kVectorContinueDelayed = 1, ! 95: kVectorfinishedImmed = 2, ! 96: kVectorNotfinished = 3, ! 97: ! 98: kPortWhichVectorShift = 8, ! 99: kPortWhichVector1 = (1<<kPortWhichVectorShift), ! 100: kPortHandlerStageMask = kPortWhichVector1-1, ! 101: ! 102: kPortVectorStageShift = 16, ! 103: kPortVectorStage1 = (1<<kPortVectorStageShift), ! 104: kPortVectorStageMask = kPortVectorStage1-1 ! 105: }; ! 106: ! 107: typedef struct{ ! 108: USBPB pb; ! 109: USBPB *portRequestPB; ! 110: portStatusChangeVector changeHandler[numChangeHandlers]; ! 111: unsigned char *errorString; ! 112: USBDeviceDescriptor desc; ! 113: USBHubPortStatus portStatus; ! 114: USBDeviceRef newDevRef; ! 115: USBDeviceRef devZeroRef; ! 116: UInt16 value; ! 117: UInt16 state; ! 118: int portIndex; ! 119: int onError; ! 120: int retries; ! 121: int delay; ! 122: UInt8 portByte; ! 123: UInt8 portMask; ! 124: }perPort; ! 125: ! 126: ! 127: ! 128: static perPort staticPorts[kMaxPorts+1], *ports = staticPorts; ! 129: static int numPorts; ! 130: static UInt32 busPowerAvail; ! 131: static UInt32 powerForCaptive; ! 132: static Boolean startExternal; ! 133: static Boolean selfPowered; ! 134: static Boolean selfPowerGood; ! 135: static Boolean busPowered; ! 136: static Boolean busPowerGood; ! 137: static HubStatus hubStatus; ! 138: static UInt16 deviceStatus; ! 139: static UInt32 hubSubClass = 1; ! 140: static UInt8 intPipeNumber; ! 141: static USBDeviceRef hubRef, hubDevRef; ! 142: static UInt16 intPipeMaxPacket; ! 143: static hubDescriptor hubDesc; ! 144: static UInt32 intFrame; ! 145: static numCaptive; ! 146: static UInt32 errataBits; ! 147: #if 1 ! 148: ! 149: ! 150: ! 151: static void hubAddDeviceHandler(USBPB *pb); ! 152: static void doPortResetHandler(USBPB *pb); ! 153: ! 154: ! 155: /* Incorporate debugging strings */ ! 156: #define noteError(s) pp->errorString = s; ! 157: ! 158: #else ! 159: ! 160: /* eliminate Error strings */ ! 161: #define noteError(s) ! 162: ! 163: #endif ! 164: ! 165: /* ! 166: This is copied wholesale from the UIM. ! 167: ! 168: This table contains the list of errata that are necessary for known problems with particular hub ! 169: The format is vendorID, product ID, lowest revisionID needing errata, highest rev needing errata, errataBits ! 170: The result of all matches is ORed together, so more than one entry may match. Typically for a given errata a ! 171: list of hubs revisions that this applies to is supplied. ! 172: */ ! 173: enum{ ! 174: kErrataCaptiveOK = 1 ! 175: }; ! 176: ! 177: typedef struct { ! 178: UInt16 vendID; ! 179: UInt16 deviceID; ! 180: UInt16 revisionLo; ! 181: UInt16 revisionHi; ! 182: UInt32 errata; ! 183: }ErrataListEntry; ! 184: ! 185: static ErrataListEntry errataList[] = { ! 186: ! 187: /* For the Cherry 4 port KB, From Cherry: ! 188: We use the bcd_releasenumber-highbyte for hardware- and the lowbyte for ! 189: firmwarestatus. We have 2 different for the hardware 03(eprom) and ! 190: 06(masked microcontroller). Firmwarestatus is 05 today. ! 191: So high byte can be 03 or 06 ---- low byte can be 01, 02, 03, 04, 05 ! 192: ! 193: Currently we are working on a new mask with the new descriptors. The ! 194: firmwarestatus will be higher than 05. ! 195: */ ! 196: {0x046a, 0x003, 0x0301, 0x0305, kErrataCaptiveOK}, // Cherry 4 port KB ! 197: {0x046a, 0x003, 0x0601, 0x0605, kErrataCaptiveOK} // Cherry 4 port KB ! 198: }; ! 199: ! 200: #define errataListLength (sizeof(errataList)/sizeof(ErrataListEntry)) ! 201: ! 202: static UInt32 GetErrataBits(USBDeviceDescriptor *desc) ! 203: { ! 204: UInt32 vendID, deviceID, revisionID; ! 205: ErrataListEntry *entryPtr; ! 206: UInt32 i, errata = 0; ! 207: ! 208: // get this chips vendID, deviceID, revisionID ! 209: vendID = USBToHostWord(desc->vendor); ! 210: deviceID = USBToHostWord(desc->product); ! 211: revisionID = USBToHostWord(desc->devRel); ! 212: for(i=0, entryPtr = errataList; i<errataListLength; i++, entryPtr++){ ! 213: if (vendID == entryPtr->vendID && deviceID == entryPtr->deviceID && ! 214: revisionID >= entryPtr->revisionLo && revisionID <= entryPtr->revisionHi){ ! 215: errata |= entryPtr->errata; // we match, add this errata to our list ! 216: } ! 217: } ! 218: return(errata); ! 219: } ! 220: ! 221: static Boolean bit(long value, long mask) ! 222: { ! 223: return( (value & mask) != 0); ! 224: } ! 225: ! 226: static Boolean immediateError(OSStatus err) ! 227: { ! 228: Boolean result; ! 229: result = false; ! 230: if((err != kUSBPending) && (err != noErr)) ! 231: { ! 232: //Debugger(); ! 233: result = true; ! 234: } ! 235: // return((err != kUSBPending) && (err != noErr) ); ! 236: return(result ); ! 237: } ! 238: ! 239: static void initPortVectors(portStatusChangeVector *changeHandler) ! 240: { ! 241: int vector; ! 242: for(vector = 0; vector < numChangeHandlers; vector++) ! 243: { ! 244: changeHandler[vector] = defaultPortVectors[vector]; ! 245: } ! 246: } ! 247: ! 248: static void setDeadPortVectors(portStatusChangeVector *changeHandler) ! 249: { ! 250: int vector; ! 251: initPortVectors(changeHandler); ! 252: for(vector = 0; vector < numChangeHandlers; vector++) ! 253: { ! 254: changeHandler[vector].handler = defDoNothingChangeHandler; ! 255: } ! 256: } ! 257: ! 258: ! 259: static void setPortVector(portStatusChangeVector *changeHandler, void *routine, UInt32 condition) ! 260: { ! 261: int vector; ! 262: for(vector = 0; vector < numChangeHandlers; vector++) ! 263: { ! 264: if(condition == changeHandler[vector].bit) ! 265: { ! 266: if(routine == nil) ! 267: { ! 268: changeHandler[vector].handler = defaultPortVectors[vector].handler; ! 269: } ! 270: else ! 271: { ! 272: changeHandler[vector].handler = routine; ! 273: } ! 274: } ! 275: } ! 276: } ! 277: ! 278: ! 279: static void HubFatalError(perPort *pp, OSStatus err, unsigned char *str, UInt32 num) ! 280: { ! 281: // Debugger(); ! 282: USBExpertFatalError(hubDevRef, err, str, num); ! 283: ! 284: if(!pp->state != kDead) ! 285: { ! 286: USBExpertStatus(hubDevRef, "******* DEVICE IS DEAD ********", 0); ! 287: if(pp->newDevRef != 0) ! 288: { ! 289: pp->pb.usbReference = pp->newDevRef; ! 290: pp->pb.usbCompletion = kUSBNoCallBack; ! 291: (void)USBHubDeviceRemoved(&pp->pb); ! 292: USBExpertRemoveDeviceDriver(pp->newDevRef); ! 293: } ! 294: } ! 295: pp->pb.usbRefcon = 0; ! 296: pp->delay = 0; ! 297: pp->state = kDead; ! 298: setDeadPortVectors(pp->changeHandler); ! 299: setPortVector(pp->changeHandler, deadConnectionChangeHandler, kHubPortConnection); ! 300: pp->newDevRef = 0; ! 301: pp->retries = kInitialRetries; ! 302: } ! 303: ! 304: static OSStatus HubAreWeFinishedYet(void) ! 305: { ! 306: enum{ ! 307: hubTimeOut = 256 ! 308: }; ! 309: USBPB pb={0,0, sizeof(USBPB), kUSBCurrentPBVersion, 0, 0, 0 ,0, 0, 0, 0, 0, 0, 0}; ! 310: int i; ! 311: OSStatus retVal = noErr; ! 312: static Boolean finished; ! 313: static UInt32 firstFrame=0, askCount=0; ! 314: ! 315: if(finished) ! 316: { ! 317: return(kUSBNoErr); ! 318: } ! 319: ! 320: if(firstFrame == 0) ! 321: { ! 322: pb.usbCompletion = kUSBNoCallBack; ! 323: pb.usbReference = hubDevRef; ! 324: USBGetFrameNumberImmediate(&pb); ! 325: firstFrame = pb.usbFrame; ! 326: } ! 327: askCount++; ! 328: ! 329: // USBExpertStatus(hubDevRef, "Hub driver - Are we finished", hubDevRef); ! 330: if(intFrame == 0) ! 331: { ! 332: //USBExpertStatus(hubDevRef, "Hub driver - Not got to int handler yet", 0); ! 333: retVal = kUSBDeviceBusy; ! 334: } ! 335: ! 336: if(retVal == noErr) ! 337: { ! 338: if(intFrame == 0xffffffff) ! 339: { ! 340: //USBExpertStatus(hubDevRef, "Hub driver - Int already happened", 0); ! 341: } ! 342: else ! 343: { ! 344: pb.usbCompletion = kUSBNoCallBack; ! 345: pb.usbReference = hubDevRef; ! 346: if(USBGetFrameNumberImmediate(&pb) != noErr) ! 347: { ! 348: USBExpertStatus(hubDevRef, "Hub driver - Failed to get frame", pb.usbStatus); ! 349: intFrame = 0xffffffff; ! 350: pb.usbFrame = 0; ! 351: } ! 352: //USBExpertStatus(hubDevRef, "Hub driver - num frames", pb.usbFrame - intFrame); ! 353: if( (pb.usbFrame - intFrame) < hubTimeOut) ! 354: { ! 355: //USBExpertStatus(hubDevRef, "Hub driver - no timeout yet", 0); ! 356: retVal = kUSBDeviceBusy; ! 357: } ! 358: } ! 359: } ! 360: if(retVal == noErr) ! 361: { ! 362: //USBExpertStatus(hubDevRef, "Hub driver - check if any port busy", 0); ! 363: finished = true; ! 364: for(i = 1; i<=numPorts; i++) ! 365: { ! 366: if(ports[i].pb.usbRefcon != 0) ! 367: { ! 368: //USBExpertStatus(hubDevRef, "Hub driver - port busy:", i); ! 369: //USBExpertStatus(hubDevRef, "Hub driver - port ref:", ports[i].pb.usbRefcon); ! 370: finished = false; ! 371: } ! 372: } ! 373: } ! 374: ! 375: if(retVal != noErr) ! 376: { ! 377: finished = false; ! 378: return(retVal); ! 379: } ! 380: if(finished && (firstFrame != 0xffffffff) ) ! 381: { ! 382: #if 0 ! 383: if(intFrame == 0xffffffff) ! 384: { ! 385: USBExpertStatus(hubDevRef, "Hub driver - Finished Enumeration Int happened", hubDevRef); ! 386: } ! 387: else ! 388: { ! 389: USBExpertStatus(hubDevRef, "Hub driver - Finished Enumeration Timed out", hubDevRef); ! 390: } ! 391: #endif ! 392: // USBExpertStatus(hubDevRef, "Hub driver - Ask count", askCount); ! 393: pb.usbCompletion = kUSBNoCallBack; ! 394: pb.usbReference = hubDevRef; ! 395: USBGetFrameNumberImmediate(&pb); ! 396: // USBExpertStatus(hubDevRef, "Hub driver - Ask time", pb.usbFrame - firstFrame); ! 397: firstFrame = 0xffffffff; ! 398: } ! 399: ! 400: return(finished?kUSBNoErr:kUSBDeviceBusy); ! 401: } ! 402: ! 403: ! 404: static void detachDevice(USBPB *pb) ! 405: { ! 406: perPort *pp; ! 407: pp = (void *)pb; /* parameter block has been extended */ ! 408: ! 409: if(pb->usbStatus != noErr) ! 410: { ! 411: if( (pp->onError == 0) && (pp->retries == 0) ) ! 412: { ! 413: /* no idea what to do now?? */ ! 414: USBExpertFatalError(hubDevRef, pb->usbStatus, pp->errorString, 1); ! 415: ! 416: pb->usbRefcon = 0; ! 417: /* Mark port as errored */ ! 418: return; ! 419: } ! 420: else ! 421: { ! 422: USBExpertStatus(hubDevRef, pp->errorString, 2); ! 423: pb->usbRefcon = pp->onError; ! 424: pp->retries--; ! 425: ! 426: if(pp->retries == 1) ! 427: { ! 428: pp->delay = -3; ! 429: } ! 430: else if(pp->retries == 0) ! 431: { ! 432: pp->delay = -30; ! 433: } ! 434: /* we'll delay comming back to here */ ! 435: pb->usbReqCount = 0; ! 436: /* pb->usbFlags = kUSBtaskTime */ ! 437: // USBDelay(pb); ! 438: } ! 439: ! 440: } ! 441: ! 442: pp->onError = 0; ! 443: if(pp->delay != 0) ! 444: { ! 445: pp->delay = -pp->delay; ! 446: if(pp->delay > 0) ! 447: { ! 448: pb->usbReqCount = pp->delay; ! 449: USBDelay(pb); ! 450: return; ! 451: } ! 452: } ! 453: ! 454: ! 455: do{switch(pb->usbRefcon++) ! 456: { ! 457: case 1: ! 458: /* Power off the port */ ! 459: ! 460: /* Maybe should only do this if there is power switching */ ! 461: ! 462: pb->usbReference = hubRef; ! 463: ! 464: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 465: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 466: pb->usb.cntl.WValue = kUSBHubPortPowerFeature; ! 467: pb->usb.cntl.WIndex = pp->portIndex; ! 468: pb->usbReqCount = 0; ! 469: pb->usbBuffer = nil; ! 470: ! 471: noteError("Hub Driver - Powering off port"); ! 472: if(immediateError(USBDeviceRequest(pb))) ! 473: { ! 474: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 475: } ! 476: break; ! 477: ! 478: case 2: ! 479: pb->usbReqCount = 100; // wait 100ms ! 480: USBDelay(pb); ! 481: break; ! 482: ! 483: case 3: ! 484: /* Power on the port */ ! 485: ! 486: /* Maybe should only do this if there is power switching */ ! 487: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 488: pb->usb.cntl.BRequest = kUSBRqSetFeature; ! 489: pb->usb.cntl.WValue = kUSBHubPortPowerFeature; ! 490: pb->usb.cntl.WIndex = pp->portIndex; ! 491: pb->usbReqCount = 0; ! 492: pb->usbBuffer = nil; ! 493: ! 494: noteError("Hub Driver - Powering on port again"); ! 495: if(immediateError(USBDeviceRequest(pb))) ! 496: { ! 497: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 498: } ! 499: break; ! 500: ! 501: case 4: ! 502: pp->state = kDead; ! 503: pb->usbRefcon = 0; ! 504: break; ! 505: ! 506: default: ! 507: noteError("Hub dead Driver Error - Unused case in detach device"); ! 508: USBExpertFatalError(hubDevRef, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 509: break; ! 510: } ! 511: break; /* only execute once, unless continue used */ ! 512: }while(1); /* so case can be reentered with a continue */ ! 513: ! 514: ! 515: } ! 516: ! 517: ! 518: static Boolean handleError(USBPB *pb) ! 519: { ! 520: perPort *pp; ! 521: pp = (void *)pb; /* parameter block has been extended */ ! 522: if(pb->usbStatus != noErr) ! 523: { ! 524: if( (pb->usbStatus == kUSBAbortedError) && (pp->state != kDead) &(pp->state != kDeadDeviceZero) ) ! 525: { ! 526: /* If the hub watchdog times this out, we may get an aborted error */ ! 527: /* We do need to do something about this */ ! 528: if(pp->state == kDeviceZero) ! 529: { ! 530: pb->usbStatus = noErr; ! 531: pp->state = kDeadDeviceZero; ! 532: return(false); ! 533: } ! 534: USBExpertFatalError(hubDevRef, hubDevRef, "Hub driver - Processing Aborted - Exiting", pb->usbStatus); ! 535: pb->usbRefcon = 0; ! 536: return(true); ! 537: } ! 538: if( (pp->onError == 0) || (pp->retries == 0) ) ! 539: { ! 540: if(pp->state == kDeviceZero) ! 541: { ! 542: pp->state = kDeadDeviceZero; ! 543: return(false); ! 544: } ! 545: else if(pp->state == kSetAddress) ! 546: { ! 547: /* set address failed, need to turn off this device */ ! 548: USBExpertStatus(hubDevRef, "Hub driver - set address failed, turning off device", 0); ! 549: pp->retries = kInitialRetries; ! 550: pb->usbRefcon = 1; ! 551: pb->usbStatus = noErr; ! 552: pp->state = kSetAddressFailed; ! 553: pb->usbFlags = 0; ! 554: pp->delay = 0; ! 555: pb->usbCompletion = detachDevice; ! 556: detachDevice(pb); ! 557: return(true); ! 558: } ! 559: ! 560: if(pp->state == kDead) ! 561: { ! 562: USBExpertFatalError(hubDevRef, pb->usbStatus, pp->errorString, 1); ! 563: } ! 564: else ! 565: { ! 566: /* no idea what to do now?? */ ! 567: HubFatalError(pp, pb->usbStatus, pp->errorString, 1); ! 568: } ! 569: pb->usbRefcon = 0; ! 570: return(true); ! 571: } ! 572: else ! 573: { ! 574: USBExpertStatus(hubDevRef, pp->errorString, 2); ! 575: pb->usbRefcon = pp->onError; ! 576: pp->retries--; ! 577: ! 578: if(pp->retries == 1) ! 579: { ! 580: pp->delay = -3; ! 581: } ! 582: else if(pp->retries == 0) ! 583: { ! 584: pp->delay = -30; ! 585: } ! 586: } ! 587: } ! 588: ! 589: pp->onError = 0; ! 590: ! 591: if(pp->delay != 0) ! 592: { ! 593: pp->delay = -pp->delay; ! 594: if(pp->delay > 0) ! 595: { ! 596: pb->usbReqCount = pp->delay; ! 597: USBDelay(pb); // Should check for error here ! 598: return(true); ! 599: } ! 600: } ! 601: ! 602: return(false); /* tell function to carry on */ ! 603: } ! 604: ! 605: static UInt32 resetChangeHandler(USBPB *pb) ! 606: { ! 607: perPort *pp; ! 608: ! 609: pp = (void *)pb; /* parameter block has been extended */ ! 610: ! 611: do{switch(pb->usbRefcon >> kPortVectorStageShift) ! 612: { ! 613: case 1: ! 614: if(pp->state == kDeadDeviceZero) ! 615: { ! 616: pb->usbRefcon += kPortVectorStage1; ! 617: continue; // we need to fall forwards to set address ! 618: } ! 619: ! 620: if(bit(pp->portStatus.portFlags, kHubPortBeingReset)) ! 621: { ! 622: USBExpertStatus(hubDevRef, "Hub Driver Error - Port not finished resetting, retrying", pb->usbRefcon); ! 623: // we should never be here, just wait for another status change int ! 624: return(kVectorContinueImmed); ! 625: } ! 626: ! 627: if(pp->state == kDeadDeviceZero) ! 628: { ! 629: pb->usbRefcon += kPortVectorStage1; ! 630: continue; // we need to fall forwards to set address ! 631: } ! 632: ! 633: ! 634: /* Now wait 10 ms after reset */ ! 635: /* Do fancy things with perPort to shorten this when looping */ ! 636: ! 637: pb->usbReqCount = 7; // This should be ready in 10ms ! 638: // However devices don't have to respond for another 10ms ! 639: // The set address below, won't arrive before 20ms ! 640: // Thats 17 + at least 3ms one each for each of 3 controlls ! 641: ! 642: //pb->usbReqCount = 10; // On root hub things are happening too quickly. ! 643: // I'll have to fix that, in the meantime amke it 20 ! 644: ! 645: noteError("Hub Driver - Calling USBDelay"); ! 646: //USBExpertStatus(hubDevRef, "Hub Driver - calling delay", pb->usbReqCount); ! 647: if(immediateError(USBDelay(pb))) ! 648: { ! 649: pb->usbRefcon += kPortVectorStage1; ! 650: resetChangeHandler(pb); ! 651: } ! 652: break; ! 653: ! 654: case 2: ! 655: if(pp->state == kDeadDeviceZero) ! 656: { ! 657: pb->usbRefcon += kPortVectorStage1; ! 658: continue; // we need to fall forwards to set address ! 659: } ! 660: ! 661: pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 662: //pb->usb.cntl.WValue = 8; // max packet size ! 663: ! 664: // This should make no difference. For 1.1 max packet size discovery ! 665: pb->usb.cntl.WValue = 64; // max packet size ! 666: ! 667: pb->usbReference = pp->newDevRef; ! 668: ! 669: noteError("Hub Driver Error - configuring endpoint zero"); ! 670: if(immediateError(USBHubConfigurePipeZero(pb))) ! 671: { ! 672: USBExpertStatus(hubDevRef, "Config pipe zero failed", pb->usbStatus); ! 673: pb->usbRefcon += kPortVectorStage1; ! 674: resetChangeHandler(pb); ! 675: } ! 676: break; ! 677: ! 678: case 3: ! 679: if(pp->state == kDeadDeviceZero) ! 680: { ! 681: pb->usbRefcon += kPortVectorStage1; ! 682: continue; // we need to fall forwards to set address ! 683: } ! 684: pb->usbFlags = 0; // tidy up after above ! 685: ! 686: /* now do a device request to find out what it is */ ! 687: ! 688: ! 689: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice); ! 690: pb->usb.cntl.BRequest = kUSBRqGetDescriptor; ! 691: pb->usb.cntl.WValue = (kUSBDeviceDesc << 8) + 0/*index*/; ! 692: pb->usb.cntl.WIndex = 0; ! 693: //pb->usbReqCount = OFFSET(USBDeviceDescriptor, descEnd); ! 694: ! 695: // For 1.1 max packet size discovery, we're relying on numConf being zero here ! 696: pb->usbReqCount = 8; ! 697: pp->desc.numConf = 0; // This is the flag to read the rest. ! 698: // Do not forget numConf for 1.1 discovery, or take out check below ! 699: ! 700: /* did we get here because the get descriptor failed? */ ! 701: if(pb->usbStatus == kUSBOverRunErr) ! 702: { /* endpoint zero max packet too large. Read first */ ! 703: /* 8 bytes to get the value you need */ ! 704: USBExpertStatus(hubDevRef, "Hub driver - overrun error reading device descriptor:", pb->usbActCount); ! 705: pb->usbReqCount = 8; ! 706: pp->desc.numConf = 0; // make a note to read all of this ! 707: } ! 708: ! 709: pb->usbBuffer = &pp->desc; ! 710: ! 711: pp->onError = pb->usbRefcon-kPortVectorStage1; /* do a retry on error */ ! 712: /* the get descriptor seems to screw up most often */ ! 713: noteError("Hub Driver Error - kUSBRqGetDescriptor (get device descriptor after a SetAddress)"); ! 714: if(immediateError(USBDeviceRequest(pb))) ! 715: { ! 716: pb->usbRefcon += kPortVectorStage1; ! 717: resetChangeHandler(pb); ! 718: } ! 719: break; ! 720: ! 721: case 4: ! 722: if( (hubDesc.removablePortFlags[pp->portByte] & pp->portMask) != 0) ! 723: { ! 724: pb->usbOther = powerForCaptive; ! 725: } ! 726: else ! 727: { ! 728: pb->usbOther = selfPowerGood?kUSB500mAAvailable:kUSB100mAAvailable; ! 729: } ! 730: ! 731: ! 732: /* Now address the device */ ! 733: ! 734: pb->usb.cntl.WValue = pp->desc.maxPacketSize; ! 735: pp->newDevRef = 0; // if set address fails, don't try to remove old ! 736: pp->onError = pb->usbRefcon; /* Go back to start, via next case */ ! 737: pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 738: pb->usbFlags |= kUSBHubPower; ! 739: ! 740: pp->state = kSetAddress; /* If this fails, detatch */ ! 741: noteError("Hub Driver Error - Setting the device address"); ! 742: if(immediateError(USBHubSetAddress(pb))) ! 743: { ! 744: pb->usbRefcon += kPortVectorStage1; ! 745: resetChangeHandler(pb); ! 746: } ! 747: ! 748: break; ! 749: ! 750: case 5: ! 751: if( (pp->state == kDeadDeviceZero) || (pb->usbReference == 0) ) ! 752: { ! 753: noteError("Hub Driver Error - dead set address"); ! 754: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 755: return(kVectorfinishedImmed); ! 756: } ! 757: ! 758: pb->usbFlags = 0; ! 759: pp->state = kNormal; /* no longer need special handling to avoid deadlock */ ! 760: ! 761: if(pb->usbStatus != noErr) ! 762: { ! 763: /* an error setting the addres, so go back and try resetting again */ ! 764: pb->usbRefcon = 1; ! 765: pb->usbStatus = noErr; ! 766: pb->usbCompletion = hubAddDeviceHandler; ! 767: pb->usbReqCount = 1; ! 768: setPortVector(pp->changeHandler, 0, kHubPortBeingReset); ! 769: USBDelay(pb); ! 770: break; ! 771: } ! 772: ! 773: /* refernce is now new device ref, no longer dev zero */ ! 774: ! 775: pp->newDevRef = pb->usbReference; ! 776: ! 777: if(pp->desc.numConf == 0) // don't have full descriptor, try again */ ! 778: { ! 779: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice); ! 780: pb->usb.cntl.BRequest = kUSBRqGetDescriptor; ! 781: pb->usb.cntl.WValue = (kUSBDeviceDesc << 8) + 0/*index*/; ! 782: pb->usb.cntl.WIndex = 0; ! 783: pb->usbReqCount = OFFSET(USBDeviceDescriptor, descEnd); ! 784: pb->usbBuffer = &pp->desc; ! 785: ! 786: pp->onError = pb->usbRefcon-kPortVectorStage1; /* do a retry on error */ ! 787: /* the get descriptor seems to screw up most often */ ! 788: noteError("Hub Driver Error - kUSBRqGetDescriptor (get device descriptor after a SetAddress)"); ! 789: if(immediateError(USBDeviceRequest(pb))) ! 790: { ! 791: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 792: } ! 793: } ! 794: else ! 795: { ! 796: pb->usbRefcon += kPortVectorStage1; ! 797: continue; ! 798: } ! 799: break; ! 800: ! 801: case 6: ! 802: ! 803: /* FInally use the data gathered */ ! 804: USBExpertInstallDeviceDriver(pb->usbReference, &pp->desc, hubDevRef, pp->portIndex, pb->usbOther); ! 805: /* Call to the expert */ ! 806: ! 807: setPortVector(pp->changeHandler, 0, kHubPortBeingReset); ! 808: return(kVectorfinishedImmed); ! 809: break; ! 810: ! 811: default: ! 812: noteError("Hub Driver Error - Unused case in reset change handler"); ! 813: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 814: break; ! 815: } ! 816: break; /* only execute once, unless continue used */ ! 817: }while(1); /* so case can be reentered with a continue */ ! 818: ! 819: return(kVectorNotfinished); ! 820: } ! 821: ! 822: static void hubAddDeviceHandler(USBPB *pb) ! 823: { ! 824: perPort *pp; ! 825: ! 826: if(handleError(pb)) ! 827: return; ! 828: pp = (void *)pb; /* parameter block has been extended */ ! 829: ! 830: do{switch(pb->usbRefcon++) ! 831: { ! 832: ! 833: case 1: ! 834: pb->usbReference = hubRef; ! 835: ! 836: /* Check if the port is suspended */ ! 837: if(bit(pp->portStatus.portFlags, kHubPortSuspend)) ! 838: { ! 839: /* resume the port */ ! 840: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 841: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 842: pb->usb.cntl.WValue = kUSBHubPortSuspecdFeature; ! 843: pb->usb.cntl.WIndex = pp->portIndex; ! 844: pb->usbReqCount = 0; ! 845: pb->usbBuffer = nil; ! 846: ! 847: noteError("Hub Driver - kUSBRqClearFeature (clearing 'port suspend' feature)"); ! 848: if(immediateError(USBDeviceRequest(pb))) ! 849: { ! 850: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 851: } ! 852: } ! 853: else ! 854: { ! 855: continue; ! 856: } ! 857: ! 858: break; ! 859: ! 860: case 2: ! 861: /* Tell the USB to add the device */ ! 862: // pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 863: // Speed no longer set in add device ! 864: ! 865: noteError("Hub Driver - Device found, calling USBHubAddDevice"); ! 866: USBExpertStatus(hubDevRef, "Hub Driver - Device found, calling USBHubAddDevice. Port", pp->portIndex); ! 867: if(immediateError(USBHubAddDevice(pb))) ! 868: { ! 869: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 870: } ! 871: break; ! 872: ! 873: case 3: ! 874: pb->usbFlags = 0; ! 875: /* We're called back when its time to reset */ ! 876: pp->state = kDeviceZero; /* remeber to clean up if fails */ ! 877: ! 878: /* remember the ref to the new device (as dev zero) */ ! 879: pp->newDevRef = pb->usbReference; ! 880: ! 881: pb->usbReference = hubRef; ! 882: ! 883: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 884: pb->usb.cntl.BRequest = kUSBRqSetFeature; ! 885: pb->usb.cntl.WValue = kUSBHubPortResetFeature; ! 886: pb->usb.cntl.WIndex = pp->portIndex; ! 887: pb->usbReqCount = 0; ! 888: pb->usbBuffer = nil; ! 889: ! 890: setPortVector(pp->changeHandler, resetChangeHandler, kHubPortBeingReset); ! 891: ! 892: noteError("Hub Driver Error - kUSBRqSetFeature (resetting port)"); ! 893: if(immediateError(USBDeviceRequest(pb))) ! 894: { ! 895: hubAddDeviceHandler(pb); ! 896: } ! 897: ! 898: break; ! 899: ! 900: case 4: ! 901: pb->usbRefcon = 0; /* this continues via the status change handler */ ! 902: break; ! 903: ! 904: default: ! 905: noteError("Hub Driver Error - Unused case in add device"); ! 906: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 907: break; ! 908: } ! 909: break; /* only execute once, unless continue used */ ! 910: }while(1); /* so case can be reentered with a continue */ ! 911: } ! 912: ! 913: static UInt32 doPortResetChangeHandler(USBPB *pb) ! 914: { ! 915: perPort *pp; ! 916: ! 917: pp = (void *)pb; /* parameter block has been extended */ ! 918: ! 919: do{switch(pb->usbRefcon >> kPortVectorStageShift) ! 920: { ! 921: case 1: ! 922: if(pp->state == kDeadDeviceZero) ! 923: { ! 924: pb->usbRefcon += kPortVectorStage1; ! 925: continue; // we need to fall forwards to set address ! 926: } ! 927: ! 928: if(bit(pp->portStatus.portFlags, kHubPortBeingReset)) ! 929: { ! 930: USBExpertStatus(hubDevRef, "Hub Driver Error - Port not finished resetting, retrying", pb->usbRefcon); ! 931: // we should never be here, just wait for another status change int ! 932: return(kVectorContinueImmed); ! 933: } ! 934: ! 935: if(pp->state == kDeadDeviceZero) ! 936: { ! 937: pb->usbRefcon += kPortVectorStage1; ! 938: continue; // we need to fall forwards to set address ! 939: } ! 940: ! 941: ! 942: /* Now wait 10 ms after reset */ ! 943: /* Do fancy things with perPort to shorten this when looping */ ! 944: ! 945: pb->usbReqCount = 7; // This should be ready in 10ms ! 946: // However devices don't have to respond for another 10ms ! 947: // The set address below, won't arrive before 20ms ! 948: // Thats 17 + at least 3ms one each for each of 3 controlls ! 949: ! 950: //pb->usbReqCount = 10; // On root hub things are happening too quickly. ! 951: // I'll have to fix that, in the meantime amke it 20 ! 952: ! 953: noteError("Hub Driver - Calling USBDelay"); ! 954: //USBExpertStatus(hubDevRef, "Hub Driver - calling delay", pb->usbReqCount); ! 955: if(immediateError(USBDelay(pb))) ! 956: { ! 957: pb->usbRefcon += kPortVectorStage1; ! 958: doPortResetChangeHandler(pb); ! 959: } ! 960: break; ! 961: ! 962: case 2: ! 963: if(pp->state == kDeadDeviceZero) ! 964: { ! 965: pb->usbRefcon += kPortVectorStage1; ! 966: continue; // we need to fall forwards to set address ! 967: } ! 968: ! 969: pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 970: pb->usb.cntl.WValue = 8; // max packet size ! 971: ! 972: pb->usbReference = pp->devZeroRef; ! 973: ! 974: noteError("Hub Driver Error - configuring endpoint zero"); ! 975: if(immediateError(USBHubConfigurePipeZero(pb))) ! 976: { ! 977: USBExpertStatus(hubDevRef, "Config pipe zero failed", pb->usbStatus); ! 978: pb->usbRefcon += kPortVectorStage1; ! 979: doPortResetChangeHandler(pb); ! 980: } ! 981: break; ! 982: ! 983: case 3: ! 984: if(pp->state == kDeadDeviceZero) ! 985: { ! 986: pb->usbRefcon += kPortVectorStage1; ! 987: continue; // we need to fall forwards to set address ! 988: } ! 989: pb->usbFlags = 0; // tidy up after above ! 990: ! 991: /* now do a device request to find out what it is */ ! 992: ! 993: ! 994: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice); ! 995: pb->usb.cntl.BRequest = kUSBRqGetDescriptor; ! 996: pb->usb.cntl.WValue = (kUSBDeviceDesc << 8) + 0/*index*/; ! 997: pb->usb.cntl.WIndex = 0; ! 998: pb->usbReqCount = OFFSET(USBDeviceDescriptor, descEnd); ! 999: ! 1000: /* did we get here because the get descriptor failed? */ ! 1001: if(pb->usbStatus == kUSBOverRunErr) ! 1002: { /* endpoint zero max packet too large. Read first */ ! 1003: /* 8 bytes to get the value you need */ ! 1004: USBExpertStatus(hubDevRef, "Hub driver - overrun error reading device descriptor:", pb->usbActCount); ! 1005: pb->usbReqCount = 8; ! 1006: pp->desc.numConf = 0; // make a note to read all of this ! 1007: } ! 1008: ! 1009: pb->usbBuffer = &pp->desc; ! 1010: ! 1011: pp->onError = pb->usbRefcon-kPortVectorStage1; /* do a retry on error */ ! 1012: /* the get descriptor seems to screw up most often */ ! 1013: noteError("Hub Driver Error - kUSBRqGetDescriptor (get device descriptor after a SetAddress)"); ! 1014: if(immediateError(USBDeviceRequest(pb))) ! 1015: { ! 1016: pb->usbRefcon += kPortVectorStage1; ! 1017: doPortResetChangeHandler(pb); ! 1018: } ! 1019: break; ! 1020: ! 1021: case 4: ! 1022: if( (hubDesc.removablePortFlags[pp->portByte] & pp->portMask) != 0) ! 1023: { ! 1024: pb->usbOther = powerForCaptive; ! 1025: } ! 1026: else ! 1027: { ! 1028: pb->usbOther = selfPowerGood?kUSB500mAAvailable:kUSB100mAAvailable; ! 1029: } ! 1030: ! 1031: /* Now address the device */ ! 1032: pb->usbReference = pp->newDevRef; ! 1033: pb->usb.cntl.WValue = pp->desc.maxPacketSize; ! 1034: pp->devZeroRef = 0; // if set address fails, don't try to remove old ! 1035: pp->onError = pb->usbRefcon; /* Go back to start, via next case */ ! 1036: pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 1037: pb->usbFlags |= kUSBHubPower | kUSBHubReaddress; ! 1038: ! 1039: pp->state = kSetAddress; /* If this fails, detatch */ ! 1040: noteError("Hub Driver Error - Setting the device address"); ! 1041: if(immediateError(USBHubSetAddress(pb))) ! 1042: { ! 1043: pb->usbRefcon += kPortVectorStage1; ! 1044: doPortResetChangeHandler(pb); ! 1045: } ! 1046: ! 1047: break; ! 1048: ! 1049: case 5: ! 1050: if( (pp->state == kDeadDeviceZero) || (pb->usbReference == 0) ) ! 1051: { ! 1052: /* If you want to try again with dead devices this is the place to do it */ ! 1053: noteError("Hub Driver Error - dead set address"); ! 1054: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1055: return(kVectorfinishedImmed); ! 1056: } ! 1057: ! 1058: pb->usbFlags = 0; ! 1059: pp->state = kNormal; /* no longer need special handling to avoid deadlock */ ! 1060: ! 1061: if(pb->usbStatus != noErr) ! 1062: { ! 1063: pb->usbRefcon += kPortVectorStage1; ! 1064: continue; // we need to fall forwards to set address ! 1065: } ! 1066: ! 1067: /* refernce is now new device ref, no longer dev zero */ ! 1068: ! 1069: pp->devZeroRef = pb->usbReference; ! 1070: ! 1071: if(pp->desc.numConf == 0) // don't have full descriptor, try again */ ! 1072: { ! 1073: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice); ! 1074: pb->usb.cntl.BRequest = kUSBRqGetDescriptor; ! 1075: pb->usb.cntl.WValue = (kUSBDeviceDesc << 8) + 0/*index*/; ! 1076: pb->usb.cntl.WIndex = 0; ! 1077: pb->usbReqCount = OFFSET(USBDeviceDescriptor, descEnd); ! 1078: pb->usbBuffer = &pp->desc; ! 1079: ! 1080: pp->onError = pb->usbRefcon-kPortVectorStage1; /* do a retry on error */ ! 1081: /* the get descriptor seems to screw up most often */ ! 1082: noteError("Hub Driver Error - kUSBRqGetDescriptor (get device descriptor after a SetAddress)"); ! 1083: if(immediateError(USBDeviceRequest(pb))) ! 1084: { ! 1085: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1086: } ! 1087: } ! 1088: else ! 1089: { ! 1090: pb->usbRefcon += kPortVectorStage1; ! 1091: continue; ! 1092: } ! 1093: break; ! 1094: ! 1095: case 6: ! 1096: ! 1097: /* FInally use the data gathered */ ! 1098: setPortVector(pp->changeHandler, 0, kHubPortBeingReset); ! 1099: pp->portRequestPB->usbStatus = pb->usbStatus; ! 1100: pb = pp->portRequestPB; ! 1101: pp->portRequestPB = nil; // The port is now free ! 1102: ! 1103: if( (pb->usbCompletion != nil) || (pb->usbCompletion != (void *)-1) ) ! 1104: { ! 1105: (*pb->usbCompletion)(pb); ! 1106: } ! 1107: return(kVectorfinishedImmed); ! 1108: break; ! 1109: ! 1110: default: ! 1111: noteError("Hub Driver Error - Unused case in port reset change handler"); ! 1112: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1113: break; ! 1114: } ! 1115: break; /* only execute once, unless continue used */ ! 1116: }while(1); /* so case can be reentered with a continue */ ! 1117: ! 1118: return(kVectorNotfinished); ! 1119: } ! 1120: ! 1121: static void doPortResetHandler(USBPB *pb) ! 1122: { ! 1123: perPort *pp; ! 1124: ! 1125: if(handleError(pb)) ! 1126: return; ! 1127: pp = (void *)pb; /* parameter block has been extended */ ! 1128: ! 1129: do{switch(pb->usbRefcon++) ! 1130: { ! 1131: ! 1132: case 1: ! 1133: pb->usbReference = hubRef; ! 1134: ! 1135: /* Check if the port is suspended */ ! 1136: if(bit(pp->portStatus.portFlags, kHubPortSuspend)) ! 1137: { ! 1138: /* resume the port */ ! 1139: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1140: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 1141: pb->usb.cntl.WValue = kUSBHubPortSuspecdFeature; ! 1142: pb->usb.cntl.WIndex = pp->portIndex; ! 1143: pb->usbReqCount = 0; ! 1144: pb->usbBuffer = nil; ! 1145: ! 1146: noteError("Hub Driver - kUSBRqClearFeature (clearing 'port suspend' feature)"); ! 1147: if(immediateError(USBDeviceRequest(pb))) ! 1148: { ! 1149: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1150: } ! 1151: } ! 1152: else ! 1153: { ! 1154: continue; ! 1155: } ! 1156: ! 1157: break; ! 1158: ! 1159: case 2: ! 1160: /* Tell the USB to add the device */ ! 1161: // pb->usbFlags = ((pp->portStatus.portFlags & kHubPortSpeed) != 0); /* 1 if low speed */ ! 1162: // Speed no longer set in add device ! 1163: ! 1164: noteError("Hub Driver - Resetting device"); ! 1165: USBExpertStatus(hubDevRef, "Hub Driver - Waiting to reset device", 0); ! 1166: if(immediateError(USBHubAddDevice(pb))) ! 1167: { ! 1168: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1169: } ! 1170: break; ! 1171: ! 1172: case 3: ! 1173: pb->usbFlags = 0; ! 1174: /* We're called back when its time to reset */ ! 1175: pp->state = kDeviceZero; /* remeber to clean up if fails */ ! 1176: ! 1177: /* remember the ref to the new device (as dev zero) */ ! 1178: pp->devZeroRef = pb->usbReference; ! 1179: ! 1180: pb->usbReference = hubRef; ! 1181: ! 1182: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1183: pb->usb.cntl.BRequest = kUSBRqSetFeature; ! 1184: pb->usb.cntl.WValue = kUSBHubPortResetFeature; ! 1185: pb->usb.cntl.WIndex = pp->portIndex; ! 1186: pb->usbReqCount = 0; ! 1187: pb->usbBuffer = nil; ! 1188: ! 1189: setPortVector(pp->changeHandler, doPortResetChangeHandler, kHubPortBeingReset); ! 1190: ! 1191: noteError("Hub Driver Error - kUSBRqSetFeature (resetting port)"); ! 1192: if(immediateError(USBDeviceRequest(pb))) ! 1193: { ! 1194: doPortResetHandler(pb); ! 1195: } ! 1196: ! 1197: break; ! 1198: ! 1199: case 4: ! 1200: pb->usbRefcon = 0; /* this continues via the status change handler */ ! 1201: break; ! 1202: ! 1203: default: ! 1204: noteError("Hub Driver Error - Unused case in reset device"); ! 1205: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1206: break; ! 1207: } ! 1208: break; /* only execute once, unless continue used */ ! 1209: }while(1); /* so case can be reentered with a continue */ ! 1210: } ! 1211: ! 1212: static void hubStatusChangeHandler(USBPB *pb) ! 1213: { ! 1214: perPort *pp; ! 1215: static void *oldHandler; ! 1216: static UInt32 oldRefcon; ! 1217: static USBReference oldRef; ! 1218: ! 1219: if(pb->usbCompletion != hubStatusChangeHandler) ! 1220: { ! 1221: oldHandler = pb->usbCompletion; ! 1222: pb->usbCompletion = hubStatusChangeHandler; ! 1223: oldRefcon = pb->usbRefcon; ! 1224: pb->usbRefcon = 1; ! 1225: oldRef = pb->usbReference; ! 1226: pb->usbReference = hubRef; ! 1227: USBExpertStatus(hubDevRef, "Hub Status change",0); ! 1228: } ! 1229: ! 1230: pp = (void *)pb; /* parameter block has been extended */ ! 1231: if(handleError(pb)) ! 1232: return; ! 1233: ! 1234: do{switch(pb->usbRefcon++) ! 1235: { ! 1236: case 1: ! 1237: /* Now get hub status */ ! 1238: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBDevice); ! 1239: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1240: pb->usb.cntl.WValue = 0; ! 1241: pb->usb.cntl.WIndex = 0; ! 1242: pb->usbReqCount = sizeof(hubStatus); ! 1243: pb->usbBuffer = &hubStatus; ! 1244: ! 1245: noteError("Hub Driver Error - kUSBRqGetStatus (get status before turning on ports)"); ! 1246: if(immediateError(USBDeviceRequest(pb))) ! 1247: { ! 1248: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1249: } ! 1250: ! 1251: break; ! 1252: ! 1253: case 2: ! 1254: hubStatus.status = USBToHostWord(hubStatus.status); ! 1255: hubStatus.change = USBToHostWord(hubStatus.change); ! 1256: if(bit(hubStatus.change, kHubLocalPowerStatusChange) ) ! 1257: { ! 1258: USBExpertStatus(hubDevRef, "Hub Driver - Local Power Status Change detected",0); ! 1259: /* Reset the change enable status */ ! 1260: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBDevice); ! 1261: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 1262: pb->usb.cntl.WValue = kUSBHubLocalPowerChangeFeature; ! 1263: pb->usb.cntl.WIndex = 0; ! 1264: pb->usbReqCount = 0; ! 1265: pb->usbBuffer = nil; ! 1266: ! 1267: noteError("Hub Driver Error - kUSBRqClearFeature (clear 'hub local power change' feature)"); ! 1268: if(immediateError(USBDeviceRequest(pb))) ! 1269: { ! 1270: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1271: } ! 1272: } ! 1273: else ! 1274: { ! 1275: pb->usbRefcon+=2; /* Skip the next status */ ! 1276: continue; /* Carry on with next case */ ! 1277: } ! 1278: break; ! 1279: ! 1280: case 3: ! 1281: /* Now get hub status */ ! 1282: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBDevice); ! 1283: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1284: pb->usb.cntl.WValue = 0; ! 1285: pb->usb.cntl.WIndex = 0; ! 1286: pb->usbReqCount = sizeof(hubStatus); ! 1287: pb->usbBuffer = &hubStatus; ! 1288: ! 1289: noteError("Hub Driver Error - kUSBRqGetStatus (get status before turning on ports)"); ! 1290: if(immediateError(USBDeviceRequest(pb))) ! 1291: { ! 1292: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1293: } ! 1294: break; ! 1295: ! 1296: case 4: ! 1297: hubStatus.status = USBToHostWord(hubStatus.status); ! 1298: hubStatus.change = USBToHostWord(hubStatus.change); ! 1299: continue; ! 1300: break; ! 1301: ! 1302: case 5: ! 1303: if(bit(hubStatus.change, kHubOverCurrentIndicatorChange) ) ! 1304: { ! 1305: USBExpertStatus(hubDevRef, "Hub Driver - OverCurrent Indicator Change detected",0); ! 1306: /* Reset the change enable status */ ! 1307: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBDevice); ! 1308: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 1309: pb->usb.cntl.WValue = kUSBHubOverCurrentChangeFeature; ! 1310: pb->usb.cntl.WIndex = 0; ! 1311: pb->usbReqCount = 0; ! 1312: pb->usbBuffer = nil; ! 1313: ! 1314: noteError("Hub Driver Error - kUSBRqClearFeature (clear 'hub local power change' feature)"); ! 1315: if(immediateError(USBDeviceRequest(pb))) ! 1316: { ! 1317: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1318: } ! 1319: } ! 1320: else ! 1321: { ! 1322: pb->usbRefcon+=2; /* Skip the next status */ ! 1323: continue; /* Carry on with next case */ ! 1324: } ! 1325: break; ! 1326: ! 1327: case 6: ! 1328: /* Now get hub status */ ! 1329: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBDevice); ! 1330: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1331: pb->usb.cntl.WValue = 0; ! 1332: pb->usb.cntl.WIndex = 0; ! 1333: pb->usbReqCount = sizeof(hubStatus); ! 1334: pb->usbBuffer = &hubStatus; ! 1335: ! 1336: noteError("Hub Driver Error - kUSBRqGetStatus (get status before turning on ports)"); ! 1337: if(immediateError(USBDeviceRequest(pb))) ! 1338: { ! 1339: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1340: } ! 1341: break; ! 1342: ! 1343: case 7: ! 1344: hubStatus.status = USBToHostWord(hubStatus.status); ! 1345: hubStatus.change = USBToHostWord(hubStatus.change); ! 1346: continue; ! 1347: break; ! 1348: ! 1349: case 8: ! 1350: pb->usbCompletion = oldHandler; ! 1351: pb->usbRefcon = oldRefcon; ! 1352: pb->usbReference = oldRef; ! 1353: ! 1354: pb->usbReqCount = 10; ! 1355: USBExpertStatus(hubDevRef, "Hub Driver - calling delay reentering poll loop", 10); ! 1356: USBDelay(pb); ! 1357: break; ! 1358: ! 1359: default: ! 1360: noteError("Hub Driver Error - Unused case in hub status change handler"); ! 1361: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1362: break; ! 1363: } ! 1364: break; /* only execute once, unless continue used */ ! 1365: }while(1); /* so case can be reentered with a continue */ ! 1366: } ! 1367: ! 1368: ! 1369: static UInt32 defDoNothingChangeHandler(USBPB *pb) ! 1370: { ! 1371: pb = 0; ! 1372: return(kVectorContinueImmed); ! 1373: } ! 1374: ! 1375: static UInt32 deadConnectionChangeHandler(USBPB *pb) ! 1376: { ! 1377: perPort *pp; ! 1378: pp = (void *)pb; /* parameter block has been extended */ ! 1379: if(!bit(pp->portStatus.portFlags, kHubPortConnection)) ! 1380: { ! 1381: USBExpertStatus(hubDevRef, "Hub dead driver - disconnect", 0); ! 1382: pp->state = kNormal; ! 1383: pp->retries = kInitialRetries; ! 1384: initPortVectors(pp->changeHandler); ! 1385: pp->delay = 0; ! 1386: } ! 1387: return(kVectorContinueImmed); ! 1388: } ! 1389: ! 1390: static UInt32 defOverCrntChangeHandler(USBPB *pb) ! 1391: { ! 1392: perPort *pp; ! 1393: pp = (void *)pb; /* parameter block has been extended */ ! 1394: USBExpertStatus(hubDevRef, "Hub Driver - Over current change notification", 0); ! 1395: pp->state = kDead; ! 1396: return(kVectorContinueImmed); ! 1397: } ! 1398: ! 1399: static UInt32 defResetChangeHandler(USBPB *pb) ! 1400: { ! 1401: perPort *pp; ! 1402: pp = (void *)pb; /* parameter block has been extended */ ! 1403: USBExpertStatus(hubDevRef, "Hub Driver - Resett change notification", 0); ! 1404: pp->state = kDead; ! 1405: return(kVectorContinueImmed); ! 1406: } ! 1407: ! 1408: static UInt32 defSuspendChangeHandler(USBPB *pb) ! 1409: { ! 1410: perPort *pp; ! 1411: pp = (void *)pb; /* parameter block has been extended */ ! 1412: USBExpertStatus(hubDevRef, "Hub Driver - Resett change notification", 0); ! 1413: return(kVectorContinueImmed); ! 1414: } ! 1415: ! 1416: static UInt32 defEndableChangeHandler(USBPB *pb) ! 1417: { ! 1418: perPort *pp; ! 1419: pp = (void *)pb; /* parameter block has been extended */ ! 1420: do{switch(pb->usbRefcon >> kPortVectorStageShift) ! 1421: { ! 1422: case 1: ! 1423: if(!bit(pp->portStatus.portFlags, kHubPortEnabled) && ! 1424: !bit(pp->portStatus.portChangeFlags, kHubPortConnection) ) ! 1425: { ! 1426: /* The hub gave us an enable status change and we're now disabled, strange */ ! 1427: /* Cosmo does this sometimes, try Re-enabling the port */ ! 1428: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1429: pb->usb.cntl.BRequest = kUSBRqSetFeature; ! 1430: pb->usb.cntl.WValue = kUSBHubPortEnablenFeature; ! 1431: pb->usb.cntl.WIndex = pp->portIndex; ! 1432: pb->usbReqCount = 0; ! 1433: pb->usbBuffer = nil; ! 1434: ! 1435: USBExpertStatus(hubDevRef, "Hub driver - re-enabling dead port", pp->portIndex); ! 1436: noteError("Hub Driver Error - kUSBRqSetFeature (trying to re-enable port)"); ! 1437: if(immediateError(USBDeviceRequest(pb))) ! 1438: { ! 1439: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1440: } ! 1441: } ! 1442: else ! 1443: { ! 1444: return(kVectorContinueImmed); ! 1445: } ! 1446: break; ! 1447: ! 1448: case 2: ! 1449: return(kVectorContinueImmed); ! 1450: break; ! 1451: ! 1452: default: ! 1453: noteError("Hub Driver Error - Unused case in enable change handler"); ! 1454: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1455: break; ! 1456: } ! 1457: break; /* only execute once, unless continue used */ ! 1458: }while(1); /* so case can be reentered with a continue */ ! 1459: return(kVectorNotfinished); ! 1460: } ! 1461: ! 1462: static UInt32 defConnectionChangeHandler(USBPB *pb) ! 1463: { ! 1464: perPort *pp; ! 1465: OSStatus err; ! 1466: ! 1467: pp = (void *)pb; /* parameter block has been extended */ ! 1468: do{switch(pb->usbRefcon >> kPortVectorStageShift) ! 1469: { ! 1470: case 1: ! 1471: pb->usbReqCount = 97; /* Power on wait 100ms, plus at least 3 control requests */ ! 1472: pb->usbFlags = 0; ! 1473: pb->usbStatus = noErr; ! 1474: ! 1475: //USBExpertStatus(hubDevRef, "Hub Driver - PS2 calling delay", 100); ! 1476: noteError("Hub Driver Error - delaying before adding device"); ! 1477: if(immediateError(USBDelay(pb))) ! 1478: { ! 1479: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1480: } ! 1481: break; ! 1482: ! 1483: case 2: ! 1484: ! 1485: /* If we get to here, there was a connection change */ ! 1486: /* if we already have a device it must have been disconnected */ ! 1487: /* at sometime. We should kill it before serviceing a connect event */ ! 1488: if(pp->newDevRef != 0) ! 1489: { /* already removed, dead device?? */ ! 1490: pb->usbReference = pp->newDevRef; ! 1491: USBExpertStatus(hubDevRef, "Hub driver - Removing dead device:", pb->usbRefcon); ! 1492: noteError("Hub Driver Error - removing dead device"); ! 1493: err = USBHubDeviceRemoved(pb); ! 1494: if(immediateError(err)) ! 1495: { /* hub error procedures not needed for this */ ! 1496: USBExpertFatalError(hubDevRef, pb->usbStatus, pp->errorString, 0); ! 1497: break; ! 1498: } ! 1499: if(err == noErr) ! 1500: { /* completed immediatly */ ! 1501: pb->usbRefcon += kPortVectorStage1; ! 1502: continue; ! 1503: } ! 1504: } ! 1505: else ! 1506: { ! 1507: pb->usbRefcon += kPortVectorStage1; ! 1508: continue; ! 1509: } ! 1510: break; ! 1511: ! 1512: case 3: ! 1513: ! 1514: if(pp->newDevRef != 0) ! 1515: { /* this bit transplanted from end of case above */ ! 1516: USBExpertRemoveDeviceDriver(pp->newDevRef); ! 1517: pp->newDevRef = 0; ! 1518: ! 1519: ! 1520: pp->delay = 0; ! 1521: pp->retries = kInitialRetries; ! 1522: /* Disconnection on the port */ ! 1523: } ! 1524: ! 1525: // BT 23Jul98 Check port again after delay. Get bounced connections ! 1526: /* Do a port status request on current port */ ! 1527: pb->usbReference = hubRef; ! 1528: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBOther); ! 1529: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1530: pb->usb.cntl.WValue = 0; /* Standard type 0 and index 0 */ ! 1531: pb->usb.cntl.WIndex = pp->portIndex; ! 1532: pb->usbReqCount = sizeof(USBHubPortStatus); ! 1533: pb->usbBuffer = &pp->portStatus; ! 1534: ! 1535: noteError("Hub Driver Error - kUSBRqGetStatus (after delay)"); ! 1536: if(immediateError(USBDeviceRequest(pb))) ! 1537: { ! 1538: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1539: } ! 1540: break; ! 1541: ! 1542: case 4: ! 1543: pp->portStatus.portChangeFlags = USBToHostWord(pp->portStatus.portChangeFlags); ! 1544: pp->portStatus.portFlags = USBToHostWord(pp->portStatus.portFlags); ! 1545: ! 1546: // USBExpertStatus(hubDevRef, "Hub driver - port status", pp->portStatus.portFlags); ! 1547: // USBExpertStatus(hubDevRef, "Hub driver - port change", pp->portStatus.portChangeFlags); ! 1548: if(bit(pp->portStatus.portChangeFlags, kHubPortConnection) ) ! 1549: { ! 1550: USBExpertStatus(hubDevRef, "Hub driver - Connection bounce:", pb->usbReference); ! 1551: ! 1552: return(kVectorContinueImmed); ! 1553: } ! 1554: ! 1555: if( bit(pp->portStatus.portFlags, kHubPortConnection) ) ! 1556: { /* We have a connection on this port */ ! 1557: ! 1558: pb->usbCompletion = hubAddDeviceHandler; ! 1559: pb->usbRefcon = 1; ! 1560: pb->usbStatus = noErr; ! 1561: pb->usbFlags = 0; ! 1562: ! 1563: hubAddDeviceHandler(pb); ! 1564: } ! 1565: else ! 1566: { ! 1567: return(kVectorfinishedImmed); ! 1568: } ! 1569: break; ! 1570: ! 1571: default: ! 1572: noteError("Hub Driver Error - Unused case in connection change handler"); ! 1573: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1574: break; ! 1575: } ! 1576: break; /* only execute once, unless continue used */ ! 1577: }while(1); /* so case can be reentered with a continue */ ! 1578: return(kVectorNotfinished); ! 1579: } ! 1580: ! 1581: ! 1582: static void portStatusChangedHandler(USBPB *pb) ! 1583: { ! 1584: perPort *pp; ! 1585: int which, ret; ! 1586: static getDescLoop; ! 1587: ! 1588: pp = (void *)pb; /* parameter block has been extended */ ! 1589: ! 1590: if(handleError(pb)) ! 1591: return; ! 1592: ! 1593: do{switch( (pb->usbRefcon++) & kPortHandlerStageMask) ! 1594: { ! 1595: case 1: ! 1596: ! 1597: pb->usbReference = hubRef; ! 1598: ! 1599: /* Do a port status request on current port */ ! 1600: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBOther); ! 1601: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1602: pb->usb.cntl.WValue = 0; /* Standard type 0 and index 0 */ ! 1603: pb->usb.cntl.WIndex = pp->portIndex; ! 1604: pb->usbReqCount = sizeof(USBHubPortStatus); ! 1605: pb->usbBuffer = &pp->portStatus; ! 1606: ! 1607: pb->usbFlags = 0; // These were getting set during error processing ! 1608: ! 1609: noteError("Hub Driver Error - kUSBRqGetStatus (first after port status change)"); ! 1610: if(immediateError(USBDeviceRequest(pb))) ! 1611: { ! 1612: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1613: } ! 1614: break; ! 1615: ! 1616: case 2: ! 1617: pp->portStatus.portChangeFlags = USBToHostWord(pp->portStatus.portChangeFlags); ! 1618: pp->portStatus.portFlags = USBToHostWord(pp->portStatus.portFlags); ! 1619: ! 1620: getDescLoop = (pb->usbRefcon & kPortHandlerStageMask); ! 1621: continue; ! 1622: break; ! 1623: ! 1624: case 3: ! 1625: pb->usbRefcon &= kPortHandlerStageMask; ! 1626: ! 1627: for(which = 0; which<numChangeHandlers; which++) ! 1628: { ! 1629: if( (pp->portStatus.portChangeFlags & pp->changeHandler[which].bit) != 0 ) ! 1630: { ! 1631: pb->usbRefcon += which*kPortWhichVector1; ! 1632: break; ! 1633: } ! 1634: } ! 1635: if(which >= numChangeHandlers) ! 1636: { ! 1637: pb->usbRefcon = 0; // Handled all changed bits ! 1638: } ! 1639: else ! 1640: { ! 1641: continue; ! 1642: } ! 1643: break; ! 1644: ! 1645: case 4: ! 1646: which = (pb->usbRefcon & kPortVectorStageMask) >> kPortWhichVectorShift; ! 1647: ! 1648: /* Reset the changed status */ ! 1649: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1650: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 1651: pb->usb.cntl.WValue = pp->changeHandler[which].clearFeature; ! 1652: pb->usb.cntl.WIndex = pp->portIndex; ! 1653: pb->usbReqCount = 0; ! 1654: pb->usbBuffer = nil; ! 1655: ! 1656: noteError("Hub Driver Error - kUSBRqClearFeature (clear port vector bit feature)"); ! 1657: if(immediateError(USBDeviceRequest(pb))) ! 1658: { ! 1659: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1660: } ! 1661: break; ! 1662: ! 1663: case 5: ! 1664: pb->usbReference = hubRef; ! 1665: ! 1666: /* Do a port status request on current port */ ! 1667: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBOther); ! 1668: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1669: pb->usb.cntl.WValue = 0; /* Standard type 0 and index 0 */ ! 1670: pb->usb.cntl.WIndex = pp->portIndex; ! 1671: pb->usbReqCount = sizeof(USBHubPortStatus); ! 1672: pb->usbBuffer = &pp->portStatus; ! 1673: ! 1674: noteError("Hub Driver Error - kUSBRqGetStatus (second after port status change)"); ! 1675: if(immediateError(USBDeviceRequest(pb))) ! 1676: { ! 1677: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1678: } ! 1679: break; ! 1680: ! 1681: case 6: ! 1682: pp->portStatus.portChangeFlags = USBToHostWord(pp->portStatus.portChangeFlags); ! 1683: pp->portStatus.portFlags = USBToHostWord(pp->portStatus.portFlags); ! 1684: continue; ! 1685: ! 1686: case 7: ! 1687: ! 1688: which = (pb->usbRefcon & kPortVectorStageMask) >> kPortWhichVectorShift; ! 1689: pb->usbRefcon--; // come back to here for completion ! 1690: pb->usbRefcon += kPortVectorStage1; // Step the handlers stage on ! 1691: ! 1692: ret = (*pp->changeHandler[which].handler)(pb); ! 1693: ! 1694: if( (kVectorContinueImmed == ret) || (kVectorContinueDelayed == ret) ) ! 1695: { ! 1696: pb->usbRefcon = getDescLoop; ! 1697: if(kVectorContinueImmed == ret) ! 1698: { ! 1699: continue; ! 1700: } ! 1701: } ! 1702: else if(kVectorfinishedImmed == ret) ! 1703: { ! 1704: pb->usbRefcon = 0; ! 1705: } ! 1706: else if(kVectorNotfinished == ret) ! 1707: { ! 1708: } ! 1709: break; ! 1710: ! 1711: default: ! 1712: noteError("Hub Driver Error - Unused case in port status change handler"); ! 1713: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1714: break; ! 1715: } ! 1716: break; /* only execute once, unless continue used */ ! 1717: }while(1); /* so case can be reentered with a continue */ ! 1718: } ! 1719: ! 1720: ! 1721: static void intPipeHandler(USBPB *pb) ! 1722: { ! 1723: perPort *pp, *intPort; ! 1724: static UInt8 buffer[256/8+1]; ! 1725: static numBytes; ! 1726: static readPipeLoop; ! 1727: int byteCounter, bitMask, portIndex; ! 1728: ! 1729: if(handleError(pb)) ! 1730: return; ! 1731: ! 1732: pp = (void *)pb; /* parameter block has been extended */ ! 1733: ! 1734: do{switch(pb->usbRefcon++) ! 1735: { ! 1736: case 1: ! 1737: pb->usbReference = hubRef; ! 1738: /* Open the pipes (there's only one) in the interface */ ! 1739: pb->usb.cntl.WValue = 0; ! 1740: pb->usbFlags = 0; ! 1741: ! 1742: pb->usbReqCount = 0; ! 1743: pb->usbActCount = 0; ! 1744: pb->usbBuffer = 0; ! 1745: ! 1746: pb->usbOther = 0; // alternative interface ! 1747: ! 1748: noteError("Hub Driver Error - USBConfigureInterface"); ! 1749: if(immediateError(USBConfigureInterface(pb))) ! 1750: { ! 1751: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1752: } ! 1753: break; ! 1754: ! 1755: case 2: ! 1756: ! 1757: /* Find out when we first ask for the int, so enumeration */ ! 1758: /* completion can work out its not going to happen. */ ! 1759: pb->usbFlags = 0; ! 1760: if(USBGetFrameNumberImmediate(pb) != noErr) ! 1761: { ! 1762: USBExpertStatus(hubDevRef, "Hub driver - Frame number error:", pb->usbReference); ! 1763: intFrame = 1; ! 1764: } ! 1765: else ! 1766: { ! 1767: intFrame = pb->usbFrame; ! 1768: } ! 1769: ! 1770: /* New reads to this pipe will go to the same place we are */ ! 1771: readPipeLoop = pb->usbRefcon; ! 1772: ! 1773: /* Find the pipe ref for the (only) pipe */ ! 1774: pb->usbFlags = kUSBIn; ! 1775: pb->usbClassType = kUSBInterrupt; ! 1776: noteError("Hub Driver Error - finding interrupt pipe"); ! 1777: if(immediateError(USBFindNextPipe(pb))) ! 1778: { ! 1779: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1780: } ! 1781: break; ! 1782: ! 1783: case 3: ! 1784: pb->usbFlags = 0; ! 1785: ! 1786: /* reference is now int pipe */ ! 1787: numBytes = (numPorts+1)/8+1; ! 1788: pb->usbReqCount = numBytes; ! 1789: pb->usbBuffer = buffer; ! 1790: noteError("Hub Driver Error - Reading interrupt pipe"); ! 1791: if(immediateError(USBIntRead(pb))) ! 1792: { ! 1793: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1794: } ! 1795: break; ! 1796: ! 1797: case 4: ! 1798: ! 1799: /* Now interpret the status returned */ ! 1800: pb->usbRefcon = readPipeLoop; /* end up back at the beginning */ ! 1801: ! 1802: bitMask = 2; ! 1803: byteCounter = 0; ! 1804: for(portIndex = 1; portIndex <= numPorts; portIndex++) ! 1805: { ! 1806: if( (buffer[byteCounter] & bitMask) != 0 ) ! 1807: { ! 1808: intPort = &ports[portIndex]; // Do it this way so debugger can see pp ! 1809: if(intPort->pb.usbRefcon != 0) ! 1810: { ! 1811: // Maybe want to count failures here ! 1812: USBExpertStatus(hubDevRef, "Hub Driver - Interrupt while hub was busy", portIndex); ! 1813: } ! 1814: else ! 1815: { ! 1816: intFrame = 0xffffffff; /* note an interrupt happened. */ ! 1817: intPort->pb.usbStatus = noErr; ! 1818: intPort->pb.usbRefcon = 1; ! 1819: intPort->pb.usbCompletion = portStatusChangedHandler; ! 1820: portStatusChangedHandler(&intPort->pb); ! 1821: } ! 1822: } ! 1823: bitMask <<= 1; ! 1824: if(bitMask > 128) ! 1825: { ! 1826: bitMask = 1; ! 1827: byteCounter++; ! 1828: } ! 1829: } ! 1830: ! 1831: if((buffer[0] & 1) != 0) ! 1832: { /* hub status changed */ ! 1833: intFrame = 0xffffffff; /* note an interrupt happened. */ ! 1834: hubStatusChangeHandler(pb); ! 1835: break; ! 1836: } ! 1837: else ! 1838: { ! 1839: OSStatus ret_status; ! 1840: ! 1841: if(HubAreWeFinishedYet() == noErr) ! 1842: { ! 1843: pb->usbReqCount = 255; ! 1844: } ! 1845: else ! 1846: { ! 1847: pb->usbReqCount = 20; ! 1848: } ! 1849: noteError("Hub Driver - Delay after hub status change"); ! 1850: //USBExpertStatus(hubDevRef, "Hub Driver - Pipe calling delay", pb->usbReqCount); ! 1851: if(immediateError(ret_status = USBDelay(pb))) ! 1852: { ! 1853: kprintf("USB: immediateError delay %d\n", ret_status); ! 1854: HubFatalError(pp, pb->usbStatus, pp->errorString, pb->usbReqCount); ! 1855: } ! 1856: } ! 1857: break; ! 1858: default: ! 1859: noteError("Hub Driver Error - Unused case in interrupt handler"); ! 1860: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 1861: break; ! 1862: } ! 1863: break; /* only execute once, unless continue used */ ! 1864: }while(1); /* so case can be reentered with a continue */ ! 1865: } ! 1866: ! 1867: ! 1868: static void startPorts(USBPB *pb) ! 1869: { ! 1870: perPort *pp; ! 1871: int currentPort, byte, mask; ! 1872: ! 1873: if(handleError(pb)) ! 1874: return; ! 1875: ! 1876: pp = (void *)pb; /* parameter block has been extended */ ! 1877: ! 1878: do{switch(pb->usbRefcon++) ! 1879: { ! 1880: case 1: ! 1881: ! 1882: /* These help with port removable and power flags */ ! 1883: byte = 0; ! 1884: mask = 2; /* First bit is reserved */ ! 1885: ! 1886: for(currentPort = 1; currentPort <= numPorts; currentPort++) ! 1887: { ! 1888: ! 1889: pp = &ports[currentPort]; ! 1890: pp->pb = *pb; ! 1891: pp->pb.pbLength = sizeof(perPort); ! 1892: pp->pb.pbVersion = kUSBCurrentPBVersion; ! 1893: ! 1894: initPortVectors(pp->changeHandler); ! 1895: ! 1896: pp->portIndex = currentPort; ! 1897: pp->retries = kInitialRetries; ! 1898: pp->delay = 0; ! 1899: ! 1900: /* Setup port mask for this port, ready for next */ ! 1901: pp->portByte = byte; ! 1902: pp->portMask = mask; ! 1903: if( startExternal || ( (hubDesc.removablePortFlags[byte] & mask) != 0) ) ! 1904: { ! 1905: startPorts(&pp->pb); /* Carry on with next case, with new pb */ ! 1906: } ! 1907: ! 1908: mask <<= 1; ! 1909: if(mask > 0x80) ! 1910: { ! 1911: mask = 1; ! 1912: byte++; ! 1913: } ! 1914: } ! 1915: ! 1916: ! 1917: break; ! 1918: ! 1919: case 2: ! 1920: /* Power the port */ ! 1921: ! 1922: /* Maybe should only do this if there is power switching */ ! 1923: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1924: pb->usb.cntl.BRequest = kUSBRqSetFeature; ! 1925: pb->usb.cntl.WValue = kUSBHubPortPowerFeature; ! 1926: pb->usb.cntl.WIndex = pp->portIndex; ! 1927: pb->usbReqCount = 0; ! 1928: pb->usbBuffer = nil; ! 1929: ! 1930: noteError("Hub Driver - kUSBRqSetFeature (Powering on port)"); ! 1931: if(immediateError(USBDeviceRequest(pb))) ! 1932: { ! 1933: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1934: } ! 1935: break; ! 1936: ! 1937: case 3: ! 1938: if( (hubDesc.removablePortFlags[pp->portByte] & pp->portMask) == 0) ! 1939: { ! 1940: pb->usbRefcon = 0; ! 1941: break; // This is all done by the int handler hopefully. ! 1942: /* Tell the world we're finsihed */ ! 1943: } ! 1944: // This for static hub ! 1945: // Debugger(); ! 1946: /* wait for the power on good time */ ! 1947: ! 1948: pb->usbReqCount = hubDesc.powerOnToGood * 2; ! 1949: /* pb->usbFlags = kUSBtaskTime */ ! 1950: ! 1951: //USBExpertStatus(hubDevRef, "Hub Driver - Power on calling delay", pb->usbReqCount); ! 1952: noteError("Hub Driver - Waiting for port to power on"); ! 1953: if(immediateError(USBDelay(pb))) ! 1954: { ! 1955: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1956: } ! 1957: break; ! 1958: ! 1959: case 4: ! 1960: /* We should now be in the disconnected state */ ! 1961: ! 1962: /* Do a port request on current port */ ! 1963: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBOther); ! 1964: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 1965: pb->usb.cntl.WValue = 0; /* Standard type 0 and index 0 */ ! 1966: pb->usb.cntl.WIndex = pp->portIndex; ! 1967: pb->usbReqCount = sizeof(USBHubPortStatus); ! 1968: pb->usbBuffer = &pp->portStatus; ! 1969: ! 1970: noteError("Hub Driver - kUSBRqGetStatus (after power on)"); ! 1971: if(immediateError(USBDeviceRequest(pb))) ! 1972: { ! 1973: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1974: } ! 1975: break; ! 1976: ! 1977: case 5: ! 1978: pp->portStatus.portChangeFlags = USBToHostWord(pp->portStatus.portChangeFlags); ! 1979: pp->portStatus.portFlags = USBToHostWord(pp->portStatus.portFlags); ! 1980: /* we now have port status */ ! 1981: if(bit(pp->portStatus.portChangeFlags, kHubPortConnection) ) ! 1982: { ! 1983: /* Reset the change connection status */ ! 1984: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBClass, kUSBOther); ! 1985: pb->usb.cntl.BRequest = kUSBRqClearFeature; ! 1986: pb->usb.cntl.WValue = kUSBHubPortConnectionChangeFeature; ! 1987: pb->usb.cntl.WIndex = pp->portIndex; ! 1988: pb->usbReqCount = 0; ! 1989: pb->usbBuffer = nil; ! 1990: ! 1991: noteError("Hub Driver - kUSBRqClearFeature (clear 'port change connection' feature"); ! 1992: if(immediateError(USBDeviceRequest(pb))) ! 1993: { ! 1994: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 1995: } ! 1996: ! 1997: } ! 1998: else ! 1999: { ! 2000: pb->usbRefcon+=2; /* Skip the next status */ ! 2001: continue; /* Carry on with next case */ ! 2002: } ! 2003: break; ! 2004: ! 2005: case 6: ! 2006: /* We should now be in the disconnected state */ ! 2007: /* Do a port request on current port */ ! 2008: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBOther); ! 2009: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 2010: pb->usb.cntl.WValue = 0; /* Standard type 0 and index 0 */ ! 2011: pb->usb.cntl.WIndex = pp->portIndex; ! 2012: pb->usbReqCount = sizeof(USBHubPortStatus); ! 2013: pb->usbBuffer = &pp->portStatus; ! 2014: ! 2015: noteError("Hub Driver - kUSBRqGetStatus (after change connection)"); ! 2016: if(immediateError(USBDeviceRequest(pb))) ! 2017: { ! 2018: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2019: } ! 2020: break; ! 2021: ! 2022: case 7: ! 2023: pp->portStatus.portChangeFlags = USBToHostWord(pp->portStatus.portChangeFlags); ! 2024: pp->portStatus.portFlags = USBToHostWord(pp->portStatus.portFlags); ! 2025: continue; ! 2026: break; ! 2027: ! 2028: case 8: ! 2029: if( bit(pp->portStatus.portFlags, kHubPortConnection) ) ! 2030: { /* We have a connection on this port */ ! 2031: ! 2032: pb->usbCompletion = hubAddDeviceHandler; ! 2033: pb->usbRefcon = 1; ! 2034: pb->usbStatus = noErr; ! 2035: ! 2036: hubAddDeviceHandler(pb); ! 2037: } ! 2038: else ! 2039: { ! 2040: pb->usbRefcon = 0; // this should never happen, but don't freeze port ! 2041: } ! 2042: // Static hub ! 2043: break; ! 2044: ! 2045: default: ! 2046: noteError("Hub Driver Error - Unused case in start ports"); ! 2047: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 2048: break; ! 2049: } ! 2050: break; /* only execute once, unless continue used */ ! 2051: }while(1); /* so case can be reentered with a continue */ ! 2052: } ! 2053: ! 2054: ! 2055: static void hubHandler(USBPB *pb) ! 2056: { ! 2057: perPort *pp; ! 2058: USBDeviceDescriptor *desc; ! 2059: static USBConfigurationDescriptor conf; ! 2060: UInt32 powerStatus; ! 2061: ! 2062: if(handleError(pb)) ! 2063: return; ! 2064: ! 2065: pp = (void *)pb; /* parameter block has been extended */ ! 2066: kprintf("hubHandler:usbRefcon=%d,ref=0x%x\n",pb->usbRefcon,pb->usbReference); ! 2067: do{switch(pb->usbRefcon++) ! 2068: { ! 2069: case 1: ! 2070: hubRef = pb->usbReference; /* remember who we are */ ! 2071: hubDevRef = hubRef; /* remember the dev ref to talk to expt */ ! 2072: ! 2073: desc = pb->usbBuffer; ! 2074: ! 2075: errataBits = GetErrataBits(desc); ! 2076: if(errataBits != 0) ! 2077: { ! 2078: USBExpertStatus(hubDevRef, "Hub Driver - Using errata:", errataBits); ! 2079: } ! 2080: ! 2081: hubSubClass = desc->deviceSubClass; /* Old hubs = 1, new hubs = 0 it seems */ ! 2082: noteError("Hub Driver Error - Device not recognized"); ! 2083: if(desc->numConf != 1) ! 2084: { ! 2085: USBExpertStatus(hubDevRef, "Hub Driver - Device has more than 1 configuration. Using first", numPorts); ! 2086: } ! 2087: /* get the full config descriptor */ ! 2088: if(hubSubClass == 1) ! 2089: { ! 2090: pp->value = 0; /* Hope 0 is the first one */ ! 2091: } ! 2092: else ! 2093: { ! 2094: pp->value = 1; /* Hope 1 is the first one */ ! 2095: } ! 2096: pp->onError = pb->usbRefcon; /* Try the clause below again on error */ ! 2097: #if 0 ! 2098: // This bit tests device reset. You don't normally want it here ! 2099: if(hubSubClass == 1) ! 2100: { ! 2101: continue; ! 2102: } ! 2103: pb->usbFlags = 0; ! 2104: noteError("Hub Driver Error - hub reset"); ! 2105: kprintf("hubHandler:calling USBResetDevice: ref=0x%x\n",pb->usbReference); ! 2106: if(immediateError(USBResetDevice(pb))) ! 2107: { ! 2108: USBExpertStatus(hubDevRef, "Hub driver - Immediate error testing reset", pb->usbStatus); ! 2109: continue; ! 2110: //HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2111: } ! 2112: #else ! 2113: continue; ! 2114: #endif ! 2115: break; ! 2116: ! 2117: case 2: ! 2118: pb->usbClassType = kUSBHubClass; /* hub class */ ! 2119: pb->usbSubclass = hubSubClass; /* hub subclass, as in the device descriptor */ ! 2120: /* Could make this wild, but devices which have these different are bad */ ! 2121: pb->usbProtocol = 0; /* any protocol */ ! 2122: ! 2123: pb->usbReqCount = 0; ! 2124: pb->usbActCount = 0; ! 2125: pb->usbBuffer = 0; ! 2126: ! 2127: pb->usb.cntl.WValue = 0; // first config ! 2128: pb->usb.cntl.WIndex = 0; // first interface ! 2129: pb->usbOther = 0xff;// first alt ! 2130: ! 2131: pb->usbReqCount = busPowerAvail; ! 2132: pp->onError = pb->usbRefcon; ! 2133: ! 2134: noteError("Hub Driver - Getting interface"); ! 2135: kprintf("hubHandler:case 2 calling USBFindNextInterface: ref=0x%x\n",pb->usbReference); ! 2136: if(immediateError(USBFindNextInterface(pb))) ! 2137: { /* this should return immediatly */ ! 2138: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2139: break; /* Nothing else to do now */ ! 2140: } ! 2141: ! 2142: break; ! 2143: ! 2144: case 3: ! 2145: if(pb->usbStatus == kUSBDevicePowerProblem) ! 2146: { ! 2147: noteError("Hub Driver - Insufficient power to configure hub"); ! 2148: USBExpertSetDevicePowerStatus(hubDevRef, 0, 0, kUSBDevicePower_BusPowerInsufficient, busPowerAvail, kUSB500mAAvailable); // TC: <USB67> ! 2149: } ! 2150: ! 2151: if(pb->usbStatus != noErr) ! 2152: { ! 2153: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2154: break; ! 2155: } ! 2156: pb->usbReqCount = sizeof(conf); ! 2157: pb->usbBuffer = &conf; ! 2158: ! 2159: noteError("Hub Driver - Getting config descriptor"); ! 2160: kprintf("hubHandler:case 3 calling USBGetConfig: ref=0x%x\n",pb->usbReference); ! 2161: if(immediateError(USBGetConfigurationDescriptor(pb))) ! 2162: { /* this should return immediatly */ ! 2163: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2164: break; /* Nothing else to do now */ ! 2165: } ! 2166: ! 2167: break; ! 2168: ! 2169: case 4: ! 2170: ! 2171: /* Work out some power bits */ ! 2172: ! 2173: busPowered = (conf.attributes & kUSBAtrBusPowered) != 0; ! 2174: selfPowered = (conf.attributes & kUSBAtrSelfPowered) != 0; ! 2175: ! 2176: noteError("Hub Driver Error - Illegal device configuration, no power"); ! 2177: if( !(busPowered || selfPowered) ) ! 2178: { /* Neither slef nor bus powered, its dead!!! */ ! 2179: HubFatalError(pp, kUSBUnknownDeviceErr, pp->errorString, 0); ! 2180: break; /* Now what ?? */ ! 2181: } ! 2182: ! 2183: /* these got set up to read the descriptor. */ ! 2184: pb->usbReqCount = 0; ! 2185: pb->usbActCount = 0; ! 2186: pb->usbBuffer = 0; ! 2187: ! 2188: /* for error recovery */ ! 2189: pp->value = 1-pp->value; ! 2190: ! 2191: /* There is an interface for us, Configure the device */ ! 2192: //pb->usb.cntl.WValue = pb->usbValue4; // have to sort out this ! 2193: noteError("Hub Driver Error - Getting full configuration descriptor"); ! 2194: kprintf("HubClassDriver.c:case 4 SetConfig: ref=0x%x\n",pb->usbReference); ! 2195: if(immediateError(USBSetConfiguration(pb))) ! 2196: { ! 2197: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2198: } ! 2199: kprintf("hubDriver:setconfig complete****\n"); ! 2200: break; ! 2201: ! 2202: case 5: ! 2203: ! 2204: ! 2205: /* find an interface ref to work with */ ! 2206: noteError("Hub Driver Error - USBNewInterfaceRef"); ! 2207: kprintf("HubClassDriver.c:case 5 calling USBNewInterfaceRef\n"); ! 2208: if(immediateError(USBNewInterfaceRef(pb))) ! 2209: { ! 2210: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2211: } ! 2212: break; ! 2213: ! 2214: ! 2215: ! 2216: case 6: ! 2217: /* Now remember the interface ref */ ! 2218: hubRef = pb->usbReference; ! 2219: ! 2220: /* Mess with get hub descriptor */ ! 2221: if(hubSubClass == 0) ! 2222: { ! 2223: pp->value = 0; /* Standard type 0 and index 0 */ ! 2224: } ! 2225: else ! 2226: { ! 2227: pp->value = 0x2900; /* for atmel Standard type 0 and index 0 */ ! 2228: } ! 2229: pp->onError = pb->usbRefcon; /* Try the clause below again on error */ ! 2230: continue; ! 2231: break; ! 2232: ! 2233: ! 2234: case 7: ! 2235: /* Switch the value for retry */ ! 2236: pp->value = 0x2900 - pp->value; ! 2237: pb->usb.cntl.WValue = pp->value; ! 2238: ! 2239: /* Start things off, lets find out what the hub is */ ! 2240: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBClass, kUSBDevice); ! 2241: pb->usb.cntl.BRequest = kUSBRqGetDescriptor; ! 2242: pb->usb.cntl.WIndex = 0; ! 2243: pb->usbReqCount = sizeof(hubDescriptor) -1; ! 2244: pb->usbBuffer = &hubDesc.length; ! 2245: ! 2246: noteError("Hub Driver Error - kUSBRqGetDescriptor (get device descriptor)"); ! 2247: if(immediateError(USBDeviceRequest(pb))) ! 2248: { ! 2249: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2250: } ! 2251: break; ! 2252: ! 2253: case 8: ! 2254: /* Hub get descriptor now finished */ ! 2255: numPorts = hubDesc.numPorts; ! 2256: { ! 2257: /* Unpack the port flags */ ! 2258: int numFlags, i; ! 2259: numFlags = (numPorts+1)/8+1; ! 2260: for(i = 0; i < numFlags; i++) ! 2261: { ! 2262: hubDesc.pwrCtlPortFlags[i] = hubDesc.removablePortFlags[numFlags+i]; ! 2263: hubDesc.removablePortFlags[numFlags+i] = 0; ! 2264: } ! 2265: } ! 2266: ! 2267: /* Work out some bits for compound devices */ ! 2268: numCaptive = 0; ! 2269: // if(hubDesc.characteristics & kHubIsCompound) ! 2270: { ! 2271: int i, portMask = 2, portByte = 0; ! 2272: for(i = 1; i<=numPorts; i++) ! 2273: { ! 2274: if( (hubDesc.removablePortFlags[portByte] & portMask) != 0) ! 2275: { ! 2276: numCaptive++; ! 2277: } ! 2278: portMask <<= 1; ! 2279: if(portMask > 0x80) ! 2280: { ! 2281: portMask = 1; ! 2282: portByte++; ! 2283: } ! 2284: } ! 2285: } ! 2286: ! 2287: if(numPorts > kMaxPorts) ! 2288: { ! 2289: /* Need to allocate more port structs here */ ! 2290: USBExpertStatus(hubDevRef, "Hub Driver - Allocating more ports", numPorts); ! 2291: ! 2292: pb->usbReqCount = (numPorts+1)*sizeof(perPort); ! 2293: pp->onError = pb->usbRefcon; ! 2294: noteError("Hub Driver Error - Allocating memory for ports"); ! 2295: USBAllocMem(pb); ! 2296: } ! 2297: else ! 2298: { ! 2299: pb->usbRefcon++; ! 2300: continue; ! 2301: } ! 2302: break; ! 2303: ! 2304: case 9: ! 2305: /* new ports allocated */ ! 2306: if(pb->usbBuffer == nil) ! 2307: { ! 2308: /* carry on with only pre allocated ports */ ! 2309: numPorts = kMaxPorts; ! 2310: USBExpertStatus(hubDevRef, "Hub Driver Error - Allocating more ports failed", numPorts); ! 2311: continue; ! 2312: } ! 2313: else ! 2314: { ! 2315: USBExpertStatus(hubDevRef, "Hub Driver - More ports allcated", pb->usbActCount); ! 2316: ports = pb->usbBuffer; ! 2317: ports[0] = *pp; ! 2318: pb = (void *)ports; ! 2319: continue; ! 2320: } ! 2321: break; ! 2322: ! 2323: case 10: ! 2324: if(busPowered) ! 2325: { ! 2326: UInt32 pHub, pAvailForPorts,pNeededForPorts; ! 2327: /* Note hub current in units of 1mA, everything else in units of 2mA */ ! 2328: pHub = hubDesc.hubCurrent/2; ! 2329: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* pHub:", pHub); ! 2330: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* busPowerAvail:", busPowerAvail); ! 2331: if(pHub > busPowerAvail) ! 2332: { ! 2333: /* this is illegal??? */ ! 2334: USBExpertStatus(hubDevRef, "Hub Driver - Hub needs more power than available", pb->usbActCount); ! 2335: USBExpertSetDevicePowerStatus(hubDevRef, 0, 0, kUSBDevicePower_BusPowerInsufficient, busPowerAvail, pHub); // TC: <USB67> ! 2336: break; /* Thats that. */ ! 2337: } ! 2338: pAvailForPorts = busPowerAvail-pHub; ! 2339: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* pAvailForPorts:", pAvailForPorts); ! 2340: pNeededForPorts = (numPorts-numCaptive)*kUSB100mA; ! 2341: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* numPorts:", numPorts); ! 2342: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* numCaptive:", numCaptive); ! 2343: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* pNeededForPorts:", pNeededForPorts); ! 2344: busPowerGood = pAvailForPorts >= pNeededForPorts; ! 2345: //USBExpertStatus(hubDevRef, "Hub Driver - *Power* busPowerGood:", busPowerGood); ! 2346: if(numCaptive > 0) ! 2347: { ! 2348: if(busPowerGood) ! 2349: { ! 2350: powerForCaptive = (pAvailForPorts - pNeededForPorts)/numCaptive; ! 2351: } ! 2352: else ! 2353: { ! 2354: powerForCaptive = pAvailForPorts/numCaptive; ! 2355: } ! 2356: } ! 2357: ! 2358: if( (errataBits & kErrataCaptiveOK) != 0) ! 2359: { ! 2360: powerForCaptive = kUSB100mAAvailable; ! 2361: } ! 2362: } ! 2363: ! 2364: if(selfPowered) ! 2365: { ! 2366: /* Now get power status before turning on ports */ ! 2367: pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBIn, kUSBStandard, kUSBDevice); ! 2368: pb->usb.cntl.BRequest = kUSBRqGetStatus; ! 2369: pb->usb.cntl.WValue = 0; ! 2370: pb->usb.cntl.WIndex = 0; ! 2371: pb->usbReqCount = sizeof(deviceStatus); ! 2372: pb->usbBuffer = &deviceStatus; ! 2373: ! 2374: noteError("Hub Driver Error - kUSBRqGetStatus (get status before turning on ports)"); ! 2375: if(immediateError(USBDeviceRequest(pb))) ! 2376: { ! 2377: HubFatalError(pp, pb->usbStatus, pp->errorString, 0); ! 2378: } ! 2379: } ! 2380: else ! 2381: { ! 2382: continue; ! 2383: } ! 2384: break; ! 2385: ! 2386: case 11: ! 2387: ! 2388: /* Now have hub power status */ ! 2389: if(selfPowered) ! 2390: { ! 2391: deviceStatus = USBToHostWord(deviceStatus); ! 2392: selfPowerGood = ((deviceStatus & 1) != 0); ! 2393: } ! 2394: ! 2395: //OSStatus USBExpertSetDevicePowerStatus(USBDeviceRef ref, UInt32 powerStatus, UInt32 busPowerAvailable, UInt32 busPowerNeeded ) ! 2396: ! 2397: if(selfPowered && busPowered) ! 2398: { ! 2399: /* Duel power hub */ ! 2400: if(selfPowerGood) ! 2401: { ! 2402: powerStatus = kUSBDevicePower_PowerOK; ! 2403: USBExpertStatus(hubDevRef, "Hub attached - Self/Bus powered, power supply good", 0); ! 2404: } ! 2405: else ! 2406: { ! 2407: powerStatus = kUSBDevicePower_SelfPowerInsufficient; ! 2408: USBExpertStatus(hubDevRef, "Hub attached - Self/Bus powered, no external power", 0); ! 2409: } ! 2410: } ! 2411: else ! 2412: { ! 2413: /* Single power hub */ ! 2414: if(selfPowered) ! 2415: { ! 2416: if(selfPowerGood) ! 2417: { ! 2418: powerStatus = kUSBDevicePower_PowerOK; ! 2419: USBExpertStatus(hubDevRef, "Externally powered Hub attached - power supply good", 0); ! 2420: } ! 2421: else ! 2422: { ! 2423: powerStatus = kUSBDevicePower_SelfPowerInsufficient; ! 2424: USBExpertStatus(hubDevRef, "Externally powered Hub attached - no external power", 0); ! 2425: } ! 2426: } ! 2427: else ! 2428: { ! 2429: powerStatus = kUSBDevicePower_BusPowerInsufficient; ! 2430: USBExpertStatus(hubDevRef, "Bus powered Hub attached", 0); ! 2431: } ! 2432: ! 2433: } ! 2434: ! 2435: ! 2436: startExternal = (busPowerGood || selfPowerGood); ! 2437: if( !startExternal ) ! 2438: { /* not plugged in or bus powered on a bus powered hub */ ! 2439: USBExpertStatus(kUSBUnknownDeviceErr, "Hub Driver Error - Insufficient power to turn on ports", 0); ! 2440: USBExpertSetDevicePowerStatus(hubDevRef, 0, 0, powerStatus, busPowerAvail, busPowered?kUSB500mAAvailable:0); // TC: <USB67> ! 2441: if(!busPowered) ! 2442: { ! 2443: /* may be able to turn on compound devices */ ! 2444: break; /* Now what ?? */ ! 2445: } ! 2446: } ! 2447: ! 2448: //USBExpertStatus(kUSBUnknownDeviceErr, "Hub Starting ports, ext:", startExternal); ! 2449: //USBExpertStatus(kUSBUnknownDeviceErr, "Hub compound power:", powerForCaptive); ! 2450: pb->usbStatus = noErr; ! 2451: pb->usbCompletion = startPorts; ! 2452: pb->usbRefcon = 1; ! 2453: startPorts(pb); ! 2454: ! 2455: pb->usbCompletion = intPipeHandler; ! 2456: pb->usbRefcon = 1; ! 2457: pb->usbStatus = noErr; ! 2458: pp = (void *)pb; ! 2459: pp->retries = kInitialRetries; ! 2460: intPipeHandler(pb); ! 2461: ! 2462: break; ! 2463: ! 2464: default: ! 2465: noteError("Hub Driver Error - Unused case in hub handler"); ! 2466: HubFatalError(pp, kUSBInternalErr, pp->errorString, pb->usbRefcon); ! 2467: break; ! 2468: } ! 2469: break; /* only execute once, unless continue used */ ! 2470: }while(1); /* so case can be reentered with a continue */ ! 2471: } ! 2472: ! 2473: #if 0 ! 2474: ExtPower ! 2475: Good off ! 2476: ! 2477: Bus Self ! 2478: ! 2479: 0 0 Illegal config ! 2480: ! 2481: 0 1 Always 100mA per port ! 2482: ! 2483: 1 0 500mA 0 (dead) ! 2484: ! 2485: 1 1 500 100 ! 2486: ! 2487: #endif ! 2488: ! 2489: ! 2490: static OSStatus killHub(USBDeviceRef device) ! 2491: { /* This hub has died, kill its children */ ! 2492: int i; ! 2493: perPort *pp; ! 2494: USBPB *pb; ! 2495: ! 2496: pp = &ports[0]; ! 2497: if(device != hubDevRef) ! 2498: { ! 2499: HubFatalError(pp, kUSBUnknownDeviceErr, "Hub driver - Kill hub called with wrong ref num", 0); ! 2500: return(kUSBUnknownDeviceErr); ! 2501: } ! 2502: ! 2503: ! 2504: for(i = 1; i<= numPorts; i++) ! 2505: { ! 2506: pp = &ports[i]; ! 2507: pb = &pp->pb; ! 2508: pb->usbReference = pp->newDevRef; ! 2509: pb->usbCompletion = kUSBNoCallBack; // we're supposed to be called at task time ! 2510: if(pp->newDevRef != 0) ! 2511: { ! 2512: USBExpertStatus(hubDevRef, "Hub driver - Removing dead child:", pb->usbReference); ! 2513: noteError("Hub Driver Error - removing dead child"); ! 2514: if(immediateError(USBHubDeviceRemoved(pb))) ! 2515: { ! 2516: USBExpertStatus(hubDevRef, "Hub driver - Failed to remove dead child:", pb->usbReference); ! 2517: } ! 2518: ! 2519: USBExpertRemoveDeviceDriver(pp->newDevRef); ! 2520: ! 2521: pp->newDevRef = 0; ! 2522: pb->usbRefcon = 0; ! 2523: ! 2524: pp->delay = 0; ! 2525: pp->retries = kInitialRetries; ! 2526: } ! 2527: } ! 2528: ! 2529: pp = &ports[0]; ! 2530: pb = &pp->pb; ! 2531: if(pb->usbStatus == kUSBPending) ! 2532: { ! 2533: HubFatalError(pp, kUSBPending, "Hub driver - transaction still outstanding", 0); ! 2534: return(kUSBAlreadyOpenErr); ! 2535: } ! 2536: ! 2537: if(staticPorts != ports) ! 2538: { /* we allocated our own */ ! 2539: USBExpertStatus(hubDevRef, "Hub driver - Deallocating allocated ports", 0); ! 2540: pp = &staticPorts[0]; ! 2541: pb = &pp->pb; // make sure to use a static port for this. ! 2542: pb->usbCompletion = kUSBNoCallBack; ! 2543: pb->usbBuffer = ports; ! 2544: ! 2545: if(immediateError(USBDeallocMem(pb))) ! 2546: { ! 2547: USBExpertStatus(hubDevRef, "Hub driver - Failed to deallocate:", pb->usbStatus); ! 2548: } ! 2549: } ! 2550: ! 2551: ! 2552: ! 2553: pb->usbReference = hubRef; ! 2554: pb->usbCompletion = kUSBNoCallBack; ! 2555: pb->usbFlags = 0; ! 2556: USBDisposeInterfaceRef(pb); ! 2557: ! 2558: return(noErr); ! 2559: } ! 2560: ! 2561: static OSStatus resetPortRequest(USBPB *pb, UInt32 port) ! 2562: { ! 2563: pb = &ports[port].pb; ! 2564: ! 2565: pb->usbCompletion = doPortResetHandler; ! 2566: pb->usbRefcon = 1; ! 2567: pb->usbStatus = noErr; ! 2568: pb->usbFlags = 0; ! 2569: ! 2570: doPortResetHandler(pb); ! 2571: return(kUSBPending); ! 2572: } ! 2573: ! 2574: static OSStatus resetPortPowerRequest(USBPB *pb, UInt32 port) ! 2575: { ! 2576: USBExpertStatus(hubDevRef, "Hub driver - port power request, not implimented", port); ! 2577: pb=0; ! 2578: return(kUSBUnknownRequestErr); ! 2579: } ! 2580: ! 2581: static OSStatus resetRequest(USBPB *pb, UInt32 port) ! 2582: { ! 2583: if(bit(pb->usbFlags, kUSBPowerReset)) ! 2584: { ! 2585: return(resetPortPowerRequest(pb, port)); ! 2586: } ! 2587: else ! 2588: { ! 2589: return(resetPortRequest(pb, port)); ! 2590: } ! 2591: } ! 2592: ! 2593: ! 2594: ! 2595: // A.W. this next function is unused anywhere, so I'll just comment it ! 2596: // out to avoid clashing with original HubClassDriver.c ! 2597: ! 2598: #ifdef NOT_USED_ANYWHERE ! 2599: OSStatus HubChildMessage(USBReference deviceRef, USBPB *pb) ! 2600: { ! 2601: int port=1; ! 2602: Boolean busy; ! 2603: OSStatus err; ! 2604: ! 2605: // USBExpertStatus(hubDevRef, "Hub driver - Child message for device:", deviceRef); ! 2606: while(port<= numPorts) ! 2607: { ! 2608: if(ports[port].newDevRef == deviceRef) ! 2609: { ! 2610: break; ! 2611: } ! 2612: port++; ! 2613: } ! 2614: if(port > numPorts) ! 2615: { ! 2616: return(kUSBUnknownDeviceErr); ! 2617: } ! 2618: ! 2619: busy = !CompareAndSwap(nil, (UInt32)pb, (UInt32 *)&ports[port].portRequestPB); ! 2620: if(!busy) ! 2621: { ! 2622: busy = !CompareAndSwap(0, 1, &ports[port].pb.usbRefcon); ! 2623: if(busy) ! 2624: { ! 2625: ports[port].portRequestPB = nil; /* port is otherwise busy, so clear request */ ! 2626: } ! 2627: } ! 2628: if(busy) ! 2629: { ! 2630: USBExpertStatus(hubDevRef, "Hub driver - request on busy port:", port); ! 2631: return(kUSBDeviceBusy); ! 2632: } ! 2633: ! 2634: // USBExpertStatus(hubDevRef, "Hub driver - Child message for port:", port); ! 2635: ! 2636: if(pb->usb.hub.Request == kUSBHubPortResetRequest) ! 2637: { ! 2638: err = resetRequest(pb, port); ! 2639: } ! 2640: else ! 2641: { ! 2642: err = kUSBUnknownRequestErr; ! 2643: } ! 2644: if(err != kUSBPending) ! 2645: { ! 2646: ports[port].portRequestPB = nil; ! 2647: ports[port].pb.usbRefcon = 0; ! 2648: } ! 2649: return(err); ! 2650: } ! 2651: #endif ! 2652: ! 2653: ! 2654: ! 2655: //A.W. This looks like the one unique function called from uslExpert, so ! 2656: // this name must be changed for hub 0 or hub 1. I'll call it "2" for now. ! 2657: ! 2658: void Hub2DriverEntry(USBDeviceRef device, USBDeviceDescriptor *desc, UInt32 busPowerAvailable) ! 2659: { ! 2660: static Boolean beenThereDoneThat = false; ! 2661: //VersRec vers; ! 2662: //OSStatus err; ! 2663: ! 2664: if(beenThereDoneThat) ! 2665: { ! 2666: USBExpertFatalError(device, kUSBInternalErr, "Hub driver called second time", 0); ! 2667: return; ! 2668: } ! 2669: //Hot Plug n Play ! 2670: //naga beenThereDoneThat = true; ! 2671: ! 2672: // err = USBServicesGetVersion(1, &vers, sizeof(vers)); ! 2673: // err = USBServicesGetVersion(2, &vers, sizeof(vers)); ! 2674: ! 2675: ports[0].pb.pbLength = sizeof(perPort); ! 2676: ports[0].pb.pbVersion = kUSBCurrentHubPB; ! 2677: ports[0].pb.usbStatus = noErr; ! 2678: ports[0].pb.usbReference = device; ! 2679: ports[0].pb.usbCompletion = hubHandler; ! 2680: ports[0].pb.usbRefcon = 1; ! 2681: ports[0].pb.usbBuffer = desc; ! 2682: ! 2683: ports[0].retries = kInitialRetries; ! 2684: ports[0].delay = 0; ! 2685: ports[0].errorString = ""; ! 2686: ! 2687: busPowerAvail = busPowerAvailable; ! 2688: kprintf("HubDriverEntry:calling hubHandler:ref=0x%x\n",ports[0].pb.usbReference); ! 2689: hubHandler(&ports[0].pb); ! 2690: } ! 2691: ! 2692:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.