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 / cdqueue.c < prev    next >
C/C++ Source or Header  |  1996-06-18  |  29KB  |  997 lines

  1. /**************************************************************************
  2.  *
  3.  * SOURCE FILE NAME = CDQUEUE.C
  4.  *
  5.  * DESCRIPTIVE NAME = Request queuing routines for OS/2 CD-ROM Manager
  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.  * FUNCTIONS   Maintains queues of IORB requests that are awaiting
  20.  *             processing.  Also provides routing of IORBs to
  21.  *             Adapter Device Drivers.
  22.  *
  23.  * ENTRY POINTS:
  24.  *
  25.  * DEPENDENCIES:
  26.  *
  27.  * NOTES
  28.  *
  29.  *
  30.  * STRUCTURES
  31.  *
  32.  * EXTERNAL REFERENCES
  33.  *
  34.  * EXTERNAL FUNCTIONS
  35.  *
  36.  * CHANGE ACTIVITY =
  37.  *  DATE      FLAG        APAR   CHANGE DESCRIPTION
  38.  *  --------  ----------  -----  --------------------------------------
  39.  *  09/08/95  @V135221           Sam Detweiler - CD-ROM changer support
  40.  *
  41.  ****************************************************************************/
  42.  
  43. #include "cdh.h"
  44.  
  45. VOID   CallADD (NPUNITCB, NPIORB);
  46. USHORT ProcessError (NPUNITCB, NPIORB);
  47. UCHAR  NEAR MapIORBError(USHORT);
  48. USHORT NEAR MapSenseData(NPIORB);
  49. VOID   NEAR TraceError(NPIORB_CDB);
  50. VOID   NEAR PurgeWaitingQueue (NPUNITCB);
  51. USHORT NEAR RemoveWaitingQueue (NPUNITCB, NPIORB);
  52. VOID NEAR BuildCDB_ChangerLoad(NPUNITCB, NPIORB_CDB FAR *,USHORT);      //SD@135221
  53.  
  54.  
  55. /****************************************************************************
  56.  *
  57.  * FUNCTION NAME = QueueIORB
  58.  *
  59.  * DESCRIPTION   = Put a request on a waiting queue.
  60.  *
  61.  *          Put a request on the waiting queue in the unit control block
  62.  *          for the specified unit.
  63.  *
  64.  *          VOID PutWaitingQueue  (NPUNITCB pUnitCB, NPIORB pIORB)
  65.  *
  66.  * INPUT         = pUnitCB          - Pointer to UnitCB
  67.  *                 pIORB            - Pointer to IORB
  68.  *
  69.  * OUTPUT        = VOID
  70.  *
  71.  * RETURN-NORMAL =
  72.  * RETURN-ERROR  =
  73.  *
  74.  ****************************************************************************/
  75.  
  76. VOID QueueIORB (pUnitCB, pIORB)
  77.  
  78. NPUNITCB pUnitCB;
  79. NPIORB   pIORB;
  80.  
  81. {
  82.    NPIORB_DMWORK pDMWork;
  83.    NPIORB        pPrevIORB;
  84.  
  85.    PUSHFLAGS;
  86.    DISABLE;
  87.  
  88.    pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
  89.    pDMWork->WaitingQueueLink = 0;
  90.    pDMWork->pUnitCB = pUnitCB;
  91.  
  92.    if (pUnitCB->WaitingQueue.Head == 0)
  93.    {
  94.       pUnitCB->WaitingQueue.Head = pIORB;
  95.       pUnitCB->WaitingQueue.Tail = pIORB;
  96.    }
  97.    else
  98.    {
  99.       pPrevIORB = pUnitCB->WaitingQueue.Tail;
  100.       pDMWork = (NPIORB_DMWORK) &(pPrevIORB->DMWorkSpace);
  101.       pDMWork->WaitingQueueLink = pIORB;
  102.       pUnitCB->WaitingQueue.Tail = pIORB;
  103.    }
  104.  
  105.    pUnitCB->NumReqsWaiting++;
  106.    CD_NumReqsWaiting++;
  107.  
  108.    POPFLAGS;
  109.  
  110. }
  111.  
  112.  
  113. /****************************************************************************
  114.  *
  115.  * FUNCTION NAME = PullWaitingQueue
  116.  *
  117.  * DESCRIPTION   = Pull a request from a waiting queue.
  118.  *
  119.  *                 USHORT PullWaitingQueue  (NPUNITCB pUnitCB, NPIORB *pIORB)
  120.  *
  121.  * INPUT         = pUnitCB          - Pointer to UnitCB
  122.  *                 pIORB            - returned pointer to IORB
  123.  *
  124.  * OUTPUT        = USHORT           - = 0, Request pulled
  125.  *                                    <> 0, No request pulled, queues empty
  126.  *
  127.  * RETURN-NORMAL =
  128.  * RETURN-ERROR  =
  129.  *
  130.  ****************************************************************************/
  131.  
  132. USHORT PullWaitingQueue (pUnitCB, pIORB)
  133.  
  134. NPUNITCB pUnitCB;
  135. NPIORB   FAR *pIORB;
  136.  
  137. {
  138.    USHORT rc;
  139.    NPIORB pReq;
  140.    NPIORB_DMWORK pDMWork;
  141.  
  142.    PUSHFLAGS;
  143.    DISABLE;
  144.  
  145.    /*
  146.    ** Make sure there's a request waiting to be processed before
  147.    ** searching the queues.
  148.    */
  149.    if (pUnitCB->NumReqsWaiting == 0)
  150.    {
  151.       rc = ERROR;
  152.       goto PullRet;
  153.    }
  154.  
  155.    pReq = pUnitCB->WaitingQueue.Head;
  156.    pDMWork = (NPIORB_DMWORK) &(pReq->DMWorkSpace);
  157.  
  158.    pUnitCB->WaitingQueue.Head = pDMWork->WaitingQueueLink;
  159.    pDMWork->WaitingQueueLink = 0;
  160.  
  161.    if (pUnitCB->WaitingQueue.Head == 0)
  162.          pUnitCB->WaitingQueue.Tail = 0;
  163.  
  164.    *pIORB = pReq;
  165.    pUnitCB->NumReqsWaiting--;
  166.    CD_NumReqsWaiting--;
  167.    rc = NO_ERROR;
  168.  
  169.  
  170. PullRet:
  171.    POPFLAGS;
  172.    return(rc);
  173. }
  174.  
  175.  
  176. /****************************************************************************
  177.  *
  178.  * FUNCTION NAME = PurgeWaitingQueue
  179.  *
  180.  * DESCRIPTION   = Purge the waiting queue on a media changed errror.
  181.  *
  182.  *                 USHORT PurgeWaitingQueue  (NPUNITCB pUnitCB)
  183.  *
  184.  * INPUT         = pUnitCB          - Pointer to UnitCB
  185.  *
  186.  * OUTPUT        = VOID
  187.  *
  188.  * RETURN-NORMAL =
  189.  * RETURN-ERROR  =
  190.  *
  191.  ****************************************************************************/
  192.  
  193. VOID PurgeWaitingQueue (pUnitCB)
  194.  
  195. NPUNITCB pUnitCB;
  196.  
  197. {
  198.    NPIORB  pIORB;
  199.    USHORT  AwakeCount;
  200.  
  201.    while (PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORB) == NO_ERROR)
  202.    {
  203.       pIORB->Status = IORB_DONE + IORB_ERROR;
  204.       pIORB->ErrorCode = IOERR_MEDIA_CHANGED;
  205.       DevHelp_ProcRun((ULONG)pIORB, &AwakeCount);
  206.    }
  207. }
  208.  
  209.  
  210. /****************************************************************************
  211.  *
  212.  * FUNCTION NAME = RemoveWaitingQueue
  213.  *
  214.  * DESCRIPTION   = Remove an entry from the waiting queue.
  215.  *
  216.  *                 USHORT RemoveWaitingQueue  (NPUNITCB pUnitCB, NPIORB pIORB)
  217.  *
  218.  * INPUT         = pUnitCB          - Pointer to UnitCB
  219.  *                 pIORB            - Pointer to IORB
  220.  *
  221.  * OUTPUT        = USHORT           - YES, iorb removed
  222.  *                                    NO,  iorb not removed
  223.  *
  224.  * RETURN-NORMAL =
  225.  * RETURN-ERROR  =
  226.  *
  227.  ****************************************************************************/
  228.  
  229. USHORT RemoveWaitingQueue (pUnitCB, pIORB)
  230.  
  231. NPUNITCB pUnitCB;
  232. NPIORB   pIORB;
  233.  
  234. {
  235.    NPIORB pCurReq, pPrevReq;
  236.    NPIORB_DMWORK  pDMWorkCur, pDMWorkPrev;
  237.    USHORT removed = NO;
  238.  
  239.    PUSHFLAGS;
  240.    DISABLE;
  241.  
  242.    /*
  243.    ** Make sure the waiting queue isnt empty
  244.    */
  245.    if (pUnitCB->NumReqsWaiting == 0)
  246.       goto RemoveRet;
  247.  
  248.    /*
  249.    ** If it's at the head simply remove it from the head
  250.    */
  251.    if (pUnitCB->WaitingQueue.Head == pIORB)
  252.    {
  253.       pDMWorkCur = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
  254.       pUnitCB->WaitingQueue.Head = pDMWorkCur->WaitingQueueLink;
  255.       if (pDMWorkCur->WaitingQueueLink == 0)
  256.          pUnitCB->WaitingQueue.Tail = 0;
  257.       else
  258.          pDMWorkCur->WaitingQueueLink = 0;
  259.  
  260.       removed = YES;
  261.       pUnitCB->NumReqsWaiting--;
  262.       CD_NumReqsWaiting--;
  263.       goto RemoveRet;
  264.    }
  265.    /*
  266.    ** Not at the head, must search for it
  267.    */
  268.    pCurReq = pUnitCB->WaitingQueue.Head;
  269.    pDMWorkCur =  (NPIORB_DMWORK) &(pCurReq->DMWorkSpace);
  270.  
  271.    while (pCurReq != 0)
  272.    {
  273.       if (pCurReq == pIORB)
  274.       {
  275.          pDMWorkPrev->WaitingQueueLink = pDMWorkCur->WaitingQueueLink;
  276.          if (pUnitCB->WaitingQueue.Tail == pCurReq)
  277.             pUnitCB->WaitingQueue.Tail = pDMWorkCur->WaitingQueueLink;
  278.  
  279.          removed = YES;
  280.          break;
  281.       }
  282.       pPrevReq = pCurReq;
  283.       pDMWorkPrev = (NPIORB_DMWORK) &(pPrevReq->DMWorkSpace);
  284.  
  285.       if (pDMWorkCur->WaitingQueueLink != 0)
  286.       {
  287.          pCurReq = pDMWorkCur->WaitingQueueLink;
  288.          pDMWorkCur =  (NPIORB_DMWORK) &(pCurReq->DMWorkSpace);
  289.       }
  290.    }
  291.  
  292. RemoveRet:
  293.    POPFLAGS;
  294.    return(removed);
  295. }
  296.  
  297.  
  298. /****************************************************************************
  299.  *
  300.  * FUNCTION NAME = SubmitIORB_Wait
  301.  *
  302.  * DESCRIPTION   = Submit an IORB, wait till done
  303.  *
  304.  *       This function will submit a request and wait till it's done.
  305.  *       If the device is idle, the request will be submitted, else the
  306.  *       request till be queued on the unit's waiting queue.
  307.  *
  308.  *       USHORT SubmitIORB_Wait (pUnitCB, pIORB)
  309.  *
  310.  * INPUT         = pUnitCB          - pointer to unit control block
  311.  *                 pIORB            - pointer to IORB
  312.  *
  313.  * OUTPUT        = VOID
  314.  *
  315.  * RETURN-NORMAL =
  316.  * RETURN-ERROR  =
  317.  *
  318.  ****************************************************************************/
  319.  
  320. USHORT NEAR SubmitIORB_Wait (pUnitCB, pIORB)
  321.  
  322. NPUNITCB pUnitCB;
  323. NPIORB   pIORB;
  324.  
  325. {
  326.    USHORT rc;
  327.    NPIORB pIORBq;
  328.    NPIORB_DMWORK pDMWork;
  329.  
  330.    PUSHFLAGS;
  331.    DISABLE;
  332.  
  333.  
  334.    if(pUnitCB->pParentUnitCB)                                           //SD@135221
  335.      {                                                                  //SD@135221
  336.      pUnitCB=pUnitCB->pParentUnitCB;                                    //SD@135221
  337.      } /* endif */                                                      //SD@135221
  338.  
  339.    pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
  340.    pDMWork->pUnitCB = pUnitCB;
  341.  
  342.    /*
  343.    ** If the device is idle, then submit the request
  344.    */
  345.    if (pUnitCB->NumReqsInProgress == 0)
  346.    {
  347.       if (pUnitCB->NumReqsWaiting == 0)
  348.       {
  349.          pIORBq = pIORB;
  350.       }
  351.       else
  352.       {
  353.          PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORBq);
  354.          QueueIORB (pUnitCB, pIORB);
  355.       }
  356.       pUnitCB->NumReqsInProgress++;
  357.       CD_NumReqsInProgress++;
  358.  
  359.       ENABLE;
  360.       CallADD(pUnitCB, pIORBq);
  361.    }
  362.  
  363.    /*
  364.    ** else queue the request
  365.    */
  366.    else
  367.       QueueIORB (pUnitCB, pIORB);
  368.  
  369.    /*
  370.    ** Block until the request is done
  371.    */
  372.    DISABLE;
  373.    while ( !( pIORB->Status & IORB_DONE ) )
  374.    {
  375.       DevHelp_ProcBlock ((ULONG)pIORB, -1L, 1);
  376.       DISABLE;                          /* Block does an enable             */
  377.    }
  378.    ENABLE;
  379.  
  380.    POPFLAGS;
  381.  
  382.    rc = ProcessError(pUnitCB, pIORB);
  383.  
  384.    return (rc);
  385. }
  386.  
  387.  
  388. /****************************************************************************
  389.  *
  390.  * FUNCTION NAME = f_SubmitRequestsToADD
  391.  *
  392.  * DESCRIPTION   = Submit Requests to an Adapter Device Driver
  393.  *
  394.  * INPUT         = pUnitCB          - pointer to unit control block
  395.  *
  396.  * OUTPUT        = VOID
  397.  *
  398.  * RETURN-NORMAL =
  399.  * RETURN-ERROR  =
  400.  *
  401.  ****************************************************************************/
  402.  
  403. VOID FAR f_SubmitRequestsToADD (pUnitCB)
  404.  
  405. NPUNITCB pUnitCB;
  406. {
  407.    SubmitRequestsToADD (pUnitCB);
  408. }
  409.  
  410.  
  411. /****************************************************************************
  412.  *
  413.  * FUNCTION NAME = SubmitRequestsToADD
  414.  *
  415.  * DESCRIPTION   = Submit Requests to an Adapter Device Driver
  416.  *
  417.  *     This function submits requests to the Adapter Device Driver which
  418.  *     manages this unit.  Requests are pulled from the unit's waiting queue
  419.  *     and submitted to the ADD if the ADD's recommended queuing count
  420.  *     has not been exceeded.
  421.  *
  422.  *     USHORT SubmitRequestsToADD (pUnitCB)
  423.  *
  424.  * INPUT         = pUnitCB          - pointer to unit control block
  425.  *
  426.  * OUTPUT        = VOID
  427.  *
  428.  * RETURN-NORMAL =
  429.  * RETURN-ERROR  =
  430.  *
  431.  ****************************************************************************/
  432.  
  433. VOID NEAR SubmitRequestsToADD (pUnitCB)
  434.  
  435. NPUNITCB pUnitCB;
  436.  
  437. {
  438.    NPIORB pIORB;
  439.    USHORT i;
  440.    USHORT NumIORBsBuilt = 0;
  441.  
  442.    PUSHFLAGS;
  443.    DISABLE;
  444.  
  445.    /*
  446.    ** If the number of requests already submitted to the ADD is
  447.    ** less than the ADD's recommended queuing count, then submit
  448.    ** additional requests.
  449.    */
  450.    for (i=pUnitCB->NumReqsInProgress; i < pUnitCB->UnitInfo.QueuingCount; i++)
  451.    {
  452.  
  453.       if (PullWaitingQueue (pUnitCB, (NPIORB FAR *)&pIORB) != NO_ERROR)
  454.          break;
  455.  
  456.       /*
  457.       ** We've pulled another request from the queue, so build the IORB
  458.       ** for it and chain it to the previous if we've built more than one.
  459.       */
  460.       pUnitCB->NumReqsInProgress++;
  461.       CD_NumReqsInProgress++;
  462.       NumIORBsBuilt++;
  463.  
  464.       ENABLE;
  465.       CallADD(pUnitCB, pIORB);
  466.       DISABLE;
  467.    }
  468.  
  469.    ENABLE;
  470.    POPFLAGS;
  471.  
  472. }
  473.  
  474.  
  475. /****************************************************************************
  476.  *
  477.  * FUNCTION NAME = CallADD
  478.  *
  479.  * DESCRIPTION   = Call the Adapter Driver Entry Point
  480.  *
  481.  *         This function calls the adapter driver entry point with the
  482.  *         specified IORB chain.
  483.  *
  484.  *         VOID CallADD (pUnitCB, pIORB)
  485.  *
  486.  * INPUT         = pUnitCB          - pointer to unit control block
  487.  *                 pIORB            - pointer to IORB chain
  488.  *
  489.  * OUTPUT        = VOID
  490.  *
  491.  * RETURN-NORMAL =
  492.  * RETURN-ERROR  =
  493.  *
  494.  ****************************************************************************/
  495.  
  496. VOID CallADD (pUnitCB, pIORB)
  497.  
  498. NPUNITCB pUnitCB;
  499. NPIORB   pIORB;
  500.  
  501. {
  502.  
  503. /*
  504. ** if (TraceFlags != 0)
  505. **    Trace(TRACE_IORB | TRACE_ENTRY, (PBYTE)pIORB, pUnitCB);
  506. */
  507.  
  508.    /*
  509.    ** If we're issuing a request to a PANSONIC 501 and it's one
  510.    ** one of the vendor unique audio commands, then just turn on
  511.    ** the high bit of the command byte so the command opcode is right.
  512.    */
  513.    if (pUnitCB->DeviceInfo.product_id_code == PANASONIC_501)
  514.    {
  515.       if (  ( ((NPIORB_CDB)pIORB)->CDB.byte_0 >= SCSI_READ_SUB_CHAN) &&
  516.             ( ((NPIORB_CDB)pIORB)->CDB.byte_0 <= SCSI_PAUSE_RESUME) )
  517.       {
  518.          ((NPIORB_CDB)pIORB)->CDB.byte_0 |= 0x80;
  519.       }
  520.    }
  521.  
  522.    /*
  523.    **  If ATAPI command, change CDB command length to 12.
  524.    */
  525.  
  526.    if ( (pUnitCB->DeviceInfo.interface_type == INTERFACE_ATAPI) &&
  527.         (pIORB->CommandCode == IOCC_ADAPTER_PASSTHRU) )
  528.    {
  529.       ((NPIORB_CDB)pIORB)->apt.ControllerCmdLen = ATAPI_CDB_LENGTH;
  530.  
  531.       if ((( (NPIORB_CDB)pIORB)->CDB.byte_0 == ATAPI_CHANGER_LOAD))  //SD@135221
  532.         {                                                            //SD@135221
  533.         if(pUnitCB->DeviceInfo.product_id_code==TORISAN_C3G)         //SD@135221
  534.           {                                                          //SD@135221
  535.           ((NPIORB_CDB)pIORB)->CDB.byte_0 = SANYO_ATAPI_CHANGER_LOAD;//SD@135221
  536.           } /* endif */                                              //SD@135221
  537.         }                                                            //SD@135221
  538.    }
  539.  
  540.    /*
  541.    **  Call the adapter device driver.
  542.    */
  543.  
  544.    (pUnitCB->AdapterDriverEP) ((PVOID) pIORB);
  545. }
  546.  
  547.  
  548.  
  549.  
  550. /****************************************************************************
  551.  *
  552.  * FUNCTION NAME = NotifyDoneIORB
  553.  *
  554.  * DESCRIPTION   = Notify routine when IORB is done in ADD
  555.  *
  556.  *   This function is the notification routine called by an Adapter Device
  557.  *   Driver when an IORB is done.  Error status and blocks transferred
  558.  *   are updated in the associated Request Packet or Request List entry.  If
  559.  *   the request is a Strategy-2 Request List Entry, the file system is
  560.  *   notified that the request has completed.  If the request is a
  561.  *   Strategy-1 Request Packet, the thread waiting on the request is woken up.
  562.  *
  563.  *   VOID NotifyDoneIORB (PIORB fpIORB)
  564.  *
  565.  * INPUT         = fpIORB            - far pointer to completed IORB
  566.  *
  567.  * OUTPUT        = VOID
  568.  *
  569.  * RETURN-NORMAL =
  570.  * RETURN-ERROR  =
  571.  *
  572.  ****************************************************************************/
  573.  
  574. VOID _loadds FAR NotifyDoneIORB (fpIORB)
  575.  
  576. PIORB fpIORB;
  577.  
  578. {
  579.    NPUNITCB pUnitCB;
  580.    NPIORB   pIORB;
  581.    USHORT   AwakeCount;
  582.    NPIORB_DMWORK pDMWork;
  583.  
  584.    pIORB = (NPIORB) (OFFSETOF(fpIORB));
  585.    pDMWork = (NPIORB_DMWORK) &(pIORB->DMWorkSpace);
  586.    pUnitCB = (NPUNITCB) pDMWork->pUnitCB;
  587.  
  588.    if(pUnitCB->pParentUnitCB)                           //SD@135221
  589.      {                                                  //SD@135221
  590.      pUnitCB=pUnitCB->pParentUnitCB;                    //SD@135221
  591.      } /* endif */                                      //SD@135221
  592.  
  593.    if (  (pIORB->Status & IORB_ERROR) &&
  594.         !(pIORB->Status & IORB_RECOV_ERROR) )
  595.    {
  596.       /*
  597.       ** If media changed error, then purge the waiting queue
  598.       */
  599.       if (pIORB->ErrorCode == IOERR_MEDIA_CHANGED)
  600.          PurgeWaitingQueue (pUnitCB);
  601.  
  602.       else if (pDMWork->pCoReqIORB != 0)
  603.       {
  604.          if (RemoveWaitingQueue (pUnitCB, pDMWork->pCoReqIORB) == YES)
  605.          {
  606.             pDMWork->pCoReqIORB->Status = IORB_DONE | IORB_ERROR;
  607.             pDMWork->pCoReqIORB->ErrorCode = pIORB->ErrorCode;
  608.             DevHelp_ProcRun((ULONG)pDMWork->pCoReqIORB, &AwakeCount);
  609.          }
  610.       }
  611.    }
  612.  
  613.    if (pDMWork->pCoReqIORB == 0)
  614.       DevHelp_ProcRun((ULONG)pIORB, &AwakeCount);
  615.  
  616.  
  617.    PUSHFLAGS;
  618.    DISABLE;
  619.    pUnitCB->NumReqsInProgress --;
  620.    CD_NumReqsInProgress--;
  621.    POPFLAGS;
  622.  
  623.    SubmitRequestsToADD(pUnitCB);
  624.  
  625. }
  626.  
  627.  
  628. /****************************************************************************
  629.  *
  630.  * FUNCTION NAME = ProcessError
  631.  *
  632.  * DESCRIPTION   = Post process a completed IORB's error code
  633.  *
  634.  *                 USHORT ProcessError (pUnitCB, pIORB)
  635.  *
  636.  * INPUT         = pUnitCB          - pointer to unit control block
  637.  *                 pIORB            - pointer to IORB
  638.  *
  639.  * OUTPUT        = VOID
  640.  *
  641.  * RETURN-NORMAL =
  642.  * RETURN-ERROR  =
  643.  *
  644.  ****************************************************************************/
  645.  
  646. USHORT ProcessError (pUnitCB, pIORB)
  647.  
  648. NPUNITCB pUnitCB;
  649. NPIORB   pIORB;
  650. {
  651.    USHORT RP_Status;
  652.    UCHAR asc,ascq;                                                      /*SD135221*/
  653.  
  654.    RP_Status = STDON;
  655.  
  656.    if (  (pIORB->Status & IORB_ERROR) &&
  657.         !(pIORB->Status & IORB_RECOV_ERROR) )
  658.    {
  659.       RP_Status = MapSenseData(pIORB);
  660.  
  661.       if(pUnitCB->DeviceInfo.Audio.capabilities &                       //SD@135221
  662.          (DCAPS_CARTRIDGE_CHANGER |DCAPS_INDIVIDUAL_CHANGER))           //SD@135221
  663.         {                                                               //SD@135221
  664.         // only ATAPI devices support this flag today                   //SD@135221
  665.         if(pUnitCB->DeviceInfo.Slots.LoadInProgress==FALSE)             //SD@135221
  666.           {                                                             //SD@135221
  667.           if(pUnitCB->DeviceInfo.product_id_code==TORISAN_C3G)          //SD@135221
  668.             {                                                           //SD@135221
  669.             asc=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code;  //SD@135221
  670.             ascq=((NPIORB_CDB)pIORB)->sense_data.additional_sense_code_qualifier;//SD@135221
  671.  
  672.             // if load in progress reported                             //SD@135221
  673.             // disc changing/changed from under us                      //SD@135221
  674.             if( (asc==ASC_UNIT_NOT_READY && ascq==1) )                  //SD@135221
  675.               {                                                         //SD@135221
  676.               // if we have a parent                                    //SD@135221
  677.               if(pUnitCB->pParentUnitCB)                                //SD@135221
  678.                 {                                                       //SD@135221
  679.                 if(!(pUnitCB->DeviceInfo.Audio.capabilities & DCAPS_SINGLE_MODE))//SD@135221
  680.                   {                                                     //SD@135221
  681.                   // mark the current slot unknown                      //SD@135221
  682.                   pUnitCB->pParentUnitCB->DeviceInfo.Slots.Current=0xff;//SD@135221
  683.                   }                                                     //SD@135221
  684.                 } /* endif */                                           //SD@135221
  685.               }                                                         //SD@135221
  686.             }                                                           //SD@135221
  687.           }                                                             //SD@135221
  688.         }                                                               //SD@135221
  689.  
  690.       if (RP_Status == 0)
  691.          (UCHAR) RP_Status = MapIORBError(pIORB->ErrorCode);
  692.  
  693.       RP_Status |= STDON + STERR;
  694.  
  695.       if (RP_Status == STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA)
  696.       {
  697.          pUnitCB->Flags |= UCF_UNCERTAIN_MEDIA;
  698.          pUnitCB->DeviceInfo.Audio.status.paused = FALSE;
  699.          pUnitCB->DeviceInfo.Audio.status.last_start_location.min   = 0;
  700.          pUnitCB->DeviceInfo.Audio.status.last_start_location.sec   = 0;
  701.          pUnitCB->DeviceInfo.Audio.status.last_start_location.frame = 0;
  702.          pUnitCB->DeviceInfo.Audio.status.last_end_location.min     = 0;
  703.          pUnitCB->DeviceInfo.Audio.status.last_end_location.sec     = 0;
  704.          pUnitCB->DeviceInfo.Audio.status.last_end_location.frame   = 0;
  705.  
  706. /*       PurgeWaitingQueue(pUnitCB, ERROR_I24_UNCERTAIN_MEDIA);             */
  707.       }
  708.  
  709.       /*
  710.       ** If a reset condition occurred, then reset lock and volume settings
  711.       */
  712.       if ( (((NPIORB_CDB)pIORB)->sense_data.sense_key == SCSI_SK_UNITATTN) &&
  713.            (((NPIORB_CDB)pIORB)->sense_data.additional_sense_code == ASC_RESET))
  714.       {
  715.          pUnitCB->DeviceInfo.Audio.capabilities &= ~DCAPS_DOOR_LOCKED;
  716.          pUnitCB->DeviceInfo.Audio.channel.input_0  = 0;
  717.          pUnitCB->DeviceInfo.Audio.channel.volume_0 = 0xFF;
  718.          pUnitCB->DeviceInfo.Audio.channel.input_1  = 1;
  719.          pUnitCB->DeviceInfo.Audio.channel.volume_1 = 0xFF;
  720.       }
  721.  
  722.       TraceError( (NPIORB_CDB) pIORB);
  723.    }
  724.    return(RP_Status);
  725. }
  726.  
  727.  
  728. /****************************************************************************
  729.  *
  730.  * FUNCTION NAME = MapSenseData
  731.  *
  732.  * DESCRIPTION   = Maps a SCSI sense data to an ERROR_I24 error code.
  733.  *
  734.  *                 USHORT  MapSenseData (NPIORB IORBErrorCode)
  735.  *
  736.  * INPUT         = IORBError        - IORB error code
  737.  *
  738.  * OUTPUT        = UCHAR            - ERROR_I24 error code
  739.  *
  740.  * RETURN-NORMAL =
  741.  * RETURN-ERROR  =
  742.  *
  743.  ****************************************************************************/
  744.  
  745. typedef struct _ASC_TABLE_ENTRY
  746. {
  747.    UCHAR    additional_sense_code;
  748.    USHORT   I24_ErrorCode;
  749. } ASC_TABLE_ENTRY;
  750.  
  751. typedef struct _SK_TABLE_ENTRY
  752. {
  753.    UCHAR    asc_count;
  754.    USHORT   I24_ErrorCode;
  755. } SK_TABLE_ENTRY;
  756.  
  757.  
  758. USHORT MapSenseData (pIORB)
  759.  
  760. NPIORB pIORB;
  761. {
  762.  
  763.    static ASC_TABLE_ENTRY ASCT_NotRdy[] =
  764.    {
  765.       {ASC_INCOMPATIBLE_CARTRIDGE,  STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  766.       {0xFF,                        STDON + STERR + ERROR_I24_NOT_READY}
  767.    };
  768.  
  769.    static ASC_TABLE_ENTRY ASCT_MediumError[] =
  770.    {
  771.      {ASC_UNRECOVERED_ERROR,      STDON + STERR + ERROR_I24_CRC},
  772.      {ASC_NO_ADDRESS_MARK,        STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  773.      {ASC_SEEK_POSITIONING_ERROR, STDON + STERR + ERROR_I24_SEEK},
  774.      {ASC_DATA_SYNC_ERROR,        STDON + STERR + ERROR_I24_READ_FAULT},
  775.      {ASC_INCOMPATIBLE_CARTRIDGE, STDON + STERR + ERROR_I24_NOT_DOS_DISK},
  776.      {0xFF,                       STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  777.    };
  778.  
  779.    static ASC_TABLE_ENTRY ASCT_HardwareError[] =
  780.    {
  781.       {ASC_SEEK_POSITIONING_ERROR, STDON + STERR + ERROR_I24_SEEK},
  782.    };
  783.  
  784.    static ASC_TABLE_ENTRY ASCT_IllegalRequest[] =
  785.    {
  786.       {ASC_ILLEGAL_MODE_FOR_TRACK, STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  787.       {ASC_ILLEGAL_LBA,            STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  788.       {ASCV_NOT_AUDIO_TRACK,       STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  789.       {ASCV_NOT_DATA_TRACK,        STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  790.       {ASCV_NOT_AUDIO_PLAY_STATE,  STDON + STERR + ERROR_I24_SECTOR_NOT_FOUND},
  791.       {0xFF,                       STDON + STERR + ERROR_I24_INVALID_PARAMETER},
  792.    };
  793.  
  794.    static ASC_TABLE_ENTRY ASCT_UnitAttention[] =
  795.    {
  796.       {ASC_MEDIUM_CHANGED,        STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA},
  797.       {ASC_RESET,                 STDON + STERR + ERROR_I24_GEN_FAILURE},
  798.       {0xFF,                      STDON + STERR + ERROR_I24_UNCERTAIN_MEDIA},
  799.    };
  800.  
  801.    static ASC_TABLE_ENTRY ASCT_BlankCheck[] =
  802.    {
  803.       {ASC_ILLEGAL_MODE_FOR_TRACK,  STDON + STERR + ERROR_I24_BAD_COMMAND},
  804.    };
  805.  
  806.  
  807.    static SK_TABLE_ENTRY SenseKeyTable[] =
  808.    {
  809.      { 0, STDON },                                    /* 0 - NOSENSE     */
  810.      { 0, STDON },                                    /* 1 - RECERR      */
  811. //   { 0, STDON + STERR + ERROR_I24_NOT_READY },      /* 2 - NOTRDY      */
  812.  
  813.      { sizeof(ASCT_NotRdy)/sizeof(ASC_TABLE_ENTRY),
  814.              (USHORT) ASCT_NotRdy },                  /* 2 - NOTRDY      */
  815.  
  816.      { sizeof(ASCT_MediumError)/sizeof(ASC_TABLE_ENTRY),
  817.              (USHORT) ASCT_MediumError },             /* 3 - MEDIUMERR   */
  818.  
  819.      { sizeof(ASCT_HardwareError)/sizeof(ASC_TABLE_ENTRY),
  820.              (USHORT) ASCT_HardwareError },           /* 4 - HARDWAREERR */
  821.  
  822.      { sizeof(ASCT_IllegalRequest)/sizeof(ASC_TABLE_ENTRY),
  823.              (USHORT) ASCT_IllegalRequest },          /* 5 - ILLEGALREQ  */
  824.  
  825.      { sizeof(ASCT_UnitAttention)/sizeof(ASC_TABLE_ENTRY),
  826.              (USHORT) ASCT_UnitAttention },           /* 6 - UNITATTN    */
  827.  
  828.  
  829.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* 7 - DATAPROTECT */
  830.  
  831.  
  832.      { sizeof(ASCT_BlankCheck)/sizeof(ASC_TABLE_ENTRY),
  833.              (USHORT) ASCT_BlankCheck },              /* 8 - BLANKCHK    */
  834.  
  835.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* 9 - Vendor Spec */
  836.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* A - COPYABORT   */
  837.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* B - ABORTEDCMD  */
  838.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* C - EQUAL       */
  839.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* D - VOLOVERFLOW */
  840.      { 0, STDON + STERR + ERROR_I24_GEN_FAILURE},     /* E - MISCOMPARE  */
  841.    };
  842.  
  843.  
  844.  
  845.    UCHAR rc, sense_key, additional_sense_code, asc_count;
  846.    USHORT i;
  847.    ASC_TABLE_ENTRY NEAR *pTable;
  848.  
  849.    rc = 0;
  850.  
  851.    /*
  852.    ** Make sure sense data is available
  853.    */
  854.    if ( (pIORB->Status & IORB_STATUSBLOCK_AVAIL) &&
  855.         ( ((NPSCSI_STATUS_BLOCK)pIORB->pStatusBlock)->Flags &
  856.                                       STATUS_SENSEDATA_VALID)  &&
  857.         ( ((NPIORB_CDB) pIORB)->sense_data.error_code == 0x70 ||
  858.           ((NPIORB_CDB) pIORB)->sense_data.error_code == 0x71) )
  859.    {
  860.       sense_key = ((NPIORB_CDB)pIORB)->sense_data.sense_key;
  861.       additional_sense_code =
  862.                  ((NPIORB_CDB)pIORB)->sense_data.additional_sense_code;
  863.  
  864.       if (sense_key > 0x0E)
  865.          return (STDON + STERR + ERROR_I24_GEN_FAILURE);
  866.  
  867.       asc_count = SenseKeyTable[sense_key].asc_count;
  868.  
  869.       if (asc_count == 0)
  870.          return (SenseKeyTable[sense_key].I24_ErrorCode);
  871.  
  872.       (USHORT) pTable = SenseKeyTable[sense_key].I24_ErrorCode;
  873.  
  874.       for (i = 0; i < asc_count; i++)
  875.          if (pTable[i].additional_sense_code == additional_sense_code)
  876.          {
  877.             return (pTable[i].I24_ErrorCode);
  878.          }
  879.  
  880.       if (pTable[i-1].additional_sense_code == 0xFF)
  881.          return (pTable[i-1].I24_ErrorCode);
  882.  
  883.       return (STDON + STERR + ERROR_I24_GEN_FAILURE);
  884.    }
  885.    return(0);
  886. }
  887.  
  888.  
  889. /****************************************************************************
  890.  *
  891.  * FUNCTION NAME = MapIORBError
  892.  *
  893.  * DESCRIPTION   = Maps an IORB error code to an ERROR_I24 error code.
  894.  *
  895.  *                 UCHAR  MapIORBError (USHORT IORBErrorCode)
  896.  *
  897.  * INPUT         = IORBError        - IORB error code
  898.  *
  899.  * OUTPUT        = UCHAR            - ERROR_I24 error code
  900.  *
  901.  * RETURN-NORMAL =
  902.  * RETURN-ERROR  =
  903.  *
  904.  ****************************************************************************/
  905.  
  906. typedef struct _ERROR_TABLE_ENTRY
  907. {
  908.    USHORT   IORB_ErrorCode;
  909.    UCHAR    I24_ErrorCode;
  910. } ERROR_TABLE_ENTRY;
  911.  
  912.  
  913. UCHAR MapIORBError(IORB_ErrorCode)
  914.  
  915. USHORT IORB_ErrorCode;
  916.  
  917. {
  918.    static ERROR_TABLE_ENTRY ErrorTable[] =
  919.    {
  920.       {IOERR_UNIT_NOT_READY,        ERROR_I24_NOT_READY},
  921.       {IOERR_RBA_ADDRESSING_ERROR,  ERROR_I24_SECTOR_NOT_FOUND},
  922.       {IOERR_RBA_LIMIT,             ERROR_I24_SECTOR_NOT_FOUND},
  923.       {IOERR_RBA_CRC_ERROR,         ERROR_I24_CRC},
  924.       {IOERR_MEDIA_NOT_FORMATTED,   ERROR_I24_SECTOR_NOT_FOUND},
  925.       {IOERR_MEDIA_NOT_SUPPORTED,   ERROR_I24_SECTOR_NOT_FOUND},
  926.       {IOERR_MEDIA_WRITE_PROTECT,   ERROR_I24_WRITE_PROTECT},
  927.       {IOERR_MEDIA_CHANGED,         ERROR_I24_UNCERTAIN_MEDIA},
  928.       {IOERR_MEDIA_NOT_PRESENT,     ERROR_I24_NOT_READY},
  929.       {IOERR_CMD_NOT_SUPPORTED,     ERROR_I24_BAD_COMMAND},
  930.       {IOERR_CMD_SYNTAX,            ERROR_I24_BAD_COMMAND},
  931.       {-1,-1},
  932.    };
  933.  
  934.    USHORT i;
  935.  
  936.    /*
  937.    ** Map the IORB error to the corresponding ERROR_I24 error code
  938.    */
  939.    for (i = 0; ErrorTable[i].IORB_ErrorCode != -1; i++)
  940.      if (ErrorTable[i].IORB_ErrorCode == IORB_ErrorCode)
  941.         return(ErrorTable[i].I24_ErrorCode);
  942.  
  943.    return(ERROR_I24_GEN_FAILURE);
  944. }
  945.  
  946.  
  947. /****************************************************************************
  948.  *
  949.  * FUNCTION NAME = TraceError
  950.  *
  951.  * DESCRIPTION   = Logs an error in the trace buffer
  952.  *
  953.  *                 VOID  TraceError (NPIORB pIORB)
  954.  *
  955.  * INPUT         = pIORB            - pointer to IORB
  956.  *
  957.  * OUTPUT        = VOID
  958.  *
  959.  * RETURN-NORMAL =
  960.  * RETURN-ERROR  =
  961.  *
  962.  ****************************************************************************/
  963.  
  964. VOID TraceError (pIORB)
  965.  
  966. NPIORB_CDB pIORB;
  967.  
  968. {
  969.    USHORT i;
  970.    UCHAR NEAR *pCDB;
  971.    UCHAR NEAR *pSenseData;
  972.  
  973.    pCDB = (UCHAR NEAR *) &pIORB->CDB;
  974.    pSenseData = (UCHAR NEAR *) &pIORB->sense_data;
  975.  
  976.    /*
  977.    ** Only trace adapter passthru commands
  978.    */
  979.    if (pIORB->apt.iorbh.CommandCode == IOCC_ADAPTER_PASSTHRU)
  980.    {
  981.       (USHORT) *pCDTraceHead     = pIORB->apt.iorbh.UnitHandle;
  982.       (USHORT) *(pCDTraceHead+2) = pIORB->apt.iorbh.ErrorCode;
  983.  
  984.       for (i = 0; i < 12; i++)
  985.          *(pCDTraceHead+4+i) = *(pCDB+i);
  986.  
  987.       for (i = 0; i < 16; i++)
  988.          *(pCDTraceHead+16+i) = *(pSenseData+i);
  989.  
  990.       pCDTraceHead += 32;
  991.  
  992.       if (pCDTraceHead >= pCDTraceEnd)
  993.          pCDTraceHead = pCDTraceBuf;
  994.    }
  995. }
  996.  
  997.