/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = TOIORB.C
 *
 * DESCRIPTIVE NAME = Toshiba IORB and CDB conversion routines
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   Filters SCSI-2 Command Descriptor Blocks and converts
 *             them to the vendor unique Toshiba Command Descriptor
 *             Blocks.
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#include <flthdr.h>

USHORT NotifyReadSubChannel (PIORB_CDB);
USHORT NotifyReadTOC1 (PIORB_CDB);
USHORT NotifyReadTOC2 (PIORB_CDB);
USHORT NotifyPlayAudio (PIORB_CDB);
USHORT NotifyResume (PIORB_CDB);


/****************************************************************************
 *
 * FUNCTION NAME = Filter_Seek_6
 *
 * DESCRIPTION   = Filter SCSI-2 Seek (6) Command     (0x0B)
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_Seek_6 (pIORB)

PIORB_CDB pIORB;
{

   struct TOSH_CDB_AudioTrackSearch FAR *pCDB1;
   struct CDB_Seek_6 FAR *pCDB2;

   pCDB1 = (struct TOSH_CDB_AudioTrackSearch FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_Seek_6 FAR *) pCDB1;

   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_AudioTrackSearch);

   pCDB1->OpCode = TOSH_AUDIO_TRACK_SEARCH;

   pCDB1->search_address.hsg.byte_3 = pCDB2->LBA.usbytes.byte_1;
   pCDB1->search_address.hsg.byte_2 = pCDB2->LBA.usbytes.byte_0;
   pCDB1->search_address.hsg.byte_1 = pCDB2->LBA_msb;
   pCDB1->search_address.hsg.byte_0 = 0;

   pCDB1->play = 0;                     /* Search, no play */
   pCDB1->reserved_1 = 0;
   pCDB1->reserved_2 = 0;
   pCDB1->reserved_3 = 0;
   pCDB1->reserved_4 = 0;
   pCDB1->control = 0;

   return(CALL_ADD_AND_RET);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_Seek_10
 *
 * DESCRIPTION   = Filter SCSI-2 Seek (10) Command    (0x2B)
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_Seek_10 (pIORB)

PIORB_CDB pIORB;
{

   struct TOSH_CDB_AudioTrackSearch FAR *pCDB1;
   struct CDB_Seek_10 FAR *pCDB2;

   pCDB1 = (struct TOSH_CDB_AudioTrackSearch FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_Seek_10 FAR *) pCDB1;

   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_AudioTrackSearch);

   pCDB1->OpCode = TOSH_AUDIO_TRACK_SEARCH;
   pCDB1->play = 0;                     /* Search, no play */
   pCDB1->reserved_1 = 0;
   pCDB1->reserved_2 = 0;
   pCDB1->reserved_3 = 0;
   pCDB1->reserved_4 = 0;
   pCDB1->control = 0;

   return(CALL_ADD_AND_RET);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_ModeSelect
 *
 * DESCRIPTION   = Filter SCSI-2 Mode Select command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_ModeSelect (pIORB)

PIORB_CDB pIORB;

