Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
MyRegisterPort.c
/* |
File: MyRegisterPort.c |
Contains: Contains the custom routines for registering an offlineing an OT Port |
See the PortScanner.c file for an explanation of the call |
Written by: |
Copyright: Copyright © 1998-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
8/16/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 |
*/ |
#pragma export on |
//---------------------------------------------------------------------- |
#define DEBUG 1 |
//---------------------------------------------------------------------- |
#include <OpenTptModule.h> |
#include <OpenTptLinks.h> |
#include <PCCardEnablerPlugin.h> |
#include <PCCardTuples.h> |
#include <Gestalt.h> |
#include <DriverFamilyMatching.h> |
#include "EnablerSample.h" |
#include "MyRegisterPort.h" |
static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum); |
static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef); |
/* |
The OfflinePortExists call is used to offline a port |
where the assumption is that the deviceRef for the device |
in the NameRegistry is stored in the fContext field of the |
portRecord. This routine searches the ports for an entry which |
has a matching deviceRef value and unregisters the port. |
Assumes that there is an existing port that has as it's fContext |
value, the same as *deviceRef, so that the value can be matched. |
*/ |
static Boolean OfflinePortExists(RegEntryID *deviceRef, DriverDescription *dd, UInt32 socketNum) |
{ |
DriverServiceInfo *dsi; |
TPortRecord *portRecord; |
UInt32 index; |
UInt32 busType; |
size_t idx; |
OSStatus err; |
Boolean foundOne; |
#if DEBUG |
DebugStr("\p about to check for offlined ports"); |
#endif |
index = 0; |
while (portRecord = OTGetIndexedPort(index)) |
{ |
index++; |
busType = OTGetBusTypeFromPortRef(portRecord->fRef); |
if (busType == kOTPCCardBus) |
{ |
#if DEBUG |
DebugStr("\p PCCard port found"); |
#endif |
// check if the socket numbers match |
if (((UInt8)portRecord->fSlotID[0] - '0') != socketNum) |
{ |
#if DEBUG |
DebugStr("\p socketNum - no match"); |
#endif |
continue; |
} |
#if DEBUG |
DebugStr("\p socketNum - matches"); |
#endif |
// check if the port is offlined |
if (portRecord->fPortFlags && kOTPortIsOffline) |
{ |
// we've found an offline port. |
// check if the driver descriptor info matches the info in the port |
dsi = dd->driverServices.service; |
foundOne = false; |
for (idx = 0; idx < dd->driverServices.nServices; ++idx) |
{ |
if ( dsi->serviceCategory == kServiceCategoryOpenTransport ) |
{ |
foundOne = true; |
break; |
} |
dsi += 1; |
} |
if (foundOne == true) |
{ |
// check if the driver name matches |
if (OTMemcmp(&(dd->driverOSRuntimeInfo.driverName[1]), portRecord->fModuleName, |
dd->driverOSRuntimeInfo.driverName[0]) == true) |
{ |
#if DEBUG |
DebugStr("\p matching offline port found"); |
#endif |
// restore the fPortFlags |
portRecord->fPortFlags &= ~(kOTPortIsOffline + kOTPortIsUnavailable ); |
// set the fContext field to the current deviceRef |
*(RegEntryID *)portRecord->fContext = *deviceRef; |
err = SetPortConfiguredProperty(deviceRef); |
if (err) |
{ |
#if DEBUG |
DebugStr("\p RegistryPropertySet for port-configured property failed"); |
#endif |
} |
return true; |
} |
} |
} |
} |
} |
#if DEBUG |
DebugStr("\p matching offliner port not found"); |
#endif |
return false; |
} |
/* |
The OfflineThePort call is used to offline a port |
where the assumption is that the deviceRef for the device |
in the NameRegistry is stored in the fContext field of the |
portRecord. This routine searches the ports for an entry which |
has a matching deviceRef value and unregisters the port. |
Assumes that there is an existing port that has as it's fContext |
value, the same as *deviceRef, so that the value can be matched. |
*/ |
extern void OfflineThePort(RegEntryID *deviceRef) |
{ |
RegEntryID *portContext; |
TPortRecord *portRecord; |
UInt32 index; |
UInt32 busType; |
#if DEBUG |
DebugStr("\p about to check bus"); |
#endif |
index = 0; |
while (portRecord = OTGetIndexedPort(index)) |
{ |
index++; |
busType = OTGetBusTypeFromPortRef(portRecord->fRef); |
if (busType == kOTPCCardBus) |
{ |
// check if the deviceRef matches |
portContext = portRecord->fContext; |
if (*((long*)deviceRef) == *((long*)portContext)) |
{ |
// set the offline bit in the fPortFlags field |
portRecord->fPortFlags |= kOTPortIsOffline; |
portRecord->fPortFlags |= kOTPortIsUnavailable; |
#if DEBUG |
DebugStr("\p port offlined"); |
#endif |
return; |
} |
} |
} |
#if DEBUG |
DebugStr("\p port not found to offline"); |
#endif |
} |
/* |
The RegisterThePort call is used to register a network port for a |
PC Card 3.0 device with Open Transport. The call |
is designed for alternate networking cards like TokenRing, and ATM |
which are not handled by the default PC Card Port Scanner. |
This function checks for the presence of a |
"driver-descriptor" and the "SocketNumber" property associated with |
the device node. It uses the these properties to fill in the port information. |
The call looks at the "driver-descriptor" property to know how to fill out the |
TPortRecord structure. |
*/ |
void RegisterThePort( RegEntryID *deviceRef) |
{ |
char buffer[sizeof(DriverDescription) + |
kMaxServices*sizeof(DriverServiceInfo)]; |
DriverDescription *dd = (DriverDescription*)buffer; |
DriverServiceInfo *dsi; |
OTPortRecord *portRecord; |
RegEntryID *portContext; |
OSStatus err; |
UInt32 size; |
UInt32 framing; |
UInt32 socket; |
size_t idx; |
size_t sIndex = 0; |
UInt16 other; |
UInt16 otType; |
UInt16 iface; |
Boolean foundOne; |
#if DEBUG |
DebugStr("\p port scanner: RegisterThePort"); |
#endif |
// |
// If the driver has no driver-descriptor property, or the size |
// is too small, or it is too large to fit our buffer - forget |
// this one. |
// |
err = RegistryPropertyGetSize(deviceRef, kDescriptorProperty, &size); |
if ( err != noErr || size < sizeof(DriverDescription) || |
size > sizeof(buffer) ) |
{ |
#if DEBUG |
DebugStr("\p kPropertyDriverDesc not found"); |
#endif |
return; |
} |
// |
// Read the driver-descriptor property into our buffer. |
// |
err = RegistryPropertyGet(deviceRef, kDescriptorProperty, buffer, &size); |
if ( err != noErr ) |
{ |
#if DEBUG |
DebugStr("\p kPropertyDriverDesc not found"); |
#endif |
return; |
} |
// |
// Read the SocketNumber property into our buffer. |
// |
size = sizeof(socket); |
err = RegistryPropertyGet(deviceRef, kSocketNumber, &socket, &size); |
if ( err != noErr ) |
{ |
#if DEBUG |
DebugStr("\p socket property not found"); |
#endif |
return; |
} |
// |
// Check whether an offline port exists for this module |
// |
if (OfflinePortExists(deviceRef, dd, socket) == true) |
{ |
return; |
} |
dsi = dd->driverServices.service; |
foundOne = false; |
for (idx = 0; idx < dd->driverServices.nServices; ++idx) |
{ |
if ( dsi->serviceCategory == kServiceCategoryOpenTransport ) |
{ |
foundOne = true; |
break; |
} |
dsi += 1; |
} |
if (foundOne == false) |
return; |
// check if there is a driver name |
if (dd->driverOSRuntimeInfo.driverName[0] == 0 ) |
return; |
// lets register this port - first get some memory |
portRecord = (OTPortRecord*)OTAllocPortMem(sizeof(OTPortRecord)); |
if (portRecord == nil) |
return; |
OTMemzero(portRecord, sizeof(OTPortRecord)); |
OTMemcpy(&portRecord->fModuleName, &dd->driverOSRuntimeInfo.driverName[1], |
dd->driverOSRuntimeInfo.driverName[0]); |
otType = (UInt16)((dsi->serviceType >> 16) & 0x7ff); |
iface = (UInt16)(dsi->serviceType & 3); |
framing = (UInt32)((dsi->serviceType >> 8) & 0xff); |
// find a unique "other" value for this device |
other = 0; |
do |
{ |
portRecord->fRef = OTCreatePortRef(kOTPCCardBus, otType, socket, other++); |
} while ( OTFindPortByRef(portRecord->fRef) != 0 ); |
// now set the associated slot |
// portRecord->fSlotID[0] = 0; |
OTMemcpy(&portRecord->fSlotID, " \0", 2); |
portRecord->fSlotID[0] = (char)('0'+ socket); |
// for the fInfoFlag the 0x1 indicates the module is DLPI |
// for a TPI interface, set the value to 0x2 |
portRecord->fInfoFlags = iface; |
portRecord->fCapabilities = framing; |
portRecord->fNumChildPorts = 0; |
portRecord->fPortName[0] = 0; |
// allocate port context memory |
portContext = (RegEntryID*)OTAllocPortMem(sizeof(RegEntryID)); |
if (portContext != nil) |
{ |
// store the deviceRef in the portContext field so that |
// we can discriminate this port entry later when we for a matching |
// port to offline. |
*portContext = *deviceRef; |
#if DEBUG |
DebugStr("\p about to register port"); |
#endif |
err = OTRegisterPort(portRecord, (void*)portContext); |
if (err == noErr) |
{ |
err = SetPortConfiguredProperty(deviceRef); |
if (err) |
{ |
#if DEBUG |
DebugStr("\p RegistryPropertySet for port-configured property failed"); |
#endif |
} |
} |
else |
{ |
#if DEBUG |
DebugStr("\p OTRegisterPort failed"); |
#endif |
} |
} |
else |
{ |
#if DEBUG |
DebugStr("\p OTAllocPortMem failed"); |
#endif |
OTFreePortMem(portRecord); |
} |
} |
static OSStatus SetPortConfiguredProperty (RegEntryID *deviceRef) |
{ |
OSStatus err; |
UInt16 portConfigProperty = 1; |
// modify the port-configured property to indicate that we have registered the |
// port. Note that the presence of this property tells the default PC Card |
// Port scanner that the port has been previously registered, whatever the |
// value. This scanner checks the value and if zero, registers the port. |
// then we set the value to 1 to indicate that we've registered it. Later |
// we might find this port and have a way to know that we've already configured |
// this device. |
err = RegistryPropertySet(deviceRef, kPortConfigured, |
&portConfigProperty, sizeof(portConfigProperty)); |
return err; |
} |
#pragma export off |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22