Source to iokit/Families/IOFireWire/IOFWUtils.cpp


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
 * 3 June 99 wgulland created.
 *
 * Useful stuff called from several different FireWire objects.
 */
#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/firewire/IOFWRegs.h>
#include <IOKit/firewire/IOFireWirePriv.h>

////////////////////////////////////////////////////////////////////////////////
//
// FWComputeCRC16
//
//   This proc computes a CRC 16 check.
//

UInt16	FWComputeCRC16(UInt32 *pQuads, UInt32 numQuads)
{
    SInt32	shift;
    UInt32	sum;
    UInt32	crc16;
    UInt32	quadNum;
    UInt32	quad;

    // Compute CRC 16 over all quads.
    crc16 = 0;
    for (quadNum = 0; quadNum < numQuads; quadNum++) {
        quad = *pQuads++;
        for (shift = 28; shift >= 0; shift -= 4) {
            sum = ((crc16 >> 12) ^ (quad >> shift)) & 0x0F;
            crc16 = (crc16 << 4) ^ (sum << 12) ^ (sum << 5) ^ (sum);
        }
    }

    return (crc16 & 0xFFFF);
}


////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMInvalidateEntryIDType
//
//   Invalidate a CSR ROM entry ID.  This will deallocate any memory allocated
// for the ID excluding the ID data record itself.
//
// Probably only thing needed is to release reference to the ROM.
//

void  FWCSRROMInvalidateEntryIDType(CSRROMEntryID csrROMEntryID)
{
    CSRROMEntryIDDataPtr		pCSRROMEntryIDData;

    if (csrROMEntryID != kInvalidCSRROMEntryID)
    {
        pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;

        switch (pCSRROMEntryIDData->entryType)
        {
                case kLocalCSRROMEntryIDType :
                        break;

                case kRemoteCSRROMEntryIDType :

                        break;

                default :
                        break;
        }

        // Entry is now invalid.
        pCSRROMEntryIDData->entryType = kInvalidCSRROMEntryIDType;
    }
}

////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMCreateEntryID
//
//   Allocate memory for a CSR ROM entry ID.
//zzz could be a little more efficient computing allocation size.
//

CSRROMEntryID	FWCSRROMCreateEntryID(void)
{
    CSRROMEntryID		csrROMEntryID = kInvalidCSRROMEntryID;
    CSRROMEntryIDDataPtr	pCSRROMEntryIDData;
    UInt32			maxSize;

    // Determine maximum size of all entry types.
    // Need enough for local ID type.
    maxSize = sizeof (CSRROMLocalIDData);
    if (sizeof (CSRROMRemoteIDData) > maxSize)
        maxSize = sizeof (CSRROMRemoteIDData);

    // Allocate the data.
    pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) IOMalloc (maxSize);
    if (pCSRROMEntryIDData != NULL) {
        pCSRROMEntryIDData->entryType = kInvalidCSRROMEntryIDType;
        csrROMEntryID = (CSRROMEntryID) pCSRROMEntryIDData;
    }
    return (csrROMEntryID);
}

////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMDisposeEntryID
//
//   Deallocate memory for a CSR ROM entry ID.
//

void  FWCSRROMDisposeEntryID(CSRROMEntryID csrROMEntryID)
{
    CSRROMEntryIDDataPtr pCSRROMEntryIDData;

    if (csrROMEntryID != kInvalidCSRROMEntryID) {
        UInt32 maxSize;

        // Determine maximum size of all entry types.
        // Need enough for local ID type.
        maxSize = sizeof (CSRROMLocalIDData);
        if (sizeof (CSRROMRemoteIDData) > maxSize)
            maxSize = sizeof (CSRROMRemoteIDData);
        pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;

        // Invalidate entry.
        FWCSRROMInvalidateEntryIDType (csrROMEntryID);

        // Deallocate entry.
        IOFree(pCSRROMEntryIDData, maxSize);
    }
}

////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMCreateRemoteEntryID
//
//   Create a remote CSR ROM entry ID.
//

