home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ddkx86v5.zip / DDKX86 / SRC / DEV / TESTCFG / TCFGSCSI.C < prev    next >
C/C++ Source or Header  |  1995-04-14  |  17KB  |  528 lines

  1. /*DDK*************************************************************************/
  2. /*                                                                           */
  3. /* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
  4. /*                                                                           */
  5. /*    The following IBM OS/2 WARP source code is provided to you solely for  */
  6. /*    the purpose of assisting you in your development of OS/2 WARP device   */
  7. /*    drivers. You may use this code in accordance with the IBM License      */
  8. /*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
  9. /*    Copyright statement may not be removed.                                */
  10. /*                                                                           */
  11. /*****************************************************************************/
  12. /*static char *SCCSID = "@(#)tcfgscsi.c  6.1 92/02/13";*/
  13.  
  14. /*********************************************************************
  15.  *
  16.  *
  17.  *
  18.  *
  19.  *********************************************************************/
  20.  
  21. /*** TCFGSCSI.C - SCSI Inquiry routine for TESTCFG device driver
  22.  *   DESCRIPTION
  23.  *
  24.  *     This file contains the routines for issuing SCSI inquiry
  25.  *     commands.
  26.  *
  27.  *
  28. */
  29. #include "testcfg.h"
  30. #include "IORB.h"
  31. #include "SCSI.h"
  32. #include "devclass.h"
  33. #include "tcfgscsi.h"
  34. #include "tcfgx.h"
  35. #define RMCode SWAPCODE
  36. #include "rmcalls.h"
  37. #include "tcfgex.h"
  38.  
  39.  
  40.  
  41. /*** CFG_SCSI_Inquiry -  Issue SCSI Inquiry for specified device type
  42.  *
  43.  *   This routine is used to issue SCSI INQUIRY command a specified
  44.  *   device type
  45.  *
  46.  *   ENTRY
  47.  *      PREQPACKET rp - pointer to Device driver request packet
  48.  *
  49.  *   EXIT
  50.  *      returns Device Driver Completion Code
  51.  *
  52.  */
  53. USHORT far CFG_SCSI_Inquiry(PREQPACKET rp)
  54. {
  55.  PINQUIRYPARMPACKET  pParm;
  56.  PINQUIRYDATAPACKET  pBuffer;
  57.  
  58.   /* Get and Verify Command Information Field */
  59.   pParm = (PINQUIRYPARMPACKET)rp->s.IOCtl.parameters;
  60.   if(VerifyAccess(pParm,sizeof(PINQUIRYPARMPACKET),VERIFY_READACCESS))
  61.     return(RPDONE | RPERR | ERROR_INVALID_PARAMETER);
  62.  
  63.   if(pParm->CmdWord==0) {
  64.  
  65.     /* Get and Verify Buffer Field */
  66.     pBuffer = (PINQUIRYDATAPACKET)rp->s.IOCtl.buffer;
  67.     if(VerifyAccess(pBuffer,sizeof(INQUIRYDATAPACKET),VERIFY_READWRITEACCESS))
  68.       return(RPDONE | RPERR | ERROR_INVALID_PARAMETER);
  69.  
  70.     Build_UnitCBs(pBuffer,pParm->Dev_Type);
  71.     }
  72.   else
  73.     return(RPDONE | RPERR | ERROR_INVALID_PARAMETER);
  74.  
  75.   return(RPDONE);
  76. }
  77.  
  78.  
  79.  
  80. /********************** START OF SPECIFICATIONS *****************************
  81. *                                                                           *
  82. * SUBROUTINE NAME:  Build_UnitCBs                                           *
  83. *                                                                           *
  84. *                                                                           *
  85. * ENTRY POINT:      Build_UnitCBs                                           *
  86. *                                                                           *
  87. * LINKAGE:          Call Near                                               *
  88. *                                                                           *
  89. * INPUT:                                                                    *
  90. *                                                                           *
  91. * EXIT-NORMAL:      0                                                       *
  92. *                                                                           *
  93. * EXIT-ERROR:       -1                                                      *
  94. *                                                                           *
  95. *                                                                           *
  96. *********************** END OF SPECIFICATIONS *******************************/
  97.  
  98. unsigned near Build_UnitCBs(PINQUIRYDATAPACKET  pBuffer, UCHAR DevType)
  99.  
  100. {
  101.  
  102.   PIORB_CONFIGURATION    pIORBDT;        // ptr to IORB
  103.  
  104.   PADAPTERINFO         pAdapterInfo;      // ptr to AdapterInfo
  105.   PDEVICETABLE         pDeviceTable;      // ptr to Device table
  106.   PUNITINFO            pUnitInfo;         // ptr to UnitInfo
  107.  
  108.  
  109.   USHORT                rc;
  110.   USHORT                i,j,k;
  111.   USHORT                NumDrivers;
  112.   USHORT                DevBus;
  113.  
  114.   /*--------------------------------------------------------------------*/
  115.   /* Get the adapter device tables for each adapter driver and          */
  116.   /* issue SCSI INQUIRY command to each unit                            */
  117.   /*--------------------------------------------------------------------*/
  118.  
  119.   pBuffer->nDevices = 0;
  120.   pDeviceTable = (PDEVICETABLE)&DeviceTableBuffer;
  121.  
  122.   rc = GetDCTable((POINTER) &pDriverTable);
  123.  
  124.   if (!rc)
  125.      {
  126.      /*----------------------------------------------------*/
  127.      /* For each .ADD registered in the DEVICE CLASS TABLE */
  128.      /*----------------------------------------------------*/
  129.  
  130.      NumDrivers = pDriverTable->DCCount;
  131.      for (i= 0; i < NumDrivers; i++)
  132.         {
  133.         pIORBDT   = (PIORB_CONFIGURATION)&ConfigIORB;
  134.  
  135.         pIORBDT->iorbh.Length          = sizeof(IORB_CONFIGURATION);
  136.         pIORBDT->iorbh.CommandCode     = IOCC_CONFIGURATION;
  137.         pIORBDT->iorbh.CommandModifier = IOCM_GET_DEVICE_TABLE;
  138.         pIORBDT->iorbh.Status          = 0;
  139.         pIORBDT->iorbh.ErrorCode       = 0;
  140.         pIORBDT->iorbh.RequestControl  = IORB_ASYNC_POST;
  141.         pIORBDT->iorbh.NotifyAddress   = &IORBPost;
  142.         pIORBDT->pDeviceTable          = pDeviceTable;
  143.         pIORBDT->DeviceTableLen        = MAX_DT_SIZE;
  144.  
  145.         OFFSETOF(DriverEP)   = pDriverTable->DCTableEntries[i].DCOffset;
  146.         SELECTOROF(DriverEP) = pDriverTable->DCTableEntries[i].DCSelector;
  147.  
  148.         ZeroCB((PBYTE)pDeviceTable, MAX_DT_SIZE);
  149.  
  150.         (*DriverEP) ((FARPOINTER)(pIORBDT));
  151.  
  152.  
  153.         PUSHFLAGS;
  154.         DISABLE;
  155.         while ( !( pIORBDT->iorbh.Status & IORB_DONE ) )
  156.            {
  157.            ProcBlock ((ULONG)pIORBDT, -1L, 1);
  158.            DISABLE;                          /* Block does an enable  */
  159.            }
  160.         ENABLE;
  161.         POPFLAGS;
  162.  
  163.         if (!(pIORBDT->iorbh.Status & IORB_ERROR))
  164.            {
  165.            for (j = 0; j < pDeviceTable->TotalAdapters; j++)
  166.               {
  167.               pAdapterInfo =  pDeviceTable->pAdapter[j];
  168.               DevBus = (pAdapterInfo->AdapterDevBus & 0x00ff);
  169.  
  170.  
  171.               if (( DevBus == AI_DEVBUS_SCSI_1) ||
  172.                   ( DevBus == AI_DEVBUS_SCSI_2) ||
  173.                   ( DevBus == AI_DEVBUS_SCSI_3) ||
  174.                   ( DevBus == AI_DEVBUS_NONSCSI_CDROM) ||
  175.                   ((DevBus == AI_DEVBUS_ST506) && (DevType == UIB_TYPE_CDROM)) )
  176.                  {
  177.  
  178.                  for (k = 0; k < pAdapterInfo->AdapterUnits; k++)
  179.                     {
  180.  
  181.                     /* Inquiry only types devices requested               */
  182.                     /* that are not "defective"                           */
  183.  
  184.                     if ((pAdapterInfo->UnitInfo[k].UnitType == DevType) &&
  185.                       !(pAdapterInfo->UnitInfo[k].UnitFlags & UF_DEFECTIVE) )
  186.                        {
  187.                        pUnitInfo = &(pAdapterInfo->UnitInfo[k]);
  188.                        /* Do inquiry  */
  189.                        rc = Do_Inquiry(pUnitInfo, pBuffer, DevBus);
  190.  
  191.                        /* If Error (might not be allocated       */
  192.                        /* but we can't depend on the error code) */
  193.                        if (rc & IORB_ERROR)
  194.                           {
  195.                           /* then allocate it and dos inquiry */
  196.                           rc = Do_AllocDeallocUnit(IOCM_ALLOCATE_UNIT,
  197.                                                    pUnitInfo);
  198.                           /* Skip if allocate fails           */
  199.                           if (!(rc & IORB_ERROR))
  200.                              {
  201.                              rc = Do_Inquiry(pUnitInfo, pBuffer, DevBus);
  202.                              rc = Do_AllocDeallocUnit(IOCM_DEALLOCATE_UNIT,
  203.                                                       pUnitInfo);
  204.                              } /* endif */
  205.                           }
  206.                        }
  207.                     }  /* end unit loop */
  208.                  } /* endif */
  209.               }  /* end adapter loop */
  210.            }
  211.         }  // end driver loop
  212.  
  213.      return(0);
  214.      }
  215.   else
  216.      {
  217.      return(-1);
  218.      }
  219. }
  220.  
  221. /*---------------------------------------------------------------------------
  222. ;
  223. ;** BuildCDB_Inquiry - Setup SCSI Inquiry Command Descriptor Block
  224. ;
  225. ;   This routine builds a SCSI Inquiry CDB.
  226. ;
  227. ;   BuildCDB_Inquiry (PUNITINFO pUnitInfo, PIORB_CDB pIORB)
  228. ;
  229. ;   ENTRY:   pUnitInfo       - pointer to UnitInfo
  230. ;            pIORB           - IORB
  231. ;
  232. ;   RETURN:
  233. ;
  234. ----------------------------------------------------------------------------*/
  235. void near BuildCDB_Inquiry(pUnitInfo, pIORB, DevBus)
  236.  
  237. PUNITINFO    pUnitInfo;
  238. PIORB_CDB  pIORB;                             /* ptr to IORB              */
  239. USHORT     DevBus;
  240. {
  241.  
  242.   struct
  243.   CDB_Inquiry *pCDB;                           /* ptr to CDB               */
  244.  
  245.  
  246.   /* Build a CDB passthru IORB */
  247.  
  248.   BuildIORB_PassthruCDB (pUnitInfo,
  249.                sizeof(INQUIRYDATA),
  250.                (ULONG) (ppDataSeg+(ULONG)((USHORT)&(InquiryData))),
  251.                (PIORB_CDB) pIORB );
  252.  
  253.   if (DevBus == AI_DEVBUS_ST506)
  254.   {
  255.      pIORB->apt.ControllerCmdLen = ATAPI_Cmd_Length;
  256.   }
  257.   else
  258.      pIORB->apt.ControllerCmdLen = sizeof(struct CDB_Inquiry);
  259.  
  260.   pIORB->apt.Flags |= PT_DIRECTION_IN;
  261.  
  262.   /* Setup the CDB */
  263.  
  264.   pCDB = (struct CDB_Inquiry *) &pIORB->CDB;
  265.   pCDB->OpCode = SCSI_INQUIRY;
  266.   pCDB->LUN = pUnitInfo->UnitSCSILUN;
  267.   pCDB->alloc_length = sizeof(INQUIRYDATA);
  268.  
  269. }
  270.  
  271. /*---------------------------------------------------------------------------
  272. ;
  273. ;** BuildIORB_PassthruCDB - Setup a passthru IORB for a CDB
  274. ;
  275. ;   This routine allocates and sets up a CDB passthru IORB
  276. ;
  277. ;   BuildIORB_PassthruCDB (PUNITINFO pUnitInfo, ULONG data_length,
  278. ;                          ULONG ppData, PIORB_CDB pIORB)
  279. ;
  280. ;   ENTRY:   pUnitInfo       - pointer to UnitInfo
  281. ;            data_length     - length of data to transfer
  282. ;            ppData          - physical address of data buffer
  283. ;            pIORB           - pointer to IORB
  284. ;
  285. ;   RETURN:
  286. ;
  287. ----------------------------------------------------------------------------*/
  288.  
  289. void near BuildIORB_PassthruCDB (pUnitInfo, data_length, ppData, pIORB)
  290.  
  291. PUNITINFO       pUnitInfo;
  292. ULONG           data_length;
  293. ULONG           ppData;
  294. PIORB_CDB       pIORB;
  295.  
  296. {
  297.    PIORB_DMWORK pDMWork;
  298.  
  299.  
  300.  
  301.    pDMWork = (PIORB_DMWORK) &(pIORB->apt.iorbh.DMWorkSpace);
  302.  
  303.     pIORB->apt.iorbh.UnitHandle = pUnitInfo->UnitHandle;
  304.     pIORB->apt.iorbh.NotifyAddress = &IORBPost;
  305.  
  306.    /* If data transfer involved, setup the scatter/gather list     */
  307.  
  308.    if (data_length != 0)
  309.    {
  310.       pIORB->apt.cSGList = 1;
  311.       pIORB->apt.pSGList = (FARPOINTER) pIORB;
  312.       OFFSETOF(pIORB->apt.pSGList) = (USHORT) ( &(pDMWork->SGList) );
  313.       pIORB->apt.ppSGLIST =
  314.           (ULONG) (ppDataSeg + (ULONG) ((USHORT) &(pDMWork->SGList)) );
  315.  
  316.       if (ppData == -1)
  317.          pDMWork->SGList.ppXferBuf =
  318.                       (ULONG)(ppDataSeg+(ULONG)((USHORT)&(pIORB->CDB_data)));
  319.       else
  320.          pDMWork->SGList.ppXferBuf = ppData;
  321.  
  322.       pDMWork->SGList.XferBufLen = data_length;
  323.    }
  324.  
  325.    /* Fill in the pointer to the SCSI CDB */
  326.  
  327.    pIORB->apt.pControllerCmd = (FARPOINTER) pIORB;
  328.    OFFSETOF(pIORB->apt.pControllerCmd) = (USHORT) ( &(pIORB->CDB) );
  329.    pIORB->apt.ppSCB =
  330.           (ULONG) (ppDataSeg + (ULONG) ((USHORT) &(pIORB->CDB)) );
  331.    ZeroCB((PBYTE)pIORB->apt.iorbh.ADDWorkSpace, ADD_WORKSPACE_SIZE);
  332.  
  333.  
  334. }
  335.  
  336. /*---------------------------------------------------------------------------
  337. ;
  338. ;** Do_Inquiry  - Do the actual inquiry for one unit
  339. ;
  340. ;   This routine does the acutal inquiry for one unit.
  341. ;
  342. ;   Do_Inquiry (PUNITINFO pUnitInfo, PINQUIRYDATAPACKET  pBuffer);
  343. ;
  344. ;   ENTRY:   pUnitInfo       - pointer to UnitInfo
  345. ;            pBuffer         - pointer to user buffer
  346. ;
  347. ;   RETURN NORMAL : 0
  348. ;
  349. ;   RETURN: IORB.Status
  350. ;
  351. ----------------------------------------------------------------------------*/
  352.  
  353. USHORT near Do_Inquiry(pUnitInfo,pBuffer,DevBus)
  354.   PUNITINFO            pUnitInfo;         // ptr to UnitInfo
  355.   PINQUIRYDATAPACKET  pBuffer;
  356.   USHORT              DevBus;
  357.  
  358. {
  359.   PIORB_CDB              pIORBPT;        // ptr to IORB
  360.  
  361.  
  362.   pIORBPT = &PassthruIORB;
  363.  
  364.   pIORBPT->apt.iorbh.Length  = sizeof(IORB_ADAPTER_PASSTHRU);
  365.   pIORBPT->apt.iorbh.CommandCode    = IOCC_ADAPTER_PASSTHRU;
  366.   pIORBPT->apt.iorbh.CommandModifier= IOCM_EXECUTE_CDB;
  367.   pIORBPT->apt.iorbh.Status         = 0;
  368.   pIORBPT->apt.iorbh.ErrorCode      = 0;
  369.   pIORBPT->apt.iorbh.RequestControl = IORB_ASYNC_POST;
  370.   pIORBPT->apt.iorbh.NotifyAddress  = &IORBPost;
  371.  
  372.   BuildCDB_Inquiry(pUnitInfo, (PIORB_CDB) pIORBPT, DevBus);
  373.  
  374.   ZeroCB((PBYTE)&InquiryData,
  375.            (USHORT) sizeof(INQUIRYDATA));
  376.  
  377.   FilterADDHandle = pUnitInfo->FilterADDHandle;
  378.  
  379.   if ( !FilterADDHandle )
  380.      {
  381.      (*DriverEP)((FARPOINTER)(pIORBPT));
  382.      }
  383.   else
  384.      {
  385.      OFFSETOF(DriverEPF) =
  386.        pDriverTable->DCTableEntries[FilterADDHandle-1].DCOffset;
  387.      SELECTOROF(DriverEPF) =
  388.        pDriverTable->DCTableEntries[FilterADDHandle-1].DCSelector;
  389.  
  390.      (*DriverEPF)((FARPOINTER)(pIORBPT));
  391.      }
  392.  
  393.  
  394.   PUSHFLAGS;
  395.   DISABLE;
  396.   while ( !( pIORBPT->apt.iorbh.Status & IORB_DONE ) )
  397.      {
  398.      ProcBlock ((ULONG)pIORBPT, -1L, 1);
  399.      DISABLE;                 /* Block does an enable  */
  400.      }
  401.   ENABLE;
  402.   POPFLAGS;
  403.  
  404.   if (!( pIORBPT->apt.iorbh.Status & IORB_ERROR))
  405.      {
  406.      /* Copy into buffer then increment nDevices */
  407.  
  408.      BlockCopy((PBYTE)&(pBuffer->InquiryEntry[pBuffer->nDevices]),
  409.                  (PBYTE)&InquiryData,
  410.                  (USHORT) sizeof(INQUIRYDATA)) ;
  411.      pBuffer->nDevices++;
  412.      }
  413.  return(pIORBPT->apt.iorbh.Status);
  414. }
  415.  
  416. /*---------------------------------------------------------------------------
  417. ;
  418. ;** Do_AllocDeallocUnit - Allocate or Deallocate a unit
  419. ;
  420. ;   This routine does allocates one unit or Deallocates one unit
  421. ;
  422. ;   Do_AllocDeallocUnit (USHORT command_modifier,PUNITINFO pUnitInfo)
  423. ;
  424. ;   ENTRY:   command_modifier - either ALLOCATE or DEALLOCATE IORB command
  425. ;            pUnitInfo        - pointer to UnitInfo
  426. ;
  427. ;   RETURN: IORB.Status
  428. ;
  429. ----------------------------------------------------------------------------*/
  430.  
  431. USHORT near Do_AllocDeallocUnit(command_modifier, pUnitInfo)
  432.   USHORT     command_modifier;
  433.   PUNITINFO            pUnitInfo;         // ptr to UnitInfo
  434.  
  435. {
  436.    PIORB_UNIT_CONTROL pIORB;
  437.  
  438.    pIORB = (NPIORB_UNIT_CONTROL)&UnitControlIORB;
  439.  
  440.    BuildIORB_UnitControl (command_modifier,
  441.                           pUnitInfo->UnitHandle);
  442.  
  443.    FilterADDHandle = pUnitInfo->FilterADDHandle;
  444.  
  445.    if ( !FilterADDHandle )
  446.       {
  447.       (*DriverEP) ((FARPOINTER)(pIORB));
  448.       }
  449.    else
  450.       {
  451.       OFFSETOF(DriverEPF) =
  452.            pDriverTable->DCTableEntries[FilterADDHandle-1].DCOffset;
  453.       SELECTOROF(DriverEPF) =
  454.            pDriverTable->DCTableEntries[FilterADDHandle-1].DCSelector;
  455.  
  456.       (*DriverEPF) ((FARPOINTER)(pIORB));
  457.       }
  458.  
  459.   PUSHFLAGS;
  460.   DISABLE;
  461.   while ( !( pIORB->iorbh.Status & IORB_DONE ) )
  462.      {
  463.      ProcBlock ((ULONG)pIORB, -1L, 1);
  464.      DISABLE;                 /* Block does an enable  */
  465.      }
  466.   ENABLE;
  467.   POPFLAGS;
  468.  
  469.  
  470.    return(pIORB->iorbh.Status);
  471. }
  472.  
  473.  
  474. /*---------------------------------------------------------------------------
  475. ;
  476. ;** BuildIORB_UnitControl - Build a Unit Control IORB
  477. ;
  478. ;   This routine build a unit control IORB.
  479. ;
  480. ;   VOID Build_UnitControl(USHORT command_modifier, USHORT unit_handle);
  481. ;
  482. ;   ENTRY:   command_modifier   - IORB command modifier code
  483. ;            unit_handle        - unit handle
  484. ;
  485. ;
  486. ;   RETURN:
  487. ;
  488. ;   NOTES:
  489. ;
  490. ;---------------------------------------------------------------------------*/
  491. void near BuildIORB_UnitControl (command_modifier, unit_handle)
  492.  
  493. USHORT     command_modifier;
  494. USHORT     unit_handle;
  495.  
  496. {
  497.    NPIORB_UNIT_CONTROL pIORB;
  498.  
  499.    pIORB = (NPIORB_UNIT_CONTROL)&UnitControlIORB;
  500.  
  501.    pIORB->iorbh.Length = sizeof(IORB_UNIT_CONTROL);
  502.    pIORB->iorbh.CommandCode = IOCC_UNIT_CONTROL;
  503.    pIORB->iorbh.CommandModifier = command_modifier;
  504.    pIORB->iorbh.Status = 0;
  505.    pIORB->iorbh.ErrorCode = 0;
  506.    pIORB->iorbh.UnitHandle = unit_handle;
  507.    pIORB->iorbh.RequestControl = IORB_ASYNC_POST;
  508.    pIORB->iorbh.NotifyAddress = &IORBPost;
  509.    pIORB->Flags = 0;
  510.  
  511.    pIORB->pUnitInfo = 0;
  512.    pIORB->UnitInfoLen = 0;
  513.    ZeroCB((PBYTE)pIORB->iorbh.ADDWorkSpace, ADD_WORKSPACE_SIZE);
  514. }
  515.  
  516.  
  517. /* Dummy notification callout for ADDs */
  518.  
  519. void _loadds far IORBPost(PIORBH pIORB)
  520. {
  521.    USHORT   AwakeCount;
  522.  
  523.    ProcRun((ULONG)pIORB, &AwakeCount);
  524.    return;
  525.  
  526. }
  527.  
  528.