home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cdrom.zip / DDK / BASE / SRC / DEV / DASD / CDROM / ATAPI / atapiosm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-10  |  33.0 KB  |  1,096 lines

  1. /* SCCSID = %W% %E% */
  2. /**************************************************************************
  3.  *
  4.  * SOURCE FILE NAME = ATAPIOSM.C
  5.  *
  6.  * DESCRIPTION : OUTER STATE MACHINE for ATAPI driver
  7.  *
  8.  *
  9.  * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
  10.  *             LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
  11.  *             REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
  12.  *             RESTRICTED MATERIALS OF IBM
  13.  *             IBM CONFIDENTIAL
  14.  *
  15.  * VERSION = 1.0
  16.  *
  17.  * DATE
  18.  *
  19.  * DESCRIPTION :
  20.  *
  21.  * Purpose:
  22.  *
  23.  *
  24.  * CHANGE ACTIVITY =
  25.  *   DATE      FLAG        DEFECT  CHANGE DESCRIPTION
  26.  *   --------  ----------  ------  --------------------------------------
  27.  *   08/22/94  V@93531     93531   1) Suspend/Resume logic passes IRQ handler
  28.  *                                 address. 2) DRQ polling is not valid while
  29.  *                                 BSY bit set.
  30.  *   11/30/95  @V132280            Minor sanity cleanup - removed references
  31.  *                                 to InitComplete.
  32.  *   04/05/96  @V151168            Merged warm dock/swap code.
  33.  *   04/26/98  @V195083            Added Panasonic PD support.
  34.  ***************************************************************************/
  35.  
  36. #define INCL_NOBASEAPI
  37. #define INCL_NOPMAPI
  38. #include "os2.h"
  39. #include "dos.h"
  40. #include "dskinit.h"
  41.  
  42. #include "iorb.h"
  43. #include "addcalls.h"
  44. #include "dhcalls.h"
  45. #include "apmcalls.h"                                               /*@V151168*/
  46.  
  47. #define INCL_INITRP_ONLY
  48. #include "reqpkt.h"
  49.  
  50. #include "scsi.h"
  51. #include "cdbscsi.h"
  52.  
  53. #include "atapicon.h"
  54. #include "atapireg.h"
  55. #include "atapityp.h"
  56. #include "atapiext.h"
  57. #include "atapipro.h"
  58.  
  59. /*
  60. ╔══════════════════════════════════╗
  61. ║                                  ║
  62. ║  StartOSM                        ║
  63. ║                                  ║
  64. ║  Outer State Machine Router      ║
  65. ║                                  ║
  66. ╚══════════════════════════════════╝
  67. */
  68. VOID FAR StartOSM ( NPACB npACB )
  69. {
  70.    DISABLE
  71.  
  72.    npACB->OSMUseCount++;
  73.  
  74.  
  75.    if ( npACB->OSMUseCount == 1 )
  76.    {
  77.       do
  78.       {
  79.          ENABLE
  80.          do
  81.          {
  82.             npACB->OSMFlags &= ~ACBOF_WAITSTATE;
  83.             switch ( npACB->OSMState )
  84.             {
  85.                case ACBOS_START_IORB:
  86.                   StartIORB( npACB );
  87.                   break;
  88.  
  89.                case ACBOS_ISM_COMPLETE :
  90.                   ISMComplete( npACB );
  91.                   break;
  92.  
  93.                case ACBOS_COMPLETE_IORB:
  94.                   CompleteIORB( npACB );
  95.                   break;
  96.  
  97.                case ACBOS_RESUME_COMPLETE:
  98.                   Resume_Complete( npACB );
  99.                   break;
  100.  
  101.                case ACBOS_SUSPEND_COMPLETE:
  102.                   Suspend_Complete( npACB );
  103.                   break;
  104.  
  105.                default:
  106.                   _asm { int 3 }
  107.                   break;
  108.             } /* endswitch */
  109.  
  110.          } while ( !(npACB->OSMFlags & ACBOF_WAITSTATE) ); /* enddo */
  111.  
  112.          DISABLE
  113.  
  114.       } while ( --npACB->OSMUseCount ); /* enddo */
  115.  
  116.    } /* endif */
  117.    ENABLE
  118. }
  119.  
  120. /*
  121. ╔══════════════════════════════════╗
  122. ║                                  ║
  123. ║                                  ║
  124. ║                                  ║
  125. ║                                  ║
  126. ║                                  ║
  127. ╚══════════════════════════════════╝
  128. */
  129. VOID NEAR StartIORB ( NPACB npACB )
  130. {
  131.    NPUCB   npUCB;
  132.    PIORB   pIORB      = npACB->pIORB;
  133.    USHORT  CmdError   = 0;
  134.    USHORT  Command    = 0;
  135.    USHORT  Modifier   = 0;
  136.  
  137.    if (pIORB)
  138.    {
  139.       Command    = pIORB->CommandCode;
  140.       Modifier   = pIORB->CommandModifier;
  141.       npACB->IORBError  = 0;
  142.       npACB->TimerFlags = 0;
  143.  
  144.       // The IORB requested timeout can override the default        /*@V195083*/
  145.       // timeout.                                                   /*@V195083*/
  146.       if (pIORB->Timeout >= MIN_USER_TIMEOUT)                       /*@V195083*/
  147.          npACB->IRQTimeOut = pIORB->Timeout * 1000;                 /*@V195083*/
  148.       else                                                          /*@V195083*/
  149.          npACB->IRQTimeOut = npACB->TimeOut;                        /*@V195083*/
  150.  
  151.       npUCB             = (NPUCB) pIORB->UnitHandle;
  152.       if (!npUCB)
  153.       {
  154.          _asm INT 3
  155.       }
  156.       npACB->npUCB      = npUCB;
  157.       npACB->UnitId     = npACB->npUCB->UnitId;
  158.       npACB->ISMFlags    = 0;
  159.  
  160.       switch ( Command )
  161.       {
  162.          case IOCC_CONFIGURATION:
  163.  
  164.             switch ( Modifier )
  165.             {
  166.                case IOCM_GET_DEVICE_TABLE:
  167.                   GetDeviceTable( npACB );
  168.                   break;
  169.  
  170.                case IOCM_COMPLETE_INIT:
  171.                   ATAPICompleteInit( npACB );                       /*@V151168*/
  172.                   break;
  173.  
  174.                default:
  175.                   CmdError = 1;
  176.  
  177.             } /* endswitch */
  178.             break;
  179.  
  180.          case IOCC_UNIT_CONTROL:
  181.             switch ( Modifier )
  182.             {
  183.                case IOCM_ALLOCATE_UNIT:
  184.                   AllocateUnit( npACB );
  185.                   break;
  186.  
  187.                case IOCM_DEALLOCATE_UNIT:
  188.                   DeallocateUnit( npACB );
  189.                   break;
  190.  
  191.                case IOCM_CHANGE_UNITINFO:
  192.                   ChangeUnitInfo( npACB );
  193.                   break;
  194.  
  195.                default:
  196.                   CmdError = 1;
  197.  
  198.             } /* endswitch */
  199.             break;
  200.  
  201.          case IOCC_GEOMETRY:
  202.             switch ( Modifier )
  203.             {
  204.                case IOCM_GET_MEDIA_GEOMETRY:
  205.                   GetMediaGeometry( npACB );
  206.                   break;
  207.  
  208.                case IOCM_SET_MEDIA_GEOMETRY:   /* ┌───────────────────────┐ */
  209.                   CmdError = 1;                /* │ Command Not Supported │ */
  210.                   break;                       /* └───────────────────────┘ */
  211.  
  212.                case IOCM_GET_DEVICE_GEOMETRY:
  213.                   GetDeviceGeometry( npACB );
  214.                   break;
  215.  
  216.                case IOCM_SET_LOGICAL_GEOMETRY: /* ┌───────────────────────┐ */
  217.                   CmdError = 1;                /* │ Command Not Supported │ */
  218.                   break;                       /* └───────────────────────┘ */
  219.  
  220.                default:
  221.                   CmdError = 1;
  222.  
  223.             } /* endswitch */
  224.             break;
  225.  
  226.          case IOCC_EXECUTE_IO:
  227.             switch ( Modifier )
  228.             {
  229.                case IOCM_READ:
  230.                   IORBRead( npACB );
  231.                   break;
  232.  
  233.                case IOCM_READ_VERIFY:          /* ┌────────────────────────┐ */
  234.                case IOCM_READ_PREFETCH:        /* │ Commands Not Supported │ */
  235.                case IOCM_WRITE:                /* └────────────────────────┘ */
  236.                case IOCM_WRITE_VERIFY:
  237.                default:
  238.                   CmdError = 1;
  239.             }
  240.             break;
  241.  
  242.          case IOCC_FORMAT:   /* ┌────────────────────────────────────────────┐ */
  243.             CmdError = 1;    /* │ Format Commands are Not Supported for CDROM│ */
  244.             break;           /* └────────────────────────────────────────────┘ */
  245.  
  246.          case IOCC_UNIT_STATUS:
  247.             switch ( Modifier )
  248.             {
  249.                case IOCM_GET_UNIT_STATUS:
  250.                   GetUnitStatus( npACB );
  251.                   break;
  252.  
  253.                case IOCM_GET_CHANGELINE_STATE:  /* ┌────────────────────────┐ */
  254.                case IOCM_GET_MEDIA_SENSE:       /* │ Commands Not Supported │ */
  255.                   CmdError = 1;                 /* └────────────────────────┘ */
  256.                   break;
  257.  
  258.                case IOCM_GET_LOCK_STATUS:
  259.                   GetLockStatus( npACB );
  260.                   break;
  261.  
  262.                default:
  263.                   CmdError = 1;
  264.             }
  265.             break;
  266.  
  267.          case IOCC_DEVICE_CONTROL:
  268.             switch ( Modifier )
  269.             {
  270.                case IOCM_ABORT:
  271.                   Abort( npACB );
  272.                   break;
  273.  
  274.                case IOCM_RESET:
  275.                   Reset( npACB );
  276.                   break;
  277.  
  278.                case IOCM_SUSPEND:
  279.                   Suspend( npACB );
  280.                   break;
  281.  
  282.                case IOCM_RESUME:
  283.                   Resume( npACB );
  284.                   break;
  285.  
  286.                case IOCM_LOCK_MEDIA:
  287.                   LockMedia( npACB );
  288.                   break;
  289.  
  290.                case IOCM_UNLOCK_MEDIA:
  291.                   UnlockMedia( npACB );
  292.                   break;
  293.  
  294.                case IOCM_EJECT_MEDIA:
  295.                   EjectMedia( npACB );
  296.                   break;
  297.  
  298.                case IOCM_GET_QUEUE_STATUS:
  299.                   GetQueueStatus( npACB );
  300.                   break;
  301.  
  302.                default:
  303.                   CmdError = 1;
  304.  
  305.             } /* endswitch */
  306.             break;
  307.  
  308.          case IOCC_ADAPTER_PASSTHRU:
  309.             switch ( Modifier )
  310.             {
  311.                case IOCM_EXECUTE_ATA:    /* Continue on to Execute CDB */
  312.                   npACB->ISMFlags |= ACBIF_ATA_OPERATION;
  313.  
  314.                case IOCM_EXECUTE_CDB:
  315.                   SetUpXferData( npACB );
  316.                   Execute_CDB( npACB );
  317.                   break;
  318.                                          /* ┌───────────────────────┐ */
  319.                case IOCM_EXECUTE_SCB:    /* │ Command Not Supported │ */
  320.                                          /* └───────────────────────┘ */
  321.                default:
  322.                   CmdError = 1;
  323.  
  324.             } /* endswitch */
  325.             break;
  326.  
  327.          default:
  328.             CmdError = 1;
  329.  
  330.       } /* endswitch */
  331.       if ( CmdError )
  332.       {
  333.          npACB->IORBError = IOERR_CMD_NOT_SUPPORTED;
  334.          npACB->OSMState  = ACBOS_COMPLETE_IORB;
  335.          npACB->OSMFlags  &= ~ACBOF_WAITSTATE;
  336.       }
  337.    }
  338.    else
  339.    {
  340.       /* How did we get here? */
  341.       _asm { INT 3 }
  342.       npACB->OSMFlags |= ACBOF_WAITSTATE;
  343.    }
  344. }
  345.  
  346. /*
  347. ╔══════════════════════════════════╗
  348. ║                                  ║
  349. ║                                  ║
  350. ║                                  ║
  351. ║                                  ║
  352. ║                                  ║
  353. ╚══════════════════════════════════╝
  354. */
  355. VOID NEAR ISMComplete ( NPACB npACB )
  356. {
  357.    UCHAR                    i;
  358.    PSCSI_STATUS_BLOCK       pSCSISB;
  359.    PIORBH                   pIORB;
  360.    UCHAR                    ASC;
  361.    ULONG                    ppExternalSenseDataBuf;
  362.  
  363.    pIORB = npACB->pIORB;
  364.  
  365.    npACB->OSMFlags    &= ~ACBOF_WAITSTATE;
  366.  
  367.    /* is an internal request sense in progress */
  368.    if ( npACB->OSMFlags & ACBOF_SENSE_DATA_ACTIVE )
  369.    {
  370.       npACB->OSMFlags    &= ~ACBOF_SENSE_DATA_ACTIVE;
  371.       npACB->OSMReqFlags &= ~ACBR_SENSE_DATA;
  372.  
  373.       /*-------------------------------------------------------------------*/
  374.       /* if we are putting the sense data in the users buffer, make a copy */
  375.       /* so it can be examined with the debugger                           */
  376.       /*-------------------------------------------------------------------*/
  377.       if ( npACB->pIORB->RequestControl & IORB_REQ_STATUSBLOCK )
  378.       {
  379.          pSCSISB = MAKEP(SELECTOROF(npACB->pIORB),
  380.                                           (NPBYTE) npACB->pIORB->pStatusBlock);
  381.          memcopy( (PBYTE) &SenseDataBuf,
  382.                           MAKEP( SELECTOROF( pSCSISB ),
  383.                                  OFFSETOF  (pSCSISB->SenseData) ),
  384.                           SENSE_DATA_BYTES );
  385.       }
  386.  
  387.       if ( !(npACB->OSMReqFlags & ACBR_RESET))
  388.                  /* pass sense data back to caller if requested */
  389.       {
  390.          pSCSISB = MAKEP(SELECTOROF(npACB->pIORB),
  391.                                           (NPBYTE) npACB->pIORB->pStatusBlock);
  392.  
  393.          if ( npACB->pIORB->pStatusBlock)                           /*@VXXXXXX*/
  394.          {                                                          /*@VXXXXXX*/
  395.             if ( npACB->pIORB->RequestControl & IORB_REQ_STATUSBLOCK )
  396.                pSCSISB->Flags |= STATUS_SENSEDATA_VALID;
  397.  
  398.             ASC = pSCSISB->SenseData->AddSenseCode;
  399.  
  400.             if ( ASC > MaxAddSenseDataEntry )
  401.                npACB->pIORB->ErrorCode = IOERR_ADAPTER_REFER_TO_STATUS;
  402.             else
  403.                npACB->pIORB->ErrorCode = AddSenseDataMap[ASC];
  404.  
  405.             npACB->pIORB->Status    |=  IORB_STATUSBLOCK_AVAIL;     /*@VXXXXXX*/
  406.          }                                                          /*@VXXXXXX*/
  407.  
  408.          npACB->pIORB->Status    |= IORB_ERROR | IORB_DONE;         /*@VXXXXXX*/
  409.          npACB->OSMState  = ACBOS_COMPLETE_IORB;
  410.       }
  411.    }
  412.  
  413.    /* was a reset request successful */
  414.    else if ( npACB->OSMFlags & ACBOF_RESET_ACTIVE )
  415.    {
  416.  
  417.       npACB->npUCB->ReqFlags  &= ~UCBR_RESET;
  418.       npACB->ISMFlags         &= ~ACBIF_ATA_OPERATION;
  419.       npACB->OSMFlags         &= ~ACBOF_RESET_ACTIVE;
  420.  
  421.  
  422.       if ( BSYWAIT(npACB) ) /* successful reset */
  423.       {
  424.          npACB->OSMReqFlags      &= ~ACBR_RESET;
  425.          npACB->OSMState          = ACBOS_START_IORB;
  426.          npACB->IORBStatus        = 0;
  427.          npACB->IORBError         = 0;
  428.          // See comment in CompleteIORB about second retry after    /*@V195083*/
  429.          // error.                                                  /*@V195083*/
  430.          //npACB->pIORB->ErrorCode |= IOERR_DEVICE_RESET;           /*@V195083*/
  431.       }
  432.       else
  433.       {
  434.          npACB->OSMState   = ACBOS_ISM_COMPLETE;
  435.       }
  436.  
  437.    }
  438.  
  439.    /* was there a request for reset */
  440.    else if ( npACB->OSMReqFlags & ACBR_RESET )
  441.    {
  442.       npACB->cResetRequests++;
  443.       cResets++;
  444.  
  445.       /* if over the reset limit, return error */
  446.       if ( npACB->cResetRequests > MAXRESETS )
  447.       {
  448.          npACB->OSMReqFlags &= ~ACBR_RESET;
  449.          pIORB->ErrorCode  = IOERR_DEVICE_NONSPECIFIC;
  450.          pIORB->Status    |= IORB_DONE | IORB_ERROR;
  451.  
  452.          npACB->OSMState   = ACBOS_COMPLETE_IORB;
  453.       }
  454.       /* issue reset request */
  455.       else
  456.       {
  457.          npACB->OSMFlags                       |= ACBOF_RESET_ACTIVE;
  458.          // See CompleteIORB about the second retry after error.           /*@V195083*/
  459.          npACB->OSMFlags                       |= ACBOF_RETRY_AFTER_RESET; /*@V195083*/
  460.          npACB->npUCB->ReqFlags                |= UCBR_RESET;
  461.          npACB->ISMFlags                       |= ACBIF_ATA_OPERATION;
  462.  
  463.          Execute_CDB( npACB );
  464.          npACB->OSMFlags  |= ACBOF_WAITSTATE;
  465.  
  466.       }
  467.    }
  468.  
  469.    /* was there a request for sense data */
  470.    else if ( npACB->OSMReqFlags & ACBR_SENSE_DATA )
  471.    {
  472.  
  473.       npACB->OSMFlags                       |= ACBOF_SENSE_DATA_ACTIVE;
  474.       npACB->npCmdIO                         = &npACB->InternalCmd;
  475.  
  476.       if ( npACB->pIORB->RequestControl & IORB_REQ_STATUSBLOCK )
  477.       {
  478.          pSCSISB = MAKEP(SELECTOROF(npACB->pIORB),
  479.                                           (NPBYTE) npACB->pIORB->pStatusBlock);
  480.  
  481.          npACB->npCmdIO->cXferBytesRemain    = pSCSISB->ReqSenseLen;
  482.          SenseDataSGList.XferBufLen          = pSCSISB->ReqSenseLen;
  483.          ppExternalSenseDataBuf = VirtToPhys ( (PBYTE) pSCSISB->SenseData );
  484.  
  485.          SenseDataSGList.ppXferBuf           = ppExternalSenseDataBuf;
  486.       }
  487.       else
  488.       {
  489.          npACB->npCmdIO->cXferBytesRemain    = SENSE_DATA_BYTES;
  490.          SenseDataSGList.XferBufLen          = SENSE_DATA_BYTES;
  491.          SenseDataSGList.ppXferBuf           = ppSenseDataBuf;
  492.       }
  493.  
  494.       npACB->npCmdIO->IOSGPtrs.cSGList       = 1;
  495.       npACB->npCmdIO->IOSGPtrs.pSGList       = &SenseDataSGList;
  496.       npACB->npCmdIO->IOSGPtrs.Mode          = PORT_TO_SGLIST;
  497.       npACB->npCmdIO->IOSGPtrs.iPortAddress  = npACB->IOPorts[FI_PDATA];
  498.       npACB->npCmdIO->IOSGPtrs.iSGList       = 0;
  499.       npACB->npCmdIO->IOSGPtrs.SGOffset      = 0;
  500.       npACB->npCmdIO->IOSGPtrs.iSGListStart  = 0;
  501.       npACB->npCmdIO->IOSGPtrs.SGOffsetStart = 0;
  502.       npACB->npCmdIO->cXferBytesComplete     = 0;
  503.       for ( i=0; i < SENSE_DATA_BYTES ; i++ )
  504.       {
  505.          npACB->npCmdIO->ATAPIPkt[i]  =  0;
  506.       }
  507.       npACB->npCmdIO->ATAPIPkt[0]  =  SCSI_REQUEST_SENSE;
  508.       // We are building a new request sence.  Make sure we         /*@V195083*/
  509.       // ask the right LUN.                                         /*@V195083*/
  510.       npACB->npCmdIO->ATAPIPkt[1]  =                                       /*@V195083*/
  511.          ((PIORB_ADAPTER_PASSTHRU)npACB->pIORB)->pControllerCmd[1] & 0xE0; /*@V195083*/
  512.       npACB->npCmdIO->ATAPIPkt[4]  =  sizeof(SENSE_DATA);
  513.  
  514.       Execute_CDB( npACB );
  515.       npACB->OSMFlags  |= ACBOF_WAITSTATE;
  516.  
  517.    }
  518.    else
  519.    {
  520.       npACB->OSMState  = ACBOS_COMPLETE_IORB;
  521.    }
  522. }
  523.  
  524. /*
  525. ╔══════════════════════════════════╗
  526. ║                                  ║
  527. ║                                  ║
  528. ║                                  ║
  529. ║                                  ║
  530. ║                                  ║
  531. ╚══════════════════════════════════╝
  532. */
  533. VOID NEAR CompleteIORB ( NPACB npACB )
  534. {
  535.    PIORB    pIORB;
  536.    USHORT   ErrorCode = 0;
  537.    NPUCB    npUCB;
  538.  
  539.    pIORB     = npACB->pIORB;
  540.    npUCB     = npACB->npUCB;
  541.    ErrorCode = npACB->IORBError;
  542.  
  543.    // If we have finished the reset sequence and retried the        /*@V195083*/
  544.    // command, the command will have returned an error (due to      /*@V195083*/
  545.    // the reset) so we must retry the command a second time to      /*@V195083*/
  546.    // actually retry the command                                    /*@V195083*/
  547.                                                                     /*@V195083*/
  548.    if (npACB->OSMFlags & ACBOF_RETRY_AFTER_RESET)                   /*@V195083*/
  549.    {                                                                /*@V195083*/
  550.          npACB->OSMFlags  &= ~ACBOF_RETRY_AFTER_RESET;              /*@V195083*/
  551.          npACB->ISMFlags   = 0;                                     /*@V195083*/
  552.          npACB->npCmdIO    = &npACB->ExternalCmd;                   /*@V195083*/
  553.                                                                     /*@V195083*/
  554.          npACB->IORBStatus        = IORB_RECOV_ERROR;               /*@V195083*/
  555.          npACB->IORBError         = 0;                              /*@V195083*/
  556.          pIORB->ErrorCode         = 0;                              /*@V195083*/
  557.          pIORB->Status            &=~(IORB_ERROR | IORB_DONE);      /*@V195083*/
  558.          pIORB->Status            |= IORB_RECOV_ERROR;              /*@V195083*/
  559.                                                                     /*@V195083*/
  560.          Execute_CDB( npACB );                                      /*@V195083*/
  561.          npACB->OSMFlags  |= ACBOF_WAITSTATE;                       /*@V195083*/
  562.          return;                                                    /*@V195083*/
  563.    }                                                                /*@V195083*/
  564.  
  565.    if ( npACB->TimerFlags )
  566.    {
  567.       ErrorCode = IOERR_UNIT_NOT_READY;
  568.    }
  569.  
  570.    if ( ErrorCode )
  571.    {
  572.       pIORB->ErrorCode = ErrorCode;
  573.       pIORB->Status    |= IORB_ERROR;
  574.    }
  575.  
  576.    pIORB->Status |= IORB_DONE;
  577.  
  578.    npACB->pIORB = 0;
  579.  
  580.    if ( pIORB->RequestControl & IORB_ASYNC_POST )
  581.    {
  582.       if (( npACB->npUCB->Capabilities & UCBC_SPEC_REV_17B)     &&
  583.           ( npACB->npCmdIO->ATAPIPkt[0] == SCSI_MODE_SENSE_10 ) &&
  584.           (( npACB->npCmdIO->ATAPIPkt[2] & REV_17B_PAGE_CODE_MASK)
  585.                                    == REV_17B_PAGE_CAPABILITIES))
  586.       {
  587.          Convert_17B_to_ATAPI( npACB->npCmdIO->IOSGPtrs.pSGList->ppXferBuf );
  588.       }
  589.  
  590.       (*pIORB->NotifyAddress)(pIORB);
  591.    }
  592.  
  593.    DISABLE
  594.  
  595.    if (( npACB->ResourceFlags & ACBRF_SHARED     ) &&
  596.        ( npACB->ResourceFlags & ACBRF_CURR_OWNER ) )
  597.    {
  598.       if ( npACB->pHeadIORB )          /* more stuff to do */
  599.       {
  600.  
  601.          if ( QueryOtherAdd( npACB ) ) /* other add has stuff in queue */
  602.          {
  603.             npACB->OSMState = ACBOS_RESUME_COMPLETE;
  604.             npACB->OSMFlags |= ACBOF_WAITSTATE;
  605.             npACB->ResourceFlags &= ~ACBRF_CURR_OWNER;
  606.             ENABLE
  607.             ResumeOtherAdd( npACB );
  608.          }
  609.          else                          /* other add has empty queue */
  610.          {
  611.             npACB->OSMState = ACBOS_START_IORB;
  612.             if ( NextIORB( npACB ) )
  613.             {
  614.                _asm int 3             /* we said above we had stuff to do
  615.                                          and now we don't ? */
  616.             }
  617.          }
  618.       }
  619.       else                            /* no more work to do */
  620.       {
  621.          npACB->OSMState = ACBOS_RESUME_COMPLETE;
  622.          npACB->OSMFlags |= ACBOF_WAITSTATE;
  623.          npACB->ResourceFlags &= ~ACBRF_CURR_OWNER;                  /*V@93531*/
  624.          ENABLE
  625.          ResumeOtherAdd( npACB );
  626.       }
  627.    }
  628.    else
  629.    {
  630.       npACB->OSMState = ACBOS_START_IORB;
  631.  
  632.       if ( NextIORB( npACB ) )  /* DISABLE is in NextIORB */
  633.       {
  634.          npACB->OSMFlags |= ACBOF_WAITSTATE;
  635.          npACB->OSMFlags &= ~ACBOF_SM_ACTIVE;
  636.       }
  637.    }
  638.    ENABLE
  639. }
  640.  
  641. VOID NEAR Resume_Complete( NPACB npACB )
  642. {
  643.    DISABLE
  644.    npACB->suspended = 1;
  645.    if ( NextIORB( npACB) )
  646.    {
  647.       npACB->OSMState = ACBOS_START_IORB;
  648.       npACB->OSMFlags &= ~ACBOF_SM_ACTIVE;
  649.       npACB->OSMFlags |= ACBOF_WAITSTATE;
  650.    }
  651.    else
  652.    {
  653.       npACB->OSMState = ACBOS_SUSPEND_COMPLETE;
  654.       npACB->OSMFlags |= ACBOF_WAITSTATE;
  655.       ENABLE
  656.  
  657.       SuspendOtherAdd( npACB );
  658.    }
  659. }
  660.  
  661. VOID NEAR Suspend_Complete( NPACB npACB )
  662. {
  663.    UCHAR Data;
  664.  
  665.    DISABLE
  666.    npACB->suspended = 0;
  667.    npACB->OSMState = ACBOS_START_IORB;
  668.    npACB->OSMFlags &= ~ACBOF_WAITSTATE;                              /*V@93531*/
  669.    npACB->ResourceFlags |= ACBRF_CURR_OWNER;                         /*V@93531*/
  670.    ENABLE
  671. }
  672.  
  673. /*
  674. ╔══════════════════════════════════╗
  675. ║                                  ║
  676. ║                                  ║
  677. ║                                  ║
  678. ║                                  ║
  679. ║                                  ║
  680. ╚══════════════════════════════════╝
  681. */
  682. USHORT FAR NextIORB( NPACB npACB )
  683. {
  684.    DISABLE
  685.    if ( npACB->pIORB = npACB->pHeadIORB )
  686.    {
  687.       if ( !(npACB->pHeadIORB = npACB->pIORB->pNxtIORB) )
  688.       {
  689.          npACB->pFootIORB = 0;
  690.       }
  691.    }
  692.  
  693.    return( (npACB->pIORB) ? 0 : 1);
  694.  
  695. }
  696.  
  697. /*
  698. ╔══════════════════════════════════════════════════════════════════════════════╗
  699. ║                        IOCC_CONFIGUARTION Functions                          ║
  700. ╚══════════════════════════════════════════════════════════════════════════════╝
  701.  
  702. ╔══════════════════════════════════╗
  703. ║                                  ║
  704. ║                                  ║
  705. ║                                  ║
  706. ║                                  ║
  707. ║                                  ║
  708. ╚══════════════════════════════════╝
  709. */
  710. VOID NEAR GetDeviceTable( NPACB npACB )
  711. {
  712.  
  713.    PIORB_CONFIGURATION pIORB = (PIORB_CONFIGURATION) npACB->pIORB;
  714.  
  715.    USHORT        RequiredLength;
  716.    USHORT        AdapterIndex;
  717.    USHORT        UnitIndex;
  718.    PADAPTERINFO  pADPT;
  719.    PUNITINFO     pUI0, pUI1;
  720.    PDEVICETABLE  pDT;
  721.    NPACB         npACBP;
  722.  
  723.    RequiredLength = sizeof(DEVICETABLE);
  724.  
  725.    if ( pIORB->DeviceTableLen < RequiredLength )
  726.    {
  727.       pIORB->iorbh.Status   |= IORB_ERROR;
  728.       pIORB->iorbh.ErrorCode = IOERR_CMD_SYNTAX;
  729.    }
  730.    else
  731.    {
  732.       pDT = pIORB->pDeviceTable;
  733.  
  734.       pDT->ADDLevelMajor = ADD_LEVEL_MAJOR;
  735.       pDT->ADDLevelMinor = ADD_LEVEL_MINOR;
  736.       pDT->ADDHandle     = ADDHandle;
  737.       pDT->TotalAdapters = 0;
  738.  
  739.    } /* end else */
  740.  
  741.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  742.  
  743. } /* GetDeviceTable */
  744.  
  745. /*
  746. ╔══════════════════════════════════════════════════════════════════════════════╗
  747. ║                        IOCC_UNIT_CONTROL Functions                           ║
  748. ╚══════════════════════════════════════════════════════════════════════════════╝
  749.  
  750. ╔══════════════════════════════════╗
  751. ║                                  ║
  752. ║                                  ║
  753. ║                                  ║
  754. ║                                  ║
  755. ║                                  ║
  756. ╚══════════════════════════════════╝
  757. */
  758. VOID NEAR AllocateUnit( NPACB npACB )
  759. {
  760.    NPUCB     npUCB;
  761.  
  762.    npUCB = npACB->npUCB;
  763.  
  764.    if ( npUCB->Flags & UCBF_ALLOCATED )
  765.    {
  766.       npACB->IORBError = IOERR_UNIT_ALLOCATED;
  767.    }
  768.    else
  769.    {
  770.       npUCB->Flags |= UCBF_ALLOCATED;
  771.    }
  772.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  773. }
  774.  
  775. /*
  776. ╔══════════════════════════════════╗
  777. ║                                  ║
  778. ║                                  ║
  779. ║                                  ║
  780. ║                                  ║
  781. ║                                  ║
  782. ╚══════════════════════════════════╝
  783. */
  784. VOID NEAR DeallocateUnit( NPACB npACB )
  785. {
  786.    NPUCB      npUCB;
  787.  
  788.    npUCB = npACB->npUCB;
  789.  
  790.    if( !(npUCB->Flags & UCBF_ALLOCATED) )
  791.    {
  792.       npACB->IORBError = IOERR_UNIT_NOT_ALLOCATED;
  793.    }
  794.    else
  795.    {
  796.       npUCB->Flags &= ~UCBF_ALLOCATED;
  797.    }
  798.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  799. }
  800.  
  801. /*
  802. ╔══════════════════════════════════╗
  803. ║                                  ║
  804. ║                                  ║
  805. ║                                  ║
  806. ║                                  ║
  807. ║                                  ║
  808. ╚══════════════════════════════════╝
  809. */
  810. VOID NEAR ChangeUnitInfo( NPACB npACB )
  811. {
  812.    npACB->npUCB->pUnitInfo = ((PIORB_UNIT_CONTROL) npACB->pIORB)->pUnitInfo;
  813.    npACB->OSMState         = ACBOS_COMPLETE_IORB;
  814. }
  815.  
  816. /*
  817. ╔══════════════════════════════════════════════════════════════════════════════╗
  818. ║                          IOCC_GEOMETRY Functions                             ║
  819. ╚══════════════════════════════════════════════════════════════════════════════╝
  820. ╔══════════════════════════════════╗
  821. ║                                  ║
  822. ║                                  ║
  823. ║                                  ║
  824. ║                                  ║
  825. ║                                  ║
  826. ╚══════════════════════════════════╝
  827. */
  828. VOID NEAR GetMediaGeometry( NPACB npACB )
  829. {
  830.  
  831.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  832. }
  833.  
  834. /*
  835. ╔══════════════════════════════════╗
  836. ║                                  ║
  837. ║                                  ║
  838. ║                                  ║
  839. ║                                  ║
  840. ║                                  ║
  841. ╚══════════════════════════════════╝
  842. */
  843. VOID NEAR GetDeviceGeometry( NPACB npACB )
  844. {
  845.  
  846.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  847. }
  848.  
  849. /*
  850. ╔══════════════════════════════════════════════════════════════════════════════╗
  851. ║                         IOCC_EXECUTE_IO Functions                            ║
  852. ╚══════════════════════════════════════════════════════════════════════════════╝
  853. ╔══════════════════════════════════╗
  854. ║                                  ║
  855. ║                                  ║
  856. ║                                  ║
  857. ║                                  ║
  858. ║                                  ║
  859. ╚══════════════════════════════════╝
  860. */
  861. VOID NEAR IORBRead( NPACB npACB )
  862. {
  863.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  864.  
  865. }
  866.  
  867. /*
  868. ╔══════════════════════════════════════════════════════════════════════════════╗
  869. ║                        IOCC_UNIT_STATUS Functions                            ║
  870. ╚══════════════════════════════════════════════════════════════════════════════╝
  871. ╔══════════════════════════════════╗
  872. ║                                  ║
  873. ║                                  ║
  874. ║                                  ║
  875. ║                                  ║
  876. ║                                  ║
  877. ╚══════════════════════════════════╝
  878. */
  879. VOID NEAR GetUnitStatus( NPACB npACB )
  880. {
  881.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  882.  
  883. }
  884.  
  885. /*
  886. ╔══════════════════════════════════╗
  887. ║                                  ║
  888. ║                                  ║
  889. ║                                  ║
  890. ║                                  ║
  891. ║                                  ║
  892. ╚══════════════════════════════════╝
  893. */
  894. VOID NEAR GetLockStatus( NPACB npACB )
  895. {
  896.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  897.  
  898. }
  899.  
  900. /*
  901. ╔══════════════════════════════════════════════════════════════════════════════╗
  902. ║                       IOCC_DEVICE_CONTROL Functions                          ║
  903. ╚══════════════════════════════════════════════════════════════════════════════╝
  904. ╔══════════════════════════════════╗
  905. ║                                  ║
  906. ║                                  ║
  907. ║                                  ║
  908. ║                                  ║
  909. ║                                  ║
  910. ╚══════════════════════════════════╝
  911. */
  912. VOID NEAR Abort( NPACB npACB )
  913. {
  914.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  915.  
  916. }
  917.  
  918. /*
  919. ╔══════════════════════════════════╗
  920. ║                                  ║
  921. ║                                  ║
  922. ║                                  ║
  923. ║                                  ║
  924. ║                                  ║
  925. ╚══════════════════════════════════╝
  926. */
  927. VOID NEAR Reset( NPACB npACB )
  928. {
  929.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  930.  
  931. }
  932.  
  933. /*
  934. ╔══════════════════════════════════╗
  935. ║                                  ║
  936. ║                                  ║
  937. ║                                  ║
  938. ║                                  ║
  939. ║                                  ║
  940. ╚══════════════════════════════════╝
  941. */
  942. VOID NEAR Suspend( NPACB npACB )
  943. {
  944.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  945.  
  946. }
  947.  
  948. /*
  949. ╔══════════════════════════════════╗
  950. ║                                  ║
  951. ║                                  ║
  952. ║                                  ║
  953. ║                                  ║
  954. ║                                  ║
  955. ╚══════════════════════════════════╝
  956. */
  957. VOID NEAR Resume( NPACB npACB )
  958. {
  959.  
  960.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  961. }
  962.  
  963. /*
  964. ╔══════════════════════════════════╗
  965. ║                                  ║
  966. ║                                  ║
  967. ║                                  ║
  968. ║                                  ║
  969. ║                                  ║
  970. ╚══════════════════════════════════╝
  971. */
  972. VOID NEAR LockMedia( NPACB npACB )
  973. {
  974.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  975.  
  976. }
  977.  
  978. /*
  979. ╔══════════════════════════════════╗
  980. ║                                  ║
  981. ║                                  ║
  982. ║                                  ║
  983. ║                                  ║
  984. ║                                  ║
  985. ╚══════════════════════════════════╝
  986. */
  987. VOID NEAR UnlockMedia( NPACB npACB )
  988. {
  989.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  990.  
  991. }
  992.  
  993. /*
  994. ╔══════════════════════════════════╗
  995. ║                                  ║
  996. ║                                  ║
  997. ║                                  ║
  998. ║                                  ║
  999. ║                                  ║
  1000. ╚══════════════════════════════════╝
  1001. */
  1002. VOID NEAR EjectMedia( NPACB npACB )
  1003. {
  1004.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  1005.  
  1006. }
  1007.  
  1008. /*
  1009. ╔══════════════════════════════════╗
  1010. ║                                  ║
  1011. ║                                  ║
  1012. ║                                  ║
  1013. ║                                  ║
  1014. ║                                  ║
  1015. ╚══════════════════════════════════╝
  1016. */
  1017. VOID NEAR GetQueueStatus( NPACB npACB )
  1018. {
  1019.  
  1020.    npACB->OSMState = ACBOS_COMPLETE_IORB;
  1021. }
  1022.  
  1023. /*
  1024. ╔══════════════════════════════════════════════════════════════════════════════╗
  1025. ║                      IOCC_ADAPTER_PASSTHRU Functions                         ║
  1026. ╚══════════════════════════════════════════════════════════════════════════════╝
  1027. /*
  1028. ╔══════════════════════════════════╗
  1029. ║                                  ║
  1030. ║                                  ║
  1031. ║                                  ║
  1032. ║                                  ║
  1033. ║                                  ║
  1034. ╚══════════════════════════════════╝
  1035. */
  1036. VOID NEAR Execute_CDB ( NPACB npACB)
  1037. {
  1038.    npACB->OSMFlags |= ACBOF_WAITSTATE;
  1039.    npACB->OSMState = ACBOS_ISM_COMPLETE;
  1040.    StartOSMRequest( npACB );
  1041. }
  1042.  
  1043. VOID NEAR SetUpXferData( NPACB npACB )
  1044. {
  1045.    PIORB_ADAPTER_PASSTHRU pIORB;
  1046.    UCHAR                  i;
  1047.    ULONG                  cXferBytes;
  1048.    PSCATGATENTRY          pTempSGList;
  1049.  
  1050.    pIORB = (PIORB_ADAPTER_PASSTHRU) npACB->pIORB;
  1051.  
  1052.    for ( i=0 ; i < pIORB->ControllerCmdLen ; i++ )
  1053.    {
  1054.       npACB->npCmdIO->ATAPIPkt[i] = pIORB->pControllerCmd[i];
  1055.    }
  1056.  
  1057.    /*
  1058.    ┌───────────────────────────────────────┐
  1059.    │ determine number of bytes in s/g list │
  1060.    └───────────────────────────────────────┘
  1061.    */
  1062.  
  1063.    cXferBytes = 0;
  1064.    pTempSGList = pIORB->pSGList;
  1065.  
  1066.    for ( i=0; i < pIORB->cSGList ; i++, pTempSGList++)
  1067.    {
  1068.       cXferBytes += pTempSGList->XferBufLen;
  1069.    } /* endfor */
  1070.  
  1071.    npACB->npCmdIO->cXferBytesRemain   = cXferBytes;
  1072.    npACB->npCmdIO->cXferBytesComplete = 0;
  1073.                                        /* Clear SG Pointer Entries */
  1074.    setmem ( (PBYTE)  &npACB->npCmdIO->IOSGPtrs, 0, sizeof (ADD_XFER_IO) );
  1075.  
  1076.    if ( cXferBytes )                   /* Data area is allocated */
  1077.    {
  1078.       npACB->npCmdIO->IOSGPtrs.Mode          = PORT_TO_SGLIST;
  1079.       npACB->npCmdIO->IOSGPtrs.cSGList       = pIORB->cSGList;
  1080.       npACB->npCmdIO->IOSGPtrs.pSGList       = pIORB->pSGList;
  1081.       npACB->npCmdIO->IOSGPtrs.iPortAddress  = npACB->IOPorts[FI_PDATA];
  1082.       npACB->npCmdIO->IOSGPtrs.iSGList       = 0;
  1083.       npACB->npCmdIO->IOSGPtrs.SGOffset      = 0;
  1084.       npACB->npCmdIO->IOSGPtrs.iSGListStart  = 0;
  1085.       npACB->npCmdIO->IOSGPtrs.SGOffsetStart = 0;
  1086.    }
  1087.  
  1088.    if ( npACB->ISMFlags & ACBIF_ATA_OPERATION )
  1089.    {
  1090.       if ( npACB->npUCB->ReqFlags & UCBR_IDENTIFY )
  1091.       {
  1092.          npACB->npCmdIO->IOSGPtrs.Mode = PORT_TO_SGLIST;
  1093.       }
  1094.    }
  1095. }
  1096.