1/* 2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 cc -fno-rtti -fno-exceptions -fcheck-new -fvtable-thunks -arch ppc -lIOKit FireWireTest.cpp -o FireWireTest 25 26 cc -fno-rtti -fno-exceptions -fcheck-new -fvtable-thunks -I.. -I../../BUILD/obj/EXPORT_HDRS/libkern -I../../BUILD/obj/EXPORT_HDRS/osfmk FireWireTest.cpp ../../BUILD/obj/RELEASE_PPC/iokit/User/libIOKit.A.dylib -o FireWireTest 27 28*/ 29 30extern "C" { 31#include <mach/message.h> 32} 33 34#include <IOKit/IOLib.h> 35#include <IOKit/IOKitLib.h> 36#include <IOKit/IOContainers.h> 37#include <IOKit/IOSerialize.h> 38 39extern "C" { 40#include "../../BUILD/obj/RELEASE_PPC/iokit/User/DeviceUser.h" 41 extern mach_port_t bootstrap_port; 42} 43 44#include <ctype.h> 45#include <stdlib.h> 46#include <stdio.h> 47 48// Temporary place for these 49enum { 50 kFireWireRead = 0, 51 kFireWireWrite, 52 kFireWireCompareSwap, 53 kFireWireBusReset, 54 kFireWireTest, 55 kNumFireWireMethods 56}; 57 58mach_port_t master_device_port; 59io_connect_t connection; 60bool dotest, domap, doread, dowrite, dolock, doforever, dobusreset; 61 62UInt32 addrHi, addrLo; 63int tranSize; 64 65IOReturn doTest() 66{ 67 IOReturn kr; 68 int args[4]; 69 unsigned int size; 70 size = 0; 71 kr = io_connect_method_scalarI_scalarO( connection, kFireWireTest, 72 args, 0, NULL, &size); 73 if(kIOReturnSuccess != kr) 74 printf("Test returned 0x%x, size = %d:\n", kr, size); 75 return kr; 76} 77 78IOReturn doMapMem() 79{ 80 IOReturn kr; 81 vm_size_t shmemSize; 82 vm_address_t bufMem; 83 84 kr = IOMapMemory( connection, addrLo, mach_task_self(), 85 &bufMem, &shmemSize, TRUE); 86 if(kIOReturnSuccess == kr) { 87 int i; 88 printf("mapped %d bytes at 0x%x\n", shmemSize, bufMem); 89 for(i=0; i<shmemSize/4; i++) 90 *(int *)(bufMem+i*sizeof(int)) = i; 91 } 92 return kr; 93} 94 95void runTests(io_object_t device) 96{ 97 IOReturn kr; 98 unsigned int size; 99 int i; 100 int args[4]; 101 char buf[4096]; 102 kr = IOServiceOpen(device, mach_task_self(), 11, &connection); 103 if(kIOReturnSuccess != kr) { 104 printf("IOServiceOpen failed: 0x%x\n", kr); 105 return; 106 } 107 108 if(domap) { 109 // Now map some memory for it. 110 kr = doMapMem(); 111 if(kIOReturnSuccess != kr) 112 return; 113 } 114 if(doread) { 115 args[0] = addrHi; // Addr Hi 116 args[1] = addrLo; // Addr Lo 117 size = tranSize; 118 kr = io_connect_method_scalarI_structureO( connection, kFireWireRead, 119 args, 2, buf, &size); 120 printf("Read of 0x%x:0x%x returned 0x%x, size = %d: ", args[0], args[1], kr, size); 121 for(i=0; i<size/4; i++) 122 printf("0x%x ", *((UInt32 *)buf + i)); 123 printf("\n"); 124 } 125 do { 126 if(dobusreset) { 127 size = 0; 128 kr = io_connect_method_scalarI_scalarO(connection, 129 kFireWireBusReset, args, 0, args, &size); 130 if(kIOReturnSuccess != kr) 131 printf("Bus reset returned 0x%x: ", kr); 132 } 133 134 if(dowrite) { 135 size = tranSize; 136 for(i=0; i<size/4; i++) 137 *( (UInt32 *)buf+i) += 0x01010101; 138 args[0] = addrHi; // Addr Hi 139 args[1] = addrLo; // Addr Lo 140 kr = io_connect_method_scalarI_structureI(connection, kFireWireWrite, 141 args, 2, buf, size); 142 if(kIOReturnSuccess != kr) 143 printf("Write returned 0x%x, size = %d:\n", kr, size); 144 } 145 if(dolock) { 146 args[0] = addrHi; // Addr Hi 147 args[1] = addrLo; // Addr Lo 148 args[2] = ((UInt32 *)buf)[0]; 149 args[3] = ((UInt32 *)buf)[1]; 150 size = 0; 151 kr = io_connect_method_scalarI_scalarO( connection, kFireWireCompareSwap, 152 args, 4, NULL, &size); 153 if(kIOReturnSuccess != kr) { 154 printf("Compare&Swap returned 0x%x\n", kr); 155 break; 156 } 157 } 158 if(doread) { 159 args[0] = addrHi; // Addr Hi 160 args[1] = addrLo; // Addr Lo 161 size = tranSize; 162 kr = io_connect_method_scalarI_structureO( connection, kFireWireRead, 163 args, 2, buf, &size); 164 printf("Read of 0x%x:0x%x returned 0x%x, size = %d: ", args[0], args[1], kr, size); 165 if(kIOReturnSuccess != kr) 166 break; 167 for(i=0; i<size/4; i++) 168 printf("0x%x ", *((UInt32 *)buf + i)); 169 printf("\n"); 170 } 171 if(dotest) 172 kr = doTest(); 173 174 } while(doforever && kIOReturnSuccess == kr); 175 176} 177 178kern_return_t processDevice(io_object_t device, UInt64 guid) 179{ 180 kern_return_t kr; 181 IOObject * object; 182 IODictionary * properties; 183 IOOffset * dataDesc; 184 UInt32 nodeID; 185 UInt64 gotGUID; 186 187 kr = IORegistryEntryGetProperties(device, &object); 188 if (kr) 189 return kr; 190 if(!object) 191 return kIOReturnBadArgument; 192 193 properties = (IODictionary *)object; 194 dataDesc = (IOOffset *)properties->getObject("FireWire Node ID"); 195 if(0 == dataDesc) 196 return kIOReturnBadArgument; 197 nodeID = dataDesc->unsigned32BitValue(); 198 dataDesc = (IOOffset *)properties->getObject("GUID"); 199 if(0 == dataDesc) 200 return kIOReturnBadArgument; 201 gotGUID = dataDesc->unsigned64BitValue(); 202 dataDesc = (IOOffset *)properties->getObject("Unit_Spec_ID"); 203 if(0 != dataDesc) { 204 printf("Found device %x, Unit_Spec_ID: 0x%x, GUID: 0x%x:0x%x\n", nodeID, dataDesc->unsigned32BitValue(), 205 (UInt32)(gotGUID>>32), (UInt32)(gotGUID & 0xffffffff)); 206 } 207 else { 208 printf("Found device %x with no units, GUID: 0x%x:0x%x\n", nodeID, 209 (UInt32)(gotGUID>>32), (UInt32)(gotGUID & 0xffffffff)); 210 } 211 object->release(); 212 if(guid == gotGUID) { 213 printf("Found it!\n"); 214 runTests(device); 215 exit(0); 216 } 217 return kIOReturnSuccess; 218} 219 220int pokeDevices(UInt64 guid) 221{ 222 kern_return_t kr; 223 io_iterator_t enumer; 224 io_object_t obj; 225 mach_port_t port; 226 unsigned long int notifyType; 227 unsigned long int ref; 228 struct { 229 mach_msg_header_t msgHdr; 230 OSNotificationHeader notifyHeader; 231 mach_msg_trailer_t trailer; 232 } msg; 233 234 kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); 235 if(KERN_SUCCESS != kr) { 236 printf("Failed to create port!:%d\n", kr); 237 return kr; 238 } 239 240 kr = IOServiceAddNotification( master_device_port, kIOMatchedNotification, 241 IOServiceMatching( "IOFireWireDevice" ), 242 port, 12345, &enumer ); 243 244 if(kIOReturnSuccess != kr) { 245 printf("IOServiceAddNotification = %d\n", kr); 246 return kr; 247 } 248 249 // First process any devices already connected 250 while(obj = IOIteratorNext(enumer)) { 251 processDevice(obj, guid); 252 } 253 254 // Now wait for a new device (or devices) to appear and 255 // process them. 256 kr = mach_msg(&msg.msgHdr, MACH_RCV_MSG, 257 0, sizeof(msg), port, 0, MACH_PORT_NULL); 258 kr = OSGetNotificationFromMessage( &msg.msgHdr, 0, ¬ifyType, &ref, 259 0, 0 ); 260 261 if(ref == 12345) { 262 while(obj = IOIteratorNext(enumer)) { 263 processDevice(obj, guid); 264 } 265 } 266 else 267 printf("Unexpected notification type %d, ref %d\n", 268 notifyType, ref); 269 IOObjectRelease( enumer); 270 return kr; 271} 272 273int 274main(int argc, char **argv) 275{ 276 kern_return_t kr; 277 UInt64 guid = 0; 278 279 IOString *grr; 280 grr = new IOString; 281 grr->release(); 282 283 /* 284 * Get master device port 285 */ 286 kr = IOMasterPort(bootstrap_port, 287 &master_device_port); 288 289 if (kr != KERN_SUCCESS) 290 printf("IOMasterPort failed: %lx\n", kr); 291 tranSize = 32; 292 addrHi = 0xffff; 293 addrLo = 0xf0000400; 294 if(argc > 1) { 295 if(strrchr(argv[1], 'h')) { 296 printf("%s guid [t/m/r/w/l/b/f] [size] [addrHi] [addrLo]\n", argv[0]); 297 printf("t=test, m=map memory, r=read, w=write, l=lock, b=busreset, f=repeat forever\n"); 298 printf("size defaults to %d, addrHi to 0x%x, addrLo to 0x%x (config ROM)\n", 299 tranSize, addrHi, addrLo); 300 exit(0); 301 } 302 guid = strtoq(argv[1], NULL, 0); 303 } 304 if(argc > 2) { 305 dotest = strrchr(argv[2], 't'); 306 domap = strrchr(argv[2], 'm'); 307 doread = strrchr(argv[2], 'r'); 308 dowrite = strrchr(argv[2], 'w'); 309 dolock = strrchr(argv[2], 'l'); 310 dobusreset = strrchr(argv[2], 'b'); 311 doforever = strrchr(argv[2], 'f'); 312 } 313 if(argc > 3) 314 tranSize = strtol(argv[3], NULL, 0); 315 if(argc > 4) 316 addrHi = strtol(argv[4], NULL, 0); 317 if(argc > 5) 318 addrLo = (UInt32)strtoq(argv[5], NULL, 0); 319 pokeDevices(guid); 320} 321 322