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
/
cdstrat1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-18
|
60KB
|
1,786 lines
/**************************************************************************
*
* SOURCE FILE NAME = CDSTRAT1.C
*
* DESCRIPTIVE NAME = Strategy 1 interface for OS/2 CDROM Device Manager
*
* 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 Provides validation and routing of Strategy 1 requests
* received from the OS/2 Kernel.
*
* ENTRY POINTS:
*
* DEPENDENCIES:
*
* NOTES
*
*
* STRUCTURES
*
* EXTERNAL REFERENCES
*
* EXTERNAL FUNCTIONS
*
* CHANGE ACTIVITY =
* DATE FLAG DEFECT CHANGE DESCRIPTION
* -------- -------- ------ --------------------------------------
* 08/22/94 @V91985 91985 1) Mask errors for reads of sector 0 length 1
* from the kernel. 2) Pause while trying to
* access a not ready device. 3) Allow ATAPI
* devices to return lock status from device.
* 09/04/94 @V96674 96674 Change the fix for defect 91985 to: If the
* file system is attempting to read sector 0 and
* it fails, attempt to read the volume descriptor
* at sector 16 and return the error generated if
* any. This will allow mounting of XAS disks but
* will also return the sector not found for audio
* discs at the earliest read.
* 09/08/95 @V135221 Sam Detweiler - CD-ROM changer support
* 11/15/95 @V132783 Fix trap while booting with CDI disk
* 11/15/95 @V142227 Fix read error on video CD after reading
* multisession CD.
* 04/23/96 @V151345 Breakup requests greater than 64K-1 to ATAPI
* devices
* 05/28/96 @V156096 Sam Detweiler - HP update
****************************************************************************/
#include "cdh.h"
USHORT NonSCSI_GetLastSessionAddr (NPUNITCB, ULONG FAR *);
CMDFUNC functable[]= //SD@135221
{ /*--------------------------------------*/ //SD@135221
{CD_DriveInit, TRUE }, /* 0x00 initialize */ //SD@135221
{CD_MediaCheck, FALSE}, /* 0x01 check the media */ //SD@135221
{CD_BuildBPB, TRUE,}, /* 0x02 build BPB */ //SD@135221
{CmdErr, TRUE }, /* 0x03 reserved */ //SD@135221
{CD_Read, FALSE}, /* 0x04 read */ //SD@135221
{CmdErr, TRUE }, /* 0x05 non-destructive read */ //SD@135221
{CmdErr, TRUE }, /* 0x06 input status */ //SD@135221
{CmdErr, TRUE }, /* 0x07 input flush */ //SD@135221
{WriteErr, TRUE }, /* 0x08 write */ //SD@135221
{WriteVErr, TRUE }, /* 0x09 write with verify */ //SD@135221
{CmdErr, TRUE }, /* 0x0A get output status */ //SD@135221
{CmdErr, TRUE }, /* 0x0B flush output */ //SD@135221
{CmdErr, TRUE }, /* 0x0C reserved */ //SD@135221
{StatusComplete, TRUE }, /* 0x0D open */ //SD@135221
{StatusComplete, TRUE }, /* 0x0E close */ //SD@135221
{RemovableMedia, TRUE }, /* 0x0F removable media */ //SD@135221
{DriveGenIOCTL, TRUE}, /* 0x10 generic IOCTL */ //SD@135221
{ResetMedia, FALSE}, /* 0x11 reset uncertain media */ //SD@135221
{GetLogDriveMap, TRUE }, /* 0x12 get Logical Drive Map */ //SD@135221
{SetLogDriveMap, TRUE }, /* 0x13 set Logical Drive Map */ //SD@135221
{CmdErr, TRUE }, /* 0x14 de-Install this device */ //SD@135221
{CmdErr, TRUE }, /* 0x15 reserved */ //SD@135221
{PartFixedDisks, TRUE }, /* 0x16 get number of partitions */ //SD@135221
{GetUnitMap, TRUE }, /* 0x17 get unit map */ //SD@135221
{CD_Read, FALSE}, /* 0x18 no caching read */ //SD@135221
{WriteErr, TRUE }, /* 0x19 no caching write */ //SD@135221
{WriteVErr, TRUE }, /* 0x1A no caching write/verify */ //SD@135221
{CD_DriveInit, TRUE }, /* 0x1B initialize */ //SD@135221
{StatusComplete, TRUE }, /* 0x1C prepare for shutdown */ //SD@135221
{CmdErr, TRUE }, /* 0x1D Get Driver Capabilities */ //SD@135221
}; /*--------------------------------------*/ //SD@135221
/****************************************************************************
*
* FUNCTION NAME = CD_Strat1
*
* DESCRIPTION = OS2CDROM strategy 1 routine
*
* INPUT = ES:BX - pointer to Request Packet
*
* OUTPUT =
*
* RETURN-NORMAL =
*
* RETURN-ERROR =
*
****************************************************************************/
void near CD_Strat1(pRPH)
PRPH pRPH;
{
NPUNITCB pUnitCB;
USHORT Cmd, Status;
pRPH->Status = 0;
pRPH->Flags = 0;
Cmd = pRPH->Cmd;
/*
** Filter out invalid requests
*/
/*
**if (DDFlags & DDF_NO_MEDIA)
**{
** Status = STDON + STERR + ERROR_I24_BAD_UNIT;
** goto ExitDiskDD;
**}
*/
if (Cmd > MAX_DISKDD_CMD)
{
Status = STDON + STERR + ERROR_I24_BAD_COMMAND;
goto ExitDiskDD;
}
if ( (Get_UnitCB_Addr(pRPH->Unit, (NPUNITCB FAR *) &pUnitCB) != NO_ERROR) &&
(Cmd != CMDInitBase) &&
(Cmd != CMDInit) &&
(Cmd != CMDPartfixeddisks) )
{
Status = STDON + STERR + ERROR_I24_BAD_UNIT;
goto ExitDiskDD;
}
/*
**if ( (Cmd != CMDInitBase) && IsTraceOn() )
** Trace(TRACE_STRAT1 | TRACE_ENTRY, (PBYTE) pRPH, pUnitCB);
*/
/*
** Call Worker Routine
*/
if((CDFlags & CDF_INIT_COMPLETE) && //SD@135221
(pUnitCB->DeviceInfo.Audio.capabilities & (DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER)))//SD@135221
{ //SD@135221
// only ATAPI devices support this flag today //SD@135221
if(pUnitCB->pParentUnitCB) //SD@135221
{ //SD@135221
// serialize here //SD@135221
#define SEM_INDEFINITE_WAIT ((ULONG)(-1L)) //SD@135221
DevHelp_SemRequest((ULONG)(&pUnitCB->pParentUnitCB->Semaphore),SEM_INDEFINITE_WAIT);//SD@135221
// if we have a parent, and the active slot is not ours //SD@135221
if(!(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_SINGLE_MODE)) //SD@135221
{ //SD@135221
if(pUnitCB->pParentUnitCB && (pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current!=pUnitCB->DeviceInfo.Slot))//SD@135221
{ //SD@135221
// load cd for requested Unit, may fail (no disk etc) //SD@135221
Status = MakeSlotActive(pUnitCB,(UCHAR)pUnitCB->DeviceInfo.Slot);//SD@135221
if(Status!=STDON && functable[Cmd].ChangerAllowed==TRUE) //SD@135221
{ //SD@135221
Status=STDON; //SD@135221
} /* endif */ //SD@135221
} //SD@135221
else //SD@135221
{ //SD@135221
Status=STDON; //SD@135221
} //SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
Status=STDON; //SD@135221
} //SD@135221
// if slot is now active one //SD@135221
if(Status==STDON) //SD@135221
{ //SD@135221
Status = (*functable[Cmd].Strat1Near)(pRPH, pUnitCB); //SD@135221
} /* endif */ //SD@135221
// deserialize here //SD@135221
DevHelp_SemClear((ULONG)(&pUnitCB->pParentUnitCB->Semaphore)); //SD@135221
} /* endif */ //SD@135221
} /* endif */ //SD@135221
else //SD@135221
Status = (*functable[Cmd].Strat1Near)(pRPH, pUnitCB);
/*
** Finish up by setting the Status word in the Request Packet Header
*/
ExitDiskDD: ;
DISABLE;
pRPH->Status = Status; /* Save status in Request Packet */
ENABLE;
/*
**if ( (TraceFlags != 0) && (pRPH->Status & STDON) && (Cmd != CMDInitBase) )
** Trace(TRACE_STRAT1 | TRACE_EXIT, (PBYTE) pRPH, pVolCB);
*/
}
/****************************************************************************
*
* FUNCTION NAME = CD_MediaCheck
*
* DESCRIPTION = Check the Media (Command = 0x01)
*
* Checks to see if the media in the drive has changed.
*
* USHORT CD_MediaCheck (PRP_MEDIACHECK pRP, NPUNITCB pUnitCB)
*
* EFFECTS: The Return Code in the Request Packet is set to one
* of the following:
*
* -1 = Media has been changed
* 0 = Unsure if media has been changed
* 1 = Media unchanged
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT NEAR CD_MediaCheck(pRP, pUnitCB)
PRP_MEDIACHECK pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
USHORT cTries; /*V@91985*/
NPIORB pIORB;
BOOL playing; //SD@135221
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
{
pRP->rc = -1;
return(STDON);
}
if (pUnitCB->DeviceInfo.playing==FALSE && //SD@135221
(pUnitCB->pParentUnitCB && pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying))//SD@135221
{ //SD@135221
rc = GetPlayStatus(pUnitCB, &playing); //SD@135221
//SD@135221
if ( (rc == STDON) && playing) //SD@135221
{ //SD@135221
return(STDON + STERR + ERROR_I24_DEVICE_IN_USE); //SD@135221
} //SD@135221
} //SD@135221
BuildCDB_TestUnitReady (pUnitCB, (NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
if(pIORB->Status & IORB_ERROR)
{
if ( ((NPIORB_CDB)pIORB)->sense_data.additional_sense_code != /*@V91985*/
ASC_MEDIUM_NOT_PRESENT ) /*@V91985*/
{ /*@V91985*/
if(pUnitCB->DeviceInfo.Audio.capabilities & (DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER))//SD@135221
{ //SD@135221
if(pUnitCB->DeviceInfo.product_id_code==TORISAN_C3G) //SD@135221
{ //SD@135221
UCHAR asc,ascq; //SD@135221
asc=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code; //SD@135221
ascq=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code_qualifier;//SD@135221
if(asc==ASC_MEDIUM_CHANGED && ascq==0) //SD@135221
{ //SD@135221
// only ATAPI devices support this flag today //SD@135221
// load cd for requested Unit, may fail (no disk etc) //SD@135221
if(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_SINGLE_MODE)//SD@135221
{ //SD@135221
MakeSlotActive(pUnitCB,(UCHAR)pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current);//SD@135221
} /* endif */ //SD@135221
else //SD@135221
{ //SD@135221
MakeSlotActive(pUnitCB,(UCHAR)pUnitCB->DeviceInfo.Slot);//SD@135221
} /* endelse */ //SD@135221
} /* endif */ //SD@135221
} /* endif */ //SD@135221
} //SD@135221
cTries = 0; /*@V91985*/
while ( (((NPIORB_CDB)pIORB)->sense_data.sense_key == /*@V91985*/
SCSI_SK_NOTRDY ) /*@V91985*/
&& (cTries++ < MAX_NOT_READY_RETRIES )) /*@V91985*/
{ /*@V91985*/
FreeIORB (pUnitCB, (NPIORB_CDB) pIORB); /*@V91985*/
DevHelp_ProcBlock( (ULONG) pIORB, NOT_READY_WAIT, /*@V91985*/
WAIT_IS_INTERRUPTABLE ); /*@V91985*/
BuildCDB_TestUnitReady (pUnitCB, /*@V91985*/
(NPIORB_CDB FAR *) &pIORB); /*@V91985*/
rc = SubmitIORB_Wait (pUnitCB, pIORB); /*@V91985*/
} /*@V91985*/
} /*@V91985*/
} /* endif */
pRP->rc = ! (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA);
FreeIORB (pUnitCB, (NPIORB_CDB) pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_BuildBPB
*
* DESCRIPTION = Build the BPB (Command = 0x02)
*
* Builds the BPB. This is requested when the media has changed
* of when the media type is uncertain.
*
* USHORT BuildBPB (PRP_BUILDBPB pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT NEAR CD_BuildBPB(pRP, pUnitCB)
PRP_BUILDBPB pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
ULONG volume_size;
if ( (rc = GetVolumeSize (pUnitCB, (ULONG FAR *) &volume_size)) & STERR)
return(rc);
DefaultBPB.BigTotalSectors = volume_size;
pRP->bpb = (PVOID) &(DefaultBPB);
return (rc);
}
/****************************************************************************
*
* FUNCTION NAME = CD_Read
*
* DESCRIPTION = Read Command (Command 0x04)
*
* This is the basic strategy-1 I/O read routine for the driver.
* The request is queued and sent to the adapter driver for
* processing.
*
* USHORT CD_Read (PRP_RWV pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT CD_Read (pRP, pUnitCB)
PRP_RWV pRP;
NPUNITCB pUnitCB;
{
USHORT rc, disk_density;
ULONG EndSector;
NPIORB_DMWORK pDMWork;
BOOL playing,
MountDrive = FALSE; /*@V91985*/
PULONG pBuff; /*@V91985*/
PULONG i; /*@V96674*/
USHORT ModeFlag; /*@V91985*/
NPIORB_CDB pIORB = 0, pModeIORB = 0;
/*
** Check for valid input parms
*/
if (pRP->NumSectors == 0)
return (STDON);
/*
** if ((pRP->rba + pRP->NumSectors) > pUnitCB->TotalSectors)
** return (STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND);
*/
/*
** Check for uncertain media
*/
if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
{
pRP->NumSectors = 0;
return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
}
/*
** Cant read when unit is playing so check play status
*/
if (pUnitCB->DeviceInfo.playing || //SD@135221
(pUnitCB->pParentUnitCB && pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying))//SD@135221
{ //SD@135221
rc = GetPlayStatus(pUnitCB, &playing);
if ( (rc == STDON) && playing)
{
pRP->NumSectors = 0;
return(STDON + STERR + ERROR_I24_DEVICE_IN_USE);
}
} //SD@135221
/*
** If multisession photo CD mounted and the target read is one of the
** Volume Descriptor Sectors, then remap the RBA to the last session
*/
if ( (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_MULTISESSION) &&
(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_MULTISESSION_MOUNTED) &&
(pRP->rba >= PRIMARY_VOL_DESCR_RBA) &&
(pRP->rba <= pUnitCB->DeviceInfo.volume_descr_terminator) )
{
pRP->rba = pRP->rba + pUnitCB->DeviceInfo.last_session_addr;
}
/* @V91985
** Determine if the File System is attempting to mount the Drive. @V91985
*/ /*@V91985*/
/*@V91985*/
if ( (pRP->rba == 0) && /*@V91985*/
(pRP->NumSectors == 1) ) /*@V91985*/
{ /*@V91985*/
if ( DevHelp_PhysToVirt( (ULONG) pRP->XferAddr, /*@V91985*/
(USHORT) 2048, /*@V96674*/
(PVOID) &pBuff, /*@V91985*/
(PUSHORT) &ModeFlag ) ) /*@V91985*/
{ /*@V91985*/
_asm {int 3} /*@V91985*/
} /*@V91985*/
/*@V91985*/
if (*pBuff == 0x544f4f42l) /* Boot Signature */ /*@V91985*/
{ /*@V91985*/
MountDrive = TRUE; /*@V91985*/
} /*@V91985*/
} /*@V91985*/
/*
** Toshiba 3301 & 3401 is vendor unique since we must make sure the
** density code is set properly.
*/
switch (pUnitCB->DeviceInfo.product_id_code)
{
case TOSHIBA_3301:
case TOSHIBA_3401:
rc = Tosh_Read_2048(pUnitCB, pRP->rba, pRP->NumSectors, pRP->XferAddr);
break;
default:
if ( (pUnitCB->DeviceInfo.current_block_size != 2048) &&
(pUnitCB->DeviceInfo.interface_type != INTERFACE_ATAPI) )
{
rc = ChainModeSelectRead (pUnitCB, pRP->rba, pRP->NumSectors,
pRP->XferAddr, 2048, 0);
}
else
{
rc = ReadSector (pUnitCB, pRP->rba, pRP->NumSectors,
pRP->XferAddr, 2048);
}
}
/*
** Sony 561 can't read 2048 byte Mode 2 Form 2 XA sectors with the
** Read 6 command. We must issue the Read CD-XA command.
*/
if ( (pUnitCB->DeviceInfo.product_id_code == SONY_561) &&
(rc == STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND) )
{
rc = Sony_Read_2048(pUnitCB, pRP->rba, pRP->NumSectors, pRP->XferAddr);
}
/*
** If reading sector 0 on an NEC SCSI drive and it's an XA disk then change
** the density code to XA, and reissue the read.
*/
if ( (rc == STDON + STERR + ERROR_I24_READ_FAULT) &&
(pUnitCB->DeviceInfo.vendor_id_code == NEC) &&
(pUnitCB->DeviceInfo.interface_type == INTERFACE_SCSI) &&
(pRP->rba == 0) )
{
rc = ChainModeSelectRead (pUnitCB, pRP->rba, pRP->NumSectors,
pRP->XferAddr, 2048, 0x81);
}
if (rc & STERR)
pRP->NumSectors = 0;
if (rc == STDON + STERR + ERROR_I24_BAD_COMMAND)
rc = STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND;
/*
** If we are mounting the volume, then check for multi-session disk
*/
if ( (MountDrive) && /*@142227*/
(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_MULTISESSION) ) /*@142227*/
{
Check_MultiSession_Mounted(pUnitCB, pRP->XferAddr);
}
/* @V91985
** If the File System is attempting to mount the drive, and there @V91985
** was an error that was not a drive ready error, give the error @V91985
** (if any) from a read of the volumne descriptor. @V91985
** Clear the buffer if the read was successful. @V91985
*/ /*@V91985*/
/*@V91985*/
if (MountDrive && // Atempting to mount a disc /*@V96674*/
(rc != STDON) && // An error was encountered /*@V96674*/
(rc != STDON + STERR + ERROR_I24_NOT_READY) && /*@V91985*/
(rc != STDON + STERR + ERROR_I24_DISK_CHANGE) && /*@V91985*/
(rc != STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA) ) /*@V91985*/
{ /*@V91985*/
if ((rc = ReadSector( pUnitCB, /*@V96674*/
(ULONG) PRIMARY_VOL_DESCR_RBA, /*@V96674*/
1, /*@V96674*/
pRP->XferAddr, /*@V96674*/
2048)) == STDON ) /*@V96674*/
{
if ( DevHelp_PhysToVirt( (ULONG) pRP->XferAddr, /*@V132783*/
(USHORT) 2048, /*@V132783*/
(PVOID) &pBuff, /*@V132783*/
(PUSHORT) &ModeFlag ) ) /*@V132783*/
{ /*@V132783*/
_asm {int 3} /*@V132783*/
} /*@V132783*/
/*@V91985*/
/* zero out buffer (512 ULONGS = 2048 bytes) */
for (i=pBuff; i<pBuff+512; i++ ) /*@V96674*/
{ /*@V96674*/
*i = 0l; /*@V96674*/
} /*@V96674*/
} /* if rc=ReadSector */ /*@V96674*/
} /*@V91985*/
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = RemovableMedia
*
* DESCRIPTION = Check for Removable Media (Command = 0x0F)
*
* USHORT RemovableMedia (PRPH pRPH, NPUNITCB pUnitCB)
*
* EFFECTS: The busy bit of the status word is set as follows:
*
* 1 = Media is non-removable
* 0 = Media is removable
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT RemovableMedia(pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
if (pUnitCB->UnitInfo.UnitFlags & UF_REMOVABLE)
return (STDON);
else
return (STDON + STBUI);
}
/****************************************************************************
*
* FUNCTION NAME = ResetMedia
*
* DESCRIPTION = Reset Uncertain Media (Command = 0x11)
*
* USHORT ResetMedia (PRPH pRPH, NPUNITCB pUnitCB)
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ResetMedia (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
USHORT rc;
BOOL playing; //SD@135221
if (pUnitCB->pParentUnitCB && //SD@135221
pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying) //SD@135221
{ //SD@135221
rc = GetPlayStatus(pUnitCB, &playing); //SD@135221
//SD@135221
if ( (rc == STDON) && playing) //SD@135221
{ //SD@135221
return(STDON + STERR + ERROR_I24_DEVICE_IN_USE); //SD@135221
} //SD@135221
} //SD@135221
pUnitCB->Flags &= ~UCF_UNCERTAIN_MEDIA;
/*
** Issue a Mode Select to set default density code to CD-ROM
** and default block size to 2048 bytes.
*/
if (!( pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI ))
rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2048);
return (STDON);
}
/****************************************************************************
*
* FUNCTION NAME = GetLogDriveMap
*
* DESCRIPTION = Get Logical Drive Mapping (Command = 0x12)
*
* Returns which logical drive is currently mapped onto a particular
* physical drive. A zero is returned if only one logical drive is
* mapped to the physical drive.
*
* USHORT GetLogDriveMap (PRPH pRPH, NPUNITCB pUnitCB)
*
* EFFECTS: The logical drive is returned in the unit field
* of the request packet header. The logical drive
* is actually LogDriveNum + 1, which represents the
* drive letter, i.e. C: = 3. A zero is returned
* if only one logical drive is mapped to the physical drive.
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetLogDriveMap (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
pRPH->Unit = 0; /* ret 0 if one drive mapped */
return (STDON);
}
/****************************************************************************
*
* FUNCTION NAME = SetLogDriveMap
*
* DESCRIPTION = Set Logical Drive Mapping (Command = 0x13)
*
* Maps the specified logical drive onto the physical drive.
*
* USHORT SetLogDriveMap (PRPH pRPH, NPVOLCB pVolCB)
*
* EFFECTS: The logical drive is returned in the unit field
* of the request packet header. The logical drive
* is actually LogDriveNum + 1, which represents the
* drive letter, i.e. C: = 3. A zero is returned
* if only one logical drive is mapped to the physical drive.
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT SetLogDriveMap (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
pRPH->Unit = 0; /* only 1 drive can be mapped */
return (STDON);
}
/****************************************************************************
*
* FUNCTION NAME = PartFixedDisks
*
* DESCRIPTION = Get number of fixed disks (Command = 0x16)
*
* Returns the number of fixed disks supported by the driver.
*
* USHORT PartFixedDisks (PRP_PARTFIXEDDISKS pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT PartFixedDisks (pRP, pUnitCB)
PRP_PARTFIXEDDISKS pRP;
NPUNITCB pUnitCB;
{
pRP->NumFixedDisks = 0;
return (STDON);
}
/****************************************************************************
*
* FUNCTION NAME = GetUnitMap
*
* DESCRIPTION = Get logical units mapped to a physical unit (Command = 0x17)
*
* This command is only supported for disk media.
*
* USHORT GetUnitMap (PRP_GETUNITMAP pRP, NPUNITCB pUnitCB)
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetUnitMap (pRP, pUnitCB)
PRP_GETUNITMAP pRP;
NPUNITCB pUnitCB;
{
pRP->UnitMap = 0; /* No units mapped */
return (STDON);
}
/*
** Near Entry Point to swappable IOCTL routine.
*/
/****************************************************************************
*
* FUNCTION NAME = DriveGenIOCTL
*
* DESCRIPTION =
*
* INPUT = pRP - Request Packet
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT DriveGenIOCTL(pRP, pUnitCB)
PRP_GENIOCTL pRP;
NPUNITCB pUnitCB;
{
USHORT rc;
rc = f_CD_DriveGenIOCTL (pRP, pUnitCB);
rc |= STDON;
return(rc);
}
/*
** Packet Status return functions:
**
** CmdErr, StatusError, StatusDevReady, StatusComplete
*/
/****************************************************************************
*
* FUNCTION NAME = CmdErr
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT near CmdErr (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
return (STERR + STDON + ERROR_I24_BAD_COMMAND);
}
/****************************************************************************
*
* FUNCTION NAME = WriteErr
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT near WriteErr (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
return (STERR + STDON + ERROR_I24_WRITE_FAULT);
}
/****************************************************************************
*
* FUNCTION NAME = WriteVErr
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT near WriteVErr (pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
return (STERR + STDON + ERROR_I24_WRITE_FAULT);
}
/****************************************************************************
*
* FUNCTION NAME = StatusDevReady
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT StatusDevReady(pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
return (STDON + STBUI);
}
/****************************************************************************
*
* FUNCTION NAME = StatusComplete
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT StatusComplete(pRPH, pUnitCB)
PRPH pRPH;
NPUNITCB pUnitCB;
{
return (STDON);
}
/****************************************************************************
*
* FUNCTION NAME = StatusError
*
* DESCRIPTION =
*
* INPUT = pRPH - Request Packet Header
* ErrorCode - Error Code
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT StatusError( pRPH, ErrorCode )
PRPH pRPH;
USHORT ErrorCode;
{
return (STDON + STERR);
}
/****************************************************************************
*
* FUNCTION NAME = ChainModeSelectRead
*
* DESCRIPTION = Chain Mode Select and Read Commands
*
* USHORT ChainModeSelectRead (NPUNITCB pUnitCB, ULONG LBA,
* USHORT transfer_count, ULONG ppDataBuff,
* USHORT block_length, USHORT density)
*
* INPUT = pUnitCB - Pointer to UnitCB
* LBA - LBA
* transfer_count - count of sectors to transfer
* ppDataBuff - phys addr of data buffer
* block_length - block_length
* density - density code
*
* OUTPUT = USHORT - Packet Status word
*
* NOTES: This routine should not be called for an ATAPI device since
* ATAPI drives do not support Mode Selects for density codes
* and block lengths.
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ChainModeSelectRead (pUnitCB, LBA, transfer_count, ppDataBuff,
block_length, density)
NPUNITCB pUnitCB;
ULONG LBA;
USHORT transfer_count;
ULONG ppDataBuff;
USHORT block_length;
USHORT density;
{
USHORT rc;
NPIORB_CDB pIORB = 0, pModeIORB = 0;
NPIORB_DMWORK pDMWork;
BuildCDB_ModeSelect (pUnitCB, density, block_length,
(NPIORB_CDB FAR *) &pModeIORB);
/*
** If transfer count < 255 sectors, issue Read (6) else issue Read (10)
*/
if (transfer_count <= 255)
{
BuildCDB_Read_6 (pUnitCB, LBA, block_length,
transfer_count, ppDataBuff,
(NPIORB_CDB FAR *) &pIORB);
}
else
{
BuildCDB_Read_10 (pUnitCB, LBA, block_length,
transfer_count, ppDataBuff,
(NPIORB_CDB FAR *) &pIORB);
}
pDMWork = (NPIORB_DMWORK) &(pModeIORB->apt.iorbh.DMWorkSpace);
pDMWork->pCoReqIORB = (NPIORB) pIORB;
QueueIORB (pUnitCB, pModeIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if ( !(pModeIORB->apt.iorbh.Status & IORB_ERROR) )
{
pUnitCB->DeviceInfo.current_density = density;
pUnitCB->DeviceInfo.current_block_size = block_length;
}
FreeIORB (pUnitCB, pModeIORB);
FreeIORB (pUnitCB, pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = ReadSector
*
* DESCRIPTION = Issue Read Command
*
* USHORT ReadSector (NPUNITCB pUnitCB, ULONG LBA,
* USHORT transfer_count, ULONG ppDataBuff,
* USHORT block_length)
*
* INPUT = pUnitCB - Pointer to UnitCB
* LBA - LBA
* transfer_count - count of sectors to transfer
* ppDataBuff - phys addr of data buffer
* block_length - block_length
*
* OUTPUT = USHORT - Packet Status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ReadSector (pUnitCB, LBA, transfer_count, ppDataBuff, block_length)
NPUNITCB pUnitCB;
ULONG LBA;
USHORT transfer_count;
ULONG ppDataBuff;
USHORT block_length;
{
USHORT rc;
NPIORB_CDB pIORB = 0;
ULONG nBytesRem; /*@151345*/
USHORT partialBlockCount; /*@151345*/
/*
** If transfer count < 255 sectors, issue Read (6) else issue Read (10)
** ATAPI drives only support Read 10.
*/
if ( (transfer_count <= 255) &&
(pUnitCB->DeviceInfo.interface_type != INTERFACE_ATAPI) )
{
BuildCDB_Read_6 (pUnitCB, LBA, block_length,
transfer_count, ppDataBuff,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB); /*@151345*/
FreeIORB (pUnitCB, pIORB); /*@151345*/
}
else
{
nBytesRem = (ULONG)transfer_count * block_length; /*@151345*/
while( nBytesRem > 0 ) /*@151345*/
{ /*@151345*/
if( nBytesRem > CDATAPI_LIMIT_64K ) /*@151345*/
{ /*@151345*/
/* Limit to blocks which fit in 64K */ /*@151345*/
partialBlockCount = CDATAPI_LIMIT_64K / block_length; /*@151345*/
} /*@151345*/
else /*@151345*/
{ /*@151345*/
/* Do the last partial read */ /*@151345*/
partialBlockCount = nBytesRem / block_length; /*@151345*/
} /*@151345*/
/*@151345*/
BuildCDB_Read_10 (pUnitCB, LBA, block_length,
partialBlockCount, ppDataBuff, /*@151345*/
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait(pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
/* @151345
** Adjust the buffer pointers for more requests. @151345
*/ /*@151345*/
LBA += partialBlockCount; /*@151345*/
ppDataBuff += partialBlockCount * block_length; /*@151345*/
nBytesRem -= (ULONG)partialBlockCount * block_length; /*@151345*/
}
}
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = GetVolumeSize
*
* DESCRIPTION = Get volume size
*
* Return the volume size of the current CD
*
* USHORT GetVolumeSize (NPUNITCB pUnitCB, ULONG FAR * volume_size)
*
* INPUT = pUnitCB - Pointer to UnitCB
* volume_size - Pointer to return volume size
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetVolumeSize (pUnitCB, volume_size)
NPUNITCB pUnitCB;
ULONG FAR * volume_size;
{
USHORT rc;
NPIORB_CDB pIORB;
BOOL playing; //SD@135221
struct ReadCapacity_Data NEAR *pCDBData;
union ULONGB ul_volume;
if (pUnitCB->DeviceInfo.playing==FALSE && //SD@135221
(pUnitCB->pParentUnitCB && pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying))//SD@135221
{ //SD@135221
rc = GetPlayStatus(pUnitCB, &playing); //SD@135221
//SD@135221
if ( (rc == STDON) && playing) //SD@135221
{ //SD@135221
return(STDON + STERR + ERROR_I24_DEVICE_IN_USE);//SD@135221
}
}
BuildCDB_ReadCapacity(pUnitCB, (NPIORB_CDB FAR *) &pIORB);
pCDBData = (struct ReadCapacity_Data NEAR *) pIORB->CDB_data;
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if (rc == STDON)
{
ul_volume.ulbytes.byte_3 = pCDBData->capacity_LBA.ulbytes.byte_0;
ul_volume.ulbytes.byte_2 = pCDBData->capacity_LBA.ulbytes.byte_1;
ul_volume.ulbytes.byte_1 = pCDBData->capacity_LBA.ulbytes.byte_2;
ul_volume.ulbytes.byte_0 = pCDBData->capacity_LBA.ulbytes.byte_3;
*volume_size = ul_volume.dword;
}
else if (rc == STDON + STERR + ERROR_I24_INVALID_PARAMETER)
ul_volume.dword = 270000L;
FreeIORB (pUnitCB, pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = ClearCheckCondition
*
* DESCRIPTION = Clear check condition and return error code
*
* USHORT ClearCheckCondition (NPUNITCB pUnitCB)
*
* INPUT = pUnitCB - Pointer to UnitCB
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT ClearCheckCondition (pUnitCB)
NPUNITCB pUnitCB;
{
ULONG volume_size;
return(GetVolumeSize (pUnitCB, (ULONG FAR *) &volume_size) );
}
/****************************************************************************
*
* FUNCTION NAME = GetSectorMode
*
* DESCRIPTION = Get mode for sector zero.
*
* This routine returns the mode of sector zero by reading the header.
*
* USHORT GetSectorMode (NPUNITCB pUnitCB, USHORT FAR * mode)
*
* INPUT = pUnitCB - Pointer to UnitCB
* mode - mode
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetSectorMode (pUnitCB, mode)
NPUNITCB pUnitCB;
USHORT FAR *mode;
{
USHORT rc;
NPIORB_CDB pIORB;
struct ReadHeader_Data NEAR *pCDBData;
BuildCDB_ReadHeader(pUnitCB, 0, (NPIORB_CDB FAR *) &pIORB);
pCDBData = (struct ReadHeader_Data NEAR *) pIORB->CDB_data;
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if (rc == STDON)
{
*mode = pCDBData->cdrom_data_mode;
}
FreeIORB (pUnitCB, pIORB);
return (rc);
}
/****************************************************************************
*
* FUNCTION NAME = Check_MultiSession_Mounted
*
* DESCRIPTION = Check if multisession mounted
*
* This routine checks to see if a multisession photoCD disk is mounted.
* If it is, then the driver reads the volume descriptors until the
* volume descriptor terminator is found. All subsequent reads from
* the Primary Volume Descriptor till the Volume Descriptor Terminator
* are mapped to the last session prior to the read. This routine is
* only called if the multi_session_support bit is set in the UnitCB.
*
* USHORT Check_MultiSession_Mounted (NPUNITCB pUnitCB, ULONG physaddr)
*
* INPUT = pUnitCB - Pointer to UnitCB
* physaddr - physical address of I/O buffer
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT Check_MultiSession_Mounted (pUnitCB, physaddr)
NPUNITCB pUnitCB;
ULONG physaddr;
{
USHORT rc, n, mode_flag;
ULONG session_addr;
PBYTE pBuffer;
BOOL term_found = FALSE;
/*
** Initialize to not multisession disk
*/
pUnitCB->DeviceInfo.Audio.capabilities &= ~DCAPS_MULTISESSION_MOUNTED;
pUnitCB->DeviceInfo.last_session_addr = 0;
pUnitCB->DeviceInfo.volume_descr_terminator = 0;
switch (pUnitCB->DeviceInfo.product_id_code)
{
case TOSHIBA_3401:
rc = Tosh_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);
break;
case SONY_561:
case TEXEL_3024K:
case PIONEER_604X:
case HITACHI_6750:
case LMS_215:
rc = Sony_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);
break;
case CHINON_535:
rc = Chinon_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);
break;
case NEC_84_1:
rc = NEC_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);
break;
case HP_C4324: /*@V156096*/
rc = HP_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);/*@V156096*/
break; /*@V156096*/
default:
if (pUnitCB->DeviceInfo.interface_type == INTERFACE_PROPRIETARY)
rc=NonSCSI_GetLastSessionAddr(pUnitCB, (ULONG FAR *) &session_addr);
else if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
rc = Sony_GetLastSessionAddr (pUnitCB, (ULONG FAR *) &session_addr);
else
rc = STDON + STERR;
break;
}
/*
** If no error, then multisession disk. Read the volume descriptors
** till the terminator descriptor is found.
*/
if (rc == STDON)
{
for (n = PRIMARY_VOL_DESCR_RBA; term_found != TRUE; n++)
{
if ((rc = ReadSector(pUnitCB, (ULONG) n, 1, physaddr, 2048)) != STDON)
break;
/*
** Check for the volume descriptor id of "CD001"
*/
DevHelp_PhysToVirt (physaddr,
(USHORT) 2048,
(PBYTE FAR *) &pBuffer,
(USHORT FAR *) &mode_flag);
if ( *(pBuffer+1) != 'C' || *(pBuffer+2) != 'D' ||
*(pBuffer+3) != '0' || *(pBuffer+4) != '0' ||
*(pBuffer+5) != '1' )
{
rc = STDON + STERR;
break;
}
/*
** Check for terminator volume descriptor
*/
if ( (UCHAR) *pBuffer == VOL_DESCR_TERMINATOR)
{
pUnitCB->DeviceInfo.Audio.capabilities |= DCAPS_MULTISESSION_MOUNTED;
pUnitCB->DeviceInfo.last_session_addr = session_addr;
pUnitCB->DeviceInfo.volume_descr_terminator = n;
term_found = TRUE;
}
}
/*
** Read back original sector 0
*/
ReadSector (pUnitCB, (ULONG) 0, 1, physaddr, 2048);
}
}
/****************************************************************************
*
* FUNCTION NAME = NonSCSI_GetLastSessionAddr
*
* DESCRIPTION = Get address of last session on multisession disk
*
* This routine returns the address of the last session of a multisession
* photo CD disk. This routine should only be called is the drive is
* a non SCSI CD-ROM.
*
* USHORT NonSCSI_GetLastSessionAddr(NPUNITCB pUnitCB, ULONG FAR *session_addr)
*
* INPUT = pUnitCB - Pointer to UnitCB
* session_addr - Pointer to returned session addr
*
* OUTPUT = USHORT - Packet status word
*
* if the STERR bit is on, then the disk
* is not a multisession disk and the
* session_addr field is not valid
*
* if the STERR bit is NOT set, then the
* disk is a multi-session disk and the
* session addr field is valid
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT NonSCSI_GetLastSessionAddr (pUnitCB, session_addr)
NPUNITCB pUnitCB;
ULONG FAR *session_addr;
{
USHORT rc;
NPIORB_CDB pIORB;
union ADD_ReadDiskInfo_Data NEAR *pCDBData;
union AddressType last_session;
ADD_BuildCDB_ReadDiskInfo (pUnitCB, TYPE_LASTSESSION_INFO,
(NPIORB_CDB FAR *) &pIORB);
pCDBData = (union ADD_ReadDiskInfo_Data NEAR *) pIORB->CDB_data;
rc = SubmitIORB_Wait(pUnitCB, pIORB);
if (rc == STDON)
{
/*
** If zero returned in data fields, then not multisession
*/
if ( (pCDBData->last_session.amin == 0) &&
(pCDBData->last_session.asec == 0) &&
(pCDBData->last_session.aframe == 0) )
{
rc = STDON + STERR;
}
else
{
last_session.ul_redbook.min = pCDBData->last_session.amin;
last_session.ul_redbook.sec = pCDBData->last_session.asec;
last_session.ul_redbook.frame = pCDBData->last_session.aframe;
last_session.ul_redbook.zero = 0;
last_session.dword = RedBookToHSG (last_session.dword);
*session_addr = last_session.dword;
}
}
FreeIORB (pUnitCB, pIORB);
return (rc);
}
/****************************************************************************
*
* FUNCTION NAME = GetPlayStatus
*
* DESCRIPTION = Get play status
*
* USHORT GetPlayStatus (NPUNITCB pUnitCB, BOOL FAR * playing)
*
* INPUT = pUnitCB - Pointer to UnitCB
* playing - returned play status
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT GetPlayStatus (pUnitCB, playing)
NPUNITCB pUnitCB;
BOOL FAR *playing;
{
USHORT rc;
NPIORB_CDB pIORB;
struct SubChannel_Position NEAR *pCDBData;
if(pUnitCB->DeviceInfo.playing==FALSE && //SD@135221
(pUnitCB->pParentUnitCB && pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying))//SD@135221
{ //SD@135221
*playing=TRUE; //SD@135221
return STDON; //SD@135221
} /* endif */ //SD@135221
BuildCDB_ReadSubChannel(pUnitCB, RSC_CURRENT_POSITION,
(NPIORB_CDB FAR *) &pIORB);
pCDBData = (struct SubChannel_Position NEAR *) pIORB->CDB_data;
*playing = FALSE;
if ( (rc = SubmitIORB_Wait(pUnitCB, pIORB)) == STDON)
{
if (pCDBData->sub_channel_hdr.audio_status == AS_PLAY_IN_PROGRESS)
*playing = TRUE;
pUnitCB->DeviceInfo.playing = *playing;
if(pUnitCB->pParentUnitCB) //SD@135221
{
pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying = pUnitCB->DeviceInfo.playing;//SD@135221
} /* endif */ //SD@135221
}
FreeIORB (pUnitCB, pIORB);
return(rc);
}
/****************************************************************************
*
* FUNCTION NAME = Submit_ModeSelect
*
* DESCRIPTION = Submit a Mode Select command
*
* Submit_ModeSelect (NPUNITCB pUnitCB, USHORT density_code,
* USHORT block_length)
*
* INPUT = pUnitCB - pointer to UnitCB
* density_code - density code
* block_length - block_length
* pIORBOut - returned pointer to IORB
*
* OUTPUT = USHORT - packet status
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT Submit_ModeSelect (pUnitCB, density_code, block_length)
NPUNITCB pUnitCB;
USHORT density_code;
USHORT block_length;
{
USHORT rc;
NPIORB_CDB pIORB;
BuildCDB_ModeSelect (pUnitCB, density_code, block_length,
(NPIORB_CDB FAR *) &pIORB);
rc = SubmitIORB_Wait (pUnitCB, pIORB);
FreeIORB (pUnitCB, pIORB);
if (rc == STDON)
{
pUnitCB->DeviceInfo.current_density = density_code;
pUnitCB->DeviceInfo.current_block_size = block_length;
}
return (rc);
}
/****************************************************************************
*
* FUNCTION NAME = Get_UnitCB_Addr
*
* DESCRIPTION = Get UnitCB address
*
* Return the address of the UnitCB for the specified unit.
*
* USHORT Get_UnitCB_Addr (UCHAR LogDriveNum, NPUNITCB FAR *pUnitCB)
*
* INPUT = unit - logical drive number
* pUnitCB - returned pointer to UnitCB
*
* OUTPUT = USHORT - Packet status word
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
USHORT Get_UnitCB_Addr (LogDriveNum, pUnitCB)
UCHAR LogDriveNum;
NPUNITCB FAR *pUnitCB;
{
NPUNITCB pUnitCBx;
USHORT found = FALSE;
pUnitCBx = UnitCB_Head;
while (pUnitCBx != NULL && found == FALSE)
{
if ( (UCHAR) pUnitCBx->LogDriveNum == LogDriveNum )
found = TRUE;
else
pUnitCBx = pUnitCBx->pNextUnitCB;
}
if (found == TRUE)
{
*pUnitCB = pUnitCBx;
return(NO_ERROR);
}
else
return(ERROR);
}
/****************************************************************************
*
* FUNCTION NAME = Strncmp
*
* DESCRIPTION = string compare
*
* Strncmp (NPBYTE string1, NPBYTE string2, USHORT length)
*
* This is like the standard C function, except it is boolean
*
* INPUT = string1 - string 1
* string2 - string 2
* length - length of string
*
* OUTPUT = BOOLEAN, 1 if equal, 0 if not equal
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
BOOL Strncmp ( string1, string2, length )
UCHAR *string1, *string2;
USHORT length;
{
BOOL equal = TRUE;
while ( length-- > 0 )
{
if ( *string1++ != *string2++ )
{
equal = FALSE;
break;
}
}
return ( equal );
}
/****************************************************************************
*
* FUNCTION NAME = CD_Strat1b
*
* DESCRIPTION = VOID CD_strat1b ()
*
* INPUT = ES:BX - Request Packet
*
* OUTPUT =
*
* RETURN-NORMAL =
* RETURN-ERROR =
*
****************************************************************************/
VOID NEAR CD_Strat1b()
{
PRP_GENIOCTL pRP;
USHORT Cmd, Status;
PRPINITOUT pRPO;
_asm
{
push es
push bx
mov word ptr pRP[0], bx
mov word ptr pRP[2], es
}
pRPO = (PRPINITOUT) pRP; /* Output for Init RP */
Status = 0;
Cmd = pRP->rph.Cmd;
if (Cmd == CMDInitBase || Cmd == CMDInit)
{
pRPO->DataEnd = DataBreakAddress;
pRPO->CodeEnd = CodeBreakAddress;
if (CodeBreakAddress == 0)
Status = STDON + STERR + ERROR_I24_QUIET_INIT_FAIL;
}
else if ( (Cmd == CMDGenIOCTL) && (pRP->Category == IOC_CDROM_2) &&
(pRP->Function == IOCD_RETURN_DRIVE_LETTER) )
{
/* Status = VerifyParameters(pRP, 0, 4, ParamLockHandle, DataLockHandle);*/
if (Status == 0)
{
((struct DriveLetter_Data FAR *)pRP->DataPacket)->drive_count =
NumCDROMDrives;
((struct DriveLetter_Data FAR *)pRP->DataPacket)->first_drive_number =
FirstDriveNumber;
}
}
else
Status = STDON + STERR + ERROR_I24_BAD_COMMAND;
DISABLE;
pRP->rph.Status = Status | STDON ; /*Save status in Request Packet */
ENABLE;
_asm
{
pop bx
pop es
LEAVE
retf
}
}