#ifndef  DRIVERGESTALT_H
#define DRIVERGESTALT_H

#ifndef  MACTYPES_H
#include <CarbonCore/MacTypes.h>
#endif

#ifndef  OSUTILS_H
#include <CarbonCore/OSUtils.h>
#endif

#ifndef  NAMEREGISTRY_H
#include <CarbonCore/NameRegistry.h>
#endif

#ifndef  SCSI_H
#include <OSServices/SCSI.h>
#endif

#ifndef   USB_H
#include <IOKit/usb/USB.h>
#endif

#ifndef  DISKS_H
#include <Disks.h>
#endif

#include <APPLE/DriverGestalt.h>
#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*GetADrive Control Call

The kGetADrive control call ( csCode = 51) asks the driver to create a new drive queue element. This control call supports synchronous and asynchronous operation. 

On input, DrvQElPtr contains the address of a drive queue element pointer. The call creates a new drive queue element based on the supplied drive queue element and places a pointer to the new drive queue element in the supplied address.

The following describes how the fields of the new drive queue element must be filled out: 
Field name	
Description
drive flags 	(the 4 bytes prior to qLink) Inherited from the supplied drive queue element. 
qLink 	Set up when you add the drive to the drive queue using AddDrive. 
qType 	Inherited from the supplied drive queue element. 
dQDrive 	Must be set to a new unique drive number. 
dQRefNum 	Must be set to your driver's reference number. 
dQFSID 	Inherited from the supplied drive queue element. 
dQDrvSz 	Inherited from the supplied drive queue element. 
dQDrvSz2 	Inherited from the supplied drive queue element. 
partition offset 	(typically held in extra bytes beyond dQDrvSz2 ) Inherited from the supplied drive queue element. 


Your driver must return the new drive queue element in the memory pointed by csParam[0..1]. You must not post a disk inserted event for the new drive, or send the fsmDrvQElChangedMessage message to the File System Manager.*/
enum {
 kGetADrive                    = 51
};

/*RegisterPartition Control Call

The kRegisterPartition control call ( csCode = 50) registers a non-Macintosh partition found on a disk. This control call supports synchronous and asynchrous operation. The driver should fill in csParam as follows:
csParam[0..1] DrvQElPtr             // The drive queue element whose //
                                    // partition is to be changed //
(UInt32) csParam[2..3]              // The block number of the first //
                                    // block in the partition //
(UInt32) csParam[4..5]              // Size of partition in blocks // 

In response to this call, your disk driver must retarget the specified drive queue element to represent the given partition on the disk. After this call, the drive queue element must represent a partition that starts at the block specified by csParam[2..3] and is of the size specified by csParam[4..5].

You must not post a disk inserted event for the new drive, or send the fsmDrvQElChangedMessage message to the File System Manager.

IMPORTANT

The effects of this call are limited to the drive queue element in memory. This call must not change the partitioning scheme on disk.*/
enum {
  kRegisterPartition            = 50,
};

/*GetPartInfo Status Call

The kGetPartInfo status call ( csCode = 51) returns information about a partition in the partInfoRec structure described earlier in ProhibitMounting Control Call This status call supports synchronous and asynchronous operation. 

In response to this call, your disk driver must place partition information about the specified drive in the partition information record pointed to by csParam[0..1].

The driver fills in the partInfoRec structure as follows:
/(partInfoRecPtr)csParam.SCSIID <-              // DeviceIdent for //
                                                // the device //
/(partInfoRecPtr)csParam.physPartitionLoc <-        // physical block //
                                        // number of partition start //
/(partInfoRecPtr)csParam.partitionNumber 
                                // partition number of this partition //*/

enum {
  kGetPartInfo                  = 51
};

