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