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 >
C/C++ Source or Header  |  1996-06-18  |  42KB  |  1,175 lines

  1.  #define INCL_DOSINFOSEG
  2.  #define INCL_NOPMAPI
  3.  #define INCL_NO_SCB
  4.  #define INCL_INITRP_ONLY
  5.  #include "os2.h"                  // \DRV6\H
  6.  #include "dos.h"                  // \DRV6\H
  7.  #include "sas.h"                  // \DRV6\H
  8.  #include "devcmd.h"               // \DRV6\H
  9.  
  10.  #include "iorb.h"                 // \DRV6\SRC\DEV\DASD\DISKH
  11.  #include "reqpkt.h"               // \DRV6\SRC\DEV\DASD\DISKH
  12.  #include "addcalls.h"             // \DRV6\SRC\DEV\DASD\DISKH
  13.  #include "dskinit.h"
  14.  
  15.  #include <scsi.h>
  16.  #include <cdbscsi.h>
  17.  #include <CMD.H>
  18.  #include <cdb.h>
  19.  #include "devhelp.h"
  20.  #include "proto.h"
  21.  #include <string.h>
  22.  #include <memory.h>
  23.  
  24.  
  25.  extern TOCINFO near TOCInfoArea[99] ;
  26.  extern ULONG near ulLeadOut ;
  27.  extern UCHAR  near bMinTno, near bMaxTno , near bPlayFlag, near bPauseFlag;
  28.  extern USHORT near bStatusFlag;              // drive firmware level
  29.  extern UCHAR  near CD_ID,near wDrvVer[4], near Mode;
  30.  CDROMSTAT HoldPos;
  31.  ULONG AudioPlayStop;
  32.  extern ULONG near ulVSSize;
  33.  extern PGINFOSEG near PGinfo;
  34.  USHORT DrvBlockSize=2048;
  35.  UCHAR DrawerState=Unlocked;
  36.  extern PUCHAR near Read_IOBuffer;
  37.  extern BOOL near Lu002;
  38.  extern UCHAR near bInfoFlag;
  39.  
  40.  VOID ProcessCDB(PIORB PIORB)
  41.  {
  42.  USHORT Status;
  43.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  44.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  45.  
  46.  PCDCDB pCDB= (PCDCDB)pIORB->apt.pControllerCmd;
  47.  
  48.  USHORT ErrorCode;
  49.  
  50.         DevHelp_RAS( 160 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  51.         if(pCDB->OpCode==SCSI_INQUIRY)
  52.           {
  53.           ProcessInquiry(PIORB, pCDB);
  54.           } /* end if */
  55.         else
  56.           {
  57.           if(!ReadyHardware(PIORB,pCDB->OpCode))
  58.             {
  59.             DevHelp_RAS( 161 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  60.             switch(pCDB->OpCode)
  61.               {
  62.               case SCSI_READ_TOC:                                           // ok
  63.                 ProcessTOC(PIORB,pCDB);
  64.                 break;
  65.               case SCSI_TEST_UNIT_READY:                                    // ok
  66.                 break;
  67.               case SCSI_REQUEST_SENSE:
  68.                 break;
  69.               case SCSI_READ_6:
  70.               case SCSI_READ_10:
  71.                 ProcessRead(PIORB,pCDB);
  72.                 break;
  73.               case SCSI_SEEK_6:                                             // ok
  74.               case SCSI_SEEK_10:
  75.                 ProcessSeek(PIORB, pCDB);
  76.                 break;
  77.               case SCSI_MODE_SELECT:
  78.               case SCSI_MODE_SENSE:
  79.                 ProcessModeSelectSense(PIORB,pCDB);
  80.                 break;
  81.               case SCSI_LOCK_UNLOCK:
  82.                 ProcessLock(PIORB,pCDB);
  83.                 break;
  84.               case SCSI_READ_CAPACITY:                                      // ok
  85.                 ProcessCapacity(PIORB,pCDB);
  86.                 break;
  87.               case SCSI_READ_SUB_CHAN:
  88.                 ProcessSubChan(PIORB , pCDB);
  89.                 break;
  90.               case SCSI_READ_HEADER:
  91.                 ProcessHeader(PIORB,pCDB);
  92.                 break;
  93.               case SCSI_PAUSE_RESUME:
  94.                 ProcessPauseResume(PIORB, pCDB);
  95.                 break;
  96.               case SCSI_START_STOP_UNIT:
  97.                 ProcessStartStop(PIORB, pCDB);
  98.                 break;
  99.               case SCSI_PLAY_MSF:
  100.                 ProcessPlay(PIORB,pCDB);
  101.                 break;
  102.               case ADD_READ_DISK_INFO:
  103.                  ProcessDiskInfo(PIORB,pCDB);
  104.                 break;
  105.               default:
  106.                 break;
  107.               } /* end switch */
  108.             } /* end else */
  109.           } /* end else */
  110.           DevHelp_RAS( 163 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  111.  }
  112.  
  113.  
  114. VOID ProcessTOC(PIORB PIORB, PCDCDB pCDB)
  115.  {
  116.  CDROMSTAT  Data;
  117.  CDROMSTAT  Data1;
  118.  struct ReadTOC_Data  far * TocDatap;
  119.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  120.  PSCATGATENTRY pSGList;
  121.  UCHAR trk;
  122.  
  123.      pSGList=pIORB->apt.pSGList;
  124.      if( TocDatap = (struct ReadTOC_Data  far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
  125.        {
  126.        trk=TocDatap->toc_descriptor[0].track_num=pCDB->ReadTOC.starting_track;
  127.        if(trk==Lead_Out_Track || (trk>=bMinTno && trk<=bMaxTno))
  128.          {
  129.          DevHelp_RAS( 165 , trk , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  130.          if(trk==Lead_Out_Track)
  131.            {
  132.            TocDatap->toc_hdr.first_track=bMinTno;
  133.            TocDatap->toc_hdr.last_track=bMaxTno;
  134.            trk=0;
  135.            }
  136.          DevHelp_RAS( 167 , trk , sizeof(TOCInfoArea[trk]), &(TOCInfoArea[trk]));
  137.          TocDatap->toc_descriptor[0].control = TOCInfoArea[trk].Control;
  138.          TocDatap->toc_descriptor[0].ADR     = TOCInfoArea[trk].ADR;
  139.  
  140.          TocDatap->toc_descriptor[0].abs_address.redbook.zero=0;
  141.          TocDatap->toc_descriptor[0].abs_address.redbook.min=TOCInfoArea[trk].min;
  142.          TocDatap->toc_descriptor[0].abs_address.redbook.sec=TOCInfoArea[trk].sec;
  143.          TocDatap->toc_descriptor[0].abs_address.redbook.frame=TOCInfoArea[trk].frame;
  144.          } /* end if */
  145.        else
  146.          {
  147.          IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  148.          DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  149.          } /* end else */
  150.        }
  151.  }
  152. VOID ProcessMediaCatalogNumber(PIORB PIORB, PCDCDB pCDB)
  153. {
  154. CDROMSTAT  Data;
  155. PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  156. union CDROM_SubChannel_Info far *SubChan;
  157. PSCATGATENTRY pSGList;
  158. USHORT Status;
  159. UCHAR State;
  160.  
  161.     if(!COMMANDCHECK(Status=DriveCommand( ReadUPC, 0,0, &Data,sizeof(Data.UPC))))
  162.       {
  163.       pSGList=pIORB->apt.pSGList;
  164.       if( SubChan = (union CDROM_SubChannel_Info far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
  165.         {
  166.         if(AUDIOBUSY(Status))
  167.           {
  168.           if(bPauseFlag)
  169.             {
  170.             State=AS_PLAY_PAUSED;
  171.             } /* end if */
  172.           else
  173.             {
  174.             State=AS_PLAY_IN_PROGRESS;
  175.             } /* end else */
  176.           } /* end if */
  177.         else
  178.           {
  179.           if(bPlayFlag)
  180.             {
  181.             State=AS_PLAY_COMPLETE;
  182.             } /* end if */
  183.           else
  184.             {
  185.             State=AS_NO_STATUS;
  186.             } /* end else */
  187.           } /* end else */
  188.         SubChan->media_cat_number.mcval=TRUE;
  189.         SubChan->media_cat_number.sub_channel_hdr.audio_status=State;
  190.         SubChan->media_cat_number.sub_channel_hdr.data_length.word=sizeof(struct SubChannel_Media_Cat)-2;
  191.         memcpy(SubChan->media_cat_number.media_catalog_no,Data.UPC.UPCCode,sizeof(SubChan->media_cat_number.media_catalog_no));
  192.         }
  193.       }
  194.     else
  195.       {
  196.       IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  197.       }
  198. }
  199.  
  200.  
  201.  VOID ProcessInquiry(PIORB PIORB, PCDCDB pCDB)
  202.  {
  203.  CDROMSTAT Data;
  204.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  205.  struct Inquiry_Data far *IqData;
  206.  PSCATGATENTRY pSGList;
  207.  PCHAR p;
  208.  
  209.  
  210.        if(strlen(wDrvVer))
  211.        {
  212.        pSGList=pIORB->apt.pSGList;
  213.        if( IqData = (struct Inquiry_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
  214.          {
  215.          IqData->additional_length=sizeof(struct Inquiry_Data)-4;;
  216.          IqData->peripheral_device_type = CD_MEDIUM_80_CDROM_DATA;
  217.          IqData->device_type_qualifier  =0;
  218.          IqData->ansi_version           = 2;
  219.          IqData->removable_medium       = TRUE;
  220.          IqData->ecma_version           =0;
  221.          IqData->iso_version            =0;
  222.          IqData->response_data_format   =2;
  223.          IqData->bits                   =0;
  224.          switch(wDrvVer[0])
  225.            {
  226.            case 'M':
  227.              if(Lu002)
  228.                {
  229.                p="CD-ROM LU002S   ";
  230.                } /* end if */
  231.              else
  232.                {
  233.                p="CD-ROM LU005S   ";
  234.                } /* end else */
  235.              break;
  236.            case 'F':
  237.              p="CD-ROM FX001    ";
  238.              break;
  239.            case 'D':
  240.              p="CD-ROM FX001D   ";
  241.              break;
  242.            default:
  243.              p="CD-ROM ?????    ";
  244.              break;
  245.            } /* end switch */
  246.          memcpy(IqData->vendor_id,"MITSUMI     ",sizeof(IqData->vendor_id));
  247.          memcpy(IqData->product_id,p,sizeof(IqData->product_id));
  248.          memcpy(IqData->revision_level,wDrvVer,strlen(wDrvVer));
  249.          }
  250.        }
  251.      else
  252.        {
  253.        IORB_CmdErr(IOERR_DEVICE_NONSPECIFIC, PIORB,SCSI_SK_HARDWAREERR,ASC_UNRECOVERED_ERROR);
  254.        DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  255.        }
  256.  }
  257.  
  258.  
  259.  VOID ProcessCurrentPosition(PIORB PIORB,PCDCDB pCDB)
  260.  {
  261.  struct SubChannel_Position far *SubChan;
  262.  CDROMSTAT  Data;
  263.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  264.  USHORT Status;
  265.  PSCATGATENTRY pSGList;
  266.  UCHAR State;
  267.  
  268.  
  269.      Status=DriveCommand(ReadSubQ,NULL,NULL,&Data,sizeof(Data.TrackInfo));
  270.      if(!COMMANDCHECK(Status))
  271.        {
  272.        pSGList=pIORB->apt.pSGList;
  273.        if( SubChan = (struct SubChannel_Position far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen ) )
  274.          {
  275.          memset(SubChan,0,(USHORT)pSGList->XferBufLen);
  276.          if(AUDIOBUSY(Status))
  277.            {
  278.            if(bPauseFlag)
  279.              {
  280.              State=AS_PLAY_PAUSED;
  281.              } /* end if */
  282.            else
  283.              {
  284.              State=AS_PLAY_IN_PROGRESS;
  285.              } /* end else */
  286.            } /* end if */
  287.          else
  288.            {
  289.            if(bPlayFlag)
  290.              {
  291.              State=AS_PLAY_COMPLETE;
  292.              } /* end if */
  293.            else
  294.              {
  295.              State=AS_NO_STATUS;
  296.              } /* end else */
  297.            } /* end else */
  298.          SubChan->sub_channel_hdr.audio_status=State;
  299.          SubChan->rel_address.redbook.zero=0;
  300.          SubChan->rel_address.redbook.min=BCD2Bin(Data.TrackInfo.Min);
  301.          SubChan->rel_address.redbook.sec=BCD2Bin(Data.TrackInfo.Sec);
  302.          SubChan->rel_address.redbook.frame=BCD2Bin(Data.TrackInfo.Frame);
  303.          SubChan->abs_address.redbook.zero=0;
  304.          SubChan->abs_address.redbook.min=BCD2Bin(Data.TrackInfo.AMin);
  305.          SubChan->abs_address.redbook.sec=BCD2Bin(Data.TrackInfo.ASec);
  306.          SubChan->abs_address.redbook.frame=BCD2Bin(Data.TrackInfo.AFrame);
  307.          SubChan->control  = Data.TrackInfo.S.Control;
  308.          SubChan->ADR      = Data.TrackInfo.S.ADR;
  309.          SubChan->track_number = BCD2Bin(Data.TrackInfo.TNO);
  310.          SubChan->index_number = BCD2Bin(Data.TrackInfo.Index);
  311.          DevHelp_RAS( 196 ,pCDB->OpCode , (USHORT)pSGList->XferBufLen,SubChan );
  312.          }
  313.        }
  314.      else
  315.        {
  316.        IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  317.        DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  318.        }
  319.  
  320.   }
  321.  
  322.    VOID ProcessAudioPageControl(PIORB PIORB, struct ModeSelectParmList far *pDescriptor)
  323.  {
  324.  CDROMSTAT  Data;
  325.  UCHAR Att0,Att1,Att2,Att3,TempAtt0,TempAtt1,TempAtt2,TempAtt3,Saveflag;
  326.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  327.  USHORT Status,PreStatus,i;
  328.  
  329.  
  330.         if(pIORB->apt.Flags==PT_DIRECTION_IN)
  331.           {
  332.           DevHelp_RAS( 166 , 255 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  333.           Status=DriveCommand( GetAudioVolume, 0, 0, &Data, sizeof(Data.AudioLevel) );
  334.           if(!COMMANDCHECK(Status))
  335.             {
  336.             TempAtt0=Att0 = Data.AudioLevel.ATT0;
  337.             TempAtt1=Att1 = Data.AudioLevel.ATT1;
  338.             TempAtt2=Att2 = Data.AudioLevel.ATT2;
  339.             TempAtt3=Att3 = Data.AudioLevel.ATT3;
  340.  
  341.             switch(TempAtt0)                    // left volume value
  342.               {
  343.               case 0:                           // zero
  344.                 switch(Att1)
  345.                   {
  346.                   case 0:                       // normal state when silent
  347.                     if(TempAtt2 && TempAtt3)    // mono from Right channel
  348.                       {
  349.                       Att1 = TempAtt3;          // volume when mono
  350.                       Att0=PCS_CHANNEL1;        // say channel 1 playing here too;
  351.                       } /* end if */
  352.                     else
  353.                       {
  354.                       Att0=PCS_MUTED;           // say muted
  355.                       } /* end else */
  356.                     break;
  357.                   default:                      // channel swapped
  358.                     Att1 = Att0;                // save volume level
  359.                     Att0=PCS_CHANNEL1;          // say channel swapped
  360.                     break;
  361.                   } /* end switch */
  362.                 break;
  363.               default:                          // left volume non zero
  364.                 switch(Att1)                    // based on left extra value
  365.                   {
  366.                   case 0:                       // normal state
  367.                     Att1 = Att0;                // save volume level
  368.                     Att0=PCS_CHANNEL0;          // left channel on
  369.                     break;
  370.                   default:                      // mixing
  371.                     Att1 = Att0;                // save volume level
  372.                     Att0=PCS_CHANNEL0;          // say channel on
  373.                     break;
  374.                   } /* end switch */
  375.                 break;
  376.               } /* end switch */
  377.  
  378.             switch(TempAtt2)                    // right volume value
  379.               {
  380.               case 0:                           // zero
  381.                 switch(Att3)                    // based on right extra value
  382.                   {
  383.                   case 0:                       // normal muted
  384.                     if(TempAtt0 && TempAtt1)    // if both lefts are on then mono from left
  385.                       {
  386.                       Att3 = TempAtt1;          // save volume level
  387.                       Att2 = PCS_CHANNEL0;      // say left is playing here as well
  388.                       } /* end if */
  389.                     else
  390.                       {
  391.                       Att2 = PCS_MUTED;         // otherwise we are muted
  392.                       } /* end else */
  393.                     break;
  394.                   default:
  395.                     Att3 = Att2;                // save volume
  396.                     Att2 = PCS_CHANNEL0;        // channel swapped
  397.                     break;
  398.                   } /* end switch */
  399.                 break;
  400.               default:                          // right volume non zero
  401.                 switch(Att3)                    // right extra value
  402.                   {
  403.                   case 0:
  404.                     Att3 = Att2;                // save volume level
  405.                     Att2 = PCS_CHANNEL1;        // say normal channel 1
  406.                     break;
  407.                   default:
  408.                     Att3 = Att2;                // save volume level
  409.                     Att2 = PCS_CHANNEL1;        // mixing
  410.                     break;
  411.                   } /* end switch */
  412.                 break;
  413.               } /* end switch */
  414.  
  415.  
  416.  
  417.             pDescriptor->Descriptors.audio_control.output0_select=Att0;
  418.             pDescriptor->Descriptors.audio_control.output0_volume=Att1;
  419.  
  420.             pDescriptor->Descriptors.audio_control.output1_select=Att2;
  421.             pDescriptor->Descriptors.audio_control.output1_volume=Att3;
  422.             }
  423.           else
  424.             {
  425.             IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  426.             DevHelp_RAS( 162 ,0, sizeof(PGinfo->msecs), &(PGinfo->msecs));
  427.             }
  428.           } /* end if */
  429.         else
  430.           {
  431.           DevHelp_RAS( 166 , 254 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  432.  
  433.           Att1=TempAtt1=pDescriptor->Descriptors.audio_control.output0_volume;
  434.           Att3=TempAtt3=pDescriptor->Descriptors.audio_control.output1_volume;
  435.  
  436.           if( wDrvVer[0]!='D' && ((Att1!=0 && Att1!=0xff) ||            // left side both either 0 or max?
  437.               (Att3!=0 && Att3!=0xff)) )          // right side both either 0 or max
  438.             {                                                   // any of these are an error
  439.             IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  440.             DevHelp_RAS( 162 ,0, sizeof(PGinfo->msecs), &(PGinfo->msecs));
  441.             return;
  442.             } /* end if */
  443.  
  444.           TempAtt0=Att0=pDescriptor->Descriptors.audio_control.output0_select;
  445.           TempAtt2=Att2=pDescriptor->Descriptors.audio_control.output1_select;
  446.  
  447.           if(TempAtt0==TempAtt2)        // if both channels mapped the same
  448.             {
  449.             switch(TempAtt0)
  450.               {
  451.               case PCS_MUTED:           // both channels off
  452.                 Att0=Att1=Att2=Att3=0;
  453.                 break;
  454.               case PCS_CHANNEL0:        // mono from left
  455.                 if(TempAtt1==TempAtt3)          // same volume setting required
  456.                   {
  457.                   Att0=Att1;            // volume setting on left channel
  458.                   Att2=Att3=0;          // no volume on right
  459.                   } /* end if */
  460.                 else
  461.                   {
  462.                   // this is an error
  463.                   IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  464.                   DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  465.                   return;
  466.                   } /* end else */
  467.                 break;
  468.               case PCS_CHANNEL1:        // mono from right
  469.                 if(TempAtt1==TempAtt3)          // same volume setting required
  470.                   {
  471.                   Att2=Att3;            // volume setting on right channel
  472.                   Att0=Att1=0;          // no volume on left
  473.                   } /* end if */
  474.                 else
  475.                   {
  476.                   // this is an error
  477.                   IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  478.                   DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  479.                   return;
  480.                   } /* end else */
  481.                 break;
  482.               default:
  483.                 break;
  484.               } /* end switch */
  485.             } /* end if */
  486.           else                          // different channel settings
  487.             {
  488.             switch(TempAtt0)              // left channel
  489.               {
  490.               case PCS_MUTED:             // turn off channel
  491.                 Att0=0;
  492.                 Att1=0;
  493.                 break;
  494.               case PCS_CHANNEL0:          // normal condition
  495.                 Att0=Att1;
  496.                 Att1=0;
  497.                 break;
  498.               case PCS_CHANNEL1:          // left swapped with right
  499.                 if(TempAtt1==TempAtt3)    // volumes MUST match
  500.                   {
  501.                   Att1=Att0;
  502.                   Att0=0;
  503.                   } /* end if */
  504.                 else
  505.                   {
  506.                   // this is an error
  507.                   IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  508.                   DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  509.                   return;
  510.                   } /* end else */
  511.                 break;
  512.               default:
  513.                 break;
  514.               } /* end switch */
  515.  
  516.             switch(TempAtt2)
  517.               {
  518.               case PCS_MUTED:             // turn off channel
  519.                 Att2=0;
  520.                 Att3=0;
  521.                 break;
  522.               case PCS_CHANNEL0:          // right swapped to left
  523.                 if(TempAtt1==TempAtt3)    // volumes MUST match
  524.                   {
  525.                   Att3=Att2;
  526.                   Att2=0;
  527.                   } /* end if */
  528.                 else
  529.                   {
  530.                   // this is an error
  531.                   IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  532.                   DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  533.                   return;
  534.                   } /* end else */
  535.                 break;
  536.               case PCS_CHANNEL1:          // normal condition
  537.                 Att2=Att3;
  538.                 Att3=0;
  539.                 break;
  540.               default:
  541.                 break;
  542.               } /* end switch */
  543.             } /* end else */
  544.  
  545.  
  546.           PreStatus=DriveStatus(Spincount);     // get drive status now
  547.           Saveflag=bInfoFlag;
  548.           Status=DriveCommand( SetAudioVolume, MAKEULONG(MAKEUSHORT(Att0,Att1),0),
  549.                                                MAKEULONG(MAKEUSHORT(Att2,Att3),0),
  550.                                                0, 0);
  551.           if( COMMANDCHECK(Status))
  552.             {
  553.              IORB_CmdErr( IOERR_CMD_NOT_SUPPORTED, PIORB, SCSI_SK_ILLEGALREQ, ASC_INVALID_FIELD);
  554.              DevHelp_RAS( 162 , 0 , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  555.             }
  556.           else
  557.             {
  558.             i=0;
  559.             do 
  560.               {
  561.               SHORTWAIT;
  562.               Status=DriveStatus(Spincount);
  563.               i++;
  564.               } while (Status!=PreStatus && i<255); /* end do */
  565.             bInfoFlag=Saveflag;
  566.             }
  567.  
  568.           } /* end else */
  569.  
  570.  }
  571.  
  572. VOID ProcessRead(PIORB PIORB,PCDCDB pCDB)
  573. {
  574.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  575. USHORT i,usBlkCount,usBlkSize,Status,SenseStatus;
  576. SHORT readtries=3;
  577. PSCATGATENTRY pSGList;
  578. ULONG LBA;
  579. CDROMSTAT e;
  580. BOOL TriedMode=FALSE;
  581. UCHAR OldMode,NewMode;
  582.  
  583. if (wDrvVer[0]=='D')
  584.   {
  585.   readtries=8;
  586.   } 
  587.  
  588. if(pCDB->OpCode==SCSI_READ_6)
  589.   {
  590.   LBA=AdrHsg2Red(MAKEULONG(MAKEUSHORT(pCDB->Read_6.LBA.usbytes.byte_1,
  591.                 pCDB->Read_6.LBA.usbytes.byte_0),
  592.                 MAKEUSHORT(pCDB->Read_6.LBA_msb,0)));
  593.   usBlkCount=(USHORT)pCDB->Read_6.transfer_length;
  594.   } /* end if */
  595. else
  596.   {
  597.   LBA=AdrHsg2Red(pCDB->Read_10.LBA.dword);
  598.   usBlkCount=(USHORT)pCDB->Read_10.transfer_length.word;
  599.   } /* end else */
  600.  
  601. DevHelp_RAS( 166 ,pCDB->OpCode , sizeof(LBA), &(LBA));
  602. if( ulLeadOut < LBA )
  603.   {
  604.   IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_LBA);
  605.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  606.   return;
  607.   }
  608.  
  609. for(i=bMinTno; i<=bMaxTno+1; i++)
  610.   {
  611.   if((TOCInfoArea[i].start>LBA))        // find track past LBA (or leadout area)
  612.     {
  613.     i--;                              // back up one (could be last track)
  614.     if(i>=bMinTno)
  615.       {
  616.       if((TOCInfoArea[i].Control & TCI_DATA))  // if track is data, ok
  617.         {
  618.  
  619.         pSGList=pPIORB->pSGList;
  620.  
  621.         for(i=0;i<pPIORB->cSGList;i++,pSGList++ )
  622.           {
  623.           usBlkSize=pSGList->XferBufLen/usBlkCount;
  624.         tryagain1:
  625.           DevHelp_PhysToGDT(pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen, FP_SEG(Read_IOBuffer));
  626.         tryagain:
  627.           Status=DriveCommand( Read, LBA, usBlkCount, (PCDROMSTAT) Read_IOBuffer ,DrvBlockSize);
  628.  
  629. #if 0
  630.           if(READERROR(Status))                 // read error ?
  631.             {
  632.             SenseStatus=DriveCommand(RequestSense,0,0,&e,sizeof(e.SenseData));
  633.             DevHelp_RAS1( 168 ,e.SenseData.SenseKey , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  634.             DevHelp_RAS1( 168 ,SenseStatus , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  635.             DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  636.             IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  637.             break;
  638.             } /* end if */
  639.           else if(COMMANDCHECK(Status) || TIMEOUT(Status) || DOOROPEN(Status))
  640. #endif
  641.           if(COMMANDCHECK(Status) || TIMEOUT(Status) || DOOROPEN(Status) || READERROR(Status))
  642.             {
  643.             DevHelp_RAS1( 168 ,(pCDB->OpCode<<8) | LOBYTE(Status) , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  644.             if(READERROR(Status))                 // read error ?
  645.               {
  646.               SenseStatus=DriveCommand(RequestSense,0,0,&e,sizeof(e.SenseData));
  647.               DevHelp_RAS1( 168 ,e.SenseData.SenseKey , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  648.               DevHelp_RAS1( 168 ,SenseStatus , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  649.               } /* end if */
  650.             --readtries;                // only try 3 times
  651.             if(readtries>0)             // counter 0?
  652.               {
  653.               goto tryagain;            // try read again
  654.               } /* end if */
  655.             else                        // maybe after last retry
  656.               {
  657.               if(readtries==0)          // three tries already?
  658.                 {
  659.                 ResetDrive();           // reset
  660.                 goto tryagain1;         // try one more time
  661.                                         // remap GDTsel first
  662.                 } /* end if */
  663.               }
  664.             IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  665.             DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  666.             break;
  667.             }
  668.           } /* end for */
  669.         break;                          // end of track search loop
  670.         }
  671.       else
  672.         {
  673.         IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  674.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  675.         break;
  676.         }
  677.       } /* end if */
  678.     else
  679.       {
  680.       IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  681.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  682.       break;
  683.       }
  684.     } /* end if */
  685.   } /* end for */
  686. if(i>bMaxTno+1)
  687.   {
  688.   IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  689.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  690.   } /* end if */
  691. }
  692. VOID ProcessSeek(PIORB PIORB,PCDCDB pCDB)
  693. {
  694. ULONG ulPos;
  695. USHORT Status;
  696. if(pCDB->OpCode==SCSI_SEEK_6)
  697.   {
  698.   ulPos= AdrHsg2Red(MAKEULONG( MAKEUSHORT(pCDB->Seek_6.LBA.usbytes.byte_0,
  699.                                pCDB->Seek_6.LBA.usbytes.byte_1),
  700.                     MAKEUSHORT(pCDB->Seek_6.LBA_msb,0)));
  701.   } /* end if */
  702. else
  703.   {
  704.   ulPos=AdrHsg2Red(pCDB->Seek_10.LBA.dword);
  705.   } /* end else */
  706. if(ValidMSF(ulPos))
  707.   {
  708.   if((ulPos>=TOCInfoArea[0].start) && (ulPos<=TOCInfoArea[bMaxTno+1].start) )        // find track past LBA (or leadout area)
  709.     {
  710.     if(COMMANDCHECK((Status=DriveCommand( Seek, ulPos,0,0,0))))
  711.       {
  712.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
  713.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  714.       } /* end else */
  715.     } /* end if */
  716.   else
  717.     {
  718.     IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
  719.     DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  720.     }
  721.   } /* end if */
  722. else
  723.   {
  724. //IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  725. //  IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
  726.   IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
  727.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  728.   } /* end else */
  729. }
  730. VOID ProcessModeSelectSense(PIORB PIORB,PCDCDB pCDB)
  731. {
  732.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  733.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  734. struct ModeSelectParmList far *pDescriptor;
  735. USHORT BlockLength;
  736. CDROMSTAT Data;
  737.  
  738. if( pDescriptor = (struct ModeSelectParmList far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  739.   {
  740.   if(pDescriptor->ModeSelectHdr.block_descriptor_len==0)
  741.     {
  742.     if(pDescriptor->Descriptors.audio_control.page_code == PAGE_AUDIO_CONTROL)
  743.       {
  744.       ProcessAudioPageControl(PIORB, pDescriptor);
  745.       } /* end if */
  746.     else
  747.       {
  748.       IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  749.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  750.       } /* end else */
  751.     } /* end if */
  752.   else if(pDescriptor->ModeSelectHdr.block_descriptor_len==sizeof(struct BlockDescriptor))
  753.     {
  754.     if(pIORB->apt.Flags == PT_DIRECTION_IN)
  755.       {
  756.       if(1)
  757.         {
  758.         pDescriptor->Descriptors.BlockDescriptor.block_length_2=LOBYTE(DrvBlockSize);
  759.         pDescriptor->Descriptors.BlockDescriptor.block_length_1=HIBYTE(DrvBlockSize);
  760.         }
  761.       else
  762.         {
  763.         IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
  764.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  765.         }
  766.       } /* end if */
  767.     else
  768.       {
  769.       BlockLength=MAKEUSHORT(pDescriptor->Descriptors.BlockDescriptor.block_length_2 ,pDescriptor->Descriptors.BlockDescriptor.block_length_1 );
  770.       if(BlockLength)
  771.         {
  772.         if(COMMANDCHECK(DriveCommand( DriveConfig,BLOCKSIZE ,BlockLength, 0, 0)))
  773.           {
  774.           IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
  775.           DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  776.           DevHelp_RAS( 169 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  777.           }
  778.         else
  779.           {
  780.           DrvBlockSize=BlockLength;
  781.           if(DrvBlockSize==2352)
  782.             {
  783.             DriveCommand( SetDriveMode,DataLength|EccBit|MuteData ,0, 0, 0);
  784.             } /* end if */
  785.           else
  786.             {
  787. //            DriveCommand( SetDriveMode,TestMode|MuteData ,0, 0, 0);
  788.             DriveCommand( SetDriveMode,Mode==Mode2?TestMode|MuteData:MuteData ,0, 0, 0);
  789.             } /* end else */
  790.           }
  791.         } /* end if */
  792.       else
  793.         {
  794.         IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  795.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  796.         } /* end else */
  797.       } /* end else */
  798.     } /* end else */
  799.   DUMMYWAIT;
  800.   }
  801. }
  802. VOID ProcessPauseResume(PIORB PIORB,PCDCDB pCDB)
  803. {
  804. ULONG Start;
  805. if(pCDB->PauseResume.resume)            // is this a resume request?
  806.   {
  807.   if(bPauseFlag)                        // are we paused?
  808.     {
  809.     Start=MAKEULONG(MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AFrame),BCD2Bin(HoldPos.TrackInfo.ASec)),
  810.                   MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AMin),0));
  811.     if(!COMMANDCHECK(DriveCommand( PlayAudioMSF, Start, AudioPlayStop,0,0)))
  812.       {
  813.       bPlayFlag=TRUE;
  814.       bPauseFlag=FALSE;
  815.       }
  816.     else
  817.       {
  818.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  819.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  820.       }
  821.     } /* end if */
  822.   } /* end if */
  823. else                                    // must be a pause request
  824.   {
  825.   if(!bPauseFlag)
  826.     {
  827.     if(!COMMANDCHECK(DriveCommand(Hold,0,0,0,0)))
  828.       {
  829.       DriveCommand(ReadSubQ,0,0,&HoldPos,sizeof(HoldPos.TrackInfo));
  830.       bPlayFlag=FALSE;
  831.       bPauseFlag=TRUE;
  832.       } /* end if */
  833.     else
  834.       {
  835.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  836.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  837.       }
  838.     } /* end if */
  839.   } /* end else */
  840. }
  841. VOID ProcessPlay(PIORB PIORB,PCDCDB pCDB)
  842. {
  843. ULONG Start,End;
  844. USHORT Status,i,q;
  845. Start=MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.starting_F,pCDB->PlayAudio_MSF.starting_S),
  846.                 MAKEUSHORT(pCDB->PlayAudio_MSF.starting_M,0));
  847. AudioPlayStop=End=  MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.ending_F,pCDB->PlayAudio_MSF.ending_S),
  848.                 MAKEUSHORT(pCDB->PlayAudio_MSF.ending_M,0));
  849. if(ValidMSF(Start) && ValidMSF(End))
  850.   {
  851.   if(Start<=End)
  852.     {
  853.     for(i=bMinTno; i<=bMaxTno+1; i++)
  854.       {
  855.       if((TOCInfoArea[i].start>Start))    // find track past LBA (or leadout area)
  856.         {
  857.         i--;                              // back up one (could be last track)
  858.         if(i>=bMinTno)
  859.           {
  860.           if(!(TOCInfoArea[i].Control & TCI_DATA))  // if track is NOT data, ok
  861.             {
  862.             // are we playing or THINK we're playing
  863.             if(bPlayFlag || AUDIOBUSY(bStatusFlag))
  864.               {
  865.               DriveCommand(Hold,0,0,0,0);   // then STOP playing NOW
  866.               bPlayFlag=FALSE;
  867.               } /* end if */
  868.             for(q=4; q--; )
  869.               {
  870.               Status=DriveCommand( PlayAudioMSF, Start, End ,0,0);
  871.               if(AUDIOBUSY(Status))
  872.                 {
  873.                 break;
  874.                 } /* end if */
  875.               else
  876.                 {
  877.                 Status=DriveStatus(Spincount);
  878.                 if(AUDIOBUSY(Status))
  879.                   {
  880.                   break;
  881.                   } /* end if */
  882.                 } /* end else */
  883.               } /* end for */
  884.             if(q)
  885.               {
  886.               bPlayFlag=TRUE;
  887.               bPauseFlag=FALSE;
  888.               }
  889.             else
  890.               {
  891.               bPlayFlag=FALSE;
  892.               bPauseFlag=FALSE;
  893.               IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  894.               DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  895.               }
  896.             break;                          // end of track search loop
  897.             }
  898.           else
  899.             {
  900.             IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  901.             DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  902.             break;
  903.             }
  904.           } /* end if */
  905.         else
  906.           {
  907.           IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  908.           DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  909.           break;
  910.           }
  911.         break;
  912.         } /* end if */
  913.       } /* end for */
  914.     if(i>bMaxTno+1)
  915.       {
  916.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  917.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  918.       } /* end if */
  919.     } /* end if */
  920.   else
  921.     {
  922. //  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  923.     IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  924.     DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  925.     } /* end else */
  926.   } /* end if */
  927. else
  928.   {
  929. //IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  930.   IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  931.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  932.   } /* end else */
  933. }
  934.  
  935. VOID ProcessDiskInfo(PIORB PIORB,PCDCDB pCDB)
  936. {
  937. union ADD_ReadDiskInfo_Data * buffer;
  938. CDROMSTAT Data;
  939.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  940.  SHORT Status;
  941.  
  942. if( buffer= (union ADD_ReadDiskInfo_Data *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  943.   {
  944.   memset(buffer,0,sizeof(union ADD_ReadDiskInfo_Data));
  945.   switch(pCDB->AddDiscInfo.type)
  946.     {
  947.     case TYPE_CAPABILITIES_INFO:
  948.       buffer->capabilities.read_capabilities=CAP_MODE2_FORM1 | CAP_MODE2_FORM2 ;
  949.       if(Lu002==FALSE)
  950.         {
  951.         buffer->capabilities.read_capabilities|=CAP_MULTISESSION;
  952.         } /* end if */
  953.       buffer->capabilities.reserved_1=0;
  954.       buffer->capabilities.max_block_length.usbytes.byte_0=HIBYTE(2352);
  955.       buffer->capabilities.max_block_length.usbytes.byte_1=LOBYTE(2352);
  956.       break;
  957.  
  958.     case TYPE_LASTSESSION_INFO:
  959.       if(DISCIN(bStatusFlag))
  960.         {
  961.         while(TIMEOUT(Status=DriveCommand(ReadDiscInfo,0,0,&Data,sizeof(Data.DiscInfo))));
  962.         if (!TIMEOUT(Status))
  963.           {
  964.           if(Data.DiscInfo.Type!=0)
  965.             {
  966.             buffer->last_session.reserved=  0;
  967.             buffer->last_session.amin    =  BCD2Bin(Data.DiscInfo.Min);
  968.             buffer->last_session.asec    =  BCD2Bin(Data.DiscInfo.Sec);
  969.             buffer->last_session.aframe  =  BCD2Bin(Data.DiscInfo.Frame);
  970.             }
  971.           }
  972.         } /* end if */
  973.       break;
  974.     }
  975.   }
  976. }
  977.  
  978. VOID ProcessStartStop(PIORB PIORB,PCDCDB pCDB)
  979. {
  980. USHORT Status;
  981. if(pCDB->StartStopUnit.LoEj == 1 )
  982.   {
  983.   CDROMSTAT c;
  984.   // eject
  985.   if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
  986.     {
  987.     if(pCDB->StartStopUnit.start == 1 )
  988.       {
  989.       if(DOOROPEN(bStatusFlag))
  990.         {
  991.         Status= DriveCommand( Close,0 ,0, 0, 0);
  992.         }
  993.       }
  994.     else if(!DOOROPEN(bStatusFlag))  // can't eject if door open
  995.       {
  996.       Status= DriveCommand( LockUnlock,Query ,0, &c, sizeof(c.LockStatus));
  997.       if(c.LockStatus.State==Unlocked)
  998.         {
  999.         Status= DriveCommand( Eject,0 ,0, 0, 0);
  1000.         bPauseFlag=FALSE;
  1001.         bPlayFlag=FALSE;
  1002.         } /* end if */
  1003.       } /* end if */
  1004.     } /* end if */
  1005.   else
  1006.     {
  1007.     IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1008.     } /* end else */
  1009.   } /* end else */
  1010. else if(pCDB->StartStopUnit.start==1)
  1011.   {
  1012.   // Start unit
  1013.   } /* end if */
  1014. else
  1015.   {
  1016.   DriveCommand(Stop,0,0,0,0);
  1017.   bPauseFlag=FALSE;
  1018.   bPlayFlag=FALSE;
  1019.   // must be stop
  1020.   }
  1021. }
  1022.  
  1023. VOID ProcessLock(PIORB PIORB,PCDCDB pCDB)
  1024. {
  1025. CDROMSTAT c;
  1026. USHORT Status;
  1027.  
  1028. if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
  1029.   {
  1030.   if(!DOOROPEN(bStatusFlag))    // only issue command if door not open
  1031.     {
  1032.     Status= DriveCommand( LockUnlock,pCDB->PreventAllowRemoval.prevent?Lock:Unlock ,0, &c, sizeof(c.LockStatus));
  1033.     if(TIMEOUT(Status))
  1034.       {
  1035.       IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1036.       } /* end if */
  1037.     else
  1038.       {
  1039.       DrawerState=pCDB->PreventAllowRemoval.prevent?Locked:Unlocked;
  1040.       }
  1041.     } /* end if */
  1042.   } /* end if */
  1043. else
  1044.   {
  1045.   IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1046.   } /* end else */
  1047. }
  1048. VOID ProcessSubChan(PIORB PIORB,PCDCDB pCDB)
  1049. {
  1050.          switch (pCDB->ReadSubChannel.data_format)
  1051.            {
  1052.  
  1053.             case RSC_Q_SUB_CHANNEL:
  1054.             case RSC_CURRENT_POSITION:
  1055.                  ProcessCurrentPosition(PIORB, pCDB);
  1056.                break;
  1057.  
  1058.             case RSC_MEDIA_CAT_NUM:
  1059.                  ProcessMediaCatalogNumber(PIORB, pCDB);
  1060.                break;
  1061.  
  1062.               case RSC_TRACK_ISRC:      // not supported on Mitsumi
  1063. //               ProcessTrackISrc(PIORB, pCDB);
  1064.                  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1065.                  break;
  1066.             default:
  1067.                  break;
  1068.            }
  1069. }
  1070.  
  1071. VOID ProcessCapacity(PIORB PIORB,PCDCDB pCDB)
  1072. {
  1073. CDROMSTAT Data;
  1074. struct ReadCapacity_Data far *pReadCap;
  1075.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  1076.  
  1077. if( pReadCap= (struct ReadCapacity_Data far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  1078.   {
  1079.   if(ulVSSize)
  1080.     {
  1081.     pReadCap->capacity_LBA.ulbytes.byte_0=HIBYTE(HIUSHORT(ulVSSize));
  1082.     pReadCap->capacity_LBA.ulbytes.byte_1=LOBYTE(HIUSHORT(ulVSSize));
  1083.     pReadCap->capacity_LBA.ulbytes.byte_2=HIBYTE(LOUSHORT(ulVSSize));
  1084.     pReadCap->capacity_LBA.ulbytes.byte_3=LOBYTE(LOUSHORT(ulVSSize));
  1085.     pReadCap->capacity_block_length.dword=2048;
  1086.     } /* end if */
  1087.   }
  1088. }
  1089. BOOL ValidMSF(ULONG pos)
  1090. {
  1091. BOOL Flag=FALSE;
  1092. UCHAR Min,Sec, Frame;
  1093.         Min = LOBYTE(HIUSHORT(pos));
  1094.         Sec = HIBYTE(LOUSHORT(pos));
  1095.         Frame = LOBYTE(LOUSHORT(pos));
  1096.  
  1097.         if(Min>=0 && Min<=75)
  1098.           {
  1099.           Flag=TRUE;
  1100.           } /* end if */
  1101.         if(Sec>=0 && Sec<=59)
  1102.           {
  1103.           Flag=TRUE;
  1104.           } /* end if */
  1105.         if(Frame>=0 && Frame<=59)
  1106.           {
  1107.           Flag=TRUE;
  1108.           } /* end if */
  1109.  
  1110.         return Flag;
  1111. }
  1112. // Not supported on Mitsumi
  1113. VOID ProcessHeader(PIORB PIORB, PCDCDB pCDB)
  1114.  {
  1115.  struct ReadHeader_Data far *HeaderData;
  1116.  CDROMSTAT Data;
  1117.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  1118.  PSCATGATENTRY pSGList;
  1119.  
  1120. //   if(!CD_DriveCmd( DC_ReadHeader, pCDB->ReadHeader.MSF?MSF_BIT:0,pCDB->ReadHeader.LBA.dword, (PBYTE)&Data))
  1121. //     {
  1122. //     pSGList=pIORB->apt.pSGList;
  1123. //     if( HeaderData = (struct ReadHeader_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
  1124. //       {
  1125. //       HeaderData->cdrom_data_mode = Data.s.HDR.Mode;
  1126. //       if(pCDB->ReadHeader.MSF)
  1127. //         {
  1128. //         HeaderData->abs_address.msf0.min=Data.s.HDR.ABSCDROMAddr[0];
  1129. //         HeaderData->abs_address.msf0.sec=Data.s.HDR.ABSCDROMAddr[1];
  1130. //         HeaderData->abs_address.msf0.frame=Data.s.HDR.ABSCDROMAddr[2];
  1131. //         HeaderData->abs_address.msf0.zero=0;
  1132. //         } /* end if */
  1133. //       }
  1134. //     }
  1135. //   else
  1136. //     {
  1137. //     IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_INCOMPATIBLE_CARTRIDGE);
  1138. //     }
  1139.  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1140. }
  1141. #ifdef SUPPORTED
  1142. // Not supported on Mitsumi
  1143. //VOID ProcessTrackISrc(PIORB PIORB, PCDCDB pCDB)
  1144. //{
  1145. //CDROMSTAT  Data;
  1146. //PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  1147. //union CDROM_SubChannel_Info far *SubChan;
  1148. //PSCATGATENTRY pSGList;
  1149. //
  1150. //
  1151. //    if(!CD_DriveCmd( DC_ReadISRC, pCDB->ReadSubChannel.track_number,0, (PBYTE)&Data))
  1152. //      {
  1153. //      if(Data.s.ISRC.Valid)
  1154. //        {
  1155. //        pSGList=pIORB->apt.pSGList;
  1156. //        if( SubChan = (union CDROM_SubChannel_Info far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
  1157. //          {
  1158. //          SubChan->track_ISRC.sub_channel_hdr.audio_status=Data.s.ISRC.Audio_Status;
  1159. //          SubChan->track_ISRC.track_number=pCDB->ReadSubChannel.track_number;
  1160. //          SubChan->track_ISRC.tcval=Data.s.ISRC.Control<<4 || Data.s.ISRC.ADR;
  1161. //          memcpy(SubChan->track_ISRC.media_catalog_number,Data.s.ISRC.code,sizeof(Data.s.ISRC.code));
  1162. //          }
  1163. //        } /* end if */
  1164. //      else
  1165. //        {
  1166. //        IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  1167. //        } /* end else */
  1168. //      }
  1169. //    else
  1170. //      {
  1171. //      IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  1172. //      }
  1173. //}
  1174. #endif
  1175.