|
|
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.