/* * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* cc -fno-rtti -fno-exceptions -fcheck-new -fvtable-thunks -arch ppc -lIOKit FireWireTest.cpp -o FireWireTest 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 */ extern "C" { #include } #include #include #include #include extern "C" { #include "../../BUILD/obj/RELEASE_PPC/iokit/User/DeviceUser.h" extern mach_port_t bootstrap_port; } #include #include #include // Temporary place for these enum { kFireWireRead = 0, kFireWireWrite, kFireWireCompareSwap, kFireWireBusReset, kFireWireTest, kNumFireWireMethods }; mach_port_t master_device_port; io_connect_t connection; bool dotest, domap, doread, dowrite, dolock, doforever, dobusreset; UInt32 addrHi, addrLo; int tranSize; IOReturn doTest() { IOReturn kr; int args[4]; unsigned int size; size = 0; kr = io_connect_method_scalarI_scalarO( connection, kFireWireTest, args, 0, NULL, &size); if(kIOReturnSuccess != kr) printf("Test returned 0x%x, size = %d:\n", kr, size); return kr; } IOReturn doMapMem() { IOReturn kr; vm_size_t shmemSize; vm_address_t bufMem; kr = IOMapMemory( connection, addrLo, mach_task_self(), &bufMem, &shmemSize, TRUE); if(kIOReturnSuccess == kr) { int i; printf("mapped %d bytes at 0x%x\n", shmemSize, bufMem); for(i=0; igetObject("FireWire Node ID"); if(0 == dataDesc) return kIOReturnBadArgument; nodeID = dataDesc->unsigned32BitValue(); dataDesc = (IOOffset *)properties->getObject("GUID"); if(0 == dataDesc) return kIOReturnBadArgument; gotGUID = dataDesc->unsigned64BitValue(); dataDesc = (IOOffset *)properties->getObject("Unit_Spec_ID"); if(0 != dataDesc) { printf("Found device %x, Unit_Spec_ID: 0x%x, GUID: 0x%x:0x%x\n", nodeID, dataDesc->unsigned32BitValue(), (UInt32)(gotGUID>>32), (UInt32)(gotGUID & 0xffffffff)); } else { printf("Found device %x with no units, GUID: 0x%x:0x%x\n", nodeID, (UInt32)(gotGUID>>32), (UInt32)(gotGUID & 0xffffffff)); } object->release(); if(guid == gotGUID) { printf("Found it!\n"); runTests(device); exit(0); } return kIOReturnSuccess; } int pokeDevices(UInt64 guid) { kern_return_t kr; io_iterator_t enumer; io_object_t obj; mach_port_t port; unsigned long int notifyType; unsigned long int ref; struct { mach_msg_header_t msgHdr; OSNotificationHeader notifyHeader; mach_msg_trailer_t trailer; } msg; kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port); if(KERN_SUCCESS != kr) { printf("Failed to create port!:%d\n", kr); return kr; } kr = IOServiceAddNotification( master_device_port, kIOMatchedNotification, IOServiceMatching( "IOFireWireDevice" ), port, 12345, &enumer ); if(kIOReturnSuccess != kr) { printf("IOServiceAddNotification = %d\n", kr); return kr; } // First process any devices already connected while(obj = IOIteratorNext(enumer)) { processDevice(obj, guid); } // Now wait for a new device (or devices) to appear and // process them. kr = mach_msg(&msg.msgHdr, MACH_RCV_MSG, 0, sizeof(msg), port, 0, MACH_PORT_NULL); kr = OSGetNotificationFromMessage( &msg.msgHdr, 0, ¬ifyType, &ref, 0, 0 ); if(ref == 12345) { while(obj = IOIteratorNext(enumer)) { processDevice(obj, guid); } } else printf("Unexpected notification type %d, ref %d\n", notifyType, ref); IOObjectRelease( enumer); return kr; } int main(int argc, char **argv) { kern_return_t kr; UInt64 guid = 0; IOString *grr; grr = new IOString; grr->release(); /* * Get master device port */ kr = IOMasterPort(bootstrap_port, &master_device_port); if (kr != KERN_SUCCESS) printf("IOMasterPort failed: %lx\n", kr); tranSize = 32; addrHi = 0xffff; addrLo = 0xf0000400; if(argc > 1) { if(strrchr(argv[1], 'h')) { printf("%s guid [t/m/r/w/l/b/f] [size] [addrHi] [addrLo]\n", argv[0]); printf("t=test, m=map memory, r=read, w=write, l=lock, b=busreset, f=repeat forever\n"); printf("size defaults to %d, addrHi to 0x%x, addrLo to 0x%x (config ROM)\n", tranSize, addrHi, addrLo); exit(0); } guid = strtoq(argv[1], NULL, 0); } if(argc > 2) { dotest = strrchr(argv[2], 't'); domap = strrchr(argv[2], 'm'); doread = strrchr(argv[2], 'r'); dowrite = strrchr(argv[2], 'w'); dolock = strrchr(argv[2], 'l'); dobusreset = strrchr(argv[2], 'b'); doforever = strrchr(argv[2], 'f'); } if(argc > 3) tranSize = strtol(argv[3], NULL, 0); if(argc > 4) addrHi = strtol(argv[4], NULL, 0); if(argc > 5) addrLo = (UInt32)strtoq(argv[5], NULL, 0); pokeDevices(guid); }