1/* 2 * 3 * @APPLE_LICENSE_HEADER_START@ 4 * 5 * Copyright (c) 1998-2003 Apple Computer, Inc. All Rights Reserved. 6 * 7 * This file contains Original Code and/or Modifications of Original Code 8 * as defined in and that are subject to the Apple Public Source License 9 * Version 2.0 (the 'License'). You may not use this file except in 10 * compliance with the License. Please obtain a copy of the License at 11 * http://www.opensource.apple.com/apsl/ and read it before using this 12 * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. 19 * Please see the License for the specific language governing rights and 20 * limitations under the License. 21 * 22 * @APPLE_LICENSE_HEADER_END@ 23 */ 24 25 /* AppleUSBCDCECMControl.cpp - MacOSX implementation of */ 26 /* USB Communication Device Class (CDC) Driver, Ethernet Control Interface. */ 27 28#include <machine/limits.h> /* UINT_MAX */ 29#include <libkern/OSByteOrder.h> 30 31#include <IOKit/network/IOEthernetController.h> 32#include <IOKit/network/IOEthernetInterface.h> 33#include <IOKit/network/IOGatedOutputQueue.h> 34 35#include <IOKit/IOTimerEventSource.h> 36#include <IOKit/assert.h> 37#include <IOKit/IOLib.h> 38#include <IOKit/IOService.h> 39#include <IOKit/IOBufferMemoryDescriptor.h> 40#include <IOKit/IOMessage.h> 41 42#include <IOKit/pwr_mgt/RootDomain.h> 43 44#if !TARGET_OS_IPHONE 45#include <IOKit/usb/IOUSBBus.h> 46#endif /* TARGET_OS_IPHONE */ 47 48#include <IOKit/usb/IOUSBNub.h> 49#include <IOKit/usb/IOUSBDevice.h> 50#include <IOKit/usb/IOUSBPipe.h> 51#include <IOKit/usb/USB.h> 52#include <IOKit/usb/IOUSBInterface.h> 53 54#include <UserNotification/KUNCUserNotifications.h> 55 56extern "C" 57{ 58 #include <sys/param.h> 59 #include <sys/mbuf.h> 60} 61 62#define DEBUG_NAME "AppleUSBCDCECMControl" 63 64#include "AppleUSBCDCECM.h" 65#include "AppleUSBCDCECMControl.h" 66#include "AppleUSBCDCECMData.h" 67 68#if 0 69static IOPMPowerState gOurPowerStates[kNumCDCStates] = 70{ 71 {1,0,0,0,0,0,0,0,0,0,0,0}, 72 {1,IOPMDeviceUsable,IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0} 73}; 74#endif 75 76#define numStats 13 77UInt16 stats[numStats] = { kXMIT_OK_REQ, 78 kRCV_OK_REQ, 79 kXMIT_ERROR_REQ, 80 kRCV_ERROR_REQ, 81 kRCV_CRC_ERROR_REQ, 82 kRCV_ERROR_ALIGNMENT_REQ, 83 kXMIT_ONE_COLLISION_REQ, 84 kXMIT_MORE_COLLISIONS_REQ, 85 kXMIT_DEFERRED_REQ, 86 kXMIT_MAX_COLLISION_REQ, 87 kRCV_OVERRUN_REQ, 88 kXMIT_TIMES_CARRIER_LOST_REQ, 89 kXMIT_LATE_COLLISIONS_REQ 90 }; 91 92#define super IOService 93 94OSDefineMetaClassAndStructors(AppleUSBCDCECMControl, IOService); 95 96/****************************************************************************************************/ 97// 98// Function: findCDCDriverEC 99// 100// Inputs: controlAddr - my address 101// 102// Outputs: 103// 104// Desc: Finds the initiating CDC driver 105// 106/****************************************************************************************************/ 107 108AppleUSBCDC *findCDCDriverEC(void *controlAddr, IOReturn *retCode) 109{ 110 AppleUSBCDCECMControl *me = (AppleUSBCDCECMControl *)controlAddr; 111 AppleUSBCDC *CDCDriver = NULL; 112 bool driverOK = false; 113 OSIterator *iterator = NULL; 114 OSDictionary *matchingDictionary = NULL; 115 116 XTRACE(me, 0, 0, "findCDCDriverEC"); 117 118 // Get matching dictionary 119 120 matchingDictionary = IOService::serviceMatching("AppleUSBCDC"); 121 if (!matchingDictionary) 122 { 123 XTRACE(me, 0, 0, "findCDCDriverEC - Couldn't create a matching dictionary"); 124 *retCode = kIOReturnError; 125 return NULL; 126 } 127 128 // Get an iterator 129 130 iterator = IOService::getMatchingServices(matchingDictionary); 131 if (!iterator) 132 { 133 XTRACE(me, 0, 0, "findCDCDriverEC - No AppleUSBCDC driver found!"); 134 matchingDictionary->release(); 135 *retCode = kIOReturnError; 136 return NULL; 137 } 138 139 // Iterate until we find our matching CDC driver 140 141 CDCDriver = (AppleUSBCDC *)iterator->getNextObject(); 142 while (CDCDriver) 143 { 144 XTRACEP(me, 0, CDCDriver, "findCDCDriverEC - CDC driver candidate"); 145 146 if (me->fControlInterface->GetDevice() == CDCDriver->getCDCDevice()) 147 { 148 XTRACEP(me, 0, CDCDriver, "findCDCDriverEC - Found our CDC driver"); 149 driverOK = CDCDriver->confirmControl(kUSBEthernetControlModel, me->fControlInterface); 150 break; 151 } 152 CDCDriver = (AppleUSBCDC *)iterator->getNextObject(); 153 } 154 155 matchingDictionary->release(); 156 iterator->release(); 157 158 if (!CDCDriver) 159 { 160 XTRACE(me, 0, 0, "findCDCDriverEC - CDC driver not found"); 161 *retCode = kIOReturnNotReady; 162 return NULL; 163 } 164 165 if (!driverOK) 166 { 167 XTRACE(me, kUSBEthernetControlModel, 0, "findCDCDriverEC - Not my interface"); 168 *retCode = kIOReturnError; 169 return NULL; 170 } 171 172 *retCode = kIOReturnSuccess; 173 174 return CDCDriver; 175 176}/* end findCDCDriverAC */ 177 178/****************************************************************************************************/ 179// 180// Function: AppleUSBCDCECMControl::Asciihex_to_binary 181// 182// Inputs: c - Ascii character 183// 184// Outputs: return byte - binary byte 185// 186// Desc: Converts to hex (binary). 187// 188/****************************************************************************************************/ 189 190UInt8 AppleUSBCDCECMControl::Asciihex_to_binary(char c) 191{ 192 193 if ('0' <= c && c <= '9') 194 return(c-'0'); 195 196 if ('A' <= c && c <= 'F') 197 return((c-'A')+10); 198 199 if ('a' <= c && c <= 'f') 200 return((c-'a')+10); 201 202 // Not a hex digit, do whatever 203 204 return(0); 205 206}/* end Asciihex_to_binary */ 207 208/****************************************************************************************************/ 209// 210// Method: AppleUSBCDCECMControl::commReadComplete 211// 212// Inputs: obj - me 213// param - unused 214// rc - return code 215// remaining - what's left 216// 217// Outputs: 218// 219// Desc: Interrupt pipe (Comm interface) read completion routine 220// 221/****************************************************************************************************/ 222//This method rolled back to the one from 4.1.17 due to radar://11946906 223void AppleUSBCDCECMControl::commReadComplete(void *obj, void *param, IOReturn rc, UInt32 remaining) 224{ 225 AppleUSBCDCECMControl *me = (AppleUSBCDCECMControl*)obj; 226 IOReturn ior; 227 UInt32 dLen; 228 UInt8 notif; 229 ConnectionSpeedChange *speedChange; 230 231 if (rc == kIOReturnSuccess) // If operation returned ok 232 { 233 dLen = COMM_BUFF_SIZE - remaining; 234 XTRACE(me, rc, dLen, "commReadComplete"); 235 236 // Now look at the state stuff 237 238 notif = me->fCommPipeBuffer[1]; 239 if (dLen > 7) 240 { 241 switch(notif) 242 { 243 case kUSBNETWORK_CONNECTION: 244 me->fLinkStatus = me->fCommPipeBuffer[2]; 245 XTRACE(me, 0, me->fLinkStatus, "commReadComplete - kNetwork_Connection"); 246 if (me->fDataDriver) 247 { 248 me->fDataDriver->linkStatusChange(me->fLinkStatus); 249 } 250 break; 251 case kUSBCONNECTION_SPEED_CHANGE: 252 speedChange = (ConnectionSpeedChange *)me->fCommPipeBuffer; 253 me->fUpSpeed = USBToHostLong(speedChange->USBitRate); 254 me->fDownSpeed = USBToHostLong(speedChange->DSBitRate); 255 256 XTRACE(me, me->fUpSpeed, me->fDownSpeed, "commReadComplete - kConnection_Speed_Change"); 257 if (me->fDataDriver) 258 { 259 me->fDataDriver->linkSpeedChange(me->fUpSpeed, me->fDownSpeed); 260 } 261 break; 262 default: 263 XTRACE(me, 0, notif, "commReadComplete - Unknown notification"); 264 break; 265 } 266 } else { 267 XTRACE(me, 0, notif, "commReadComplete - Invalid notification"); 268 } 269 } else { 270 XTRACE(me, 0, rc, "commReadComplete - IO error"); 271 if (rc != kIOReturnAborted) 272 { 273 rc = me->checkPipe(me->fCommPipe, false); 274 if (rc != kIOReturnSuccess) 275 { 276 XTRACE(me, 0, rc, "dataReadComplete - clear stall failed (trying to continue)"); 277 } 278 } 279 } 280 281 // Queue the next read, only if not aborted 282 283 if (rc != kIOReturnAborted) 284 { 285 ior = me->fCommPipe->Read(me->fCommPipeMDP, &me->fCommCompletionInfo, NULL); 286 if (ior != kIOReturnSuccess) 287 { 288 XTRACE(me, 0, rc, "commReadComplete - Read io error"); 289 me->fCommDead = true; 290 } 291 } 292 293 return; 294 295}/* end commReadComplete */ 296 297/****************************************************************************************************/ 298// 299// Method: AppleUSBCDCECMControl::merWriteComplete 300// 301// Inputs: obj - me 302// param - MER (may or may not be present depending on request) 303// rc - return code 304// remaining - what's left 305// 306// Outputs: 307// 308// Desc: Management element request write completion routine 309// 310/****************************************************************************************************/ 311 312void AppleUSBCDCECMControl::merWriteComplete(void *obj, void *param, IOReturn rc, UInt32 remaining) 313{ 314#if LDEBUG 315 AppleUSBCDCECMControl *me = (AppleUSBCDCECMControl *)obj; 316#endif 317 IOUSBDevRequest *MER = (IOUSBDevRequest*)param; 318 UInt16 dataLen; 319 320 if (MER) 321 { 322 if (rc == kIOReturnSuccess) 323 { 324 XTRACE(me, MER->bRequest, remaining, "merWriteComplete"); 325 } else { 326 XTRACE(me, MER->bRequest, rc, "merWriteComplete - io err"); 327 } 328 329 dataLen = MER->wLength; 330 XTRACE(me, 0, dataLen, "merWriteComplete - data length"); 331 if ((dataLen != 0) && (MER->pData)) 332 { 333 IOFree(MER->pData, dataLen); 334 } 335 IOFree(MER, sizeof(IOUSBDevRequest)); 336 337 } else { 338 if (rc == kIOReturnSuccess) 339 { 340 XTRACE(me, 0, remaining, "merWriteComplete (request unknown)"); 341 } else { 342 XTRACE(me, 0, rc, "merWriteComplete (request unknown) - io err"); 343 } 344 } 345 346 return; 347 348}/* end merWriteComplete */ 349 350/****************************************************************************************************/ 351// 352// Method: AppleUSBCDCECMControl::statsWriteComplete 353// 354// Inputs: obj - me 355// param - parameter block 356// rc - return code 357// remaining - what's left 358// 359// Outputs: 360// 361// Desc: Ethernet statistics request write completion routine 362// 363/****************************************************************************************************/ 364 365void AppleUSBCDCECMControl::statsWriteComplete(void *obj, void *param, IOReturn rc, UInt32 remaining) 366{ 367 AppleUSBCDCECMControl *me = (AppleUSBCDCECMControl *)obj; 368 IOUSBDevRequest *STREQ = (IOUSBDevRequest*)param; 369 UInt16 currStat; 370 371 if (STREQ) 372 { 373 if (rc == kIOReturnSuccess) 374 { 375 XTRACE(me, STREQ->bRequest, remaining, "statsWriteComplete"); 376 currStat = STREQ->wValue; 377 switch(currStat) 378 { 379 case kXMIT_OK_REQ: 380 me->fpNetStats->outputPackets = USBToHostLong(me->fStatValue); 381 break; 382 case kRCV_OK_REQ: 383 me->fpNetStats->inputPackets = USBToHostLong(me->fStatValue); 384 break; 385 case kXMIT_ERROR_REQ: 386 me->fpNetStats->outputErrors = USBToHostLong(me->fStatValue); 387 break; 388 case kRCV_ERROR_REQ: 389 me->fpNetStats->inputErrors = USBToHostLong(me->fStatValue); 390 break; 391 case kRCV_CRC_ERROR_REQ: 392 me->fpEtherStats->dot3StatsEntry.fcsErrors = USBToHostLong(me->fStatValue); 393 break; 394 case kRCV_ERROR_ALIGNMENT_REQ: 395 me->fpEtherStats->dot3StatsEntry.alignmentErrors = USBToHostLong(me->fStatValue); 396 break; 397 case kXMIT_ONE_COLLISION_REQ: 398 me->fpEtherStats->dot3StatsEntry.singleCollisionFrames = USBToHostLong(me->fStatValue); 399 break; 400 case kXMIT_MORE_COLLISIONS_REQ: 401 me->fpEtherStats->dot3StatsEntry.multipleCollisionFrames = USBToHostLong(me->fStatValue); 402 break; 403 case kXMIT_DEFERRED_REQ: 404 me->fpEtherStats->dot3StatsEntry.deferredTransmissions = USBToHostLong(me->fStatValue); 405 break; 406 case kXMIT_MAX_COLLISION_REQ: 407 me->fpNetStats->collisions = USBToHostLong(me->fStatValue); 408 break; 409 case kRCV_OVERRUN_REQ: 410 me->fpEtherStats->dot3StatsEntry.frameTooLongs = USBToHostLong(me->fStatValue); 411 break; 412 case kXMIT_TIMES_CARRIER_LOST_REQ: 413 me->fpEtherStats->dot3StatsEntry.carrierSenseErrors = USBToHostLong(me->fStatValue); 414 break; 415 case kXMIT_LATE_COLLISIONS_REQ: 416 me->fpEtherStats->dot3StatsEntry.lateCollisions = USBToHostLong(me->fStatValue); 417 break; 418 default: 419 XTRACE(me, currStat, rc, "statsWriteComplete - Invalid stats code"); 420 break; 421 } 422 423 } else { 424 XTRACE(me, STREQ->bRequest, rc, "statsWriteComplete - io err"); 425 } 426 427 IOFree(STREQ, sizeof(IOUSBDevRequest)); 428 } else { 429 if (rc == kIOReturnSuccess) 430 { 431 XTRACE(me, 0, remaining, "statsWriteComplete (request unknown)"); 432 } else { 433 XTRACE(me, 0, rc, "statsWriteComplete (request unknown) - io err"); 434 } 435 } 436 437 me->fStatValue = 0; 438 me->fStatInProgress = false; 439 return; 440 441}/* end statsWriteComplete */ 442 443/****************************************************************************************************/ 444// 445// Method: AppleUSBCDCECMControl::probe 446// 447// Inputs: provider - my provider 448// 449// Outputs: IOService - from super::probe, score - probe score 450// 451// Desc: Modify the probe score if necessary (we don't at the moment) 452// 453/****************************************************************************************************/ 454 455IOService* AppleUSBCDCECMControl::probe(IOService *provider, SInt32 *score) 456{ 457 IOService *res; 458 459 // If our IOUSBInterface has a "do not match" property, it means that we should not match and need 460 // to bail. See rdar://3716623 461 462 OSBoolean *boolObj = OSDynamicCast(OSBoolean, provider->getProperty("kDoNotClassMatchThisInterface")); 463 if (boolObj && boolObj->isTrue()) 464 { 465 XTRACE(this, 0, 0, "probe - provider doesn't want us to match"); 466 return NULL; 467 } 468 469 res = super::probe(provider, score); 470 471 return res; 472 473}/* end probe */ 474 475/****************************************************************************************************/ 476// 477// Method: AppleUSBCDCECMControl::start 478// 479// Inputs: provider - my provider 480// 481// Outputs: Return code - true (it's me), false (sorry it probably was me, but I can't configure it) 482// 483// Desc: This is called once it has beed determined I'm probably the best 484// driver for this device. 485// 486/****************************************************************************************************/ 487 488bool AppleUSBCDCECMControl::start(IOService *provider) 489{ 490 IOReturn rtn; 491 UInt16 devDriverCount = 0; 492 493 XTRACE(this, 0, 0, "start"); 494 495 fCurrStat = 0; 496 fCDCDriver = NULL; 497 fStatInProgress = false; 498 fMax_Block_Size = MAX_BLOCK_SIZE; 499 fCommDead = false; 500 fPacketFilter = kPACKET_TYPE_DIRECTED | kPACKET_TYPE_BROADCAST | kPACKET_TYPE_MULTICAST; 501 fpNetStats = NULL; 502 fpEtherStats = NULL; 503 fDataDriver = NULL; 504 505 if(!super::start(provider)) 506 { 507 ALERT(0, 0, "start - super failed"); 508 return false; 509 } 510 511 // Get my USB provider - the interface 512 513 fControlInterface = OSDynamicCast(IOUSBInterface, provider); 514 if(!fControlInterface) 515 { 516 ALERT(0, 0, "start - provider invalid"); 517 return false; 518 } 519 520 // See if we can find/wait for the CDC driver 521 522 while (!fCDCDriver) 523 { 524 rtn = kIOReturnSuccess; 525 fCDCDriver = findCDCDriverEC(this, &rtn); 526 if (fCDCDriver) 527 { 528 XTRACE (this, 0, fControlInterface->GetInterfaceNumber(), "start: Found the CDC device driver"); 529 break; 530 } else { 531 if (rtn == kIOReturnNotReady) 532 { 533 devDriverCount++; 534 XTRACE(this, devDriverCount, fControlInterface->GetInterfaceNumber(), "start - Waiting for CDC device driver..."); 535 if (devDriverCount > 9) 536 { 537 break; 538 } 539 IOSleep(100); 540 } else { 541 break; 542 } 543 } 544 } 545 546 // If we didn't find him then we have to bail 547 548 if (!fCDCDriver) 549 { 550 ALERT(0, fControlInterface->GetInterfaceNumber(), "start - Failed to find the CDC driver"); 551 return false; 552 } 553 554 if (!configureECM()) 555 { 556 ALERT(0, 0, "start - configureECM failed"); 557 return false; 558 } 559 560 if (!allocateResources()) 561 { 562 ALERT(0, 0, "start - allocateResources failed"); 563 return false; 564 } 565 566 fControlInterface->retain(); 567 568#if 0 569 if (!initForPM(provider)) 570 { 571 ALERT(0, 0, "start - initForPM failed"); 572 return false; 573 } 574#endif 575 576 registerService(); 577 578 XTRACE(this, 0, 0, "start - successful"); 579 580 return true; 581 582}/* end start */ 583 584/****************************************************************************************************/ 585// 586// Method: AppleUSBCDCECMControl::stop 587// 588// Inputs: provider - my provider 589// 590// Outputs: 591// 592// Desc: Stops the driver 593// 594/****************************************************************************************************/ 595 596void AppleUSBCDCECMControl::stop(IOService *provider) 597{ 598 599 XTRACE(this, 0, 0, "stop"); 600 601 releaseResources(); 602 603// PMstop(); 604 605 super::stop(provider); 606 607 return; 608 609}/* end stop */ 610 611/****************************************************************************************************/ 612// 613// Method: AppleUSBCDCECMControl::configureECM 614// 615// Inputs: 616// 617// Outputs: return Code - true (device configured), false (device not configured) 618// 619// Desc: Finds the configurations and then the appropriate interfaces etc. 620// 621/****************************************************************************************************/ 622 623bool AppleUSBCDCECMControl::configureECM() 624{ 625 626 XTRACE(this, 0, 0, "configureECM"); 627 628 fCommInterfaceNumber = fControlInterface->GetInterfaceNumber(); 629 XTRACE(this, 0, fCommInterfaceNumber, "configureECM - Comm interface number."); 630 631 if (!getFunctionalDescriptors()) 632 { 633 ALERT(0, 0, "configureECM - getFunctionalDescriptors failed"); 634// releaseResources(); 635 return false; 636 } 637 638 return true; 639 640}/* end configureECM */ 641 642/****************************************************************************************************/ 643// 644// Method: AppleUSBCDCECMControl::getFunctionalDescriptors 645// 646// Inputs: 647// 648// Outputs: return - true (descriptors ok), false (somethings not right or not supported) 649// 650// Desc: Finds all the functional descriptors for the specific interface 651// 652/****************************************************************************************************/ 653 654bool AppleUSBCDCECMControl::getFunctionalDescriptors() 655{ 656 bool gotDescriptors = false; 657 bool configok = true; 658 bool enet = false; 659 IOReturn ior; 660 const HDRFunctionalDescriptor *funcDesc = NULL; 661 ECMFunctionalDescriptor *ENETFDesc; 662 UnionFunctionalDescriptor *UNNFDesc; 663 UInt8 serString; 664 char ascii_mac[14]; 665 UInt16 i; 666 667 XTRACE(this, 0, 0, "getFunctionalDescriptors"); 668 669 do 670 { 671 funcDesc = (const HDRFunctionalDescriptor *)fControlInterface->FindNextAssociatedDescriptor((void*)funcDesc, CS_INTERFACE); 672 if (!funcDesc) 673 { 674 gotDescriptors = true; 675 } else { 676 switch (funcDesc->bDescriptorSubtype) 677 { 678 case Header_FunctionalDescriptor: 679 XTRACE(this, funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype, "getFunctionalDescriptors - Header Functional Descriptor"); 680 break; 681 case ECM_Functional_Descriptor: 682 ENETFDesc = (ECMFunctionalDescriptor *)funcDesc; 683 XTRACE(this, funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype, "getFunctionalDescriptors - Ethernet Functional Descriptor"); 684 enet = true; 685 break; 686 case Union_FunctionalDescriptor: 687 UNNFDesc = (UnionFunctionalDescriptor *)funcDesc; 688 XTRACE(this, funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype, "getFunctionalDescriptors - Union Functional Descriptor"); 689 if (UNNFDesc->bFunctionLength > sizeof(FunctionalDescriptorHeader)) 690 { 691 fDataInterfaceNumber = UNNFDesc->bSlaveInterface[0]; // Use the first slave (may need to revisit) 692 } else { 693 XTRACE(this, UNNFDesc->bFunctionLength, 0, "getFunctionalDescriptors - Union descriptor length error"); 694 } 695 break; 696 default: 697 XTRACE(this, funcDesc->bDescriptorType, funcDesc->bDescriptorSubtype, "getFunctionalDescriptors - unknown Functional Descriptor"); 698 break; 699 } 700 } 701 } while(!gotDescriptors); 702 703 if (!enet) 704 { 705// configok = false; // The Enet Func. Desc. must be present 706 707 // We're going to make some assumptions for now 708 709 fOutputPktsOK = true; 710 fInputPktsOK = true; 711 fOutputErrsOK = true; 712 fInputErrsOK = true; 713 714 fEthernetStatistics[0] = 0; 715 fEthernetStatistics[1] = 0; 716 fEthernetStatistics[2] = 0; 717 fEthernetStatistics[3] = 0; 718 719 fMcFilters = 0; 720 721 serString = fControlInterface->GetDevice()->GetSerialNumberStringIndex(); // Default to the serial number string 722 ior = fControlInterface->GetDevice()->GetStringDescriptor(serString, (char *)&ascii_mac, 13); 723 if (ior == kIOReturnSuccess) 724 { 725 for (i = 0; i < 6; i++) 726 { 727 fEaddr[i] = (Asciihex_to_binary(ascii_mac[i*2]) << 4) | Asciihex_to_binary(ascii_mac[i*2+1]); 728 } 729 } else { 730 ALERT(0, 0, "getFunctionalDescriptors - Error retrieving Ethernet address (serial string)"); 731 configok = false; 732 } 733 } else { 734 735 // Determine who is collecting the input/output network stats. 736 737 if (!(ENETFDesc->bmEthernetStatistics[0] & kXMIT_OK)) 738 { 739 fOutputPktsOK = true; 740 } else { 741 fOutputPktsOK = false; 742 } 743 if (!(ENETFDesc->bmEthernetStatistics[0] & kRCV_OK)) 744 { 745 fInputPktsOK = true; 746 } else { 747 fInputPktsOK = false; 748 } 749 if (!(ENETFDesc->bmEthernetStatistics[0] & kXMIT_ERROR)) 750 { 751 fOutputErrsOK = true; 752 } else { 753 fOutputErrsOK = false; 754 } 755 if (!(ENETFDesc->bmEthernetStatistics[0] & kRCV_ERROR)) 756 { 757 fInputErrsOK = true; 758 } else { 759 fInputErrsOK = false; 760 } 761 762 // Save the stats (it's bit mapped) 763 764 fEthernetStatistics[0] = ENETFDesc->bmEthernetStatistics[0]; 765 fEthernetStatistics[1] = ENETFDesc->bmEthernetStatistics[1]; 766 fEthernetStatistics[2] = ENETFDesc->bmEthernetStatistics[2]; 767 fEthernetStatistics[3] = ENETFDesc->bmEthernetStatistics[3]; 768 769 // Save the multicast filters (remember it's intel format) 770 771 fMcFilters = USBToHostWord(ENETFDesc->wNumberMCFilters); 772 773 // Get the Ethernet address 774 775 if (ENETFDesc->iMACAddress != 0) 776 { 777 ior = fControlInterface->GetDevice()->GetStringDescriptor(ENETFDesc->iMACAddress, (char *)&ascii_mac, 13); 778 if (ior == kIOReturnSuccess) 779 { 780 for (i = 0; i < 6; i++) 781 { 782 fEaddr[i] = (Asciihex_to_binary(ascii_mac[i*2]) << 4) | Asciihex_to_binary(ascii_mac[i*2+1]); 783 } 784 fMax_Block_Size = USBToHostWord(ENETFDesc->wMaxSegmentSize); 785 XTRACE(this, 0, fMax_Block_Size, "getFunctionalDescriptors - Maximum segment size"); 786 } else { 787 ALERT(0, 0, "getFunctionalDescriptors - Error retrieving Ethernet address"); 788 configok = false; 789 } 790 } else { 791 ALERT(0, 0, "getFunctionalDescriptors - Ethernet address is zero"); 792 configok = false; 793 } 794 } 795 796 return configok; 797 798}/* end getFunctionalDescriptors */ 799 800/****************************************************************************************************/ 801// 802// Method: AppleUSBCDCECMControl::dataAcquired 803// 804// Inputs: netStats - Network statistics structure address 805// etherStats - Ethernet statistics structure address 806// 807// Outputs: return Code - true (it worked), false (it didn't) 808// 809// Desc: Tells this driver the data driver's port has been acquired 810// 811/****************************************************************************************************/ 812 813bool AppleUSBCDCECMControl::dataAcquired(IONetworkStats *netStats, IOEthernetStats *etherStats) 814{ 815 IOReturn rtn = kIOReturnSuccess; 816 817 XTRACE(this, 0, 0, "dataAcquired"); 818 819 // Read the comm interrupt pipe for status (if we have one) 820 821 fCommCompletionInfo.target = this; 822 fCommCompletionInfo.action = commReadComplete; 823 fCommCompletionInfo.parameter = NULL; 824 825 if (fCommPipe) 826 { 827 rtn = fCommPipe->Read(fCommPipeMDP, &fCommCompletionInfo, NULL); 828 } 829 //radar://11946906 830 /* 831 else { 832 if (fDataDriver) 833 { 834 fDataDriver->fLinkStatus = fLinkStatus; 835 } 836 } 837 */ 838 if (rtn == kIOReturnSuccess) 839 { 840 841 // Set up the management Element Request completion routine 842 843 fMERCompletionInfo.target = this; 844 fMERCompletionInfo.action = merWriteComplete; 845 fMERCompletionInfo.parameter = NULL; 846 847 // Set up the statistics request completion routine: 848 849 fStatsCompletionInfo.target = this; 850 fStatsCompletionInfo.action = statsWriteComplete; 851 fStatsCompletionInfo.parameter = NULL; 852 853 } else { 854 XTRACE(this, 0, rtn, "dataAcquired - Reading the interrupt pipe failed"); 855 return false; 856 } 857 858 fpNetStats = netStats; 859 fpEtherStats = etherStats; 860 861 fdataAcquired = true; 862 863 return true; 864 865}/* end dataAcquired */ 866 867/****************************************************************************************************/ 868// 869// Method: AppleUSBCDCECMControl::dataReleased 870// 871// Inputs: None 872// 873// Outputs: None 874// 875// Desc: Tells this driver the data driver's port has been released 876// 877/****************************************************************************************************/ 878 879void AppleUSBCDCECMControl::dataReleased() 880{ 881 882 XTRACE(this, 0, 0, "dataReleased"); 883 884 if (fCommPipe) 885 { 886 fCommPipe->Abort(); 887 } 888 fdataAcquired = false; 889 890}/* end dataReleased */ 891 892/****************************************************************************************************/ 893// 894// Method: AppleUSBCDCECMControl::allocateResources 895// 896// Inputs: 897// 898// Outputs: return code - true (allocate was successful), false (it failed) 899// 900// Desc: Finishes up the rest of the configuration and gets all the endpoints open etc. 901// 902/****************************************************************************************************/ 903 904bool AppleUSBCDCECMControl::allocateResources() 905{ 906 IOUSBFindEndpointRequest epReq; 907 908 XTRACE(this, 0, 0, "allocateResources."); 909 910 // Open the end point and get the buffers 911 912 if (!fControlInterface->open(this)) 913 { 914 ALERT(0, 0, "allocateResources - open comm interface failed."); 915 return false; 916 } 917 // Interrupt pipe 918 919 epReq.type = kUSBInterrupt; 920 epReq.direction = kUSBIn; 921 fCommPipe = fControlInterface->FindNextPipe(0, &epReq); 922 if (!fCommPipe) 923 { 924 XTRACE(this, 0, 0, "allocateResources - no interrupt in pipe."); 925 fCommPipeMDP = NULL; 926 fCommPipeBuffer = NULL; 927 fLinkStatus = 1; // Mark it active cause we'll never get told 928 } else { 929 XTRACE(this, epReq.maxPacketSize << 16 |epReq.interval, 0, "allocateResources - comm pipe."); 930 931 // Allocate Memory Descriptor Pointer with memory for the Interrupt pipe: 932 933 fCommPipeMDP = IOBufferMemoryDescriptor::withCapacity(COMM_BUFF_SIZE, kIODirectionIn); 934 if (!fCommPipeMDP) 935 { 936 XTRACE(this, 0, 0, "allocateResources - Couldn't allocate MDP for interrupt pipe"); 937 return false; 938 } 939 940 fCommPipeBuffer = (UInt8*)fCommPipeMDP->getBytesNoCopy(); 941 XTRACEP(this, 0, fCommPipeBuffer, "allocateResources - comm buffer"); 942 } 943 944 return true; 945 946}/* end allocateResources */ 947 948/****************************************************************************************************/ 949// 950// Method: AppleUSBCDCECMControl::releaseResources 951// 952// Inputs: 953// 954// Outputs: 955// 956// Desc: Frees up the resources allocated in allocateResources 957// 958/****************************************************************************************************/ 959 960void AppleUSBCDCECMControl::releaseResources() 961{ 962 XTRACE(this, 0, 0, "releaseResources"); 963 964 if (fControlInterface) 965 { 966 fControlInterface->close(this); 967 fControlInterface->release(); 968 fControlInterface = NULL; 969 } 970 971 if (fCommPipeMDP) 972 { 973 fCommPipeMDP->release(); 974 fCommPipeMDP = 0; 975 } 976 977}/* end releaseResources */ 978 979/****************************************************************************************************/ 980// 981// Method: AppleUSBCDCECMControl::USBSetMulticastFilter 982// 983// Inputs: addrs - the list of addresses 984// count - How many 985// 986// Outputs: 987// 988// Desc: Set up and send SetMulticastFilter Management Element Request(MER). 989// 990/****************************************************************************************************/ 991 992bool AppleUSBCDCECMControl::USBSetMulticastFilter(IOEthernetAddress *addrs, UInt32 count) 993{ 994 IOReturn rc; 995 IOUSBDevRequest *MER; 996 UInt8 *eaddrs; 997 UInt32 eaddLen; 998 UInt32 i,j,rnum; 999 1000 XTRACE(this, fMcFilters, count, "USBSetMulticastFilter"); 1001 1002 if (!fControlInterface) 1003 { 1004 XTRACE(this, fMcFilters, count, "USBSetMulticastFilter - Control interface has gone"); 1005 return true; 1006 } 1007 1008 if (count > (UInt32)(fMcFilters & kFiltersSupportedMask)) 1009 { 1010 XTRACE(this, 0, 0, "USBSetMulticastFilter - No multicast filters supported"); 1011 return false; 1012 } 1013 1014 MER = (IOUSBDevRequest*)IOMalloc(sizeof(IOUSBDevRequest)); 1015 if (!MER) 1016 { 1017 XTRACE(this, 0, 0, "USBSetMulticastFilter - allocate MER failed"); 1018 return false; 1019 } 1020 bzero(MER, sizeof(IOUSBDevRequest)); 1021 1022 eaddLen = count * kIOEthernetAddressSize; 1023 eaddrs = (UInt8 *)IOMalloc(eaddLen); 1024 if (!eaddrs) 1025 { 1026 XTRACE(this, 0, 0, "USBSetMulticastFilter - allocate address buffer failed"); 1027 return false; 1028 } 1029 bzero(eaddrs, eaddLen); 1030 1031 // Build the filter address buffer 1032 1033 rnum = 0; 1034 for (i=0; i<count; i++) 1035 { 1036 if (rnum > eaddLen) // Just in case 1037 { 1038 break; 1039 } 1040 for (j=0; j<kIOEthernetAddressSize; j++) 1041 { 1042 eaddrs[rnum++] = addrs[i].bytes[j]; 1043 } 1044 } 1045 1046 // Now build the Management Element Request 1047 1048 MER->bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBInterface); 1049 MER->bRequest = kSet_Ethernet_Multicast_Filter; 1050 MER->wValue = count; 1051 MER->wIndex = fCommInterfaceNumber; 1052 MER->wLength = eaddLen; 1053 MER->pData = eaddrs; 1054 1055 fMERCompletionInfo.parameter = MER; 1056 1057 rc = fControlInterface->GetDevice()->DeviceRequest(MER, &fMERCompletionInfo); 1058 if (rc != kIOReturnSuccess) 1059 { 1060 XTRACE(this, MER->bRequest, rc, "USBSetMulticastFilter - Error issueing DeviceRequest"); 1061 IOFree(MER->pData, eaddLen); 1062 IOFree(MER, sizeof(IOUSBDevRequest)); 1063 return false; 1064 } 1065 1066 return true; 1067 1068}/* end USBSetMulticastFilter */ 1069 1070/****************************************************************************************************/ 1071// 1072// Method: AppleUSBCDCECMControl::USBSetPacketFilter 1073// 1074// Inputs: 1075// 1076// Outputs: 1077// 1078// Desc: Set up and send SetEthernetPackettFilters Management Element Request(MER). 1079// 1080/****************************************************************************************************/ 1081 1082bool AppleUSBCDCECMControl::USBSetPacketFilter() 1083{ 1084 IOReturn rc; 1085 IOUSBDevRequest *MER; 1086 1087 XTRACE(this, 0, fPacketFilter, "USBSetPacketFilter"); 1088 1089 if (!fControlInterface) 1090 { 1091 XTRACE(this, 0, fPacketFilter, "USBSetPacketFilter - Control interface has gone"); 1092 return true; 1093 } 1094 1095 MER = (IOUSBDevRequest*)IOMalloc(sizeof(IOUSBDevRequest)); 1096 if (!MER) 1097 { 1098 XTRACE(this, 0, 0, "USBSetPacketFilter - allocate MER failed"); 1099 return false; 1100 } 1101 bzero(MER, sizeof(IOUSBDevRequest)); 1102 1103 // Now build the Management Element Request 1104 1105 MER->bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBInterface); 1106 MER->bRequest = kSet_Ethernet_Packet_Filter; 1107 MER->wValue = fPacketFilter; 1108 MER->wIndex = fCommInterfaceNumber; 1109 MER->wLength = 0; 1110 MER->pData = NULL; 1111 1112 fMERCompletionInfo.parameter = MER; 1113 1114 rc = fControlInterface->GetDevice()->DeviceRequest(MER, &fMERCompletionInfo); 1115 if (rc != kIOReturnSuccess) 1116 { 1117 XTRACE(this, MER->bRequest, rc, "USBSetPacketFilter - DeviceRequest error"); 1118 if (rc == kIOUSBPipeStalled) 1119 { 1120 1121 // Clear the stall and try it once more 1122 1123 fControlInterface->GetDevice()->GetPipeZero()->ClearPipeStall(false); 1124 rc = fControlInterface->GetDevice()->DeviceRequest(MER, &fMERCompletionInfo); 1125 if (rc != kIOReturnSuccess) 1126 { 1127 XTRACE(this, MER->bRequest, rc, "USBSetPacketFilter - DeviceRequest, error a second time"); 1128 IOFree(MER, sizeof(IOUSBDevRequest)); 1129 return false; 1130 } 1131 } 1132 } 1133 1134 return true; 1135 1136}/* end USBSetPacketFilter */ 1137 1138/****************************************************************************************************/ 1139// 1140// Method: AppleUSBCDCECMControl::checkInterfaceNumber 1141// 1142// Inputs: dataDriver - the data driver enquiring 1143// 1144// Outputs: 1145// 1146// Desc: Called by the data driver to ask if this is the correct 1147// control interface driver. 1148// 1149/****************************************************************************************************/ 1150 1151bool AppleUSBCDCECMControl::checkInterfaceNumber(AppleUSBCDCECMData *dataDriver) 1152{ 1153 IOUSBInterface *dataInterface; 1154 1155 XTRACEP(this, 0, dataDriver, "checkInterfaceNumber"); 1156 1157 // First check we have the same provider (Device) 1158 1159 dataInterface = OSDynamicCast(IOUSBInterface, dataDriver->getProvider()); 1160 if (dataInterface == NULL) 1161 { 1162 XTRACE(this, 0, 0, "checkInterfaceNumber - Error getting Data provider"); 1163 return FALSE; 1164 } 1165 1166 XTRACEP(this, dataInterface->GetDevice(), fControlInterface->GetDevice(), "checkInterfaceNumber - Checking device"); 1167 if (dataInterface->GetDevice() == fControlInterface->GetDevice()) 1168 { 1169 1170 // Then check to see if it's the correct data interface number 1171 1172 if (dataDriver->fDataInterfaceNumber == fDataInterfaceNumber) 1173 { 1174 fDataDriver = dataDriver; 1175 return true; 1176 } else { 1177 XTRACE(this, dataDriver->fDataInterfaceNumber, fDataInterfaceNumber, "checkInterfaceNumber - Not correct interface number"); 1178 } 1179 } else { 1180 XTRACE(this, 0, 0, "checkInterfaceNumber - Not correct device"); 1181 } 1182 1183 return false; 1184 1185}/* end checkInterfaceNumber */ 1186 1187/****************************************************************************************************/ 1188// 1189// Method: AppleUSBCDCECMControl::checkPipe 1190// 1191// Inputs: thePipe - the pipe 1192// devReq - true(send CLEAR_FEATURE), false(only if status returns stalled) 1193// 1194// Outputs: 1195// 1196// Desc: Clear a stall on the specified pipe. If ClearPipeStall is issued 1197// all outstanding I/O is returned with kIOUSBTransactionReturned and 1198// a CLEAR_FEATURE Endpoint stall is sent. 1199// 1200/****************************************************************************************************/ 1201 1202IOReturn AppleUSBCDCECMControl::checkPipe(IOUSBPipe *thePipe, bool devReq) 1203{ 1204 IOReturn rtn = kIOReturnSuccess; 1205 1206 XTRACEP(this, 0, thePipe, "checkPipe"); 1207 1208 if (!devReq) 1209 { 1210 rtn = thePipe->GetPipeStatus(); 1211 if (rtn != kIOUSBPipeStalled) 1212 { 1213 XTRACE(this, 0, 0, "checkPipe - Pipe not stalled"); 1214 return rtn; 1215 } 1216 } 1217 1218 rtn = thePipe->ClearPipeStall(true); 1219 if (rtn == kIOReturnSuccess) 1220 { 1221 XTRACE(this, 0, 0, "checkPipe - ClearPipeStall Successful"); 1222 } else { 1223 XTRACE(this, 0, rtn, "checkPipe - ClearPipeStall Failed"); 1224 } 1225 1226 return rtn; 1227 1228}/* end checkPipe */ 1229 1230/****************************************************************************************************/ 1231// 1232// Method: AppleUSBCDCECMControl::statsProcessing 1233// 1234// Inputs: 1235// 1236// Outputs: 1237// 1238// Desc: Handles stats gathering. 1239// 1240/****************************************************************************************************/ 1241 1242bool AppleUSBCDCECMControl::statsProcessing() 1243{ 1244 UInt32 *enetStats; 1245 UInt16 currStat; 1246 IOReturn rc; 1247 IOUSBDevRequest *STREQ; 1248 bool statOk = false; 1249 1250// XTRACE(this, 0, 0, "statsProcessing"); 1251 1252 enetStats = (UInt32 *)&fEthernetStatistics; 1253 if (*enetStats == 0) 1254 { 1255 XTRACE(this, 0, 0, "statsProcessing - No Ethernet statistics defined"); 1256 return false; // and don't bother us again 1257 } 1258 1259 if ((fpNetStats == NULL) || (fpEtherStats == NULL)) // Means we're not ready yet 1260 { 1261 XTRACE(this, 0, 0, "statsProcessing - Not ready"); 1262 return true; 1263 } 1264 1265 if (fReady == false) 1266 { 1267 XTRACE(this, 0, 0, "statsProcessing - Spurious"); 1268 } else { 1269 1270 // Only do it if it's not already in progress 1271 1272 if (!fStatInProgress) 1273 { 1274 1275 // Check if the stat we're currently interested in is supported 1276 1277 currStat = stats[fCurrStat++]; 1278 if (fCurrStat >= numStats) 1279 { 1280 fCurrStat = 0; 1281 } 1282 switch(currStat) 1283 { 1284 case kXMIT_OK_REQ: 1285 if (fEthernetStatistics[0] & kXMIT_OK) 1286 { 1287 statOk = true; 1288 } 1289 break; 1290 case kRCV_OK_REQ: 1291 if (fEthernetStatistics[0] & kRCV_OK) 1292 { 1293 statOk = true; 1294 } 1295 break; 1296 case kXMIT_ERROR_REQ: 1297 if (fEthernetStatistics[0] & kXMIT_ERROR_REQ) 1298 { 1299 statOk = true; 1300 } 1301 break; 1302 case kRCV_ERROR_REQ: 1303 if (fEthernetStatistics[0] & kRCV_ERROR_REQ) 1304 { 1305 statOk = true; 1306 } 1307 break; 1308 case kRCV_CRC_ERROR_REQ: 1309 if (fEthernetStatistics[2] & kRCV_CRC_ERROR) 1310 { 1311 statOk = true; 1312 } 1313 break; 1314 case kRCV_ERROR_ALIGNMENT_REQ: 1315 if (fEthernetStatistics[2] & kRCV_ERROR_ALIGNMENT) 1316 { 1317 statOk = true; 1318 } 1319 break; 1320 case kXMIT_ONE_COLLISION_REQ: 1321 if (fEthernetStatistics[2] & kXMIT_ONE_COLLISION) 1322 { 1323 statOk = true; 1324 } 1325 break; 1326 case kXMIT_MORE_COLLISIONS_REQ: 1327 if (fEthernetStatistics[2] & kXMIT_MORE_COLLISIONS) 1328 { 1329 statOk = true; 1330 } 1331 break; 1332 case kXMIT_DEFERRED_REQ: 1333 if (fEthernetStatistics[2] & kXMIT_DEFERRED) 1334 { 1335 statOk = true; 1336 } 1337 break; 1338 case kXMIT_MAX_COLLISION_REQ: 1339 if (fEthernetStatistics[2] & kXMIT_MAX_COLLISION) 1340 { 1341 statOk = true; 1342 } 1343 break; 1344 case kRCV_OVERRUN_REQ: 1345 if (fEthernetStatistics[3] & kRCV_OVERRUN) 1346 { 1347 statOk = true; 1348 } 1349 break; 1350 case kXMIT_TIMES_CARRIER_LOST_REQ: 1351 if (fEthernetStatistics[3] & kXMIT_TIMES_CARRIER_LOST) 1352 { 1353 statOk = true; 1354 } 1355 break; 1356 case kXMIT_LATE_COLLISIONS_REQ: 1357 if (fEthernetStatistics[3] & kXMIT_LATE_COLLISIONS) 1358 { 1359 statOk = true; 1360 } 1361 break; 1362 default: 1363 break; 1364 } 1365 } 1366 1367 if (statOk) 1368 { 1369 STREQ = (IOUSBDevRequest*)IOMalloc(sizeof(IOUSBDevRequest)); 1370 if (!STREQ) 1371 { 1372 XTRACE(this, 0, 0, "statsProcessing - allocate STREQ failed"); 1373 } else { 1374 bzero(STREQ, sizeof(IOUSBDevRequest)); 1375 1376 // Now build the Statistics Request 1377 1378 STREQ->bmRequestType = USBmakebmRequestType(kUSBOut, kUSBClass, kUSBInterface); 1379 STREQ->bRequest = kGet_Ethernet_Statistics; 1380 STREQ->wValue = currStat; 1381 STREQ->wIndex = fCommInterfaceNumber; 1382 STREQ->wLength = 4; 1383 STREQ->pData = &fStatValue; 1384 1385 fStatsCompletionInfo.parameter = STREQ; 1386 1387 rc = fControlInterface->GetDevice()->DeviceRequest(STREQ, &fStatsCompletionInfo); 1388 if (rc != kIOReturnSuccess) 1389 { 1390 XTRACE(this, STREQ->bRequest, rc, "statsProcessing - Error issueing DeviceRequest"); 1391 IOFree(STREQ, sizeof(IOUSBDevRequest)); 1392 } else { 1393 fStatInProgress = true; 1394 } 1395 } 1396 } 1397 } 1398 1399 return true; 1400 1401}/* end statsProcessing */ 1402 1403/****************************************************************************************************/ 1404// 1405// Method: AppleUSBCDCECMControl::message 1406// 1407// Inputs: type - message type 1408// provider - my provider 1409// argument - additional parameters 1410// 1411// Outputs: return Code - kIOReturnSuccess 1412// 1413// Desc: Handles IOKit messages. 1414// 1415/****************************************************************************************************/ 1416 1417IOReturn AppleUSBCDCECMControl::message(UInt32 type, IOService *provider, void *argument) 1418{ 1419 IOReturn ior; 1420 1421 XTRACE(this, 0, type, "message"); 1422 1423 switch (type) 1424 { 1425 case kIOMessageServiceIsTerminated: 1426 XTRACE(this, 0, type, "message - kIOMessageServiceIsTerminated"); 1427 if (fDataDriver) 1428 { 1429 fDataDriver->message(kIOMessageServiceIsTerminated, fControlInterface, NULL); 1430 } 1431 fTerminate = true; // we're being terminated (unplugged) 1432 releaseResources(); 1433 return kIOReturnSuccess; 1434 case kIOMessageServiceIsSuspended: 1435 XTRACE(this, 0, type, "message - kIOMessageServiceIsSuspended"); 1436 break; 1437 case kIOMessageServiceIsResumed: 1438 XTRACE(this, 0, type, "message - kIOMessageServiceIsResumed"); 1439 break; 1440 case kIOMessageServiceIsRequestingClose: 1441 XTRACE(this, 0, type, "message - kIOMessageServiceIsRequestingClose"); 1442 break; 1443 case kIOMessageServiceWasClosed: 1444 XTRACE(this, 0, type, "message - kIOMessageServiceWasClosed"); 1445 break; 1446 case kIOMessageServiceBusyStateChange: 1447 XTRACE(this, 0, type, "message - kIOMessageServiceBusyStateChange"); 1448 break; 1449 case kIOUSBMessagePortHasBeenResumed: 1450 XTRACE(this, 0, type, "message - kIOUSBMessagePortHasBeenResumed"); 1451 if (fCommDead) // If it's dead try and resurrect it 1452 { 1453 ior = fCommPipe->Read(fCommPipeMDP, &fCommCompletionInfo, NULL); 1454 if (ior != kIOReturnSuccess) 1455 { 1456 XTRACE(this, 0, ior, "message - Read io error"); 1457 } else { 1458 fCommDead = false; 1459 } 1460 } 1461 return kIOReturnSuccess; 1462 case kIOUSBMessageHubResumePort: 1463 XTRACE(this, 0, type, "message - kIOUSBMessageHubResumePort"); 1464 break; 1465 default: 1466 XTRACE(this, 0, type, "message - unknown message"); 1467 break; 1468 } 1469 1470 return super::message(type, provider, argument); 1471 1472}/* end message */ 1473 1474#if 0 1475/****************************************************************************************************/ 1476// 1477// Method: AppleUSBCDCECMControl::initForPM 1478// 1479// Inputs: provider - my provider 1480// 1481// Outputs: return code - true(initialized), false(failed) 1482// 1483// Desc: Add ourselves to the power management tree so we can do 1484// the right thing on sleep/wakeup. 1485// 1486/****************************************************************************************************/ 1487 1488bool AppleUSBCDCECMControl::initForPM(IOService *provider) 1489{ 1490 XTRACE(this, 0, 0, "initForPM"); 1491 1492 fPowerState = kCDCPowerOnState; // init our power state to be 'on' 1493 PMinit(); // init power manager instance variables 1494 provider->joinPMtree(this); // add us to the power management tree 1495 if (pm_vars != NULL) 1496 { 1497 1498 // register ourselves with ourself as policy-maker 1499 1500 registerPowerDriver(this, gOurPowerStates, kNumCDCStates); 1501 return true; 1502 } else { 1503 ALERT(0, 0, "initForPM - Initializing power manager failed"); 1504 } 1505 1506 return false; 1507 1508}/* end initForPM */ 1509 1510/****************************************************************************************************/ 1511// 1512// Method: AppleUSBCDCECMControl::initialPowerStateForDomainState 1513// 1514// Inputs: flags - 1515// 1516// Outputs: return code - Current power state 1517// 1518// Desc: Request for our initial power state. 1519// 1520/****************************************************************************************************/ 1521 1522unsigned long AppleUSBCDCECMControl::initialPowerStateForDomainState(IOPMPowerFlags flags) 1523{ 1524 1525 XTRACE(this, 0, flags, "initialPowerStateForDomainState"); 1526 1527 return fPowerState; 1528 1529}/* end initialPowerStateForDomainState */ 1530 1531/****************************************************************************************************/ 1532// 1533// Method: AppleUSBCDCECMControl::setPowerState 1534// 1535// Inputs: powerStateOrdinal - on/off 1536// 1537// Outputs: return code - IOPMNoErr, IOPMAckImplied or IOPMNoSuchState 1538// 1539// Desc: Request to turn device on or off. 1540// 1541/****************************************************************************************************/ 1542 1543IOReturn AppleUSBCDCECMControl::setPowerState(unsigned long powerStateOrdinal, IOService *whatDevice) 1544{ 1545 1546 XTRACE(this, 0, powerStateOrdinal, "setPowerState"); 1547 1548 if (powerStateOrdinal == kCDCPowerOffState || powerStateOrdinal == kCDCPowerOnState) 1549 { 1550 if (powerStateOrdinal == fPowerState) 1551 return IOPMAckImplied; 1552 1553 fPowerState = powerStateOrdinal; 1554 if (fPowerState == kCDCPowerOnState) 1555 { 1556 if (fDataDriver) 1557 { 1558 fDataDriver->fResetState = kResetNeeded; 1559 fDataDriver->fReady = FALSE; 1560 } 1561 } 1562 1563 return IOPMAckImplied; 1564 } 1565 1566 return IOPMAckImplied; 1567 1568}/* end setPowerState */ 1569#endif