1/* 2cc AppleSamplePCIClient.c -o /tmp/sampleclient -framework IOKit -framework CoreFoundation -Wno-four-char-constants -Wall -g -arch ppc -arch i386 -arch ppc64 -arch x86_64 3*/ 4 5#include <assert.h> 6#include <stdlib.h> 7#include <string.h> 8#include <stdio.h> 9#include <unistd.h> 10#include <pthread.h> 11#include <inttypes.h> 12#include <IOKit/IOKitLib.h> 13 14#include "AppleSamplePCIShared.h" 15 16void Test( mach_port_t masterPort, io_service_t service ); 17void TestSharedMemory( io_connect_t connect ); 18 19 20int main( int argc, char * argv[] ) 21{ 22 mach_port_t masterPort; 23 io_iterator_t iter; 24 io_service_t service; 25 kern_return_t kr; 26 CFMutableDictionaryRef properties; 27 CFStringRef cfStr; 28 29 kr = IOMasterPort( MACH_PORT_NULL, &masterPort); 30 assert( KERN_SUCCESS == kr ); 31 32 // Look up the object we wish to open. This example uses simple class 33 // matching (IOServiceMatching()) to look up the object that is the 34 // AppleSamplePCI driver class instantiated by the kext. 35 36 kr = IOServiceGetMatchingServices( masterPort, 37 IOServiceMatching( kAppleSamplePCIClassName ), &iter); 38 assert( KERN_SUCCESS == kr ); 39 40 for( ; 41 (service = IOIteratorNext(iter)); 42 IOObjectRelease(service)) { 43 44 io_string_t path; 45 kr = IORegistryEntryGetPath(service, kIOServicePlane, path); 46 assert( KERN_SUCCESS == kr ); 47 printf("Found a device of class "kAppleSamplePCIClassName": %s\n", path); 48 49 // print the value of kIONameMatchedKey property, as an example of 50 // getting properties from the registry. Property based access 51 // doesn't require a user client connection. 52 53 // grab a copy of the properties 54 kr = IORegistryEntryCreateCFProperties( service, &properties, 55 kCFAllocatorDefault, kNilOptions ); 56 assert( KERN_SUCCESS == kr ); 57 58 cfStr = CFDictionaryGetValue( properties, CFSTR(kIONameMatchedKey) ); 59 if( cfStr) { 60 const char * c = NULL; 61 char * buffer = NULL; 62 c = CFStringGetCStringPtr(cfStr, kCFStringEncodingMacRoman); 63 if(!c) { 64 CFIndex bufferSize = CFStringGetLength(cfStr) + 1; 65 buffer = malloc(bufferSize); 66 if(buffer) { 67 if(CFStringGetCString(cfStr, buffer, bufferSize, kCFStringEncodingMacRoman)) 68 c = buffer; 69 } 70 } 71 if(c) 72 printf("it matched on name \"%s\"\n", c); 73 if(buffer) 74 free(buffer); 75 } 76 CFRelease( properties ); 77 78 // test out the user client 79 Test( masterPort, service ); 80 } 81 IOObjectRelease(iter); 82 83 exit(0); 84 return(0); 85} 86 87#define arrayCnt(var) (sizeof(var) / sizeof(var[0])) 88 89void Test( mach_port_t masterPort, io_service_t service ) 90{ 91 kern_return_t kr; 92 io_connect_t connect; 93 size_t structureOutputSize; 94 AppleSampleStructForMethod2 method2Param; 95 AppleSampleResultsForMethod2 method2Results; 96 uint32_t varStructParam[3] = { 1, 2, 3 }; 97 IOByteCount bigBufferLen; 98 uint32_t * bigBuffer; 99 100 kr = IOServiceOpen( service, mach_task_self(), kAppleSamplePCIConnectType, &connect ); 101 assert( KERN_SUCCESS == kr ); 102 103 // test a simple struct in/out method 104 structureOutputSize = sizeof(varStructParam); 105 106 107#if MAC_OS_X_VERSION_10_5 108 kr = IOConnectCallStructMethod( connect, kAppleSampleMethod1, 109 // inputStructure 110 &varStructParam, sizeof(varStructParam), 111 // ouputStructure 112 &varStructParam, &structureOutputSize ); 113#else 114 kr = IOConnectMethodStructureIStructureO( connect, kAppleSampleMethod1, 115 sizeof(varStructParam), /* structureInputSize */ 116 &structureOutputSize, /* structureOutputSize */ 117 &varStructParam, /* inputStructure */ 118 &varStructParam); /* ouputStructure */ 119#endif 120 121 assert( KERN_SUCCESS == kr ); 122 printf("kAppleSampleMethod1 results 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "\n", 123 varStructParam[0], varStructParam[1], varStructParam[2]); 124 125 // test shared memory 126 TestSharedMemory( connect ); 127 128 // test method with out of line memory 129 bigBufferLen = 0x4321; 130 bigBuffer = malloc( bigBufferLen ); 131 132 strcpy( (char *) (bigBuffer + (32 / 4)), "some out of line data"); 133 134 method2Param.parameter1 = 0x12345678; 135 method2Param.data_pointer = (uintptr_t) bigBuffer; 136 method2Param.data_length = bigBufferLen; 137 138 structureOutputSize = sizeof(method2Results); 139#if MAC_OS_X_VERSION_10_5 140 kr = IOConnectCallStructMethod( connect, kAppleSampleMethod2, 141 // inputStructure 142 &method2Param, sizeof(method2Param), 143 // ouputStructure 144 &method2Results, &structureOutputSize ); 145#else 146 kr = IOConnectMethodStructureIStructureO( connect, kAppleSampleMethod2, 147 sizeof(method2Param), /* structureInputSize */ 148 &structureOutputSize, /* structureOutputSize */ 149 &method2Param, /* inputStructure */ 150 &method2Results); /* ouputStructure */ 151#endif 152 153 assert( KERN_SUCCESS == kr ); 154 printf("kAppleSampleMethod2 result 0x%" PRIx64 "\n", method2Results.results1); 155 156 free( bigBuffer ); 157 158} 159 160void TestSharedMemory( io_connect_t connect ) 161{ 162 kern_return_t kr; 163 AppleSampleSharedMemory * shared; 164 165#if __LP64__ 166 mach_vm_address_t addr; 167 mach_vm_size_t size; 168#else 169 vm_address_t addr; 170 vm_size_t size; 171#endif 172 173 kr = IOConnectMapMemory( connect, kAppleSamplePCIMemoryType1, 174 mach_task_self(), &addr, &size, 175 kIOMapAnywhere | kIOMapDefaultCache ); 176 assert( KERN_SUCCESS == kr ); 177 assert( size == sizeof( AppleSampleSharedMemory )); 178 179 shared = (AppleSampleSharedMemory *) addr; 180 181 printf("From AppleSampleSharedMemory: %08" PRIx32 ", %08" PRIx32 ", %08" PRIx32 ", \"%s\"\n", 182 shared->field1, shared->field2, shared->field3, shared->string); 183 184 strcpy( shared->string, "some other data" ); 185} 186 187 188 189