{
   UCHAR  play_mode;
   USHORT i, rc;

   struct TOSH_CDB_PlayAudio FAR *pCDB1;
   struct CDB_ModeSelect FAR *pCDB2;
   struct ModeSelectParmList FAR *pCDBData;
   PIORB_FLTWORK pFilter_workspace;
   NPUNITCB pUnitCB;

   BOOL   left_off  = FALSE,
          right_off = FALSE;

   rc = CALL_ADD_AND_RET;

   pCDB1 = (struct TOSH_CDB_PlayAudio FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_ModeSelect FAR *) pCDB1;
   pCDBData = (struct ModeSelectParmList FAR *) &(pIORB->CDB_data);

   /*
   ** Convert Mode Select - Audio Control Page to
   **  a Toshiba Play Audio Command with play mode set.
   */
   if ( (pCDBData->ModeSelectHdr.block_descriptor_len == 0) &&
        (pCDBData->Descriptors.audio_control.page_code == PAGE_AUDIO_CONTROL) )
   {
      pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_PlayAudio);
      pIORB->apt.cSGList =  0;
      pIORB->apt.pSGList =  0;
      pIORB->apt.ppSGLIST = 0;


      if ( (pCDBData->Descriptors.audio_control.output0_select > 3) ||
           (pCDBData->Descriptors.audio_control.output0_volume == PCS_MUTED) )

         left_off = TRUE;

      if ( (pCDBData->Descriptors.audio_control.output1_select > 3) ||
           (pCDBData->Descriptors.audio_control.output1_volume == PCS_MUTED) )

         right_off = TRUE;


      if (left_off & right_off)
         play_mode = TOSH_PLAY_MUTE;
      else if (left_off)
         play_mode = TOSH_PLAY_RIGHT_CHANNEL;
      else if (right_off)
         play_mode = TOSH_PLAY_LEFT_CHANNEL;
      else if (pCDBData->Descriptors.audio_control.output0_select ^
               pCDBData->Descriptors.audio_control.output1_select)
         play_mode = TOSH_PLAY_STEREO;
      else if (pCDBData->Descriptors.audio_control.output0_select == 0)
         play_mode = TOSH_PLAY_RIGHT_CHANNEL;
      else
         play_mode = TOSH_PLAY_LEFT_CHANNEL;


      pCDB1->OpCode = TOSH_PLAY_AUDIO;
      pCDB1->play_mode = play_mode;
      pCDB1->reserved_1 = 0;

      for (i = 2; i < 9; i++)
         *( (PBYTE) pCDB1+i) = 0;

      pCDB1->control = CONTROL_TYPE_PREVIOUS_ADDRESS;

      pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
      pUnitCB = pFilter_workspace->pUnitCB;
      pUnitCB->play_mode = play_mode;


      /* If the drive is not currently playing, then dont issue play command */

      if (pFilter_workspace->input_parm_0 == 0)
        rc = NOTIFY_CDM;

   }
   return(rc);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_StartStopUnit
 *
 * DESCRIPTION   = Filter SCSI-2 StartStopUnit CDB
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_StartStopUnit (pIORB)

PIORB_CDB pIORB;
{

   USHORT i, rc;
   struct TOSH_CDB_Eject    FAR *pCDB1;
   struct CDB_StartStopUnit FAR *pCDB2;

   pCDB1 = (struct TOSH_CDB_Eject    FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_StartStopUnit FAR *) pCDB1;

   /* If Eject requested, then setup Eject command */

   if ( (pCDB2->LoEj) && !(pCDB2->start) )
   {
      pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_Eject);

      pCDB1->OpCode = TOSH_EJECT;
      pCDB1->reserved_1 = 0;

      for (i = 2; i < 10; i++)
        *( (PBYTE) pCDB1+i) = 0;

      rc = CALL_ADD_AND_RET;
   }
   else
      rc = NOTIFY_CDM_WITH_ERROR;

   return(rc);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_ReadSubChannel
 *
 * DESCRIPTION   = Filter SCSI-2 Read Subchannel Data
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_ReadSubChannel (pIORB)

PIORB_CDB pIORB;
{

   USHORT i, rc;
   struct TOSH_CDB_ReadQData FAR *pCDB1;
   struct CDB_ReadSubChannel FAR *pCDB2;
   PIORB_FLTWORK pFilter_workspace;

   pCDB1 = (struct TOSH_CDB_ReadQData FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_ReadSubChannel FAR *) pCDB1;

   if (pCDB2->data_format == RSC_CURRENT_POSITION)
   {
      pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_ReadQData);
      pIORB->apt.pSGList->XferBufLen = sizeof(struct TOSH_SubQ_Channel_Data);

      pCDB1->OpCode = TOSH_READ_Q_DATA;
      pCDB1->alloc_length = sizeof(struct TOSH_SubQ_Channel_Data);

      for (i = 2; i < 10; i++)
        *( (PBYTE) pCDB1+i) = 0;

      pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
      pFilter_workspace->completion_address = NotifyReadSubChannel;

      rc = CALL_ADD_AND_NOTIFY_FILTER;
   }
   else
      rc = NOTIFY_CDM_WITH_ERROR;

   return(rc);
}


