Annotation of XNU/iokit/Families/IOUSBBus/IOUSBPipe.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * HISTORY
        !            26:  * 08 Dec 98 ehewitt created.
        !            27:  *
        !            28:  */
        !            29: #include <libkern/OSByteOrder.h>
        !            30: 
        !            31: #include <IOKit/IOSyncer.h>
        !            32: #include <IOKit/usb/IOUSBController.h>
        !            33: 
        !            34: #include <IOKit/usb/IOUSBPipe.h>
        !            35: #include <IOKit/usb/IOUSBNub.h>
        !            36: 
        !            37: #define super OSObject
        !            38: #define self this
        !            39: #define DEBUGGING_LEVEL 0
        !            40: #define DEBUGLOG kprintf
        !            41: 
        !            42: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            43: 
        !            44: OSDefineMetaClassAndStructors(IOUSBPipe, OSObject)
        !            45: 
        !            46: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            47: 
        !            48: bool IOUSBPipe::initToEndpoint(const IOUSBEndpointDescriptor *ed, UInt8 speed,
        !            49:                                USBDeviceAddress address, IOUSBController * controller)
        !            50: {
        !            51:     if( !super::init() || ed == 0)
        !            52:         return (false);
        !            53: 
        !            54:     _controller = controller;
        !            55:     _descriptor = ed;
        !            56:     _endpoint.number = ed->endpointAddress & kUSBPipeIDMask;
        !            57:     _endpoint.transferType = ed->attributes & 0x03;
        !            58:     if(_endpoint.transferType == kUSBControl)
        !            59:         _endpoint.direction = kUSBAnyDirn;
        !            60:     else
        !            61:        _endpoint.direction = ed->endpointAddress & 0x80 ? kUSBIn : kUSBOut;
        !            62:     _endpoint.maxPacketSize = OSReadLittleInt16(&ed->maxPacketSizeLo, 0);
        !            63:     _endpoint.interval = ed->interval;
        !            64:     _status = 0;
        !            65:     _address = address;
        !            66:     if(_controller->openPipe(_address, speed, &_endpoint) != kIOReturnSuccess)
        !            67:         return false;
        !            68: 
        !            69:     return (true);
        !            70: }
        !            71: 
        !            72: IOUSBPipe *IOUSBPipe::toEndpoint(const IOUSBEndpointDescriptor *ed, UInt8 speed,
        !            73:                                  USBDeviceAddress address, IOUSBController * controller)
        !            74: {
        !            75:     IOUSBPipe *me = new IOUSBPipe;
        !            76: 
        !            77:     if (me && !me->initToEndpoint(ed, speed, address, controller)) {
        !            78:         me->free();
        !            79:         return 0;
        !            80:     }
        !            81: 
        !            82:     return me;
        !            83: }
        !            84: 
        !            85: void IOUSBPipe::free()
        !            86: {
        !            87:     _controller->closePipe(_address, &_endpoint);
        !            88:     super::free();
        !            89: }
        !            90: 
        !            91: // Controlling pipe state
        !            92: 
        !            93: UInt8 IOUSBPipe::status(void)
        !            94: {
        !            95:     return(_status);
        !            96: }
        !            97: 
        !            98: IOReturn IOUSBPipe::abort(void)
        !            99: {
        !           100:     return _controller->abortPipe(_address, &_endpoint);
        !           101: }
        !           102: 
        !           103: IOReturn IOUSBPipe::reset(void)
        !           104: {
        !           105:     return _controller->resetPipe(_address, &_endpoint);
        !           106: }
        !           107: 
        !           108: IOReturn IOUSBPipe::clearStall(void)
        !           109: {
        !           110:     return _controller->clearPipeStall(_address, &_endpoint);
        !           111: }
        !           112: 
        !           113: // Transferring Data
        !           114: IOReturn IOUSBPipe::read(IOMemoryDescriptor *  buffer,
        !           115:                            IOUSBCompletion *   completion = 0,
        !           116:                            IOByteCount *       bytesRead = 0)
        !           117: {
        !           118:     IOReturn   err = kIOReturnSuccess;
        !           119: 
        !           120: 
        !           121:     if (completion == 0)
        !           122:     {
        !           123:         // put in our own completion routine if none was specified to
        !           124:         // fake synchronous operation
        !           125:         IOUSBCompletion        tap;
        !           126:         IOSyncer *     syncer;
        !           127: 
        !           128:         syncer  = IOSyncer::create();
        !           129:        if (bytesRead)
        !           130:            *bytesRead = buffer->getLength();
        !           131: 
        !           132:         tap.target = syncer;
        !           133:         tap.action = &IOUSBSyncCompletion;
        !           134:         tap.parameter = bytesRead;
        !           135: 
        !           136:         err = _controller->read(buffer, _address, &_endpoint, &tap);
        !           137:         if (err == kIOReturnSuccess){
        !           138:             err = syncer->wait();
        !           139:         }
        !           140:         else {
        !           141:             syncer->release(); syncer->release();
        !           142:         }
        !           143:     }
        !           144:     else
        !           145:     {
        !           146:         err = _controller->read(buffer, _address, &_endpoint, completion);
        !           147:     }
        !           148: 
        !           149:     return(err);
        !           150: }
        !           151: 
        !           152: IOReturn IOUSBPipe::write(IOMemoryDescriptor * buffer,
        !           153:                             IOUSBCompletion *   completion = 0)
        !           154: {
        !           155:     IOReturn   err = kIOReturnSuccess;
        !           156: 
        !           157:     if (completion == 0)
        !           158:     {
        !           159:         // put in our own completion routine if none was specified to
        !           160:         // fake synchronous operation
        !           161:         IOUSBCompletion        tap;
        !           162:         IOSyncer *     syncer;
        !           163: 
        !           164:         syncer  = IOSyncer::create();
        !           165: 
        !           166:         tap.target = syncer;
        !           167:         tap.action = &IOUSBSyncCompletion;
        !           168:         tap.parameter = NULL;
        !           169: 
        !           170:         err = _controller->write(buffer, _address, &_endpoint, &tap);
        !           171:         if (err == kIOReturnSuccess) {
        !           172:             err = syncer->wait();
        !           173:         }
        !           174:         else {
        !           175:             syncer->release(); syncer->release();
        !           176:         }
        !           177:     }
        !           178:     else
        !           179:     {
        !           180:         err = _controller->write(buffer, _address, &_endpoint, completion);
        !           181:     }
        !           182: 
        !           183:     return(err);
        !           184: }
        !           185: 
        !           186: // Isochronous read and write
        !           187: IOReturn IOUSBPipe::read(IOMemoryDescriptor * buffer,
        !           188:        UInt64 frameStart, UInt32 numFrames, IOUSBIsocFrame *pFrames,
        !           189:                          IOUSBIsocCompletion * completion)
        !           190: {
        !           191:     IOReturn   err = kIOReturnSuccess;
        !           192: 
        !           193:     if (completion == 0)
        !           194:     {
        !           195:         // put in our own completion routine if none was specified to
        !           196:         // fake synchronous operation
        !           197:         IOUSBIsocCompletion    tap;
        !           198:         IOSyncer *             syncer;
        !           199: 
        !           200:         syncer  = IOSyncer::create();
        !           201: 
        !           202:         tap.target = (void *)syncer;
        !           203:         tap.action = IOUSBSyncIsoCompletion;
        !           204:         tap.parameter = NULL;
        !           205: 
        !           206:         err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
        !           207:                 _address, &_endpoint, &tap);
        !           208: 
        !           209:         if (err == kIOReturnSuccess) {
        !           210:             err = syncer->wait();
        !           211:         }
        !           212:         else {
        !           213:             syncer->release(); syncer->release();
        !           214:        }
        !           215:     }
        !           216:     else {
        !           217:         err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
        !           218:                 _address, &_endpoint, completion);
        !           219:     }
        !           220: 
        !           221:     return(err);
        !           222: }
        !           223: 
        !           224: IOReturn IOUSBPipe::write(IOMemoryDescriptor * buffer,
        !           225:        UInt64 frameStart, UInt32 numFrames, IOUSBIsocFrame *pFrames,
        !           226:                                        IOUSBIsocCompletion *   completion)
        !           227: {
        !           228:     IOReturn   err = kIOReturnSuccess;
        !           229: 
        !           230:     if (completion == 0)
        !           231:     {
        !           232:         // put in our own completion routine if none was specified to
        !           233:         // fake synchronous operation
        !           234:         IOUSBIsocCompletion    tap;
        !           235:         IOSyncer *             syncer;
        !           236: 
        !           237:         syncer  = IOSyncer::create();
        !           238: 
        !           239:         tap.target = syncer;
        !           240:         tap.action = &IOUSBSyncIsoCompletion;
        !           241:         tap.parameter = NULL;
        !           242: 
        !           243:         err = _controller->isocIO(buffer, frameStart, numFrames, pFrames,
        !           244:                 _address, &_endpoint, &tap);
        !           245: 
        !           246:         if (err == kIOReturnSuccess)
        !           247:         {
        !           248:             err = syncer->wait();
        !           249:         }
        !           250:         else {
        !           251:             syncer->release(); syncer->release();
        !           252:         }
        !           253:     }
        !           254:     else
        !           255:     {
        !           256:         err = _controller->isocIO(buffer, frameStart, numFrames, pFrames, 
        !           257:                _address, &_endpoint, completion);
        !           258: 
        !           259:     }
        !           260: 
        !           261:     return(err);
        !           262: }
        !           263: 
        !           264: IOReturn IOUSBPipe::controlRequest(IOUSBDevRequest     *request,
        !           265:                                     IOUSBCompletion    *completion = 0)
        !           266: {
        !           267:     IOReturn   err = kIOReturnSuccess;
        !           268: 
        !           269: 
        !           270: #if (DEBUGGING_LEVEL > 0)
        !           271:     DEBUGLOG("%s: deviceRequest([%x,%s,%x,%x],[%x,%x],[%x,%lx])\n", "IOUSBPipe",
        !           272:              request->bRequest,
        !           273:              request->rqDirection?"in":"out",
        !           274:              request->rqType, request->rqRecipient,
        !           275:              OSReadLittleInt16(&request->wValue, 0),
        !           276:              OSReadLittleInt16(&request->wIndex, 0),
        !           277:              OSReadLittleInt16(&request->wLength, 0),
        !           278:              (UInt32)request->pData);
        !           279: #endif
        !           280: 
        !           281:     if (completion == 0)
        !           282:     {
        !           283:         // put in our own completion routine if none was specified to
        !           284:         // fake synchronous operation
        !           285:         IOUSBCompletion        tap;
        !           286:         IOSyncer *     syncer;
        !           287: 
        !           288:         syncer  = IOSyncer::create();
        !           289:         request->wLenDone = OSReadLittleInt16(&request->wLength, 0);
        !           290: 
        !           291:         tap.target = syncer;
        !           292:         tap.action = &IOUSBSyncCompletion;
        !           293:         tap.parameter = &request->wLenDone;
        !           294: 
        !           295:         err = _controller->deviceRequest(request, &tap, _address, _endpoint.number);
        !           296:         if (err == kIOReturnSuccess) {
        !           297:             err = syncer->wait();
        !           298:         }
        !           299:        else {
        !           300:             syncer->release(); syncer->release();
        !           301:         }
        !           302:     }
        !           303:     else
        !           304:     {
        !           305:         err = _controller->deviceRequest(request, completion, _address, _endpoint.number);
        !           306:     }
        !           307: 
        !           308:     return(err);
        !           309: }
        !           310: 
        !           311: IOReturn IOUSBPipe::controlRequest(IOUSBDevRequestDesc *request,
        !           312:                                     IOUSBCompletion    *completion = 0)
        !           313: {
        !           314:     IOReturn   err = kIOReturnSuccess;
        !           315: 
        !           316: 
        !           317: #if (DEBUGGING_LEVEL > 0)
        !           318:     DEBUGLOG("%s: deviceRequest([%x,%s,%x,%x],[%x,%x],[%x,%lx])\n", "IOUSBPipe",
        !           319:              request->bRequest,
        !           320:              request->rqDirection?"in":"out",
        !           321:              request->rqType, request->rqRecipient,
        !           322:              OSReadLittleInt16(&request->wValue, 0),
        !           323:              OSReadLittleInt16(&request->wIndex, 0),
        !           324:              OSReadLittleInt16(&request->wLength, 0),
        !           325:              (UInt32)request->pData);
        !           326: #endif
        !           327: 
        !           328:     if (completion == 0)
        !           329:     {
        !           330:         // put in our own completion routine if none was specified to
        !           331:         // fake synchronous operation
        !           332:         IOUSBCompletion        tap;
        !           333:         IOSyncer *     syncer;
        !           334: 
        !           335:         syncer  = IOSyncer::create();
        !           336:         request->wLenDone = OSReadLittleInt16(&request->wLength, 0);
        !           337: 
        !           338:         tap.target = syncer;
        !           339:         tap.action = &IOUSBSyncCompletion;
        !           340:         tap.parameter = &request->wLenDone;
        !           341: 
        !           342:         err = _controller->deviceRequest(request, &tap, _address, _endpoint.number);
        !           343:         if (err == kIOReturnSuccess) {
        !           344:             err = syncer->wait();
        !           345:         }
        !           346:        else {
        !           347:             syncer->release(); syncer->release();
        !           348:        }
        !           349:     }
        !           350:     else
        !           351:     {
        !           352:         err = _controller->deviceRequest(request, completion, _address, _endpoint.number);
        !           353:     }
        !           354: 
        !           355:     return(err);
        !           356: }
        !           357: 
        !           358: const IOUSBDescriptorHeader *
        !           359: IOUSBPipe::findNextAssociatedDescriptor(const void *current, UInt8 type)
        !           360: {
        !           361:     const IOUSBDescriptorHeader *next;
        !           362:     if(current == NULL)
        !           363:         current = _descriptor;
        !           364:     next = (const IOUSBDescriptorHeader *)current;
        !           365: 
        !           366:     while (true) {
        !           367:         next = IOUSBNub::findNextDescriptor(next, kUSBAnyDesc);
        !           368: 
        !           369:         if(!next || next->descriptorType == kUSBEndpointDesc)
        !           370:             return NULL;       // Reached end of our list.
        !           371:         if(next->descriptorType == type || type == kUSBAnyDesc)
        !           372:             break;
        !           373:     }
        !           374:     return next;
        !           375: }
        !           376: 
        !           377: UInt32 IOUSBPipe::GetBandwidthAvailable()
        !           378: {
        !           379:     return _controller->GetBandwidthAvailable();
        !           380: }
        !           381: 
        !           382: UInt64 IOUSBPipe::GetFrameNumber()
        !           383: {
        !           384:     return _controller->GetFrameNumber();
        !           385: }
        !           386: 
        !           387: 
        !           388: /*
        !           389:  *  Accessors
        !           390:  */
        !           391: const IOUSBController::Endpoint *IOUSBPipe::endpoint(void)
        !           392: { return(&_endpoint); }
        !           393: 
        !           394: const IOUSBEndpointDescriptor *IOUSBPipe::endpointDescriptor(void)
        !           395: { return(_descriptor); }
        !           396: 
        !           397: UInt8 IOUSBPipe::direction(void)
        !           398: { return(_endpoint.direction); }
        !           399: 
        !           400: UInt8 IOUSBPipe::type(void)
        !           401: { return(_endpoint.transferType); }
        !           402: 
        !           403: UInt8 IOUSBPipe::endpointNumber(void)
        !           404: { return(_endpoint.number); }
        !           405: 
        !           406: USBDeviceAddress IOUSBPipe::address(void)
        !           407: { return(_address); }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.