Source to iokit/IOKit/firewire/IOFireWireController.h


Enter a symbol's name here to quickly find it.

/*
 * Copyright (c) 1998-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@
 */
/*
 * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved.
 *
 * HISTORY
 *
 */


#ifndef _IOKIT_IOFIREWIRECONTROLLER_H
#define _IOKIT_IOFIREWIRECONTROLLER_H

#include <IOKit/firewire/IOFireWireBus.h>
#include <IOKit/firewire/IOFWRegs.h>
#include <IOKit/firewire/IOFireWirePriv.h>

extern const OSSymbol *gFireWireROM;
extern const OSSymbol *gFireWireNodeID;
extern const OSSymbol *gFireWireSelfIDs;
extern const OSSymbol *gFireWireSpeed;
extern const OSSymbol *gFireWireUnit_Spec_ID;
extern const OSSymbol *gFireWireUnit_SW_Version;
extern const OSSymbol *gFireWireVendor_ID;
extern const OSSymbol *gFireWire_GUID;

class OSData;
class IOWorkLoop;
class IOTimerEventSource;
class IOCommandGate;
class IOMemoryDescriptor;
class IOFireWireController;
class IOFWAddressSpace;
class IOFireWireNub;
class IOFireWireDevice;
class IOFWCommand;
class IOFWAsyncCommand;
class IODCLProgram;
struct NodeScan;

typedef void (*PacketHandler)(void *refCon, IOFireWireController* control, int rcode, UInt8* data, int size);

struct AsyncPendingTrans {
    IOFWAsyncCommand *	fHandler;
    int			fTCode;
    bool		fInUse;
};

// May want to change this, to use two tcodes per request block.
#define kMaxPendingTransfers kFWAsynchTTotal

class IOFireWireController : public IOFireWireBus
{
    OSDeclareAbstractStructors(IOFireWireController)

protected:
    IOWorkLoop *	fWorkLoop;
    IOTimerEventSource *fTimer;
    IOCommandGate *	fGate;
    OSSet *		fLocalAddresses;	// Collection of local adress spaces
    OSIterator *	fSpaceIterator;		// Iterator over local addr spaces

    OSSet *		fAllocatedChannels;	// Need to be informed of bus resets
    OSIterator *	fAllocChannelIterator;	// Iterator over channels
    IOLock *		fChannelLock;

    // Bus management variables (although we aren't a FireWire Bus Manager...)
    AbsoluteTime	fResetTime;		// Time of last reset
    UInt32		fLocalNodeID;		// ID of the local node.
    UInt32		fBusGeneration;		// ID of current bus topology.
    UInt16		fRootNodeID;		// ID of root, ie. highest node id in use.
    UInt16		fIRMNodeID;		// ID of Isochronous resource manager, or kFWBadNodeID
    IOFireWireDevice *	fIRMDevice;		// NULL if no IRM.
    IORegistryEntry * 	fNodes[kFWMaxNodesPerBus];	// FireWire nodes on this bus
    UInt32 *	 	fNodeIDs[kFWMaxNodesPerBus+1];	// Pointer to SelfID list for each node
							// +1 so we know how many selfIDs the last node has
    UInt8		fSpeedCodes[(kFWMaxNodesPerBus+1)*kFWMaxNodesPerBus];
						// Max speed between two nodes
    bool		fInReset;		// True if processing a reset (waiting for selfIDs)
    int			fNumROMReads;		// Number of device ROMs we are still reading
    // SelfIDs
    int			fNumSelfIDs;		// Total number of SelfID packets
    UInt32		fSelfIDs[kMaxSelfIDs*kFWMaxNodesPerBus];

    // The local device's CSR ROM
    UInt32		fCSRROMGeneration;	// Generation number of CSR ROM.
    CSRROMDirectoryData	fCSRROMRootDirectory;	// Local CSR ROM root directory.
    CSRNodeUniqueID	fUniqueID;		// ID unique to this device.
    UInt32 		fROMHeader[5];		// More or less fixed header and bus info block
    IOFWAddressSpace *	fROMAddrSpace;

    // Array for outstanding requests (up to 64)
    AsyncPendingTrans	fTrans[kMaxPendingTransfers];
    int			fLastTrans;
    IOLock *		fTransAllocLock;

    static IOReturn execCommand(OSObject * obj, void *field0, void *field1,
						 void *field2, void *field3);
    static void clockTick(OSObject *, IOTimerEventSource *);
    static void readROMGlue(void *refcon, IOReturn status,
			IOFireWireNub *device, IOFWCommand *fwCmd);
    virtual IOWorkLoop * createWorkLoop();
    virtual bool startWorkLoop();

    virtual void processBusReset();
    virtual void processSelfIDs(UInt32 *IDs, int numIDs, UInt32 *ownIDs, int numOwnIDs);
    virtual void processRcvPacket(UInt32 *data, int numQuads);
    virtual void processWriteRequest(UInt16 sourceID, UInt32 tlabel,
				UInt32 *hdr, void *buf, int len);
    virtual void processLockRequest(UInt16 sourceID, UInt32 tlabel,
				UInt32 *hdr, void *buf, int len);

    virtual void pruneDevices();

    virtual void buildTopology(bool doFWPlane);

    virtual void readDeviceROM(NodeScan *refCon, IOReturn status);

// Hack so old OHCI driver will compile
    virtual IODCLProgram *createDCLProgram(bool talking, DCLCommandStruct *opcodes,
            UInt32 startEvent, UInt32 startState, UInt32 startMask){return NULL;};

    virtual IODCLProgram *createDCLProgram(bool talking, DCLCommandStruct *opcodes,
            DCLTaskInfo *info, UInt32 startEvent, UInt32 startState, UInt32 startMask)
	{return createDCLProgram(talking, opcodes, startEvent, startState,  startMask); };