/****************************************************************************
 *
 * FUNCTION NAME = NotifyReadSubChannel
 *
 * DESCRIPTION   = Notification processing for ReadSubChannel
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT NotifyReadSubChannel (pIORB)

PIORB_CDB pIORB;
{
   UCHAR status, control, track_number, index;

   struct TOSH_SubQ_Channel_Data FAR *pCDBData1;
   struct SubChannel_Position    FAR *pCDBData2;

   pCDBData1 = (struct TOSH_SubQ_Channel_Data FAR *) &pIORB->CDB_data;
   pCDBData2 = (struct SubChannel_Position FAR *) pCDBData1;

   /* Convert the play status byte to SCSI-2 */

   switch(pCDBData1->playback_status)
   {
      case  TOSH_PLAY_IN_PROGRESS:
        status = AS_PLAY_IN_PROGRESS;
        break;

      case  TOSH_PLAY_STILL:
        status = AS_PLAY_PAUSED;
        break;

      case  TOSH_PLAY_PAUSED:
        status = AS_PLAY_PAUSED;
        break;

      case  TOSH_PLAY_COMPLETE:
        status = AS_PLAY_COMPLETE;
        break;

      default:
        status = AS_NO_STATUS;
        break;
   }

   control = pCDBData1->control;
   track_number = BCDtoBinary(pCDBData1->track_number);
   index = BCDtoBinary(pCDBData1->point);

   pCDBData2->rel_address.redbook.frame = BCDtoBinary(pCDBData1->frame);
   pCDBData2->rel_address.redbook.sec   = BCDtoBinary(pCDBData1->sec);
   pCDBData2->rel_address.redbook.min   = BCDtoBinary(pCDBData1->min);
   pCDBData2->rel_address.redbook.zero  = 0;

   pCDBData2->abs_address.redbook.frame = BCDtoBinary(pCDBData1->aframe);
   pCDBData2->abs_address.redbook.sec   = BCDtoBinary(pCDBData1->asec);
   pCDBData2->abs_address.redbook.min   = BCDtoBinary(pCDBData1->amin);
   pCDBData2->abs_address.redbook.zero  = 0;


   pCDBData2->sub_channel_hdr.reserved_1 = 0;
   pCDBData2->sub_channel_hdr.audio_status = status;
   pCDBData2->sub_channel_hdr.data_length.usbytes.byte_0 = 0;
   pCDBData2->sub_channel_hdr.data_length.usbytes.byte_1 =
                            sizeof(struct SubChannel_Position) -
                            sizeof(struct SubChannel_Hdr);

   pCDBData2->data_format_code = 1;
   pCDBData2->control = control;
   pCDBData2->ADR = ADR_CURRENT_POSITION;
   pCDBData2->track_number = track_number;
   pCDBData2->index_number = index;

   return(NOTIFY_CDM);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_ReadTOC
 *
 * DESCRIPTION   = Filter SCSI-2 Read TOC command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_ReadTOC (pIORB)

