home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cdrom.zip / DDK / BASE / SRC / DEV / DASD / CDROM / NEC / neiorb1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-18  |  16.3 KB  |  480 lines

  1. /**************************************************************************
  2.  *
  3.  * SOURCE FILE NAME = NEIORB1.C
  4.  *
  5.  * DESCRIPTIVE NAME = IORB processor for CD-ROM NEC filter drivers
  6.  *
  7.  * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
  8.  *             LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
  9.  *             REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
  10.  *             RESTRICTED MATERIALS OF IBM
  11.  *             IBM CONFIDENTIAL
  12.  *
  13.  * VERSION = V2.0
  14.  *
  15.  * DATE
  16.  *
  17.  * DESCRIPTION
  18.  *
  19.  *
  20.  * FUNCTIONS   Filters SCSI-2 Command Descriptor Blocks and routes
  21.  *             them to the vendor unique filter routines.
  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.  *  mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
  40.  ****************************************************************************/
  41.  
  42. #include "flthdr.h"
  43.  
  44. USHORT  FilterRequest (PIORB);
  45. USHORT  Filter_ReadCapacity (PIORB_CDB);
  46. USHORT  Filter_TestUnitReady (PIORB_CDB);
  47. VOID    ProcessNextState (PIORB_CDB, USHORT);
  48. VOID    _loadds FAR Filter_NotifyDoneIORB (PIORB_CDB);
  49. VOID    NEC_Sense_Fix (PIORB_CDB);
  50.  
  51. /****************************************************************************
  52.  *
  53.  * FUNCTION NAME = Filter_IORB
  54.  *
  55.  * DESCRIPTION   = Filters IORB Requests from OS2CROM.DMD
  56.  *
  57.  * INPUT         = pIORB           - pointer to IORB
  58.  *
  59.  * OUTPUT        = NONE
  60.  *
  61.  * RETURN-NORMAL = NONE
  62.  * RETURN-ERROR  = NONE
  63.  *
  64.  ****************************************************************************/
  65.  
  66. VOID _loadds FAR Filter_IORB (pIORB)
  67.  
  68. PIORB pIORB;
  69. {
  70.    USHORT action_code;
  71.    NPUNITCB pUnitCB;
  72.    USHORT (NEAR *pRoutine)(PIORB_CDB);
  73.    PIORB_FLTWORK pFilter_workspace;
  74.  
  75.    /*
  76.    ** Handle the Get Device Table call.  Since we are just filtering
  77.    ** requests, return a table with no unit info.
  78.    */
  79.    if (pIORB->CommandCode == IOCC_CONFIGURATION)
  80.    {
  81.       if (pIORB->CommandModifier == IOCM_GET_DEVICE_TABLE)
  82.       {
  83.         ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDLevelMajor = 1;
  84.         ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDLevelMinor = 0;
  85.         ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->ADDHandle = FilterADDHandle;
  86.         ((PIORB_CONFIGURATION)pIORB)->pDeviceTable->TotalAdapters = 0;
  87.       }
  88.  
  89.       pIORB->Status = IORB_DONE;
  90.       pIORB->ErrorCode = 0;
  91.       if (pIORB->RequestControl & IORB_ASYNC_POST)
  92.          (pIORB->NotifyAddress) ( (PIORB) pIORB);
  93.       return;
  94.    }
  95.  
  96.  
  97.    if (pIORB->UnitHandle >= NumCDROMDrives)
  98.    {
  99.       pIORB->Status = IORB_DONE + IORB_ERROR;
  100.       pIORB->ErrorCode = IOERR_UNIT_NOT_ALLOCATED;
  101.       if (pIORB->RequestControl & IORB_ASYNC_POST)
  102.          (pIORB->NotifyAddress) ( (PIORB) pIORB);
  103.       return;
  104.    }
  105.  
  106.  
  107.    /* Replace unit handle for filter with unit handle for the ADD */
  108.  
  109.    pUnitCB = &UnitCBTable[pIORB->UnitHandle];
  110.    pIORB->UnitHandle = pUnitCB->ADDUnitHandle;
  111.  
  112.    if ( ( (USHORT) pRoutine = FilterRequest (pIORB)) != 0)
  113.    {
  114.       pFilter_workspace = (PIORB_FLTWORK) ((PIORB_CDB)pIORB)->filter_workspace;
  115.  
  116.       pFilter_workspace->CDM_NotifyAddress = pIORB->NotifyAddress;
  117.       pFilter_workspace->pUnitCB = pUnitCB;
  118.  
  119.       action_code = (pRoutine) ( (PIORB_CDB) pIORB);
  120.       if ( ( pUnitCB->product_id[6] == '2' ) ||
  121.            ( pUnitCB->product_id[12] == ' ' ) )
  122.       {
  123.          NEC_Sense_Fix ( (PIORB_CDB) pIORB);
  124.       }
  125.       ProcessNextState ( (PIORB_CDB) pIORB, action_code);
  126.       return;
  127.    }
  128.    else            /* Call the ADD for any requests which aren't filtered.    */
  129.    {
  130.       (pUnitCB->AdapterDriverEP) (pIORB);
  131.       return;
  132.    }
  133. }
  134.  
  135. /****************************************************************************
  136.  *
  137.  * FUNCTION NAME = FilterRequest
  138.  *
  139.  * DESCRIPTION   = See if this request should be filtered
  140.  *
  141.  * INPUT         = pIORB           - pointer to IORB
  142.  *
  143.  * OUTPUT        =
  144.  *
  145.  * RETURN-NORMAL =
  146.  * RETURN-ERROR  =
  147.  *
  148.  ****************************************************************************/
  149.  
  150. USHORT FilterRequest (pIORB)
  151.  
  152. PIORB pIORB;
  153. {
  154.    USHORT (NEAR *SCSI_Group0_Table[])() =
  155.    {
  156.        { Filter_TestUnitReady       },      /*  0x00 - Test Unit Ready        */
  157.        { 0                          },      /*  0x01 - Rezero Unit            */
  158.        { 0                          },      /*  0x02 -                        */
  159.        { 0                          },      /*  0x03 - Request Sense          */
  160.        { 0                          },      /*  0x04 -                        */
  161.        { 0                          },      /*  0x05 -                        */
  162.        { 0                          },      /*  0x06 -                        */
  163.        { 0                          },      /*  0x07 -                        */
  164.        { 0                          },      /*  0x08 - Read (6)               */
  165.        { 0                          },      /*  0x09 -                        */
  166.        { 0                          },      /*  0x0A - Write (6)              */
  167.        { Filter_Seek_6              },      /*  0x0B - Seek (6)               */
  168.        { 0                          },      /*  0x0C -                        */
  169.        { 0                          },      /*  0x0D -                        */
  170.        { 0                          },      /*  0x0E -                        */
  171.        { 0                          },      /*  0x0F -                        */
  172.        { 0                          },      /*  0x10 -                        */
  173.        { 0                          },      /*  0x11 -                        */
  174.        { 0                          },      /*  0x12 -  Inquiry               */
  175.        { 0                          },      /*  0x13 -                        */
  176.        { 0                          },      /*  0x14 -                        */
  177.        { Filter_ModeSelect          },      /*  0x15 -  Mode Select (6)       */
  178.        { 0                          },      /*  0x16 -  Reserve               */
  179.        { 0                          },      /*  0x17 -  Release               */
  180.        { 0                          },      /*  0x18 -                        */
  181.        { 0                          },      /*  0x19 -                        */
  182.        { 0                          },      /*  0x1A -  Mode Sense            */
  183.        { Filter_StartStopUnit       },      /*  0x1B -  Start/Stop Unit       */
  184.        { 0                          },      /*  0x1C -  Receive Diagnostic    */
  185.        { 0                          },      /*  0x1D -  Send Diagnostic       */
  186.        { Filter_PreventAllowRemoval },      /*  0x1E -  Prevent/Allow Removal */
  187.        { 0                          },      /*  0x1F -                        */
  188.    };
  189.  
  190.    USHORT (NEAR *SCSI_Group1_Table[])() =
  191.    {
  192.        { 0                          },      /*  0x20 -                        */
  193.        { 0                          },      /*  0x21 -                        */
  194.        { 0                          },      /*  0x22 -                        */
  195.        { 0                          },      /*  0x23 -                        */
  196.        { 0                          },      /*  0x24 -                        */
  197.        { Filter_ReadCapacity        },      /*  0x25 - Read Capacity          */
  198.        { 0                          },      /*  0x26 -                        */
  199.        { 0                          },      /*  0x27 -                        */
  200.        { 0                          },      /*  0x28 - Read (10)              */
  201.        { 0                          },      /*  0x29 -                        */
  202.        { 0                          },      /*  0x2A - Write (10)             */
  203.        { Filter_Seek_10             },      /*  0x2B - Seek (10)              */
  204.        { 0                          },      /*  0x2C -                        */
  205.        { 0                          },      /*  0x2D -                        */
  206.        { 0                          },      /*  0x2E - Write & Verify (10)    */
  207.        { 0                          },      /*  0x2F - Verify (10)            */
  208.    };
  209.  
  210.  
  211.    USHORT (NEAR *SCSI_Group2_Table[])() =
  212.    {
  213.        { 0                          },      /*  0x40 -                        */
  214.        { 0                          },      /*  0x41 -                        */
  215.        { Filter_ReadSubChannel      },      /*  0x42 -  Read sub-channel      */
  216.        { Filter_ReadTOC             },      /*  0x43 -  Read TOC              */
  217.        { Filter_ReadHeader          },      /*  0x44 -  Read Header           */
  218.        { 0                          },      /*  0x45 -  Play Audio (10)       */
  219.        { 0                          },      /*  0x46 -                        */
  220.        { Filter_PlayAudio_MSF       },      /*  0x47 -  Play Audio MSF        */
  221.        { 0                          },      /*  0x48 -  Play Audio Track/Index*/
  222.        { 0                          },      /*  0x49 -  Play Audio Track Rel. */
  223.        { 0                          },      /*  0x4A -                        */
  224.        { Filter_Pause_Resume        },      /*  0x4B -  Pause/Resume          */
  225.        { 0                          },      /*  0x4C -                        */
  226.        { 0                          },      /*  0x4D -                        */
  227.        { 0                          },      /*  0x4E -                        */
  228.        { 0                          },      /*  0x4F -                        */
  229.    };
  230.  
  231.  
  232. /* USHORT (NEAR *SCSI_Group5_Table[])() =                                     */
  233. /* {                                                                          */
  234. /*     { Filter_PlayAudio_12        },          0xA5 -  Play Audio (12)       */
  235. /*     { Filter_CmdError            },          0xA6 -                        */
  236. /*     { Filter_CmdError            },          0xA7 -                        */
  237. /*     { Filter_Read_12             },          0xA8 -  Read (12)             */
  238. /*     { Filter_PlayAudio_Track_12  },          0xA9 -  Play Audio Track (12) */
  239. /* };                                                                         */
  240.  
  241.  
  242.    UCHAR command;
  243.    USHORT (NEAR *pRoutine)();
  244.    struct SCSI_command FAR * pCDB;
  245.  
  246.    pRoutine = 0;
  247.  
  248.    if (pIORB->CommandCode == IOCC_ADAPTER_PASSTHRU &&
  249.        pIORB->CommandModifier == IOCM_EXECUTE_CDB)
  250.    {
  251.       pCDB = (struct SCSI_command FAR *)
  252.              ((PIORB_ADAPTER_PASSTHRU)pIORB)->pControllerCmd;
  253.  
  254.       command = pCDB->byte_0;
  255.  
  256.       if (command >= 0 && command <= 0x1F)
  257.             pRoutine =  SCSI_Group0_Table[command];
  258.       else if (command >= 0x20 && command <= 0x2F)
  259.             pRoutine =  SCSI_Group1_Table[command-0x20];
  260.       else if (command >= 0x40 && command <= 0x4F)
  261.             pRoutine =  SCSI_Group2_Table[command-0x40];
  262. /*    else if
  263. **       (command >= 0xA5 && command <= 0xA9)
  264. **          pRoutine = SCSI_Group5_Table[command-0xA5];
  265. */
  266.       else
  267.          pRoutine = 0;
  268.  
  269.    }
  270.    return((USHORT)pRoutine);
  271. }
  272.  
  273.  
  274. /****************************************************************************
  275.  *
  276.  * FUNCTION NAME = Filter_NotifyDoneIORB
  277.  *
  278.  * DESCRIPTION   = Filter notification routine
  279.  *
  280.  * INPUT         = pIORB           - pointer to IORB
  281.  *
  282.  * OUTPUT        = NONE
  283.  *
  284.  * RETURN-NORMAL = NONE
  285.  *
  286.  * RETURN-ERROR  = NONE
  287.  *
  288.  ****************************************************************************/
  289.  
  290. VOID _loadds FAR Filter_NotifyDoneIORB (pIORB)
  291.  
  292. PIORB_CDB pIORB;
  293.  
  294. {
  295.    USHORT action_code;
  296.    PIORB_FLTWORK pFilter_workspace;
  297.    NPUNITCB pUnitCB;
  298.  
  299.    pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
  300.    pUnitCB = pFilter_workspace->pUnitCB;
  301.  
  302.    if ( ( pUnitCB->product_id[6] == '2' ) ||
  303.         ( pUnitCB->product_id[12] == ' ' ) )
  304.    {
  305.       NEC_Sense_Fix (pIORB);
  306.    }
  307.  
  308.    if ( (pIORB->apt.iorbh.Status & IORB_ERROR) &&
  309.         ( !(pIORB->apt.iorbh.Status & IORB_RECOV_ERROR) )  &&
  310.         ( !(pFilter_workspace->flags & FWF_SKIP_ERROR_CHECK) ) )
  311.    {
  312.       pFilter_workspace->flags = 0;
  313.       action_code = NOTIFY_CDM;
  314.    }
  315.    else
  316.    {
  317.       pFilter_workspace->flags = 0;
  318.       action_code = (pFilter_workspace->completion_address) (pIORB);
  319.    }
  320.    ProcessNextState (pIORB, action_code);
  321.    return;
  322. }
  323.  
  324.  
  325. /****************************************************************************
  326.  *
  327.  * FUNCTION NAME = ProcessNextState
  328.  *
  329.  * DESCRIPTION   = Process next state of the request
  330.  *
  331.  * INPUT         = pIORB           - pointer to IORB
  332.  *
  333.  * OUTPUT        = NONE
  334.  *
  335.  * RETURN-NORMAL = NONE
  336.  *
  337.  * RETURN-ERROR  = NONE
  338.  *
  339.  ****************************************************************************/
  340.  
  341. VOID ProcessNextState (pIORB, action_code)
  342.  
  343. PIORB_CDB  pIORB;
  344. USHORT action_code;
  345. {
  346.  
  347.    NPUNITCB pUnitCB;
  348.    PIORB_FLTWORK pFilter_workspace;
  349.  
  350.    pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
  351.  
  352.    pUnitCB = pFilter_workspace->pUnitCB;
  353.  
  354.    switch (action_code)
  355.    {
  356.       case CALL_ADD_AND_RET:
  357.          pIORB->apt.iorbh.Status = 0;
  358.          pIORB->apt.iorbh.ErrorCode = 0;
  359.          (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
  360.          break;
  361.  
  362.       case CALL_ADD_AND_NOTIFY_FILTER:
  363.          (PVOID) pIORB->apt.iorbh.NotifyAddress=(PVOID) Filter_NotifyDoneIORB;
  364.          pIORB->apt.iorbh.Status = 0;
  365.          pIORB->apt.iorbh.ErrorCode = 0;
  366.          (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
  367.          break;
  368.  
  369.       case CALL_ADD_AND_NOTIFY_CDM:
  370.          pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
  371.          pIORB->apt.iorbh.Status = 0;
  372.          pIORB->apt.iorbh.ErrorCode = 0;
  373.          (pUnitCB->AdapterDriverEP) ((PIORB)pIORB);
  374.          break;
  375.  
  376.       case NOTIFY_CDM:
  377.           pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
  378.           pIORB->apt.iorbh.Status |= IORB_DONE;
  379.           (pIORB->apt.iorbh.NotifyAddress) ( (PIORB) pIORB);
  380.           break;
  381.  
  382.       case NOTIFY_CDM_WITH_ERROR:
  383.          pIORB->apt.iorbh.Status = IORB_DONE + IORB_ERROR;
  384.          pIORB->apt.iorbh.ErrorCode = IOERR_CMD_NOT_SUPPORTED;
  385.          pIORB->apt.iorbh.NotifyAddress = pFilter_workspace->CDM_NotifyAddress;
  386.          (pIORB->apt.iorbh.NotifyAddress) ( (PIORB) pIORB);
  387.          break;
  388.     }
  389. }
  390.  
  391.  
  392. /****************************************************************************
  393.  *
  394.  * FUNCTION NAME = NEC_Sense_Fix
  395.  *
  396.  * DESCRIPTION   = The older family of NEC drives place the Sense Code at byte 9
  397.  *                 instead of byte 12.  This routine will move the Sense Code to
  398.  *                 byte 12 and also set the IORB Error Code to the correct value
  399.  *                 to reflect the valid sense code.
  400.  *
  401.  * INPUT         = pIORB - pointer to IORB
  402.  *
  403.  * OUTPUT        = NONE
  404.  *
  405.  * RETURN-NORMAL = NONE
  406.  *
  407.  * RETURN-ERROR  = NONE
  408.  *
  409.  ****************************************************************************/
  410.  
  411. VOID NEC_Sense_Fix (PIORB_CDB pIORB)
  412. {
  413.    UCHAR sense_key, sense_code;
  414.  
  415.    PIORB_FLTWORK pFilter_workspace;
  416.    NPUNITCB pUnitCB;
  417.  
  418.    pFilter_workspace = (PIORB_FLTWORK) pIORB->filter_workspace;
  419.    pUnitCB = pFilter_workspace->pUnitCB;
  420.  
  421.    if ( pIORB->apt.iorbh.Status & IORB_STATUSBLOCK_AVAIL )
  422.    {
  423.       sense_key  = pIORB->sense_data.sense_key;
  424.       sense_code = pIORB->sense_data.command_specific_info[1];
  425.  
  426.       pIORB->sense_data.additional_sense_code = sense_code;
  427.  
  428.       if ( sense_key )
  429.       {
  430.          switch ( sense_key )
  431.          {
  432.             case SK_NO_SENSE:
  433.                pIORB->apt.iorbh.ErrorCode = IOERR_ADAPTER_REFER_TO_STATUS;
  434.                break;
  435.  
  436.             case SK_UNIT_ATTENTION:
  437.                pIORB->apt.iorbh.ErrorCode = IOERR_MEDIA_CHANGED;
  438.                break;
  439.  
  440.             case SK_NOT_READY:
  441.                pIORB->apt.iorbh.ErrorCode = IOERR_UNIT_NOT_READY;
  442.                break;
  443.  
  444.             case SK_MEDIUM_ERROR:
  445.                pIORB->apt.iorbh.ErrorCode = IOERR_RBA_CRC_ERROR;
  446.                break;
  447.  
  448.             case SK_HARDWARE_ERROR:
  449.                if ( sense_code == ASC_LBA_NOT_FOUND )
  450.                   pIORB->apt.iorbh.ErrorCode = IOERR_RBA_LIMIT;
  451.                else
  452.                   pIORB->apt.iorbh.ErrorCode = IOERR_DEVICE_REQ_NOT_SUPPORTED;
  453.                break;
  454.  
  455.             case SK_DATA_PROTECT:
  456.                pIORB->apt.iorbh.ErrorCode = IOERR_MEDIA_WRITE_PROTECT;
  457.                break;
  458.  
  459.             case SK_VOLUME_OVERFLOW:
  460.                pIORB->apt.iorbh.ErrorCode = IOERR_RBA_LIMIT;
  461.                break;
  462.  
  463.             default:
  464.                pIORB->apt.iorbh.ErrorCode = IOERR_DEVICE_NONSPECIFIC;
  465.                break;
  466.          }
  467.          pIORB->apt.iorbh.Status = IORB_DONE | IORB_ERROR |
  468.                                    IORB_STATUSBLOCK_AVAIL;
  469.       }
  470.       else
  471.       {
  472.          pIORB->apt.iorbh.ErrorCode = 0;
  473.          pIORB->apt.iorbh.Status = IORB_DONE;
  474.       }
  475.    }
  476.  
  477. }
  478.  
  479.  
  480.