mirror of https://github.com/PCSX2/pcsx2.git
843 lines
29 KiB
C++
843 lines
29 KiB
C++
// Aspi.cpp: implementation of the aspi methods
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "cdvd.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[]=__FILE__;
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
#define MOVESCSIDWORD(pdwSrc,pdwDst) \
|
|
{\
|
|
((PBYTE)(pdwDst))[0] = ((PBYTE)(pdwSrc))[3];\
|
|
((PBYTE)(pdwDst))[1] = ((PBYTE)(pdwSrc))[2];\
|
|
((PBYTE)(pdwDst))[2] = ((PBYTE)(pdwSrc))[1];\
|
|
((PBYTE)(pdwDst))[3] = ((PBYTE)(pdwSrc))[0];\
|
|
}
|
|
|
|
#define MOVESCSIWORD(pwSrc,pwDst) \
|
|
{\
|
|
((PBYTE)(pwDst))[0] = ((PBYTE)(pwSrc))[1];\
|
|
((PBYTE)(pwDst))[1] = ((PBYTE)(pwSrc))[0];\
|
|
}
|
|
|
|
|
|
/***********************************************************/
|
|
/* ASPI Init/Shutdown related methods */
|
|
/***********************************************************/
|
|
|
|
// using MFC classes, no aspi in other systems.
|
|
int CCdvd::Aspi_CheckValidInstallation()
|
|
{
|
|
int retval = CDVD_ERROR_FAIL;
|
|
|
|
CFileStatus fstat;
|
|
TCHAR szDir[MAX_PATH];
|
|
|
|
if(GetSystemDirectory(szDir,MAX_PATH))
|
|
{
|
|
CString directory = szDir;
|
|
WIN32OSTYPE ostype = GetWin32OSType();
|
|
|
|
if(ostype != WINNTNEW && ostype != WINNTOLD)
|
|
{
|
|
if(CFile::GetStatus(directory+_T("\\wnaspi32.dll"), fstat) &&
|
|
CFile::GetStatus(directory+_T("\\winaspi.dll"), fstat) &&
|
|
CFile::GetStatus(directory+_T("\\iosubsys\\apix.vxd"), fstat))
|
|
{
|
|
retval = CDVD_ERROR_SUCCESS;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(CFile::GetStatus(directory+_T("\\wnaspi32.dll"), fstat) &&
|
|
CFile::GetStatus(directory+_T("\\drivers\\aspi32.sys"), fstat))
|
|
{
|
|
retval = CDVD_ERROR_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// are you crazy? o_O, no fucking windows directory? o_O
|
|
retval = CDVD_ERROR_FAIL;
|
|
}
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
// called once to init Aspi
|
|
int CCdvd::Aspi_Init()
|
|
{
|
|
int retval = CDVD_ERROR_FAIL;
|
|
if(m_bAspiInitialized)
|
|
return CDVD_ERROR_SUCCESS;
|
|
|
|
if(Aspi_CheckValidInstallation() == CDVD_ERROR_SUCCESS)
|
|
{
|
|
if((m_hAspi = AfxLoadLibrary("WNASPI32")) != NULL)
|
|
{
|
|
SendASPI32Command = (CDROMSendASPI32Command) GetProcAddress(m_hAspi,"SendASPI32Command");
|
|
GetASPI32SupportInfo = (CDROMGetASPI32SupportInfo) GetProcAddress(m_hAspi,"GetASPI32SupportInfo");
|
|
|
|
if(SendASPI32Command != NULL &&
|
|
GetASPI32SupportInfo != NULL)
|
|
{
|
|
UI32 support_info = GetASPI32SupportInfo();
|
|
if( HIBYTE(LOWORD(support_info)) != SS_COMP &&
|
|
HIBYTE(LOWORD(support_info)) != SS_NO_ADAPTERS )
|
|
{
|
|
Aspi_Shutdown();
|
|
}
|
|
else
|
|
{
|
|
if(InitializeBuffers() == CDVD_ERROR_SUCCESS)
|
|
{
|
|
if(Aspi_ScsiBusScan() == CDVD_ERROR_SUCCESS)
|
|
{
|
|
SetCurrentBuffer(0);
|
|
m_bAspiInitialized = TRUE;
|
|
retval = CDVD_ERROR_SUCCESS;
|
|
GetNumSectors = Aspi_GetNumSectors;
|
|
GetToc = Aspi_GetToc;
|
|
// GetHeader = Aspi_GetHeader;
|
|
SetSpeed = Aspi_SetSpeed;
|
|
Stop = Aspi_Stop;
|
|
SetSectorSize = Aspi_SetSectorSize;
|
|
Play = Aspi_Play;
|
|
TestReady = Aspi_TestReady;
|
|
ReadSector = Dummy_T4;
|
|
UpdateInterfaceObject();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Aspi_Shutdown();
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
// shuts down aspi
|
|
int CCdvd::Aspi_Shutdown()
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
// gota detect the read_mode first before i do this
|
|
// but just reset to 2048 for now.
|
|
Aspi_SetSectorSize(CDVD_SECTOR_SIZE_DVD);
|
|
|
|
// the old ASPI drivers suck shit to hell and damnation,
|
|
// freeing them up immediately after init will crash sometimes
|
|
::Sleep(200);
|
|
|
|
if(m_hAspi != NULL)
|
|
AfxFreeLibrary(m_hAspi);
|
|
m_hAspi = NULL;
|
|
|
|
SendASPI32Command = NULL;
|
|
GetASPI32SupportInfo = NULL;
|
|
|
|
GetNumSectors = Dummy_T1;
|
|
GetToc = Dummy_T1;
|
|
Stop = Dummy_T1;
|
|
Play = Dummy_T3;
|
|
TestReady = Dummy_T1;
|
|
// GetHeader = Dummy_T1;
|
|
SetSpeed = Dummy_T2;
|
|
SetSectorSize = Dummy_T2;
|
|
ReadSector = Dummy_T4;
|
|
UpdateInterfaceObject();
|
|
|
|
ShutdownBuffers();
|
|
|
|
m_bAspiInitialized = FALSE;
|
|
|
|
return retval;
|
|
}
|
|
|
|
// open a drive for reading
|
|
int CCdvd::Aspi_OpenDrive(int drv_num)
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
CloseDrive();
|
|
m_nCurrentDrive = drv_num;
|
|
|
|
return retval;
|
|
}
|
|
|
|
// dummy for now
|
|
int CCdvd::Aspi_CloseDrive()
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
m_nCurrentDrive = -1;
|
|
|
|
return retval;
|
|
}
|
|
|
|
// get srb status
|
|
int CCdvd::Aspi_GetSrbStatus(int srb_num)
|
|
{
|
|
int retval = CDVD_SRB_ERROR;
|
|
switch(m_nCurrentReadMode)
|
|
{
|
|
case CDVD_READ_MMC: retval = m_srbReadCd [srb_num].SRB_Status; break;
|
|
case CDVD_READ_SCSI10: retval = m_srbRead10 [srb_num].SRB_Status; break;
|
|
case CDVD_READ_D8: retval = m_srbReadMat [srb_num].SRB_Status; break;
|
|
case CDVD_READ_D410: retval = m_srbReadSony[srb_num].SRB_Status; break;
|
|
case CDVD_READ_D412: retval = m_srbReadNec [srb_num].SRB_Status; break;
|
|
default: break;
|
|
}
|
|
|
|
if(retval == SS_COMP) retval = CDVD_SRB_COMPLETED;
|
|
else if(retval == SS_PENDING) retval = CDVD_SRB_PENDING;
|
|
else //if(retval == SS_ERR)
|
|
retval = CDVD_SRB_ERROR;
|
|
|
|
return retval;
|
|
}
|
|
|
|
// set read mode
|
|
int CCdvd::Aspi_SetReadMode(CDVD_READ_MODE read_mode)
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
switch(read_mode)
|
|
{
|
|
case CDVD_READ_MMC: ReadSector = Aspi_ReadSector_mmc; break;
|
|
case CDVD_READ_SCSI10: TRACE("cdvdlib: setting scsi10 readmode.\n");
|
|
ReadSector = Aspi_ReadSector_scsi10;
|
|
if(((this)->*(SetSectorSize))((m_nMmcDataMode == CDVD_MMC_DATAMODE_RAW) ?
|
|
CDVD_SECTOR_SIZE_CD : CDVD_SECTOR_SIZE_DVD) != CDVD_ERROR_SUCCESS)
|
|
{
|
|
retval = CDVD_ERROR_FAIL;
|
|
}
|
|
break;
|
|
case CDVD_READ_D8: ReadSector = Aspi_ReadSector_matsu; break;
|
|
case CDVD_READ_D410: ReadSector = Aspi_ReadSector_sony; break;
|
|
case CDVD_READ_D412: ReadSector = Aspi_ReadSector_nec; break;
|
|
default: retval = CDVD_ERROR_FAIL; break;
|
|
}
|
|
|
|
UpdateInterfaceObject();
|
|
|
|
return retval;
|
|
}
|
|
|
|
// search for scsi adapters with c/dvd drives.
|
|
int CCdvd::Aspi_ScsiBusScan()
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
SRB_HAInquiry srbHAInquiry;
|
|
m_nDrives = 0;
|
|
memset(m_drvDetails, 0, CDVD_MAX_SUPPORTED_DRIVES * sizeof(ADAPTERINFO));
|
|
memset(&srbHAInquiry, 0, sizeof (SRB_HAInquiry) );
|
|
|
|
srbHAInquiry.SRB_Cmd = SC_HA_INQUIRY;
|
|
srbHAInquiry.SRB_HaId = 0;
|
|
|
|
SendASPI32Command ((LPSRB) &srbHAInquiry);
|
|
if (srbHAInquiry.SRB_Status != SS_COMP)
|
|
{
|
|
return CDVD_ERROR_FAIL;
|
|
}
|
|
|
|
UI08 HA_Count = srbHAInquiry.HA_Count;
|
|
srbHAInquiry.HA_ManagerId[16] = 0;
|
|
|
|
for (UI08 HA_num = 0; HA_num < HA_Count; HA_num++)
|
|
{
|
|
char szHA_num[10];
|
|
itoa((int) HA_num, szHA_num, 10);
|
|
memset(&srbHAInquiry, 0, sizeof(SRB_HAInquiry));
|
|
srbHAInquiry.SRB_Cmd = SC_HA_INQUIRY;
|
|
srbHAInquiry.SRB_HaId = HA_num;
|
|
|
|
SendASPI32Command ((LPSRB) &srbHAInquiry);
|
|
if (srbHAInquiry.SRB_Status != SS_COMP)
|
|
{
|
|
return CDVD_ERROR_FAIL;
|
|
}
|
|
else
|
|
{
|
|
srbHAInquiry.HA_Identifier[16] = 0;
|
|
for (UI08 SCSI_Id = 0; SCSI_Id < 8; SCSI_Id++)
|
|
{
|
|
char szSCSI_Id[10];
|
|
itoa ((int) SCSI_Id, szSCSI_Id, 10);
|
|
for(UI08 SCSI_Lun = 0; SCSI_Lun < 8; SCSI_Lun++)
|
|
{
|
|
char szSCSI_Lun[10];
|
|
itoa ((int) SCSI_Lun, szSCSI_Lun, 10);
|
|
|
|
SRB_GDEVBlock srbGDEVBlock;
|
|
memset(&srbGDEVBlock, 0, sizeof(srbGDEVBlock));
|
|
srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE;
|
|
srbGDEVBlock.SRB_HaId = HA_num;
|
|
srbGDEVBlock.SRB_Target = SCSI_Id;
|
|
srbGDEVBlock.SRB_Lun = SCSI_Lun;
|
|
SendASPI32Command ((LPSRB) &srbGDEVBlock);
|
|
if (srbGDEVBlock.SRB_Status != SS_COMP ||
|
|
srbGDEVBlock.SRB_DeviceType != DTYPE_CDROM) continue;
|
|
|
|
char temp[40];
|
|
if(Aspi_ScsiInquiry(HA_num, SCSI_Id, SCSI_Lun, temp) == CDVD_ERROR_SUCCESS)
|
|
{
|
|
if(m_nDrives < CDVD_MAX_SUPPORTED_DRIVES)
|
|
{
|
|
TRACE("drive %ld: [%ld:%ld:%ld] - %s %s\n", m_nDrives, HA_num, SCSI_Id, SCSI_Lun,
|
|
m_drvDetails[m_nDrives].hostname,
|
|
temp);
|
|
m_drvDetails[m_nDrives].ha = HA_num;
|
|
m_drvDetails[m_nDrives].id = SCSI_Id;
|
|
m_drvDetails[m_nDrives].lun = SCSI_Lun;
|
|
strcpy(m_drvDetails[m_nDrives].hostname, (const char*) srbHAInquiry.HA_Identifier);
|
|
strcpy(m_drvDetails[m_nDrives].name, temp);
|
|
++m_nDrives;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
retval = CDVD_ERROR_FAIL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
// retrieve ha info
|
|
int CCdvd::Aspi_ScsiInquiry(UI08 ha, UI08 id, UI08 lun, char *destination)
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
UI08 buffer[36];
|
|
SRB_ExecSCSICmd srb;
|
|
|
|
memset(buffer, 0x20, sizeof(buffer));
|
|
memset(&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = ha;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_Target = id;
|
|
srb.SRB_Lun = lun;
|
|
srb.SRB_BufLen = 36;
|
|
srb.SRB_BufPointer = buffer;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_CDBLen = 6;
|
|
srb.CDBByte[0] = SCSI_INQUIRY;
|
|
srb.CDBByte[4] = 36; // allocation length per buffer
|
|
|
|
if (Aspi_ExecuteSrb(srb, NULL, 0) == CDVD_ERROR_SUCCESS)
|
|
{
|
|
memcpy(destination, buffer + 8, 27);
|
|
destination[27] = '\0';
|
|
}
|
|
else
|
|
{
|
|
destination[0] = '\0';
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/***********************************************************/
|
|
/* ASPI Execute SRB */
|
|
/***********************************************************/
|
|
// if HANDLE = NULL, SRB is synchronous, else its asynchronous
|
|
int CCdvd::Aspi_ExecuteSrb(SRB_ExecSCSICmd &srbExec, HANDLE *handle, int nretry)
|
|
{
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
++nretry;
|
|
// lets do sync with handle == NULL
|
|
if(handle == NULL)
|
|
{
|
|
TRACE("executing synchronous SRB.\n");
|
|
while(nretry)
|
|
{
|
|
HANDLE heventExec = CreateEvent( NULL, TRUE, FALSE, NULL );
|
|
if(heventExec) // do event based notification
|
|
{
|
|
srbExec.SRB_Flags |= SRB_EVENT_NOTIFY;
|
|
srbExec.SRB_PostProc = (LPVOID)heventExec;
|
|
|
|
DWORD dwASPIStatus = SendASPI32Command((LPSRB) &srbExec);
|
|
if(dwASPIStatus == SS_ERR)
|
|
{
|
|
CloseHandle(heventExec);
|
|
return CDVD_ERROR_FAIL;
|
|
}
|
|
|
|
if(dwASPIStatus == SS_PENDING)
|
|
{
|
|
WaitForSingleObject(heventExec, INFINITE);
|
|
}
|
|
CloseHandle(heventExec);
|
|
}
|
|
else // do shitty polling
|
|
{
|
|
SendASPI32Command((LPSRB)&srbExec);
|
|
while(srbExec.SRB_Status == SS_PENDING);
|
|
}
|
|
|
|
TRACE("SRB_Status: %ld\n", srbExec.SRB_Status);
|
|
if( srbExec.SRB_Status != SS_COMP )
|
|
{
|
|
if(nretry-- &&
|
|
(srbExec.SRB_TargStat != STATUS_CHKCOND ||
|
|
(srbExec.SenseArea[2] & 0x0F) != KEY_UNITATT) )
|
|
{
|
|
UI08 sense = srbExec.SenseArea[2] & 0x0F;
|
|
UI08 asc = srbExec.SenseArea[12];
|
|
UI08 ascq = srbExec.SenseArea[13];
|
|
TRACE("sensekey: %02Xh, %02Xh, %02Xh\n", sense, asc, ascq);
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we're done.
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TRACE("executing asynchronous SRB.\n");
|
|
|
|
ResetEvent(*handle);
|
|
srbExec.SRB_Flags |= SRB_EVENT_NOTIFY;
|
|
srbExec.SRB_PostProc = *handle;
|
|
|
|
DWORD dwASPIStatus = SendASPI32Command((LPSRB) &srbExec);
|
|
|
|
if(dwASPIStatus == SS_ERR)
|
|
{
|
|
SetEvent(*handle);
|
|
TRACE("SRB unrecoverable error.\n");
|
|
return CDVD_ERROR_FAIL;
|
|
}
|
|
|
|
if(dwASPIStatus == SS_PENDING)
|
|
{
|
|
TRACE("SRB Pending completion.\n");
|
|
return CDVD_ERROR_PENDING;
|
|
}
|
|
|
|
TRACE("SRB completed immediately.\n");
|
|
}
|
|
|
|
if(nretry == 0) retval = CDVD_ERROR_FAIL;
|
|
return retval;
|
|
}
|
|
|
|
/***********************************************************/
|
|
/* ASPI C/DVD Methods */
|
|
/***********************************************************/
|
|
|
|
// read using mmc 0xbe command
|
|
int CCdvd::Aspi_ReadSector_mmc(int sect, HANDLE *handle)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_Flags = SRB_DIR_IN | SRB_ENABLE_RESIDUAL_COUNT;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_BufPointer = m_ReadBuffer[m_nCurrentBuffer].AB_BufPointer;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_BufLen = m_ReadBuffer[m_nCurrentBuffer].AB_BufLen;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_SenseLen = SENSE_LEN;
|
|
|
|
m_srbReadCd[m_nCurrentBuffer].SRB_CDBLen = 12;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[0] = 0xBE;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[1] = 0x00;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[2] = HIBYTE(HIWORD(sect));
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[3] = LOBYTE(HIWORD(sect));
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[4] = HIBYTE(LOWORD(sect));
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[5] = LOBYTE(LOWORD(sect));
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[6] = 0x00;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[7] = 0x00;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[8] = CDVD_NUM_SECTORS_PER_BUFF;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[9] = (UI08) m_nMmcDataMode;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[10] = 0x00;
|
|
m_srbReadCd[m_nCurrentBuffer].CDBByte[11] = 0x00;
|
|
|
|
return Aspi_ExecuteSrb(m_srbReadCd[m_nCurrentBuffer], handle, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// read using scsi-10 (0x28) command, size is dependent on SetSectorSize
|
|
int CCdvd::Aspi_ReadSector_scsi10(int sect, HANDLE *handle)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
m_srbRead10[m_nCurrentBuffer].SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_Flags = SRB_DIR_IN;// | SRB_ENABLE_RESIDUAL_COUNT;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_BufPointer = m_ReadBuffer[m_nCurrentBuffer].AB_BufPointer;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_BufLen = m_ReadBuffer[m_nCurrentBuffer].AB_BufLen;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
m_srbRead10[m_nCurrentBuffer].SRB_SenseLen = SENSE_LEN;
|
|
|
|
m_srbRead10[m_nCurrentBuffer].SRB_CDBLen = 10;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[0] = 0x28;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[1] = 0x00;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[2] = HIBYTE(HIWORD(sect));
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[3] = LOBYTE(HIWORD(sect));
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[4] = HIBYTE(LOWORD(sect));
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[5] = LOBYTE(LOWORD(sect));
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[6] = 0x00;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[7] = 0x00;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[8] = CDVD_NUM_SECTORS_PER_BUFF;
|
|
m_srbRead10[m_nCurrentBuffer].CDBByte[9] = 0x00;
|
|
|
|
return Aspi_ExecuteSrb(m_srbRead10[m_nCurrentBuffer], handle, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// read using proprietary matsushita command, heck if it works
|
|
int CCdvd::Aspi_ReadSector_matsu(int sect, HANDLE *handle)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_Flags = SRB_DIR_IN | SRB_ENABLE_RESIDUAL_COUNT;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_BufPointer = m_ReadBuffer[m_nCurrentBuffer].AB_BufPointer;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_BufLen = m_ReadBuffer[m_nCurrentBuffer].AB_BufLen;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_SenseLen = SENSE_LEN;
|
|
|
|
m_srbReadMat[m_nCurrentBuffer].SRB_CDBLen = 12;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[0] = 0xd4;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[1] = 0x00;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[2] = HIBYTE(HIWORD(sect));
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[3] = LOBYTE(HIWORD(sect));
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[4] = HIBYTE(LOWORD(sect));
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[5] = LOBYTE(LOWORD(sect));
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[6] = 0x00;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[7] = 0x00;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[8] = CDVD_NUM_SECTORS_PER_BUFF;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[9] = 0x00;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[10] = 0x00;
|
|
m_srbReadMat[m_nCurrentBuffer].CDBByte[11] = 0x00;
|
|
|
|
return Aspi_ExecuteSrb(m_srbReadMat[m_nCurrentBuffer], handle, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// read using proprietary sony command, heck if it works
|
|
int CCdvd::Aspi_ReadSector_sony(int sect, HANDLE *handle)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_Flags = SRB_DIR_IN | SRB_ENABLE_RESIDUAL_COUNT;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_BufPointer = m_ReadBuffer[m_nCurrentBuffer].AB_BufPointer;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_BufLen = m_ReadBuffer[m_nCurrentBuffer].AB_BufLen;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_SenseLen = SENSE_LEN;
|
|
|
|
m_srbReadSony[m_nCurrentBuffer].SRB_CDBLen = 12;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[0] = 0xd8;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[1] = 0x00;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[2] = HIBYTE(HIWORD(sect));
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[3] = LOBYTE(HIWORD(sect));
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[4] = HIBYTE(LOWORD(sect));
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[5] = LOBYTE(LOWORD(sect));
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[6] = 0x00;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[7] = 0x00;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[8] = CDVD_NUM_SECTORS_PER_BUFF;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[9] = 0x00;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[10] = 0x00;
|
|
m_srbReadSony[m_nCurrentBuffer].CDBByte[11] = 0x00;
|
|
|
|
return Aspi_ExecuteSrb(m_srbReadSony[m_nCurrentBuffer], handle, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// read using proprietary nec command, heck if it works
|
|
int CCdvd::Aspi_ReadSector_nec(int sect, HANDLE *handle)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_Flags = SRB_DIR_IN | SRB_ENABLE_RESIDUAL_COUNT;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_BufPointer = m_ReadBuffer[m_nCurrentBuffer].AB_BufPointer;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_BufLen = m_ReadBuffer[m_nCurrentBuffer].AB_BufLen;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_SenseLen = SENSE_LEN;
|
|
|
|
m_srbReadNec[m_nCurrentBuffer].SRB_CDBLen = 10;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[0] = 0xd4;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[1] = 0x00;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[2] = HIBYTE(HIWORD(sect));
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[3] = LOBYTE(HIWORD(sect));
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[4] = HIBYTE(LOWORD(sect));
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[5] = LOBYTE(LOWORD(sect));
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[6] = 0x00;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[7] = 0x00;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[8] = CDVD_NUM_SECTORS_PER_BUFF;
|
|
m_srbReadNec[m_nCurrentBuffer].CDBByte[9] = 0x00;
|
|
|
|
return Aspi_ExecuteSrb(m_srbReadNec[m_nCurrentBuffer], handle, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// retrieve number of sectors present in c/dvd media
|
|
int CCdvd::Aspi_GetNumSectors()
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
UI08 capacity[8];
|
|
UI32 max_sector;
|
|
|
|
memset(&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_BufLen = 8;
|
|
srb.SRB_BufPointer = capacity;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_CDBLen = 10;
|
|
|
|
srb.CDBByte[0] = SCSI_RD_CAPAC;
|
|
|
|
|
|
if(Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY)
|
|
!= CDVD_ERROR_SUCCESS)
|
|
return 0; // no sectors found
|
|
|
|
MOVESCSIDWORD(&capacity[0], &max_sector);
|
|
|
|
return max_sector+1;
|
|
}
|
|
|
|
// retrieve TOC data
|
|
int CCdvd::Aspi_GetToc()
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
UI08 buff[804];
|
|
memset(buff, 0, sizeof(buff));
|
|
memset (&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_BufPointer = buff;
|
|
srb.SRB_BufLen = sizeof(buff);
|
|
srb.SRB_CDBLen = 10;
|
|
srb.CDBByte[0] = SCSI_READ_TOC;
|
|
srb.CDBByte[6] = 0;
|
|
srb.CDBByte[7] = 0x03;
|
|
srb.CDBByte[8] = 0x24;
|
|
|
|
if(Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY)
|
|
!= CDVD_ERROR_SUCCESS)
|
|
return CDVD_ERROR_FAIL;
|
|
|
|
if(ExtractTocData(buff) != CDVD_ERROR_SUCCESS)
|
|
return CDVD_ERROR_FAIL;
|
|
|
|
return CDVD_ERROR_SUCCESS;
|
|
}
|
|
|
|
// set cdrom speed
|
|
int CCdvd::Aspi_SetSpeed(int speed)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
UI16 kbSpeed = 0xFFFF;
|
|
switch(speed)
|
|
{
|
|
case 0: kbSpeed = 0xFFFF; break;
|
|
case 1: kbSpeed = 176; break;
|
|
case 2: kbSpeed = 353; break;
|
|
case 3: kbSpeed = 528; break;
|
|
case 4: kbSpeed = 706; break;
|
|
case 5: kbSpeed = 1400; break;
|
|
case 6: kbSpeed = 2800; break;
|
|
default: kbSpeed = 0xFFFF; break; // max
|
|
}
|
|
|
|
memset(&srb,0,sizeof(srb));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_Flags = SRB_DIR_OUT; //|SRB_ENABLE_RESIDUAL_COUNT;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
|
|
srb.SRB_CDBLen = 12;
|
|
srb.CDBByte[0] = 0xBB;
|
|
srb.CDBByte[2] = HIBYTE(kbSpeed);
|
|
srb.CDBByte[3] = LOBYTE(kbSpeed);
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// used for scsi only, sets sector size (i.e, 2352, 2048)
|
|
int CCdvd::Aspi_SetSectorSize(int sect_size)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
TRACE("sectorsize: %ld\n", sect_size);
|
|
MODESELHEADER mh;
|
|
SRB_ExecSCSICmd srb;
|
|
|
|
memset (&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
memset (&mh, 0, sizeof(MODESELHEADER));
|
|
|
|
mh.block_desc_length = 0x08;
|
|
mh.block_length_med = HIBYTE(LOWORD(sect_size));
|
|
mh.block_length_lo = LOBYTE(LOWORD(sect_size));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_Flags = SRB_DIR_OUT;
|
|
srb.SRB_BufLen = sizeof(mh);
|
|
srb.SRB_BufPointer = (UI08 *) &mh;
|
|
srb.SRB_CDBLen = 6;
|
|
srb.CDBByte[0] = 0x15;
|
|
srb.CDBByte[1] = 0x10;
|
|
srb.CDBByte[4] = 0x0C;
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// start cddda playback, dunno if it works right really.. :p
|
|
int CCdvd::Aspi_Play(int sect_start, int sect_stop)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
|
|
memset( &srb, 0, sizeof(SRB_ExecSCSICmd) );
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_CDBLen = 12;
|
|
|
|
srb.CDBByte[0] = 0xa5;
|
|
srb.CDBByte[2] = HIBYTE(HIWORD(sect_start));
|
|
srb.CDBByte[3] = LOBYTE(HIWORD(sect_start));
|
|
srb.CDBByte[4] = HIBYTE(LOWORD(sect_start));
|
|
srb.CDBByte[5] = LOBYTE(LOWORD(sect_start));
|
|
srb.CDBByte[6] = HIBYTE(HIWORD(sect_stop));
|
|
srb.CDBByte[7] = LOBYTE(HIWORD(sect_stop));
|
|
srb.CDBByte[8] = HIBYTE(LOWORD(sect_stop));
|
|
srb.CDBByte[9] = LOBYTE(LOWORD(sect_stop));
|
|
// srb.CDBByte[10] = 0x8F;
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// stop cdda playback, dunno if it works right really.. :p
|
|
int CCdvd::Aspi_Stop()
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
|
|
memset(&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_CDBLen = 10;
|
|
srb.CDBByte[0] = 0x4E;
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// detect if media/LUN is ready, legacy command,
|
|
// can prolly be substituted with GetMediaType(), with some modifs
|
|
int CCdvd::Aspi_TestReady()
|
|
{
|
|
SRB_ExecSCSICmd srb;
|
|
|
|
memset (&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_CDBLen = 6;
|
|
srb.CDBByte[0] = SCSI_TST_U_RDY;
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|
|
|
|
// retrieve feature details
|
|
int CCdvd::Aspi_GetConfiguration(UI16 feature, UI08 *dest, UI32 dest_size)
|
|
{
|
|
_ASSERT(m_bAspiInitialized == TRUE);
|
|
|
|
int retval = CDVD_ERROR_SUCCESS;
|
|
|
|
SRB_ExecSCSICmd srb;
|
|
memset(&srb, 0, sizeof(SRB_ExecSCSICmd));
|
|
memset(dest, 0, dest_size);
|
|
|
|
srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
|
srb.SRB_HaId = m_drvDetails[m_nCurrentDrive].ha;
|
|
srb.SRB_Target = m_drvDetails[m_nCurrentDrive].id;
|
|
srb.SRB_Lun = m_drvDetails[m_nCurrentDrive].lun;
|
|
srb.SRB_Flags = SRB_DIR_IN;
|
|
srb.SRB_SenseLen = SENSE_LEN;
|
|
srb.SRB_BufPointer = dest;
|
|
srb.SRB_BufLen = dest_size;
|
|
|
|
srb.SRB_CDBLen = 12;
|
|
srb.CDBByte[0] = 0x46;
|
|
srb.CDBByte[1] = 0x02; // return a single feature set ONLY.
|
|
srb.CDBByte[2] = HIBYTE(feature);
|
|
srb.CDBByte[3] = LOBYTE(feature);
|
|
srb.CDBByte[7] = HIBYTE(dest_size);
|
|
srb.CDBByte[8] = LOBYTE(dest_size);
|
|
|
|
return Aspi_ExecuteSrb(srb, NULL, CDVD_MAX_RETRY);
|
|
}
|