home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cdrom.zip
/
DDK
/
BASE
/
SRC
/
DEV
/
DASD
/
CDROM
/
OS2CDROM
/
cdioc80.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-18
|
46KB
|
1,441 lines
/**************************************************************************
*
* SOURCE FILE NAME = CDIOC80.C
*
* DESCRIPTIVE NAME = IOCTL handling routines for OS/2 CD-ROM Device Mgr
*
* Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
* LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
* REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
* RESTRICTED MATERIALS OF IBM
* IBM CONFIDENTIAL
*
* VERSION = V2.0
*
* DATE
*
* DESCRIPTION
*
*
* FUNCTIONS
*
* ENTRY POINTS:
*
* DEPENDENCIES:
*
* NOTES
*
*
* STRUCTURES
*
* EXTERNAL REFERENCES
*
* EXTERNAL FUNCTIONS
*
* CHANGE ACTIVITY =
* DATE FLAG APAR CHANGE DESCRIPTION
* -------- ---------- ----- --------------------------------------
* 09/08/95 @V135221 Sam Detweiler - CD-ROM changer support
*
****************************************************************************/
#include "cdh.h"
#include "dskioctl.h"
USHORT GetRawBlockSize (NPUNITCB);
/****************************************************************************
*
* FUNCTION NAME = CD_ResetDrive
*
* DESCRIPTION = Issue a reset drive command to the device.
*
* USHORT CD_ResetDrive (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ResetDrive (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc, i;
BOOL playing;
NPIORB_CDB pIORB;
struct Status *audio_status;
struct Audio *audio;
/*
** If device is playing, return DEVICE_IN_USE error
*/
rc = GetPlayStatus (pUnitCB, &playing);
if ( (rc == STDON) && playing)
return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
/*
** First, abort any oustanding commands on the device
*/
BuildIORB_DeviceControl (pUnitCB, IOCM_ABORT, (NPIORB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
/*
** Reset the device
*/
/*
** BuildIORB_DeviceControl (pUnitCB, IOCM_RESET, (NPIORB FAR *) &pIORB);
**
** rc = SubmitIORB_Wait (pUnitCB, pIORB);
**
** FreeIORB (pUnitCB, pIORB);
*/
/*
** Recover from the reset. First clear the check condition from the
** reset. Then delay long enough to recover from the not ready to
** ready transition.
*/
ClearCheckCondition(pUnitCB);
for (i = 1; i <= 10; i++)
{
DevHelp_ProcBlock( (ULONG) ppDataSeg, (ULONG) 1000, 0);
BuildCDB_TestUnitReady (pUnitCB, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if (rc == STDON)
break;
}
/*
** Issue SCSI Pause Command. Ignore the RC
*/
/*
** if (pUnitCB->Flags & UCF_AUDIO_SUPPORTED)
** {
** BuildCDB_PauseResume (pUnitCB, CDBF_PAUSE, (NPIORB_CDB FAR *) &pIORB);
**
** rc = SubmitIORB_Wait (pUnitCB, pIORB);
**
** FreeIORB (pUnitCB, pIORB);
** }
*/
/*
** Update Audio status fields in UnitCB
*/
audio = &pUnitCB->DeviceInfo.Audio;
audio_status = &audio->status;
pUnitCB->DeviceInfo.Audio.capabilities &= ~DCAPS_DOOR_LOCKED;
pUnitCB->Flags &= ~UCF_UNCERTAIN_MEDIA;
audio_status->paused = FALSE;
audio_status->last_start_location.min = 0;
audio_status->last_start_location.sec = 0;
audio_status->last_start_location.frame = 0;
audio_status->last_end_location.min = 0;
audio_status->last_end_location.sec = 0;
audio_status->last_end_location.frame = 0;
return(STDON);
}
/****************************************************************************
*
* FUNCTION NAME = CD_EjectDisk
*
* DESCRIPTION = Issue an eject disk command to the device.
*
* USHORT CD_EjectDisk (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_EjectDisk (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
BOOL playing;
NPIORB_CDB pIORB;
/*
** If device is playing, return DEVICE_IN_USE error
*/
rc = GetPlayStatus (pUnitCB, &playing);
if ( (rc == STDON) && playing)
return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
/*
** Issue SCSI Start-Stop Unit command to eject the media
*/
BuildCDB_StartStopUnit (pUnitCB, CDBF_EJECT, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if (rc == STDON + STERR + ERROR_I24_NOT_READY)
rc = STDON;
if(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CARTRIDGE_CHANGER) //SD@135221
{ //SD@135221
if(pUnitCB->pParentUnitCB) //SD@135221
{ //SD@135221
pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current=0; //SD@135221
} /* endif */ //SD@135221
} /* endif */ //SD@135221
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_CloseTray
*
* DESCRIPTION = Issue a close tray command to the device.
*
* USHORT CD_CloseTray (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_CloseTray (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
BOOL playing;
NPIORB_CDB pIORB;
/*
** If device is playing, return DEVICE_IN_USE error
*/
rc = GetPlayStatus (pUnitCB, &playing);
if ( (rc == STDON) && playing)
return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
/*
** Issue SCSI Start-Stop Unit command to close the tray
*/
BuildCDB_StartStopUnit (pUnitCB, CDBF_CLOSE_TRAY, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if (rc == STDON + STERR + ERROR_I24_NOT_READY)
rc = STDON;
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_LockUnLock
*
* DESCRIPTION = Issue a lock or unlock drive door command to the device.
*
* USHORT CD_LockUnLock (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_LockUnLock (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
NPIORB_CDB pIORB;
USHORT rc, lock_flag;
struct Audio *audio;
audio = &pUnitCB->DeviceInfo.Audio;
if (pRP->Category == 8)
lock_flag = ((PDDI_DsktRemovMediaCtl_param)pRP->ParmPacket)->Command;
else
lock_flag = ((struct LockUnlock FAR *)pRP->ParmPacket)->lock_flag;
if (lock_flag > CDBF_LOCK_DOOR)
return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
/*
** Issue SCSI PreventAllowRemoval command to lock/unlock the media
*/
BuildCDB_PreventAllowRemoval (pUnitCB, lock_flag, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if (rc == STDON)
{
if (lock_flag)
audio->capabilities |= DCAPS_DOOR_LOCKED;
else
audio->capabilities &= ~DCAPS_DOOR_LOCKED;
}
return(rc);
}
/**************************************************************************** //SD@135221
* //SD@135221
* FUNCTION NAME = CD_SetActiveTray //SD@135221
* //SD@135221
* DESCRIPTION = Select the active tray on changer devices //SD@135221
* //SD@135221
* USHORT CD_SetActiveTray ( RP_GENIOCTL pRP, NPUNITCB pUnitCB) //SD@135221
* //SD@135221
* INPUT = pRP - Request Packet //SD@135221
* pUnitCB - Pointer to UnitCB //SD@135221
* //SD@135221
* OUTPUT = USHORT - Packet Status word //SD@135221
* //SD@135221
* RETURN-NORMAL = //SD@135221
* RETURN-ERROR = //SD@135221
* //SD@135221
****************************************************************************/ //SD@135221
//SD@135221
USHORT CD_SetActiveTray (pRP, pUnitCB) //SD@135221
//SD@135221
PRP_GENIOCTL pRP; //SD@135221
NPUNITCB pUnitCB; //SD@135221
//SD@135221
{ //SD@135221
NPIORB_CDB pIORB; //SD@135221
USHORT rc; //SD@135221
//SD@135221
struct SetTray_Parm FAR *pTrayParm; //SD@135221
//SD@135221
if(pUnitCB->DeviceInfo.Audio.capabilities & //SD@135221
(DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER)) //SD@135221
{ //SD@135221
if(pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying==TRUE) //SD@135221
{ //SD@135221
rc=STDON + STERR + ERROR_I24_DEVICE_IN_USE; //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
pTrayParm=(struct SetTray_Parm FAR *)pRP->DataPacket; //SD@135221
if(pTrayParm->Newtray<=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Maximum) //SD@135221
{ //SD@135221
if(pTrayParm->Newtray!=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current)//SD@135221
{ //SD@135221
rc=MakeSlotActive(pUnitCB,pTrayParm->Newtray); //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
rc=STDON; //SD@135221
} /* endelse */ //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER; //SD@135221
} /* endelse */ //SD@135221
} //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER; //SD@135221
} /* endelse */ //SD@135221
//SD@135221
return(rc); //SD@135221
//SD@135221
}
/****************************************************************************
*
* FUNCTION NAME = CD_Seek
*
* DESCRIPTION = Issue a seek command to the device.
*
* USHORT CD_Seek (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_Seek(pRP,pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
BOOL playing;
NPIORB_CDB pIORB;
struct Seek FAR *pParmPacket;
union ULONGB ul_LBA;
pParmPacket = (struct Seek FAR *) pRP->ParmPacket;
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
ul_LBA.dword = pParmPacket->start_sector;
switch(pParmPacket->address_mode)
{
case CDROM_HSG_MODE:
break;
case CDROM_REDBOOK_MODE:
ul_LBA.dword = RedBookToHSG (ul_LBA.dword);
break;
default:
return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
}
rc = GetPlayStatus (pUnitCB, &playing);
if ( (rc == STDON) && playing)
return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
/*
** Issue the seek. If there's a seek error and the density code is not
** for CD-DA, the issue the Mode Select to change the density to CD-DA
** and retry the seek operation.
*/
if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
BuildCDB_Seek_10(pUnitCB, (ULONG)ul_LBA.dword, (NPIORB_CDB FAR *)&pIORB);
else
BuildCDB_Seek_6(pUnitCB, (ULONG)ul_LBA.dword, (NPIORB_CDB FAR *)&pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if ( (rc == STDON + STERR + ERROR_I24_SEEK) &&
( (pUnitCB->DeviceInfo.product_id_code == TOSHIBA_3301) ||
(pUnitCB->DeviceInfo.product_id_code == TOSHIBA_3401) ) &&
(pUnitCB->DeviceInfo.current_density != CD_DENSITY_CDDA) )
{
BuildCDB_ModeSelect (pUnitCB, CD_DENSITY_CDDA, 2352,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
if (rc == STDON)
{
pUnitCB->DeviceInfo.current_density = CD_DENSITY_CDDA;
pUnitCB->DeviceInfo.current_block_size = 2352;
}
FreeIORB (pUnitCB, pIORB);
if (rc == STDON)
{
BuildCDB_Seek_6 (pUnitCB,(ULONG) ul_LBA.dword,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
}
}
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_WriteLong
*
* DESCRIPTION = Issue a write long command to the device.
*
* USHORT CD_WriteLong (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_WriteLong (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
return (STDON + STERR + ERROR_I24_WRITE_FAULT);
}
/****************************************************************************
*
* FUNCTION NAME = CD_WriteVLong
*
* DESCRIPTION = Issue a write verify long command to the device.
*
* USHORT CD_WriteVLong (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_WriteVLong (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
return (STDON + STERR + ERROR_I24_WRITE_FAULT);
}
/****************************************************************************
*
* FUNCTION NAME = CD_DeviceStatus
*
* DESCRIPTION = Return device status.
*
* USHORT CD_DeviceStatus (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_DeviceStatus (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
ULONG device_status;
BOOL playing;
device_status = DSF_DEFAULT;
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_DOOR_LOCKED)
device_status &= ~DSF_DOOR_UNLOCKED;
if ( (rc = GetPlayStatus (pUnitCB, &playing)) & STERR)
playing = 0;
if (playing)
device_status |= DSF_PLAYING;
rc = ClearCheckCondition(pUnitCB);
if (rc == STDON + STERR + ERROR_I24_NOT_READY)
device_status |= DSF_DOOR_OPEN + DSF_NO_DISK_PRESENT;
if (pUnitCB->DeviceInfo.product_id_code != TOSHIBA_3201)
device_status |= DSF_LONG_SECTORS;
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_XA)
device_status |= DSF_XA_SUPPORT;
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CDDA)
device_status |= DSF_CDDA_SUPPORT;
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CARTRIDGE_CHANGER) //SD@135221
device_status |= DSF_CARTRIDGE_CHANGER; //SD@135221
//SD@135221
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_INDIVIDUAL_CHANGER) //SD@135221
device_status |= DSF_INDIVIDUAL_CHANGER; //SD@135221
((struct DeviceStatus_Data FAR *)pRP->DataPacket)->device_status =
(ULONG) device_status;
return(STDON);
}
/**************************************************************************** //SD@135221
* //SD@135221
* FUNCTION NAME = CD_TrayStatus //SD@135221
* //SD@135221
* DESCRIPTION = Return tray count/active tray for changer devices //SD@135221
* //SD@135221
* USHORT CD_TrayStatus (PRP_GENIOCTL pRP, NPUNITCB pUnitCB) //SD@135221
* //SD@135221
* INPUT = pRP - Request Packet //SD@135221
* pUnitCB - Pointer to UnitCB //SD@135221
* //SD@135221
* OUTPUT = USHORT - Packet Status word //SD@135221
* //SD@135221
* RETURN-NORMAL = //SD@135221
* RETURN-ERROR = //SD@135221
* //SD@135221
****************************************************************************/ //SD@135221
//SD@135221
USHORT CD_TrayStatus (pRP, pUnitCB) //SD@135221
//SD@135221
PRP_GENIOCTL pRP; //SD@135221
NPUNITCB pUnitCB; //SD@135221
//SD@135221
{ //SD@135221
USHORT rc; //SD@135221
struct ReturnTrayStatus_Data FAR *pTrayStatus; //SD@135221
//SD@135221
if(pUnitCB->DeviceInfo.Audio.capabilities & //SD@135221
(DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER)) //SD@135221
{ //SD@135221
pTrayStatus=(struct ReturnTrayStatus_Data FAR *)pRP->DataPacket; //SD@135221
pTrayStatus->Count=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Maximum; //SD@135221
pTrayStatus->Current=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current; //SD@135221
pTrayStatus->AssignedSLot=pUnitCB->DeviceInfo.Slot; //SD@135221
rc=STDON; //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER; //SD@135221
} /* endelse */ //SD@135221
return rc; //SD@135221
} //SD@135221
/****************************************************************************
*
* FUNCTION NAME = CD_Identify
*
* DESCRIPTION = Identify device.
*
* USHORT CD_Identify (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_Identify (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
struct IdentifyCDROMdriver FAR *pParmPkt;
struct IdentifyCDROMdriver_Data FAR *pDataPkt;
union ULONGB parameter;
USHORT rc = 0;
pParmPkt = (struct IdentifyCDROMdriver FAR *) pRP->ParmPacket;
pDataPkt = (struct IdentifyCDROMdriver_Data FAR *) pRP->DataPacket;
/*
** rc = VerifyAccess (pParmPkt,
** sizeof(struct IdentifyCDROMdriver),
** READ_ACCESS);
** if (rc & STERR)
** return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
**
*/
parameter.dword = pParmPkt->ID_code;
if (parameter.ulbwords.word_0 != CD)
return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
if (parameter.ulbytes.byte_2 > '9' || parameter.ulbytes.byte_2 < '0')
return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
if (parameter.ulbytes.byte_3 > '9' || parameter.ulbytes.byte_3 < '0')
return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
/*
**
** rc = VerifyAccess (pDataPkt,
** sizeof(struct IdentifyCDROMdriver_data),
** READ_WRITE_ACCESS);
*/
if (rc & STERR)
return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
pDataPkt->ID_code = CD01;
return(STDON);
}
/****************************************************************************
*
* FUNCTION NAME = CD_ReturnSectorSize
*
* DESCRIPTION = Return the sector size of the volume.
*
* USHORT CD_ReturnSectorSize (PRP_GENIOCTL pRP,
* NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ReturnSectorSize (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
if ( (rc = ClearCheckCondition(pUnitCB)) ==
STDON + STERR + ERROR_I24_NOT_DOS_DISK)
{
return(rc);
}
((struct ReturnSectorSize_Data FAR *)pRP->DataPacket)->sector_size =
CDROM_SECTOR_SIZE;
return(STDON);
}
/****************************************************************************
*
* FUNCTION NAME = CD_HeadLocation
*
* DESCRIPTION = Return the current head location.
*
* USHORT CD_HeadLocation(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_HeadLocation (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
NPIORB_CDB pIORB;
USHORT rc, address_mode;
struct SubChannel_Position NEAR *pCDBData;
struct LocationOfHead_Data FAR *pDataPkt;
union AddressType location;
pDataPkt = (struct LocationOfHead_Data FAR *) pRP->DataPacket;
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
return (STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
address_mode = ((struct LocationOfHead FAR *)pRP->ParmPacket)->address_mode;
if (address_mode > CDROM_REDBOOK_MODE)
return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
if ( (rc = ClearCheckCondition (pUnitCB) ) & STERR)
return(rc);
/*
** Issue SCSI Read SubChannel - Current Position Command
*/
BuildCDB_ReadSubChannel(pUnitCB, RSC_CURRENT_POSITION,
(NPIORB_CDB FAR *) &pIORB);
if ( (rc = SubmitIORB_Wait(pUnitCB, pIORB, (PBYTE) pRP)) == STDON)
{
/*
** Return the current head location from the CDB data area
*/
pCDBData = (struct SubChannel_Position NEAR *) pIORB->CDB_data;
if (pUnitCB->DeviceInfo.product_id_code == NEC_260_17B)
{
location.ul_redbook.min
= BCDtoBinary(pCDBData->abs_address.redbook.min);
location.ul_redbook.sec
= BCDtoBinary(pCDBData->abs_address.redbook.sec);
location.ul_redbook.frame
= BCDtoBinary(pCDBData->abs_address.redbook.frame);
}
else
{
location.ul_redbook.min = pCDBData->abs_address.redbook.min;
location.ul_redbook.sec = pCDBData->abs_address.redbook.sec;
location.ul_redbook.frame = pCDBData->abs_address.redbook.frame;
}
location.ul_redbook.zero = 0;
if (address_mode == CDROM_HSG_MODE)
location.dword = RedBookToHSG (location.dword);
}
pDataPkt->location_of_head = location.dword;
FreeIORB(pUnitCB, pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_ReadPrefetch
*
* DESCRIPTION = Read prefetch.
*
* USHORT CD_ReadPrefetch(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ReadPrefetch (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc, transfer_count;
struct ReadPrefetch FAR *pParmPacketR;
struct Seek FAR *pParmPacketS;
pParmPacketR = (struct ReadPrefetch FAR *) pRP->ParmPacket;
pParmPacketS = (struct Seek FAR *) pRP->ParmPacket;
/*
** Convert the prefech to a seek operation
*/
transfer_count = pParmPacketR->transfer_count;
pParmPacketS->start_sector = pParmPacketR->start_sector;
rc = CD_Seek (pRP, pUnitCB);
/*
** Put the Read Prefetch parameter packet back to original
*/
pParmPacketR->start_sector = pParmPacketS->start_sector;
pParmPacketR->transfer_count = transfer_count;
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_ReadLong
*
* DESCRIPTION = Read long.
*
* USHORT CD_ReadLong(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ReadLong (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
BOOL playing;
USHORT rc, raw_block_size;
struct ReadLong FAR *pParmPacket;
union ULONGB ul_LBA;
ULONG ppDataBuff;
USHORT transfer_count;
pParmPacket = (struct ReadLong FAR *) pRP->ParmPacket;
ul_LBA.dword = pParmPacket->start_sector;
switch(pParmPacket->address_mode)
{
case CDROM_HSG_MODE:
break;
case CDROM_REDBOOK_MODE:
ul_LBA.dword = RedBookToHSG (ul_LBA.dword);
break;
default:
return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
}
/*
** Check for uncertain media. Also, cant read while play in progress
*/
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
return (STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
if ( pUnitCB->DeviceInfo.playing )
{
rc = GetPlayStatus (pUnitCB, &playing);
if (rc == STDON && playing)
return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
}
rc = DevHelp_VirtToPhys (pRP->DataPacket, (PULONG) &ppDataBuff);
transfer_count = pParmPacket->transfer_count;
/*
** Determine what the device's raw block size is. Some drives
** support reading all 2352 bytes, others only support 2340. The call
** is only done the first time a read long is issued.
*/
if (pUnitCB->DeviceInfo.raw_block_size == 0)
{
if ( (rc = GetRawBlockSize(pUnitCB)) & STERR)
return(rc);
}
raw_block_size = pUnitCB->DeviceInfo.raw_block_size;
switch (pUnitCB->DeviceInfo.product_id_code)
{
case TOSHIBA_3301:
case TOSHIBA_3401:
rc = Tosh_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
transfer_count, ppDataBuff);
break;
case SONY_561:
rc = Sony_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
transfer_count, ppDataBuff);
break;
default:
if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
rc = ATAPI_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
transfer_count, ppDataBuff);
else
rc = CD_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
transfer_count, ppDataBuff);
if (rc == STDON && raw_block_size == 2340)
PadRaw2340 (pRP->DataPacket, pParmPacket->transfer_count);
break;
}
if (rc == STDON + STERR + ERROR_I24_BAD_COMMAND)
rc = STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND;
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_Read_2352
*
* DESCRIPTION = Read default CD-ROM Mode 1 sector with blocksize = 2352
*
* USHORT CD_Read_2352 (NPUNITCB pUnitCB, ULONG LBA,
* USHORT transfer_count, ULONG ppDataBuff)
*
* INPUT = pUnitCB - Pointer to UnitCB
* LBA - LBA
* transfer_count - count of sectors to transfer
* ppDataBuff - phys addr of data buffer
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_Read_2352 (pUnitCB, LBA, transfer_count, ppDataBuff)
NPUNITCB pUnitCB;
ULONG LBA;
USHORT transfer_count;
ULONG ppDataBuff;
{
USHORT rc, raw_sector_size;
raw_sector_size = pUnitCB->DeviceInfo.raw_block_size;
/*
** If the current block size is not a long sector, then issue
** a SCSI Mode Select command to set the block size.
*/
if ((pUnitCB->DeviceInfo.current_block_size != raw_sector_size) &
!(pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI))
{
rc = ChainModeSelectRead (pUnitCB, LBA, transfer_count, ppDataBuff,
raw_sector_size, 0);
}
else
{
rc = ReadSector (pUnitCB, LBA, transfer_count,
ppDataBuff, raw_sector_size);
}
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = ATAPI_Read_2352
*
* DESCRIPTION = Read 2352 byte sector on ATAPI device
*
* USHORT ATAPI_Read_2352 (NPUNITCB pUnitCB, ULONG LBA,
* USHORT transfer_count, ULONG ppDataBuff)
*
* INPUT = pUnitCB - Pointer to UnitCB
* LBA - LBA
* transfer_count - count of sectors to transfer
* ppDataBuff - phys addr of data buffer
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ATAPI_Read_2352 (pUnitCB, LBA, transfer_count, ppDataBuff)
NPUNITCB pUnitCB;
ULONG LBA;
USHORT transfer_count;
ULONG ppDataBuff;
{
USHORT rc;
NPIORB_CDB pIORB;
/*
** Issue ATAPI Read CD command which should read any target sector,
** including 2352 byte Mode 1, 2352 byte Mode 2 Form 1, 2352 byte
** Mode 2 Form 2, and 2352 byte CD-DA
*/
ATAPI_BuildCDB_ReadCD (pUnitCB, LBA, transfer_count,
ppDataBuff, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = GetRawBlockSize
*
* DESCRIPTION = Get the max raw block size the device supports.
*
* USHORT GetRawBlockSize (NPUNITCB, pUnitCB,
* (USHORT FAR *) raw_block_size)
*
* INPUT = pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetRawBlockSize (pUnitCB)
NPUNITCB pUnitCB;
{
USHORT rc;
NPIORB_CDB pIORB;
/*
** Assume all ATAPI drives support returning a full 2352 byte sector.
*/
if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
{
pUnitCB->DeviceInfo.raw_block_size = 2352;
return(STDON);
}
/*
** First See if a block size of 2352 bytes is supported
*/
rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2352);
if (rc == STDON)
pUnitCB->DeviceInfo.raw_block_size = 2352;
else
{
/*
** 2352 not supported, try 2340
*/
rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2340);
if (rc == STDON)
pUnitCB->DeviceInfo.raw_block_size = 2340;
}
/*
** Put the block size back to 2048
*/
rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2048);
if (rc == STDON)
{
pUnitCB->DeviceInfo.current_density = CD_DENSITY_DEFAULT;
pUnitCB->DeviceInfo.current_block_size = 2048;
}
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_ReadLongPre
*
* DESCRIPTION = Read long.
*
* USHORT CD_ReadLongPre(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ReadLongPre (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
return ( CD_ReadPrefetch (pRP, pUnitCB) );
}
/****************************************************************************
*
* FUNCTION NAME = CD_ReturnVolumeSize
*
* DESCRIPTION = Get volume size,
*
* USHORT CD_ReturnVolumeSize(PRP_GENIOCTL pRP,
* NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_ReturnVolumeSize (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
ULONG volume_size;
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
rc = GetVolumeSize (pUnitCB, &volume_size);
if (rc == STDON)
((struct ReturnVolumeSize_Data FAR *)pRP->DataPacket)->volume_size =
volume_size;
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_GetUPC
*
* DESCRIPTION = Get UPC.
*
* USHORT CD_GetUPC(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_GetUPC (pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc, i;
NPIORB_CDB pIORB;
struct UPCCode_Data FAR *pDataPkt;
union CDROM_SubChannel_Info NEAR *q_data;
USHORT GotUPC = NO;
pDataPkt = (struct UPCCode_Data FAR *) pRP->DataPacket;
if ( ! (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC) )
return(STDON + STERR + ERROR_I24_BAD_COMMAND);
/*
** First, issue ReadSubChannel for Current Position
*/
ClearCheckCondition (pUnitCB);
BuildCDB_ReadSubChannel(pUnitCB, RSC_CURRENT_POSITION,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if (rc == STDON)
{
q_data = (union CDROM_SubChannel_Info NEAR *) pIORB->CDB_data;
pDataPkt->adr_control = (q_data->current_position.control << 4) |
q_data->current_position.ADR;
/*
** if (pDataPkt->adr_control & 0x0F)
** pDataPkt->adr_control = ((q_data->current_position.control << 4) |
** MODE_2);
*/
pDataPkt->zero = 0;
pDataPkt->aframe = q_data->current_position.abs_address.redbook.frame;
}
FreeIORB (pUnitCB, pIORB);
/*
** Issue SCSI Read SubChannel - Get UPC Code
*/
if (rc == STDON)
{
ClearCheckCondition (pUnitCB);
BuildCDB_ReadSubChannel(pUnitCB, RSC_MEDIA_CAT_NUM,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if (rc == STDON)
{
q_data = (union CDROM_SubChannel_Info NEAR *) pIORB->CDB_data;
/*
** Make sure media catalog number field is valid
*/
if (q_data->media_cat_number.mcval)
{
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC_IN_BCD)
{
pDataPkt->upc_ean_code.upc_byte0 =
q_data->media_cat_number.media_catalog_no[0];
pDataPkt->upc_ean_code.upc_byte1 =
q_data->media_cat_number.media_catalog_no[1];
pDataPkt->upc_ean_code.upc_byte2 =
q_data->media_cat_number.media_catalog_no[2];
pDataPkt->upc_ean_code.upc_byte3 =
q_data->media_cat_number.media_catalog_no[3];
pDataPkt->upc_ean_code.upc_byte4 =
q_data->media_cat_number.media_catalog_no[4];
pDataPkt->upc_ean_code.upc_byte5 =
q_data->media_cat_number.media_catalog_no[5];
pDataPkt->upc_ean_code.upc_byte6 =
q_data->media_cat_number.media_catalog_no[6];
}
else
{
if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC_IN_ASCII)
{
for (i = 0; i <= 13; i++)
q_data->media_cat_number.media_catalog_no[i] -= 0x30;
}
pDataPkt->upc_ean_code.upc_byte0 =
q_data->media_cat_number.media_catalog_no[0] << 4 |
q_data->media_cat_number.media_catalog_no[1];
pDataPkt->upc_ean_code.upc_byte1 =
q_data->media_cat_number.media_catalog_no[2] << 4 |
q_data->media_cat_number.media_catalog_no[3];
pDataPkt->upc_ean_code.upc_byte2 =
q_data->media_cat_number.media_catalog_no[4] << 4 |
q_data->media_cat_number.media_catalog_no[5];
pDataPkt->upc_ean_code.upc_byte3 =
q_data->media_cat_number.media_catalog_no[6] << 4 |
q_data->media_cat_number.media_catalog_no[7];
pDataPkt->upc_ean_code.upc_byte4 =
q_data->media_cat_number.media_catalog_no[8] << 4 |
q_data->media_cat_number.media_catalog_no[9];
pDataPkt->upc_ean_code.upc_byte5 =
q_data->media_cat_number.media_catalog_no[10] << 4 |
q_data->media_cat_number.media_catalog_no[11];
pDataPkt->upc_ean_code.upc_byte6 =
q_data->media_cat_number.media_catalog_no[12] << 4 |
q_data->media_cat_number.media_catalog_no[13];
}
GotUPC = YES;
}
}
FreeIORB (pUnitCB, pIORB);
}
/*
** Add error checking code
*/
if (GotUPC == NO)
{
pDataPkt->adr_control = 0;
pDataPkt->upc_ean_code.upc_byte0 = 0;
pDataPkt->upc_ean_code.upc_byte1 = 0;
pDataPkt->upc_ean_code.upc_byte2 = 0;
pDataPkt->upc_ean_code.upc_byte3 = 0;
pDataPkt->upc_ean_code.upc_byte4 = 0;
pDataPkt->upc_ean_code.upc_byte5 = 0;
pDataPkt->upc_ean_code.upc_byte6 = 0;
pDataPkt->zero = 0;
pDataPkt->aframe = 0;
}
/*
** Clear media changed check condition on Sony CDU-541 after
** UPC command issued.
*/
ClearCheckCondition (pUnitCB);
if (pUnitCB->DeviceInfo.product_id_code == SONY_541)
pUnitCB->Flags &= ~UCF_UNCERTAIN_MEDIA;
return (STDON);
}