PIORB_CDB pIORB;
{
   USHORT i;
   struct TOSH_CDB_ReadDiskInfo FAR *pCDB1;
   struct CDB_ReadTOC FAR *pCDB2;
   struct ReadTOC_Data FAR *pCDBData2;
   PIORB_FLTWORK pFilter_workspace;

   pCDB1 = (struct TOSH_CDB_ReadDiskInfo FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_ReadTOC FAR *) pCDB1;
   pCDBData2 = (struct ReadTOC_Data FAR *) pIORB->CDB_data;

   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_ReadDiskInfo);
   pIORB->apt.pSGList->XferBufLen = 4;

   pCDB1->OpCode = TOSH_READ_DISK_INFO;

   pCDBData2->toc_descriptor[0].track_num = pCDB2->starting_track;

   /* See if getting TOC info for lead out track */

   if (pCDB2->starting_track == 0xAA)
   {
      pCDB1->type = TOSH_LEADOUT_INFO;
      pCDB1->track_number = 0;
   }
   else
   {
      /* Getting info for a specific track */

      pCDB1->type = TOSH_TRACK_INFO;
      pCDB1->track_number = BinarytoBCD(pCDB2->starting_track);
   }

   pCDB1->reserved_1 = 0;

   for (i = 3; i < 10; i++)
     *( (PBYTE) pCDB1+i) = 0;

   pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
   pFilter_workspace->completion_address = NotifyReadTOC1;

   return(CALL_ADD_AND_NOTIFY_FILTER);
}


/****************************************************************************
 *
 * FUNCTION NAME = NotifyReadTOC1
 *
 * DESCRIPTION   = Notification processing for Read TOC command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT  NotifyReadTOC1 (pIORB)

PIORB_CDB pIORB;

{
   union TOSH_ReadDiskInfo_Data FAR *pCDBData1;
   struct ReadTOC_Data FAR *pCDBData2;
   struct TOSH_CDB_ReadDiskInfo FAR *pCDB1;
   PIORB_FLTWORK pFilter_workspace;

   pCDBData1 = (union TOSH_ReadDiskInfo_Data FAR *) pIORB->CDB_data;
   pCDBData2 = (struct ReadTOC_Data FAR *) pCDBData1;
   pCDB1 = (struct TOSH_CDB_ReadDiskInfo FAR *) &(pIORB->CDB);

   pCDBData2->toc_descriptor[0].abs_address.redbook.min   =
                                        BCDtoBinary(pCDBData1->track.amin);
   pCDBData2->toc_descriptor[0].abs_address.redbook.sec =
                                        BCDtoBinary(pCDBData1->track.asec);
   pCDBData2->toc_descriptor[0].abs_address.redbook.frame =
                                        BCDtoBinary(pCDBData1->track.aframe);
   pCDBData2->toc_descriptor[0].abs_address.redbook.zero = 0;

   pCDBData2->toc_descriptor[0].ADR = ADR_CURRENT_POSITION;

/*
** if (pCDBData1->track.control == TOSH_AUDIO_TRACK)
**    pCDBData2->toc_descriptor[0].control = 0;
** else
**    pCDBData2->toc_descriptor[0].control = QCTL_DATA_TRACK;
*/
      pCDBData2->toc_descriptor[0].control = pCDBData1->track.control;


   /* Issue Read Disk Info again to get the min-max track values */

   pCDB1->type = TOSH_MINMAX_INFO;

   pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
   pFilter_workspace->completion_address = NotifyReadTOC2;

   return(CALL_ADD_AND_NOTIFY_FILTER);
}