/*Table 8-6 DriverGestalt selector four character codes and constants 
Four character code selector	
Selector constants
'boot' 	kdgBoot 
'dAPI' 	kdgAPI 
'devt' 	kdgDeviceType 
'dics ' 	kdgPhysDriveIconSuite 
'ejec ' 	kdgEject 
'flus' 	kdgFlush 
'intf' 	kdgInterface 
'lpwr' 	kdgSupportsSwitching 
'mics' 	kdgMediaIconSuite 
'mnam' 	kdgMediaName 
'pmn3' 	kdgMin3VPower 
'pmn5' 	kdgMin5VPower 
'pmx3' 	kdgMax3VPower 
'pmx5' 	kdgMax5VPower 
'psta' 	kdgInHighPower 
'psup' 	kdgSupportsPowerCtl 
'purg' 	kdgPurge 
'sync' 	kdgSync 
'vers' 	kdgVersion 
'vmop' 	kdgVMOptions 
'wide' 	kdgWide*/
enum {
	kdgBoot ='boot' ,
	kdgAPI ='dAPI' ,
	kdgDeviceType ='devt' ,
	kdgPhysDriveIconSuite= 'dics ' ,
	kdgEject ='ejec ' ,
	kdgFlush ='flus' ,
 	kdgInterface ='intf',
	kdgSupportsSwitching ='lpwr' ,
	kdgMediaIconSuite ='mics' ,
 	kdgMediaName= 'mnam',
kdgMin3VPower= 'pmn3' 	,
kdgMin5VPower ='pmn5' 	,
kdgMax3VPower= 'pmx3' 	,
	kdgMax5VPower ='pmx5' ,
	kdgInHighPower ='psta' ,
	kdgSupportsPowerCtl= 'psup' ,
kdgPurge ='purg' 	,
kdgSync= 'sync' 	,
	kdgVersion ='vers' ,
 	kdgVMOptions ='vmop',
	kdgWide ='wide' 
};

/*The following response buffers are defined for some of the driver gestalt selectors listed in Table 8-5 :
struct DriverGestaltSyncResponse
{
    Boolean behavesSynchronously;
    UInt8       pad[3]
}; 
struct DriverGestaltBootResponse
{
    UInt8 extDev;                       / packed target (upper 5 bits)
                                             LUN (lower 3 bits) /
    UInt8 partition;                    / partition /
    UInt8 SIMSlot;                      / slot /
    UInt8 SIMsRSRC;                     / sRsrcID /
}; 
struct DriverGestaltDevTResponse
{
    OSType deviceType;
};
enum {
    kdgDiskType             = 'disk',   / standard r/w disk drive /
    kdgTapeType             = 'tape',   / tape drive /
    kdgPrinterType          = 'prnt',   / printer /
    kdgProcessorType        = 'proc',   / processor /
    kdgWormType             = 'worm',   / write-once /
    kdgCDType               = 'cdrm',   / cd-rom drive /
    kdgFloppyType           = 'flop',   / floppy disk drive /
    kdgScannerType          = 'scan',   / scanner /
    kdgFileType             = 'file',   / logical partition based on a
                                            file (drive Container) /
    kdgRemovableType        = 'rdsk'    / removable media hard disk /
}; 
struct DriverGestaltIntfResponse
{
    OSType interfaceType;
};
enum {
    kdgScsiIntf             = 'scsi', / SCSI interface /
    kdgPcmciaIntf           = 'pcmc', / PCMCIA interface /
    kdgATAIntf              = 'ata ', / ATA/ATAPI interface /
    kdgFireWireIntf         = 'fire', / FireWire 1394 interface /
    kdgExtBus               = 'card' / Card Bus interface /
}; 
struct DriverGestaltAPIResponse 
{
    short               partitionCmds;  / if bit 0 is nonzero, /
                                        / supports partition /
                                        / control and status calls /
                    / prohibitMounting (control, kProhibitMounting) /
                    / partitionToVRef (status, kGetPartitionStatus) /
                    / getPartitionInfo (status, kGetPartInfo) /
    short                   unused1;        / All the unused fields /
                                            / should be zero /
    short                   unused2;
    short                   unused3;
    short                   unused4;
    short                   unused5;
    short                   unused6;
    short                   unused7;
    short                   unused8;
    short                   unused9;
    short                   unused10;
}; 
struct DriverGestaltPowerResponse {
    unsigned long       powerValue;     / Power consumed in Watts /
}; 
struct DriverGestaltFlushResponse 
{
    Boolean             canFlush;       / Return true if driver /
                                        /  supports the kdcFlush /
                                        / driver configure _Control /
                                        / call /
    Boolean             needsFlush;     / Return true if /
                                        / driver/device has /
                                        / data cached /
                                        / and needs to be flushed 
                                        / when the disk volume /
                                        / is flushed by the /
                                        / File Manager /
    UInt8               pad[2];
}; 
/ Flags for purge permissions /
enum {
    kbCloseOk               = 0,            / Ok to call Close /
    kbRemoveOk              = 1,            / Ok to call RemoveDrvr /
    kbPurgeOk               = 2,            / Ok to call DisposePtr /
    kmNoCloseNoPurge        = 0,
    kmOkCloseNoPurge        = (1 << kbCloseOk) + (1 << kbRemoveOk),
    kmOkCloseOkPurge        = (1 << kbCloseOk) + (1 << kbRemoveOk) + (1 << 
kbPurgeOk)
}; 
struct DriverGestaltPurgeResponse 
{
    UInt16          purgePermission;    / 0 = Do not change /
                                        / the state of the driver /
                                        / 3 = Do Close() and /
                                        / DrvrRemove() this driver /
                                            / but don't deallocate /
                                            / driver code /
                                            / 7 = Do Close(), /
                                            / DrvrRemove(), and /
                                            / DisposePtr() /
    UInt16          purgeReserved;
    Ptr             purgeDriverPointer;/ pointer to the start of /
                                            / the driver block (valid /
                                            / only if DisposePtr /
                                            / permission is given /
}; 
struct DriverGestaltEjectResponse {
    UInt32                  ejectFeatures;      / Features field /
}; 
/ Flags for Ejection Features field /
enum {
    kRestartDontEject           = 0,            / Dont Want eject /
                                                / during Restart /
    kShutDownDontEject          = 1,            / Dont Want eject /
                                                / during Shutdown /
    kRestartDontEject_Mask          = 1 << kRestartDontEject,
    kShutDownDontEject_Mask         = 1 << kShutDownDontEject
}; 
struct DriverGestaltWideResponse
{
    Boolean supportsWide;
};*/

