|
|
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: uslUIMInterface.c
27:
28: Contains: Interface between UIM and USL
29:
30: Version: Neptune 1.0
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: USB
41:
42: Writers:
43:
44: (DRF) Dave Falkenburg
45: (bwm) bruce merritt
46: (TC) Tom Clark
47: (CSS) Chas Spillar
48: (GG) Guillermo Gallegos
49: (DF) David Ferguson
50: (DKF) David Ferguson
51: (CJK) Craig Keithley
52: (BT) Barry Twycross
53:
54: Change History (most recent first):
55:
56: <USB81> 11/13/98 BT Delete hub device when removing bus.
57: <USB80> 11/11/98 DRF (CJK) Make sure to check ALL UIMs when polling before returning.
58: Allows us to type in Macsbug on the 3rd or 4th USB port.
59: <USB79> 10/22/98 BT Fix wrong status for deleted devices.
60: <USB78> 10/21/98 DF make probeEndpoint reentrant
61: <USB77> 10/5/98 BT Add root hub to probeendpoint
62: <USB76> 9/29/98 bwm BT: Fix UInt64 problems.
63: <USB75> 9/29/98 BT Use real frame timing
64: <USB74> 9/10/98 DF When removing a bus, clear all references to that bus.
65: <USB73> 9/9/98 BT Fix Isoc
66: <USB72> 9/9/98 BT Use correct number of frames calcing Isoc act count
67: <USB71> 9/3/98 BT Return immediate errors, fix param order
68: <USB70> 9/3/98 GG Changed Isoc interface to conform to dispatchtable interface.
69: <USB69> 9/1/98 BT FIx passing wrong parameter to UIM. Supermario compiler didn't
70: like it.
71: <USB68> 8/31/98 BT Add isoc pipes
72: <USB67> 8/25/98 BT Isoc name changes
73: <USB66> 8/24/98 BT Cope without #define for reserved4
74: <USB65> 8/13/98 BT Add multibus support
75: <USB64> 8/12/98 BT Move root hub into UIM again.
76: <USB63> 8/12/98 DF (for BT) Finally fix fix
77: <USB62+> 8/12/98 DF (for BT) Finally fix fix
78: <USB62> 8/11/98 BT Issue bad UIM version status message
79: <USB61> 8/11/98 BT Fix check
80: <USB60> 8/11/98 BT Check UIM version
81: <USB59> 8/7/98 GG Tweaked interface to USL to be consistent with direction
82: parameter.
83: <USB58> 7/23/98 BT Don't corrupt flags if control failes
84: <USB57> 7/10/98 TC Back out previous revision - it was breaking Yosemite.
85: <USB56> 6/30/98 BT Move Root hub sim into UIM
86: <USB55> 6/24/98 DF fix problem that kept the UIM's suspend change reset proc from
87: being called.
88: <USB54> 6/14/98 DF Bad integration, left out the Check_UIM change.
89: <USB53> 6/14/98 DF Do a little more in USBRemoveBus, eliminate UIM moved checks
90: <USB52> 6/5/98 GG Changed uxbusref to USBBusRef. Changed GetFrameNumberImmediate
91: to return a UInt64 zero.
92: <USB51> 6/5/98 CSS Forgot to include Math64.h.
93: <USB50> 6/5/98 CSS Update to use U64Max() instead of -1 for the maximum 64 bit
94: value.
95: <USB49> 6/5/98 BT Use UIM time
96: <USB48> 5/20/98 BT Eliminate PB0
97: <USB47> 5/5/98 GG Change Buffersize from short to unsigned long in BulkTransfer.
98: <USB46> 5/4/98 BT Fix pipe stall errors
99: <USB45> 4/30/98 BT Add real interrupt driven timer
100: <USB44> 4/29/98 BT Move common defines to USBpriv
101: <USB43> 4/28/98 BT Add bulk performance monitoring.
102: <USB42> 4/26/98 BT Add pipe state control
103: <USB41> 4/23/98 BT Add reset portsuspend change
104: <USB40> 4/22/98 DF Make USBAddBus return gracefully if more than one bus is
105: attached.
106: <USB39> 4/20/98 BT Add abort pipe
107: <USB38> 4/16/98 BT Fix unused variable
108: <USB37> 4/15/98 BT Add over current change reset
109: <USB36> 4/14/98 DF Add UIM polling for debugger support
110: <USB35> 4/14/98 BT Use EDDelete
111: <USB34> 4/9/98 BT Use USB.h
112: <33> 4/7/98 BT Fix act count in control transactions
113: <32> 4/6/98 BT Change w names
114: <31> 4/6/98 BT New param block names
115: <30> 4/2/98 BT eliminate obsolete function
116: <29> 3/24/98 BT Swap parameter order in open Int ED
117: <28> 3/18/98 BT Add reset enable change to root hub.
118: <27> 3/18/98 BT Add clear port enable change feature (Disabled waiting UIM
119: support)
120: <26> 3/11/98 BT Int simulation for root hub. More debugs for moving UIM.
121: <25> 3/5/98 BT track down changing UIM
122: <24> 3/5/98 BT Add interrupt pipe
123: <23> 2/23/98 BT Fix error recovery
124: <22> 2/19/98 BT Cut out call to process done Queue in UIM.
125: <21> 2/16/98 BT Fix calling processdone queue and timer too often.
126: <USB20> 2/11/98 DKF Add back in ProcessDoneQueue if we're at task time
127: <19> 2/8/98 BT Take out process done q in send control.
128: <18> 2/4/98 BT Fix uslControlPacket to have errors. Add mnore support for
129: usbProbe
130: <17> 2/2/98 BT Add bulk stuff
131: <16> 1/29/98 BT Use symbols for the flags fields used
132: <15> 1/26/98 BT Mangle names after design review, finish up
133: <14> 1/26/98 BT Mangle names after design review
134: <13> 1/26/98 BT Hack in clear enpoint stall
135: <12> 1/21/98 BT Change hardware status codes
136: <11> 1/20/98 BT Unwrapping root hub
137: <10> 1/19/98 BT More root hub sim
138: <9> 1/15/98 BT Do root hub simulation.
139: <8> 1/15/98 CJK Change include of USL.h to USBServicesLib.h
140: <7> 1/14/98 BT Implimenting Interrupt transactions
141: <6> 1/13/98 BT Change uslPacket to uslControlPacket
142: <5> 12/22/97 BT StartRootHub moving to USL
143: <4> 12/19/97 BT TAking out dependancy on UIM
144: <3> 12/19/97 BT UIM now a Shared lib
145: */
146:
147: #include "../USB.h"
148: #include "../USBpriv.h"
149: //#include <Math64.h"
150:
151: #include "../uimpriv.h"
152: #include "uslpriv.h"
153: //#include "../MonaUSBPriv.h"
154:
155:
156:
157: enum{
158: kSetupSent = 0x01,
159: kDataSent = 0x02,
160: kStatusSent = 0x04,
161: kSetupBack = 0x10,
162: kDataBack = 0x20,
163: kStatusBack = 0x40
164: };
165:
166: enum{
167: kMaxBus = 16
168: };
169: static struct UIMPluginDispatchTable *UIMPlugIn[kMaxBus], *pending[kMaxBus];
170: static USBBusRef UIMBus[kMaxBus];
171: static USBDeviceRef rootHubRefs[kMaxBus];
172:
173:
174: void UIMSetRootHubRef(UInt32 bus, USBDeviceRef ref)
175: {
176: if(UIMPlugIn[bus] == nil)
177: {
178: USBExpertStatus(0,"USL - Bad bus passed to root hub ref", 0);
179: }
180: else
181: {
182: rootHubRefs[bus] = ref;
183: }
184: }
185:
186: #define CHECK_UIM 0
187: #if CHECK_UIM
188: static void checkUIMMoved(UInt32 bus, void ***UIM,void **UIM1,void **current)
189: {
190:
191: static void *UIMp;
192:
193: if(UIMPlugIn[bus] != nil)
194: {
195: if(UIMp == nil)
196: {
197: UIMp = (void *)UIMPlugIn[bus];
198: }
199: else
200: {
201: if(UIMp != (void *)UIMPlugIn[bus])
202: {
203: //DebugStr("UIM Pointer changed, tell barry, you're hosed");
204: USBExpertStatus(0,"USL - UIM Pointer changed, tell barry, you're hosed", 0);
205: }
206: }
207:
208: if(*UIM == nil)
209: {
210: *UIM = (void *)*current;
211: *UIM1 = **UIM;
212: }
213: else
214: {
215: if(*UIM != (void *)*current)
216: {
217: //DebugStr("UIM moved, tell barry, you're hosed");
218: USBExpertStatus(0,"USL - UIM moved, tell barry, you're hosed", 0);
219: }
220:
221: if(*UIM1 != **UIM)
222: {
223: //DebugStr("UIM 1 moved, tell barry, you're hosed");
224: USBExpertStatus(0,"USL - UIM 1 moved, tell barry, you're hosed", 0);
225: }
226: }
227: }
228: else
229: {
230: SysDebugStr("Bad bus");
231: USBExpertStatus(0,"USL - bad bus passed to UIM interface", bus);
232: }
233: }
234: #endif
235:
236: OSStatus USBAddBus(
237: void *regEntry,
238: void *UIM, /* GG to specifiy */
239: USBBusRef inBus) /* from TC */
240: {
241:
242: UInt32 bus=
243: #if CHECK_UIM
244: 5
245: #else
246: 0
247: #endif
248: ;
249:
250: regEntry = 0; /* not used */
251:
252: printf("USBAddBus:Adding bus=%d\n",bus);
253: while( (UIMPlugIn[bus] != nil) || (pending[bus] != nil) )
254: {
255: if(bus++ >= kMaxBus)
256: {
257: return(-1);
258: }
259: }
260: USBExpertStatus(-1, "USL - Adding bus index:", bus);
261: pending[bus] = UIM;
262: if(pending[bus]->pluginVersion != kUIMPluginTableVersion)
263: {
264: USBExpertStatus(-1, "UIM is wrong versions, bus not added", pending[bus]->pluginVersion);
265: pending[bus] = nil;
266: return(kUSBPBVersionError);
267: }
268:
269:
270: UIMBus[bus] = inBus;
271:
272: printf("USBAddBus:starting roothub\n");
273: StartRootHub(bus);
274: printf("USBAddBus:roothub complete\n");
275: return(noErr);
276: }
277:
278: OSStatus UIMResetRootHub(UInt32 bus)
279: {
280: if(pending[bus] == nil)
281: {
282: SysDebugStr("Bad bus for reset");
283: USBExpertStatus(0,"USL - bad bus passed to reset", bus);
284: }
285:
286: if(pending[bus] != nil)
287: {
288: OSStatus ret;
289: ret = (*pending[bus]->uimResetRootHubProc)(UIMBus[bus]);
290: if(ret != noErr)
291: {
292: return(ret);
293: }
294: UIMPlugIn[bus] = pending[bus];
295: pending[bus] = nil;
296: }
297: return(-1);
298: }
299:
300: OSStatus USBRemoveBus(
301: USBBusRef inBus) /* from TC */
302: {
303: UInt32 bus = 0;
304: USBPB pb;
305:
306: while(inBus != UIMBus[bus])
307: {
308: if(bus++ >= kMaxBus)
309: {
310: return(kUSBNotFound);
311: }
312: }
313: USBExpertStatus(-1, "USL - Removing bus index:", bus);
314:
315: pb.pbLength = sizeof(pb);
316: pb.pbVersion = kUSBCurrentHubPB;
317: pb.usbStatus = noErr;
318: pb.usbFlags = 0;
319: pb.usbReference = rootHubRefs[bus];
320: pb.usbCompletion = kUSBNoCallBack;
321:
322: if(immediateError(USBHubDeviceRemoved(&pb)))
323: {
324: USBExpertStatus(pb.usbReference, "USL - remove bus, Failed to remove root hub", pb.usbReference);
325: }
326: USBExpertRemoveDeviceDriver(rootHubRefs[bus]);
327: rootHubRefs[bus] = 0;
328:
329: UIMPlugIn[bus] = nil;
330: UIMBus[bus] = 0;
331: pending[bus] = nil;
332:
333: return(noErr);
334: }
335:
336: void UIMPollRootHubSim(void)
337: {
338: #if CHECK_UIM
339: static void **UIM, *UIM1;
340: #endif
341: UInt32 bus = 0;
342:
343: for(bus = 0; bus<kMaxBus; bus++)
344: {
345: if(UIMPlugIn[bus] != nil)
346: {
347: #if CHECK_UIM
348: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimPollRootHubSim);
349: #endif
350:
351: (*UIMPlugIn[bus]->uimPollRootHubSim)(UIMBus[bus]);
352: }
353: }
354: }
355:
356: OSStatus USLPolledProcessDoneQueue(void)
357: {
358: #if CHECK_UIM
359: static void **UIM, *UIM1;
360: #endif
361: UInt32 bus = 0;
362: OSStatus myErr;
363:
364: for(bus = 0; bus<kMaxBus; bus++)
365: {
366: if(UIMPlugIn[bus] != nil)
367: {
368: #if CHECK_UIM
369: static void **UIM, *UIM1;
370: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimProcessDoneQueueProc);
371: #endif
372: myErr = (*UIMPlugIn[bus]->uimProcessDoneQueueProc)();
373: }
374: }
375: return(noErr);
376: }
377:
378:
379:
380:
381: UInt64 UIMGetCurrentFrame(UInt32 bus)
382: {
383: #if CHECK_UIM
384: static void **UIM, *UIM1;
385: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimGetCurrentFrameNumberProc);
386: #endif
387:
388: if(UIMPlugIn[bus] != nil)
389: {
390: return(*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
391: }
392: return(U64SetU(0));
393: }
394:
395: UInt32 UIMGetAFrame(void)
396: {
397: union{
398: UInt64 u;
399: UnsignedWide s;
400: }frame;
401: static UInt32 bus = 0;
402:
403: if(UIMPlugIn[bus] != nil)
404: {
405: frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
406: return(frame.s.lo);
407: }
408:
409: for(bus = 0; bus<kMaxBus; bus++)
410: {
411: if(UIMPlugIn[bus] != nil)
412: {
413: frame.u = (*UIMPlugIn[bus]->uimGetCurrentFrameNumberProc)();
414: return(frame.s.lo);
415: }
416: }
417: return(0);
418: }
419:
420:
421: OSStatus UIMControlEDCreate(
422: UInt32 bus,
423: UInt8 functionNumber,
424: UInt8 endpointNumber,
425: UInt16 maxPacketSize,
426: UInt8 speed)
427: {
428: #if CHECK_UIM
429: static void **UIM, *UIM1;
430: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlEndpointProc);
431: #endif
432:
433: if(UIMPlugIn[bus] != nil)
434: {
435: return(*UIMPlugIn[bus]->uimCreateControlEndpointProc)(
436: functionNumber,
437: endpointNumber,
438: maxPacketSize,
439: speed);
440: }
441: return(-1);
442: }
443:
444: OSStatus UIMInterruptEDCreate(
445: UInt32 bus,
446: UInt8 functionNumber,
447: UInt8 endpointNumber,
448: UInt16 maxPacketSize,
449: UInt8 speed)
450: {
451: #if CHECK_UIM
452: static void **UIM, *UIM1;
453: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptEndpointProc);
454: #endif
455:
456: if(UIMPlugIn[bus] != nil)
457: {
458: return(*UIMPlugIn[bus]->uimCreateInterruptEndpointProc)(
459: functionNumber,
460: endpointNumber,
461: speed,
462: maxPacketSize,
463: 8, // Polling rate
464: 0); // Reserve bandwidth??
465: }
466: return(-1);
467: }
468:
469: OSStatus UIMIsocEDCreate(
470: UInt32 bus,
471: UInt8 functionNumber,
472: UInt8 endpointNumber,
473: UInt8 direction,
474: UInt16 maxPacketSize)
475: {
476: #if CHECK_UIM
477: static void **UIM, *UIM1;
478: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochEndpointProc);
479: #endif
480:
481: if(UIMPlugIn[bus] != nil)
482: {
483: return(*UIMPlugIn[bus]->uimCreateIsochEndpointProc)(
484: functionNumber,
485: endpointNumber,
486: maxPacketSize,
487: direction);
488: }
489: return(-1);
490: }
491:
492:
493: OSStatus UIMBulkEDCreate(
494: UInt32 bus,
495: UInt8 functionNumber,
496: UInt8 endpointNumber,
497: UInt8 direction,
498: UInt8 maxPacketSize)
499: {
500: #if CHECK_UIM
501: static void **UIM, *UIM1;
502: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkEndpointProc);
503: #endif
504:
505: if(UIMPlugIn[bus] != nil)
506: {
507: return(*UIMPlugIn[bus]->uimCreateBulkEndpointProc)(
508: functionNumber,
509: endpointNumber,
510: direction,
511: maxPacketSize);
512: }
513: return(-1);
514: }
515:
516: OSStatus UIMControlTransfer(
517: UInt32 bus,
518: UInt32 refcon,
519: CallBackFuncPtr handler,
520: UInt32 CBP,
521: Boolean bufferRounding,
522: short functionNumber,
523: short endpointNumber,
524: short bufferSize,
525: short direction)
526: {
527: #if CHECK_UIM
528: static void **UIM, *UIM1;
529: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateControlTransferProc);
530: #endif
531:
532: if(UIMPlugIn[bus] != nil)
533: {
534: return(*UIMPlugIn[bus]->uimCreateControlTransferProc)(
535: refcon,
536: handler,
537: CBP,
538: bufferRounding,
539: functionNumber,
540: endpointNumber,
541: bufferSize,
542: direction);
543: }
544: return(-1);
545: }
546:
547: #if 0
548: #include "TextUtils.h"
549: static void AddNum(UInt8 *s1, UInt32 num)
550: {
551: UInt8 number[20];
552: NumToString(num, number);
553: AddString(s1, number);
554: }
555:
556: static void AddString(UInt8 *s1, UInt8 *s2)
557: {
558: int count;
559: count = 255-*s1;
560: if(count == 0)
561: {
562: return;
563: }
564: if(count > *s2)
565: {
566: count = *s2;
567: }
568: usb_BlockMoveData(&s2[1], &s1[*s1]+1, s2[0]);
569: *s1+=*s2;
570: }
571:
572: static void DebugNum(UInt8 *str, UInt32 num, Boolean stop)
573: {
574: UInt8 strBuf[256];
575:
576: AddString(strBuf, str);
577: AddString(strBuf, " : ");
578: AddNum(strBuf, num);
579: AddString(strBuf, " 100;g");
580: DebugStr(strBuf);
581: if(stop)
582: {
583: SysDebugStr("This seems bad, tell barry about it, cmd-g to continue");
584: }
585: }
586: #endif
587: OSStatus UIMControlEDDelete(
588: UInt32 bus,
589: short functionNumber,
590: short endpointNumber)
591: {
592: #if CHECK_UIM
593: static void **UIM, *UIM1;
594: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteControlEndpointProc);
595: #endif
596:
597: if(UIMPlugIn[bus] != nil)
598: {
599: return(*UIMPlugIn[bus]->uimDeleteControlEndpointProc)(functionNumber, endpointNumber);
600: }
601: else
602: {
603: USBExpertStatus(0,"USL -control ED delete failed", bus);
604: }
605: return(-1);
606: }
607:
608: OSStatus UIMEDDelete(
609: UInt32 bus,
610: short functionNumber,
611: short endpointNumber,
612: short direction)
613: {
614: #if CHECK_UIM
615: static void **UIM, *UIM1;
616: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimDeleteEndpointProc);
617: #endif
618:
619: if(UIMPlugIn[bus] != nil)
620: {
621: return(*UIMPlugIn[bus]->uimDeleteEndpointProc)(functionNumber, endpointNumber, direction);
622: }
623: return(-1);
624: }
625:
626: OSStatus UIMBulkTransfer(
627: UInt32 bus,
628: UInt32 refcon,
629: CallBackFuncPtr handler,
630: UInt32 CBP,
631: Boolean bufferRounding,
632: short functionNumber,
633: short endpointNumber,
634: UInt32 bufferSize,
635: short direction)
636: {
637: #if CHECK_UIM
638: static void **UIM, *UIM1;
639: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateBulkTransferProc);
640: #endif
641:
642: if(UIMPlugIn[bus] != nil)
643: {
644: return(*UIMPlugIn[bus]->uimCreateBulkTransferProc)(
645: refcon,
646: handler,
647: CBP,
648: bufferRounding,
649: functionNumber,
650: endpointNumber,
651: bufferSize,
652: direction);
653: }
654: return(-1);
655: }
656:
657: OSStatus UIMIntTransfer(
658: UInt32 bus,
659: short functionNumber,
660: short endpointNumber,
661: UInt32 refcon,
662: CallBackFuncPtr handler,
663: UInt32 CBP,
664: Boolean bufferRounding,
665: short bufferSize)
666: {
667: #if CHECK_UIM
668: static void **UIM, *UIM1;
669: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateInterruptTransferProc);
670: #endif
671:
672: if(UIMPlugIn[bus] != nil)
673: {
674: return(*UIMPlugIn[bus]->uimCreateInterruptTransferProc)(
675: functionNumber,
676: endpointNumber,
677: refcon,
678: handler,
679: CBP,
680: bufferRounding,
681: bufferSize);
682: }
683: return(-1);
684: }
685:
686: OSStatus UIMIsocTransfer(
687: UInt32 bus,
688: short functionNumber,
689: short endpointNumber,
690: short direction,
691: UInt32 frameStart,
692: UInt32 refcon,
693: IsocCallBackFuncPtr handler,
694: void *buffer,
695: UInt32 numFrames,
696: USBIsocFrame *frames)
697: {
698: #if CHECK_UIM
699: static void **UIM, *UIM1;
700: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimCreateIsochTransferProc);
701: #endif
702: union{
703: UInt64 u;
704: UnsignedWide s;
705: }startFrame;
706:
707: if(UIMPlugIn[bus] != nil)
708: {
709: startFrame.u = UIMGetCurrentFrame(bus);
710: startFrame.s.lo = frameStart; /* this needs to be more sophisticated */
711:
712: return(*UIMPlugIn[bus]->uimCreateIsochTransferProc)(
713: functionNumber,
714: endpointNumber,
715: refcon,
716: direction,
717: handler,
718: startFrame.u,
719: (UInt32)buffer,
720: numFrames,
721: frames);
722: }
723: return(-1);
724: }
725: /*
726: typedef CALLBACK_API_C( OSStatus , UIMCreateIsochTransferProcPtr )(
727: short functionAddress,
728: short endpointNumber,
729: UInt8 direction,
730: short refcon,
731: UInt32 pIsochHandler,
732: UInt64 frameStart,
733: UInt32 pBufferStart,
734: UInt32 frameCount,
735: USBIsocFrame *pFrames,
736: UInt32 pStatus);
737: */
738: OSStatus UIMClearEndPointStall(
739: UInt32 bus,
740: short functionNumber,
741: short endpointNumber,
742: short direction)
743: {
744: #if CHECK_UIM
745: static void **UIM, *UIM1;
746: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimClearEndPointStallProc);
747: #endif
748:
749: if(UIMPlugIn[bus] != nil)
750: {
751: return(*UIMPlugIn[bus]->uimClearEndPointStallProc)(functionNumber, endpointNumber, direction);
752: }
753: return(-1);
754: }
755:
756: OSStatus UIMAbortEndpoint(
757: UInt32 bus,
758: short functionNumber,
759: short endpointNumber,
760: short direction)
761: {
762: #if CHECK_UIM
763: static void **UIM, *UIM1;
764: checkUIMMoved(bus, &UIM, &UIM1, (void *)&UIMPlugIn[bus]->uimAbortEndpointProc);
765: #endif
766:
767: if(UIMPlugIn[bus] != nil)
768: {
769: return(*UIMPlugIn[bus]->uimAbortEndpointProc)(
770: functionNumber,
771: endpointNumber,
772: direction);
773: }
774: return(-1);
775: }
776:
777:
778: static OSStatus doUSLStatus(OSStatus status, USBReference ref)
779: {
780: if(status != noErr)
781: {
782: if(status == EDDeleteErr)
783: {
784: status = kUSBAbortedError;
785: }
786: else if(status == bandWidthFullErr)
787: {
788: status = kUSBNoBandwidthError;
789: }
790: else if(status == returnedErr)
791: {
792: status = kUSBAbortedError;
793: }
794: else
795: {
796: if( (status > 0) && (status < 16))
797: {
798: /* As ferg points out all host contoller errors stall the pipe */
799: uslSetPipeStall(ref);
800: }
801: status = kUSBLinkErr+status;
802: #if 0
803: if( (status == kUSBCRCErr) ||
804: (status == kUSBBitstufErr) ||
805: (status == kUSBDataToggleErr) ||
806: (status == kUSBEndpointStallErr) ||
807: (status == kUSBNotRespondingErr) ||
808: (status == kUSBPIDCheckErr) ||
809: (status == kUSBWrongPIDErr) )
810: {
811: uslSetPipeStall(ref);
812: }
813: #endif
814: }
815: }
816: return(status);
817: }
818:
819:
820: static void intPktHandler(long refCon, OSStatus status, short shortfall)
821: {
822: USBPB *pb;
823:
824: if(refCon == 0)
825: {
826: return;
827: }
828:
829: pb = (void *)refCon;
830:
831: status = doUSLStatus(status, pb->usbReference);
832:
833: pb->usbStatus = status;
834: pb->usbActCount = pb->usbReqCount - shortfall;
835: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
836: (*pb->usbCompletion)(pb);
837: }
838:
839: static void bulkPktHandler(long refCon, OSStatus status, short shortfall)
840: {
841: USBPB *pb;
842:
843: if(refCon == 0)
844: {
845: return;
846: }
847:
848: pb = (void *)refCon;
849:
850: status = doUSLStatus(status, pb->usbReference);
851:
852: pb->usbStatus = status;
853: if(shortfall > pb->usbReqCount)
854: {
855: pb->usbActCount = 0;
856: }
857: else
858: {
859: pb->usbActCount = pb->usbReqCount - shortfall;
860: }
861:
862: if(pb->usbFlags)
863: {
864: resolvePerformance(pb);
865: }
866:
867: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
868: (*pb->usbCompletion)(pb);
869: }
870:
871: static void isocPktHandler(long refCon, OSStatus status, USBIsocFrame *pFrames)
872: {
873: USBPB *pb;
874: OSStatus aggregate = noErr;
875: UInt32 actCount = 0, frame;
876:
877: if(refCon == 0)
878: {
879: return;
880: }
881:
882: pb = (void *)refCon;
883:
884: actCount = 0;
885: for(frame = 0; frame < pb->usb.isoc.NumFrames; frame++)
886: {
887: actCount += pFrames[frame].frActCount;
888: if(pFrames[frame].frStatus != noErr)
889: {
890: aggregate = pFrames[frame].frStatus;
891: }
892: }
893: pb->usbActCount = actCount;
894:
895: if(status == noErr)
896: {
897: pb->usbStatus = aggregate;
898: }
899: else
900: {
901: pb->usbStatus = status;
902: }
903: if(pb->usbStatus != noErr)
904: {
905: pb->usbStatus = kUSBLinkErr+pb->usbStatus;
906: }
907:
908: if ( (pb->usbCompletion != nil) && (pb->usbCompletion != kUSBNoCallBack))
909: {
910: (*pb->usbCompletion)(pb);
911: }
912: }
913:
914: static void ctlPktHandler(long refCon, OSStatus status, short shortfall)
915: {
916: UInt8 sent, back, todo;
917: USBPB *pb;
918: Boolean callBackTIme;
919: UInt32 bus;
920:
921: if(refCon == 0)
922: {
923: return;
924: }
925:
926:
927: pb = (void *)(refCon & ~1);
928: callBackTIme = ((refCon & 1) != 0);
929:
930: sent = (pb->reserved1 &0xf) << 4;
931: back = pb->reserved1 &0xf0;
932: todo = sent ^ back; /* thats xor */
933:
934: if((todo & kSetupBack) != 0)
935: {
936: pb->reserved1 |= kSetupBack;
937:
938: }
939: else if((todo & kDataBack) != 0)
940: { /* This is the data transport phase, so this is the interesting one */
941: pb->reserved1 |= kDataBack;
942: pb->usbActCount = pb->usbReqCount - shortfall;
943: }
944: else if((todo & kStatusBack) != 0)
945: {
946: pb->reserved1 |= kStatusBack;
947:
948: }
949: else
950: {
951: USBExpertStatus(-1, "Spare transactions, This seems to be harmless", 0);
952: }
953:
954: back = pb->reserved1 &0xf0;
955: todo = sent ^ back; /* thats xor */
956:
957: if( (status != noErr) && (status != returnedErr) )
958: {
959: UInt8 addr, endpt;
960: addr = ( (pb->usbFlags) &kUSLAddrMask) >> kUSLAddrShift;
961: endpt = ( (pb->usbFlags &kUSLEndpMask) >> kUSLEndpShift);
962: bus = ( (pb->usbFlags &kUSLBusMask) >> kUSLBusShift);
963:
964: pb->usbStatus = doUSLStatus(status, pb->usbReference);
965: if(endpt == 0)
966: {
967: UIMClearEndPointStall(bus, addr, endpt, 0);
968: }
969:
970: }
971:
972:
973: if( callBackTIme || (todo == 0) )
974: {
975: if( !callBackTIme || (todo != 0) ) /* One but not the other */
976: {
977: USBExpertStatus(-1, "UIM Interface odd completion", 0);
978: }
979: pb->usbFlags &= ~(kUSLAddrMask|kUSLEndpMask|kUSLBusMask);
980:
981: if(status == noErr)
982: {
983: if(pb->usbStatus != kUSBPending)
984: {
985: USBExpertStatus(-1, "UIM Interface odd status", 0);
986: }
987: pb->usbStatus = noErr;
988: }
989:
990: pb->usb.cntl.WIndex = USBToHostWord(pb->usb.cntl.WIndex);
991: pb->usb.cntl.WValue = USBToHostWord(pb->usb.cntl.WValue);
992: if (pb->usbCompletion && (pb->usbCompletion != kUSBNoCallBack))
993: (*pb->usbCompletion)(pb);
994: }
995: }
996:
997: OSStatus usbIsocPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
998: {
999: OSStatus err;
1000:
1001: pb->usbStatus = noErr;
1002:
1003: err = UIMIsocTransfer(bus,
1004: address /* address */,
1005: endpoint /* endpoint */,
1006: direction /* in or out */,
1007: pb->usbFrame /* starting frame */,
1008: (UInt32)pb /* refcon */,
1009: isocPktHandler,
1010: pb->usbBuffer /* buffer */,
1011: pb->usb.isoc.NumFrames,
1012: pb->usb.isoc.FrameList
1013: );
1014:
1015: #if 0
1016: if(err != noErr)
1017: {
1018: isocPktHandler((UInt32)pb, err, pb->usb.isoc.FrameList);
1019: }
1020: #else
1021: return(err);
1022: #endif
1023:
1024: }
1025:
1026: OSStatus usbIntPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
1027: {
1028: OSStatus err;
1029: direction = 0; /* Not used */
1030:
1031: pb->usbStatus = noErr;
1032: kprintf("usbIntPacket:Calling UIMIntTransfer:addr=%d,ep=%d,reqcount=%d\n",address,endpoint,pb->usbReqCount);
1033: err = UIMIntTransfer(bus,
1034: address,
1035: endpoint,
1036: (UInt32)pb /* refcon */,
1037: intPktHandler,
1038: (UInt32)pb->usbBuffer /* buffer */,
1039: true /* short packets OK */,
1040: pb->usbReqCount /* buffer size */);
1041: kprintf("usbIntPacket:UIMTransfer returned err=%d\n",err);
1042:
1043: return(err);
1044: }
1045:
1046:
1047: OSStatus usbBulkPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint, UInt8 direction)
1048: {
1049: OSStatus err;
1050:
1051: pb->usbStatus = noErr;
1052:
1053: err = UIMBulkTransfer(bus,
1054: (UInt32)pb /* refcon */,
1055: bulkPktHandler,
1056: (UInt32)pb->usbBuffer /* buffer */,
1057: true /* short packets OK */,
1058: address /* address */,
1059: endpoint /* endpoint */,
1060: pb->usbReqCount /* buffer size */,
1061: direction /* in or out */);
1062:
1063: return(err);
1064: }
1065:
1066: #define kUSBSetup kUSBNone
1067:
1068: OSStatus usbControlPacket(UInt32 bus, USBPB *pb, UInt8 address, UInt8 endpoint)
1069: {
1070: OSStatus err;
1071: short dirn;
1072:
1073:
1074: if( ((UInt32)pb &1) != 0)
1075: {
1076: USBExpertStatus(-1, "Missaligned PB", 0);
1077: }
1078:
1079: /* Remeber address and endpoint here for later */
1080: pb->usbFlags |= (address << kUSLAddrShift)+(endpoint << kUSLEndpShift)+(bus << kUSLBusShift);
1081:
1082: do{
1083: pb->reserved1 = 0; /* stage pointer */
1084: pb->usbStatus = kUSBPending;
1085: pb->usbActCount = 0;
1086:
1087: pb->reserved1 |= kSetupSent;
1088: //kprintf("usbControlPacket:addr=%d,ep=%d\n",address,endpoint);
1089: err = UIMControlTransfer(bus,
1090: (UInt32)pb/* refcon */,
1091: ctlPktHandler,
1092: (UInt32)&pb->usb.cntl.BMRequestType /* packet */,
1093: true /* short packets OK */,
1094: address /* address */,
1095: endpoint /* endpoint */,
1096: 8 /* packet size */,
1097: kUSBSetup /* setup */);
1098: //kprintf("usbControlPacket:After first call refcon(pb)=0x%x,err=%d\n",pb,err);
1099: if(err != noErr)
1100: {
1101: pb->usbFlags = 0;
1102: USBExpertStatus(-1, "Control packet 1 error", err);
1103: break;
1104: }
1105:
1106: dirn = ((pb->usb.cntl.BMRequestType & 0x80) == 0)?kUSBOut:kUSBIn;
1107: if(pb->usb.cntl.reserved4 != 0)
1108: {
1109: pb->reserved1 |= kDataSent;
1110: err = UIMControlTransfer(bus,
1111: (UInt32)pb /* refcon */,
1112: ctlPktHandler,
1113: (UInt32)pb->usbBuffer /* buffer */,
1114: true /* short packets OK */,
1115: address /* address */,
1116: endpoint /* endpoint */,
1117: pb->usbReqCount /* buffer size */,
1118: dirn /* in or out */);
1119: if(err != noErr)
1120: {
1121: USBExpertStatus(-1, "Control packet 2 error", err);
1122: break;
1123: }
1124: //kprintf("usbControlPacket:After second(data phase)call refcon(pb)=0x%x,err=%d\n",pb,err);
1125:
1126: }
1127:
1128: dirn = kUSBOut+kUSBIn - dirn;
1129:
1130: pb->reserved1 |= kStatusSent;
1131: err = UIMControlTransfer(bus,
1132: (UInt32)pb | 1 /* refcon, with marker */,
1133: ctlPktHandler,
1134: 0 /* buffer, for no data transfer */,
1135: true /* short packets OK */,
1136: address /* address */,
1137: endpoint /* endpoint */,
1138: 0 /* buffer size */,
1139: dirn /* in or out */);
1140:
1141: //kprintf("usbControlPacket:After third(status phase)call refcon(pb)=0x%x,err=%d\n",(UInt32)pb | 1,err);
1142: if(err != noErr)
1143: {
1144: USBExpertStatus(-1, "Control packet 3 error", err);
1145: }
1146:
1147: }while(0);
1148:
1149: return(err);
1150: }
1151:
1152: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint);
1153:
1154: OSStatus uslProbeEndpoint(USBPB *pb, UInt8 address, UInt8 endpoint)
1155: {
1156: OSStatus err;
1157: UInt32 bus;
1158:
1159: if (address > 127)
1160: {
1161: if(rootHubRefs[255-address] == 0)
1162: {
1163: return(kUSBUnknownDeviceErr);
1164: }
1165: address = rootHubRefs[255-address] & 0x7f;
1166: }
1167:
1168: if ((bus = uslDeviceAddrToBus(address)) >= kMaxBus)
1169: {
1170: return(kUSBUnknownDeviceErr);
1171: }
1172:
1173: pb->usbStatus = kUSBPending;
1174: err = usbControlPacket(bus, pb, address, endpoint);
1175:
1176: return(err);
1177: }
1178:
1179:
1180:
1181:
1182:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.