/****************************************************************************
 *
 * FUNCTION NAME = NotifyReadTOC2
 *
 * DESCRIPTION   = Notification processing for Read TOC command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT NotifyReadTOC2 (pIORB)

PIORB_CDB pIORB;
{
   union TOSH_ReadDiskInfo_Data FAR *pCDBData1;
   struct ReadTOC_Data FAR *pCDBData2;

   pCDBData1 = (union TOSH_ReadDiskInfo_Data FAR *) pIORB->CDB_data;
   pCDBData2 = (struct ReadTOC_Data FAR *) pIORB->CDB_data;

   pCDBData2->toc_hdr.first_track=BCDtoBinary(pCDBData1->track_number.minimum);
   pCDBData2->toc_hdr.last_track =BCDtoBinary(pCDBData1->track_number.maximum);

   pCDBData2->toc_hdr.toc_datalength.usbytes.byte_0 = 0;
   pCDBData2->toc_hdr.toc_datalength.usbytes.byte_1 =
                                sizeof(struct ReadTOC_Data) - 2;
   pCDBData2->toc_descriptor[0].reserved_1 = 0;
   pCDBData2->toc_descriptor[0].reserved_3 = 0;

   return (NOTIFY_CDM);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_ReadHeader
 *
 * DESCRIPTION   = Filter SCSI-2 Read Header command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_ReadHeader (pIORB)

PIORB_CDB pIORB;

{
   USHORT   i;

   struct CDB_ReadHeader   FAR *pCDB1;
   struct ReadHeader_Data  FAR *pCDBData1;

   pCDB1 = (struct CDB_ReadHeader FAR *) pIORB->apt.pControllerCmd;
   pCDBData1 = (struct ReadHeader_Data FAR *) pIORB->CDB_data;

   pCDBData1->cdrom_data_mode = 1;

   for (i=1;i<8;i++)
      *((PBYTE) pCDB1+i) = 0;

   return NOTIFY_CDM;

}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_PlayAudio_MSF
 *
 * DESCRIPTION   = Filter SCSI-2 Play Audio command
 *                 Converts SCSI-2 Play Audio MSF command to a Toshiba Audio
 *                 Track Search command followed by a Play Audio command.
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_PlayAudio_MSF (pIORB)

PIORB_CDB pIORB;

{
   struct TOSH_CDB_AudioTrackSearch FAR *pCDB1;
   struct CDB_PlayAudio_MSF FAR *pCDB2;

   PIORB_FLTWORK pFilter_workspace;
   NPUNITCB pUnitCB;

   pCDB1 = (struct TOSH_CDB_AudioTrackSearch FAR *) pIORB->apt.pControllerCmd;
   pCDB2 = (struct CDB_PlayAudio_MSF FAR *) pCDB1;

   pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
   pUnitCB = pFilter_workspace->pUnitCB;


   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_AudioTrackSearch);

   pCDB1->OpCode = TOSH_AUDIO_TRACK_SEARCH;

   pCDB1->play = 0;

   pCDB1->search_address.msf0.min   = BinarytoBCD(pCDB2->starting_M);
   pCDB1->search_address.msf0.sec   = BinarytoBCD(pCDB2->starting_S);
   pCDB1->search_address.msf0.frame = BinarytoBCD(pCDB2->starting_F);
   pCDB1->search_address.msf0.zero  = 0;

   pFilter_workspace->end_play_address.msf0.min = BinarytoBCD(pCDB2->ending_M);
   pFilter_workspace->end_play_address.msf0.sec = BinarytoBCD(pCDB2->ending_S);
   pFilter_workspace->end_play_address.msf0.frame=BinarytoBCD(pCDB2->ending_F);
   pFilter_workspace->end_play_address.msf0.zero = 0;

   pCDB1->reserved_1 = 0;
   pCDB1->reserved_2 = 0;
   pCDB1->reserved_3 = 0;
   pCDB1->reserved_4 = 0;

   pCDB1->control = CONTROL_TYPE_ATIME;

   pFilter_workspace->completion_address = NotifyPlayAudio;

   return (CALL_ADD_AND_NOTIFY_FILTER);
}


/****************************************************************************
 *
 * FUNCTION NAME = NotifyPlayAudio
 *
 * DESCRIPTION   = Notification processing for Play Audio Command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT NotifyPlayAudio (pIORB)

PIORB_CDB pIORB;

{
   struct TOSH_CDB_PlayAudio FAR *pCDB1;
   PIORB_FLTWORK pFilter_workspace;
   NPUNITCB pUnitCB;

   pCDB1 = (struct TOSH_CDB_PlayAudio FAR *) pIORB->apt.pControllerCmd;
   pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
   pUnitCB = pFilter_workspace->pUnitCB;

   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_PlayAudio);

   pCDB1->OpCode = TOSH_PLAY_AUDIO;

   pCDB1->play_mode = pUnitCB->play_mode;
   pCDB1->reserved_1 = 0;

   pCDB1->completion_address = pFilter_workspace->end_play_address;

   pCDB1->control = CONTROL_TYPE_ATIME;

   return(CALL_ADD_AND_NOTIFY_CDM);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_Pause_Resume
 *
 * DESCRIPTION   = Filter SCSI-2 PauseResume CDB
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_Pause_Resume (pIORB)

PIORB_CDB pIORB;
{

   USHORT i;
   struct TOSH_CDB_Still  FAR *pCDB1;
   struct CDB_PauseResume FAR *pCDB2;
   struct TOSH_CDB_AudioTrackSearch FAR *pCDB1a;
   PIORB_FLTWORK pFilter_workspace;
   NPUNITCB pUnitCB;

   pCDB1 =  (struct TOSH_CDB_Still  FAR *) &(pIORB->CDB);
   pCDB2 =  (struct CDB_PauseResume FAR *) &(pIORB->CDB);
   pCDB1a = (struct TOSH_CDB_AudioTrackSearch FAR *) &(pIORB->CDB);


   /* If Resume requested, then issue Audio Search followed by Play command */

   if (pCDB2->resume)
   {
      pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_AudioTrackSearch);

      pCDB1a->OpCode = TOSH_AUDIO_TRACK_SEARCH;

      pCDB1a->play = 0;

      pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
      pUnitCB = pFilter_workspace->pUnitCB;