struct DriverGestaltSyncResponse
{
    Boolean behavesSynchronously;
    UInt8       pad[3]
}; 
typedef struct DriverGestaltSyncResponse DriverGestaltSyncResponse;

struct DriverGestaltBootResponse
{
    UInt8 extDev;                       /* packed target (upper 5 bits)
                                             LUN (lower 3 bits) */
    UInt8 partition;                    /* partition */
    UInt8 SIMSlot;                      /* slot */
    UInt8 SIMsRSRC;                     /* sRsrcID */
}; 
struct DriverGestaltDevTResponse
{
    OSType deviceType;
};
typedef struct DriverGestaltDevTResponse DriverGestaltDevTResponse;

enum {
    kdgDiskType             = 'disk',   /* standard r/w disk drive */
    kdgTapeType             = 'tape',   /* tape drive */
    kdgPrinterType          = 'prnt',   /* printer */
    kdgProcessorType        = 'proc',   /* processor */
    kdgWormType             = 'worm',   /* write-once */
    kdgCDType               = 'cdrm',   /* cd-rom drive */
    kdgFloppyType           = 'flop',   /* floppy disk drive */
    kdgScannerType          = 'scan',   /* scanner */
    kdgFileType             = 'file',   /* logical partition based on a
                                            file (drive Container) */
    kdgRemovableType        = 'rdsk'    /* removable media hard disk */
}; 
struct DriverGestaltIntfResponse
{
    OSType interfaceType;
};
enum {
    kdgScsiIntf             = 'scsi', /* SCSI interface */
    kdgPcmciaIntf           = 'pcmc', /* PCMCIA interface */
    kdgATAIntf              = 'ata ', /* ATA/ATAPI interface */
    kdgFireWireIntf         = 'fire', /* FireWire 1394 interface */
    kdgExtBus               = 'card' /* Card Bus interface */
}; 
struct DriverGestaltAPIResponse 
{
    short               partitionCmds;  /* if bit 0 is nonzero, */
                                        /* supports partition */
                                        /* control and status calls */
                    /* prohibitMounting (control, kProhibitMounting) */
                    /* partitionToVRef (status, kGetPartitionStatus) */
                    /* getPartitionInfo (status, kGetPartInfo) */
    short                   unused1;        /* All the unused fields */
                                            /* should be zero */
    short                   unused2;
    short                   unused3;
    short                   unused4;
    short                   unused5;
    short                   unused6;
    short                   unused7;
    short                   unused8;
    short                   unused9;
    short                   unused10;
}; 
typedef struct DriverGestaltAPIResponse DriverGestaltAPIResponse;

