|
|
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); }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.