home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cdrom.zip
/
DDK
/
BASE
/
SRC
/
DEV
/
DASD
/
CDROM
/
MITSUMI
/
proccdb.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-18
|
42KB
|
1,175 lines
#define INCL_DOSINFOSEG
#define INCL_NOPMAPI
#define INCL_NO_SCB
#define INCL_INITRP_ONLY
#include "os2.h" // \DRV6\H
#include "dos.h" // \DRV6\H
#include "sas.h" // \DRV6\H
#include "devcmd.h" // \DRV6\H
#include "iorb.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "reqpkt.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "addcalls.h" // \DRV6\SRC\DEV\DASD\DISKH
#include "dskinit.h"
#include <scsi.h>
#include <cdbscsi.h>
#include <CMD.H>
#include <cdb.h>
#include "devhelp.h"
#include "proto.h"
#include <string.h>
#include <memory.h>
extern TOCINFO near TOCInfoArea[99] ;
extern ULONG near ulLeadOut ;
extern UCHAR near bMinTno, near bMaxTno , near bPlayFlag, near bPauseFlag;
extern USHORT near bStatusFlag; // drive firmware level
extern UCHAR near CD_ID,near wDrvVer[4], near Mode;
CDROMSTAT HoldPos;
ULONG AudioPlayStop;
extern ULONG near ulVSSize;
extern PGINFOSEG near PGinfo;
USHORT DrvBlockSize=2048;
UCHAR DrawerState=Unlocked;
extern PUCHAR near Read_IOBuffer;
extern BOOL near Lu002;
extern UCHAR near bInfoFlag;
VOID ProcessCDB(PIORB PIORB)
{
USHORT Status;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
PCDCDB pCDB= (PCDCDB)pIORB->apt.pControllerCmd;
USHORT ErrorCode;
DevHelp_RAS( 160 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
if(pCDB->OpCode==SCSI_INQUIRY)
{
ProcessInquiry(PIORB, pCDB);
} /* end if */
else
{
if(!ReadyHardware(PIORB,pCDB->OpCode))
{
DevHelp_RAS( 161 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
switch(pCDB->OpCode)
{
case SCSI_READ_TOC: // ok
ProcessTOC(PIORB,pCDB);
break;
case SCSI_TEST_UNIT_READY: // ok
break;
case SCSI_REQUEST_SENSE:
break;
case SCSI_READ_6:
case SCSI_READ_10:
ProcessRead(PIORB,pCDB);
break;
case SCSI_SEEK_6: // ok
case SCSI_SEEK_10:
ProcessSeek(PIORB, pCDB);
break;
case SCSI_MODE_SELECT:
case SCSI_MODE_SENSE:
ProcessModeSelectSense(PIORB,pCDB);
break;
case SCSI_LOCK_UNLOCK:
ProcessLock(PIORB,pCDB);
break;
case SCSI_READ_CAPACITY: // ok
ProcessCapacity(PIORB,pCDB);
break;
case SCSI_READ_SUB_CHAN:
ProcessSubChan(PIORB , pCDB);
break;
case SCSI_READ_HEADER:
ProcessHeader(PIORB,pCDB);
break;
case SCSI_PAUSE_RESUME:
ProcessPauseResume(PIORB, pCDB);
break;
case SCSI_START_STOP_UNIT:
ProcessStartStop(PIORB, pCDB);
break;
case SCSI_PLAY_MSF:
ProcessPlay(PIORB,pCDB);
break;
case ADD_READ_DISK_INFO:
ProcessDiskInfo(PIORB,pCDB);
break;
default:
break;
} /* end switch */
} /* end else */
} /* end else */
DevHelp_RAS( 163 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
VOID ProcessTOC(PIORB PIORB, PCDCDB pCDB)
{
CDROMSTAT Data;
CDROMSTAT Data1;
struct ReadTOC_Data far * TocDatap;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
PSCATGATENTRY pSGList;
UCHAR trk;
pSGList=pIORB->apt.pSGList;
if( TocDatap = (struct ReadTOC_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
{
trk=TocDatap->toc_descriptor[0].track_num=pCDB->ReadTOC.starting_track;
if(trk==Lead_Out_Track || (trk>=bMinTno && trk<=bMaxTno))
{
DevHelp_RAS( 165 , trk , sizeof(PGinfo->msecs), &(PGinfo->msecs));
if(trk==Lead_Out_Track)
{
TocDatap->toc_hdr.first_track=bMinTno;
TocDatap->toc_hdr.last_track=bMaxTno;
trk=0;
}
DevHelp_RAS( 167 , trk , sizeof(TOCInfoArea[trk]), &(TOCInfoArea[trk]));
TocDatap->toc_descriptor[0].control = TOCInfoArea[trk].Control;
TocDatap->toc_descriptor[0].ADR = TOCInfoArea[trk].ADR;
TocDatap->toc_descriptor[0].abs_address.redbook.zero=0;
TocDatap->toc_descriptor[0].abs_address.redbook.min=TOCInfoArea[trk].min;
TocDatap->toc_descriptor[0].abs_address.redbook.sec=TOCInfoArea[trk].sec;
TocDatap->toc_descriptor[0].abs_address.redbook.frame=TOCInfoArea[trk].frame;
} /* end if */
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
}
}
VOID ProcessMediaCatalogNumber(PIORB PIORB, PCDCDB pCDB)
{
CDROMSTAT Data;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
union CDROM_SubChannel_Info far *SubChan;
PSCATGATENTRY pSGList;
USHORT Status;
UCHAR State;
if(!COMMANDCHECK(Status=DriveCommand( ReadUPC, 0,0, &Data,sizeof(Data.UPC))))
{
pSGList=pIORB->apt.pSGList;
if( SubChan = (union CDROM_SubChannel_Info far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
{
if(AUDIOBUSY(Status))
{
if(bPauseFlag)
{
State=AS_PLAY_PAUSED;
} /* end if */
else
{
State=AS_PLAY_IN_PROGRESS;
} /* end else */
} /* end if */
else
{
if(bPlayFlag)
{
State=AS_PLAY_COMPLETE;
} /* end if */
else
{
State=AS_NO_STATUS;
} /* end else */
} /* end else */
SubChan->media_cat_number.mcval=TRUE;
SubChan->media_cat_number.sub_channel_hdr.audio_status=State;
SubChan->media_cat_number.sub_channel_hdr.data_length.word=sizeof(struct SubChannel_Media_Cat)-2;
memcpy(SubChan->media_cat_number.media_catalog_no,Data.UPC.UPCCode,sizeof(SubChan->media_cat_number.media_catalog_no));
}
}
else
{
IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
}
}
VOID ProcessInquiry(PIORB PIORB, PCDCDB pCDB)
{
CDROMSTAT Data;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
struct Inquiry_Data far *IqData;
PSCATGATENTRY pSGList;
PCHAR p;
if(strlen(wDrvVer))
{
pSGList=pIORB->apt.pSGList;
if( IqData = (struct Inquiry_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
{
IqData->additional_length=sizeof(struct Inquiry_Data)-4;;
IqData->peripheral_device_type = CD_MEDIUM_80_CDROM_DATA;
IqData->device_type_qualifier =0;
IqData->ansi_version = 2;
IqData->removable_medium = TRUE;
IqData->ecma_version =0;
IqData->iso_version =0;
IqData->response_data_format =2;
IqData->bits =0;
switch(wDrvVer[0])
{
case 'M':
if(Lu002)
{
p="CD-ROM LU002S ";
} /* end if */
else
{
p="CD-ROM LU005S ";
} /* end else */
break;
case 'F':
p="CD-ROM FX001 ";
break;
case 'D':
p="CD-ROM FX001D ";
break;
default:
p="CD-ROM ????? ";
break;
} /* end switch */
memcpy(IqData->vendor_id,"MITSUMI ",sizeof(IqData->vendor_id));
memcpy(IqData->product_id,p,sizeof(IqData->product_id));
memcpy(IqData->revision_level,wDrvVer,strlen(wDrvVer));
}
}
else
{
IORB_CmdErr(IOERR_DEVICE_NONSPECIFIC, PIORB,SCSI_SK_HARDWAREERR,ASC_UNRECOVERED_ERROR);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
}
VOID ProcessCurrentPosition(PIORB PIORB,PCDCDB pCDB)
{
struct SubChannel_Position far *SubChan;
CDROMSTAT Data;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
USHORT Status;
PSCATGATENTRY pSGList;
UCHAR State;
Status=DriveCommand(ReadSubQ,NULL,NULL,&Data,sizeof(Data.TrackInfo));
if(!COMMANDCHECK(Status))
{
pSGList=pIORB->apt.pSGList;
if( SubChan = (struct SubChannel_Position far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
{
memset(SubChan,0,(USHORT)pSGList->XferBufLen);
if(AUDIOBUSY(Status))
{
if(bPauseFlag)
{
State=AS_PLAY_PAUSED;
} /* end if */
else
{
State=AS_PLAY_IN_PROGRESS;
} /* end else */
} /* end if */
else
{
if(bPlayFlag)
{
State=AS_PLAY_COMPLETE;
} /* end if */
else
{
State=AS_NO_STATUS;
} /* end else */
} /* end else */
SubChan->sub_channel_hdr.audio_status=State;
SubChan->rel_address.redbook.zero=0;
SubChan->rel_address.redbook.min=BCD2Bin(Data.TrackInfo.Min);
SubChan->rel_address.redbook.sec=BCD2Bin(Data.TrackInfo.Sec);
SubChan->rel_address.redbook.frame=BCD2Bin(Data.TrackInfo.Frame);
SubChan->abs_address.redbook.zero=0;
SubChan->abs_address.redbook.min=BCD2Bin(Data.TrackInfo.AMin);
SubChan->abs_address.redbook.sec=BCD2Bin(Data.TrackInfo.ASec);
SubChan->abs_address.redbook.frame=BCD2Bin(Data.TrackInfo.AFrame);
SubChan->control = Data.TrackInfo.S.Control;
SubChan->ADR = Data.TrackInfo.S.ADR;
SubChan->track_number = BCD2Bin(Data.TrackInfo.TNO);
SubChan->index_number = BCD2Bin(Data.TrackInfo.Index);
DevHelp_RAS( 196 ,pCDB->OpCode , (USHORT)pSGList->XferBufLen,SubChan );
}
}
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
}
VOID ProcessAudioPageControl(PIORB PIORB, struct ModeSelectParmList far *pDescriptor)
{
CDROMSTAT Data;
UCHAR Att0,Att1,Att2,Att3,TempAtt0,TempAtt1,TempAtt2,TempAtt3,Saveflag;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
USHORT Status,PreStatus,i;
if(pIORB->apt.Flags==PT_DIRECTION_IN)
{
DevHelp_RAS( 166 , 255 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
Status=DriveCommand( GetAudioVolume, 0, 0, &Data, sizeof(Data.AudioLevel) );
if(!COMMANDCHECK(Status))
{
TempAtt0=Att0 = Data.AudioLevel.ATT0;
TempAtt1=Att1 = Data.AudioLevel.ATT1;
TempAtt2=Att2 = Data.AudioLevel.ATT2;
TempAtt3=Att3 = Data.AudioLevel.ATT3;
switch(TempAtt0) // left volume value
{
case 0: // zero
switch(Att1)
{
case 0: // normal state when silent
if(TempAtt2 && TempAtt3) // mono from Right channel
{
Att1 = TempAtt3; // volume when mono
Att0=PCS_CHANNEL1; // say channel 1 playing here too;
} /* end if */
else
{
Att0=PCS_MUTED; // say muted
} /* end else */
break;
default: // channel swapped
Att1 = Att0; // save volume level
Att0=PCS_CHANNEL1; // say channel swapped
break;
} /* end switch */
break;
default: // left volume non zero
switch(Att1) // based on left extra value
{
case 0: // normal state
Att1 = Att0; // save volume level
Att0=PCS_CHANNEL0; // left channel on
break;
default: // mixing
Att1 = Att0; // save volume level
Att0=PCS_CHANNEL0; // say channel on
break;
} /* end switch */
break;
} /* end switch */
switch(TempAtt2) // right volume value
{
case 0: // zero
switch(Att3) // based on right extra value
{
case 0: // normal muted
if(TempAtt0 && TempAtt1) // if both lefts are on then mono from left
{
Att3 = TempAtt1; // save volume level
Att2 = PCS_CHANNEL0; // say left is playing here as well
} /* end if */
else
{
Att2 = PCS_MUTED; // otherwise we are muted
} /* end else */
break;
default:
Att3 = Att2; // save volume
Att2 = PCS_CHANNEL0; // channel swapped
break;
} /* end switch */
break;
default: // right volume non zero
switch(Att3) // right extra value
{
case 0:
Att3 = Att2; // save volume level
Att2 = PCS_CHANNEL1; // say normal channel 1
break;
default:
Att3 = Att2; // save volume level
Att2 = PCS_CHANNEL1; // mixing
break;
} /* end switch */
break;
} /* end switch */
pDescriptor->Descriptors.audio_control.output0_select=Att0;
pDescriptor->Descriptors.audio_control.output0_volume=Att1;
pDescriptor->Descriptors.audio_control.output1_select=Att2;
pDescriptor->Descriptors.audio_control.output1_volume=Att3;
}
else
{
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,0, sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
} /* end if */
else
{
DevHelp_RAS( 166 , 254 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
Att1=TempAtt1=pDescriptor->Descriptors.audio_control.output0_volume;
Att3=TempAtt3=pDescriptor->Descriptors.audio_control.output1_volume;
if( wDrvVer[0]!='D' && ((Att1!=0 && Att1!=0xff) || // left side both either 0 or max?
(Att3!=0 && Att3!=0xff)) ) // right side both either 0 or max
{ // any of these are an error
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,0, sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
} /* end if */
TempAtt0=Att0=pDescriptor->Descriptors.audio_control.output0_select;
TempAtt2=Att2=pDescriptor->Descriptors.audio_control.output1_select;
if(TempAtt0==TempAtt2) // if both channels mapped the same
{
switch(TempAtt0)
{
case PCS_MUTED: // both channels off
Att0=Att1=Att2=Att3=0;
break;
case PCS_CHANNEL0: // mono from left
if(TempAtt1==TempAtt3) // same volume setting required
{
Att0=Att1; // volume setting on left channel
Att2=Att3=0; // no volume on right
} /* end if */
else
{
// this is an error
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
} /* end else */
break;
case PCS_CHANNEL1: // mono from right
if(TempAtt1==TempAtt3) // same volume setting required
{
Att2=Att3; // volume setting on right channel
Att0=Att1=0; // no volume on left
} /* end if */
else
{
// this is an error
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
} /* end else */
break;
default:
break;
} /* end switch */
} /* end if */
else // different channel settings
{
switch(TempAtt0) // left channel
{
case PCS_MUTED: // turn off channel
Att0=0;
Att1=0;
break;
case PCS_CHANNEL0: // normal condition
Att0=Att1;
Att1=0;
break;
case PCS_CHANNEL1: // left swapped with right
if(TempAtt1==TempAtt3) // volumes MUST match
{
Att1=Att0;
Att0=0;
} /* end if */
else
{
// this is an error
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
} /* end else */
break;
default:
break;
} /* end switch */
switch(TempAtt2)
{
case PCS_MUTED: // turn off channel
Att2=0;
Att3=0;
break;
case PCS_CHANNEL0: // right swapped to left
if(TempAtt1==TempAtt3) // volumes MUST match
{
Att3=Att2;
Att2=0;
} /* end if */
else
{
// this is an error
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
} /* end else */
break;
case PCS_CHANNEL1: // normal condition
Att2=Att3;
Att3=0;
break;
default:
break;
} /* end switch */
} /* end else */
PreStatus=DriveStatus(Spincount); // get drive status now
Saveflag=bInfoFlag;
Status=DriveCommand( SetAudioVolume, MAKEULONG(MAKEUSHORT(Att0,Att1),0),
MAKEULONG(MAKEUSHORT(Att2,Att3),0),
0, 0);
if( COMMANDCHECK(Status))
{
IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
else
{
i=0;
do
{
SHORTWAIT;
Status=DriveStatus(Spincount);
i++;
} while (Status!=PreStatus && i<255); /* end do */
bInfoFlag=Saveflag;
}
} /* end else */
}
VOID ProcessRead(PIORB PIORB,PCDCDB pCDB)
{
PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
USHORT i,usBlkCount,usBlkSize,Status,SenseStatus;
SHORT readtries=3;
PSCATGATENTRY pSGList;
ULONG LBA;
CDROMSTAT e;
BOOL TriedMode=FALSE;
UCHAR OldMode,NewMode;
if (wDrvVer[0]=='D')
{
readtries=8;
}
if(pCDB->OpCode==SCSI_READ_6)
{
LBA=AdrHsg2Red(MAKEULONG(MAKEUSHORT(pCDB->Read_6.LBA.usbytes.byte_1,
pCDB->Read_6.LBA.usbytes.byte_0),
MAKEUSHORT(pCDB->Read_6.LBA_msb,0)));
usBlkCount=(USHORT)pCDB->Read_6.transfer_length;
} /* end if */
else
{
LBA=AdrHsg2Red(pCDB->Read_10.LBA.dword);
usBlkCount=(USHORT)pCDB->Read_10.transfer_length.word;
} /* end else */
DevHelp_RAS( 166 ,pCDB->OpCode , sizeof(LBA), &(LBA));
if( ulLeadOut < LBA )
{
IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_LBA);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
return;
}
for(i=bMinTno; i<=bMaxTno+1; i++)
{
if((TOCInfoArea[i].start>LBA)) // find track past LBA (or leadout area)
{
i--; // back up one (could be last track)
if(i>=bMinTno)
{
if((TOCInfoArea[i].Control & TCI_DATA)) // if track is data, ok
{
pSGList=pPIORB->pSGList;
for(i=0;i<pPIORB->cSGList;i++,pSGList++ )
{
usBlkSize=pSGList->XferBufLen/usBlkCount;
tryagain1:
DevHelp_PhysToGDT(pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen, FP_SEG(Read_IOBuffer));
tryagain:
Status=DriveCommand( Read, LBA, usBlkCount, (PCDROMSTAT) Read_IOBuffer ,DrvBlockSize);
#if 0
if(READERROR(Status)) // read error ?
{
SenseStatus=DriveCommand(RequestSense,0,0,&e,sizeof(e.SenseData));
DevHelp_RAS1( 168 ,e.SenseData.SenseKey , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DevHelp_RAS1( 168 ,SenseStatus , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
break;
} /* end if */
else if(COMMANDCHECK(Status) || TIMEOUT(Status) || DOOROPEN(Status))
#endif
if(COMMANDCHECK(Status) || TIMEOUT(Status) || DOOROPEN(Status) || READERROR(Status))
{
DevHelp_RAS1( 168 ,(pCDB->OpCode<<8) | LOBYTE(Status) , sizeof(PGinfo->msecs), &(PGinfo->msecs));
if(READERROR(Status)) // read error ?
{
SenseStatus=DriveCommand(RequestSense,0,0,&e,sizeof(e.SenseData));
DevHelp_RAS1( 168 ,e.SenseData.SenseKey , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DevHelp_RAS1( 168 ,SenseStatus , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end if */
--readtries; // only try 3 times
if(readtries>0) // counter 0?
{
goto tryagain; // try read again
} /* end if */
else // maybe after last retry
{
if(readtries==0) // three tries already?
{
ResetDrive(); // reset
goto tryagain1; // try one more time
// remap GDTsel first
} /* end if */
}
IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
break;
}
} /* end for */
break; // end of track search loop
}
else
{
IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
break;
}
} /* end if */
else
{
IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
break;
}
} /* end if */
} /* end for */
if(i>bMaxTno+1)
{
IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end if */
}
VOID ProcessSeek(PIORB PIORB,PCDCDB pCDB)
{
ULONG ulPos;
USHORT Status;
if(pCDB->OpCode==SCSI_SEEK_6)
{
ulPos= AdrHsg2Red(MAKEULONG( MAKEUSHORT(pCDB->Seek_6.LBA.usbytes.byte_0,
pCDB->Seek_6.LBA.usbytes.byte_1),
MAKEUSHORT(pCDB->Seek_6.LBA_msb,0)));
} /* end if */
else
{
ulPos=AdrHsg2Red(pCDB->Seek_10.LBA.dword);
} /* end else */
if(ValidMSF(ulPos))
{
if((ulPos>=TOCInfoArea[0].start) && (ulPos<=TOCInfoArea[bMaxTno+1].start) ) // find track past LBA (or leadout area)
{
if(COMMANDCHECK((Status=DriveCommand( Seek, ulPos,0,0,0))))
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
} /* end if */
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
} /* end if */
else
{
//IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
// IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
}
VOID ProcessModeSelectSense(PIORB PIORB,PCDCDB pCDB)
{
PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
struct ModeSelectParmList far *pDescriptor;
USHORT BlockLength;
CDROMSTAT Data;
if( pDescriptor = (struct ModeSelectParmList far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
{
if(pDescriptor->ModeSelectHdr.block_descriptor_len==0)
{
if(pDescriptor->Descriptors.audio_control.page_code == PAGE_AUDIO_CONTROL)
{
ProcessAudioPageControl(PIORB, pDescriptor);
} /* end if */
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
} /* end if */
else if(pDescriptor->ModeSelectHdr.block_descriptor_len==sizeof(struct BlockDescriptor))
{
if(pIORB->apt.Flags == PT_DIRECTION_IN)
{
if(1)
{
pDescriptor->Descriptors.BlockDescriptor.block_length_2=LOBYTE(DrvBlockSize);
pDescriptor->Descriptors.BlockDescriptor.block_length_1=HIBYTE(DrvBlockSize);
}
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
} /* end if */
else
{
BlockLength=MAKEUSHORT(pDescriptor->Descriptors.BlockDescriptor.block_length_2 ,pDescriptor->Descriptors.BlockDescriptor.block_length_1 );
if(BlockLength)
{
if(COMMANDCHECK(DriveCommand( DriveConfig,BLOCKSIZE ,BlockLength, 0, 0)))
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
DevHelp_RAS( 169 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
else
{
DrvBlockSize=BlockLength;
if(DrvBlockSize==2352)
{
DriveCommand( SetDriveMode,DataLength|EccBit|MuteData ,0, 0, 0);
} /* end if */
else
{
// DriveCommand( SetDriveMode,TestMode|MuteData ,0, 0, 0);
DriveCommand( SetDriveMode,Mode==Mode2?TestMode|MuteData:MuteData ,0, 0, 0);
} /* end else */
}
} /* end if */
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
} /* end else */
} /* end else */
DUMMYWAIT;
}
}
VOID ProcessPauseResume(PIORB PIORB,PCDCDB pCDB)
{
ULONG Start;
if(pCDB->PauseResume.resume) // is this a resume request?
{
if(bPauseFlag) // are we paused?
{
Start=MAKEULONG(MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AFrame),BCD2Bin(HoldPos.TrackInfo.ASec)),
MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AMin),0));
if(!COMMANDCHECK(DriveCommand( PlayAudioMSF, Start, AudioPlayStop,0,0)))
{
bPlayFlag=TRUE;
bPauseFlag=FALSE;
}
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
} /* end if */
} /* end if */
else // must be a pause request
{
if(!bPauseFlag)
{
if(!COMMANDCHECK(DriveCommand(Hold,0,0,0,0)))
{
DriveCommand(ReadSubQ,0,0,&HoldPos,sizeof(HoldPos.TrackInfo));
bPlayFlag=FALSE;
bPauseFlag=TRUE;
} /* end if */
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
} /* end if */
} /* end else */
}
VOID ProcessPlay(PIORB PIORB,PCDCDB pCDB)
{
ULONG Start,End;
USHORT Status,i,q;
Start=MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.starting_F,pCDB->PlayAudio_MSF.starting_S),
MAKEUSHORT(pCDB->PlayAudio_MSF.starting_M,0));
AudioPlayStop=End= MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.ending_F,pCDB->PlayAudio_MSF.ending_S),
MAKEUSHORT(pCDB->PlayAudio_MSF.ending_M,0));
if(ValidMSF(Start) && ValidMSF(End))
{
if(Start<=End)
{
for(i=bMinTno; i<=bMaxTno+1; i++)
{
if((TOCInfoArea[i].start>Start)) // find track past LBA (or leadout area)
{
i--; // back up one (could be last track)
if(i>=bMinTno)
{
if(!(TOCInfoArea[i].Control & TCI_DATA)) // if track is NOT data, ok
{
// are we playing or THINK we're playing
if(bPlayFlag || AUDIOBUSY(bStatusFlag))
{
DriveCommand(Hold,0,0,0,0); // then STOP playing NOW
bPlayFlag=FALSE;
} /* end if */
for(q=4; q--; )
{
Status=DriveCommand( PlayAudioMSF, Start, End ,0,0);
if(AUDIOBUSY(Status))
{
break;
} /* end if */
else
{
Status=DriveStatus(Spincount);
if(AUDIOBUSY(Status))
{
break;
} /* end if */
} /* end else */
} /* end for */
if(q)
{
bPlayFlag=TRUE;
bPauseFlag=FALSE;
}
else
{
bPlayFlag=FALSE;
bPauseFlag=FALSE;
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
}
break; // end of track search loop
}
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
break;
}
} /* end if */
else
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
break;
}
break;
} /* end if */
} /* end for */
if(i>bMaxTno+1)
{
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end if */
} /* end if */
else
{
// IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
} /* end if */
else
{
//IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
} /* end else */
}
VOID ProcessDiskInfo(PIORB PIORB,PCDCDB pCDB)
{
union ADD_ReadDiskInfo_Data * buffer;
CDROMSTAT Data;
PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
SHORT Status;
if( buffer= (union ADD_ReadDiskInfo_Data *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
{
memset(buffer,0,sizeof(union ADD_ReadDiskInfo_Data));
switch(pCDB->AddDiscInfo.type)
{
case TYPE_CAPABILITIES_INFO:
buffer->capabilities.read_capabilities=CAP_MODE2_FORM1 | CAP_MODE2_FORM2 ;
if(Lu002==FALSE)
{
buffer->capabilities.read_capabilities|=CAP_MULTISESSION;
} /* end if */
buffer->capabilities.reserved_1=0;
buffer->capabilities.max_block_length.usbytes.byte_0=HIBYTE(2352);
buffer->capabilities.max_block_length.usbytes.byte_1=LOBYTE(2352);
break;
case TYPE_LASTSESSION_INFO:
if(DISCIN(bStatusFlag))
{
while(TIMEOUT(Status=DriveCommand(ReadDiscInfo,0,0,&Data,sizeof(Data.DiscInfo))));
if (!TIMEOUT(Status))
{
if(Data.DiscInfo.Type!=0)
{
buffer->last_session.reserved= 0;
buffer->last_session.amin = BCD2Bin(Data.DiscInfo.Min);
buffer->last_session.asec = BCD2Bin(Data.DiscInfo.Sec);
buffer->last_session.aframe = BCD2Bin(Data.DiscInfo.Frame);
}
}
} /* end if */
break;
}
}
}
VOID ProcessStartStop(PIORB PIORB,PCDCDB pCDB)
{
USHORT Status;
if(pCDB->StartStopUnit.LoEj == 1 )
{
CDROMSTAT c;
// eject
if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
{
if(pCDB->StartStopUnit.start == 1 )
{
if(DOOROPEN(bStatusFlag))
{
Status= DriveCommand( Close,0 ,0, 0, 0);
}
}
else if(!DOOROPEN(bStatusFlag)) // can't eject if door open
{
Status= DriveCommand( LockUnlock,Query ,0, &c, sizeof(c.LockStatus));
if(c.LockStatus.State==Unlocked)
{
Status= DriveCommand( Eject,0 ,0, 0, 0);
bPauseFlag=FALSE;
bPlayFlag=FALSE;
} /* end if */
} /* end if */
} /* end if */
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
} /* end else */
} /* end else */
else if(pCDB->StartStopUnit.start==1)
{
// Start unit
} /* end if */
else
{
DriveCommand(Stop,0,0,0,0);
bPauseFlag=FALSE;
bPlayFlag=FALSE;
// must be stop
}
}
VOID ProcessLock(PIORB PIORB,PCDCDB pCDB)
{
CDROMSTAT c;
USHORT Status;
if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
{
if(!DOOROPEN(bStatusFlag)) // only issue command if door not open
{
Status= DriveCommand( LockUnlock,pCDB->PreventAllowRemoval.prevent?Lock:Unlock ,0, &c, sizeof(c.LockStatus));
if(TIMEOUT(Status))
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
} /* end if */
else
{
DrawerState=pCDB->PreventAllowRemoval.prevent?Locked:Unlocked;
}
} /* end if */
} /* end if */
else
{
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
} /* end else */
}
VOID ProcessSubChan(PIORB PIORB,PCDCDB pCDB)
{
switch (pCDB->ReadSubChannel.data_format)
{
case RSC_Q_SUB_CHANNEL:
case RSC_CURRENT_POSITION:
ProcessCurrentPosition(PIORB, pCDB);
break;
case RSC_MEDIA_CAT_NUM:
ProcessMediaCatalogNumber(PIORB, pCDB);
break;
case RSC_TRACK_ISRC: // not supported on Mitsumi
// ProcessTrackISrc(PIORB, pCDB);
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
break;
default:
break;
}
}
VOID ProcessCapacity(PIORB PIORB,PCDCDB pCDB)
{
CDROMSTAT Data;
struct ReadCapacity_Data far *pReadCap;
PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
if( pReadCap= (struct ReadCapacity_Data far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
{
if(ulVSSize)
{
pReadCap->capacity_LBA.ulbytes.byte_0=HIBYTE(HIUSHORT(ulVSSize));
pReadCap->capacity_LBA.ulbytes.byte_1=LOBYTE(HIUSHORT(ulVSSize));
pReadCap->capacity_LBA.ulbytes.byte_2=HIBYTE(LOUSHORT(ulVSSize));
pReadCap->capacity_LBA.ulbytes.byte_3=LOBYTE(LOUSHORT(ulVSSize));
pReadCap->capacity_block_length.dword=2048;
} /* end if */
}
}
BOOL ValidMSF(ULONG pos)
{
BOOL Flag=FALSE;
UCHAR Min,Sec, Frame;
Min = LOBYTE(HIUSHORT(pos));
Sec = HIBYTE(LOUSHORT(pos));
Frame = LOBYTE(LOUSHORT(pos));
if(Min>=0 && Min<=75)
{
Flag=TRUE;
} /* end if */
if(Sec>=0 && Sec<=59)
{
Flag=TRUE;
} /* end if */
if(Frame>=0 && Frame<=59)
{
Flag=TRUE;
} /* end if */
return Flag;
}
// Not supported on Mitsumi
VOID ProcessHeader(PIORB PIORB, PCDCDB pCDB)
{
struct ReadHeader_Data far *HeaderData;
CDROMSTAT Data;
PIORB_CDB pIORB = (PIORB_CDB)PIORB;
PSCATGATENTRY pSGList;
// if(!CD_DriveCmd( DC_ReadHeader, pCDB->ReadHeader.MSF?MSF_BIT:0,pCDB->ReadHeader.LBA.dword, (PBYTE)&Data))
// {
// pSGList=pIORB->apt.pSGList;
// if( HeaderData = (struct ReadHeader_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
// {
// HeaderData->cdrom_data_mode = Data.s.HDR.Mode;
// if(pCDB->ReadHeader.MSF)
// {
// HeaderData->abs_address.msf0.min=Data.s.HDR.ABSCDROMAddr[0];
// HeaderData->abs_address.msf0.sec=Data.s.HDR.ABSCDROMAddr[1];
// HeaderData->abs_address.msf0.frame=Data.s.HDR.ABSCDROMAddr[2];
// HeaderData->abs_address.msf0.zero=0;
// } /* end if */
// }
// }
// else
// {
// IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_INCOMPATIBLE_CARTRIDGE);
// }
IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
}
#ifdef SUPPORTED
// Not supported on Mitsumi
//VOID ProcessTrackISrc(PIORB PIORB, PCDCDB pCDB)
//{
//CDROMSTAT Data;
//PIORB_CDB pIORB = (PIORB_CDB)PIORB;
//union CDROM_SubChannel_Info far *SubChan;
//PSCATGATENTRY pSGList;
//
//
// if(!CD_DriveCmd( DC_ReadISRC, pCDB->ReadSubChannel.track_number,0, (PBYTE)&Data))
// {
// if(Data.s.ISRC.Valid)
// {
// pSGList=pIORB->apt.pSGList;
// if( SubChan = (union CDROM_SubChannel_Info far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
// {
// SubChan->track_ISRC.sub_channel_hdr.audio_status=Data.s.ISRC.Audio_Status;
// SubChan->track_ISRC.track_number=pCDB->ReadSubChannel.track_number;
// SubChan->track_ISRC.tcval=Data.s.ISRC.Control<<4 || Data.s.ISRC.ADR;
// memcpy(SubChan->track_ISRC.media_catalog_number,Data.s.ISRC.code,sizeof(Data.s.ISRC.code));
// }
// } /* end if */
// else
// {
// IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
// } /* end else */
// }
// else
// {
// IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
// }
//}
#endif