/*    pCDB1a->search_address.dword = pUnitCB->last_start_location.dword; */

      pCDB1a->reserved_1 = 0;
      pCDB1a->reserved_2 = 0;
      pCDB1a->reserved_3 = 0;
      pCDB1a->reserved_4 = 0;

      pCDB1a->control = CONTROL_TYPE_ATIME;

      pFilter_workspace->completion_address = NotifyResume;

      return(CALL_ADD_AND_NOTIFY_FILTER);
   }
   else
   {
      /* Convert SCSI-2 Pause to Toshiba Still command */

      pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_Still);

      pCDB1->OpCode = TOSH_STILL;

      for (i = 2; i < 10; i++)
        *( (PBYTE) pCDB1+i) = 0;

      return(CALL_ADD_AND_RET);
   }
}


/****************************************************************************
 *
 * FUNCTION NAME = NotifyResume
 *
 * DESCRIPTION   = Notification processing for Resume command
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT NotifyResume (pIORB)

PIORB_CDB pIORB;

{
   struct TOSH_CDB_PlayAudio FAR *pCDB1;
   PIORB_FLTWORK pFilter_workspace;
   NPUNITCB pUnitCB;

   pCDB1 = (struct TOSH_CDB_PlayAudio FAR *) pIORB->apt.pControllerCmd;

   pIORB->apt.ControllerCmdLen = sizeof(struct TOSH_CDB_PlayAudio);

   pCDB1->OpCode = TOSH_PLAY_AUDIO;

   pCDB1->play_mode = TOSH_PLAY_PREVIOUS_MODE;
   pCDB1->reserved_1 = 0;

   pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
   pUnitCB = pFilter_workspace->pUnitCB;

/* pCDB1->completion_address.dword = pUnitCB->last_end_location.dword;  */

   return(CALL_ADD_AND_NOTIFY_CDM);
}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_PreventAllowRemoval
 *
 * DESCRIPTION   =
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_PreventAllowRemoval (pIORB)

PIORB_CDB pIORB;
{

   return(CALL_ADD_AND_RET);

}


/****************************************************************************
 *
 * FUNCTION NAME = Filter_Read_6
 *
 * DESCRIPTION   = Filter Read (6)
 *
 * INPUT         = pIORB           - pointer to IORB
 *
 * OUTPUT        =
 *
 * RETURN-NORMAL =
 * RETURN-ERROR  =
 *
 ****************************************************************************/

USHORT Filter_Read_6 (pIORB)

PIORB_CDB pIORB;
{

   return(CALL_ADD_AND_RET);

}
