home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cdrom.zip / DDK / BASE / SRC / DEV / DASD / CDROM / OS2CDROM / cdioc80.c < prev    next >
C/C++ Source or Header  |  1996-06-18  |  46KB  |  1,441 lines

  1. /**************************************************************************
  2.  *
  3.  * SOURCE FILE NAME = CDIOC80.C
  4.  *
  5.  * DESCRIPTIVE NAME = IOCTL handling routines for OS/2 CD-ROM Device Mgr
  6.  *
  7.  * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
  8.  *             LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
  9.  *             REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
  10.  *             RESTRICTED MATERIALS OF IBM
  11.  *             IBM CONFIDENTIAL
  12.  *
  13.  * VERSION = V2.0
  14.  *
  15.  * DATE
  16.  *
  17.  * DESCRIPTION
  18.  *
  19.  *
  20.  * FUNCTIONS
  21.  *
  22.  * ENTRY POINTS:
  23.  *
  24.  * DEPENDENCIES:
  25.  *
  26.  * NOTES
  27.  *
  28.  *
  29.  * STRUCTURES
  30.  *
  31.  * EXTERNAL REFERENCES
  32.  *
  33.  * EXTERNAL FUNCTIONS
  34.  *
  35.  * CHANGE ACTIVITY =
  36.  *  DATE      FLAG        APAR   CHANGE DESCRIPTION
  37.  *  --------  ----------  -----  --------------------------------------
  38.  *  09/08/95  @V135221           Sam Detweiler - CD-ROM changer support
  39.  *
  40.  ****************************************************************************/
  41.  
  42. #include "cdh.h"
  43. #include "dskioctl.h"
  44.  
  45. USHORT GetRawBlockSize (NPUNITCB);
  46.  
  47.  
  48. /****************************************************************************
  49.  *
  50.  * FUNCTION NAME = CD_ResetDrive
  51.  *
  52.  * DESCRIPTION   = Issue a reset drive command to the device.
  53.  *
  54.  *                 USHORT CD_ResetDrive (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  55.  *
  56.  * INPUT         = pRP              - Request Packet
  57.  *                 pUnitCB          - Pointer to UnitCB
  58.  *
  59.  * OUTPUT        = USHORT           - Packet Status word
  60.  *
  61.  * RETURN-NORMAL =
  62.  * RETURN-ERROR  =
  63.  *
  64.  ****************************************************************************/
  65.  
  66. USHORT CD_ResetDrive (pRP, pUnitCB)
  67.  
  68. PRP_GENIOCTL pRP;
  69. NPUNITCB     pUnitCB;
  70.  
  71. {
  72.    USHORT      rc, i;
  73.    BOOL        playing;
  74.    NPIORB_CDB  pIORB;
  75.  
  76.    struct    Status *audio_status;
  77.    struct    Audio  *audio;
  78.  
  79.    /*
  80.    ** If device is playing, return DEVICE_IN_USE error
  81.    */
  82.    rc = GetPlayStatus (pUnitCB, &playing);
  83.  
  84.    if ( (rc == STDON) && playing)
  85.       return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
  86.  
  87.    /*
  88.    ** First, abort any oustanding commands on the device
  89.    */
  90.    BuildIORB_DeviceControl (pUnitCB, IOCM_ABORT, (NPIORB FAR *) &pIORB);
  91.  
  92.    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  93.  
  94.    FreeIORB (pUnitCB, pIORB);
  95.  
  96.    /*
  97.    ** Reset the device
  98.    */
  99. /*
  100. ** BuildIORB_DeviceControl (pUnitCB, IOCM_RESET, (NPIORB FAR *) &pIORB);
  101. **
  102. ** rc = SubmitIORB_Wait (pUnitCB, pIORB);
  103. **
  104. ** FreeIORB (pUnitCB, pIORB);
  105. */
  106.    /*
  107.    ** Recover from the reset. First clear the check condition from the
  108.    ** reset.  Then delay long enough to recover from the not ready to
  109.    ** ready transition.
  110.    */
  111.    ClearCheckCondition(pUnitCB);
  112.  
  113.    for (i = 1; i <= 10; i++)
  114.    {
  115.        DevHelp_ProcBlock( (ULONG) ppDataSeg, (ULONG) 1000, 0);
  116.  
  117.        BuildCDB_TestUnitReady (pUnitCB, (NPIORB_CDB FAR *) &pIORB);
  118.  
  119.        rc = SubmitIORB_Wait (pUnitCB, pIORB);
  120.  
  121.        FreeIORB (pUnitCB, pIORB);
  122.  
  123.        if (rc == STDON)
  124.           break;
  125.    }
  126.  
  127.    /*
  128.    ** Issue SCSI Pause Command. Ignore the RC
  129.    */
  130. /*
  131. ** if (pUnitCB->Flags & UCF_AUDIO_SUPPORTED)
  132. ** {
  133. **    BuildCDB_PauseResume (pUnitCB, CDBF_PAUSE, (NPIORB_CDB FAR *) &pIORB);
  134. **
  135. **    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  136. **
  137. **    FreeIORB (pUnitCB, pIORB);
  138. ** }
  139. */
  140.    /*
  141.    ** Update Audio status fields in UnitCB
  142.    */
  143.    audio = &pUnitCB->DeviceInfo.Audio;
  144.    audio_status = &audio->status;
  145.  
  146.    pUnitCB->DeviceInfo.Audio.capabilities &= ~DCAPS_DOOR_LOCKED;
  147.    pUnitCB->Flags &= ~UCF_UNCERTAIN_MEDIA;
  148.  
  149.    audio_status->paused = FALSE;
  150.    audio_status->last_start_location.min   = 0;
  151.    audio_status->last_start_location.sec   = 0;
  152.    audio_status->last_start_location.frame = 0;
  153.    audio_status->last_end_location.min     = 0;
  154.    audio_status->last_end_location.sec     = 0;
  155.    audio_status->last_end_location.frame   = 0;
  156.  
  157.    return(STDON);
  158. }
  159.  
  160.  
  161. /****************************************************************************
  162.  *
  163.  * FUNCTION NAME = CD_EjectDisk
  164.  *
  165.  * DESCRIPTION   = Issue an eject disk command to the device.
  166.  *
  167.  *                 USHORT CD_EjectDisk (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  168.  *
  169.  * INPUT         = pRP              - Request Packet
  170.  *                 pUnitCB          - Pointer to UnitCB
  171.  *
  172.  * OUTPUT        = USHORT           - Packet Status word
  173.  *
  174.  * RETURN-NORMAL =
  175.  * RETURN-ERROR  =
  176.  *
  177.  ****************************************************************************/
  178.  
  179. USHORT CD_EjectDisk (pRP, pUnitCB)
  180.  
  181. PRP_GENIOCTL pRP;
  182. NPUNITCB     pUnitCB;
  183.  
  184. {
  185.    USHORT     rc;
  186.    BOOL       playing;
  187.    NPIORB_CDB pIORB;
  188.  
  189.    /*
  190.    ** If device is playing, return DEVICE_IN_USE error
  191.    */
  192.    rc = GetPlayStatus (pUnitCB, &playing);
  193.  
  194.    if ( (rc == STDON) && playing)
  195.       return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
  196.  
  197.    /*
  198.    ** Issue SCSI Start-Stop Unit command to eject the media
  199.    */
  200.    BuildCDB_StartStopUnit (pUnitCB, CDBF_EJECT, (NPIORB_CDB FAR *) &pIORB);
  201.  
  202.    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  203.  
  204.    FreeIORB (pUnitCB, pIORB);
  205.  
  206.    if (rc == STDON + STERR + ERROR_I24_NOT_READY)
  207.       rc = STDON;
  208.  
  209.    if(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CARTRIDGE_CHANGER)         //SD@135221
  210.      {                                                                          //SD@135221
  211.      if(pUnitCB->pParentUnitCB)                                                 //SD@135221
  212.        {                                                                        //SD@135221
  213.        pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current=0;                      //SD@135221
  214.        } /* endif */                                                            //SD@135221
  215.      } /* endif */                                                              //SD@135221
  216.  
  217.    return(rc);
  218. }
  219.  
  220.  
  221. /****************************************************************************
  222.  *
  223.  * FUNCTION NAME = CD_CloseTray
  224.  *
  225.  * DESCRIPTION   = Issue a close tray command to the device.
  226.  *
  227.  *                 USHORT CD_CloseTray (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  228.  *
  229.  * INPUT         = pRP              - Request Packet
  230.  *                 pUnitCB          - Pointer to UnitCB
  231.  *
  232.  * OUTPUT        = USHORT           - Packet Status word
  233.  *
  234.  * RETURN-NORMAL =
  235.  * RETURN-ERROR  =
  236.  *
  237.  ****************************************************************************/
  238.  
  239. USHORT CD_CloseTray (pRP, pUnitCB)
  240.  
  241. PRP_GENIOCTL pRP;
  242. NPUNITCB     pUnitCB;
  243.  
  244. {
  245.    USHORT     rc;
  246.    BOOL       playing;
  247.    NPIORB_CDB pIORB;
  248.  
  249.    /*
  250.    ** If device is playing, return DEVICE_IN_USE error
  251.    */
  252.    rc = GetPlayStatus (pUnitCB, &playing);
  253.  
  254.    if ( (rc == STDON) && playing)
  255.       return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
  256.  
  257.    /*
  258.    ** Issue SCSI Start-Stop Unit command to close the tray
  259.    */
  260.    BuildCDB_StartStopUnit (pUnitCB, CDBF_CLOSE_TRAY, (NPIORB_CDB FAR *) &pIORB);
  261.  
  262.    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  263.  
  264.    FreeIORB (pUnitCB, pIORB);
  265.  
  266.    if (rc == STDON + STERR + ERROR_I24_NOT_READY)
  267.       rc = STDON;
  268.  
  269.    return(rc);
  270. }
  271.  
  272.  
  273. /****************************************************************************
  274.  *
  275.  * FUNCTION NAME = CD_LockUnLock
  276.  *
  277.  * DESCRIPTION   = Issue a lock or unlock drive door command to the device.
  278.  *
  279.  *                 USHORT CD_LockUnLock (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  280.  *
  281.  * INPUT         = pRP              - Request Packet
  282.  *                 pUnitCB          - Pointer to UnitCB
  283.  *
  284.  * OUTPUT        = USHORT           - Packet Status word
  285.  *
  286.  * RETURN-NORMAL =
  287.  * RETURN-ERROR  =
  288.  *
  289.  ****************************************************************************/
  290.  
  291. USHORT CD_LockUnLock (pRP, pUnitCB)
  292.  
  293. PRP_GENIOCTL pRP;
  294. NPUNITCB     pUnitCB;
  295.  
  296. {
  297.    NPIORB_CDB pIORB;
  298.    USHORT     rc, lock_flag;
  299.    struct     Audio *audio;
  300.  
  301.  
  302.    audio = &pUnitCB->DeviceInfo.Audio;
  303.  
  304.    if (pRP->Category == 8)
  305.       lock_flag = ((PDDI_DsktRemovMediaCtl_param)pRP->ParmPacket)->Command;
  306.    else
  307.       lock_flag = ((struct LockUnlock FAR *)pRP->ParmPacket)->lock_flag;
  308.  
  309.    if (lock_flag > CDBF_LOCK_DOOR)
  310.       return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  311.  
  312.    /*
  313.    ** Issue SCSI PreventAllowRemoval command to lock/unlock the media
  314.    */
  315.    BuildCDB_PreventAllowRemoval (pUnitCB, lock_flag, (NPIORB_CDB FAR *) &pIORB);
  316.  
  317.    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  318.  
  319.    FreeIORB (pUnitCB, pIORB);
  320.  
  321.    if (rc == STDON)
  322.    {
  323.       if (lock_flag)
  324.          audio->capabilities |= DCAPS_DOOR_LOCKED;
  325.       else
  326.          audio->capabilities &= ~DCAPS_DOOR_LOCKED;
  327.  
  328.    }
  329.  
  330.    return(rc);
  331.  
  332. }
  333.  
  334. /****************************************************************************    //SD@135221
  335.  *                                                                               //SD@135221
  336.  * FUNCTION NAME = CD_SetActiveTray                                              //SD@135221
  337.  *                                                                               //SD@135221
  338.  * DESCRIPTION   = Select the active tray on changer devices                     //SD@135221
  339.  *                                                                               //SD@135221
  340.  *                 USHORT CD_SetActiveTray ( RP_GENIOCTL pRP, NPUNITCB pUnitCB)  //SD@135221
  341.  *                                                                               //SD@135221
  342.  * INPUT         = pRP              - Request Packet                             //SD@135221
  343.  *                 pUnitCB          - Pointer to UnitCB                          //SD@135221
  344.  *                                                                               //SD@135221
  345.  * OUTPUT        = USHORT           - Packet Status word                         //SD@135221
  346.  *                                                                               //SD@135221
  347.  * RETURN-NORMAL =                                                               //SD@135221
  348.  * RETURN-ERROR  =                                                               //SD@135221
  349.  *                                                                               //SD@135221
  350.  ****************************************************************************/   //SD@135221
  351.                                                                                  //SD@135221
  352. USHORT CD_SetActiveTray (pRP, pUnitCB)                                           //SD@135221
  353.                                                                                  //SD@135221
  354. PRP_GENIOCTL pRP;                                                                //SD@135221
  355. NPUNITCB     pUnitCB;                                                            //SD@135221
  356.                                                                                  //SD@135221
  357. {                                                                                //SD@135221
  358.    NPIORB_CDB pIORB;                                                             //SD@135221
  359.    USHORT     rc;                                                                //SD@135221
  360.                                                                                  //SD@135221
  361.    struct SetTray_Parm FAR *pTrayParm;                                           //SD@135221
  362.                                                                                  //SD@135221
  363.    if(pUnitCB->DeviceInfo.Audio.capabilities &                                   //SD@135221
  364.      (DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER))                        //SD@135221
  365.      {                                                                           //SD@135221
  366.      if(pUnitCB->pParentUnitCB->DeviceInfo.Parentplaying==TRUE)                  //SD@135221
  367.        {                                                                         //SD@135221
  368.        rc=STDON + STERR + ERROR_I24_DEVICE_IN_USE;                               //SD@135221
  369.        } /* endif */                                                             //SD@135221
  370.      else                                                                        //SD@135221
  371.        {                                                                         //SD@135221
  372.        pTrayParm=(struct SetTray_Parm FAR *)pRP->DataPacket;                     //SD@135221
  373.        if(pTrayParm->Newtray<=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Maximum)  //SD@135221
  374.          {                                                                       //SD@135221
  375.          if(pTrayParm->Newtray!=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current)//SD@135221
  376.            {                                                                     //SD@135221
  377.            rc=MakeSlotActive(pUnitCB,pTrayParm->Newtray);                        //SD@135221
  378.            } /* endif */                                                         //SD@135221
  379.          else                                                                    //SD@135221
  380.            {                                                                     //SD@135221
  381.            rc=STDON;                                                             //SD@135221
  382.            } /* endelse */                                                       //SD@135221
  383.          } /* endif */                                                           //SD@135221
  384.        else                                                                      //SD@135221
  385.          {                                                                       //SD@135221
  386.          rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER;                         //SD@135221
  387.          } /* endelse */                                                         //SD@135221
  388.        }                                                                         //SD@135221
  389.      } /* endif */                                                               //SD@135221
  390.    else                                                                          //SD@135221
  391.      {                                                                           //SD@135221
  392.      rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER;                             //SD@135221
  393.      } /* endelse */                                                             //SD@135221
  394.                                                                                  //SD@135221
  395.    return(rc);                                                                   //SD@135221
  396.                                                                                  //SD@135221
  397. }
  398.  
  399.  
  400. /****************************************************************************
  401.  *
  402.  * FUNCTION NAME = CD_Seek
  403.  *
  404.  * DESCRIPTION   = Issue a seek command to the device.
  405.  *
  406.  *                 USHORT CD_Seek (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  407.  *
  408.  * INPUT         = pRP              - Request Packet
  409.  *                 pUnitCB          - Pointer to UnitCB
  410.  *
  411.  * OUTPUT        = USHORT           - Packet Status word
  412.  *
  413.  * RETURN-NORMAL =
  414.  * RETURN-ERROR  =
  415.  *
  416.  ****************************************************************************/
  417.  
  418. USHORT CD_Seek(pRP,pUnitCB)
  419. PRP_GENIOCTL pRP;
  420. NPUNITCB     pUnitCB;
  421.  
  422. {
  423.    USHORT rc;
  424.    BOOL   playing;
  425.    NPIORB_CDB pIORB;
  426.    struct Seek FAR *pParmPacket;
  427.    union  ULONGB ul_LBA;
  428.  
  429.    pParmPacket = (struct Seek FAR *) pRP->ParmPacket;
  430.  
  431.    if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
  432.       return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
  433.  
  434.    ul_LBA.dword = pParmPacket->start_sector;
  435.  
  436.    switch(pParmPacket->address_mode)
  437.    {
  438.       case CDROM_HSG_MODE:
  439.          break;
  440.       case CDROM_REDBOOK_MODE:
  441.          ul_LBA.dword = RedBookToHSG (ul_LBA.dword);
  442.          break;
  443.       default:
  444.          return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  445.    }
  446.  
  447.    rc = GetPlayStatus (pUnitCB, &playing);
  448.  
  449.    if ( (rc == STDON) && playing)
  450.       return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
  451.  
  452.    /*
  453.    ** Issue the seek.  If there's a seek error and the density code is not
  454.    ** for CD-DA, the issue the Mode Select to change the density to CD-DA
  455.    ** and retry the seek operation.
  456.    */
  457.    if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
  458.       BuildCDB_Seek_10(pUnitCB, (ULONG)ul_LBA.dword, (NPIORB_CDB FAR *)&pIORB);
  459.    else
  460.       BuildCDB_Seek_6(pUnitCB, (ULONG)ul_LBA.dword, (NPIORB_CDB FAR *)&pIORB);
  461.  
  462.    rc = SubmitIORB_Wait (pUnitCB, pIORB);
  463.  
  464.    FreeIORB (pUnitCB, pIORB);
  465.  
  466.    if ( (rc == STDON + STERR + ERROR_I24_SEEK) &&
  467.         ( (pUnitCB->DeviceInfo.product_id_code == TOSHIBA_3301) ||
  468.           (pUnitCB->DeviceInfo.product_id_code == TOSHIBA_3401) ) &&
  469.         (pUnitCB->DeviceInfo.current_density != CD_DENSITY_CDDA) )
  470.    {
  471.  
  472.       BuildCDB_ModeSelect (pUnitCB, CD_DENSITY_CDDA, 2352,
  473.                                                   (NPIORB_CDB FAR *) &pIORB);
  474.  
  475.       rc = SubmitIORB_Wait (pUnitCB, pIORB);
  476.  
  477.       if (rc == STDON)
  478.       {
  479.          pUnitCB->DeviceInfo.current_density = CD_DENSITY_CDDA;
  480.          pUnitCB->DeviceInfo.current_block_size = 2352;
  481.       }
  482.  
  483.       FreeIORB (pUnitCB, pIORB);
  484.  
  485.       if (rc == STDON)
  486.       {
  487.          BuildCDB_Seek_6 (pUnitCB,(ULONG) ul_LBA.dword,
  488.                                                   (NPIORB_CDB FAR *) &pIORB);
  489.          rc = SubmitIORB_Wait (pUnitCB, pIORB);
  490.  
  491.          FreeIORB (pUnitCB, pIORB);
  492.       }
  493.    }
  494.    return(rc);
  495. }
  496.  
  497. /****************************************************************************
  498.  *
  499.  * FUNCTION NAME = CD_WriteLong
  500.  *
  501.  * DESCRIPTION   = Issue a write long command to the device.
  502.  *
  503.  *                 USHORT CD_WriteLong (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  504.  *
  505.  * INPUT         = pRP              - Request Packet
  506.  *                 pUnitCB          - Pointer to UnitCB
  507.  *
  508.  * OUTPUT        = USHORT           - Packet Status word
  509.  *
  510.  * RETURN-NORMAL =
  511.  * RETURN-ERROR  =
  512.  *
  513.  ****************************************************************************/
  514.  
  515. USHORT CD_WriteLong (pRP, pUnitCB)
  516.  
  517. PRP_GENIOCTL pRP;
  518. NPUNITCB     pUnitCB;
  519.  
  520. {
  521.    return (STDON + STERR + ERROR_I24_WRITE_FAULT);
  522. }
  523.  
  524.  
  525. /****************************************************************************
  526.  *
  527.  * FUNCTION NAME = CD_WriteVLong
  528.  *
  529.  * DESCRIPTION   = Issue a write verify long command to the device.
  530.  *
  531.  *                 USHORT CD_WriteVLong (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  532.  *
  533.  * INPUT         = pRP              - Request Packet
  534.  *                 pUnitCB          - Pointer to UnitCB
  535.  *
  536.  * OUTPUT        = USHORT           - Packet Status word
  537.  *
  538.  * RETURN-NORMAL =
  539.  * RETURN-ERROR  =
  540.  *
  541.  ****************************************************************************/
  542.  
  543. USHORT CD_WriteVLong (pRP, pUnitCB)
  544.  
  545. PRP_GENIOCTL pRP;
  546. NPUNITCB     pUnitCB;
  547.  
  548. {
  549.    return (STDON + STERR + ERROR_I24_WRITE_FAULT);
  550. }
  551.  
  552. /****************************************************************************
  553.  *
  554.  * FUNCTION NAME = CD_DeviceStatus
  555.  *
  556.  * DESCRIPTION   = Return device status.
  557.  *
  558.  *                 USHORT CD_DeviceStatus (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  559.  *
  560.  * INPUT         = pRP              - Request Packet
  561.  *                 pUnitCB          - Pointer to UnitCB
  562.  *
  563.  * OUTPUT        = USHORT           - Packet Status word
  564.  *
  565.  * RETURN-NORMAL =
  566.  * RETURN-ERROR  =
  567.  *
  568.  ****************************************************************************/
  569.  
  570. USHORT CD_DeviceStatus (pRP, pUnitCB)
  571.  
  572. PRP_GENIOCTL pRP;
  573. NPUNITCB     pUnitCB;
  574.  
  575. {
  576.    USHORT rc;
  577.    ULONG  device_status;
  578.    BOOL   playing;
  579.  
  580.    device_status = DSF_DEFAULT;
  581.  
  582.    if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_DOOR_LOCKED)
  583.       device_status &= ~DSF_DOOR_UNLOCKED;
  584.  
  585.    if ( (rc = GetPlayStatus (pUnitCB, &playing)) & STERR)
  586.       playing = 0;
  587.  
  588.    if (playing)
  589.       device_status |= DSF_PLAYING;
  590.  
  591.    rc = ClearCheckCondition(pUnitCB);
  592.  
  593.    if (rc == STDON + STERR + ERROR_I24_NOT_READY)
  594.       device_status |= DSF_DOOR_OPEN + DSF_NO_DISK_PRESENT;
  595.  
  596.    if (pUnitCB->DeviceInfo.product_id_code != TOSHIBA_3201)
  597.       device_status |= DSF_LONG_SECTORS;
  598.  
  599.    if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_XA)
  600.       device_status |= DSF_XA_SUPPORT;
  601.  
  602.    if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CDDA)
  603.       device_status |= DSF_CDDA_SUPPORT;
  604.  
  605.    if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_CARTRIDGE_CHANGER)        //SD@135221
  606.       device_status |= DSF_CARTRIDGE_CHANGER;                                   //SD@135221
  607.                                                                                 //SD@135221
  608.    if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_INDIVIDUAL_CHANGER)       //SD@135221
  609.       device_status |= DSF_INDIVIDUAL_CHANGER;                                  //SD@135221
  610.  
  611.    ((struct DeviceStatus_Data FAR *)pRP->DataPacket)->device_status =
  612.                                                  (ULONG) device_status;
  613.  
  614.    return(STDON);
  615. }
  616. /****************************************************************************   //SD@135221
  617.  *                                                                              //SD@135221
  618.  * FUNCTION NAME = CD_TrayStatus                                                //SD@135221
  619.  *                                                                              //SD@135221
  620.  * DESCRIPTION   = Return tray count/active tray for changer devices            //SD@135221
  621.  *                                                                              //SD@135221
  622.  *                 USHORT CD_TrayStatus (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)    //SD@135221
  623.  *                                                                              //SD@135221
  624.  * INPUT         = pRP              - Request Packet                            //SD@135221
  625.  *                 pUnitCB          - Pointer to UnitCB                         //SD@135221
  626.  *                                                                              //SD@135221
  627.  * OUTPUT        = USHORT           - Packet Status word                        //SD@135221
  628.  *                                                                              //SD@135221
  629.  * RETURN-NORMAL =                                                              //SD@135221
  630.  * RETURN-ERROR  =                                                              //SD@135221
  631.  *                                                                              //SD@135221
  632.  ****************************************************************************/  //SD@135221
  633.                                                                                 //SD@135221
  634. USHORT CD_TrayStatus (pRP, pUnitCB)                                             //SD@135221
  635.                                                                                 //SD@135221
  636. PRP_GENIOCTL pRP;                                                               //SD@135221
  637. NPUNITCB     pUnitCB;                                                           //SD@135221
  638.                                                                                 //SD@135221
  639. {                                                                               //SD@135221
  640.    USHORT rc;                                                                   //SD@135221
  641.    struct ReturnTrayStatus_Data FAR *pTrayStatus;                               //SD@135221
  642.                                                                                 //SD@135221
  643.    if(pUnitCB->DeviceInfo.Audio.capabilities &                                  //SD@135221
  644.       (DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER))                      //SD@135221
  645.      {                                                                          //SD@135221
  646.      pTrayStatus=(struct ReturnTrayStatus_Data FAR *)pRP->DataPacket;           //SD@135221
  647.      pTrayStatus->Count=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Maximum;       //SD@135221
  648.      pTrayStatus->Current=pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current;     //SD@135221
  649.      pTrayStatus->AssignedSLot=pUnitCB->DeviceInfo.Slot;                        //SD@135221
  650.      rc=STDON;                                                                  //SD@135221
  651.      } /* endif */                                                              //SD@135221
  652.    else                                                                         //SD@135221
  653.      {                                                                          //SD@135221
  654.      rc=STDON + STERR + ERROR_I24_INVALID_PARAMETER;                            //SD@135221
  655.      } /* endelse */                                                            //SD@135221
  656.    return rc;                                                                   //SD@135221
  657. }                                                                               //SD@135221
  658.  
  659. /****************************************************************************
  660.  *
  661.  * FUNCTION NAME = CD_Identify
  662.  *
  663.  * DESCRIPTION   = Identify device.
  664.  *
  665.  *                 USHORT CD_Identify (PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  666.  *
  667.  * INPUT         = pRP              - Request Packet
  668.  *                 pUnitCB          - Pointer to UnitCB
  669.  *
  670.  * OUTPUT        = USHORT           - Packet Status word
  671.  *
  672.  * RETURN-NORMAL =
  673.  * RETURN-ERROR  =
  674.  *
  675.  ****************************************************************************/
  676.  
  677. USHORT CD_Identify (pRP, pUnitCB)
  678.  
  679. PRP_GENIOCTL pRP;
  680. NPUNITCB     pUnitCB;
  681.  
  682. {
  683.    struct IdentifyCDROMdriver FAR      *pParmPkt;
  684.    struct IdentifyCDROMdriver_Data FAR *pDataPkt;
  685.    union ULONGB parameter;
  686.    USHORT rc = 0;
  687.  
  688.  
  689.    pParmPkt = (struct IdentifyCDROMdriver FAR *) pRP->ParmPacket;
  690.    pDataPkt = (struct IdentifyCDROMdriver_Data FAR *) pRP->DataPacket;
  691.  
  692.  
  693. /*
  694. ** rc = VerifyAccess (pParmPkt,
  695. **                    sizeof(struct IdentifyCDROMdriver),
  696. **                    READ_ACCESS);
  697. ** if (rc & STERR)
  698. **    return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  699. **
  700. */
  701.  
  702.    parameter.dword = pParmPkt->ID_code;
  703.    if (parameter.ulbwords.word_0 != CD)
  704.       return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  705.  
  706.    if (parameter.ulbytes.byte_2 > '9' || parameter.ulbytes.byte_2 < '0')
  707.       return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  708.  
  709.    if (parameter.ulbytes.byte_3 > '9' || parameter.ulbytes.byte_3 < '0')
  710.       return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  711.  
  712.  
  713. /*
  714. **
  715. ** rc = VerifyAccess (pDataPkt,
  716. **                    sizeof(struct IdentifyCDROMdriver_data),
  717. **                    READ_WRITE_ACCESS);
  718. */
  719.  
  720.  
  721.    if (rc & STERR)
  722.       return(STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  723.  
  724.  
  725.    pDataPkt->ID_code = CD01;
  726.  
  727.    return(STDON);
  728.  
  729. }
  730.  
  731.  
  732. /****************************************************************************
  733.  *
  734.  * FUNCTION NAME = CD_ReturnSectorSize
  735.  *
  736.  * DESCRIPTION   = Return the sector size of the volume.
  737.  *
  738.  *                 USHORT CD_ReturnSectorSize (PRP_GENIOCTL pRP,
  739.  *                                                     NPUNITCB pUnitCB)
  740.  *
  741.  * INPUT         = pRP              - Request Packet
  742.  *                 pUnitCB          - Pointer to UnitCB
  743.  *
  744.  * OUTPUT        = USHORT           - Packet Status word
  745.  *
  746.  * RETURN-NORMAL =
  747.  * RETURN-ERROR  =
  748.  *
  749.  ****************************************************************************/
  750.  
  751. USHORT CD_ReturnSectorSize (pRP, pUnitCB)
  752.  
  753. PRP_GENIOCTL pRP;
  754. NPUNITCB     pUnitCB;
  755.  
  756. {
  757.    USHORT   rc;
  758.  
  759.    if ( (rc = ClearCheckCondition(pUnitCB)) ==
  760.                               STDON + STERR + ERROR_I24_NOT_DOS_DISK)
  761.    {
  762.       return(rc);
  763.    }
  764.  
  765.    ((struct ReturnSectorSize_Data FAR *)pRP->DataPacket)->sector_size =
  766.                                                           CDROM_SECTOR_SIZE;
  767.    return(STDON);
  768. }
  769.  
  770.  
  771. /****************************************************************************
  772.  *
  773.  * FUNCTION NAME = CD_HeadLocation
  774.  *
  775.  * DESCRIPTION   = Return the current head location.
  776.  *
  777.  *                 USHORT CD_HeadLocation(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  778.  *
  779.  * INPUT         = pRP              - Request Packet
  780.  *                 pUnitCB          - Pointer to UnitCB
  781.  *
  782.  * OUTPUT        = USHORT           - Packet Status word
  783.  *
  784.  * RETURN-NORMAL =
  785.  * RETURN-ERROR  =
  786.  *
  787.  ****************************************************************************/
  788.  
  789. USHORT CD_HeadLocation (pRP, pUnitCB)
  790.  
  791. PRP_GENIOCTL pRP;
  792. NPUNITCB     pUnitCB;
  793.  
  794. {
  795.    NPIORB_CDB pIORB;
  796.    USHORT     rc, address_mode;
  797.  
  798.    struct SubChannel_Position NEAR *pCDBData;
  799.    struct LocationOfHead_Data FAR *pDataPkt;
  800.    union  AddressType location;
  801.  
  802.    pDataPkt = (struct LocationOfHead_Data FAR *) pRP->DataPacket;
  803.  
  804.  
  805.    if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
  806.       return (STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
  807.  
  808.    address_mode = ((struct LocationOfHead FAR *)pRP->ParmPacket)->address_mode;
  809.  
  810.    if (address_mode > CDROM_REDBOOK_MODE)
  811.       return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  812.  
  813.    if ( (rc = ClearCheckCondition (pUnitCB) ) & STERR)
  814.       return(rc);
  815.  
  816.    /*
  817.    ** Issue SCSI Read SubChannel - Current Position Command
  818.    */
  819.    BuildCDB_ReadSubChannel(pUnitCB, RSC_CURRENT_POSITION,
  820.                                     (NPIORB_CDB FAR *) &pIORB);
  821.  
  822.    if ( (rc = SubmitIORB_Wait(pUnitCB, pIORB, (PBYTE) pRP)) == STDON)
  823.    {
  824.       /*
  825.       ** Return the current head location from the CDB data area
  826.       */
  827.       pCDBData = (struct SubChannel_Position NEAR *) pIORB->CDB_data;
  828.  
  829.       if (pUnitCB->DeviceInfo.product_id_code == NEC_260_17B)
  830.       {
  831.          location.ul_redbook.min
  832.                              = BCDtoBinary(pCDBData->abs_address.redbook.min);
  833.          location.ul_redbook.sec
  834.                              = BCDtoBinary(pCDBData->abs_address.redbook.sec);
  835.          location.ul_redbook.frame
  836.                              = BCDtoBinary(pCDBData->abs_address.redbook.frame);
  837.       }
  838.       else
  839.       {
  840.          location.ul_redbook.min   = pCDBData->abs_address.redbook.min;
  841.          location.ul_redbook.sec   = pCDBData->abs_address.redbook.sec;
  842.          location.ul_redbook.frame = pCDBData->abs_address.redbook.frame;
  843.       }
  844.  
  845.       location.ul_redbook.zero  = 0;
  846.  
  847.       if (address_mode == CDROM_HSG_MODE)
  848.          location.dword = RedBookToHSG (location.dword);
  849.    }
  850.  
  851.    pDataPkt->location_of_head = location.dword;
  852.  
  853.    FreeIORB(pUnitCB, pIORB);
  854.  
  855.    return(rc);
  856.  
  857. }
  858.  
  859.  
  860. /****************************************************************************
  861.  *
  862.  * FUNCTION NAME = CD_ReadPrefetch
  863.  *
  864.  * DESCRIPTION   = Read prefetch.
  865.  *
  866.  *                 USHORT CD_ReadPrefetch(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  867.  *
  868.  * INPUT         = pRP              - Request Packet
  869.  *                 pUnitCB          - Pointer to UnitCB
  870.  *
  871.  * OUTPUT        = USHORT           - Packet Status word
  872.  *
  873.  * RETURN-NORMAL =
  874.  * RETURN-ERROR  =
  875.  *
  876.  ****************************************************************************/
  877.  
  878. USHORT CD_ReadPrefetch (pRP, pUnitCB)
  879.  
  880. PRP_GENIOCTL pRP;
  881. NPUNITCB     pUnitCB;
  882.  
  883. {
  884.    USHORT rc, transfer_count;
  885.    struct ReadPrefetch FAR *pParmPacketR;
  886.    struct Seek FAR *pParmPacketS;
  887.  
  888.    pParmPacketR = (struct ReadPrefetch FAR *) pRP->ParmPacket;
  889.    pParmPacketS = (struct Seek FAR *) pRP->ParmPacket;
  890.  
  891.    /*
  892.    ** Convert the prefech to a seek operation
  893.    */
  894.    transfer_count = pParmPacketR->transfer_count;
  895.    pParmPacketS->start_sector = pParmPacketR->start_sector;
  896.  
  897.    rc = CD_Seek (pRP, pUnitCB);
  898.  
  899.    /*
  900.    ** Put the Read Prefetch parameter packet back to original
  901.    */
  902.    pParmPacketR->start_sector = pParmPacketS->start_sector;
  903.    pParmPacketR->transfer_count = transfer_count;
  904.  
  905.    return(rc);
  906. }
  907.  
  908.  
  909. /****************************************************************************
  910.  *
  911.  * FUNCTION NAME = CD_ReadLong
  912.  *
  913.  * DESCRIPTION   = Read long.
  914.  *
  915.  *                 USHORT CD_ReadLong(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  916.  *
  917.  * INPUT         = pRP              - Request Packet
  918.  *                 pUnitCB          - Pointer to UnitCB
  919.  *
  920.  * OUTPUT        = USHORT           - Packet Status word
  921.  *
  922.  * RETURN-NORMAL =
  923.  * RETURN-ERROR  =
  924.  *
  925.  ****************************************************************************/
  926.  
  927. USHORT CD_ReadLong (pRP, pUnitCB)
  928.  
  929. PRP_GENIOCTL pRP;
  930. NPUNITCB     pUnitCB;
  931.  
  932. {
  933.    BOOL   playing;
  934.    USHORT rc, raw_block_size;
  935.    struct ReadLong FAR *pParmPacket;
  936.    union  ULONGB ul_LBA;
  937.    ULONG  ppDataBuff;
  938.    USHORT transfer_count;
  939.  
  940.  
  941.    pParmPacket = (struct ReadLong FAR *) pRP->ParmPacket;
  942.  
  943.    ul_LBA.dword = pParmPacket->start_sector;
  944.  
  945.    switch(pParmPacket->address_mode)
  946.    {
  947.       case CDROM_HSG_MODE:
  948.          break;
  949.       case CDROM_REDBOOK_MODE:
  950.          ul_LBA.dword = RedBookToHSG (ul_LBA.dword);
  951.          break;
  952.       default:
  953.          return (STDON + STERR + ERROR_I24_INVALID_PARAMETER);
  954.    }
  955.  
  956.    /*
  957.    ** Check for uncertain media.  Also, cant read while play in progress
  958.    */
  959.    if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
  960.       return (STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
  961.  
  962.    if ( pUnitCB->DeviceInfo.playing )
  963.    {
  964.        rc = GetPlayStatus (pUnitCB, &playing);
  965.  
  966.        if (rc == STDON && playing)
  967.            return (STDON + STERR + ERROR_I24_DEVICE_IN_USE);
  968.    }
  969.  
  970.    rc = DevHelp_VirtToPhys (pRP->DataPacket, (PULONG) &ppDataBuff);
  971.    transfer_count =  pParmPacket->transfer_count;
  972.  
  973.    /*
  974.    ** Determine what the device's raw block size is.  Some drives
  975.    ** support reading all 2352 bytes, others only support 2340.  The call
  976.    ** is only done the first time a read long is issued.
  977.    */
  978.    if (pUnitCB->DeviceInfo.raw_block_size == 0)
  979.    {
  980.        if ( (rc = GetRawBlockSize(pUnitCB)) & STERR)
  981.           return(rc);
  982.    }
  983.  
  984.    raw_block_size = pUnitCB->DeviceInfo.raw_block_size;
  985.  
  986.  
  987.    switch (pUnitCB->DeviceInfo.product_id_code)
  988.    {
  989.       case TOSHIBA_3301:
  990.       case TOSHIBA_3401:
  991.          rc = Tosh_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
  992.                                             transfer_count, ppDataBuff);
  993.          break;
  994.  
  995.       case SONY_561:
  996.          rc = Sony_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
  997.                                         transfer_count, ppDataBuff);
  998.          break;
  999.  
  1000.       default:
  1001.          if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
  1002.             rc = ATAPI_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
  1003.                                            transfer_count, ppDataBuff);
  1004.          else
  1005.             rc = CD_Read_2352 (pUnitCB, (ULONG) ul_LBA.dword,
  1006.                                            transfer_count, ppDataBuff);
  1007.  
  1008.          if (rc == STDON && raw_block_size == 2340)
  1009.             PadRaw2340 (pRP->DataPacket, pParmPacket->transfer_count);
  1010.  
  1011.          break;
  1012.    }
  1013.  
  1014.    if (rc == STDON + STERR + ERROR_I24_BAD_COMMAND)
  1015.       rc = STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND;
  1016.  
  1017.    return(rc);
  1018. }
  1019.  
  1020.  
  1021. /****************************************************************************
  1022.  *
  1023.  * FUNCTION NAME = CD_Read_2352
  1024.  *
  1025.  * DESCRIPTION   = Read default CD-ROM Mode 1 sector with blocksize = 2352
  1026.  *
  1027.  *                 USHORT CD_Read_2352  (NPUNITCB pUnitCB, ULONG LBA,
  1028.  *                                   USHORT transfer_count, ULONG ppDataBuff)
  1029.  *
  1030.  * INPUT         = pUnitCB          - Pointer to UnitCB
  1031.  *                 LBA              - LBA
  1032.  *                 transfer_count   - count of sectors to transfer
  1033.  *                 ppDataBuff       - phys addr of data buffer
  1034.  *
  1035.  * OUTPUT        = USHORT           - Packet Status word
  1036.  *
  1037.  * RETURN-NORMAL =
  1038.  * RETURN-ERROR  =
  1039.  *
  1040.  ****************************************************************************/
  1041.  
  1042. USHORT CD_Read_2352 (pUnitCB, LBA, transfer_count, ppDataBuff)
  1043.  
  1044. NPUNITCB pUnitCB;
  1045. ULONG    LBA;
  1046. USHORT   transfer_count;
  1047. ULONG    ppDataBuff;
  1048.  
  1049. {
  1050.    USHORT rc, raw_sector_size;
  1051.  
  1052.    raw_sector_size = pUnitCB->DeviceInfo.raw_block_size;
  1053.  
  1054.    /*
  1055.    ** If the current block size is not a long sector, then issue
  1056.    ** a SCSI Mode Select command to set the block size.
  1057.    */
  1058.    if ((pUnitCB->DeviceInfo.current_block_size != raw_sector_size) &
  1059.       !(pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI))
  1060.    {
  1061.       rc = ChainModeSelectRead (pUnitCB, LBA, transfer_count, ppDataBuff,
  1062.                                               raw_sector_size, 0);
  1063.    }
  1064.    else
  1065.    {
  1066.       rc = ReadSector (pUnitCB, LBA, transfer_count,
  1067.                                 ppDataBuff, raw_sector_size);
  1068.    }
  1069.  
  1070.    return(rc);
  1071. }
  1072.  
  1073.  
  1074. /****************************************************************************
  1075.  *
  1076.  * FUNCTION NAME = ATAPI_Read_2352
  1077.  *
  1078.  * DESCRIPTION   = Read 2352 byte sector on ATAPI device
  1079.  *
  1080.  *                 USHORT ATAPI_Read_2352  (NPUNITCB pUnitCB, ULONG LBA,
  1081.  *                                   USHORT transfer_count, ULONG ppDataBuff)
  1082.  *
  1083.  * INPUT         = pUnitCB          - Pointer to UnitCB
  1084.  *                 LBA              - LBA
  1085.  *                 transfer_count   - count of sectors to transfer
  1086.  *                 ppDataBuff       - phys addr of data buffer
  1087.  *
  1088.  * OUTPUT        = USHORT           - Packet Status word
  1089.  *
  1090.  * RETURN-NORMAL =
  1091.  * RETURN-ERROR  =
  1092.  *
  1093.  ****************************************************************************/
  1094.  
  1095. USHORT ATAPI_Read_2352 (pUnitCB, LBA, transfer_count, ppDataBuff)
  1096.  
  1097. NPUNITCB pUnitCB;
  1098. ULONG    LBA;
  1099. USHORT   transfer_count;
  1100. ULONG    ppDataBuff;
  1101.  
  1102. {
  1103.    USHORT rc;
  1104.    NPIORB_CDB pIORB;
  1105.  
  1106.    /*
  1107.    ** Issue ATAPI Read CD command which should read any target sector,
  1108.    ** including 2352 byte Mode 1, 2352 byte Mode 2 Form 1, 2352 byte
  1109.    ** Mode 2 Form 2, and 2352 byte CD-DA
  1110.    */
  1111.  
  1112.    ATAPI_BuildCDB_ReadCD  (pUnitCB, LBA, transfer_count,
  1113.                                       ppDataBuff, (NPIORB_CDB FAR *) &pIORB);
  1114.  
  1115.  
  1116.    rc = SubmitIORB_Wait(pUnitCB, pIORB);
  1117.  
  1118.    FreeIORB (pUnitCB, pIORB);
  1119.  
  1120.    return(rc);
  1121. }
  1122.  
  1123.  
  1124.  
  1125. /****************************************************************************
  1126.  *
  1127.  * FUNCTION NAME = GetRawBlockSize
  1128.  *
  1129.  * DESCRIPTION   = Get the max raw block size the device supports.
  1130.  *
  1131.  *                 USHORT GetRawBlockSize (NPUNITCB, pUnitCB,
  1132.  *                                        (USHORT FAR *) raw_block_size)
  1133.  *
  1134.  * INPUT         = pUnitCB          - Pointer to UnitCB
  1135.  *
  1136.  * OUTPUT        = USHORT           - Packet Status word
  1137.  *
  1138.  * RETURN-NORMAL =
  1139.  * RETURN-ERROR  =
  1140.  *
  1141.  ****************************************************************************/
  1142.  
  1143. USHORT GetRawBlockSize (pUnitCB)
  1144.  
  1145. NPUNITCB pUnitCB;
  1146. {
  1147.    USHORT rc;
  1148.    NPIORB_CDB pIORB;
  1149.  
  1150.  
  1151.  
  1152.    /*
  1153.    **  Assume all ATAPI drives support returning a full 2352 byte sector.
  1154.    */
  1155.  
  1156.    if (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI)
  1157.    {
  1158.       pUnitCB->DeviceInfo.raw_block_size = 2352;
  1159.       return(STDON);
  1160.    }
  1161.  
  1162.    /*
  1163.    ** First See if a block size of 2352 bytes is supported
  1164.    */
  1165.    rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2352);
  1166.  
  1167.    if (rc == STDON)
  1168.       pUnitCB->DeviceInfo.raw_block_size = 2352;
  1169.    else
  1170.    {
  1171.       /*
  1172.       ** 2352 not supported, try 2340
  1173.       */
  1174.       rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2340);
  1175.       if (rc == STDON)
  1176.          pUnitCB->DeviceInfo.raw_block_size = 2340;
  1177.    }
  1178.  
  1179.    /*
  1180.    ** Put the block size back to 2048
  1181.    */
  1182.    rc = Submit_ModeSelect (pUnitCB, CD_DENSITY_DEFAULT, 2048);
  1183.    if (rc == STDON)
  1184.    {
  1185.       pUnitCB->DeviceInfo.current_density = CD_DENSITY_DEFAULT;
  1186.       pUnitCB->DeviceInfo.current_block_size = 2048;
  1187.    }
  1188.  
  1189.    return(rc);
  1190. }
  1191.  
  1192.  
  1193. /****************************************************************************
  1194.  *
  1195.  * FUNCTION NAME = CD_ReadLongPre
  1196.  *
  1197.  * DESCRIPTION   = Read long.
  1198.  *
  1199.  *                 USHORT CD_ReadLongPre(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  1200.  *
  1201.  * INPUT         = pRP              - Request Packet
  1202.  *                 pUnitCB          - Pointer to UnitCB
  1203.  *
  1204.  * OUTPUT        = USHORT           - Packet Status word
  1205.  *
  1206.  * RETURN-NORMAL =
  1207.  * RETURN-ERROR  =
  1208.  *
  1209.  ****************************************************************************/
  1210.  
  1211. USHORT CD_ReadLongPre (pRP, pUnitCB)
  1212.  
  1213. PRP_GENIOCTL pRP;
  1214. NPUNITCB     pUnitCB;
  1215.  
  1216. {
  1217.    return ( CD_ReadPrefetch (pRP, pUnitCB) );
  1218. }
  1219.  
  1220.  
  1221. /****************************************************************************
  1222.  *
  1223.  * FUNCTION NAME = CD_ReturnVolumeSize
  1224.  *
  1225.  * DESCRIPTION   = Get volume size,
  1226.  *
  1227.  *                 USHORT CD_ReturnVolumeSize(PRP_GENIOCTL pRP,
  1228.  *                                                 NPUNITCB pUnitCB)
  1229.  *
  1230.  * INPUT         = pRP              - Request Packet
  1231.  *                 pUnitCB          - Pointer to UnitCB
  1232.  *
  1233.  * OUTPUT        = USHORT           - Packet Status word
  1234.  *
  1235.  * RETURN-NORMAL =
  1236.  * RETURN-ERROR  =
  1237.  *
  1238.  ****************************************************************************/
  1239.  
  1240. USHORT CD_ReturnVolumeSize (pRP, pUnitCB)
  1241.  
  1242. PRP_GENIOCTL pRP;
  1243. NPUNITCB     pUnitCB;
  1244.  
  1245. {
  1246.    USHORT     rc;
  1247.    ULONG      volume_size;
  1248.  
  1249.  
  1250.    if (pUnitCB->Flags & UCF_UNCERTAIN_MEDIA)
  1251.       return(STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA);
  1252.  
  1253.    rc = GetVolumeSize (pUnitCB, &volume_size);
  1254.  
  1255.    if (rc == STDON)
  1256.       ((struct ReturnVolumeSize_Data FAR *)pRP->DataPacket)->volume_size =
  1257.                                                              volume_size;
  1258.  
  1259.    return(rc);
  1260.  
  1261. }
  1262.  
  1263.  
  1264. /****************************************************************************
  1265.  *
  1266.  * FUNCTION NAME = CD_GetUPC
  1267.  *
  1268.  * DESCRIPTION   = Get UPC.
  1269.  *
  1270.  *                 USHORT CD_GetUPC(PRP_GENIOCTL pRP, NPUNITCB pUnitCB)
  1271.  *
  1272.  * INPUT         = pRP              - Request Packet
  1273.  *                 pUnitCB          - Pointer to UnitCB
  1274.  *
  1275.  * OUTPUT        = USHORT           - Packet Status word
  1276.  *
  1277.  * RETURN-NORMAL =
  1278.  * RETURN-ERROR  =
  1279.  *
  1280.  ****************************************************************************/
  1281.  
  1282. USHORT CD_GetUPC (pRP, pUnitCB)
  1283.  
  1284. PRP_GENIOCTL pRP;
  1285. NPUNITCB     pUnitCB;
  1286.  
  1287. {
  1288.    USHORT rc, i;
  1289.    NPIORB_CDB pIORB;
  1290.    struct UPCCode_Data FAR *pDataPkt;
  1291.    union CDROM_SubChannel_Info NEAR *q_data;
  1292.    USHORT GotUPC = NO;
  1293.  
  1294.    pDataPkt = (struct UPCCode_Data FAR *) pRP->DataPacket;
  1295.  
  1296.    if ( ! (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC) )
  1297.       return(STDON + STERR + ERROR_I24_BAD_COMMAND);
  1298.  
  1299.    /*
  1300.    ** First, issue ReadSubChannel for Current Position
  1301.    */
  1302.    ClearCheckCondition (pUnitCB);
  1303.  
  1304.    BuildCDB_ReadSubChannel(pUnitCB, RSC_CURRENT_POSITION,
  1305.                                     (NPIORB_CDB FAR *) &pIORB);
  1306.  
  1307.    rc = SubmitIORB_Wait(pUnitCB, pIORB);
  1308.  
  1309.    if (rc == STDON)
  1310.    {
  1311.       q_data = (union CDROM_SubChannel_Info NEAR *) pIORB->CDB_data;
  1312.  
  1313.       pDataPkt->adr_control = (q_data->current_position.control << 4) |
  1314.                                q_data->current_position.ADR;
  1315.  
  1316. /*
  1317. **    if (pDataPkt->adr_control & 0x0F)
  1318. **        pDataPkt->adr_control = ((q_data->current_position.control << 4) |
  1319. **                                  MODE_2);
  1320. */
  1321.       pDataPkt->zero = 0;
  1322.       pDataPkt->aframe = q_data->current_position.abs_address.redbook.frame;
  1323.    }
  1324.  
  1325.    FreeIORB (pUnitCB, pIORB);
  1326.  
  1327.    /*
  1328.    ** Issue SCSI Read SubChannel - Get UPC Code
  1329.    */
  1330.    if (rc == STDON)
  1331.    {
  1332.       ClearCheckCondition (pUnitCB);
  1333.  
  1334.       BuildCDB_ReadSubChannel(pUnitCB, RSC_MEDIA_CAT_NUM,
  1335.                                            (NPIORB_CDB FAR *) &pIORB);
  1336.  
  1337.       rc = SubmitIORB_Wait(pUnitCB, pIORB);
  1338.  
  1339.       if (rc == STDON)
  1340.       {
  1341.          q_data = (union CDROM_SubChannel_Info NEAR *) pIORB->CDB_data;
  1342.  
  1343.          /*
  1344.          ** Make sure media catalog number field is valid
  1345.          */
  1346.          if (q_data->media_cat_number.mcval)
  1347.          {
  1348.             if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC_IN_BCD)
  1349.             {
  1350.                pDataPkt->upc_ean_code.upc_byte0 =
  1351.                         q_data->media_cat_number.media_catalog_no[0];
  1352.  
  1353.                pDataPkt->upc_ean_code.upc_byte1 =
  1354.                         q_data->media_cat_number.media_catalog_no[1];
  1355.  
  1356.                pDataPkt->upc_ean_code.upc_byte2 =
  1357.                         q_data->media_cat_number.media_catalog_no[2];
  1358.  
  1359.                pDataPkt->upc_ean_code.upc_byte3 =
  1360.                         q_data->media_cat_number.media_catalog_no[3];
  1361.  
  1362.                pDataPkt->upc_ean_code.upc_byte4 =
  1363.                         q_data->media_cat_number.media_catalog_no[4];
  1364.  
  1365.                pDataPkt->upc_ean_code.upc_byte5 =
  1366.                         q_data->media_cat_number.media_catalog_no[5];
  1367.  
  1368.                pDataPkt->upc_ean_code.upc_byte6 =
  1369.                         q_data->media_cat_number.media_catalog_no[6];
  1370.             }
  1371.             else
  1372.             {
  1373.                if (pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_UPC_IN_ASCII)
  1374.                {
  1375.                   for (i = 0; i <= 13; i++)
  1376.                      q_data->media_cat_number.media_catalog_no[i] -= 0x30;
  1377.                }
  1378.  
  1379.  
  1380.                pDataPkt->upc_ean_code.upc_byte0 =
  1381.                         q_data->media_cat_number.media_catalog_no[0] << 4 |
  1382.                         q_data->media_cat_number.media_catalog_no[1];
  1383.  
  1384.                pDataPkt->upc_ean_code.upc_byte1 =
  1385.                         q_data->media_cat_number.media_catalog_no[2] << 4 |
  1386.                         q_data->media_cat_number.media_catalog_no[3];
  1387.  
  1388.                pDataPkt->upc_ean_code.upc_byte2 =
  1389.                         q_data->media_cat_number.media_catalog_no[4] << 4 |
  1390.                         q_data->media_cat_number.media_catalog_no[5];
  1391.  
  1392.                pDataPkt->upc_ean_code.upc_byte3 =
  1393.                         q_data->media_cat_number.media_catalog_no[6] << 4 |
  1394.                         q_data->media_cat_number.media_catalog_no[7];
  1395.  
  1396.                pDataPkt->upc_ean_code.upc_byte4 =
  1397.                         q_data->media_cat_number.media_catalog_no[8] << 4 |
  1398.                         q_data->media_cat_number.media_catalog_no[9];
  1399.  
  1400.                pDataPkt->upc_ean_code.upc_byte5 =
  1401.                         q_data->media_cat_number.media_catalog_no[10] << 4 |
  1402.                         q_data->media_cat_number.media_catalog_no[11];
  1403.  
  1404.                pDataPkt->upc_ean_code.upc_byte6 =
  1405.                         q_data->media_cat_number.media_catalog_no[12] << 4 |
  1406.                         q_data->media_cat_number.media_catalog_no[13];
  1407.             }
  1408.             GotUPC = YES;
  1409.          }
  1410.       }
  1411.       FreeIORB (pUnitCB, pIORB);
  1412.    }
  1413.  
  1414.    /*
  1415.    ** Add error checking code
  1416.    */
  1417.    if (GotUPC == NO)
  1418.    {
  1419.       pDataPkt->adr_control = 0;
  1420.       pDataPkt->upc_ean_code.upc_byte0 = 0;
  1421.       pDataPkt->upc_ean_code.upc_byte1 = 0;
  1422.       pDataPkt->upc_ean_code.upc_byte2 = 0;
  1423.       pDataPkt->upc_ean_code.upc_byte3 = 0;
  1424.       pDataPkt->upc_ean_code.upc_byte4 = 0;
  1425.       pDataPkt->upc_ean_code.upc_byte5 = 0;
  1426.       pDataPkt->upc_ean_code.upc_byte6 = 0;
  1427.       pDataPkt->zero = 0;
  1428.       pDataPkt->aframe = 0;
  1429.    }
  1430.    /*
  1431.    ** Clear media changed check condition on Sony CDU-541 after
  1432.    ** UPC command issued.
  1433.    */
  1434.    ClearCheckCondition (pUnitCB);
  1435.  
  1436.    if (pUnitCB->DeviceInfo.product_id_code == SONY_541)
  1437.       pUnitCB->Flags &= ~UCF_UNCERTAIN_MEDIA;
  1438.  
  1439.    return (STDON);
  1440. }
  1441.