home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / rmfiles.zip / mitsrc.zip / PROCCDB.C < prev    next >
C/C++ Source or Header  |  1994-07-13  |  42KB  |  1,161 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. if(pCDB->OpCode==SCSI_READ_6)
  583.   {
  584.   LBA=AdrHsg2Red(MAKEULONG(MAKEUSHORT(pCDB->Read_6.LBA.usbytes.byte_1,
  585.                 pCDB->Read_6.LBA.usbytes.byte_0),
  586.                 MAKEUSHORT(pCDB->Read_6.LBA_msb,0)));
  587.   usBlkCount=(USHORT)pCDB->Read_6.transfer_length;
  588.   } /* end if */
  589. else
  590.   {
  591.   LBA=AdrHsg2Red(pCDB->Read_10.LBA.dword);
  592.   usBlkCount=(USHORT)pCDB->Read_10.transfer_length.word;
  593.   } /* end else */
  594.  
  595. DevHelp_RAS( 166 ,pCDB->OpCode , sizeof(LBA), &(LBA));
  596. if( ulLeadOut < LBA )
  597.   {
  598.   IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_LBA);
  599.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  600.   return;
  601.   }
  602.  
  603. for(i=bMinTno; i<=bMaxTno+1; i++)
  604.   {
  605.   if((TOCInfoArea[i].start>LBA))        // find track past LBA (or leadout area)
  606.     {
  607.     i--;                              // back up one (could be last track)
  608.     if(i>=bMinTno)
  609.       {
  610.       if((TOCInfoArea[i].Control & TCI_DATA))  // if track is data, ok
  611.         {
  612.  
  613.         pSGList=pPIORB->pSGList;
  614.  
  615.         for(i=0;i<pPIORB->cSGList;i++,pSGList++ )
  616.           {
  617.           usBlkSize=pSGList->XferBufLen/usBlkCount;
  618.         tryagain1:
  619.           DevHelp_PhysToGDT(pSGList->ppXferBuf, (USHORT)pSGList->XferBufLen, FP_SEG(Read_IOBuffer));
  620.         tryagain:
  621.           Status=DriveCommand( Read, LBA, usBlkCount, (PCDROMSTAT) Read_IOBuffer ,DrvBlockSize);
  622.  
  623.  
  624.           if(READERROR(Status))                 // read error ?
  625.             {
  626.             SenseStatus=DriveCommand(RequestSense,0,0,&e,sizeof(e.SenseData));
  627.             DevHelp_RAS1( 168 ,e.SenseData.SenseKey , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  628.             DevHelp_RAS1( 168 ,SenseStatus , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  629.             DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  630.             IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  631.             break;
  632.             } /* end if */
  633.           else if(COMMANDCHECK(Status) || TIMEOUT(Status) || DOOROPEN(Status))
  634.             {
  635.             DevHelp_RAS1( 168 ,(pCDB->OpCode<<8) | LOBYTE(Status) , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  636.             --readtries;                // only try 3 times
  637.             if(readtries>0)             // counter 0?
  638.               {
  639.               goto tryagain;            // try read again
  640.               } /* end if */
  641.             else                        // maybe after last retry
  642.               {
  643.               if(readtries==0)          // three tries already?
  644.                 {
  645.                 ResetDrive();           // reset
  646.                 goto tryagain1;         // try one more time
  647.                                         // remap GDTsel first
  648.                 } /* end if */
  649.               }
  650.             IORB_CmdErr(IOERR_ADAPTER_REFER_TO_STATUS, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  651.             DevHelp_RAS1( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  652.             break;
  653.             }
  654.           } /* end for */
  655.         break;                          // end of track search loop
  656.         }
  657.       else
  658.         {
  659.         IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  660.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  661.         break;
  662.         }
  663.       } /* end if */
  664.     else
  665.       {
  666.       IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  667.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  668.       break;
  669.       }
  670.     } /* end if */
  671.   } /* end for */
  672. if(i>bMaxTno+1)
  673.   {
  674.   IORB_CmdErr(IOERR_MEDIA_NOT_PRESENT, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_DATA_TRACK);
  675.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  676.   } /* end if */
  677. }
  678. VOID ProcessSeek(PIORB PIORB,PCDCDB pCDB)
  679. {
  680. ULONG ulPos;
  681. USHORT Status;
  682. if(pCDB->OpCode==SCSI_SEEK_6)
  683.   {
  684.   ulPos= AdrHsg2Red(MAKEULONG( MAKEUSHORT(pCDB->Seek_6.LBA.usbytes.byte_0,
  685.                                pCDB->Seek_6.LBA.usbytes.byte_1),
  686.                     MAKEUSHORT(pCDB->Seek_6.LBA_msb,0)));
  687.   } /* end if */
  688. else
  689.   {
  690.   ulPos=AdrHsg2Red(pCDB->Seek_10.LBA.dword);
  691.   } /* end else */
  692. if(ValidMSF(ulPos))
  693.   {
  694.   if((ulPos>=TOCInfoArea[0].start) && (ulPos<=TOCInfoArea[bMaxTno+1].start) )        // find track past LBA (or leadout area)
  695.     {
  696.     if(COMMANDCHECK((Status=DriveCommand( Seek, ulPos,0,0,0))))
  697.       {
  698.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
  699.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  700.       } /* end else */
  701.     } /* end if */
  702.   else
  703.     {
  704.     IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
  705.     DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  706.     }
  707.   } /* end if */
  708. else
  709.   {
  710. //IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  711. //  IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_SEEK_POSITIONING_ERROR);
  712.   IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_MEDIUMERR,ASC_INVALID_FIELD);
  713.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  714.   } /* end else */
  715. }
  716. VOID ProcessModeSelectSense(PIORB PIORB,PCDCDB pCDB)
  717. {
  718.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  719.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  720. struct ModeSelectParmList far *pDescriptor;
  721. USHORT BlockLength;
  722. CDROMSTAT Data;
  723.  
  724. if( pDescriptor = (struct ModeSelectParmList far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  725.   {
  726.   if(pDescriptor->ModeSelectHdr.block_descriptor_len==0)
  727.     {
  728.     if(pDescriptor->Descriptors.audio_control.page_code == PAGE_AUDIO_CONTROL)
  729.       {
  730.       ProcessAudioPageControl(PIORB, pDescriptor);
  731.       } /* end if */
  732.     else
  733.       {
  734.       IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  735.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  736.       } /* end else */
  737.     } /* end if */
  738.   else if(pDescriptor->ModeSelectHdr.block_descriptor_len==sizeof(struct BlockDescriptor))
  739.     {
  740.     if(pIORB->apt.Flags == PT_DIRECTION_IN)
  741.       {
  742.       if(1)
  743.         {
  744.         pDescriptor->Descriptors.BlockDescriptor.block_length_2=LOBYTE(DrvBlockSize);
  745.         pDescriptor->Descriptors.BlockDescriptor.block_length_1=HIBYTE(DrvBlockSize);
  746.         }
  747.       else
  748.         {
  749.         IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
  750.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  751.         }
  752.       } /* end if */
  753.     else
  754.       {
  755.       BlockLength=MAKEUSHORT(pDescriptor->Descriptors.BlockDescriptor.block_length_2 ,pDescriptor->Descriptors.BlockDescriptor.block_length_1 );
  756.       if(BlockLength)
  757.         {
  758.         if(COMMANDCHECK(DriveCommand( DriveConfig,BLOCKSIZE ,BlockLength, 0, 0)))
  759.           {
  760.           IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_ILLEGAL_MODE_FOR_TRACK);
  761.           DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  762.           DevHelp_RAS( 169 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  763.           }
  764.         else
  765.           {
  766.           DrvBlockSize=BlockLength;
  767.           if(DrvBlockSize==2352)
  768.             {
  769.             DriveCommand( SetDriveMode,DataLength|EccBit|MuteData ,0, 0, 0);
  770.             } /* end if */
  771.           else
  772.             {
  773. //            DriveCommand( SetDriveMode,TestMode|MuteData ,0, 0, 0);
  774.             DriveCommand( SetDriveMode,Mode==Mode2?TestMode|MuteData:MuteData ,0, 0, 0);
  775.             } /* end else */
  776.           }
  777.         } /* end if */
  778.       else
  779.         {
  780.         IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  781.         DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  782.         } /* end else */
  783.       } /* end else */
  784.     } /* end else */
  785.   DUMMYWAIT;
  786.   }
  787. }
  788. VOID ProcessPauseResume(PIORB PIORB,PCDCDB pCDB)
  789. {
  790. ULONG Start;
  791. if(pCDB->PauseResume.resume)            // is this a resume request?
  792.   {
  793.   if(bPauseFlag)                        // are we paused?
  794.     {
  795.     Start=MAKEULONG(MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AFrame),BCD2Bin(HoldPos.TrackInfo.ASec)),
  796.                   MAKEUSHORT(BCD2Bin(HoldPos.TrackInfo.AMin),0));
  797.     if(!COMMANDCHECK(DriveCommand( PlayAudioMSF, Start, AudioPlayStop,0,0)))
  798.       {
  799.       bPlayFlag=TRUE;
  800.       bPauseFlag=FALSE;
  801.       }
  802.     else
  803.       {
  804.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  805.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  806.       }
  807.     } /* end if */
  808.   } /* end if */
  809. else                                    // must be a pause request
  810.   {
  811.   if(!bPauseFlag)
  812.     {
  813.     if(!COMMANDCHECK(DriveCommand(Hold,0,0,0,0)))
  814.       {
  815.       DriveCommand(ReadSubQ,0,0,&HoldPos,sizeof(HoldPos.TrackInfo));
  816.       bPlayFlag=FALSE;
  817.       bPauseFlag=TRUE;
  818.       } /* end if */
  819.     else
  820.       {
  821.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  822.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  823.       }
  824.     } /* end if */
  825.   } /* end else */
  826. }
  827. VOID ProcessPlay(PIORB PIORB,PCDCDB pCDB)
  828. {
  829. ULONG Start,End;
  830. USHORT Status,i,q;
  831. Start=MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.starting_F,pCDB->PlayAudio_MSF.starting_S),
  832.                 MAKEUSHORT(pCDB->PlayAudio_MSF.starting_M,0));
  833. AudioPlayStop=End=  MAKEULONG(MAKEUSHORT(pCDB->PlayAudio_MSF.ending_F,pCDB->PlayAudio_MSF.ending_S),
  834.                 MAKEUSHORT(pCDB->PlayAudio_MSF.ending_M,0));
  835. if(ValidMSF(Start) && ValidMSF(End))
  836.   {
  837.   if(Start<=End)
  838.     {
  839.     for(i=bMinTno; i<=bMaxTno+1; i++)
  840.       {
  841.       if((TOCInfoArea[i].start>Start))    // find track past LBA (or leadout area)
  842.         {
  843.         i--;                              // back up one (could be last track)
  844.         if(i>=bMinTno)
  845.           {
  846.           if(!(TOCInfoArea[i].Control & TCI_DATA))  // if track is NOT data, ok
  847.             {
  848.             // are we playing or THINK we're playing
  849.             if(bPlayFlag || AUDIOBUSY(bStatusFlag))
  850.               {
  851.               DriveCommand(Hold,0,0,0,0);   // then STOP playing NOW
  852.               bPlayFlag=FALSE;
  853.               } /* end if */
  854.             for(q=4; q--; )
  855.               {
  856.               Status=DriveCommand( PlayAudioMSF, Start, End ,0,0);
  857.               if(AUDIOBUSY(Status))
  858.                 {
  859.                 break;
  860.                 } /* end if */
  861.               else
  862.                 {
  863.                 Status=DriveStatus(Spincount);
  864.                 if(AUDIOBUSY(Status))
  865.                   {
  866.                   break;
  867.                   } /* end if */
  868.                 } /* end else */
  869.               } /* end for */
  870.             if(q)
  871.               {
  872.               bPlayFlag=TRUE;
  873.               bPauseFlag=FALSE;
  874.               }
  875.             else
  876.               {
  877.               bPlayFlag=FALSE;
  878.               bPauseFlag=FALSE;
  879.               IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  880.               DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  881.               }
  882.             break;                          // end of track search loop
  883.             }
  884.           else
  885.             {
  886.             IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  887.             DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  888.             break;
  889.             }
  890.           } /* end if */
  891.         else
  892.           {
  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.           break;
  896.           }
  897.         break;
  898.         } /* end if */
  899.       } /* end for */
  900.     if(i>bMaxTno+1)
  901.       {
  902.       IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASCV_NOT_AUDIO_TRACK);
  903.       DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  904.       } /* end if */
  905.     } /* end if */
  906.   else
  907.     {
  908. //  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  909.     IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  910.     DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  911.     } /* end else */
  912.   } /* end if */
  913. else
  914.   {
  915. //IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  916.   IORB_CmdErr(IOERR_RBA_ADDRESSING_ERROR, PIORB,SCSI_SK_ILLEGALREQ,ASC_INVALID_FIELD);
  917.   DevHelp_RAS( 162 ,pCDB->OpCode , sizeof(PGinfo->msecs), &(PGinfo->msecs));
  918.   } /* end else */
  919. }
  920.  
  921. VOID ProcessDiskInfo(PIORB PIORB,PCDCDB pCDB)
  922. {
  923. union ADD_ReadDiskInfo_Data * buffer;
  924. CDROMSTAT Data;
  925.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  926.  SHORT Status;
  927.  
  928. if( buffer= (union ADD_ReadDiskInfo_Data *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  929.   {
  930.   memset(buffer,0,sizeof(union ADD_ReadDiskInfo_Data));
  931.   switch(pCDB->AddDiscInfo.type)
  932.     {
  933.     case TYPE_CAPABILITIES_INFO:
  934.       buffer->capabilities.read_capabilities=CAP_MODE2_FORM1 | CAP_MODE2_FORM2 ;
  935.       if(Lu002==FALSE)
  936.         {
  937.         buffer->capabilities.read_capabilities|=CAP_MULTISESSION;
  938.         } /* end if */
  939.       buffer->capabilities.reserved_1=0;
  940.       buffer->capabilities.max_block_length.usbytes.byte_0=HIBYTE(2352);
  941.       buffer->capabilities.max_block_length.usbytes.byte_1=LOBYTE(2352);
  942.       break;
  943.  
  944.     case TYPE_LASTSESSION_INFO:
  945.       if(DISCIN(bStatusFlag))
  946.         {
  947.         while(TIMEOUT(Status=DriveCommand(ReadDiscInfo,0,0,&Data,sizeof(Data.DiscInfo))));
  948.         if (!TIMEOUT(Status))
  949.           {
  950.           if(Data.DiscInfo.Type!=0)
  951.             {
  952.             buffer->last_session.reserved=  0;
  953.             buffer->last_session.amin    =  BCD2Bin(Data.DiscInfo.Min);
  954.             buffer->last_session.asec    =  BCD2Bin(Data.DiscInfo.Sec);
  955.             buffer->last_session.aframe  =  BCD2Bin(Data.DiscInfo.Frame);
  956.             }
  957.           }
  958.         } /* end if */
  959.       break;
  960.     }
  961.   }
  962. }
  963.  
  964. VOID ProcessStartStop(PIORB PIORB,PCDCDB pCDB)
  965. {
  966. USHORT Status;
  967. if(pCDB->StartStopUnit.LoEj == 1 )
  968.   {
  969.   CDROMSTAT c;
  970.   // eject
  971.   if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
  972.     {
  973.     if(pCDB->StartStopUnit.start == 1 )
  974.       {
  975.       if(DOOROPEN(bStatusFlag))
  976.         {
  977.         Status= DriveCommand( Close,0 ,0, 0, 0);
  978.         }
  979.       }
  980.     else if(!DOOROPEN(bStatusFlag))  // can't eject if door open
  981.       {
  982.       Status= DriveCommand( LockUnlock,Query ,0, &c, sizeof(c.LockStatus));
  983.       if(c.LockStatus.State==Unlocked)
  984.         {
  985.         Status= DriveCommand( Eject,0 ,0, 0, 0);
  986.         bPauseFlag=FALSE;
  987.         bPlayFlag=FALSE;
  988.         } /* end if */
  989.       } /* end if */
  990.     } /* end if */
  991.   else
  992.     {
  993.     IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  994.     } /* end else */
  995.   } /* end else */
  996. else if(pCDB->StartStopUnit.start==1)
  997.   {
  998.   // Start unit
  999.   } /* end if */
  1000. else
  1001.   {
  1002.   DriveCommand(Stop,0,0,0,0);
  1003.   bPauseFlag=FALSE;
  1004.   bPlayFlag=FALSE;
  1005.   // must be stop
  1006.   }
  1007. }
  1008.  
  1009. VOID ProcessLock(PIORB PIORB,PCDCDB pCDB)
  1010. {
  1011. CDROMSTAT c;
  1012. USHORT Status;
  1013.  
  1014. if(wDrvVer[0]=='F' || wDrvVer[0]=='D')
  1015.   {
  1016.   if(!DOOROPEN(bStatusFlag))    // only issue command if door not open
  1017.     {
  1018.     Status= DriveCommand( LockUnlock,pCDB->PreventAllowRemoval.prevent?Lock:Unlock ,0, &c, sizeof(c.LockStatus));
  1019.     if(TIMEOUT(Status))
  1020.       {
  1021.       IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1022.       } /* end if */
  1023.     else
  1024.       {
  1025.       DrawerState=pCDB->PreventAllowRemoval.prevent?Locked:Unlocked;
  1026.       }
  1027.     } /* end if */
  1028.   } /* end if */
  1029. else
  1030.   {
  1031.   IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1032.   } /* end else */
  1033. }
  1034. VOID ProcessSubChan(PIORB PIORB,PCDCDB pCDB)
  1035. {
  1036.          switch (pCDB->ReadSubChannel.data_format)
  1037.            {
  1038.  
  1039.             case RSC_Q_SUB_CHANNEL:
  1040.             case RSC_CURRENT_POSITION:
  1041.                  ProcessCurrentPosition(PIORB, pCDB);
  1042.                break;
  1043.  
  1044.             case RSC_MEDIA_CAT_NUM:
  1045.                  ProcessMediaCatalogNumber(PIORB, pCDB);
  1046.                break;
  1047.  
  1048.               case RSC_TRACK_ISRC:      // not supported on Mitsumi
  1049. //               ProcessTrackISrc(PIORB, pCDB);
  1050.                  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1051.                  break;
  1052.             default:
  1053.                  break;
  1054.            }
  1055. }
  1056.  
  1057. VOID ProcessCapacity(PIORB PIORB,PCDCDB pCDB)
  1058. {
  1059. CDROMSTAT Data;
  1060. struct ReadCapacity_Data far *pReadCap;
  1061.  PIORB_ADAPTER_PASSTHRU pPIORB=(PIORB_ADAPTER_PASSTHRU)PIORB;
  1062.  
  1063. if( pReadCap= (struct ReadCapacity_Data far *)DevHelp_PhysToVirt( (ULONG)pPIORB->pSGList->ppXferBuf, (USHORT)pPIORB->pSGList->XferBufLen ) )
  1064.   {
  1065.   if(ulVSSize)
  1066.     {
  1067.     pReadCap->capacity_LBA.ulbytes.byte_0=HIBYTE(HIUSHORT(ulVSSize));
  1068.     pReadCap->capacity_LBA.ulbytes.byte_1=LOBYTE(HIUSHORT(ulVSSize));
  1069.     pReadCap->capacity_LBA.ulbytes.byte_2=HIBYTE(LOUSHORT(ulVSSize));
  1070.     pReadCap->capacity_LBA.ulbytes.byte_3=LOBYTE(LOUSHORT(ulVSSize));
  1071.     pReadCap->capacity_block_length.dword=2048;
  1072.     } /* end if */
  1073.   }
  1074. }
  1075. BOOL ValidMSF(ULONG pos)
  1076. {
  1077. BOOL Flag=FALSE;
  1078. UCHAR Min,Sec, Frame;
  1079.         Min = LOBYTE(HIUSHORT(pos));
  1080.         Sec = HIBYTE(LOUSHORT(pos));
  1081.         Frame = LOBYTE(LOUSHORT(pos));
  1082.  
  1083.         if(Min>=0 && Min<=75)
  1084.           {
  1085.           Flag=TRUE;
  1086.           } /* end if */
  1087.         if(Sec>=0 && Sec<=59)
  1088.           {
  1089.           Flag=TRUE;
  1090.           } /* end if */
  1091.         if(Frame>=0 && Frame<=59)
  1092.           {
  1093.           Flag=TRUE;
  1094.           } /* end if */
  1095.  
  1096.         return Flag;
  1097. }
  1098. // Not supported on Mitsumi
  1099. VOID ProcessHeader(PIORB PIORB, PCDCDB pCDB)
  1100.  {
  1101.  struct ReadHeader_Data far *HeaderData;
  1102.  CDROMSTAT Data;
  1103.  PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  1104.  PSCATGATENTRY pSGList;
  1105.  
  1106. //   if(!CD_DriveCmd( DC_ReadHeader, pCDB->ReadHeader.MSF?MSF_BIT:0,pCDB->ReadHeader.LBA.dword, (PBYTE)&Data))
  1107. //     {
  1108. //     pSGList=pIORB->apt.pSGList;
  1109. //     if( HeaderData = (struct ReadHeader_Data far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
  1110. //       {
  1111. //       HeaderData->cdrom_data_mode = Data.s.HDR.Mode;
  1112. //       if(pCDB->ReadHeader.MSF)
  1113. //         {
  1114. //         HeaderData->abs_address.msf0.min=Data.s.HDR.ABSCDROMAddr[0];
  1115. //         HeaderData->abs_address.msf0.sec=Data.s.HDR.ABSCDROMAddr[1];
  1116. //         HeaderData->abs_address.msf0.frame=Data.s.HDR.ABSCDROMAddr[2];
  1117. //         HeaderData->abs_address.msf0.zero=0;
  1118. //         } /* end if */
  1119. //       }
  1120. //     }
  1121. //   else
  1122. //     {
  1123. //     IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_INCOMPATIBLE_CARTRIDGE);
  1124. //     }
  1125.  IORB_CmdErr(IOERR_CMD_NOT_SUPPORTED, PIORB,SCSI_SK_ABORTEDCMD,ASC_INVALID_FIELD);
  1126. }
  1127. #ifdef SUPPORTED
  1128. // Not supported on Mitsumi
  1129. //VOID ProcessTrackISrc(PIORB PIORB, PCDCDB pCDB)
  1130. //{
  1131. //CDROMSTAT  Data;
  1132. //PIORB_CDB pIORB = (PIORB_CDB)PIORB;
  1133. //union CDROM_SubChannel_Info far *SubChan;
  1134. //PSCATGATENTRY pSGList;
  1135. //
  1136. //
  1137. //    if(!CD_DriveCmd( DC_ReadISRC, pCDB->ReadSubChannel.track_number,0, (PBYTE)&Data))
  1138. //      {
  1139. //      if(Data.s.ISRC.Valid)
  1140. //        {
  1141. //        pSGList=pIORB->apt.pSGList;
  1142. //        if( SubChan = (union CDROM_SubChannel_Info far *)DevHelp_PhysToVirt( (ULONG)pSGList->ppXferBuf, pSGList->XferBufLen ) )
  1143. //          {
  1144. //          SubChan->track_ISRC.sub_channel_hdr.audio_status=Data.s.ISRC.Audio_Status;
  1145. //          SubChan->track_ISRC.track_number=pCDB->ReadSubChannel.track_number;
  1146. //          SubChan->track_ISRC.tcval=Data.s.ISRC.Control<<4 || Data.s.ISRC.ADR;
  1147. //          memcpy(SubChan->track_ISRC.media_catalog_number,Data.s.ISRC.code,sizeof(Data.s.ISRC.code));
  1148. //          }
  1149. //        } /* end if */
  1150. //      else
  1151. //        {
  1152. //        IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  1153. //        } /* end else */
  1154. //      }
  1155. //    else
  1156. //      {
  1157. //      IORB_CmdErr(IOERR_UNIT_NOT_READY, PIORB,SCSI_SK_MEDIUMERR,ASC_UNRECOVERED_ERROR);
  1158. //      }
  1159. //}
  1160. #endif
  1161.