1/* 2 * Copyright (c) 1998-2002 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/* 24 * 25 * IOFWAddressSpace.cpp 26 * 27 * Classes which describe addresses in the local node which are accessable to other nodes 28 * via firewire asynchronous read/write/lock requests. 29 * 30 * HISTORY 31 * 32 */ 33 34#include <IOKit/firewire/IOFWAddressSpace.h> 35#include <IOKit/firewire/IOFireWireController.h> 36#include <IOKit/firewire/IOFireWireDevice.h> 37 38#include "FWDebugging.h" 39 40OSDefineMetaClassAndStructors(IOFWAddressSpaceAux, OSObject); 41 42OSMetaClassDefineReservedUsed(IOFWAddressSpaceAux, 0); // intersects 43OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 1); 44OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 2); 45OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 3); 46OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 4); 47OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 5); 48OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 6); 49OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 7); 50OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 8); 51OSMetaClassDefineReservedUnused(IOFWAddressSpaceAux, 9); 52 53#pragma mark - 54 55// init 56// 57// 58 59bool IOFWAddressSpaceAux::init( IOFWAddressSpace * primary ) 60{ 61 bool success = true; // assume success 62 63 // init super 64 65 if( !OSObject::init() ) 66 success = false; 67 68 fExclusive = false; 69 70 if( success ) 71 { 72 fPrimary = primary; 73 fControl = fPrimary->fControl; 74 75 // 76 // create node set 77 // 78 79 fTrustedNodeSet = OSSet::withCapacity(1); 80 if( fTrustedNodeSet == NULL ) 81 success = false; 82 } 83 84 if( success ) 85 { 86 fTrustedNodeSetIterator = OSCollectionIterator::withCollection( fTrustedNodeSet ); 87 if( fTrustedNodeSetIterator == NULL ) 88 success = false; 89 } 90 91 if( !success ) 92 { 93 if( fTrustedNodeSet != NULL ) 94 { 95 fTrustedNodeSet->release(); 96 fTrustedNodeSet = NULL; 97 } 98 99 if( fTrustedNodeSetIterator != NULL ) 100 { 101 fTrustedNodeSetIterator->release(); 102 fTrustedNodeSetIterator = NULL; 103 } 104 } 105 106 return success; 107} 108 109// free 110// 111// 112 113void IOFWAddressSpaceAux::free() 114{ 115 if( fTrustedNodeSet != NULL ) 116 { 117 fTrustedNodeSet->release(); 118 fTrustedNodeSet = NULL; 119 } 120 121 if( fTrustedNodeSetIterator != NULL ) 122 { 123 fTrustedNodeSetIterator->release(); 124 fTrustedNodeSetIterator = NULL; 125 } 126 127 OSObject::free(); 128} 129 130// isTrustedNode 131// 132// 133 134bool IOFWAddressSpaceAux::isTrustedNode( UInt16 nodeID ) 135{ 136 bool trusted = false; 137 138#if 1 139 // 140 // trusted if not in secure mode 141 // 142 143 if( fControl->getSecurityMode() == kIOFWSecurityModeNormal ) 144 trusted = true; 145#endif 146 147 // 148 // trusted if the local node 149 // trusted if no nodes in set (no source node ID verification) 150 // 151 152 if( !trusted ) 153 { 154 UInt16 localNodeID = fControl->getLocalNodeID(); 155 156// FWKLOG(( "IOFWAddressSpaceAux::isTrustedNode - localNodeID = 0x%x\n", localNodeID )); 157 158 if( nodeID == localNodeID || fTrustedNodeSet->getCount() == 0 ) 159 trusted = true; 160 } 161 162 // 163 // check node id of all devices in set 164 // 165 166 IOFireWireDevice * item = NULL; 167 fTrustedNodeSetIterator->reset(); 168 while( !trusted && (item = (IOFireWireDevice *) fTrustedNodeSetIterator->getNextObject()) ) 169 { 170 UInt32 generation = 0; 171 UInt16 deviceNodeID = 0; 172 173 item->getNodeIDGeneration( generation, deviceNodeID ); 174 175 // FWKLOG(( "IOFWAddressSpaceAux::isTrustedNode - deviceNodeID = 0x%x\n", deviceNodeID )); 176 177 if( deviceNodeID == nodeID ) 178 trusted = true; 179 } 180 181// FWKLOG(( "IOFWAddressSpaceAux::isTrustedNode - nodeID = 0x%x, trusted = %d\n", nodeID, trusted )); 182 183 return trusted; 184} 185 186// addTrustedNode 187// 188// 189 190void IOFWAddressSpaceAux::addTrustedNode( IOFireWireDevice * device ) 191{ 192 fTrustedNodeSet->setObject( device ); 193} 194 195// removeTrustedNode 196// 197// 198 199void IOFWAddressSpaceAux::removeTrustedNode( IOFireWireDevice * device ) 200{ 201 fTrustedNodeSet->removeObject( device ); 202} 203 204// removeAllTrustedNodes 205// 206// 207 208void IOFWAddressSpaceAux::removeAllTrustedNodes( void ) 209{ 210 fTrustedNodeSet->flushCollection(); 211} 212 213// isExclusive 214// 215// 216 217bool IOFWAddressSpaceAux::isExclusive( void ) 218{ 219 return fExclusive; 220} 221 222// setExclusive 223// 224// 225 226void IOFWAddressSpaceAux::setExclusive( bool exclusive ) 227{ 228 fExclusive = exclusive; 229} 230 231// intersects 232// 233// 234 235bool IOFWAddressSpaceAux::intersects( IOFWAddressSpace * space ) 236{ 237 return false; 238} 239 240#pragma mark - 241 242/* 243 * Base class for FireWire address space objects 244 */ 245 246OSDefineMetaClass( IOFWAddressSpace, OSObject ) 247OSDefineAbstractStructors(IOFWAddressSpace, OSObject) 248 249//OSMetaClassDefineReservedUnused(IOFWAddressSpace, 0); 250//OSMetaClassDefineReservedUnused(IOFWAddressSpace, 1); 251 252// init 253// 254// 255 256bool IOFWAddressSpace::init(IOFireWireBus *bus) 257{ 258 bool success = true; // assume success 259 260 // init super 261 262 if( !OSObject::init() ) 263 success = false; 264 265 // get controller 266 267 if( success ) 268 { 269 fControl = OSDynamicCast(IOFireWireController, bus); 270 if( fControl == NULL ) 271 success = false; 272 } 273 274 // create expansion data 275 276 if( success ) 277 { 278 fIOFWAddressSpaceExpansion = (ExpansionData*) IOMalloc( sizeof(ExpansionData) ); 279 if( fIOFWAddressSpaceExpansion == NULL ) 280 success = false; 281 } 282 283 // zero expansion data 284 285 if( success ) 286 { 287 bzero( fIOFWAddressSpaceExpansion, sizeof(ExpansionData) ); 288 fIOFWAddressSpaceExpansion->fAuxiliary = createAuxiliary(); 289 if( fIOFWAddressSpaceExpansion->fAuxiliary == NULL ) 290 success = false; 291 } 292 293 // clean up on failure 294 295 if( !success ) 296 { 297 if( fIOFWAddressSpaceExpansion->fAuxiliary != NULL ) 298 { 299 fIOFWAddressSpaceExpansion->fAuxiliary->release(); 300 fIOFWAddressSpaceExpansion->fAuxiliary = NULL; 301 } 302 303 if( fIOFWAddressSpaceExpansion != NULL ) 304 { 305 IOFree ( fIOFWAddressSpaceExpansion, sizeof(ExpansionData) ); 306 fIOFWAddressSpaceExpansion = NULL; 307 } 308 } 309 310 return success; 311} 312 313// createAuxiliary 314// 315// virtual method for creating auxiliary object. subclasses needing to subclass 316// the auxiliary object can override this. 317 318IOFWAddressSpaceAux * IOFWAddressSpace::createAuxiliary( void ) 319{ 320 IOFWAddressSpaceAux * auxiliary; 321 322 auxiliary = OSTypeAlloc( IOFWAddressSpaceAux ); 323 324 if( auxiliary != NULL && !auxiliary->init(this) ) 325 { 326 auxiliary->release(); 327 auxiliary = NULL; 328 } 329 330 return auxiliary; 331} 332 333// free 334// 335// 336 337void IOFWAddressSpace::free() 338{ 339 if( fIOFWAddressSpaceExpansion != NULL ) 340 { 341 // release auxiliary object 342 343 if( fIOFWAddressSpaceExpansion->fAuxiliary != NULL ) 344 { 345 fIOFWAddressSpaceExpansion->fAuxiliary->release(); 346 fIOFWAddressSpaceExpansion->fAuxiliary = NULL; 347 } 348 349 // free expansion data 350 351 IOFree ( fIOFWAddressSpaceExpansion, sizeof(ExpansionData) ); 352 fIOFWAddressSpaceExpansion = NULL; 353 } 354 355 OSObject::free(); 356} 357 358// doLock 359// 360// 361 362UInt32 IOFWAddressSpace::doLock(UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 inLen, 363 const UInt32 *newVal, UInt32 &outLen, UInt32 *oldVal, UInt32 type, 364 IOFWRequestRefCon refcon) 365{ 366 UInt32 ret = kFWResponseAddressError; 367 bool ok; 368 int size; 369 int i; 370 IOMemoryDescriptor *desc = NULL; 371 IOByteCount offset; 372 373 size = inLen/8; // Depends on type, right for 'compare and swap' 374 outLen = inLen/2; // right for 'compare and swap' 375 376 ret = doRead(nodeID, speed, addr, size*4, &desc, &offset, refcon); 377 if(ret != kFWResponseComplete) 378 return ret; 379 380 desc->readBytes(offset, oldVal, size*4); 381 382 switch (type) 383 { 384 case kFWExtendedTCodeCompareSwap: 385 ok = true; 386 for(i=0; i<size; i++) 387 ok = ok && oldVal[i] == newVal[i]; 388 if(ok) 389 ret = doWrite(nodeID, speed, addr, size*4, newVal+size, refcon); 390 break; 391 392 default: 393 ret = kFWResponseTypeError; 394 } 395 return ret; 396} 397 398// activate 399// 400// 401 402IOReturn IOFWAddressSpace::activate() 403{ 404 return fControl->allocAddress(this); 405} 406 407// deactivate 408// 409// 410 411void IOFWAddressSpace::deactivate() 412{ 413 fControl->freeAddress(this); 414} 415 416// contains 417// 418// 419 420UInt32 IOFWAddressSpace::contains(FWAddress addr) 421{ 422 return 0; 423} 424