static IOReturn	FWCSRROMCreateRemoteEntryID(
	CSRROMEntryID			*pCSRROMEntryID,
	const UInt32 *			data,
	UInt32				*physicalPath,
	UInt32				pathSize)
{
    CSRROMEntryID			csrROMEntryID = *pCSRROMEntryID;
    CSRROMEntryIDDataPtr		pCSRROMEntryIDData;
    CSRROMRemoteIDDataPtr		pCSRROMRemoteIDData;

    // Allocate an entry ID if given entry ID is invalid.
    if (csrROMEntryID == kInvalidCSRROMEntryID) {
        csrROMEntryID = FWCSRROMCreateEntryID ();
        // If entry ID is still invalid, there must have been a memory error.
        if (csrROMEntryID == kInvalidCSRROMEntryID)
            return kIOReturnNoMemory;
   }


    // Get data from ID.
    pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;
    pCSRROMRemoteIDData = (CSRROMRemoteIDDataPtr) pCSRROMEntryIDData;

    // If entry is not a remote type, invalidate its type.
    if ((pCSRROMEntryIDData->entryType != kRemoteCSRROMEntryIDType) &&
        (pCSRROMEntryIDData->entryType != kInvalidCSRROMEntryIDType)) {
        FWCSRROMInvalidateEntryIDType (csrROMEntryID);
    }

    // Make entry a remote type.
    pCSRROMEntryIDData->entryType = kRemoteCSRROMEntryIDType;


    // Copy directory paths and data pointer
    pCSRROMRemoteIDData->data = data;
    bcopy (physicalPath, pCSRROMRemoteIDData->physicalPath, pathSize * sizeof (UInt32));
    pCSRROMRemoteIDData->pathSize = pathSize;

    // Return entry ID.
    *pCSRROMEntryID = csrROMEntryID;

    return (kIOReturnSuccess);
}

////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMDisposeIterator
//
//   Dispose of storage allocated for iterator.
//

void FWCSRROMDisposeIterator(CSRROMEntryIterator csrROMIterator)
{
    CSRROMEntryIteratorRecPtr	pIteratorRec;

    // Deallocate if iterator is valid.
    if (csrROMIterator != kInvalidCSRROMIterator) {
        // Get iterator record.
        pIteratorRec = (CSRROMEntryIteratorRecPtr) csrROMIterator;

        // Deallocate iterator record.
        IOFree (pIteratorRec, sizeof (CSRROMEntryIteratorRec));
    }
}


////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMSetIterator
//
//   Set current path and relationship of iterator.
//zzz should support all entry ID types.
//zzz should support kIterateRoot
//

IOReturn FWCSRROMSetIterator(
	CSRROMEntryIterator			csrROMIterator,
	CSRROMEntryID				csrROMEntryID,
	CSRROMIterationOp			relationship)
{
    CSRROMEntryIteratorRecPtr	pIteratorRec;
    CSRROMEntryIDDataPtr		pCSRROMEntryIDData;
    CSRROMRemoteIDDataPtr		pCSRROMRemoteIDData;

    // Get CSR ROM search iterator record.
    pIteratorRec = (CSRROMEntryIteratorRecPtr) csrROMIterator;

    // Set to given entry.
    if (csrROMEntryID != kInvalidCSRROMEntryID) {
        // Get entry data from ID.
        pCSRROMEntryIDData = (CSRROMEntryIDDataPtr) csrROMEntryID;

        if (pCSRROMEntryIDData->entryType == kRemoteCSRROMEntryIDType) {
            // Recast entry data.
            pCSRROMRemoteIDData = (CSRROMRemoteIDDataPtr) pCSRROMEntryIDData;

            // Copy physical path.
            bcopy (pCSRROMRemoteIDData->physicalPath,
                                            pIteratorRec->physicalPath,
                                            pCSRROMRemoteIDData->pathSize * sizeof (UInt32));

            // Copy data pointer and path depth
            pIteratorRec->data = pCSRROMRemoteIDData->data;
            pIteratorRec->pathSize = pCSRROMRemoteIDData->pathSize;
        }
    }

    // Set to given relationship.
    if (relationship != kIterateContinue)
            pIteratorRec->relationship = relationship;

    return (kIOReturnSuccess);
}


////////////////////////////////////////////////////////////////////////////////
//
// FWCSRROMEntrySearch
//
//   Search for the next ROM entry that matches the search criteria.
//zzz need to check the search type in the criteria record and the relationship
//zzz could be more efficient.  should make and use more defs.
//zzz need to return information on what exactly was found
//zzz fill in entry value better
//zzz should break this up
//zzz should support all entry ID types.
//

// zzz
// Made a quick fix here so that if we are searching for Unit Directories (key d1)