struct DriverGestaltPowerResponse {
    unsigned long       powerValue;     /* Power consumed in Watts */
}; 
struct DriverGestaltFlushResponse 
{
    Boolean             canFlush;       /* Return true if driver */
                                        /*  supports the kdcFlush */
                                        /* driver configure _Control */
                                        /* call */
    Boolean             needsFlush;     /* Return true if */
                                        /* driver/device has */
                                        /* data cached */
                                        /* and needs to be flushed *
                                        /* when the disk volume */
                                        /* is flushed by the */
                                        /* File Manager */
    UInt8               pad[2];
}; 
/* Flags for purge permissions */
enum {
    kbCloseOk               = 0,            /* Ok to call Close */
    kbRemoveOk              = 1,            /* Ok to call RemoveDrvr */
    kbPurgeOk               = 2,            /* Ok to call DisposePtr */
    kmNoCloseNoPurge        = 0,
    kmOkCloseNoPurge        = (1 << kbCloseOk) + (1 << kbRemoveOk),
    kmOkCloseOkPurge        = (1 << kbCloseOk) + (1 << kbRemoveOk) + (1 << 
kbPurgeOk)
}; 
struct DriverGestaltPurgeResponse 
{
    UInt16          purgePermission;    /* 0 = Do not change */
                                        /* the state of the driver */
                                        /* 3 = Do Close() and */
                                        /* DrvrRemove() this driver */
                                            /* but don't deallocate */
                                            /* driver code */
                                            /* 7 = Do Close(), */
                                            /* DrvrRemove(), and */
                                            /* DisposePtr() */
    UInt16          purgeReserved;
    Ptr             purgeDriverPointer;/* pointer to the start of */
                                            /* the driver block (valid */
                                            /* only if DisposePtr */
                                            /* permission is given */
}; 
struct DriverGestaltEjectResponse {
    UInt32                  ejectFeatures;      /* Features field */
}; 
/* Flags for Ejection Features field */
enum {
    kRestartDontEject           = 0,            /* Dont Want eject */
                                                /* during Restart */
    kShutDownDontEject          = 1,            /* Dont Want eject */
                                                /* during Shutdown */
    kRestartDontEject_Mask          = 1 << kRestartDontEject,
    kShutDownDontEject_Mask         = 1 << kShutDownDontEject
}; 
struct DriverGestaltWideResponse
{
    Boolean supportsWide;
};


/*Using DriverGestalt and DriverConfigure

Status code csCode 43 (0x2B) is defined as DriverGestalt. It takes two parameters, at csParam and csParam +4, that contain a gestalt-like selector and long word output. Similarly, control csCode 43 is defined as DriverConfigure. It also takes two parameters, an OSType selector that specifies the requested operation and a long word. The parameter blocks have these structures:
struct DriverGestaltParam {
    QElemPtr                qLink;
    short                   qType;
    short                   ioTrap;
    Ptr                     ioCmdAddr;
    ProcPtr                 ioCompletion;
    OSErr                   ioResult;
    StringPtr               ioNamePtr;
    short                   ioVRefNum;
    short                   ioCRefNum;      // refNum for I/O operation//
    short                   csCode;         // == kDriverGestaltCode //
    OSType                  driverGestaltSelector;

    UInt32                  driverGestaltResponse;      // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse1;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse2;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse3;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt16                  driverGestaltfiller; // To pad out to the //
                                                // size of a controlPB //
}; 

struct DriverConfigParam {
    QElemPtr                    qLink;
    short                       qType;
    short                       ioTrap;
    Ptr                         ioCmdAddr;
    IOCompletionUPP             ioCompletion;
    OSErr                       ioResult;
    StringPtr                   ioNamePtr;
    short                       ioVRefNum;
    short                       ioCRefNum;  // refNum for I/O operation//
    short                       csCode;     // == driverConfigureCode//
    OSType                      driverConfigureSelector;
    UInt32                      driverConfigureParameter;
}; 

The OSType selectors for DriverGestalt and DriverConfigure are defined according to the rules of gestalt selector definition set forth in Inside Macintosh: Operating System Utilities. In particular, Apple reserves all four-character sequences consisting entirely of lowercase letters and nonalphabetic characters.
DriverGestalt Selectors 
Using the 'boot' Selector*/
struct DriverGestaltParam {
    QElemPtr                qLink;
    short                   qType;
    short                   ioTrap;
    Ptr                     ioCmdAddr;
    ProcPtr                 ioCompletion;
    OSErr                   ioResult;
    StringPtr               ioNamePtr;
    short                   ioVRefNum;
    short                   ioCRefNum;      // refNum for I/O operation//
    short                   csCode;         // == kDriverGestaltCode //
    OSType                  driverGestaltSelector;

    UInt32                  driverGestaltResponse;      // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse1;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse2;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt32                  driverGestaltResponse3;     // Could be a //
                                            // pointer, bit field or //
                                            // other format // 

    UInt16                  driverGestaltfiller; // To pad out to the //
                                                // size of a controlPB //
}; 

typedef struct DriverGestaltParam       DriverGestaltParam;

#ifdef __cplusplus
}
#endif

#endif 

