ShowSCSIDeviceIdent.c

/*
    File:       ShowSCSIDeviceIdent.c
 
    Contains:   This subroutine prints the bus ID or device ident associated with the
                specified driver.
 
    Written by: Martin Minow    
 
    Copyright:  Copyright © 1992-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):
                7/14/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#include <stdio.h>
#include <Files.h>
#include <Devices.h>
#include <Memory.h>
#ifndef FALSE
#define FALSE       0
#define TRUE        1
#endif
/*
 * Include the O.S. files in a specific order to make sure that we have
 * a definition for the _SCSIAtomic trap.
 */
#include <Traps.h>
#ifndef _SCSIAtomic
#define _SCSIAtomic 0xA089
#endif
/*
 * Note that this uses a later version of <Scsi.h> than is available in
 * the published headers.
 */
#include "Scsi.h"
 
void                    ShowSCSIDeviceIdent(
        short               driverRefNum
    );
Boolean                 AsyncSCSIPresent(void);
 
static void
ClearMemory(
        Ptr             ptr,
        Size            size
    )
{
        while (size > 0) {
            *ptr++ = 0;
            --size;
        }
}
 
/*
 * The following macros are valid for the old SCSI Manager and for SCSI Manager
 * 4.3 in the simple case where the device is the first registered on a bus
 * and is registered under logical unit zero.
 */
#define DriverRefNumToSCSI(x)   ((signed short) (~(x) - 32))
/*
 * This macro converts a SCSI bus ID to a DriverRefNum
 */
#define SCSIToDriverRefNum(x)   ((signed short) (~((x) + 32)))
/*
 * These constants define the range of Driver RefNum's that are associated with
 * hard-wired SCSI bus id's. Note that the driver reference numbers are negative.
 * If a driver is present in this range, the device can be accessed through both
 * the old and New SCSI Manager.
 */
#define kMinSCSIDrive   (SCSIToDriverRefNum(6))
#define kMaxSCSIDrive   (SCSIToDriverRefNum(0))
 
Boolean                     IsHardWiredSCSIDevice(
        register short          driverRefNum
    );
Boolean                     DriverRefNumToDeviceIdent(
        register short          driverRefNum,
        DeviceIdent             *deviceIdentPtr
    );
 
void
ShowSCSIDeviceIdent(
        short               driverRefNum
    )
{
        DeviceIdent         deviceIdent;
        
        if (DriverRefNumToDeviceIdent(driverRefNum, &deviceIdent)) {
            /*
             * This device is registered with SCSI Manager 4.3
             */
            printf(
                " -- [%d.%d.%d] (registered)",
                (int) deviceIdent.bus,
                (int) deviceIdent.targetID,
                (int) deviceIdent.LUN
            );
        }
        else if (IsHardWiredSCSIDevice(driverRefNum)) {
            /*
             * This is a SCSI device whose driver did not register
             * with SCSI Manager 4.3, possibly because the new
             * SCSI Manager is not installed on this machine.
             */
            printf(" -- [%d] (hardwired)",
                (int) DriverRefNumToSCSI(driverRefNum));
        }
        else {
            /*
             * This is not a SCSI device.
             */
            printf(" -- Not SCSI");
        }
}
 
/*
 * If SCSI Manager 4.3 is present and this driver has been registered, return
 * TRUE and store the SCSI Device Ident in the deviceIdentPtr location. If SCSI
 * Manager 4.3 is not present, or this is not a registered driver, return FALSE.
 *
 * Note that this returns FALSE even if SCSI Manager 4.3 is present if the
 * device's driver did not register with the new SCSI Manager (i.e. if the
 * device uses an "old-style" driver).
 */
Boolean
DriverRefNumToDeviceIdent(
        register short          driverRefNum,
        DeviceIdent             *deviceIdentPtr
    )
{
        SCSIDriverPB            pb;
        OSErr                   status;
        
        if (AsyncSCSIPresent()) {
            ClearMemory((Ptr) &pb, sizeof pb);
            pb.scsiPBLength = sizeof (SCSIDriverPB);
            pb.scsiCompletion = NULL;
            pb.scsiFlags = 0;
            pb.scsiFunctionCode = SCSILookupRefNumXref;
            * ((long *) &pb.scsiDevice) = 0xFFFFFFFFL;
            do {
                status = SCSIAction((SCSI_PB *) &pb);
                if (status != noErr)
                    break;
                else if (pb.scsiDriver == driverRefNum
                      && pb.scsiDevice.bus != 0xFF) {
                    *deviceIdentPtr = pb.scsiDevice;
                    return (TRUE);                      /* Success              */
                }
                else {
                    pb.scsiDevice = pb.scsiNextDevice;
                }
            }
            while (pb.scsiDevice.bus != 0xFF);
        }
        /*
         * Exit here if either the New SCSI Manager is no present or
         * the device is not a SCSI device.
         */
         return (FALSE);
}
 
                
 
/*
 * TRUE if this driver is a SCSI device. Note: this is valid only for the Old SCSI
 * Manager and for the New SCSI Manager in a simple bus configuration where all
 * devices have unique target ID's and all SCSI devices are at logical unit zero.
 */
Boolean
IsHardWiredSCSIDevice(
        register short          driverRefNum
    )
{
        return (
            DriverRefNumToSCSI(driverRefNum) >= 0
            && DriverRefNumToSCSI(driverRefNum) <= 6
        );
}