From: Shamus Hammons Date: Thu, 25 Mar 2004 21:02:40 +0000 (+0000) Subject: New OS dependent CDROM code X-Git-Tag: 1.0.7~35 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8791af3d267761a4d63f0950a2668f9a689b7167;p=virtualjaguar New OS dependent CDROM code --- diff --git a/src/cdintf.cpp b/src/cdintf.cpp new file mode 100644 index 0000000..4f8924f --- /dev/null +++ b/src/cdintf.cpp @@ -0,0 +1,41 @@ +// +// OS agnostic CDROM interface functions +// +// by James L. Hammons +// +// This file is basically a shell to keep the front-end clean and also pull in the +// appropriate back-end code depending on which target is being compiled for. +// + +#include "cdintf.h" // Every OS has to implement these + +/*#ifdef __GCCWIN32__ +#include "cdintf_win32.cpp" +#endif + +#ifdef __GCCUNIX__ +#ifdef _OSX_ + +#include "cdintf_osx.cpp" + +#else +#include "cdintf_linux.cpp" + +#endif +#endif//*/ + +#if defined(__GCCWIN32__) + +#include "cdintf_win32.cpp" + +#elif defined(__GCCUNIX__) +#if defined(_OSX_) + +#include "cdintf_osx.cpp" + +#else + +#include "cdintf_linux.cpp" + +#endif +#endif diff --git a/src/cdintf_linux.cpp b/src/cdintf_linux.cpp new file mode 100644 index 0000000..c418df5 --- /dev/null +++ b/src/cdintf_linux.cpp @@ -0,0 +1,5 @@ +// +// OS specific CDROM interface (linux) +// +// by James L. Hammons +// diff --git a/src/cdintf_osx.cpp b/src/cdintf_osx.cpp new file mode 100644 index 0000000..1ca290e --- /dev/null +++ b/src/cdintf_osx.cpp @@ -0,0 +1,5 @@ +// +// OS specific CDROM interface (Mac OS X) +// +// by ? +// diff --git a/src/cdintf_win32.cpp b/src/cdintf_win32.cpp new file mode 100644 index 0000000..b075af5 --- /dev/null +++ b/src/cdintf_win32.cpp @@ -0,0 +1,412 @@ +// +// OS specific CDROM interface (Win32) +// +// by James L. Hammons +// + +// OS dependent CDROM stuffola +#include +#include +#include "wnaspi32.h" +#include "scsidefs.h" +// End OS dependent + +#include "log.h" + +using namespace std; + +// Local variables + +DWORD remain = 0, sector = 0; +BYTE cdBuf[2532 * 10]; + +// Private function prototypes + + +HINSTANCE WNASPI32_handle = NULL; //Handle to ASPI for Win32 (WNASPI.DLL) +//WNASPI.DLL functions +DWORD (*ASPI_GetASPI32SupportInfo)(VOID); +DWORD (*ASPI_SendASPI32Command)(LPSRB); +//BOOL (*ASPI_GetASPI32Buffer)(PASPI32BUFF); +//BOOL (*ASPI_FreeASPI32Buffer)(PASPI32BUFF); +//BOOL (*ASPI_TranslateASPI32Address)(PDWORD, PDWORD); + +byte DataBuf[2352]; //Buffer for holding data to/from drive +//************************************************************ +//End of globals + +// +// Load the WNASPI32.DLL and import the required functions, then initialise +// Win ASPI 32. +// +BOOL InitASPI() +{ + DWORD dwSupportInfo; + SRB_GetSetTimeouts srbTimeouts; + + WNASPI32_handle = LoadLibrary("WNASPI32"); //WNASPI32.DLL + + if (!WNASPI32_handle) + { + WriteLog("CDINTF: Could not load WNASPI32.DLL\n"); + return FALSE; + }; + + /* + ** Get the ASPI entry points. Note that only two functions are mandatory: + ** GetASPI32SupportInfo and SendASPI32Command. The code will run if the + ** others are not present. + */ + ASPI_GetASPI32SupportInfo = (DWORD (*)(void))GetProcAddress(WNASPI32_handle, "GetASPI32SupportInfo"); + ASPI_SendASPI32Command = (DWORD (*)(LPSRB))GetProcAddress(WNASPI32_handle, "SendASPI32Command"); + //ASPI_GetASPI32Buffer = (BOOL (*)(PASPI32BUFF))GetProcAddress(WNASPI32_handle, "GetASPI32Buffer"); + //ASPI_FreeASPI32Buffer = (BOOL (*)(PASPI32BUFF))GetProcAddress(WNASPI32_handle, "FreeASPI32Buffer"); + //ASPI_TranslateASPI32Address = (BOOL (*)(PDWORD, PDWORD))GetProcAddress(WNASPI32_handle, "TranslateASPI32Address"); + + //Check if the 2 functions were imported. + if(!ASPI_GetASPI32SupportInfo || !ASPI_SendASPI32Command) + { + WriteLog("Could not import GetASPI32SupportInfo & SendASPI32Command functions from WNASPI32.DLL\n"); + return FALSE; + }; + + //Initialise Win ASPI 32 by calling ASPI_GetASPI32SupportInfo(). + dwSupportInfo = ASPI_GetASPI32SupportInfo(); + if (HIBYTE(LOWORD(dwSupportInfo)) != SS_COMP && HIBYTE(LOWORD(dwSupportInfo)) != SS_NO_ADAPTERS) + { + WriteLog("Could not initialise using GetASPI32SupportInfo function or no adapters\n"); + return FALSE; + }; + + /* + ** Set timeouts for ALL devices to 15 seconds. Nothing we deal with should + ** take that long to do ANYTHING. We are just doing inquiries to most + ** devices, and then simple reads to CDs, disks, etc. so 10 seconds (even + ** if they have to spin up) should be plenty. + */ + memset(&srbTimeouts, 0, sizeof(SRB_GetSetTimeouts)); + srbTimeouts.SRB_Cmd = SC_GETSET_TIMEOUTS; + srbTimeouts.SRB_HaId = 0xFF; + srbTimeouts.SRB_Flags = SRB_DIR_OUT; + srbTimeouts.SRB_Target = 0xFF; + srbTimeouts.SRB_Lun = 0xFF; + srbTimeouts.SRB_Timeout = 15 * 2; + ASPI_SendASPI32Command(&srbTimeouts); + + return TRUE; +}; + +/* + Sends a SRB (SCSI Request Block) to Win ASPI32 driver for processing and + waits for completion. + + The SRB contains the CDB (Command Descriptor Block) which has the + raw SCSI command/info you want to send to the drive. So effectively + this is actually sending the SCSI command to the drive. + + Note that this uses a Windows event to wait for the drive to reply back + which is efficient. If an event is not available (which should never + happen really) a loop is used to poll for reply back. + + Both methods will wait infinitely - so the drive must reply back otherwise + this software will appear to hang. There seems to be no mechanism for + cancelling the SRB process - the Win ASPI 32 'SC_ABORT_SRB' command doesn't + seem to work. +*/ +BOOL SendASPICMD_and_wait(BYTE HA_ID, BYTE Target_ID, BYTE SRB_flags, DWORD Buffer_len, + PBYTE Buffer, BYTE CDB_len, PBYTE CDB) +{ + DWORD dwASPIStatus; + HANDLE hevent_SRB; //A handle for a new Windows event + SRB_ExecSCSICmd SRB; //The SRB variable with CDB included + BOOL b_retry = TRUE; + + //Clear & setup the SRB for this command.. + memset(&SRB, 0, sizeof(SRB_ExecSCSICmd)); //Set it to zeroes + memcpy(SRB.CDBByte, CDB, CDB_len); //Copy CDB into SRB + + SRB.SRB_Cmd = SC_EXEC_SCSI_CMD; + SRB.SRB_HaId = HA_ID; + SRB.SRB_Target = Target_ID; + //SRB.SRB_Lun = 0; //It's already zero + SRB.SRB_Flags = SRB_flags; + SRB.SRB_BufLen = Buffer_len; + SRB.SRB_BufPointer = Buffer; + SRB.SRB_SenseLen = SENSE_LEN; + SRB.SRB_CDBLen = CDB_len; + + do + { + /* + ** Create an event (if possible) and issue the command. After sending + ** the command, wait for completion. + */ + hevent_SRB = CreateEvent(NULL, TRUE, FALSE, NULL); + if (hevent_SRB) + { + //Windows event method for waiting - efficient. + + SRB.SRB_Flags |= SRB_EVENT_NOTIFY; + SRB.SRB_PostProc = (LPVOID)hevent_SRB; + + //Send the SRB for processing. + dwASPIStatus = ASPI_SendASPI32Command((LPSRB)&SRB); + if (dwASPIStatus == SS_PENDING) + { + //Wait for reply back. + WaitForSingleObject(hevent_SRB, INFINITE); + } + CloseHandle(hevent_SRB); + } + else + { + //Polling method for waiting - not very efficient. + + //Send the SRB for processing. + ASPI_SendASPI32Command((LPSRB)&SRB); + //Wait for reply back. + while(SRB.SRB_Status == SS_PENDING); + }; + + /* + ** Check for errors. We'll retry on unit attention condition. Anything + ** else will generate an error msg. + */ + if (SRB.SRB_Status != SS_COMP) + { + if (b_retry && (SRB.SRB_TargStat != STATUS_CHKCOND + || (SRB.SenseArea[2] & 0x0F) != KEY_UNITATT)) + b_retry = FALSE; + else + { + WriteLog("SCSI command failed.\n"); + return FALSE; + } + } + } + while (b_retry == FALSE); + + return TRUE; +}; + +/* + Lists all available CDROM type drives. This includes: + - CDROM drives + - CD rewriters/Combo + - DVD drives + - DVD rewriters + etc + + It can only list the SCSI IDs not drive letters. Win ASPI 32 does + not provide a mechanism for this. You will have to use windows API + for this. +*/ +VOID ListDevices() +{ + BYTE HaId; + BYTE Target; + BYTE MaxHaId; + BYTE MaxTarget; + BYTE InquiryBuf[36]; + BYTE InquiryCDB[6]; + CHAR szVendor[9]; + CHAR szProduct[17]; + CHAR szRev[5]; + BOOL bSRB_exec; + DWORD dwASPIStatus; + DWORD dwMaxTransferBytes; + SRB_HAInquiry srbHAInquiry; + SRB_GDEVBlock srbGDEVBlock; + DWORD n_CDROM_drives=0; //No of CDROM type drives found. + + //Use support info for host adapter count and loop over all of them. + dwASPIStatus = ASPI_GetASPI32SupportInfo(); + if(HIBYTE(LOWORD(dwASPIStatus)) == SS_COMP) + { + MaxHaId = LOBYTE(LOWORD(dwASPIStatus)); + for(HaId = 0; HaId < MaxHaId; HaId++) + { + /* + ** Do a host adapter inquiry to get max target count. If the + ** target count isn't 8 or 16 then go with a default of 8. + */ + memset(&srbHAInquiry, 0, sizeof(SRB_HAInquiry)); + srbHAInquiry.SRB_Cmd = SC_HA_INQUIRY; + srbHAInquiry.SRB_HaId = HaId; + + ASPI_SendASPI32Command((LPSRB)&srbHAInquiry); + if(srbHAInquiry.SRB_Status != SS_COMP) + { + continue; + }; + + MaxTarget = srbHAInquiry.HA_Unique[3]; + if(MaxTarget != 8 && MaxTarget != 16) + { + MaxTarget = 8; + }; + + /* + ** Loop over all the targets on this host adapter. + */ + for(Target = 0; Target < MaxTarget; Target++ ) + { + /* + ** Issue get device type call to see if there is a device we're + ** interested in at this address. We're interested in CDROMs. + */ + memset(&srbGDEVBlock, 0, sizeof(SRB_GDEVBlock)); + srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE; + srbGDEVBlock.SRB_HaId = HaId; + srbGDEVBlock.SRB_Target = Target; + + ASPI_SendASPI32Command((LPSRB)&srbGDEVBlock); + if(srbGDEVBlock.SRB_Status != SS_COMP || + (srbGDEVBlock.SRB_DeviceType != DTYPE_CDROM)) + { + continue; + }; + + /* + ** Determine the max transfer count of this target. It will + ** be the min of the host adapters min count and the size + ** of our global transfer buffer. + */ + dwMaxTransferBytes = (DWORD)&srbHAInquiry.HA_Unique[4]; + + /* + ** Issue an INQUIRY. + */ + memset(InquiryCDB, 0, 6); + InquiryCDB[0] = SCSI_INQUIRY; + InquiryCDB[4] = 36; //Size in bytes of inquiry buffer. + + //Send SCSI device inquiry command and wait for completion. + bSRB_exec = SendASPICMD_and_wait + ( + HaId, + Target, + SRB_DIR_IN, + 36, + InquiryBuf, + 6, + InquiryCDB + ); + + /* + ** Make sure the inquiry worked. If it failed, or if the + ** inquiry data returns a different device type than we got + ** before (guards against certain device drivers and against + ** vendor unique devices). + */ + if(!bSRB_exec || (InquiryBuf[0] != DTYPE_CDROM)) + continue; + + /* + ** Add this target to the screen. + */ + WriteLog("Host adapter ID: %ld\n", HaId); + WriteLog("Target ID : %ld\n", Target); + WriteLog("LUN ID : 0\n"); + WriteLog("Max buffer size: %ld bytes\n", dwMaxTransferBytes); + + memcpy(szVendor, InquiryBuf + 8, 8); + szVendor[8] = '\0'; //Terminate the string + + memcpy(szProduct, InquiryBuf + 16, 16); + szProduct[16] = '\0'; //Terminate the string + + memcpy(szRev, InquiryBuf + 32, 4); + szRev[4] = '\0'; //Terminate the string + + WriteLog("Vendor : %s\n", szVendor); + WriteLog("Product : %s\n", szProduct); + WriteLog("Revision : %s\n\n", szRev); + + n_CDROM_drives++; + } + } + + if (n_CDROM_drives == 0) + WriteLog("No CDROM type drives found.\n"); + } +} + +// +// 1. Sets up the CDB for MMC readcd (CDB12) command. +// 2. Send the request to the drive. +// 3. If success displays the sector data as hex on the screen. +// +BOOL ReadCD(BYTE HA_ID, BYTE Target_ID, long int MMC_LBA_sector) +{ + BYTE read_CDB12[12]; + long int MMC_LBA_sector2; + + //CDB with values for ReadCD CDB12 command. The values were taken from MMC1 draft paper. + read_CDB12[0] = 0xBE; //Code for ReadCD CDB12 command + read_CDB12[1] = 0; + + read_CDB12[5] = byte(MMC_LBA_sector); //Least sig byte of LBA sector no. to read from CD + MMC_LBA_sector2 = MMC_LBA_sector >> 8; + read_CDB12[4] = byte(MMC_LBA_sector2); //2nd byte of: + MMC_LBA_sector2 = MMC_LBA_sector2 >> 8; + read_CDB12[3] = byte(MMC_LBA_sector2); //3rd byte of: + MMC_LBA_sector2 = MMC_LBA_sector2 >> 8; + read_CDB12[2] = byte(MMC_LBA_sector2); //Most significant byte + + read_CDB12[6] = 0; //No. of sectors to read from CD byte 2 (MSB) + read_CDB12[7] = 0; //No. of sectors to read from CD byte 1 + read_CDB12[8] = 1; //No. of sectors to read from CD byte 0 (LSB) + read_CDB12[9] = 0xF8; //Raw read, 2352 bytes per sector + read_CDB12[10] = 0; //Sub-channel selection bits. + read_CDB12[11] = 0; + + return SendASPICMD_and_wait(HA_ID, Target_ID, SRB_DIR_IN, 2352, DataBuf, 12, read_CDB12); +} + +// +// Initialize the SDL sound system +// +void __CDInit(void) +{ + if (!InitASPI()) + { + WriteLog("Sound: Failed to init ASPI layer!\n"); + exit(1);//bad! + } +} + +// +// Close down the SDL sound subsystem +// +void __CDDone(void) +{ + //Unload ASPI if it has been loaded. + if (WNASPI32_handle) + FreeLibrary(WNASPI32_handle); +} + +/*// +// Sound card callback handler +// +void SDLSoundCallback(void * userdata, Uint8 * buffer, int length) +{ + if (remain > 0) + { + memcpy(buffer, DataBuf + 2352 - remain, remain); + length -= remain; + buffer += remain; + remain = 0; + } + + while (length > 0) + { + ReadCD(0, 1, sector++); + memcpy(buffer, DataBuf, (length >= 2352 ? 2352 : length)); + length -= 2352; + buffer += 2352; + } + + if (length < 0) + remain = -length; +}*/ diff --git a/src/include/cdintf.h b/src/include/cdintf.h new file mode 100644 index 0000000..e69de29 diff --git a/src/include/scsidefs.h b/src/include/scsidefs.h new file mode 100644 index 0000000..0d782b7 --- /dev/null +++ b/src/include/scsidefs.h @@ -0,0 +1,275 @@ +//*************************************************************************** +// +// Name: SCSIDEFS.H +// +// Description: SCSI definitions ('C' Language) +// +//*************************************************************************** + +//*************************************************************************** +// %%% TARGET STATUS VALUES %%% +//*************************************************************************** +#define STATUS_GOOD 0x00 // Status Good +#define STATUS_CHKCOND 0x02 // Check Condition +#define STATUS_CONDMET 0x04 // Condition Met +#define STATUS_BUSY 0x08 // Busy +#define STATUS_INTERM 0x10 // Intermediate +#define STATUS_INTCDMET 0x14 // Intermediate-condition met +#define STATUS_RESCONF 0x18 // Reservation conflict +#define STATUS_COMTERM 0x22 // Command Terminated +#define STATUS_QFULL 0x28 // Queue full + +//*************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//*************************************************************************** +#define MAXLUN 7 // Maximum Logical Unit Id +#define MAXTARG 7 // Maximum Target Id +#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs +#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Commands for all Device Types %%% +//*************************************************************************** +#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional) +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_COPY 0x18 // Copy (O) +#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O) +#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY) +#define SCSI_LOG_SELECT 0x4C // Log Select (O) +#define SCSI_LOG_SENSE 0x4D // Log Sense (O) +#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific) +#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific) +#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific) +#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific) +#define SCSI_READ_BUFF 0x3C // Read Buffer (O) +#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O) +#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY) +#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Direct Access Devices %%% +//*************************************************************************** +#define SCSI_COMPARE 0x39 // Compare (O) +#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY) +#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O) +#define SCSI_PREFETCH 0x34 // Prefetch (O) +#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O) +#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY) +#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY) +#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY) +#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O) +#define SCSI_READ_LONG 0x3E // Read Long (O) +#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O) +#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O) +#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY) +#define SCSI_REZERO 0x01 // Rezero Unit (O) +#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O) +#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O) +#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O) +#define SCSI_SEEK6 0x0B // Seek 6-Byte (O) +#define SCSI_SEEK10 0x2B // Seek 10-Byte (O) +#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY) +#define SCSI_SET_LIMIT 0x33 // Set Limits (O) +#define SCSI_START_STP 0x1B // Start/Stop Unit (O) +#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O) +#define SCSI_VERIFY 0x2F // Verify (O) +#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY) +#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY) +#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O) +#define SCSI_WRITE_LONG 0x3F // Write Long (O) +#define SCSI_WRITE_SAME 0x41 // Write Same (O) + +//*************************************************************************** +// %%% Commands Unique to Sequential Access Devices %%% +//*************************************************************************** +#define SCSI_ERASE 0x19 // Erase (MANDATORY) +#define SCSI_LOAD_UN 0x1B // Load/Unload (O) +#define SCSI_LOCATE 0x2B // Locate (O) +#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY) +#define SCSI_READ_POS 0x34 // Read Position (O) +#define SCSI_READ_REV 0x0F // Read Reverse (O) +#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O) +#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY) +#define SCSI_REWIND 0x01 // Rewind (MANDATORY) +#define SCSI_SPACE 0x11 // Space (MANDATORY) +#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O) +#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Printer Devices %%% +//*************************************************************************** +#define SCSI_PRINT 0x0A // Print (MANDATORY) +#define SCSI_SLEW_PNT 0x0B // Slew and Print (O) +#define SCSI_STOP_PNT 0x1B // Stop Print (O) +#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O) + +//*************************************************************************** +// %%% Commands Unique to Processor Devices %%% +//*************************************************************************** +#define SCSI_RECEIVE 0x08 // Receive (O) +#define SCSI_SEND 0x0A // Send (O) + +//*************************************************************************** +// %%% Commands Unique to Write-Once Devices %%% +//*************************************************************************** +#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O) +#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O) +#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O) +#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O) +#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O) +#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O) +#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O) +#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O) +#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O) +#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O) +#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O) +#define SCSI_WRITE12 0xAA // Write 12-Byte (O) +#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O) +#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O) + +//*************************************************************************** +// %%% Commands Unique to CD-ROM Devices %%% +//*************************************************************************** +#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O) +#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O) +#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O) +#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O) +#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O) +#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O) +#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY) +#define SCSI_READHEADER 0x44 // Read Header (O) +#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O) +#define SCSI_READ_TOC 0x43 // Read TOC (O) + +//*************************************************************************** +// %%% Commands Unique to Scanner Devices %%% +//*************************************************************************** +#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O) +#define SCSI_GETWINDOW 0x25 // Get Window (O) +#define SCSI_OBJECTPOS 0x31 // Object Postion (O) +#define SCSI_SCAN 0x1B // Scan (O) +#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY) + +//*************************************************************************** +// %%% Commands Unique to Optical Memory Devices %%% +//*************************************************************************** +#define SCSI_UpdateBlk 0x3D // Update Block (O) + +//*************************************************************************** +// %%% Commands Unique to Medium Changer Devices %%% +//*************************************************************************** +#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O) +#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O) +#define SCSI_POSTOELEM 0x2B // Position to Element (O) +#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O) +#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O) + +//*************************************************************************** +// %%% Commands Unique to Communication Devices %%% +//*************************************************************************** +#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY) +#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O) +#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O) +#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY) +#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O) +#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O) + +//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ +// +// %%% END OF SCSI COMMAND OPCODES %%% +// +///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + +//*************************************************************************** +// %%% Request Sense Data Format %%% +//*************************************************************************** +typedef struct { + + BYTE ErrorCode; // Error Code (70H or 71H) + BYTE SegmentNum; // Number of current segment descriptor + BYTE SenseKey; // Sense Key(See bit definitions too) + BYTE InfoByte0; // Information MSB + BYTE InfoByte1; // Information MID + BYTE InfoByte2; // Information MID + BYTE InfoByte3; // Information LSB + BYTE AddSenLen; // Additional Sense Length + BYTE ComSpecInf0; // Command Specific Information MSB + BYTE ComSpecInf1; // Command Specific Information MID + BYTE ComSpecInf2; // Command Specific Information MID + BYTE ComSpecInf3; // Command Specific Information LSB + BYTE AddSenseCode; // Additional Sense Code + BYTE AddSenQual; // Additional Sense Code Qualifier + BYTE FieldRepUCode; // Field Replaceable Unit Code + BYTE SenKeySpec15; // Sense Key Specific 15th byte + BYTE SenKeySpec16; // Sense Key Specific 16th byte + BYTE SenKeySpec17; // Sense Key Specific 17th byte + BYTE AddSenseBytes; // Additional Sense Bytes + +} SENSE_DATA_FMT; + +//*************************************************************************** +// %%% REQUEST SENSE ERROR CODE %%% +//*************************************************************************** +#define SERROR_CURRENT 0x70 // Current Errors +#define SERROR_DEFERED 0x71 // Deferred Errors + +//*************************************************************************** +// %%% REQUEST SENSE BIT DEFINITIONS %%% +//*************************************************************************** +#define SENSE_VALID 0x80 // Byte 0 Bit 7 +#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7 +#define SENSE_EOM 0x40 // Byte 2 Bit 6 +#define SENSE_ILI 0x20 // Byte 2 Bit 5 + +//*************************************************************************** +// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%% +//*************************************************************************** +#define KEY_NOSENSE 0x00 // No Sense +#define KEY_RECERROR 0x01 // Recovered Error +#define KEY_NOTREADY 0x02 // Not Ready +#define KEY_MEDIUMERR 0x03 // Medium Error +#define KEY_HARDERROR 0x04 // Hardware Error +#define KEY_ILLGLREQ 0x05 // Illegal Request +#define KEY_UNITATT 0x06 // Unit Attention +#define KEY_DATAPROT 0x07 // Data Protect +#define KEY_BLANKCHK 0x08 // Blank Check +#define KEY_VENDSPEC 0x09 // Vendor Specific +#define KEY_COPYABORT 0x0A // Copy Abort +#define KEY_EQUAL 0x0C // Equal (Search) +#define KEY_VOLOVRFLW 0x0D // Volume Overflow +#define KEY_MISCOMP 0x0E // Miscompare (Search) +#define KEY_RESERVED 0x0F // Reserved + +//*************************************************************************** +// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%% +//*************************************************************************** +#define DTYPE_DASD 0x00 // Disk Device +#define DTYPE_SEQD 0x01 // Tape Device +#define DTYPE_PRNT 0x02 // Printer +#define DTYPE_PROC 0x03 // Processor +#define DTYPE_WORM 0x04 // Write-once read-multiple +#define DTYPE_CROM 0x05 // CD-ROM device +#define DTYPE_CDROM 0x05 // CD-ROM device +#define DTYPE_SCAN 0x06 // Scanner device +#define DTYPE_OPTI 0x07 // Optical memory device +#define DTYPE_JUKE 0x08 // Medium Changer device +#define DTYPE_COMM 0x09 // Communications device +#define DTYPE_RESL 0x0A // Reserved (low) +#define DTYPE_RESH 0x1E // Reserved (high) +#define DTYPE_UNKNOWN 0x1F // Unknown or no device type + +//*************************************************************************** +// %%% ANSI APPROVED VERSION DEFINITIONS %%% +//*************************************************************************** +#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand +#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1) +#define ANSI_SCSI2 0x2 // Device complies to SCSI-2 +#define ANSI_RESLO 0x3 // Reserved (low) +#define ANSI_RESHI 0x7 // Reserved (high) diff --git a/src/include/wnaspi32.h b/src/include/wnaspi32.h new file mode 100644 index 0000000..b2c7ef5 --- /dev/null +++ b/src/include/wnaspi32.h @@ -0,0 +1,325 @@ +/****************************************************************************** +** +** Module Name: wnaspi32.h +** +** Description: Header file for ASPI for Win32. This header includes +** macro and type declarations, and can be included without +** modification when using Borland C++ or Microsoft Visual +** C++ with 32-bit compilation. If you are using a different +** compiler then you MUST ensure that structures are packed +** onto byte alignments, and that C++ name mangling is turned +** off. +** +** Notes: This file created using 4 spaces per tab. +** +******************************************************************************/ + +#ifndef __WNASPI32_H__ +#define __WNASPI32_H__ + +/* +** Make sure structures are packed and undecorated. +*/ + +#ifdef __BORLANDC__ +#pragma option -a1 +#endif //__BORLANDC__ + +#ifdef _MSC_VER +#pragma pack(1) +#endif //__MSC_VER + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//***************************************************************************** +// %%% SCSI MISCELLANEOUS EQUATES %%% +//***************************************************************************** + +#define SENSE_LEN 14 // Default sense buffer length +#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI +#define SRB_POSTING 0x01 // Enable ASPI posting +#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting +#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host +#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target +#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification + +#define RESIDUAL_COUNT_SUPPORTED 0x02 // Extended buffer flag +#define MAX_SRB_TIMEOUT 108000lu // 30 hour maximum timeout in s +#define DEFAULT_SRB_TIMEOUT 108000lu // Max timeout by default + + +//***************************************************************************** +// %%% ASPI Command Definitions %%% +//***************************************************************************** + +#define SC_HA_INQUIRY 0x00 // Host adapter inquiry +#define SC_GET_DEV_TYPE 0x01 // Get device type +#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command +#define SC_ABORT_SRB 0x03 // Abort an SRB +#define SC_RESET_DEV 0x04 // SCSI bus device reset +#define SC_SET_HA_PARMS 0x05 // Set HA parameters +#define SC_GET_DISK_INFO 0x06 // Get Disk information +#define SC_RESCAN_SCSI_BUS 0x07 // ReBuild SCSI device map +#define SC_GETSET_TIMEOUTS 0x08 // Get/Set target timeouts + +//***************************************************************************** +// %%% SRB Status %%% +//***************************************************************************** + +#define SS_PENDING 0x00 // SRB being processed +#define SS_COMP 0x01 // SRB completed without error +#define SS_ABORTED 0x02 // SRB aborted +#define SS_ABORT_FAIL 0x03 // Unable to abort SRB +#define SS_ERR 0x04 // SRB completed with error + +#define SS_INVALID_CMD 0x80 // Invalid ASPI command +#define SS_INVALID_HA 0x81 // Invalid host adapter number +#define SS_NO_DEVICE 0x82 // SCSI device not installed + +#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB +#define SS_OLD_MANAGER 0xE1 // ASPI manager doesn't support Windows +#define SS_BUFFER_ALIGN 0xE1 // Buffer not aligned (replaces OLD_MANAGER in Win32) +#define SS_ILLEGAL_MODE 0xE2 // Unsupported Windows mode +#define SS_NO_ASPI 0xE3 // No ASPI managers resident +#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init +#define SS_ASPI_IS_BUSY 0xE5 // No resources available to execute cmd +#define SS_BUFFER_TO_BIG 0xE6 // Buffer size to big to handle! +#define SS_MISMATCHED_COMPONENTS 0xE7 // The DLLs/EXEs of ASPI don't version check +#define SS_NO_ADAPTERS 0xE8 // No host adapters to manage +#define SS_INSUFFICIENT_RESOURCES 0xE9 // Couldn't allocate resources needed to init +#define SS_ASPI_IS_SHUTDOWN 0xEA // Call came to ASPI after PROCESS_DETACH +#define SS_BAD_INSTALL 0xEB // The DLL or other components are installed wrong + +//***************************************************************************** +// %%% Host Adapter Status %%% +//***************************************************************************** + +#define HASTAT_OK 0x00 // Host adapter did not detect an // error +#define HASTAT_SEL_TO 0x11 // Selection Timeout +#define HASTAT_DO_DU 0x12 // Data overrun data underrun +#define HASTAT_BUS_FREE 0x13 // Unexpected bus free +#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence // failure +#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed. +#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB. +#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE +#define HASTAT_BUS_RESET 0x0E // A bus reset was detected. +#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected. +#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing + +//***************************************************************************** +// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY (0) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_HA_INQUIRY + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE HA_Count; // 08/008 Number of host adapters present + BYTE HA_SCSI_ID; // 09/009 SCSI ID of host adapter + BYTE HA_ManagerId[16]; // 0A/010 String describing the manager + BYTE HA_Identifier[16]; // 1A/026 String describing the host adapter + BYTE HA_Unique[16]; // 2A/042 Host Adapter Unique parameters + WORD HA_Rsvd1; // 3A/058 Reserved, MUST = 0 +} +SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry; + +//***************************************************************************** +// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DEV_TYPE + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_DeviceType; // 0A/010 Target's peripheral device type + BYTE SRB_Rsvd1; // 0B/011 Reserved, MUST = 0 +} +SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock; + +//***************************************************************************** +// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + WORD SRB_Rsvd1; // 0A/010 Reserved for Alignment + DWORD SRB_BufLen; // 0C/012 Data Allocation Length + BYTE FAR *SRB_BufPointer; // 10/016 Data Buffer Pointer + BYTE SRB_SenseLen; // 14/020 Sense Allocation Length + BYTE SRB_CDBLen; // 15/021 CDB Length + BYTE SRB_HaStat; // 16/022 Host Adapter Status + BYTE SRB_TargStat; // 17/023 Target Status + VOID FAR *SRB_PostProc; // 18/024 Post routine + BYTE SRB_Rsvd2[20]; // 1C/028 Reserved, MUST = 0 + BYTE CDBByte[16]; // 30/048 SCSI CDB + BYTE SenseArea[SENSE_LEN+2]; // 50/064 Request Sense buffer +} +SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd; + +//***************************************************************************** +// %%% SRB - ABORT AN SRB - SC_ABORT_SRB (3) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_ABORT_SRB + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + VOID FAR *SRB_ToAbort; // 08/008 Pointer to SRB to abort +} +SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort; + +//***************************************************************************** +// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV (4) %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESET_DEV + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_Rsvd1[12]; // 0A/010 Reserved for Alignment + BYTE SRB_HaStat; // 16/022 Host Adapter Status + BYTE SRB_TargStat; // 17/023 Target Status + VOID FAR *SRB_PostProc; // 18/024 Post routine + BYTE SRB_Rsvd2[36]; // 1C/028 Reserved, MUST = 0 +} +SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset; + +//***************************************************************************** +// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DISK_INFO + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + BYTE SRB_DriveFlags; // 0A/010 Driver flags + BYTE SRB_Int13HDriveInfo; // 0B/011 Host Adapter Status + BYTE SRB_Heads; // 0C/012 Preferred number of heads translation + BYTE SRB_Sectors; // 0D/013 Preferred number of sectors translation + BYTE SRB_Rsvd1[10]; // 0E/014 Reserved, MUST = 0 +} +SRB_GetDiskInfo, *PSRB_GetDiskInfo, FAR *LPSRB_GetDiskInfo; + +//***************************************************************************** +// %%% SRB - RESCAN SCSI BUS(ES) ON SCSIPORT %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESCAN_SCSI_BUS + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 Reserved, MUST = 0 + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 +} +SRB_RescanPort, *PSRB_RescanPort, FAR *LPSRB_RescanPort; + +//***************************************************************************** +// %%% SRB - GET/SET TARGET TIMEOUTS %%% +//***************************************************************************** + +typedef struct // Offset +{ // HX/DEC + BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GETSET_TIMEOUTS + BYTE SRB_Status; // 01/001 ASPI command status byte + BYTE SRB_HaId; // 02/002 ASPI host adapter number + BYTE SRB_Flags; // 03/003 ASPI request flags + DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0 + BYTE SRB_Target; // 08/008 Target's SCSI ID + BYTE SRB_Lun; // 09/009 Target's LUN number + DWORD SRB_Timeout; // 0A/010 Timeout in half seconds +} +SRB_GetSetTimeouts, *PSRB_GetSetTimeouts, FAR *LPSRB_GetSetTimeouts; + +//***************************************************************************** +// %%% ASPIBUFF - Structure For Controllng I/O Buffers %%% +//***************************************************************************** + +typedef struct tag_ASPI32BUFF // Offset +{ // HX/DEC + PBYTE AB_BufPointer; // 00/000 Pointer to the ASPI allocated buffer + DWORD AB_BufLen; // 04/004 Length in bytes of the buffer + DWORD AB_ZeroFill; // 08/008 Flag set to 1 if buffer should be zeroed + DWORD AB_Reserved; // 0C/012 Reserved +} +ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF; + +//***************************************************************************** +// %%% PROTOTYPES - User Callable ASPI for Win32 Functions %%% +//***************************************************************************** + +typedef void *LPSRB; + +#if defined(__BORLANDC__) + +DWORD _import GetASPI32SupportInfo( void ); +DWORD _import SendASPI32Command( LPSRB ); +BOOL _import GetASPI32Buffer( PASPI32BUFF ); +BOOL _import FreeASPI32Buffer( PASPI32BUFF ); +BOOL _import TranslateASPI32Address( PDWORD, PDWORD ); + +#elif defined(_MSC_VER) + +__declspec(dllimport) DWORD GetASPI32SupportInfo( void ); +__declspec(dllimport) DWORD SendASPI32Command( LPSRB ); +__declspec(dllimport) BOOL GetASPI32Buffer( PASPI32BUFF ); +__declspec(dllimport) BOOL FreeASPI32Buffer( PASPI32BUFF ); +__declspec(dllimport) BOOL TranslateASPI32Address( PDWORD, PDWORD ); + +#else + +extern DWORD GetASPI32SupportInfo( void ); +extern DWORD GetASPI32Command( LPSRB ); +extern BOOL GetASPI32Buffer( PASPI32BUFF ); +extern BOOL FreeASPI32Buffer( PASPI32BUFF ); +extern BOOL TranslateASPI32Address( PDWORD, PDWORD ); + +#endif + +/* +** Restore compiler default packing and close off the C declarations. +*/ + +#ifdef __BORLANDC__ +#pragma option -a. +#endif //__BORLANDC__ + +#ifdef _MSC_VER +#pragma pack() +#endif //_MSC_VER + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__WNASPI32_H__