#ifndef IOS_H #define IOS_H /** This is a big mess of IOS structs and functions. * They come from the storage.doc / FAQ. * There are also some VxDCall wrappers, manually generated. */ #include #include #include "sassert.h" typedef void __cdecl (*IO_callback)(struct IOP *iop); // IOS ================ #define IOS_DEVICE_ID 0x10 static inline uint32_t IOS_Get_Version(void); #pragma aux IOS_Get_Version = \ "int 0x20" \ "dd ( 0x10 shl 16 ) + 0" \ "jnc ok" \ "xor eax, eax" \ "ok:" \ __parm __caller [] __value [eax] __modify [ecx edx] static inline void IOS_Register(const struct DRP *drp); #pragma aux IOS_Register = \ "int 0x20" \ "dd ( 0x10 shl 16 ) + 7" \ __parm __caller [] __modify [eax ecx edx] // AEP ================ typedef _Packed struct AEPHDR { uint16_t AEP_func; // function; see below uint16_t AEP_result; // result; set to zero if successful; see below uint32_t AEP_ddb; // address of DDB uint8_t AEP_lgn; // current load group number (from DVT) uint8_t AEP_align[3]; // reserved; don't use } AEPHDR, *PAEPHDR; typedef _Packed struct AEP_bi_init { AEPHDR AEP_bi_i_hdr; uint32_t AEP_bi_reference_data; // optional value passed in from DRP uint8_t AEP_bi_flags; // flags; see below uint8_t AEP_bi_i_max_target; // max scsi target id uint8_t AEP_bi_i_max_lun; // max scsi lun uint32_t AEP_bi_i_dcb; // init DCB for port drivers void* AEP_bi_i_hdevnode; // handle to devnode for this adapter void* AEP_bi_i_regkey; // registry key for this adapter uint8_t AEP_bi_i_align[1]; // reserved; don't use } AEP_bi_init, *PAEP_bi_init; typedef _Packed struct AEP_boot_done { AEPHDR AEP_bi_i_hdr; } AEP_boot_done, *PAEP_boot_done; typedef _Packed struct AEP_dcb_config { struct AEPHDR AEP_d_c_hdr; struct DCB *AEP_d_c_dcb; // 32-bit ptr to DCB } AEP_dcb_config, *PAEP_dcb_config; typedef _Packed struct AEP_dcb_unconfig { struct AEPHDR AEP_d_u_hdr; struct DCB *AEP_d_u_dcb; // 32-bit ptr to DCB } AEP_dcb_unconfig, *PAEP_dcb_unconfig; typedef _Packed struct AEP_iop_timeout_occurred { struct AEPHDR AEP_i_t_o_hdr; struct IOP *AEP_i_t_o_iop; // address of IOP that timed out } AEP_iop_timeout_occurred, *PAEP_iop_timeout_occurred; typedef _Packed struct AEP_inquiry_device { struct AEPHDR AEP_i_d_hdr; uint32_t AEP_i_d_dcb; // address of DCB } AEP_inquiry_device, *PAEP_inquiry_device; typedef _Packed struct AEP_bi_uninit { struct AEPHDR AEP_bi_u_hdr; } AEP_bi_uninit, *PAEP_bi_uninit; typedef struct AEP_dcb_unconfig_pend { struct AEPHDR AEP_d_u_p_hdr; struct DCB *AEP_d_u_p_dcb; // 32-bit ptr to DCB } AEP_dcb_unconfig_pend, *PAEP_dcb_unconfig_pend; typedef _Packed union AEP { struct AEPHDR; struct AEP_bi_init bi_i; struct AEP_boot_done b_d; struct AEP_dcb_config d_c; struct AEP_dcb_unconfig d_u; struct AEP_iop_timeout_occurred i_t_o; struct AEP_inquiry_device i_d; struct AEP_bi_uninit bi_u; struct AEP_dcb_unconfig_pend d_u_p; } AEP, *PAEP; typedef enum AEP_result { AEP_SUCCESS = 0, AEP_FAILURE = -1, AEP_NO_INQ_DATA = 1, AEP_NO_MORE_DEVICES = 2 } AEP_result; enum AEP_funcs { /** initializes driver/interface */ AEP_INITIALIZE = 0, /** indicates system critical shutdown */ AEP_SYSTEM_CRIT_SHUTDOWN = 1, /** booting done - switch to run time */ AEP_BOOT_COMPLETE = 2, /* configure device */ AEP_CONFIG_DCB = 3, /* unconfigure device */ AEP_UNCONFIG_DCB = 4, /* iop timeout occured */ AEP_IOP_TIMEOUT = 5, /* get device indentification data */ AEP_DEVICE_INQUIRY = 6, /* 1/2 second interval notification */ AEP_HALF_SEC = 7, /* one second interval notification */ AEP_1_SEC = 8, /* two second interval notification */ AEP_2_SECS = 9, /* four second interval notification*/ AEP_4_SECS = 10, /* parameters for '.I' debug command*/ AEP_DBG_DOT_CMD = 11, /* associate logical DCBs w/ physical */ AEP_ASSOCIATE_DCB = 12, /* IFSMGR about to hook in */ AEP_REAL_MODE_HANDOFF = 13, /* indicates system shutdown */ AEP_SYSTEM_SHUTDOWN = 14, /* uninitialize driver/interface */ AEP_UNINITIALIZE = 15, /* logical dcb is going to be locked */ AEP_DCB_LOCK = 16, /* notify drivers of volume mount */ AEP_MOUNT_NOTIFY = 17, /* notify drivers of VRP creation */ AEP_CREATE_VRP = 18, /* notify drivers of VRP destruction */ AEP_DESTROY_VRP = 19, /* tell drivers to refresh drive data */ AEP_REFRESH_DRIVE = 20, /** tell drivers that DCB removal is pending */ AEP_PEND_UNCONFIG_DCB = 21, /** notify int13 of a possible change in the int 1eh vector for copy protection */ AEP_1E_VEC_UPDATE = 22, /** inform driver vsd to change the floppy spindle speed */ AEP_CHANGE_RPM = 23, }; // BlockDev =========== typedef struct BlockDev_Scatter_Gather{ uint32_t BD_SG_Count; // Block count; else byte count if IORF_CHAR_COMMAND set void* BD_SG_Buffer_Ptr; } _BlockDev_Scatter_Gather; enum BDD_FLAGS { BDF_Int13_Drive = 0x01, BDF_Int13_Drive_Bit = 0, BDF_Writeable = 0x02, BDF_Writeable_Bit = 1, BDF_Removable = 0x04, BDF_Removable_Bit = 2, BDF_Remote = 0x08, BDF_Remote_Bit = 3, BDF_Serial_Cmd = 0x10, BDF_Serial_Cmd_Bit = 4, BDF_Cache = 0x20, BDF_Cache_Bit = 5, }; // DCB ================ typedef _Packed struct _DCB_COMMON { uint32_t DCB_physical_dcb; // DCB for physical device uint32_t DCB_expansion_length; // expansion length; see below struct DCB_cd_entry *DCB_ptr_cd; // address of calldown list uint32_t DCB_next_dcb; // link to next DCB uint32_t DCB_next_logical_dcb; // address of next logical dcb uint8_t DCB_drive_lttr_equiv; // drive number; see below uint8_t DCB_unit_number; // drive or unit #; see below uint16_t DCB_TSD_Flags; // TSD flags; see below // Volume Tracking uint32_t DCB_vrp_ptr; // address of VRP for this DCB uint32_t DCB_dmd_flags; // demand bits; see below uint32_t DCB_device_flags; // general purpose flags; see DCB_DEV_FLAGS uint32_t DCB_device_flags2; // general purpose flags; see DCB_DEV_FLAGS2 uint32_t DCB_Partition_Start; // partition start sector uint32_t DCB_track_table_ptr; // address of track table buffer // for ioctls uint32_t DCB_bds_ptr; // DOS BDS corresp. to this DCB // (logical DCB's only) uint32_t DCB_Reserved1; // reserved; must be zero uint32_t DCB_Reserved2; // reserved; must be zero uint8_t DCB_apparent_blk_shift; // log of apparent_blk_size uint8_t DCB_partition_type; // partition type uint16_t DCB_sig; // padding and signature uint8_t DCB_device_type; // device type; see below uint32_t DCB_Exclusive_VM; // exclusive access handle uint8_t DCB_disk_bpb_flags; // BPB flags; see below uint8_t DCB_cAssoc; // # of assoc. logical drives uint8_t DCB_Sstor_Host; // indicates a sstor host volume uint16_t DCB_user_drvlet; // userdriveletter settings or 0xff uint16_t DCB_Reserved3; // reserved; must be zero uint32_t DCB_Reserved4; // reserved; must be zero } DCB_COMMON, *PDCB_COMMON; typedef _Packed struct _DCB_BLOCKDEV { uint32_t DCB_BDD_Next; uint8_t DCB_BDD_BD_Major_Version; // INIT uint8_t DCB_BDD_BD_Minor_Version; // INIT uint8_t DCB_BDD_Device_SubType; uint8_t DCB_BDD_Int_13h_Number; uint32_t DCB_BDD_flags; // was BDD_Flags char * DCB_BDD_Name_Ptr; // Apparent geometry as seen by TSD and above uint64_t DCB_apparent_sector_cnt; // # of sectors uint32_t DCB_apparent_blk_size; // blk size of device uint32_t DCB_apparent_head_cnt; // # of heads uint32_t DCB_apparent_cyl_cnt; // # of cylinders uint32_t DCB_apparent_spt; // # of secs/trk uint32_t DCB_BDD_Sync_Cmd_Proc; uint32_t DCB_BDD_Command_Proc; uint32_t DCB_BDD_Hw_Int_Proc; // INIT <0> uint32_t DCB_BDP_Cmd_Queue_Ascending; uint32_t DCB_BDP_Cmd_Queue_Descending; uint32_t DCB_BDP_Current_Flags; uint32_t DCB_BDP_Int13_Param_Ptr; uint32_t DCB_BDP_Current_Command; uint32_t DCB_BDP_Current_Position[2]; uint32_t DCB_BDP_Reserved[5]; uint32_t DCB_fastdisk_bdd; // set for DCBs created when a // fastdisk regs with the // blockdev BDD for it. Else 0. } DCB_BLOCKDEV, *PDCB_BLOCKDEV; typedef _Packed struct DCB { DCB_COMMON DCB_cmn; // common information uint32_t DCB_max_xfer_len; // maximum transfer length // Actual geometry data (as seen below the TSD) uint64_t DCB_actual_sector_cnt; // number of sectors uint32_t DCB_actual_blk_size; // actual block size of the device uint32_t DCB_actual_head_cnt; // number of heads uint32_t DCB_actual_cyl_cnt; // number of cylinders uint32_t DCB_actual_spt; // number of sectors per track void* DCB_next_ddb_dcb; // link to next DCB on DDB chain void* DCB_dev_node; // address of dev node for device uint8_t DCB_bus_type; // Bus type; see below uint8_t DCB_bus_number; // channel (cable) within adapter uint8_t DCB_queue_freeze; // queue freeze depth counter uint8_t DCB_max_sg_elements; // max # s/g elements; see below // Volume tracking layer use only uint8_t DCB_io_pend_count; // # of pending requests for DCB uint8_t DCB_lock_count; // # of LOCK MEDIA commands // SCSI uint16_t DCB_SCSI_VSD_FLAGS; // Flags for SRB builder uint8_t DCB_scsi_target_id; // SCSI target ID uint8_t DCB_scsi_lun; // SCSI logical unit number uint8_t DCB_scsi_hba; // prot-driver-relative adapter # uint8_t DCB_max_sense_data_len; // Maximum sense length uint16_t DCB_srb_ext_size; // miniport srb extension length uint8_t DCB_inquiry_flags[8]; // Device inquiry flags char DCB_vendor_id[8]; // Vendor ID string char DCB_product_id[16]; // Product ID string char DCB_rev_level[4]; // Product revision level char DCB_port_name[8]; // uint8_t DCB_current_unit; // current unit #; see below // Volume tracking layer use only uint32_t DCB_blocked_iop; // address of requests for an // inactive volume uint32_t DCB_vol_unlock_timer; // unlock timer handle uint8_t DCB_access_timer; // time measure between accesses // Volume tracking layer use only uint8_t DCB_Vol_Flags; // Volume tracking; see below uint8_t DCB_q_algo; // algorithm index; see below uint8_t DCB_unit_on_ctl; // 0-based device number on ctlr uint32_t DCB_Port_Specific; // bytes for port driver use uint32_t DCB_spindown_timer; // timer for drive spin down DCB_BLOCKDEV DCB_bdd; } DCB, *PDCB; /** Contains information about a calldown entry. */ typedef _Packed struct DCB_cd_entry { IO_callback DCB_cd_io_address; // address of request routine uint32_t DCB_cd_flags; // demand bits; see below struct DDB *DCB_cd_ddb; // driver's DDB pointer struct DCB_cd_entry *DCB_cd_next; // address of next cd entry uint16_t DCB_cd_expan_off; // offset of expansion area uint8_t DCB_cd_layer_flags; // flags for layer's use uint8_t DCB_cd_lgn; // load group number } DCB_cd_entry, *PDCB_cd_entry; enum DCB_BUS { DCB_BUS_ESDI = 0, DCB_BUS_SCSI = 1, DCB_BUS_NEC = 2, DCB_BUS_SMART = 3, DCB_BUS_ABIOS = 4 }; enum DCB_TSD_FLAGS { /** Don't trust the BPB */ DCB_TSD_INVALID_PARTITION = 1, /** Bad MBR (physical device only) */ DCB_TSD_BAD_MBR = 1, /** User drive letters checked */ DCB_TSD_USER_LETTERS_CHECKED = (1 << 1), /** User drive letters checked first time */ DCB_TSD_FIRST_USER_CHECK = (1 << 2), /** User set the a drive letter range */ DCB_TSD_USER_SET = (1 << 4), /** User int 13 disabled */ DCB_TSD_NO_USER_INT13 = 0x020, /** Protmode only int 13 */ DCB_TSD_PROTMODE_INT_13 = (1 << 6), /** Reserved drive letter */ DCB_TSD_NONEXIST_PARTITION = (1 << 7), /** Recommend BPB set from PBR by TSD (from int 41 or int 46) */ DCB_TSD_MBPB_PBR = 0x0100, /** Bit shift for recommended BPB initialized */ DCB_TSD_RBPB_INIT = (1 << 9), /** Media BPB initialized */ DCB_TSD_MBPB_INIT = 0x0400, /** Apparent set from primary PBR */ DCB_TSD_APPARENT_PBR = 0x0800, /** Apparent set from ROM data */ DCB_TSD_APPARENT_ROM = 0x1000, /** Actual set from apparent by TSD */ DCB_TSD_ACTUAL_SET = 0x2000, /** Actual geometry set prior to TSD */ DCB_TSD_ACTUAL_PRE_SET = 0x4000, /** Apparent geometry set prior to TSD */ DCB_TSD_APPARENT_PRE_SET = 0x8000 }; enum DCB_DEV_FLAGS { /** indicates drive supports spindown command */ DCB_DEV_SPINDOWN_SUPPORTED_BIT = 31, DCB_DEV_SPINDOWN_SUPPORTED = (1 << DCB_DEV_SPINDOWN_SUPPORTED_BIT), /* indicates drive is currently spun down */ DCB_DEV_SPUN_DOWN_BIT = 30, DCB_DEV_SPUN_DOWN = (1 << DCB_DEV_SPUN_DOWN_BIT), /* port driver use only - indicates I/O has been received for this DCB */ DCB_DEV_IO_ACTIVE_BIT = 29, DCB_DEV_IO_ACTIVE = (1 << DCB_DEV_IO_ACTIVE_BIT), /* this device has been configured as an int 13 drive */ DCB_DEV_INT13_CONFIGURED_BIT = 28, DCB_DEV_INT13_CONFIGURED = (1 << DCB_DEV_INT13_CONFIGURED_BIT), /* This DCB cannot handle ASPI or CAM requests */ DCB_DEV_NO_ASPICAM_BIT = 27, DCB_DEV_NO_ASPICAM = (1 << DCB_DEV_NO_ASPICAM_BIT), /* this device is going away soon */ DCB_DEV_REMOVAL_PENDING_BIT = 26, DCB_DEV_REMOVAL_PENDING = (1 << DCB_DEV_REMOVAL_PENDING_BIT), /* logical drives for this int 13 device are controlled by the mapper */ DCB_DEV_RMM_INT13_BIT = 25, DCB_DEV_RMM_INT13 = (1 << DCB_DEV_RMM_INT13_BIT), /* this device has been processed by a TSD */ DCB_DEV_TSD_PROCESSED_BIT = 24, DCB_DEV_TSD_PROCESSED = (1 << DCB_DEV_TSD_PROCESSED_BIT), /* this is an equivlaent of IRS_DRV_SINGLE_FLOPPY. This indicates that */ /* the dmd_a_b_toggling is not set in the floppy dcb. */ DCB_DEV_SINGLE_FLOPPY = 0x00800000, /* this device must be controlled by a real mode driver, and should not */ /* be taken over in protected mode */ DCB_DEV_REAL_MODE = 0x00400000, /* current queing direction is descending - used by port drivers or IOS if */ /* DCB_SERIAL_CMD flag is set */ DCB_DEV_QUE_DESCEND = 0x00200000, /* hardware indicated media change */ DCB_DEV_MEDIA_CHANGED = 0x00100000, /* bit indicates the disk geometry has become invalid. */ DCB_DEV_INVALID_GEOM = 0x00080000, /* If this bit is set, it specifies not have the volume tracking layer do * the 2 second timing stuff for media change. This bit is typically set * if DCB_DEV_SYNC_MED_CHG_SUPPORT is set. */ DCB_DEV_INHIBIT_SW_TIMED_SUPPORT = 0x00040000, /* drive is in read only mode */ /* drive has h/w support to indicate by interrupt that disk door has been * popped open, etc. */ DCB_DEV_ASYNC_MED_CHG_SUPPORT = 0x00020000, /* drive has h/w sync med. chg supp. -- when u first access a drive with * media changed, drive returns an error. */ DCB_DEV_SYNC_MED_CHG_SUPPORT = 0x00010000, DCB_DEV_PHYSICAL = 0x00008000, /* on = physical */ DCB_DEV_LOGICAL = 0x00004000, /* on = logical */ DCB_DEV_LOGICAL_BIT = 14, DCB_DEV_RMM = 0x00002000, /* on = real mode mapper DCB*/ DCB_DEV_RMM_BIT = 13, DCB_DEV_UNCERTAIN_MEDIA = 0x00001000, /* media may have been changed */ DCB_DEV_ROM_CFG_REQ = 0x00000800, /* tsd must use rom chain data */ DCB_DEV_MUST_CONFIGURE = 0x00000400,/* set at create dcb time */ /* cleared after all layers */ /* get the config aep for */ /* this DCB. */ DCB_DEV_SSTOR_VOL = 0x00000200, /* set if this is SSTOR volume */ DCB_DEV_PAGING_DEVICE = 0x00000100, /* indicates that the paging drive */ /* is on this DCB */ DCB_CHAR_DEVICE = 0x00000080, /* indicates that this is a char dev*/ /* * The foll. DCB_DEV_I13_IN_PROGRESS flag is used in conjunction with RMM * and the global DCB. This flag is set when an int 13 in progress, in * iosint13.asm, and cleared when the int 13 is done. */ DCB_DEV_I13_IN_PROGRESS = 0x00000040, /** Cached device */ DCB_DEV_CACHE = 0x00000020 , /** Serial commands */ DCB_DEV_SERIAL_CMD = 0x00000010, /** Remote device */ DCB_DEV_REMOTE = 0x00000008, /* Removable media */ DCB_DEV_REMOVABLE = 0x00000004 , DCB_DEV_REMOVABLE_BIT = 2, /** Writeable media */ DCB_DEV_WRITEABLE = 0x00000002, /** Int 13h drive */ DCB_DEV_INT13_DRIVE = 0x00000001, }; enum DCB_DEV2_FLAGS { DCB_DEV2_THREAD_LOCK = 0x00000001, DCB_DEV2_THREAD_LOCK_BIT = 0, DCB_DEV2_ATAPI_DEVICE = 0x00000002, DCB_DEV2_ATAPI_DEVICE_BIT = 1, DCB_DEV2_DMF_DISK = 0x00000004, /* indicates current media is DMF */ DCB_DEV2_DMF_DISK_BIT = 2, DCB_DEV2_I13_COPY_PROT = 0x00000008,/* indicates int 13 copy protection */ DCB_DEV2_I13_COPY_PROT_BIT = 3, /* access to one of the floppies */ DCB_DEV2_FAIL_FORMAT = 0x00000010, /* indicates that we cannot allow format*/ DCB_DEV2_FAIL_FORMAT_BIT = 4, DCB_DEV2_FLOPTICAL = 0x00000020, /* indicates device is floptical */ DCB_DEV2_FLOPTICAL_BIT = 5, }; enum DCB_TYPE { DCB_type_disk = 0x00, /* All Direct Access Devices -- non-removable */ DCB_type_tape = 0x01, /* Sequencial Access Devices */ DCB_type_printer = 0x02, /* Printer Device */ DCB_type_processor = 0x03, /* Processor type device */ DCB_type_worm = 0x04, /* Write Once Read Many Device */ DCB_type_cdrom = 0x05, /* CD ROM Device */ DCB_type_scanner = 0x06, /* Scanner Device */ DCB_type_optical_memory = 0x07, /* some Optical disk */ DCB_type_changer = 0x08, /* Changer device e.g. juke box */ DCB_type_comm = 0x09, /* Communication devices */ DCB_type_floppy = 0x0A, /* devices like floppy */ DCB_type_optical_nec = 0x84 /* NEC 5.25" optical disk */ }; enum DCB_dmd_flags { DCB_dmd_srb_cdb = 0x00000001, /* there must be an srb and cdb for */ /* each ior. */ DCB_dmd_rsrv_1 = 0x00000002, /* reserved - must be zero. */ DCB_dmd_logical = 0x00000004, /* media address must be logical and*/ /* dcb must be for a logical device.*/ DCB_dmd_physical = 0x00000008, /* media adresses must be physical */ /* and dcb must be for a physical */ /* device. */ DCB_dmd_small_memory = 0x00000010, /* data buffers must reside in */ /* in low 16M. */ DCB_dmd_rsrv_2 = 0x00000020, /* reserved - must be zero. */ DCB_dmd_rsrv_3 = 0x00000040, /* reserved - must be zero. */ DCB_dmd_rsrv_4 = 0x00000080, /* reserved - must be zero. */ DCB_dmd_not_512 = 0x00000100, /* sector size on the media is not */ /* 512 bytes */ DCB_dmd_word_align = 0x00000200, /* data buffers must be word */ /* aligned. */ DCB_dmd_dword_align = 0x00000400, /* data buffers must be double word */ /* aligned. */ DCB_dmd_phys_sgd = 0x00000800, /* scatter/gather descriptors must */ /* contain physical addresses (they */ /* will contain linear addresses if */ /* this demand bit is not set). */ DCB_dmd_phys_sgd_ptr = 0x00001000, /* the pointer to the first */ /* scatter/gather descriptor */ /* (IOR_sgd_lin_phys) must be a */ /* physical address (it will be a */ /* linear addresses if this demand */ /* bit is not set). */ /* If foll. bit set, single floppy drive system -- voltrack needs to do * the toggling between A: and B: when accesses to made to these drive * letters. */ DCB_dmd_do_a_b_toggling = 0x00002000, DCB_dmd_query_remov = 0x00004000, /* lower level must be called to */ /* check if media is removeable/has */ /* changed. */ DCB_dmd_request_sns = 0x00008000, /* port driver cannot perform autosense */ DCB_dmd_lock_unlock_media = 0x00010000, /* media supports software locking */ DCB_dmd_load_eject_media = 0x00020000, /* media supports electronic eject */ DCB_dmd_clear_media_chg = 0x00040000, /* command to clear media change */ DCB_dmd_serialize_bit = 19, /* layer requires request serialization */ DCB_dmd_serialize = 1 << DCB_dmd_serialize_bit, DCB_dmd_prot_mode = 0x00100000, /* override real mode checks for */ /* this device i.e. ATAPI cdrom */ DCB_dmd_no_xclusive = 0x00200000, /* indicates exclusive access is */ /* not required for abs write */ DCB_dmd_pageability = 0x00400000, /* indicates that access to this volume */ /* can cause paging */ DCB_dmd_rsrv = DCB_dmd_rsrv_1+DCB_dmd_rsrv_2+DCB_dmd_rsrv_3+DCB_dmd_rsrv_4 }; // DDB ================ typedef _Packed struct DDB { // uint32_t DDB_phys_addr; // Physical address of ddb uint32_t DDB_Next_DDB; // next DDB on DVT_DDB chain uint32_t DDB_Next_DDB_init; // next DDB on DVT_DDB_init chain uint32_t DDB_dcb_ptr; // address of first DCB owned by this DDB uint8_t DDB_number_buses; // # of buses supported by the adapter uint8_t DDB_ios_flags; // IOS flags; see below uint16_t DDB_sig; // DDB signature; also padding void* DDB_dvt; // address of this DDB's DVT void* DDB_devnode_ptr; // address of devnode for device void* DDB_reserved; // reserved; must be zero } DDB , *PDDB; // DRP ================ typedef _Packed struct DRP { char DRP_eyecatch_str[8]; // eye catcher string uint32_t DRP_LGN; // load group number; see below void* DRP_aer; // addr of asynchronous event routine struct ILB *DRP_ilb; // address of ILB; see below char DRP_ascii_name[16]; // driver name; see below uint8_t DRP_revision; // driver revision uint32_t DRP_feature_code; // feature code; see below uint16_t DRP_if_requirements; // I/F requirements; see below uint8_t DRP_bus_type; // type of I/O bus; see below uint16_t DRP_reg_result; // registration result; see below uint32_t DRP_reference_data; // data to pass with AEP_INITIALIZE uint8_t DRP_reserved1[2]; // reserved uint32_t DRP_reserved2[1]; // reserved; must be zero } DRP, *PDRP; enum DRP_IF { DRP_IF_ISA = 0x01, DRP_IF_EISA = 0x02, DRP_IF_MCA = 0x04, DRP_IF_STD = 0xFF }; enum DRP_LGN { /* Installable File System layer. */ DRP_FSD = 1 << 0x02, /** Other port drivers. */ DRP_MISC_PD = 1 << 0x13 }; enum DRP_reg_result { /* Driver should remain resident */ DRP_REMAIN_RESIDENT = 1, /* Driver should minimize */ DRP_MINIMIZE = 2, /* Driver should not load */ DRP_ABORT = 3, /* bad layer number - abort driver */ DRP_INVALID_LAYER = 4 }; // ILB ================== typedef _Packed struct ILB { /* service routine */ void __cdecl (*ILB_service)(struct ISP *pisp); void __cdecl (*ILB_dprintf)(const char *format, ...); /** waits for 1/10 seconds. */ void __cdecl (*ILB_Wait_10th_Sec)(void); void* ILB_internal_request; // addr of request routine void* ILB_io_criteria_rtn; // addr of IOR criteria routine void* ILB_int_io_criteria_rtn; // addr of IOP criteria routine uint32_t ILB_dvt; // offset to addr of driver's DVT uint32_t ILB_ios_mem_virt; // addr of IOS memory pool void __cdecl (*ILB_enqueue_iop)(struct IOP *iop, struct DCB *dcb); struct IOP * __cdecl (*ILB_dequeue_iop)(struct DCB *dcb); uint32_t ILB_reserved_1; // reserved; must be zero uint32_t ILB_reserved_2; // reserved; must be zero uint16_t ILB_flags; // flags uint8_t ILB_driver_numb; // number of calls to AEP_INITIALIZE uint8_t ILB_reserved_3; // reserved; must be zero } ILB, *PILB; // IOR ================= typedef _Packed struct type_sdeffsd_req_usage { /* */ uint16_t _IOR_ioctl_drive; uint16_t _IOR_ioctl_function ; uint32_t _IOR_ioctl_control_param ; uint32_t _IOR_ioctl_buffer_ptr; uint32_t _IOR_ioctl_client_params; uint32_t _IOR_ioctl_return; } _type_sdeffsd_req_usage; typedef _Packed union urequestor_usage { /* */ uint32_t _IOR_requestor_usage[5]; struct type_sdeffsd_req_usage sdeffsd_req_usage; } _urequestor_usage; typedef void (* CMDCPLT)(void); typedef _Packed struct _IOR { uint32_t IOR_next; // client link; see below uint16_t IOR_func; // function; see below uint16_t IOR_status; // request status; see below uint32_t IOR_flags; // request flags; see below CMDCPLT IOR_callback; // address of callback; see below uint64_t IOR_start_addr; // starting address; see below uint32_t IOR_xfer_count; // # of sectors/bytes; see below void* IOR_buffer_ptr; // client buffer; see below uint32_t IOR_private_client; // BlockDev/IOS client reserved uint32_t IOR_private_IOS; // reserved space for IOS uint32_t IOR_private_port; // private area for port driver union urequestor_usage _ureq; // requestor usage; see below uint32_t IOR_req_req_handle; // request handle; see below uint32_t IOR_req_vol_handle; // media handle; see below uint32_t IOR_sgd_lin_phys; // first physical SGD; see below uint8_t IOR_num_sgds; // number of physical SGDs uint8_t IOR_vol_designtr; // drive letter; see below uint16_t IOR_ios_private_1; // reserved by IOS to force alignment uint32_t IOR_reserved_2[2]; // reserved for internal use } IOR, *PIOR; /** command codes for IOR_func as defined above */ enum IOR_funcs { /* ** IOR_READ ** ** Function: ** ** Reads the # of sectors/bytes as specified in IOR_xfer_count. ** See PDK documentation for specifics of parameter setting. ** ** ** Notes: ** */ IOR_READ = 0x00, /* ** IOR_WRITE ** ** Function: ** ** Writes the # of sectors/bytes as specified in IOR_xfer_count. ** See PDK documentation for specifics of parameter setting. ** ** Notes: ** */ IOR_WRITE = 0x01, /* ** IOR_VERIFY ** ** Function: ** ** Verifies the # of sectors/bytes as specified in IOR_xfer_count. ** ** Notes: ** */ IOR_VERIFY = 0x02, /* verify data on device */ /* ** IOR_CANCEL ** ** Function: ** ** Cancels the IOR referenced in ... ** ** Notes: ** ** Currently not supported in Chicago ** */ IOR_CANCEL = 0x03, /* ** IOR_WRITEV ** ** Function: ** ** Writes and verifies the # of sectors/bytes as specified in IOR_xfer_count. ** ** Notes: ** ** Some hardware (IDE, for example) does not support this function. ** */ IOR_WRITEV = 0x04, /* ** IOR_MEDIA_CHECK ** ** Function: ** ** Checks to see if media has changed, and returns status in IOR_status. ** ** Notes: ** ** Obsolete. Use MEDIA_CHECK_RESET below ** */ IOR_MEDIA_CHECK = 0x05, /* ** IOR_MEDIA_CHECK_RESET ** ** Function: ** ** Checks to see if media has changed, and returns status in IOR_status. ** ** Notes: ** */ IOR_MEDIA_CHECK_RESET = 0x06, /* ** IOR_LOAD_MEDIA ** ** Function: ** ** Performs a LOAD MEDIA operation on removable drives. ** ** Notes: ** */ IOR_LOAD_MEDIA = 0x07, /* ** IOR_EJECT_MEDIA ** ** Function: ** ** Performs an EJECT MEDIA operation on removable drives. ** ** Notes: ** ** For disk and CD-ROM devices, applications are queried before eject, ** and the lock count is checked for zero. If one of these checks fails, ** the user is queried to see if he wants to proceed. */ IOR_EJECT_MEDIA = 0x08, /* ** IOR_LOCK_MEDIA ** ** Function: ** ** Performs a LOCK MEDIA operation on removable drives. ** ** Notes: ** ** LOCK and UNLOCK MEDIA calls must be synchronized, as a depth counter is ** maintained by IOS. */ IOR_LOCK_MEDIA = 0x09, /* ** IOR_UNLOCK_MEDIA ** ** Function: ** ** Performs an UNLOCK MEDIA operation on removable drives. ** ** Notes: ** ** LOCK and UNLOCK MEDIA calls must be synchronized, as a depth counter is ** maintained by IOS. UNLOCK MEDIA is delayed by about 5 seconds. */ IOR_UNLOCK_MEDIA = 0x0A, /* ** IOR_REQUEST_SENSE ** ** Function: ** ** Performs an REQUEST SENSE operation on removable drives. ** ** Notes: ** ** Currently supported for SCSI devices only. ** */ IOR_REQUEST_SENSE = 0x0B, /* ** IOR_COMPUTE_GEOM ** ** Function: ** ** Results in a reexamination of volume and device characteristics. ** ** Notes: ** ** When this command is received, each IOS layer assumes the device has ** changed, and performs whatever initialization required. For example, ** the disk TSD will reexamine the partitions of a device. ** */ IOR_COMPUTE_GEOM = 0x0C, /* ** IOR_GEN_IOCTL ** ** Function: ** ** Function permits device-specific IOCtl's to be issued to IOS drivers. ** Also supports standard Int 21 function 44xx DOS IOCtl's. See CDIOCTL.H ** for examples of CD IOCtl's. ** ** aliasing for fields used by IOCTL's - ** this section gives both the normal and IOCTL names for the fields ** ** IOR_ioctl_drive - BX from 16 bit IOCTL - usually a 1 based drive number ** IOR_ioctl_function - AX from 16 bit IOCTL ** IOR_ioctl_handle - useful handle? or original? ** IOR_ioctl_control_param - CX zero extended to ULONG ** IOR_ioctl_buffer_ptr - DS:DX mapped flat general buffer from the IOCTL ** IOR_ioctl_client_params - a pointer to the parameters passed in from ** the calling application the IORF_16BIT_IOCTL flag must be used to ** determine the structure type. If it is a 16 bit IOCTL, the pointer ** will be to the CLIENT_REGS structure. 32 bit is as of yet undef'ed ** IOR_ioctl_return - return value to be mapped to the IOCTL caller on exit ** IOR_ioctl_buffer_length - size of buffer pointed to by ** IOR_ioctl_buffer_ptr (not used by int 21 440d IOCTL calls) ** ** Notes: ** */ IOR_GEN_IOCTL = 0x0D, /* ** IOR_FORMAT ** ** Function: ** ** Allows issuance of a low level format packet as defined in the int 13 ** specification. ** ** Notes: ** ** IOR_format_address_field => low level sector map ** See IOP.H IOP_FORMAT_XXX fields for additional information. */ IOR_FORMAT = 0x0E, /* ** IOR_SCSI_PASS_THROUGH ** ** Function: ** ** Each layer passes this request down with modification to the SCSI port ** driver. ** ** Notes: ** ** The IOR must contain a pointer to a valid SRB. Also, "ebx" must point ** to the BDD portion of the DCB when IOS_SendCommand is called with a ** passthrough request. */ IOR_SCSI_PASS_THROUGH = 0x0F, /* ** IOR_CLEAR_QUEUE ** ** Function: ** ** Callback of request indicates all requests issued prior to this request ** have been completed. ** ** Notes: */ IOR_CLEAR_QUEUE = 0x10, /* ** IOR_DOS_RESET ** ** Function: ** ** Issued in response to an int 13 reset by the int 13 vxd ** ** Notes: ** ** Currently used only by and for the IOS floppy driver. */ IOR_DOS_RESET = 0x11, /* ** IOR_SCSI_REQUEST ** ** Function: ** ** generic function that indicates the request is for SCSI. ** ** Notes: ** ** SRB field in IOR must be valid. Normally used by IOS layers to send ** internal requests to SCSI devices. */ IOR_SCSI_REQUEST = 0x12, /* ** IOR_SET_WRITE_STATUS ** ** Function: ** ** results in the correct setting of DCB_DEV_WRITABLE flag in the DCB if ** SUCCESS status is returned. ** ** Notes: ** ** Currently only supported by the IOS floppy driver. */ IOR_SET_WRITE_STATUS = 0x22, /* ** IOR_RESTART_QUEUE ** ** Function: ** ** "Placeholder" function that results in restarting of the queue provided ** by the IOS queuing services. Has no other effect. ** ** Notes: ** ** Should be sent after the DCB_QUEUE_FREEZE field has been decremented to ** zero. */ IOR_RESTART_QUEUE = 0x23, /* ** IOR_ABORT_QUEUE ** ** Function: ** ** Causes each layer to call back each queued request with status of ** IORS_CANCELED ** ** Notes: ** */ IOR_ABORT_QUEUE = 0x24, /* ** IOR_SPIN_DOWN ** ** Function: ** ** Causes the specified drive to be spun down. ** ** Notes: ** */ IOR_SPIN_DOWN = 0x25, /* ** IOR_SPIN_UP ** ** Function: ** ** Causes the specified drive to be spun up. ** ** Notes: ** */ IOR_SPIN_UP = 0x26, /* ** IOR_FLUSH_DRIVE ** ** Function: ** ** Causes layer drivers to flush out dirty data. ** ** Notes: ** ** This is a synchronous function and should not be called at ** event/interrupt time. ** */ IOR_FLUSH_DRIVE = 0x27, /* ** IOR_FLUSH_DRIVE_AND_DISCARD ** ** Function: ** ** Causes layer drivers to flush out dirty data and then dicard cached ** data. ** ** Notes: ** ** This is a synchronous function and should not be called at ** event/interrupt time. ** */ IOR_FLUSH_DRIVE_AND_DISCARD = 0x28, /* ** IOR_FSD_EXT ** ** Function: ** ** Sends private command from an IOS client to the FSD extension ** layer (DRP_FSD_EXT_1 or DRP_FSD_EXT_2) such as a Compressed ** Volume Manager (CVM). ** ** Notes: ** ** This call is similar in intent and usage to IOR_GEN_IOCTL; ** however, it can be used in the swapper path, so, in general, ** the handling driver should not touch pageable code or data. ** */ IOR_FSD_EXT = 0x29, /* ** IOR_FLOPTICAL_MODE_SENSE ** ** Function: ** ** Issues MODE SENSE command to page 0x2e, as is required to indicate to the ** floptical that it is supported. ** ** Notes: ** ** Don't use this command, as it is used by the system. ** */ IOR_FLOPTICAL_MODE_SENSE = 0x2A, }; /** IOR status codes for IOR_status */ enum IOR_STATUS { IORS_SUCCESS = 0x00, /* command completed successfully */ IORS_SUCCESS_WITH_RETRY = 0x01, /* successful, but retries required */ IORS_SUCCESS_WITH_ECC = 0x02, /* ditto, but with ECC */ IORS_INVALID_SECTOR = 0x10, /* old blockdev error code for */ /* requests on an invalid sector */ /* number */ IORS_CANCELED = 0x11, /* command was canceled */ IORS_CMD_IN_PROGRESS = 0x12, /* command is in progress, and can't be canceled */ IORS_INVALID_CMD_PTR = 0x13, /* cancel of an invalid command */ IORS_MEDIA_ERROR = 0x14, /* media failure */ IORS_DEVICE_ERROR = 0x15, /* error on recalib. drive, etc. */ IORS_INVALID_COMMAND = 0x16, /* Command not supported or invalid */ IORS_NO_DEVICE = 0x17, /* physical or logical device nonexistant */ IORS_NO_MEDIA = 0x18, /* media removed from device */ IORS_UNCERTAIN_MEDIA = 0x19, /* media may have changed */ IORS_UNREC_ERROR = 0x1A, /* un-recoverable error */ IORS_HW_FAILURE = 0x1B, /* general hardware failure */ IORS_UNFORMATTED_MEDIA = 0x1C, /* unformatted media */ IORS_MEMORY_ERROR = 0x1D, /* error allocating DMA buffer space for I/O */ IORS_TIME_OUT = 0x1E, /* device timed out */ IORS_WRITE_PROTECT = 0x1F, /* write protect error */ IORS_NOT_READY = 0x20, /* device not ready */ IORS_BUSY = 0x21, /* device is busy */ IORS_VOL_NOT_LOCKED = 0x22, /* volume received unlock without lk*/ IORS_VOL_LOCKED = 0x23, /* eject received with drive locked */ IORS_VOL_NOT_REMOVABLE = 0x24, /* removable request to non-remov drive */ IORS_VOL_IN_USE = 0x25, /* volume is in use - used for eject*/ IORS_LOCK_COUNT_EXCEEDED = 0x26, /* volume lock count exceeded */ IORS_VALID_EJECT_FAILED = 0x27, /* eject command was not accepted */ IORS_ILLEGAL_ACCESS_MODE = 0x28, /* cdrom read on audio or attempt */ /* play on data */ IORS_LOCK_VIOLATION = 0x29, /* illegal access to locked device */ IORS_WRONG_MEDIA = 0x2a, /* wrong media in drive */ IORS_OUT_OF_SPACE = 0x2b, /* no space on media */ IORS_BIG_IO_BREAKUP_FAILED = 0x2c,/* attempt to split big I/O barfed */ IORS_ERROR_DESIGNTR = 0x10, /* bit indicating error occurred */ IORS_INVALID_PARM = IORS_ERROR_DESIGNTR, /* bit indicating error occurred */ }; enum IOR_FLAGS { IORF_HIGH_PRIORITY_BIT=0, /* binary priority indication */ IORF_HIGH_PRIORITY = (1 << IORF_HIGH_PRIORITY_BIT), /* 0x0001 */ IORF_SCATTER_GATHER_BIT=1, /* bit indicating BDCB physical SGD */ /* list present */ IORF_SCATTER_GATHER = (1 << IORF_SCATTER_GATHER_BIT), /* 0x0002 */ IORF_DONT_CACHE_BIT=2, /* bit indicating that the BDCB data*/ /* should not be cached */ IORF_DONT_CACHE = (1 << IORF_DONT_CACHE_BIT), /* 0x0004 */ IORF_BYPASS_VOLTRK=0x0008, /* request will not be volume trked */ IORF_BYPASS_VOLTRK_BIT=3, IORF_16BIT_IOCTL=0x0010, /* if true, 16 bit IOCTL calling */ /* app, else 32 bit ioctl */ IORF_16BIT_IOCTL_BIT=4, IORF_SWAPPER_IO=0x0020, /* request is from the swapper */ IORF_SWAPPER_IO_BIT=5, IORF_DOUBLE_BUFFER=0x0040, /* indicates that the request is to */ /* be completed via double */ /* buffering. client must */ /* ensure that both the sgd buffer */ /* pointers and IOR_sgd_lin_phys */ /* are virtual pointers. */ IORF_DOUBLE_BUFFER_BIT=6, IORF_SYNC_CMD_DONE=0x0080, /* used by IOS only to indicate */ /* completion */ /* of synchronous command */ IORF_SYNC_CMD_DONE_BIT=7, IORF_SYNC_COMMAND=0x0100, /* indicates synchronous command */ /* (complete before return from IOS */ IORF_SYNC_COMMAND_BIT=8, IORF_CHAR_COMMAND=0x0200, /* indicates transfer counts and */ /* scatter/gather buffer sizes are */ /* byte values */ IORF_CHAR_COMMAND_BIT=9, IORF_VERSION_002=0x0400, /* indicates use of extended BCB */ /* (IOR) format for request */ IORF_VERSION_002_BIT=10, IORF_BYPASS_QUEUE=0x0800, /* request should bypass IOS queuing*/ /* internal IOS driver use only */ IORF_BYPASS_QUEUE_BIT=11, IORF_BLOCKDEV_EMULATE=0x1000, /* this request started as a BCB */ IORF_BLOCKDEV_EMULATE_BIT=12, IORF_POSTPONED_VOL_OPS=0x2000, IORF_POSTPONED_VOL_OPS_BIT=13, IORF_INHIBIT_GEOM_RECOMPUTE=0x4000, IORF_INHIBIT_GEOM_RECOMPUTE_BIT=14, /* force inhibit of device geometry */ /* recomputation. */ IORF_SRB_VALID=0x8000, /* indicates that IOP_srb points to */ IORF_SRB_VALID_BIT=15, /* a valid SRB */ IORF_BYPASS_A_B=0x10000, /* indicates that VOLTRK should */ IOFR_BYPASS_A_B_BIT=16, /* bypass AB check */ IORF_QUIET_VOLTRK=0x20000, /* indicates that volume tracking */ IORF_QUIET_VOLTRL_BIT=17, /* just return error when wrong */ /* media in drive (no dialog box) */ IORF_AUDIO_DATA_READ=0x40000, /* indicates an audio data read */ IORF_AUDIO_DATA_READ_BIT=18, IORF_LOGICAL_START_SECTOR=0x80000, IORF_LOGICAL_START_SECTOR_BIT=19, /* IOR_start_addr is logical */ IORF_PARTITION_BIAS_ADDED=0x100000, IORF_PARTITION_BIAS_ADDED_BIT=20, /* set by TSD only to indicate that */ /* it has added in the bias, as req'd */ /* by IORF_LOGICAL_START_SECTOR */ IORF_DATA_IN_BIT=21, /* indicates a data read operation */ IORF_DATA_IN = (1 << IORF_DATA_IN_BIT), IORF_DATA_OUT_BIT=22, /* indicates a data write operation */ IORF_DATA_OUT = (1 << IORF_DATA_OUT_BIT), IORF_VOL_RETRY_BIT=23, /* indicates volume tracking retried*/ IORF_VOL_RETRY = (1 << IORF_VOL_RETRY_BIT), /* request (internal use only) */ IORF_NO_COMPRESS_BIT=24, /* do not compress data */ IORF_NO_COMPRESS = (1 << IORF_NO_COMPRESS_BIT), IORF_DIRECT_IO_BIT=25, /* E.g., INT 25h or INT 26h */ IORF_DIRECT_IO = (1 << IORF_DIRECT_IO_BIT), IORF_PHYS_SGDS_BIT=26, IORF_PHYS_SGDS = (1 << IORF_PHYS_SGDS_BIT), /* indicates IOR_sgd_lin_phys valid */ IORF_IO_TOO_BIG_BIT=27, IORF_IO_TOO_BIG = (1 << IORF_IO_TOO_BIG_BIT), /* indicates I/O is too big for */ /* single pass (set by IOS criteria*/ /* code). */ IORF_WIN32_BIT=28, IORF_WIN32 = (1 << IORF_WIN32_BIT), /* indicates I/O is from 32 bit API */ IORF_CHAR_DEVICE_BIT=29, IORF_CHAR_DEVICE = (1 << IORF_CHAR_DEVICE_BIT), IORF_PHYS_CMD_BIT=30, /* indicates I/O is for a physical */ /* device */ IORF_PHYS_CMD = (1 << IORF_PHYS_CMD_BIT), IORF_IDE_RESERVED_BIT=31, /* indicates I/O is for a physical */ /* device */ IORF_IDE_RESERVED = (1 << IORF_IDE_RESERVED_BIT) }; // IOP ================= #define IOP_CALLBACK_TABLE_DEPTH 6 typedef _Packed struct IOP_callback_entry { IO_callback IOP_CB_address; /* call back address */ uint32_t IOP_CB_ref_data; /* pointer to callback ref data */ } IOP_callback_entry; typedef _Packed struct IOP { uint32_t IOP_physical; // physical address of IOP struct DCB *IOP_physical_dcb; // address of physical DCB struct DCB *IOP_original_dcb; // address of DCB designated by IOR uint16_t IOP_timer; // Request Control Block (RCB) current // timeout value uint16_t IOP_timer_orig; // original timeout value DCB_cd_entry* IOP_calldown_ptr; // address of next calldown routine IOP_callback_entry* IOP_callback_ptr; // address of current callback address uint32_t IOP_voltrk_private; // for use by volume tracking uint32_t IOP_Thread_Handle; // handle of thread originating // the I/O request uint32_t IOP_srb; // used by SCSI'izers to pass SRB // address to next layer uint32_t IOP_reserved[2]; // reserved; must be zero IOP_callback_entry IOP_callback_table[IOP_CALLBACK_TABLE_DEPTH]; // RCB_CallBackTable uint8_t IOP_format_head; // low level format data uint8_t IOP_format_xfer_rate; uint16_t IOP_format_track; uint32_t IOP_format_num_sectors; IOR IOP_ior; // I/O request descriptor } IOP, *PIOP; /** Let lower levels continue processing this IOP. */ static void IopCalldown(IOP* iop) { // Get who is supposed to be next driver in the chain iop->IOP_calldown_ptr = iop->IOP_calldown_ptr->DCB_cd_next; // Call it iop->IOP_calldown_ptr->DCB_cd_io_address(iop); } /** Finish processing this IOP, and call back previous levels. */ static void IopCallback(IOP* iop) { iop->IOP_callback_ptr -= 1; iop->IOP_callback_ptr->IOP_CB_address(iop); } // ISP ================= typedef uint16_t IspResult; // unspecified error codes, but zero = no error typedef _Packed struct ISP { uint16_t ISP_func; // function to be performed; see below IspResult ISP_result; // result: zero = no error } ISP, *PISP; enum ISP_funcs { /* create ddb */ ISP_CREATE_DDB = 0, /* create dcb (Physical) */ ISP_CREATE_DCB = 1, /* create iop */ ISP_CREATE_IOP = 2, /* allocate memory */ ISP_ALLOC_MEM = 3, /* deallocate memory */ ISP_DEALLOC_MEM = 4, /** insert entry in calldown table */ ISP_INSERT_CALLDOWN = 5, /* associate dcb & relative drive # */ ISP_ASSOCIATE_DCB = 6, /* return DCB for logical volume */ ISP_GET_DCB = 7, /** get first/next DCB */ ISP_GET_FIRST_NEXT_DCB = 8, /* deallocate DDB */ ISP_DEALLOC_DDB = 9, /* destroy DCB */ ISP_DESTROY_DCB = 10, /* ask for logical-to-physical info */ ISP_QUERY_MATCHING_DCBS = 11, /* ask if we can remove a device */ ISP_QUERY_REMOVE_DCB = 12, /* indicate that a device has been removed */ ISP_DEVICE_REMOVED = 13, /* indicate that a device has arrived */ ISP_DEVICE_ARRIVED = 14, /* disassociate dcb & drive # */ ISP_DISASSOCIATE_DCB = 15, /* pick a drive letter */ ISP_DRIVE_LETTER_PICK = 16, /* read registry */ ISP_REGISTRY_READ = 17, /* find LDM entry */ ISP_FIND_LDM_ENTRY = 18, /* delete LDM entry */ ISP_DELETE_LDM_ENTRY = 19, /* broadcast an AEP from a driver */ ISP_BROADCAST_AEP = 20 }; typedef _Packed struct ISP_dcb_create { // ISP ISP_dcb_hdr; // Standard header uint16_t ISP_dcb_size; // size of DCB to create, in bytes uint32_t ISP_dcb_ptr; // address of DCB uint8_t ISP_pad1[2]; // Pad to DWORD boundary } ISP_dcb_create, *PISP_dcb_create; static PDCB IspCreateDcb(ILB* ilb, uint16_t size) { ISP_dcb_create isp = {{ISP_CREATE_DCB}}; isp.ISP_dcb_size = size; ilb->ILB_service((PISP)&isp); return isp.ISP_dcb_hdr.ISP_result != 0 ? NULL : (PDCB) isp.ISP_dcb_ptr; } typedef _Packed struct ISP_ddb_create { // ISP ISP_ddb_hdr; // Standard header uint16_t ISP_ddb_size; // size of DDB to create, in bytes uint32_t ISP_ddb_ptr; // address of DDB uint8_t ISP_ddb_flags; // flags; see below uint8_t ISP_pad0[1]; // Pad to DWORD boundary } ISP_ddb_create, *PISP_ddb_create; static PDDB IspCreateDdb(ILB* ilb, uint16_t size) { ISP_ddb_create isp = {{ISP_CREATE_DDB}}; isp.ISP_ddb_size = size; ilb->ILB_service((PISP)&isp); return isp.ISP_ddb_hdr.ISP_result != 0 ? NULL : (PDDB) isp.ISP_ddb_ptr; } typedef _Packed struct ISP_calldown_insert { ISP ISP_i_cd_hdr; // Standard header uint32_t ISP_i_cd_dcb; // address of DCB void* ISP_i_cd_req; // address of request routine uint32_t ISP_i_cd_ddb; // address of DDB uint16_t ISP_i_cd_expan_len; // size of IOP expansion required by this driver uint32_t ISP_i_cd_flags; // demand flags uint8_t ISP_i_cd_lgn; // load group number; typically same as AEP_lgn uint8_t ISP_pad4[1]; // Pad to DWORD boundary } ISP_calldown_insert, *PISP_calldown_insert; static IspResult IspInsertCalldown(ILB* ilb, PDCB dcb, void (*calldown)(PIOP), PDDB ddb, uint16_t expand_len, uint32_t flags, uint8_t lgn) { ISP_calldown_insert isp = {{ISP_INSERT_CALLDOWN}}; isp.ISP_i_cd_dcb = (uint32_t) dcb; isp.ISP_i_cd_req = calldown; isp.ISP_i_cd_ddb = (uint32_t) ddb; isp.ISP_i_cd_expan_len = expand_len; isp.ISP_i_cd_flags = flags; isp.ISP_i_cd_lgn = lgn; ilb->ILB_service((PISP)&isp); return isp.ISP_i_cd_hdr.ISP_result; } typedef _Packed struct ISP_AEP_BROADCAST { ISP ISP_baep_hdr; // Standard header void* ISP_baep_paep; // address of AEP to broadcast } ISP_AEP_BROADCAST,*PISP_AEP_BROADCAST; static IspResult IspBroadcastAep(ILB* ilb, PAEP paep) { ISP_AEP_BROADCAST isp = {{ISP_BROADCAST_AEP}}; isp.ISP_baep_paep = paep; ilb->ILB_service((PISP)&isp); return isp.ISP_baep_hdr.ISP_result; } // SGD ========= typedef struct _SGD { uint32_t SG_buff_ptr; // address of data buffer; see below uint32_t SG_buff_size; // number of bytes to transfer } SGD, *PSGD; #endif // IOS_H