    // Send a PHY packet
    virtual IOReturn sendPHYPacket(UInt32 quad) = 0;

public:

    static const IORegistryPlane * gIOFireWirePlane;

    // Initialization
    virtual bool init(OSDictionary * dict);

    // Implement IOService::getWorkLoop
    virtual IOWorkLoop *getWorkLoop() const;

    // Methods called by commands. Not really public.
    virtual void fireBugMsg(const char *msg) = 0;
    virtual IOReturn resetBus() = 0;
    virtual IOReturn asyncRead(UInt16 nodeID, UInt16 addrHi, UInt32 addrLo, 
				int speed, int label, int size, IOFWAsyncCommand *cmd) = 0;
    virtual IOReturn asyncReadQuadResponse(UInt16 nodeID, int speed, 
					int label, int rcode, UInt32 data) = 0;
    virtual IOReturn asyncReadResponse(UInt16 nodeID, int speed, 
					int label, int rcode, void *data, int len) = 0;
    virtual IOReturn asyncReadResponse(UInt16 nodeID, int speed,
                                       int label, int rcode, IOMemoryDescriptor *buf,
				       IOByteCount offset, int len) = 0;

    virtual IOReturn asyncWrite(UInt16 nodeID, UInt16 addrHi, UInt32 addrLo,
		int speed, int label, IOMemoryDescriptor *buf, IOByteCount offset,
		int size, IOFWAsyncCommand *cmd) = 0;
    virtual IOReturn asyncWrite(UInt16 nodeID, UInt16 addrHi, UInt32 addrLo,
                                int speed, int label, void *data, int size, IOFWAsyncCommand *cmd) = 0;
    virtual IOReturn asyncWriteResponse(UInt16 nodeID, int speed, 
					int label, int rcode, UInt16 addrHi) = 0;

    virtual IOReturn asyncLock(UInt16 nodeID, UInt16 addrHi, UInt32 addrLo, 
			int speed, int label, int type, void *data, int size, IOFWAsyncCommand *cmd) = 0;
    virtual IOReturn asyncLockResponse(UInt16 nodeID, int speed, 
				int label, int rcode, int type, void *data, int len) = 0;

    // Read Cycle time register. safe to call at any time.
    virtual IOReturn getCycleTime(UInt32 *cycleTime) = 0;

    virtual IOReturn allocAddress(IOFWAddressSpace *space);
    virtual void freeAddress(IOFWAddressSpace *space);
    virtual IOReturn UpdateROM();

    // Allocate struct for receiving a read response
    virtual AsyncPendingTrans *allocTrans(bool sleepOK = true);
    virtual void freeTrans(AsyncPendingTrans *trans);

    // Really public methods

    // Methods to manipulate the local CSR ROM
    virtual IOReturn CSRROMGetRootDirectory(CSRROMEntryID *pCSRROMEntryID);
    virtual IOReturn CSRROMCreateEntry(CSRROMEntryID parentCSRROMEntryID, CSRROMEntryID *pCSRROMEntryID,
	UInt32 entryType, UInt32 entryKeyValue, void *entryData, UInt32 entrySize);

    // Convert a firewire nodeID into the IOFireWireDevice for it
    virtual IOFireWireDevice * nodeIDtoDevice(UInt16 nodeID);

    // Add/remove a channel from the list informed of bus resets
    virtual void addAllocatedChannel(IOFWIsochChannel *channel);
    virtual void removeAllocatedChannel(IOFWIsochChannel *channel);

    // Create a device nub
    virtual IOFireWireDevice *createDeviceNub(OSDictionary *propTable);

    // Create an Isochronous Channel object
    virtual IOFWIsochChannel *createIsochChannel(
	bool doIRM, UInt32 bandwidth, IOFWSpeed prefSpeed,
	FWIsochChannelForceStopNotificationProc stopProc=NULL,
	void *stopRefCon=NULL);

    // Create a local isochronous port to run the given DCL program
    // if task is 0, the DCL program is for the kernel task,
    // otherwise all DCL pointers are valid in the specified task.
    // opcodes is also pointer valid in the specified task.
    virtual IOFWIsochPort *createLocalIsochPort(bool talking,
        DCLCommandStruct *opcodes, DCLTaskInfo *info = 0,
	UInt32 startEvent = 0, UInt32 startState = 0, UInt32 startMask = 0);

    // Inline accessors for protected member variables
    IOCommandGate *getGate() const {return fGate;};
    bool checkGeneration(UInt32 gen) const {return gen == fBusGeneration;};
    UInt32 getGeneration() const {return fBusGeneration;};
    UInt16 getIRMNodeID() const {return fIRMNodeID;};
    IOFireWireDevice * getIRMDevice() const {return fIRMDevice;};
    const AbsoluteTime * getResetTime() const {return &fResetTime;};

    IOFWSpeed FWSpeed(UInt16 nodeAddress) const
	{return (IOFWSpeed)fSpeedCodes[(kFWMaxNodesPerBus+1)*(nodeAddress & 63)+(fLocalNodeID & 63)];};
    IOFWSpeed FWSpeed(UInt16 nodeA, UInt16 nodeB) const
      {return (IOFWSpeed)fSpeedCodes[(kFWMaxNodesPerBus+1)*(nodeA & 63)+(nodeB & 63)];};

    // How big (as a power of two) can packets sent to/received from the node be?
    virtual int maxPackLog(bool forSend, UInt16 nodeAddress) const;

    // How big (as a power of two) can packets sent from A to B be?
    virtual int maxPackLog(UInt16 nodeA, UInt16 nodeB) const;
};

#endif /* ! _IOKIT_IOFIREWIRECONTROLLER_H */