|
|
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: uslPipe.c
27:
28: Contains: xxx put contents here xxx
29:
30: Version: xxx put version here xxx
31:
32: Copyright: � 1998 by Apple Computer, Inc., all rights reserved.
33:
34: File Ownership:
35:
36: DRI: xxx put dri here xxx
37:
38: Other Contact: xxx put other contact here xxx
39:
40: Technology: xxx put technology here xxx
41:
42: Writers:
43:
44: (BT) Barry Twycross
45:
46: Change History (most recent first):
47:
48: <USB18> 11/16/98 BT Clear pipe state on open
49: <USB17> 11/5/98 BT Fix returning noErr instead of pending.
50: <USB16> 10/22/98 BT Fix wrong status for deleted devices.
51: <USB15> 10/12/98 BT Add addressed device request
52: <USB14> 9/29/98 BT Use real frame timing
53: <USB13> 8/31/98 BT Add isoc pipes
54: <USB12> 8/25/98 BT Isoc name changes
55: <USB11> 8/24/98 BT Isoc param block definition
56: <USB10> 8/13/98 BT Add multibus support
57: <USB9> 8/13/98 BT Allow zero length transactions
58: <USB8> 7/23/98 BT Cut annoying message
59: <USB7> 7/7/98 BT Avoid control reentrancy problem by making sure they're done at
60: secondary interrupt time.
61: <USB6> 5/21/98 BT Don't corrupt usbBuffer when diverting to opendevice.
62: <USB5> 5/20/98 BT Find implicit dev config
63: <USB4> 5/20/98 BT Fix pipe devidx field
64: <USB3> 5/17/98 BT Device request doesn't squash reqcount, buffer. Add internal
65: open pipe for config interface
66: <USB2> 4/28/98 BT Add bulk performance monitoring.
67: <USB1> 4/26/98 BT first checked in
68: */
69:
70: #include "../USB.h"
71: #include "../USBpriv.h"
72:
73: #include "uslpriv.h"
74: #include "../uimpriv.h"
75:
76: #include "../driverservices.h"
77:
78:
79: static pipe pipeZeroZero; // the default pipe to device zero
80:
81: #if 0
82: static OSStatus uslOpenControlEndpoint(struct USBPB *pb)
83: {
84: usbDevice *deviceP;
85: OSStatus retVal = kUSBInternalErr;
86: pipe *newPipe;
87:
88: do{ /* For error recovery */
89:
90: /* Validate device */
91: deviceP = getDevicePtr(pb->usbReference);
92:
93: if(deviceP == nil)
94: {
95: retVal = kUSBUnknownDeviceErr;
96: break;
97: }
98:
99: #if 0
100: /* Validate endpoint */
101: if(deviceP->numberOfEndpoints >= endpoint)
102: {
103: retVal = kUSBUnknownEndpointErr;
104: break;
105: }
106: #endif
107:
108: newPipe = getPipe(deviceP, pb->usbValue2);
109:
110: if(newPipe != nil)
111: {
112: retVal = kUSBAlreadyOpenErr;
113: break;
114: }
115:
116: /* This endpoint has not yet been opened. */
117: if(pb->usbValue2 == 0) /* Endpoint zero is a control endpoint */
118: {
119: retVal = kUSBUnknownEndpointErr;
120: break;
121: }
122:
123:
124: /* Allocate a new pipe */
125: newPipe = AllocPipe(deviceP, pb->usbValue2);
126: if(newPipe == nil)
127: {
128: retVal = kUSBTooManyPipesErr;
129: break;
130: }
131: /* Fill in pertinent information for this pipe instantiation */
132: newPipe->deviceIdx = makeDeviceIdx(pb->usbReference);
133: newPipe->intrfc = pb->usbReference;
134: newPipe->endPt = pb->usbValue2;
135: newPipe->devAddress = deviceP->usbAddress;
136: newPipe->flags = pb->usbFlags;
137: newPipe->state = kUSBActive;
138:
139: #if 0
140: retVal = UIMSetupControlEndpoint(newPipe->addEnd, &newPipe->uimRef,
141: newPipe->maxPacket, controlCallBack, newPipe->iflags, newPipe->addEnd /* refCon */);
142: #endif
143:
144: if(retVal != kUSBNoErr)
145: {
146: deallocPipe(deviceP, pb->usbValue2);
147: break;
148: }
149:
150:
151: pb->usbReference = newPipe->ref;
152:
153: /* Just assume you can have an endpoint zero for now. */
154: /* Shouldn't this be already open */
155:
156: #if 0
157: /* XXXXXXXX In real version should add something here */
158: if(pipeH->type != kUSBControlType)
159: {
160: retVal = kUSBIncorrectTypeErr;
161: break;
162: }
163: #endif
164:
165:
166: retVal = kUSBNoErr;
167:
168: break;
169: }while(0); /* End error checking */
170:
171: return(retVal);
172: }
173: #endif
174:
175: static OSStatus uslOpenInterruptEndpoint(USBPB *pb)
176: {
177: usbDevice *deviceP;
178: OSStatus retVal = kUSBInternalErr;
179: pipe *newPipe;
180:
181: do{ /* For error recovery */
182:
183: /* Validate device */
184: deviceP = getDevicePtr(pb->usbReference);
185:
186: if(deviceP == nil)
187: {
188: retVal = kUSBUnknownDeviceErr;
189: break;
190: }
191:
192: #if 0
193: /* Validate endpoint */
194: if(deviceP->numberOfEndpoints >= endpoint)
195: {
196: retVal = kUSBUnknownEndpointErr;
197: break;
198: }
199: #endif
200:
201: newPipe = getPipe(deviceP, pb->usbOther, kUSBIn);
202:
203: if(newPipe != nil)
204: {
205: retVal = kUSBAlreadyOpenErr;
206: break;
207: }
208:
209: /* This endpoint has not yet been opened. */
210: if(pb->usbOther == 0) /* Int pipe can't be zero */
211: {
212: retVal = kUSBIncorrectTypeErr;
213: break;
214: }
215:
216:
217: /* Allocate a new pipe */
218: newPipe = AllocPipe(deviceP, pb->usbOther, kUSBIn);
219: if(newPipe == nil)
220: {
221: retVal = kUSBTooManyPipesErr;
222: break;
223: }
224:
225: /* Fill in pertinent information for this pipe instantiation */
226: newPipe->bus = deviceP->bus;
227: newPipe->devIntfRef = pb->usbReference;
228: newPipe->endPt = pb->usbOther;
229: newPipe->direction = kUSBIn;
230: newPipe->devAddress = deviceP->usbAddress;
231: newPipe->flags = pb->usbFlags;
232: newPipe->type = kUSBInterrupt;
233: newPipe->maxPacket = pb->usb.cntl.WValue;
234: newPipe->state = kUSBActive;
235: pb->usbReference = 0;
236:
237: retVal = UIMInterruptEDCreate(newPipe->bus,
238: newPipe->devAddress,
239: pb->usbOther, /* User gives Endpoint number here */
240: pb->usb.cntl.WValue, /* System fills in Max packet size here */
241: deviceP->speed);
242:
243: pb->usbStatus = retVal;
244: if(retVal != kUSBNoErr)
245: {
246: deallocPipe(deviceP, pb->usbOther, kUSBIn);
247: break;
248: }
249:
250: pb->usbReference = newPipe->ref;
251: if(pb->usbCompletion != nil)
252: {
253: (*pb->usbCompletion)(pb);
254: }
255:
256: break;
257: }while(0); /* End error checking */
258:
259: return(retVal);
260: }
261:
262:
263: static OSStatus uslOpenIsocEndpoint(USBPB *pb)
264: {
265: usbDevice *deviceP;
266: OSStatus retVal = kUSBInternalErr;
267: pipe *newPipe;
268: USBDirection usbDirection;
269:
270: do{ /* For error recovery */
271:
272: /* Validate device */
273: deviceP = getDevicePtr(pb->usbReference);
274:
275: if(deviceP == nil)
276: {
277: retVal = kUSBUnknownDeviceErr;
278: break;
279: }
280:
281: #if 0
282: /* Validate endpoint */
283: if(deviceP->numberOfEndpoints >= endpoint)
284: {
285: retVal = kUSBUnknownEndpointErr;
286: break;
287: }
288: #endif
289:
290: usbDirection = pb->usbFlags & 0xff;
291: newPipe = getPipe(deviceP, pb->usbOther, usbDirection);
292:
293: if(newPipe != nil)
294: {
295: retVal = kUSBAlreadyOpenErr;
296: break;
297: }
298:
299: /* This endpoint has not yet been opened. */
300: if(pb->usbOther == 0) /* Isoc pipe can't be zero */
301: {
302: retVal = kUSBIncorrectTypeErr;
303: break;
304: }
305:
306:
307: /* Allocate a new pipe */
308: newPipe = AllocPipe(deviceP, pb->usbOther, usbDirection);
309: if(newPipe == nil)
310: {
311: retVal = kUSBTooManyPipesErr;
312: break;
313: }
314:
315: /* Fill in pertinent information for this pipe instantiation */
316: newPipe->bus = deviceP->bus;
317: newPipe->devIntfRef = pb->usbReference;
318: newPipe->endPt = pb->usbOther;
319: newPipe->direction = usbDirection;
320: newPipe->devAddress = deviceP->usbAddress;
321: newPipe->flags = pb->usbFlags;
322: newPipe->type = kUSBIsoc;
323: newPipe->maxPacket = pb->usb.cntl.WValue;
324: newPipe->state = kUSBActive;
325: pb->usbReference = 0;
326:
327: retVal = UIMIsocEDCreate(newPipe->bus,
328: newPipe->devAddress,
329: pb->usbOther, /* User gives Endpoint number here */
330: usbDirection,
331: pb->usb.cntl.WValue); /* System fills in Max packet size here */
332:
333: pb->usbStatus = retVal;
334: if(retVal != kUSBNoErr)
335: {
336: deallocPipe(deviceP, pb->usbOther, usbDirection);
337: break;
338: }
339:
340: pb->usbReference = newPipe->ref;
341: if(pb->usbCompletion != nil)
342: {
343: (*pb->usbCompletion)(pb);
344: }
345:
346: break;
347: }while(0); /* End error checking */
348:
349: return(retVal);
350: }
351:
352:
353: static OSStatus uslOpenBulkEndpoint(USBPB *pb)
354: {
355: usbDevice *deviceP;
356: OSStatus retVal = kUSBInternalErr;
357: pipe *newPipe;
358: USBDirection usbDirection;
359:
360: do{ /* For error recovery */
361:
362: /* Validate device */
363: deviceP = getDevicePtr(pb->usbReference);
364:
365: if(deviceP == nil)
366: {
367: retVal = kUSBUnknownDeviceErr;
368: break;
369: }
370:
371: #if 0
372: /* Validate endpoint */
373: if(deviceP->numberOfEndpoints >= endpoint)
374: {
375: retVal = kUSBUnknownEndpointErr;
376: break;
377: }
378: #endif
379:
380: usbDirection = pb->usbFlags & 0xff;
381:
382: newPipe = getPipe(deviceP, pb->usbOther, usbDirection);
383:
384: if(newPipe != nil)
385: {
386: retVal = kUSBAlreadyOpenErr;
387: break;
388: }
389:
390: /* This endpoint has not yet been opened. */
391: if(pb->usbOther == 0) /* Not default pipe */
392: {
393: retVal = kUSBIncorrectTypeErr;
394: break;
395: }
396:
397:
398: /* Allocate a new pipe */
399: newPipe = AllocPipe(deviceP, pb->usbOther, usbDirection );
400: if(newPipe == nil)
401: {
402: retVal = kUSBTooManyPipesErr;
403: break;
404: }
405: /* Fill in pertinent information for this pipe instantiation */
406: newPipe->bus = deviceP->bus;
407: newPipe->devIntfRef = pb->usbReference;
408: newPipe->endPt = pb->usbOther;
409: newPipe->direction = usbDirection;
410: newPipe->devAddress = deviceP->usbAddress;
411: newPipe->flags = pb->usbFlags;
412: newPipe->type = kUSBBulk;
413: newPipe->maxPacket = pb->usb.cntl.WValue;
414: newPipe->state = kUSBActive;
415:
416: retVal = UIMBulkEDCreate(newPipe->bus,
417: newPipe->devAddress,
418: pb->usbOther, /* User gives Endpoint number here */
419: usbDirection,
420: pb->usb.cntl.WValue);
421:
422: if(retVal != kUSBNoErr)
423: {
424: deallocPipe(deviceP, pb->usbOther, usbDirection );
425: break;
426: }
427:
428: pb->usbReference = newPipe->ref;
429:
430: retVal = kUSBNoErr;
431: if(pb->usbCompletion != nil)
432: {
433: (*pb->usbCompletion)(pb);
434: }
435:
436: break;
437: }while(0); /* End error checking */
438:
439: return(retVal);
440: }
441:
442: static OSStatus usbSIControlPacket(void *p1, void *addrEp)
443: { // p1 is pointer to paramblock
444: // second param has addr and endpoint munged together
445: UInt32 p2;
446: UInt8 addr, endPt;
447: OSStatus err;
448: USBPB *pb;
449: UInt32 bus;
450:
451: p2 = (UInt32)addrEp;
452: bus = p2 >> 16;
453: addr = (p2>>8) & 0xff;
454: endPt = p2 & 0xf;
455:
456: err = usbControlPacket(bus, p1, addr, endPt);
457: if(err != noErr)
458: {
459: pb = p1;
460: if( (pb->usbCompletion != nil) && (pb->usbCompletion != (void *)-1) )
461: {
462: pb->usbStatus = err;
463: (*pb->usbCompletion)(pb);
464: }
465: }
466: return(noErr);
467: }
468:
469: /* We need to make sure these are queued as well */
470: OSStatus xUSLControlRequest(UInt32 bus, USBPB *pb, pipe *thisPipe)
471: {
472: setupPacket *packet;
473: OSStatus err = kUSBPending;
474:
475: USBDirection direction;
476: USBRqType type;
477: USBRqRecipient recipient;
478: USBRequest request;
479: UInt16 transferSize;
480: //kprintf("xUSLControlRequest:ref=0x%x,device=%d\n",thisPipe->ref,thisPipe->devAddress);
481: do{
482: direction = pb->usb.cntl.BMRequestType >> 7;
483: type = (pb->usb.cntl.BMRequestType >> 5) & 3;
484: recipient = pb->usb.cntl.BMRequestType & 31;
485: request = pb->usb.cntl.BRequest;
486:
487: /* FInd the packet in the param block */
488: packet = (void *)&pb->usb.cntl.BMRequestType;
489:
490: /* Check the direction flag */
491: if(kUSBNone == direction || pb->usbReqCount == 0 || pb->usbBuffer == nil)
492: {
493: transferSize = 0; /* Don't sit on reqcount and buffer */
494: direction = kUSBOut;
495: }
496: else
497: {
498: transferSize = pb->usbReqCount;
499: }
500:
501: /* Put together the bitmap request type byte */
502: if(packet->byte[bmRqType] == 0xff)
503: {
504: err = kUSBRqErr;
505: break;
506: }
507:
508: /* Check the request is a valid one */
509: if( (type == kUSBStandard) &&
510: (request < kUSBRqGetStatus || request > kUSBRqSyncFrame ||
511: request == kUSBRqReserved1 || request == kUSBRqReserved2) )
512: {
513: err = kUSBUnknownRequestErr;
514: break;
515: }
516:
517: /* Put together the rest of the packet */
518: packet->word[wValue] = HostToUSBWord(pb->usb.cntl.WValue);
519: packet->word[wIndex] = HostToUSBWord(pb->usb.cntl.WIndex);
520: packet->word[wLength] = HostToUSBWord(transferSize);
521:
522: pb->usbStatus = kUSBPending;
523: if(CurrentExecutionLevel() == kSecondaryInterruptLevel)
524: {
525: err = usbControlPacket(bus, pb, thisPipe->devAddress, thisPipe->endPt);
526: }
527: else
528: {
529: #if 0
530: static pipe *rootHub;
531: // temp hack.
532: // If we're not being called at secondary int, avoid reentrancy prob
533: // by arranging to be called at secondary int.
534:
535: // First try to suppress root hub messages
536: if(rootHub == nil) // assume first seen pipe is root hub
537: {
538: rootHub = thisPipe;
539: }
540: if(thisPipe != rootHub)
541: {
542: USBExpertStatus(-1, "\pUSL - Queueing secondary interrupt Control", thisPipe->devAddress);
543: }
544: #endif
545: // now queue the call back. address and endpoint munged into second parameter
546: err = QueueSecondaryInterruptHandler(usbSIControlPacket, nil, pb,
547: (void *)(
548: (bus << 16) +
549: ((UInt32)thisPipe->devAddress << 8) +
550: ((UInt32)thisPipe->endPt)
551: ) );
552: }
553:
554: /* Processing now continues in controlCallBack */
555:
556:
557: }while(0);
558:
559: if(err == noErr)
560: {
561: err = kUSBPending;
562: }
563: else
564: {
565: pb->usbStatus = err;
566: }
567: return(err);
568: }
569:
570: OSStatus uslDeviceRequest(USBPB *pb)
571: {
572: USBReference ref0, ref;
573: pipe *thisPipe;
574: OSStatus retVal = noErr;
575: UInt32 bus=0;
576:
577: do{
578: ref = pb->usbReference;
579:
580: if((pb->usbFlags & kUSBAddressRequest) != 0)
581: {
582: USBRqRecipient recipient;
583: recipient = pb->usb.cntl.BMRequestType & 31;
584: if(recipient == kUSBInterface)
585: {
586: uslInterface *ifc;
587: retVal = findInterface(ref, &ifc);
588: if(ifc != nil)
589: {
590: pb->usb.cntl.WIndex = ifc->interfaceNum;
591: }
592: }
593: else if(recipient == kUSBEndpoint)
594: {
595: thisPipe = GetPipePtr(ref);
596: if(thisPipe != 0)
597: {
598: ref = thisPipe->devIntfRef;
599: pb->usb.cntl.WIndex = thisPipe->endPt;
600: if(thisPipe->direction == kUSBIn)
601: {
602: pb->usb.cntl.WIndex |= 0x80;
603: }
604: }
605: else
606: {
607: retVal = kUSBUnknownPipeErr;
608: }
609: }
610: else
611: {
612: retVal = paramErr;
613: }
614: if(retVal != noErr)
615: {
616: pb->usbStatus = retVal;
617: break;
618: }
619: }
620:
621: ref0 = getPipeZero(ref);
622: if(ref0 == nil)
623: {
624: if(uslHubValidateDevZero(ref, &bus))
625: {
626: thisPipe = &pipeZeroZero;
627: thisPipe->bus = bus;
628: }
629: else
630: {
631: retVal = kUSBUnknownDeviceErr;
632: break;
633: }
634: }
635: else
636: {
637: thisPipe = GetPipePtr(ref0);
638: if(thisPipe == nil)
639: {
640: pb->usbStatus = kUSBUnknownPipeErr;
641: break;
642: }
643: }
644: retVal = xUSLControlRequest(thisPipe->bus, pb, thisPipe);
645: if(retVal != kUSBPending)
646: {
647: break;
648: }
649:
650: }while(0);
651: return(retVal);
652: }
653:
654:
655:
656: OSStatus USBDeviceRequest(USBPB *pb)
657: {
658: if(!checkPBVersion(pb, kUSBAddressRequest))
659: {
660: return(pb->usbStatus);
661: }
662:
663: /* Short circuit config device requests */
664: if( (pb->pbVersion != 1) && // requires 0.02 PB
665: (pb->usb.cntl.BMRequestType == 0) &&
666: (pb->usb.cntl.BRequest == kUSBRqSetConfig) )
667: {
668: pb->usbReqCount = 0;
669: pb->usbActCount = 0;
670:
671: pb->addrStash = (UInt32)pb->usbBuffer;
672: pb->usbBuffer = 0;
673: return(uslOpenDevice(pb));
674: }
675:
676: return(uslDeviceRequest(pb));
677: }
678:
679:
680: /* xxxx do checking that params are correct, now we have config desc */
681:
682: /* xxxx do checking that params are correct, now we have config desc */
683: static OSStatus uslOpenPipe(USBPB *pb)
684: {
685:
686: switch(pb->usbClassType)
687: {
688: case kUSBBulk:
689: return(uslOpenBulkEndpoint(pb));
690: break;
691:
692: case kUSBInterrupt:
693: return(uslOpenInterruptEndpoint(pb));
694: break;
695:
696: case kUSBIsoc:
697: return(uslOpenIsocEndpoint(pb));
698: break;
699:
700: case kUSBControl:
701: //OSStatus uslOpenControlEndpoint(USBPB *pb);
702: return(kUSBIncorrectTypeErr);
703: break;
704:
705: default:
706: return(kUSBIncorrectTypeErr);
707: break;
708:
709: }
710: }
711:
712: OSStatus USBOpenPipe(USBPB *pb)
713: {
714: if(!checkPBVersion(pb, kUSBAnyDirn))
715: {
716: return(pb->usbStatus);
717: }
718:
719: return(uslOpenPipe(pb));
720:
721: }
722:
723:
724: OSStatus uslOpenPipeImmed(USBInterfaceRef intrfc, USBEndPointDescriptor *endp)
725: {
726: /* this relies on USBOpenPipe, and the bulk and interrupt opens */
727: /* completing immediatly and not caring if the completion is zero */
728: USBPB pb;
729:
730: pb.usbReference = intrfc;
731: pb.usbCompletion = nil;
732:
733: if((endp->endpointAddress & 0x80) == 0)
734: {
735: pb.usbFlags = kUSBOut;
736: }
737: else
738: {
739: pb.usbFlags = kUSBIn;
740: }
741:
742: pb.usbClassType = endp->attributes&3; // endpoint type
743: pb.usbOther = endp->endpointAddress & 0xf;
744: pb.usb.cntl.WValue = USBToHostWord(endp->maxPacketSize);
745: return(uslOpenPipe(&pb));
746: }
747:
748:
749: void resolvePerformance(USBPB *pb)
750: {
751: pipe *thisPipe;
752: OSStatus err;
753:
754: err = findPipe(pb->usbReference, &thisPipe);
755: if( (thisPipe != nil) && (thisPipe->monitorPerformance) )
756: {
757: pb->usbFrame = deltaFrames(pb->usbFrame, thisPipe->bus);
758: AddAtomic(pb->usbFrame, (void *)&thisPipe->transferTime);
759: AddAtomic(pb->usbActCount, (void *)&thisPipe->bytesTransfered);
760: pb->usbFlags = 0;
761: }
762: }
763:
764: OSStatus USBBulkRead(USBPB *pb)
765: {
766: pipe *thisPipe;
767: OSStatus retVal;
768: if(!checkPBVersion(pb, 0))
769: {
770: return(pb->usbStatus);
771: }
772:
773: retVal = kUSBPending;
774: pb->usbStatus = retVal;
775: do{
776: /* Find our pipe structure for this */
777: retVal = findPipe(pb->usbReference, &thisPipe);
778: if(retVal != noErr)
779: {
780: break;
781: }
782:
783: if(thisPipe->monitorPerformance)
784: {
785: pb->usbFlags = 1;
786: pb->usbFrame = deltaFrames(0, thisPipe->bus);
787: }
788:
789: /* Validate its a bulk out pipe */
790: if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBBulk) )
791: {
792: retVal = kUSBIncorrectTypeErr;
793: break;
794: }
795:
796: /* BT 13Aug98, allow zero length transactions, they're valid. */
797:
798: retVal = usbBulkPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
799: /* Processing now continues in bulkCallBack */
800:
801:
802: }while(0);
803:
804: if(retVal == noErr)
805: {
806: retVal = kUSBPending;
807: }
808: else
809: {
810: pb->usbStatus = retVal;
811: }
812: return(retVal);
813: }
814:
815: OSStatus USBIntRead(USBPB *pb)
816: {
817: pipe *thisPipe;
818: OSStatus retVal;
819:
820: if(!checkPBVersion(pb, 0))
821: {
822: return(pb->usbStatus);
823: }
824:
825: retVal = kUSBPending;
826: pb->usbStatus = retVal;
827: do{
828: /* Find our pipe structure for this */
829: retVal = findPipe(pb->usbReference, &thisPipe);
830: if(retVal != noErr)
831: {
832: break;
833: }
834:
835: if(thisPipe->monitorPerformance)
836: {
837: pb->usbFrame = deltaFrames(0, thisPipe->bus);
838: }
839:
840: /* Validate its a bulk out pipe */
841: if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBInterrupt) )
842: {
843: retVal = kUSBIncorrectTypeErr;
844: break;
845: }
846:
847: /* BT 13Aug98, allow zero length transactions, they're valid. */
848:
849: kprintf("USBIntRead:calling usbIntPacket\n");
850: retVal = usbIntPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
851: /* Processing now continues in intCallBack */
852:
853:
854: }while(0);
855: if(retVal == noErr)
856: {
857: retVal = kUSBPending;
858: }
859: else
860: {
861: pb->usbStatus = retVal;
862: }
863: return(retVal);
864: }
865:
866: OSStatus USBIsocRead(USBPB *pb)
867: {
868: pipe *thisPipe;
869: OSStatus retVal;
870:
871: if(!checkPBVersionIsoc(pb, 0))
872: {
873: return(pb->usbStatus);
874: }
875:
876: retVal = kUSBPending;
877: pb->usbStatus = retVal;
878: do{
879: /* Find our pipe structure for this */
880: retVal = findPipe(pb->usbReference, &thisPipe);
881: if(retVal != noErr)
882: {
883: break;
884: }
885:
886: /* Validate its a bulk out pipe */
887: if( (thisPipe->direction != kUSBIn) || (thisPipe->type != kUSBIsoc) )
888: {
889: retVal = kUSBIncorrectTypeErr;
890: break;
891: }
892:
893: retVal = usbIsocPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBIn);
894: /* Processing now continues in bulkCallBack */
895:
896:
897: }while(0);
898: if(retVal == noErr)
899: {
900: retVal = kUSBPending;
901: }
902: else
903: {
904: pb->usbStatus = retVal;
905: }
906: return(retVal);
907: }
908:
909: OSStatus USBBulkWrite(USBPB *pb)
910: {
911: pipe *thisPipe;
912: OSStatus retVal;
913: if(!checkPBVersion(pb, 0))
914: {
915: return(pb->usbStatus);
916: }
917:
918: retVal = kUSBPending;
919: pb->usbStatus = retVal;
920: do{
921: /* Find our pipe structure for this */
922: retVal = findPipe(pb->usbReference, &thisPipe);
923: if(retVal != noErr)
924: {
925: break;
926: }
927:
928: if(thisPipe->monitorPerformance)
929: {
930: pb->usbFlags = 1;
931: pb->usbFrame = deltaFrames(0, thisPipe->bus);
932: }
933:
934: /* Validate its a bulk out pipe */
935: if( (thisPipe->direction != kUSBOut) || (thisPipe->type != kUSBBulk) )
936: {
937: retVal = kUSBIncorrectTypeErr;
938: break;
939: }
940:
941: /* BT 13Aug98, allow zero length transactions, they're valid. */
942:
943: retVal = usbBulkPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBOut);
944: /* Processing now continues in controlCallBack */
945:
946:
947: }while(0);
948: if(retVal == noErr)
949: {
950: retVal = kUSBPending;
951: }
952: else
953: {
954: pb->usbStatus = retVal;
955: }
956: return(retVal);
957: }
958:
959: OSStatus USBIsocWrite(USBPB *pb)
960: {
961: pipe *thisPipe;
962: OSStatus retVal;
963: if(!checkPBVersionIsoc(pb, 0))
964: {
965: return(pb->usbStatus);
966: }
967:
968: retVal = kUSBPending;
969: pb->usbStatus = retVal;
970: do{
971: /* Find our pipe structure for this */
972: retVal = findPipe(pb->usbReference, &thisPipe);
973: if(retVal != noErr)
974: {
975: break;
976: }
977:
978: /* Validate its a bulk out pipe */
979: if( (thisPipe->direction != kUSBOut) || (thisPipe->type != kUSBIsoc) )
980: {
981: retVal = kUSBIncorrectTypeErr;
982: break;
983: }
984:
985: retVal = usbIsocPacket(thisPipe->bus, pb, thisPipe->devAddress, thisPipe->endPt, kUSBOut);
986: /* Processing now continues in controlCallBack */
987:
988:
989: }while(0);
990: if(retVal == noErr)
991: {
992: retVal = kUSBPending;
993: }
994: else
995: {
996: pb->usbStatus = retVal;
997: }
998: return(retVal);
999: }
1000:
1001: OSStatus uslMonitorBulkPerformanceByReference(USBPipeRef ref, UInt32 what,
1002: UInt32 *lastRead, UInt32 *bytesTransfered, UInt32 *transferTime)
1003: {
1004: pipe *thisPipe;
1005: OSStatus err = noErr;
1006:
1007: do{
1008: /* Note this can't be a device ref, they're automatically cleared */
1009: /* Find the pipe struct */
1010: err = findPipe(ref, &thisPipe);
1011: if(thisPipe == nil)
1012: {
1013: break;
1014: }
1015:
1016: /* Do something here */
1017: switch(what)
1018: {
1019: case 0:
1020: /* stop monitoring this pipe */
1021: if(thisPipe->monitorPerformance)
1022: {
1023: thisPipe->monitorPerformance = false;
1024: }
1025: else
1026: {
1027: err = kUSBNotFound;
1028: }
1029: break;
1030:
1031: case 1:
1032: /* Start monitoring pipe */
1033: if(thisPipe->monitorPerformance)
1034: {
1035: err = kUSBAlreadyOpenErr;
1036: }
1037: else
1038: {
1039: thisPipe->monitorPerformance = true;
1040: thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
1041: }
1042: break;
1043:
1044: case 2:
1045: /* Get stats, don't clear */
1046: if(thisPipe->monitorPerformance)
1047: {
1048: *lastRead = thisPipe->lastRead;
1049: thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
1050: *bytesTransfered = thisPipe->bytesTransfered;
1051: *transferTime = thisPipe->transferTime;
1052: }
1053: else
1054: {
1055: err = kUSBNotFound;
1056: }
1057: break;
1058:
1059: case 3:
1060: /* Get stats clear */
1061: if(thisPipe->monitorPerformance)
1062: {
1063: thisPipe->monitorPerformance = true;
1064: }
1065: *lastRead = thisPipe->lastRead;
1066: thisPipe->lastRead = deltaFrames(0, thisPipe->bus);
1067: *bytesTransfered = thisPipe->bytesTransfered;
1068: *transferTime = thisPipe->transferTime;
1069:
1070: AddAtomic(-*bytesTransfered, (void *)&thisPipe->bytesTransfered);
1071: AddAtomic(-*transferTime, (void *)&thisPipe->transferTime);
1072:
1073: break;
1074:
1075: }
1076:
1077: }while(0);
1078:
1079: return(err);
1080: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.