Annotation of XNU/iokit/Families/IOUSBBus/IOUSBPipe.cpp, revision 1.1.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.