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//#define IOASSERT 1 // Set to 1 to activate assert() 24 25// public 26#include <IOKit/firewire/IOFWCommand.h> 27#include <IOKit/firewire/IOFireWireController.h> 28#include <IOKit/firewire/IOFireWireNub.h> 29#include <IOKit/firewire/IOLocalConfigDirectory.h> 30 31// system 32#include <IOKit/assert.h> 33#include <IOKit/IOWorkLoop.h> 34#include <IOKit/IOCommand.h> 35 36OSDefineMetaClassAndStructors(IOFWReadCommand, IOFWAsyncCommand) 37OSMetaClassDefineReservedUnused(IOFWReadCommand, 0); 38OSMetaClassDefineReservedUnused(IOFWReadCommand, 1); 39 40#pragma mark - 41 42// gotPacket 43// 44// 45 46void IOFWReadCommand::gotPacket(int rcode, const void* data, int size) 47{ 48 setResponseCode( rcode ); 49 50 if(rcode != kFWResponseComplete) { 51 //kprintf("Received rcode %d for read command 0x%x, nodeID %x\n", rcode, this, fNodeID); 52 if(rcode == kFWResponseTypeError && fMaxPack > 4) { 53 // try reading a quad at a time 54 fMaxPack = 4; 55 size = 0; 56 } 57 else { 58 complete(kIOFireWireResponseBase+rcode); 59 return; 60 } 61 } 62 else { 63 fMemDesc->writeBytes(fBytesTransferred, data, size); 64 fSize -= size; 65 fBytesTransferred += size; 66 } 67 68 if(fSize > 0) { 69 fAddressLo += size; 70 fControl->freeTrans(fTrans); // Free old tcode 71 updateTimer(); 72 fCurRetries = fMaxRetries; 73 execute(); 74 } 75 else { 76 complete(kIOReturnSuccess); 77 } 78} 79 80// initAll 81// 82// 83 84bool IOFWReadCommand::initAll(IOFireWireNub *device, FWAddress devAddress, 85 IOMemoryDescriptor *hostMem, FWDeviceCallback completion, 86 void *refcon, bool failOnReset) 87{ 88 return IOFWAsyncCommand::initAll(device, devAddress, 89 hostMem, completion, refcon, failOnReset); 90} 91 92// initAll 93// 94// 95 96bool IOFWReadCommand::initAll(IOFireWireController *control, 97 UInt32 generation, FWAddress devAddress, 98 IOMemoryDescriptor *hostMem, FWDeviceCallback completion, 99 void *refcon) 100{ 101 return IOFWAsyncCommand::initAll(control, generation, devAddress, 102 hostMem, completion, refcon); 103} 104 105// reinit 106// 107// 108 109IOReturn IOFWReadCommand::reinit(FWAddress devAddress, 110 IOMemoryDescriptor *hostMem, 111 FWDeviceCallback completion, void *refcon, bool failOnReset) 112{ 113 return IOFWAsyncCommand::reinit(devAddress, 114 hostMem, completion, refcon, failOnReset); 115} 116 117IOReturn IOFWReadCommand::reinit(UInt32 generation, FWAddress devAddress, 118 IOMemoryDescriptor *hostMem, 119 FWDeviceCallback completion, void *refcon) 120{ 121 return IOFWAsyncCommand::reinit(generation, devAddress, 122 hostMem, completion, refcon); 123} 124 125// execute 126// 127// 128 129IOReturn IOFWReadCommand::execute() 130{ 131 IOReturn result; 132 int transfer; 133 134 fStatus = kIOReturnBusy; 135 136 if(!fFailOnReset) { 137 // Update nodeID and generation 138 fDevice->getNodeIDGeneration(fGeneration, fNodeID); 139 fSpeed = fControl->FWSpeed( fNodeID ); 140 if( fMembers->fMaxSpeed < fSpeed ) 141 { 142 fSpeed = fMembers->fMaxSpeed; 143 } 144 } 145 146 transfer = fSize; 147 if(transfer > fMaxPack) 148 { 149 transfer = fMaxPack; 150 } 151 152 int maxPack = (1 << fControl->maxPackLog(fWrite, fNodeID)); 153 if( maxPack < transfer ) 154 { 155 transfer = maxPack; 156 } 157 158 UInt32 flags = kIOFWReadFlagsNone; 159 160 if( fMembers ) 161 { 162 if( ((IOFWAsyncCommand::MemberVariables*)fMembers)->fForceBlockRequests ) 163 { 164 flags |= kIOFWWriteBlockRequest; 165 } 166 } 167 168 fTrans = fControl->allocTrans(this); 169 if(fTrans) { 170 result = fControl->asyncRead(fGeneration, fNodeID, fAddressHi, 171 fAddressLo, fSpeed, fTrans->fTCode, transfer, this, (IOFWReadFlags)flags ); 172 } 173 else { 174 // IOLog("IOFWReadCommand::execute: Out of tLabels?\n"); 175 result = kIOFireWireOutOfTLabels; 176 } 177 178 // complete could release us so protect fStatus with retain and release 179 IOReturn status = fStatus; 180 if(result != kIOReturnSuccess) 181 { 182 retain(); 183 complete(result); 184 status = fStatus; 185 release(); 186 } 187 188 return status; 189} 190