/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
 #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
