Source to iokit/Families/IOFireWire/IOFWUtils.cpp
/*
* 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)