|
|
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: rootHubSimulation.c ! 27: ! 28: Contains: Packet level simulation of root hub functions ! 29: ! 30: Version: Neptune 1.0 ! 31: ! 32: Copyright: � 1998 by Apple Computer, Inc., all rights reserved. ! 33: ! 34: File Ownership: ! 35: ! 36: DRI: Barry Twycross ! 37: ! 38: Other Contact: xxx put other contact here xxx ! 39: ! 40: Technology: USB ! 41: ! 42: Writers: ! 43: ! 44: (DF) David Ferguson ! 45: (DKF) David Ferguson ! 46: (CJK) Craig Keithley ! 47: (BT) Barry Twycross ! 48: ! 49: Change History (most recent first): ! 50: ! 51: <USB27> 6/14/98 DF change implemented spelling. ! 52: <USB26> 5/20/98 BT Fix alt settings field of interface descriptor ! 53: <USB25> 5/17/98 BT Make get conf descriptor more forgiving. Fix hub endpoint desc ! 54: <USB24> 5/14/98 DF Add status messages for unimplemented root hub stuff, also use ! 55: info from the UIM when getting the hub status. ! 56: <USB23> 4/23/98 BT Fix reset portsuspend change feature ! 57: <USB22> 4/20/98 BT Add device status ! 58: <USB21> 4/16/98 BT Eliminate debugger ! 59: <USB20> 4/15/98 BT More root hub capabilities ! 60: <USB19> 4/9/98 BT Use USB.h ! 61: <18> 4/2/98 BT Do OPTI chip gang switching, fix sim stall error number ! 62: <17> 3/19/98 BT Split UIM into UIM and root hub parts ! 63: <16> 3/18/98 BT Add port enable and clear port enable change features ! 64: <15> 3/11/98 BT interrupt transaction simulation ! 65: <14> 3/9/98 BT Eliminate one set of redundant descriptors ! 66: <13> 2/27/98 BT Add string descriptors ! 67: <12> 2/25/98 BT Add Apple product codes. ! 68: <11> 2/24/98 BT Change Apple vendor ID. ! 69: <10> 2/23/98 BT Simulate root hub to not corrupt reqCount ! 70: <USB9> 2/9/98 DKF Byte swap configuration descriptor totalLength field ! 71: <8> 2/8/98 BT More Power allocation stuff ! 72: <7> 2/4/98 BT Cope with multiple configs ! 73: <6> 1/30/98 BT Put Apple vendor ID in root hub device descriptor ! 74: <5> 1/26/98 CJK Change to use USBDeviceDescriptor (instead of just ! 75: devicedescriptor) ! 76: <4> 1/26/98 BT Mangle names after design review ! 77: <3> 1/20/98 BT Endian swap port status, and other fixes ! 78: <2> 1/20/98 BT More root hub simulation ! 79: <1> 1/19/98 BT first checked in ! 80: */ ! 81: ! 82: #include <USB.h> ! 83: #include <USBpriv.h> ! 84: #include "OHCIUIM.h" ! 85: #include "OHCIRootHub.h" ! 86: #include "uimpriv.h" ! 87: #include "uslpriv.h" ! 88: #include "hub.h" ! 89: #include <DriverServices.h> ! 90: ! 91: static UInt16 configuration; ! 92: ! 93: static Boolean SimulateSetConfiguration(UInt16 value) ! 94: { ! 95: if((value == 1) || (value == 0) ) ! 96: { ! 97: configuration = value; ! 98: return(false); ! 99: } ! 100: return(true); ! 101: } ! 102: ! 103: static Boolean SimulateGetDeviceDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex) ! 104: { ! 105: UInt32 length; ! 106: static USBDeviceDescriptor desc ={ ! 107: 18, // UInt8 length; ! 108: kUSBDeviceDesc, // UInt8 descType; ! 109: USB_CONSTANT16(kUSBRel10), // UInt16 usbRel; ! 110: kUSBHubClass, // UInt8 class; ! 111: kUSBHubSubClass, // UInt8 subClass; ! 112: 0, // UInt8 protocol; ! 113: 8, // UInt8 maxPacketSize; ! 114: USB_CONSTANT16(kAppleVendorID), // UInt16 vendor; Apple = 1452 (decimal, swapped) ! 115: USB_CONSTANT16(kPrdRootHubCMD), // UInt16 product; 0x8001 ! 116: USB_CONSTANT16(0x0100), // UInt16 devRel; 1.00 ! 117: 0, // UInt8 manuIdx; ! 118: 0, // UInt8 prodIdx; ! 119: 0, // UInt8 serialIdx; ! 120: 1, // UInt8 numConf; ! 121: 0 // UInt16 end; ! 122: }; ! 123: ! 124: if(descIndex != 0) ! 125: { ! 126: return(true); ! 127: } ! 128: ! 129: length = sizeof(desc); ! 130: if(*bufLen < length) ! 131: { ! 132: length = *bufLen; ! 133: } ! 134: usb_BlockMoveData(&desc, buf, length); ! 135: *bufLen -= length; ! 136: ! 137: return(false); ! 138: } ! 139: ! 140: static Boolean SimulateGetConfDescriptor(UInt8 *buf, UInt32 *bufLen, UInt32 descIndex) ! 141: { ! 142: UInt32 length; ! 143: #define totalLen (9+9+7) ! 144: static USBConfigurationDescriptor confDesc ={ ! 145: 9, //UInt8 length; ! 146: kUSBConfDesc, //UInt8 descriptorType; ! 147: USB_CONSTANT16(totalLen), //UInt16 totalLength; ! 148: 1, //UInt8 numInterfaces; ! 149: 1, //UInt8 configValue; ! 150: 0, //UInt8 configStrIndex; ! 151: 0x60, //UInt8 attributes; self powered, supports remote wkup ! 152: 0, //UInt8 maxPower; ! 153: }; ! 154: static USBInterfaceDescriptor intfDesc ={ ! 155: 9, //UInt8 length; ! 156: kUSBInterfaceDesc, //UInt8 descriptorType; ! 157: 1, //UInt8 interfaceNumber; ! 158: 0, //UInt8 alternateSetting; ! 159: 1, //UInt8 numEndpoints; ! 160: kUSBHubClass, //UInt8 interfaceClass; ! 161: kUSBHubSubClass, //UInt8 interfaceSubClass; ! 162: 1, //UInt8 interfaceProtocol; ! 163: 0 //UInt8 interfaceStrIndex; ! 164: }; ! 165: static USBEndPointDescriptor endptDesc ={ ! 166: 7, //UInt8 length; ! 167: kUSBEndpointDesc, //UInt8 descriptorType; ! 168: 0x81, //UInt8 endpointAddress; In, 1 ! 169: kUSBInterrupt, //UInt8 attributes; ! 170: USB_CONSTANT16(8), //UInt16 maxPacketSize; ! 171: 255, //UInt8 interval; ! 172: }; ! 173: UInt8 confBuf[totalLen]; ! 174: ! 175: if(descIndex != 0) ! 176: { ! 177: //return(true); // temp don't make this fail while debugging root hub ! 178: } ! 179: if(totalLen != confDesc.length+intfDesc.length+endptDesc.length) ! 180: { ! 181: return(true); ! 182: } ! 183: usb_BlockMoveData(&confDesc, &confBuf[0], confDesc.length); ! 184: usb_BlockMoveData(&intfDesc, &confBuf[confDesc.length], intfDesc.length); ! 185: usb_BlockMoveData(&endptDesc, &confBuf[confDesc.length+intfDesc.length], endptDesc.length); ! 186: ! 187: length = totalLen; ! 188: if(*bufLen < length) ! 189: { ! 190: length = *bufLen; ! 191: } ! 192: usb_BlockMoveData(&confBuf, buf, length); ! 193: *bufLen -= length; ! 194: ! 195: return(false); ! 196: } ! 197: ! 198: static Boolean SimulateGetADeviceDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen) ! 199: { ! 200: UInt8 descType, descIndex; ! 201: descType = USBToHostWord(packet->word[wValue]) >> 8; ! 202: descIndex = USBToHostWord(packet->word[wValue]) & 0xff; ! 203: if( (packet->word[wIndex] != 0) || (descType != kUSBStringDesc) ) ! 204: { ! 205: /* This is not a string descriptor and its is not a string descriptor */ ! 206: if(descType == kUSBDeviceDesc) ! 207: { ! 208: return(SimulateGetDeviceDescriptor(buf, bufLen, descIndex)); ! 209: } ! 210: else if(descType == kUSBConfDesc) ! 211: { ! 212: return(SimulateGetConfDescriptor(buf, bufLen, descIndex)); ! 213: } ! 214: else ! 215: { ! 216: return(true); /* Unknown dscriptor */ ! 217: } ! 218: } ! 219: else if(descType == kUSBStringDesc) ! 220: { ! 221: /* cope with string descriptor */ ! 222: return(true); ! 223: } ! 224: ! 225: /* Non zero index with non string descriptor */ ! 226: return(true); ! 227: ! 228: } ! 229: ! 230: static Boolean SimulateGetHubDescriptor(setupPacket *packet, UInt8 *buf, UInt32 *bufLen) ! 231: { ! 232: uslRootHubDescriptor descr; ! 233: int bytesOfFlags, copy, length; ! 234: ! 235: if(packet->word[wValue] == 0) ! 236: { ! 237: ! 238: if(UIMGetRootDescriptor(&descr) != noErr) ! 239: { ! 240: return(true); ! 241: } ! 242: ! 243: length = *bufLen; ! 244: ! 245: if(length > 0) ! 246: { ! 247: /* Descriptor length */ ! 248: bytesOfFlags = (descr.numPorts+1)/8+1; ! 249: buf[0] = bytesOfFlags*2 + 7; ! 250: length--; ! 251: } ! 252: if(length > 0) ! 253: { ! 254: /* Descriptor type */ ! 255: buf[1] = kUSBHubDescriptorType; ! 256: length--; ! 257: } ! 258: if(length > 0) ! 259: { ! 260: buf[2] = descr.numPorts; ! 261: length--; ! 262: } ! 263: if(length > 0) ! 264: { ! 265: if(descr.powerSwitching) ! 266: { ! 267: buf[3] = !descr.gangedSwitching; ! 268: } ! 269: else ! 270: { ! 271: buf[3] = 2; ! 272: } ! 273: if(descr.compoundDevice) ! 274: { ! 275: buf[3] |= 4; ! 276: } ! 277: if(descr.overCurrent) ! 278: { ! 279: buf[3] = (!descr.globalOverCurrent) << 3; ! 280: } ! 281: else ! 282: { ! 283: buf[3] |= 0x10; ! 284: } ! 285: length--; ! 286: } ! 287: if(length > 0) ! 288: { ! 289: /* Flags high byte */ ! 290: buf[4] = 0; ! 291: length--; ! 292: } ! 293: if(length > 0) ! 294: { ! 295: /* power on to good */ ! 296: buf[5] = 50; /* 100 ms? */ ! 297: length--; ! 298: } ! 299: if(length > 0) ! 300: { ! 301: /* Hub controller current */ ! 302: buf[6] = 0; /* no cuurrent from bus */ ! 303: length--; ! 304: } ! 305: if(length > 0) ! 306: { ! 307: copy = length; ! 308: if(copy > bytesOfFlags) ! 309: { ! 310: copy = bytesOfFlags; ! 311: } ! 312: usb_BlockMoveData(&descr.portFlags[0], &buf[7], copy); ! 313: length -= copy; ! 314: } ! 315: if(length > 0) ! 316: { ! 317: int copy2; ! 318: copy2 = length; ! 319: if(copy2 > bytesOfFlags) ! 320: { ! 321: copy2 = bytesOfFlags; ! 322: } ! 323: usb_BlockMoveData(&descr.portFlags[copy], &buf[7+copy], copy2); ! 324: length -= copy2; ! 325: } ! 326: ! 327: *bufLen -= length; ! 328: return(false); ! 329: } ! 330: ! 331: return(true); ! 332: ! 333: ! 334: } ! 335: static Boolean SimulateClearPortFeature(setupPacket *packet) ! 336: { ! 337: UInt16 feature, port; ! 338: OSStatus err = -1; ! 339: feature = USBToHostWord(packet->word[wValue]); ! 340: port = USBToHostWord(packet->word[wIndex]); ! 341: ! 342: switch(feature) ! 343: { ! 344: case kUSBHubPortConnectionChangeFeature : ! 345: err =UIMRootHubResetChangeConnection(port); ! 346: break; ! 347: ! 348: case kUSBHubPortSuspendChangeFeature : ! 349: err =UIMRootHubResetChangeSuspend(port); ! 350: break; ! 351: ! 352: case kUSBHubPortEnablenFeature : ! 353: err =UIMRootHubPortEnable(port, false); ! 354: break; ! 355: ! 356: case kUSBHubPortPowerFeature : ! 357: err =UIMRootHubPortPower(port, false); ! 358: // Now need to check if all ports are switched off and ! 359: // gang off if in gang mode ! 360: break; ! 361: ! 362: case kUSBHubPortResetChangeFeature : ! 363: err =UIMRootHubResetResetChange(port); ! 364: break; ! 365: ! 366: case kUSBHubPortEnableChangeFeature : ! 367: err =UIMRootHubResetEnableChange(port); ! 368: break; ! 369: ! 370: case kUSBHubPortOverCurrentChangeFeature : ! 371: err =UIMRootHubResetOverCurrentChange(port); ! 372: break; ! 373: ! 374: ! 375: defualt: ! 376: //DebugStr("\pUnknown port clear"); ! 377: USBExpertStatus(0,"\pUSL - Unknown port clear in root hub simulation", 0); ! 378: break; ! 379: } ! 380: return(err != noErr); ! 381: } ! 382: ! 383: static Boolean SimulateGetHubStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen) ! 384: { ! 385: OSStatus err = -1; ! 386: static struct{ ! 387: UInt16 status; ! 388: UInt16 change; ! 389: }hubStatus = {0,0}; /* Change this is overcurrent is implimeneted */ ! 390: UInt32 rhStatus; ! 391: ! 392: if( (packet->word[wValue] == 0) && (packet->word[wIndex] == 0) ) ! 393: { ! 394: if ((err = UIMGetRhStatus(&rhStatus)) == noErr){ ! 395: ! 396: // wouldn't it be handy to have HostToUSBLong ! 397: hubStatus.status = HostToUSBWord(rhStatus & 0x0FFFF); ! 398: hubStatus.change = HostToUSBWord((rhStatus >> 16) & 0x0FFFF); ! 399: ! 400: if(*bufLen > sizeof(hubStatus)) ! 401: { ! 402: *bufLen = sizeof(hubStatus); ! 403: } ! 404: usb_BlockMoveData(&hubStatus, buf, *bufLen); ! 405: err = noErr; ! 406: } ! 407: } ! 408: return(err != noErr); ! 409: } ! 410: ! 411: ! 412: static Boolean SimulateGetPortStatus(setupPacket *packet, UInt8 *buf, UInt32 *bufLen) ! 413: { ! 414: uslRootHubPortStatus stat; ! 415: OSStatus err = -1; ! 416: UInt32 length; ! 417: ! 418: if(packet->word[wValue] == 0) ! 419: { ! 420: err = UIMRootHubGetPortStatus(USBToHostWord(packet->word[wIndex]), &stat); ! 421: stat.portChangeFlags = USBToHostWord(stat.portChangeFlags); ! 422: stat.portFlags = USBToHostWord(stat.portFlags); ! 423: if(err == noErr) ! 424: { ! 425: length = *bufLen; ! 426: if(length > sizeof(stat)) ! 427: { ! 428: length = sizeof(stat); ! 429: } ! 430: usb_BlockMoveData(&stat, buf, length); ! 431: *bufLen -= length; ! 432: } ! 433: } ! 434: return(err != noErr); ! 435: } ! 436: static Boolean SimulateSetPortFeature(setupPacket *packet) ! 437: { ! 438: UInt16 feature, port; ! 439: OSStatus err = -1; ! 440: feature = USBToHostWord(packet->word[wValue]); ! 441: port = USBToHostWord(packet->word[wIndex]); ! 442: switch(feature) ! 443: { ! 444: case kUSBHubPortSuspecdFeature : ! 445: err = UIMRootHubPortSuspend(port, true); ! 446: break; ! 447: ! 448: case kUSBHubPortResetFeature : ! 449: err = UIMRootHubResetPort(port); ! 450: break; ! 451: ! 452: case kUSBHubPortEnablenFeature : ! 453: err = UIMRootHubPortEnable(port, true); ! 454: break; ! 455: ! 456: case kUSBHubPortPowerFeature : ! 457: err = UIMRootHubPortPower(port, true); ! 458: if(err == noErr) ! 459: { ! 460: err = UIMRootHubPower(true); ! 461: } ! 462: break; ! 463: ! 464: default: ! 465: // DebugStr("\pUnknown port set"); ! 466: USBExpertStatus(0,"\pUSL - Unknown port set in root hub simulation", 0); ! 467: break; ! 468: } ! 469: return(err != noErr); ! 470: } ! 471: ! 472: static Boolean SimulateHubClearFeature(setupPacket *packet) ! 473: { ! 474: OSStatus err = -1; ! 475: if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature) ! 476: { ! 477: USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Power Change Feature", 0); ! 478: // err = UIMRootHubLPSChange(false); // not implemented yet ! 479: } ! 480: if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature) ! 481: { ! 482: USBExpertStatus(0,"\pRoot hub simulation - unimplemented Clear Overcurrent Change Feature", 0); ! 483: // err = UIMRootHubOCChange(false); // not implemented yet ! 484: } ! 485: return(err != noErr); ! 486: } ! 487: static Boolean SimulateHubSetFeature(setupPacket *packet) ! 488: { ! 489: OSStatus err = -1; ! 490: if(packet->word[wValue] == kUSBHubLocalPowerChangeFeature) ! 491: { ! 492: USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Power Change Feature", 0); ! 493: // err = UIMRootHubLPSChange(true); // not implemented yet ! 494: } ! 495: if(packet->word[wValue] == kUSBHubOverCurrentChangeFeature) ! 496: { ! 497: USBExpertStatus(0,"\pRoot hub simulation - unimplemented Set Overcurrent Change Feature", 0); ! 498: // err = UIMRootHubOCChange(true); // not implemented yet ! 499: } ! 500: return(err != noErr); ! 501: } ! 502: ! 503: typedef struct{ ! 504: UInt8 *buf; ! 505: UInt32 bufLen; ! 506: CallBackFuncPtr handler; ! 507: UInt32 refCon; ! 508: }intTrans; ! 509: #define kMaxOutstandingTrans 4 ! 510: ! 511: static intTrans outstanding[kMaxOutstandingTrans]; ! 512: ! 513: static UInt32 intLock; ! 514: ! 515: ! 516: static void rootHubStatusChangeHandler(void) ! 517: { /* Only called if the RHSC bit is set at int. */ ! 518: UInt16 statusChanged; /* only have 15 ports in OHCI */ ! 519: UInt32 status, statusBit; ! 520: uslRootHubDescriptor descr; ! 521: static numPorts; ! 522: int index, move; ! 523: uslRootHubPortStatus stat; ! 524: intTrans last; ! 525: ! 526: last = outstanding[0]; ! 527: if(last.handler == nil) ! 528: { ! 529: return; ! 530: } ! 531: ! 532: if(CompareAndSwap(0, 1, &intLock)) ! 533: { ! 534: for(index = 1; index < kMaxOutstandingTrans ; index++) ! 535: { ! 536: outstanding[index-1] = outstanding[index]; ! 537: if(outstanding[index].handler == nil) ! 538: { ! 539: break; ! 540: } ! 541: } ! 542: ! 543: statusChanged = 0; ! 544: statusBit = 1; ! 545: if(UIMGetRhStatus(&status) == noErr) ! 546: { ! 547: if( (status & kOHCIHcRhStatus_Change ) != 0) ! 548: { ! 549: statusChanged |= statusBit; /* Hub status change bit */ ! 550: } ! 551: ! 552: if(numPorts == 0) ! 553: { ! 554: if(UIMGetRootDescriptor(&descr) == noErr) ! 555: { ! 556: numPorts = descr.numPorts; ! 557: } ! 558: else ! 559: { ! 560: //DebugStr("\pRoot hub int simulation hosed. No ports, tell Barry"); ! 561: USBExpertStatus(0,"\pUSL - Root hub int simulation hosed. No ports, tell Barry", 0); ! 562: } ! 563: } ! 564: ! 565: for(index = 1; index <= numPorts; index++) ! 566: { ! 567: statusBit <<= 1; /* Next bit */ ! 568: ! 569: if(UIMRootHubGetPortStatus(index, &stat) == noErr) ! 570: { ! 571: if(stat.portChangeFlags != 0) ! 572: { ! 573: statusChanged |= statusBit; /* Hub status change bit */ ! 574: } ! 575: } ! 576: ! 577: } ! 578: ! 579: } ! 580: ! 581: move = last.bufLen; ! 582: if(move > sizeof(statusChanged)) ! 583: { ! 584: move = sizeof(statusChanged); ! 585: } ! 586: if(numPorts < 8) ! 587: { ! 588: move = 1; ! 589: } ! 590: statusChanged = HostToUSBWord(statusChanged); ! 591: usb_BlockMoveData(&statusChanged, last.buf, move); ! 592: CompareAndSwap(1, 0, &intLock); /* Unlock the queue */ ! 593: (*last.handler)(last.refCon, noErr, last.bufLen - move); ! 594: } ! 595: } ! 596: ! 597: ! 598: ! 599: ! 600: void pollRootHubSim(void) ! 601: { ! 602: UInt32 intrStatus; ! 603: ! 604: if(outstanding[0].handler != nil) ! 605: { ! 606: if( (UIMGetInterruptStatus(&intrStatus) == noErr) && ! 607: ((intrStatus & kOHCIHcInterrupt_RHSC) != 0) ) ! 608: { ! 609: UIMClearInterruptStatus(kOHCIHcInterrupt_RHSC); ! 610: rootHubStatusChangeHandler(); ! 611: } ! 612: } ! 613: } ! 614: ! 615: void SimulateRootHubInt(UInt8 endpoint, UInt8 *buf, UInt32 bufLen, ! 616: CallBackFuncPtr handler, UInt32 refCon) ! 617: { ! 618: int index; ! 619: ! 620: if(endpoint != 1) ! 621: { ! 622: (*handler)(refCon, -1, bufLen); ! 623: return; ! 624: } ! 625: ! 626: if(!CompareAndSwap(0, 1, &intLock)) ! 627: { /* Busy */ ! 628: (*handler)(refCon, -1, bufLen); ! 629: return; ! 630: } ! 631: ! 632: for(index = 0; index < kMaxOutstandingTrans; index++) ! 633: { ! 634: if(outstanding[0].handler == nil) ! 635: { ! 636: /* found free trans */ ! 637: outstanding[0].buf = buf; ! 638: outstanding[0].bufLen = bufLen; ! 639: outstanding[0].handler = handler; ! 640: outstanding[0].refCon = refCon; ! 641: CompareAndSwap(1, 0, &intLock); /* Unlock the queue */ ! 642: return; ! 643: } ! 644: } ! 645: ! 646: CompareAndSwap(1, 0, &intLock); /* Unlock the queue */ ! 647: (*handler)(refCon, -1, bufLen); /* too many trans */ ! 648: ! 649: } ! 650: ! 651: void SimulateRootHub(setupPacket *packet, UInt8 endpoint, UInt8 *buf, UInt32 inBufLen, ! 652: CallBackFuncPtr handler, UInt32 refCon) ! 653: { ! 654: UInt8 dirn, type, recipient; ! 655: Boolean stall; ! 656: UInt32 *bufLen; ! 657: if(endpoint != 0) ! 658: { ! 659: return; ! 660: } ! 661: bufLen = &inBufLen; /* Barry, was stamping on param block field */ ! 662: ! 663: #if 0 ! 664: typedef union{ ! 665: UInt8 byte[8]; ! 666: UInt16 word[4]; ! 667: }setupPacket; ! 668: ! 669: enum{ ! 670: /* Byte offsets */ ! 671: bmRqType = 0, ! 672: bUsedFlag = bmRqType, ! 673: bRequest, ! 674: /* Word offsets */ ! 675: wValue =1, ! 676: wIndex, ! 677: wLength ! 678: }; ! 679: #endif ! 680: ! 681: stall = false; ! 682: dirn = (packet->byte[bmRqType] >> kUSBRqDirnShift) & kUSBRqDirnMask; ! 683: type = (packet->byte[bmRqType] >> kUSBRqTypeShift) & kUSBRqTypeMask; ! 684: recipient = packet->byte[bmRqType] & kUSBRqRecipientMask; ! 685: ! 686: if(type == kUSBStandard) ! 687: { ! 688: ! 689: #if 0 ! 690: Standard Requests ! 691: ! 692: bmRequestType bRequest wValue wIndex wLength Data ! 693: 00000000B CLEAR_FEATURE device ! 694: 00000001B Interface ! 695: 00000010B Endpoint ! 696: ! 697: 10000000B GET_CONFIGURATION Zero Zero One Configuration ! 698: 10000000B GET_DESCRIPTOR Descriptor ! 699: 10000001B GET_INTERFACE Zero Interface One Alternate ! 700: ! 701: 10000000B GET_STATUS device ! 702: 10000001B Interface ! 703: 10000010B Endpoint ! 704: ! 705: 00000000B SET_ADDRESS Device ! 706: 00000000B SET_CONFIGURATION Configuration ! 707: 00000000B SET_DESCRIPTOR Descriptor ! 708: ! 709: 00000000B SET_FEATURE device ! 710: 00000001B Interface ! 711: 00000010B Endpoint ! 712: ! 713: 00000001B SET_INTERFACE Alternate ! 714: 10000010B SYNCH_FRAME Zero Endpoint Two Frame Number#endif ! 715: #endif ! 716: switch(packet->byte[bRequest]) ! 717: { ! 718: case kUSBRqClearFeature: ! 719: if(packet->byte[bmRqType] == 0x00) ! 720: { ! 721: /* Clear Device Feature */ ! 722: stall = SimulateHubClearFeature(packet); ! 723: } ! 724: else if(packet->byte[bmRqType] == 0x01) ! 725: { ! 726: /* Clear Interface Feature */ ! 727: stall = true; ! 728: //DebugStr("\pRoot hub not implemented yet 2"); ! 729: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 2", 0); ! 730: } ! 731: else if(packet->byte[bmRqType] == 0x02) ! 732: { ! 733: /* Clear Endpoint Feature */ ! 734: stall = true; ! 735: //DebugStr("\pRoot hub not implemented yet 3"); ! 736: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 3", 0); ! 737: } ! 738: else ! 739: { ! 740: stall = true; ! 741: } ! 742: break; ! 743: ! 744: case kUSBRqGetConfig: ! 745: if(packet->byte[bmRqType] == 0x80) ! 746: { ! 747: /* Get configuration */ ! 748: stall = true; ! 749: //DebugStr("\pRoot hub not implemented yet 4"); ! 750: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 4", 0); ! 751: } ! 752: else ! 753: { ! 754: stall = true; ! 755: } ! 756: break; ! 757: ! 758: case kUSBRqGetDescriptor: ! 759: if(packet->byte[bmRqType] == 0x80) ! 760: { ! 761: /* Get descriptor */ ! 762: stall = SimulateGetADeviceDescriptor(packet, buf, bufLen); ! 763: } ! 764: else ! 765: { ! 766: stall = true; ! 767: } ! 768: ! 769: break; ! 770: ! 771: case kUSBRqGetInterface: ! 772: if(packet->byte[bmRqType] == 0x81) ! 773: { ! 774: /* Get interface */ ! 775: stall = true; ! 776: //DebugStr("\pRoot hub not implemented yet 6"); ! 777: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 6", 0); ! 778: } ! 779: else ! 780: { ! 781: stall = true; ! 782: } ! 783: break; ! 784: ! 785: case kUSBRqGetStatus: ! 786: if(packet->byte[bmRqType] == 0x80) ! 787: { ! 788: UInt16 status; ! 789: int copy; ! 790: /* Get Device Status */ ! 791: stall = false; ! 792: status = USB_CONSTANT16(1); // self powered ! 793: copy = sizeof(status); ! 794: if(copy > *bufLen) ! 795: { ! 796: copy = *bufLen; ! 797: } ! 798: usb_BlockMoveData(&status, buf, copy); ! 799: *bufLen -= copy; ! 800: ! 801: } ! 802: else if(packet->byte[bmRqType] == 0x81) ! 803: { ! 804: /* Get Interface Status */ ! 805: stall = true; ! 806: //DebugStr("\pRoot hub not implemented yet 8"); ! 807: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 8", 0); ! 808: } ! 809: else if(packet->byte[bmRqType] == 0x82) ! 810: { ! 811: /* Get Endpoint Status */ ! 812: stall = true; ! 813: //DebugStr("\pRoot hub not implemented yet 9"); ! 814: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 9", 0); ! 815: } ! 816: else ! 817: { ! 818: stall = true; ! 819: } ! 820: break; ! 821: ! 822: case kUSBRqSetAddress: ! 823: if(packet->byte[bmRqType] == 0x00) ! 824: { ! 825: /* Set address */ ! 826: stall = UIMSetOurAddress(USBToHostWord(packet->word[wValue])); ! 827: } ! 828: else ! 829: { ! 830: stall = true; ! 831: } ! 832: break; ! 833: ! 834: case kUSBRqSetConfig: ! 835: if(packet->byte[bmRqType] == 0x00) ! 836: { ! 837: /* Set configuration */ ! 838: stall = SimulateSetConfiguration(USBToHostWord(packet->word[wValue])); ! 839: } ! 840: else ! 841: { ! 842: stall = true; ! 843: } ! 844: break; ! 845: ! 846: case kUSBRqSetDescriptor: ! 847: if(packet->byte[bmRqType] == 0x00) ! 848: { ! 849: /* Set descriptor */ ! 850: stall = true; ! 851: //DebugStr("\pRoot hub not implemented yet 12"); ! 852: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 12", 0); ! 853: } ! 854: else ! 855: { ! 856: stall = true; ! 857: } ! 858: break; ! 859: ! 860: case kUSBRqSetFeature: ! 861: if(packet->byte[bmRqType] == 0x00) ! 862: { ! 863: /* Set Device Feature */ ! 864: stall = SimulateHubSetFeature(packet); ! 865: } ! 866: else if(packet->byte[bmRqType] == 0x01) ! 867: { ! 868: /* Set Interface Feature */ ! 869: stall = true; ! 870: //DebugStr("\pRoot hub not implemented yet 14"); ! 871: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 14", 0); ! 872: } ! 873: else if(packet->byte[bmRqType] == 0x02) ! 874: { ! 875: /* Set Endpoint Feature */ ! 876: stall = true; ! 877: //DebugStr("\pRoot hub not implemented yet 15"); ! 878: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 15", 0); ! 879: } ! 880: else ! 881: { ! 882: stall = true; ! 883: } ! 884: break; ! 885: ! 886: case kUSBRqSetInterface: ! 887: if(packet->byte[bmRqType] == 0x01) ! 888: { ! 889: /* Set interface */ ! 890: stall = true; ! 891: //DebugStr("\pRoot hub not implemented yet 16"); ! 892: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 16", 0); ! 893: } ! 894: else ! 895: { ! 896: stall = true; ! 897: } ! 898: break; ! 899: ! 900: case kUSBRqSyncFrame: ! 901: stall = true; ! 902: break; ! 903: ! 904: default: ! 905: stall = true; ! 906: break; ! 907: ! 908: } ! 909: } ! 910: else if(type == kUSBClass) ! 911: { ! 912: ! 913: #if 0 ! 914: Class-specific Requests ! 915: ! 916: ClearHubFeature 0010 0000B CLEAR_FEATURE Feature ! 917: ClearPortFeature 0010 0011B CLEAR_FEATURE Feature ! 918: GetBusState 1010 0011B GET_STATE Zero Port One Per Port ! 919: GetHubDescriptor 1010 0000B GET_DESCRIPTOR Descriptor ! 920: GetHubStatus 1010 0000B GET_STATUS Zero Zero Four Hub Status ! 921: GetPortStatus 1010 0011B GET_STATUS Zero Port Four Port Status ! 922: SetHubDescriptor 0010 0000B SET_DESCRIPTOR Descriptor ! 923: SetHubFeature 0010 0000B SET_FEATURE Feature ! 924: SetPortFeature 0010 0011B SET_FEATURE Feature ! 925: #endif ! 926: switch(packet->byte[bRequest]) ! 927: { ! 928: case kUSBRqClearFeature: ! 929: if(packet->byte[bmRqType] == 0x20) ! 930: { ! 931: /* ClearHubFeature */ ! 932: stall = true; ! 933: //DebugStr("\pRoot hub not implemented yet 17"); ! 934: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 17", 0); ! 935: } ! 936: else if(packet->byte[bmRqType] == 0x23) ! 937: { ! 938: stall = SimulateClearPortFeature(packet); ! 939: } ! 940: else ! 941: { ! 942: stall = true; ! 943: } ! 944: ! 945: break; ! 946: ! 947: case kUSBRqReserved1 /*GET_STATE*/: ! 948: if(packet->byte[bmRqType] == 0xA3) ! 949: { ! 950: /* GetBusState */ ! 951: stall = true; ! 952: //DebugStr("\pRoot hub not implemented yet 18"); ! 953: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 18", 0); ! 954: } ! 955: else ! 956: { ! 957: stall = true; ! 958: } ! 959: break; ! 960: ! 961: case kUSBRqGetDescriptor: ! 962: if(packet->byte[bmRqType] == 0xA0) ! 963: { ! 964: /* GetHubDescriptor */ ! 965: SimulateGetHubDescriptor(packet, buf, bufLen); ! 966: } ! 967: else ! 968: { ! 969: stall = true; ! 970: } ! 971: ! 972: break; ! 973: ! 974: case kUSBRqGetStatus: ! 975: if(packet->byte[bmRqType] == 0xA0) ! 976: { ! 977: /* GetHubStatus */ ! 978: stall = SimulateGetHubStatus(packet, buf, bufLen); ! 979: } ! 980: else if(packet->byte[bmRqType] == 0xA3) ! 981: { ! 982: stall = SimulateGetPortStatus(packet, buf, bufLen); ! 983: } ! 984: else ! 985: { ! 986: stall = true; ! 987: } ! 988: ! 989: break; ! 990: ! 991: case kUSBRqSetDescriptor: ! 992: if(packet->byte[bmRqType] == 0x20) ! 993: { ! 994: /* SetHubDescriptor */ ! 995: stall = true; ! 996: //DebugStr("\pRoot hub not implemented yet 20"); ! 997: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 20", 0); ! 998: } ! 999: else ! 1000: { ! 1001: stall = true; ! 1002: } ! 1003: ! 1004: break; ! 1005: ! 1006: case kUSBRqSetFeature : ! 1007: if(packet->byte[bmRqType] == 0x20) ! 1008: { ! 1009: /* SetHubFeature */ ! 1010: stall = true; ! 1011: //DebugStr("\pRoot hub not implemented yet 21"); ! 1012: USBExpertStatus(0,"\pUSL - Root hub not implemented yet 21", 0); ! 1013: } ! 1014: else if(packet->byte[bmRqType] == 0x23) ! 1015: { ! 1016: stall = SimulateSetPortFeature(packet); ! 1017: } ! 1018: else ! 1019: { ! 1020: stall = true; ! 1021: } ! 1022: break; ! 1023: ! 1024: default: ! 1025: stall = true; ! 1026: break; ! 1027: } ! 1028: ! 1029: } ! 1030: else ! 1031: { ! 1032: stall = true; ! 1033: } ! 1034: ! 1035: if(stall) ! 1036: { ! 1037: //DebugStr("\pSim Stall"); ! 1038: USBExpertStatus(0,"\pUSL - Root hub simulated stall", 0); ! 1039: } ! 1040: (*handler)(refCon, stall?4:noErr, *bufLen); ! 1041: } ! 1042: ! 1043: void ResetRootHubSimulation(void) ! 1044: { ! 1045: int index; ! 1046: ! 1047: for(index = 0; index < kMaxOutstandingTrans; index++) ! 1048: { ! 1049: outstanding[0].handler = nil; // clear out any outstanding transactions ! 1050: } ! 1051: intLock = 0; ! 1052: } ! 1053:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.