1/* 2 File: AppleSCSIEmulatorAdapterUC.cpp 3 4 Contains: 5 6 Version: 1.0.0 7 8 Copyright: Copyright (c) 2007 by Apple Inc., All Rights Reserved. 9 10Disclaimer:IMPORTANT: This Apple software is supplied to you by Apple Inc. 11("Apple") in consideration of your agreement to the following terms, and your use, 12installation, modification or redistribution of this Apple software constitutes acceptance 13of these terms. If you do not agree with these terms, please do not use, install, modify or 14redistribute this Apple software. 15 16In consideration of your agreement to abide by the following terms, and subject 17to these terms, Apple grants you a personal, non-exclusive license, under Apple's 18copyrights in this original Apple software (the "Apple Software"), to use, reproduce, 19modify and redistribute the Apple Software, with or without modifications, in source and/or 20binary forms; provided that if you redistribute the Apple Software in its entirety 21and without modifications, you must retain this notice and the following text 22and disclaimers in all such redistributions of the Apple Software. Neither the 23name, trademarks, service marks or logos of Apple Inc. may be used to 24endorse or promote products derived from the Apple Software without specific prior 25written permission from Apple. Except as expressly stated in this notice, no 26other rights or licenses, express or implied, are granted by Apple herein, 27including but not limited to any patent rights that may be infringed by your derivative 28works or by other works in which the Apple Software may be incorporated. 29 30The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES, 31EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, 32MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE 33OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. IN NO EVENT SHALL APPLE 34BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 35NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 36OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, 37REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 38AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT 39LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40*/ 41 42 43//----------------------------------------------------------------------------- 44// Includes 45//----------------------------------------------------------------------------- 46 47#include "AppleSCSIEmulatorAdapterUC.h" 48#include "AppleSCSIEmulatorAdapter.h" 49 50 51//----------------------------------------------------------------------------- 52// Macros 53//----------------------------------------------------------------------------- 54 55#define DEBUG 1 56#define DEBUG_ASSERT_COMPONENT_NAME_STRING "AdapterUC" 57 58#if DEBUG 59#define ADAPTER_UC_DEBUGGING_LEVEL 3 60#endif 61 62#include "DebugSupport.h" 63 64#if ( ADAPTER_UC_DEBUGGING_LEVEL >= 1 ) 65#define PANIC_NOW(x) panic x 66#else 67#define PANIC_NOW(x) 68#endif 69 70#if ( ADAPTER_UC_DEBUGGING_LEVEL >= 2 ) 71#define ERROR_LOG(x) IOLog x; IOSleep(1) 72#else 73#define ERROR_LOG(x) 74#endif 75 76#if ( ADAPTER_UC_DEBUGGING_LEVEL >= 3 ) 77#define STATUS_LOG(x) IOLog x; IOSleep(1) 78#else 79#define STATUS_LOG(x) 80#endif 81 82 83// Define superclass 84#define super IOUserClient 85OSDefineMetaClassAndStructors ( AppleSCSIEmulatorAdapterUserClient, IOUserClient ); 86 87 88#if 0 89#pragma mark - 90#pragma mark Public Methods 91#pragma mark - 92#endif 93 94 95//----------------------------------------------------------------------------- 96// initWithTask - Save task_t and validate the connection type [PUBLIC] 97//----------------------------------------------------------------------------- 98 99bool 100AppleSCSIEmulatorAdapterUserClient::initWithTask ( 101 task_t owningTask, 102 void * securityToken, 103 UInt32 type, 104 OSDictionary * properties ) 105{ 106 107 bool result = false; 108 109 STATUS_LOG ( ( "AppleSCSIEmulatorAdapterUserClient::initWithTask called\n" ) ); 110 111 result = super::initWithTask ( owningTask, securityToken, type, properties ); 112 require ( result, ErrorExit ); 113 114 fTask = owningTask; 115 result = true; 116 117 118ErrorExit: 119 120 121 return result; 122 123} 124 125 126//----------------------------------------------------------------------------- 127// start - Start providing services [PUBLIC] 128//----------------------------------------------------------------------------- 129 130bool 131AppleSCSIEmulatorAdapterUserClient::start ( IOService * provider ) 132{ 133 134 bool result = false; 135 IOWorkLoop * workLoop = NULL; 136 137 STATUS_LOG ( ( "AppleSCSIEmulatorAdapterUserClient::start\n" ) ); 138 139 require ( ( fProvider == 0 ), ErrorExit ); 140 require ( super::start ( provider ), ErrorExit ); 141 142 // Save the provider 143 fProvider = provider; 144 145 STATUS_LOG ( ( "Creating command gate\n" ) ); 146 147 fCommandGate = IOCommandGate::commandGate ( this ); 148 require_nonzero ( fCommandGate, ErrorExit ); 149 150 workLoop = getWorkLoop ( ); 151 require_nonzero_action ( workLoop, 152 ErrorExit, 153 fCommandGate->release ( ) ); 154 155 STATUS_LOG ( ( "Adding event source\n" ) ); 156 157 workLoop->addEventSource ( fCommandGate ); 158 159 STATUS_LOG ( ( "Opening provider\n" ) ); 160 161 result = provider->open ( this, kSCSIEmulatorAdapterUserClientAccessMask, 0 ); 162 require_action ( result, 163 ErrorExit, 164 workLoop->removeEventSource ( fCommandGate ); 165 fCommandGate->release ( ); 166 fCommandGate = NULL ); 167 168 fWorkLoop = workLoop; 169 170 171ErrorExit: 172 173 174 return result; 175 176} 177 178 179//----------------------------------------------------------------------------- 180// clientClose - Called to when a client closes/dies [PUBLIC] 181//----------------------------------------------------------------------------- 182 183IOReturn 184AppleSCSIEmulatorAdapterUserClient::clientClose ( void ) 185{ 186 187 if ( fProvider != NULL ) 188 { 189 190 if ( fProvider->isOpen ( this ) == true ) 191 { 192 193 fProvider->close ( this, kSCSIEmulatorAdapterUserClientAccessMask ); 194 195 } 196 197 detach ( fProvider ); 198 fProvider = NULL; 199 200 } 201 202 return super::clientClose ( ); 203 204} 205 206 207//----------------------------------------------------------------------------- 208// finalize - Called to finalize resources [PUBLIC] 209//----------------------------------------------------------------------------- 210 211bool 212AppleSCSIEmulatorAdapterUserClient::finalize ( IOOptionBits options ) 213{ 214 215 clientClose ( ); 216 return super::finalize ( options ); 217 218} 219 220 221//----------------------------------------------------------------------------- 222// free - Releases any items we need to release. [PUBLIC] 223//----------------------------------------------------------------------------- 224 225void 226AppleSCSIEmulatorAdapterUserClient::free ( void ) 227{ 228 229 // Remove the command gate from the workloop 230 if ( fWorkLoop != NULL ) 231 { 232 233 fWorkLoop->removeEventSource ( fCommandGate ); 234 fWorkLoop = NULL; 235 236 } 237 238 // Release the command gate 239 if ( fCommandGate != NULL ) 240 { 241 242 fCommandGate->release ( ); 243 fCommandGate = NULL; 244 245 } 246 247 super::free ( ); 248 249} 250 251 252//----------------------------------------------------------------------------- 253// externalMethod - Main dispatcher. [PUBLIC] 254//----------------------------------------------------------------------------- 255 256IOReturn 257AppleSCSIEmulatorAdapterUserClient::externalMethod ( 258 uint32_t selector, 259 IOExternalMethodArguments * args, 260 IOExternalMethodDispatch * dispatch, 261 OSObject * target, 262 void * reference ) 263{ 264 265 IOReturn status = kIOReturnBadArgument; 266 267 // We only have synchronous requests. If the asyncWakePort is a port, 268 // this is an async request and we should reject it. 269 require ( ( args->asyncWakePort == MACH_PORT_NULL ), ErrorExit ); 270 require ( ( selector < kUserClientMethodCount ), ErrorExit ); 271 272 if ( selector == kUserClientCreateLUN ) 273 { 274 275 require ( ( args->structureInputSize == sizeof ( EmulatorTargetParamsStruct ) ), ErrorExit ); 276 require ( ( args->structureOutputSize == 0 ), ErrorExit ); 277 278 STATUS_LOG ( ( "args->structureInputSize = %u\n", args->structureInputSize ) ); 279 280 status = ( ( AppleSCSIEmulatorAdapter * ) fProvider )->CreateLUN ( ( EmulatorTargetParamsStruct * ) args->structureInput, fTask ); 281 282 } 283 284 else if ( selector == kUserClientDestroyLUN ) 285 { 286 287 require ( ( args->scalarInputCount == 2 ), ErrorExit ); 288 require ( ( args->scalarOutputCount == 0 ), ErrorExit ); 289 290 STATUS_LOG ( ( "args->scalarInputCount = %u\n", args->scalarInputCount ) ); 291 STATUS_LOG ( ( "args->scalarInput[0] = %qd, args->scalarInput[1] = %qd\n", args->scalarInput[0], args->scalarInput[1] ) ); 292 293 status = ( ( AppleSCSIEmulatorAdapter * ) fProvider )->DestroyLUN ( args->scalarInput[0], args->scalarInput[1] ); 294 295 } 296 297 else if ( selector == kUserClientDestroyTarget ) 298 { 299 300 require ( ( args->scalarInputCount == 1 ), ErrorExit ); 301 require ( ( args->scalarOutputCount == 0 ), ErrorExit ); 302 303 STATUS_LOG ( ( "args->scalarInputCount = %u\n", args->scalarInputCount ) ); 304 STATUS_LOG ( ( "args->scalarInput[0] = %qd\n", args->scalarInput[0] ) ); 305 306 status = ( ( AppleSCSIEmulatorAdapter * ) fProvider )->DestroyTarget ( args->scalarInput[0] ); 307 308 } 309 310 311ErrorExit: 312 313 314 STATUS_LOG ( ( "externalMethod status = 0x%08x\n", status ) ); 315 316 return status; 317 318}