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