/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1992 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 source code is provided to you solely for       */
/*    the purpose of assisting you in your development of OS/2 device        */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Developer Connection Device Driver       */
/*    Source Kit for OS/2. This Copyright statement may not be removed.      */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = OPBSCSI.H
 *
 * DESCRIPTIVE NAME = SCSI Command Descriptor Block definitions for
 *                    the OS/2 Optical Device Mgr.
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION
 *
 *
 * FUNCTIONS
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define ATAPI_CDB_LENGTH        0x0C         /* All ATAPI CDBs are 12 bytes */

/*
**    Optical device specific data structures
*/
union ULONGB  {                           /* to pick apart a long */
        ULONG           dword;
        struct {
                USHORT  word_0;
                USHORT  word_1;
        } ulbwords;
        struct {
                UCHAR   byte_0;
                UCHAR   byte_1;
                UCHAR   byte_2;
                UCHAR   byte_3;
        } ulbytes;
};


union ULONGW  {
        ULONG           dword;
        struct {
                USHORT  word_0;
                USHORT  word_1;
        } ulwords;
};

struct  bytes     {
        UCHAR     byte_0;
        UCHAR     byte_1;
};

union   USHORTB {
        USHORT          word;
        struct {
                UCHAR   byte_0;
                UCHAR   byte_1;
        } usbytes;
};


struct SCSI_command {
        UCHAR   byte_0;
        UCHAR   byte_1;
        UCHAR   byte_2;
        UCHAR   byte_3;
        UCHAR   byte_4;
        UCHAR   byte_5;
        UCHAR   byte_6;
        UCHAR   byte_7;
        UCHAR   byte_8;
        UCHAR   byte_9;
        UCHAR   byte_10;
        UCHAR   byte_11;
        UCHAR   byte_12;
        UCHAR   byte_13;
        UCHAR   byte_14;
        UCHAR   byte_15;
};

/************************************************
 * SCSI Test Unit Ready  (0x00)                 *
 ************************************************/
struct CDB_TestUnitReady {

        UCHAR   OpCode;

        UCHAR   Reserved_1 : 5;
        UCHAR   LUN        : 3;

        UCHAR   Reserved_2;
        UCHAR   Reserved_3;
        UCHAR   Reserved_4;
        UCHAR   Control;
};

/*
** CDB Control Bit Flags
*/
#define CDB_CONTROL_LINK   0x01
#define CDB_CONTROL_FLAG   0x02

/*
** CDB Control Bits - IBM vendor specific field in bits 6 & 7
*/
#define CDB_CONTROL_LBA    0x00
#define CDB_CONTROL_HEADER 0x40
#define CDB_CONTROL_TRACK  0x80



/************************************************
 * SCSI Rezero Unit      (0x01)                 *
 ************************************************/
struct CDB_RezeroUnit {

        UCHAR   OpCode;

        UCHAR   reserved_1 : 5;
        UCHAR   LUN        : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;
        UCHAR   reserved_4;
        UCHAR   control;
};

/************************************************
 * SCSI Request Sense    (0x03)                 *
 ************************************************/
struct CDB_RequestSense {

        UCHAR   OpCode;

        UCHAR   reserved_1 : 5;
        UCHAR   LUN        : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;
        UCHAR   alloc_length;
        UCHAR   control;
};


struct Sense_Data
{
        USHORT  error_code                  : 7;
        USHORT  valid                       : 1;
        USHORT  segment_number              : 8;

        UCHAR   sense_key                   : 4;
        UCHAR   reserved_1                  : 1;
        UCHAR   ILI                         : 1;
        UCHAR   EOM                         : 1;
        UCHAR   filemark                    : 1;

        ULONG   information;
        UCHAR   additional_sense_length;
        UCHAR   command_specific_info[4];
        UCHAR   additional_sense_code;
        UCHAR   additional_sense_code_qualifier;
        UCHAR   FRU_Code;
        UCHAR   sensekey_specific[3];
};

/************************************************
 * SCSI Read(6)          (0x08)                 *
 ************************************************/
struct CDB_Read_6 {

        UCHAR   OpCode;

        UCHAR   LBA_msb     : 5;
        UCHAR   LUN         : 3;

        union
        USHORTB LBA;
        UCHAR   transfer_length;
        UCHAR   control;
};

/************************************************
 * SCSI Read(10)         (0x28)                 *
 ************************************************/
struct CDB_Read_10 {
        UCHAR   OpCode;

        UCHAR   RelAdr      : 1;
        UCHAR   Reserved_1  : 2;
        UCHAR   FUA         : 1;
        UCHAR   DPO         : 1;
        UCHAR   LUN         : 3;

        union
        ULONGB  LBA;
        UCHAR   reserved_2;
        union
        USHORTB transfer_length;
        UCHAR   control;
};

/************************************************
 * SCSI Read(12)         (0xA8)                 *
 ************************************************/
struct CDB_Read_12 {
        UCHAR   OpCode;

        UCHAR   RelAdr      : 1;
        UCHAR   reserved_1  : 7;

        union
        ULONGB  LBA;
        union
        ULONGB  transfer_length;
        UCHAR   reserved_2;
        UCHAR   control;
};

/************************************************
 * SCSI Seek(6)          (0x0B)                 *
 ************************************************/
struct CDB_Seek_6 {

        UCHAR   OpCode;

        UCHAR   LBA_msb     : 5;
        UCHAR   LUN         : 3;

        union
        USHORTB LBA;
        UCHAR   reserved_1;
        UCHAR   control;
};

/************************************************
 * SCSI Seek(10)         (0x2B)                 *
 ************************************************/
struct CDB_Seek_10 {

        UCHAR   OpCode;

        UCHAR   reserved_1  : 5;
        UCHAR   LUN         : 3;

        union
        ULONGB  LBA;
        UCHAR   reserved_2;
        UCHAR   reserved_3;
        UCHAR   reserved_4;
        UCHAR   control;
};

/************************************************
 * SCSI Write(10)        (0x2A)                 *
 ************************************************/
struct CDB_Write_10 {
        UCHAR   OpCode;

        UCHAR   RelAdr      : 1;
        UCHAR   BytChk      : 1;
        UCHAR   EBP         : 1;
        UCHAR   Reserved    : 1;
        UCHAR   DPO         : 1;
        UCHAR   LUN         : 3;

        union
        ULONGB  LBA;
        UCHAR   reserved_2;
        union
        USHORTB transfer_length;
        UCHAR   control;
};
/************************************************
 * SCSI Write(12)        (0xAA)                 *
 ************************************************/
struct CDB_Write_12 {
        UCHAR   OpCode;

        UCHAR   RelAdr      : 1;
        UCHAR   BytChk      : 1;
        UCHAR   EBP         : 1;
        UCHAR   Reserved    : 1;
        UCHAR   DPO         : 1;
        UCHAR   LUN         : 3;

        union
        ULONGB  LBA;
        union
        ULONGB  transfer_length;
        UCHAR   reserved_2;
        UCHAR   control;
};

/************************************************
 * SCSI Inquiry Command  (0x12)                 *
 ************************************************/
struct CDB_Inquiry {

        UCHAR   OpCode;

        UCHAR   EVPD       : 1;
        UCHAR   reserved_1 : 4;
        UCHAR   LUN        : 3;

        UCHAR   page_code;
        UCHAR   reserved_2;
        UCHAR   alloc_length;
        UCHAR   control;
};

struct Inquiry_Data
{
        USHORT  peripheral_device_type      : 8;
        USHORT  device_type_qualifier       : 7;
        USHORT  removable_medium            : 1;
        USHORT  ansi_version                : 3;
        USHORT  ecma_version                : 3;
        USHORT  iso_version                 : 2;
        USHORT  response_data_format        : 4;
        USHORT  bits                        : 4;
        UCHAR   additional_length;
        UCHAR   zeros [3];
        UCHAR   vendor_id [8];
        UCHAR   product_id [16];
        UCHAR   revision_level [4];
        UCHAR   scsi_firmware_date [8];
//      UCHAR   zero;
};

/************************************************
 * SCSI Mode Select Command(6)   (0x15)         *
 ************************************************/

struct CDB_ModeSelect {

        UCHAR   OpCode;

        UCHAR   SP         : 1;
        UCHAR   reserved_1 : 3;
        UCHAR   PF         : 1;
        UCHAR   LUN        : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;
        UCHAR   parm_length;
        UCHAR   control;
};


/************************************************
 * SCSI Mode Select Command(10)     (0x55)      *
 ************************************************/

struct CDB_ModeSelect_10 {

        UCHAR   OpCode;

        UCHAR   SP         : 1;
        UCHAR   reserved_1 : 3;
        UCHAR   PF         : 1;
        UCHAR   LUN        : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;
        UCHAR   reserved_4;
        UCHAR   reserved_5;
        UCHAR   reserved_6;
        union
        USHORTB parm_length;
        UCHAR   control;
};


/*  Mode Parameter Header for 6 byte Mode Select command*/

struct ModeSelectHdr {
        UCHAR     mode_data_length;
        UCHAR     medium_type;
        UCHAR     device_specific_parm;
        UCHAR     block_descriptor_len;
        UCHAR   page_code;
        UCHAR   page_length;
};


/*  Mode Parameter Header for 10 byte Mode Select command */

struct ModeSelectHdr_10 {
        union
        USHORTB   mode_data_length;
        UCHAR     medium_type;
        UCHAR     device_specific_parm;
        UCHAR     reserved_1;
        UCHAR     reserved_2;
        union
        USHORTB   block_descriptor_len;
        UCHAR   page_code;
        UCHAR   page_length;
};




struct BlockDescriptor {
        UCHAR     density_code;
        UCHAR     block_count_0;
        UCHAR     block_count_1;
        UCHAR     block_count_2;
        UCHAR     reserved_1;
        UCHAR     block_length_0;
        UCHAR     block_length_1;
        UCHAR     block_length_2;
};



struct ModeSelectParmList {
        struct ModeSelectHdr          ModeSelectHdr;
};


struct ModeSelectParmList_10 {
        struct ModeSelectHdr_10       ModeSelectHdr;
};


/*
** Mode Page Codes
*/
#define PAGE_0                  0x00
#define PAGE_20                 0x20
#define PAGE_21                 0x21

        // Mode Sense bits
#define FD_BIT                    0x10
#define CL_BIT                    0x08

#define IWV_BIT                 0x20
#define AVRE_BIT                0x10
#define C2MD_BIT                0x08
#define PRVNT_BIT               0x04

#define STANDARD_TRACK_LAYOUT       1
#define MULTI_TRACK_FORMAT          2
#define FORCE_LOW_LEVEL_FORMAT      4
#define MULTI_TRACK_SUCCESSFUL      0x8000
#define MULTI_TRACK_FAILED          0x2000

struct
ModeSelectPage0 {
                    UCHAR   select;
};

struct
ModeSelectPage20 {
                    UCHAR   number_of_groups_msb;
                    UCHAR   number_of_groups_lsb;
                    UCHAR   blocks_per_group_msb;
                    UCHAR   blocks_per_group;
                    UCHAR   blocks_per_group_lsb;
                    UCHAR   spare_blocks_per_group_msb;
                    UCHAR   spare_blocks_per_group;
                    UCHAR   spare_blocks_per_group_lsb;
};

struct
ModeSelectPage21 {
                    UCHAR   laser_timeout_value;
};

union ModePages {
      struct ModeSelectPage0 Page0;
      struct ModeSelectPage20 Page20;
      struct ModeSelectPage21 Page21;
      };

typedef struct {
      struct ModeSelectHdr          ModeSelectHdr;
      union  ModePages              Page;
      } MODEPAGES, near *PMODEPAGES;


/************************************************
 * SCSI Reserve Command (0x16)                  *
 ************************************************/

struct CDB_Reserve {

        UCHAR   OpCode;

        UCHAR   extent     : 1;
        UCHAR   device_ID  : 3;
        UCHAR   ThirdPty   : 1;
        UCHAR   LUN        : 3;

        UCHAR   reservation_ID;
        union
        USHORTB extent_list_length;
        UCHAR   control;
};

/************************************************
 * SCSI Release Command (0x17)                  *
 ************************************************/

struct CDB_Release {

        UCHAR   OpCode;

        UCHAR   extent     : 1;
        UCHAR   device_ID  : 3;
        UCHAR   ThirdPty   : 1;
        UCHAR   LUN        : 3;

        UCHAR   reservation_ID;
        UCHAR   reserved_1;
        UCHAR   reserved_2;
        UCHAR   control;
};


/************************************************
 * SCSI Mode Sense(6)   (0x1A)                  *
 ************************************************/

struct CDB_ModeSense_6 {

        UCHAR   OpCode;

        UCHAR   reserved_1 : 3;
        UCHAR   DBD        : 1;
        UCHAR   reserved_2 : 1;
        UCHAR   LUN        : 3;

        UCHAR   page_code  : 6;
        UCHAR   PC         : 2;

        UCHAR   reserved_3;
//        union
//        USHORTB alloc_length;
        UCHAR   alloc_length;
        UCHAR   control;
};

/************************************************
 * SCSI Mode Sense(10)  (0x5A)                  *
 ************************************************/

struct CDB_ModeSense_10 {

        UCHAR   OpCode;

        UCHAR   reserved_1 : 3;
        UCHAR   DBD        : 1;
        UCHAR   reserved_2 : 1;
        UCHAR   LUN        : 3;

        UCHAR   page_code  : 6;
        UCHAR   PC         : 2;

        UCHAR   reserved_3;
        UCHAR   reserved_4;
        UCHAR   reserved_5;
        UCHAR   reserved_6;

        union
        USHORTB alloc_length;
        UCHAR   control;
};




/* Page Control Field Definitions for Mode Sense */

#define PC_CURRENT     0x00
#define PC_CHANGEABLE  0x01
#define PC_DEFAULT     0x02
#define PC_SAVED       0x03


/************************************************
 * SCSI Start Stop Unit Command (0x1B)          *
 ************************************************/

struct CDB_StartStopUnit {

        UCHAR   OpCode;

        UCHAR   Immed     : 1;
        UCHAR   reserved_1: 4;
        UCHAR   LUN       : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;

        UCHAR   start     : 1;
        UCHAR   LoEj      : 1;
        UCHAR   reserved_4: 6;

        UCHAR   control;
};

/************************************************
 * SCSI Send Diagnostic Command (0x1D)          *
 ************************************************/

struct CDB_SendDiagnostic {

        UCHAR   OpCode;

        UCHAR   UnitOfL    : 1;
        UCHAR   DevOfL     : 1;
        UCHAR   SelfTest   : 1;
        UCHAR   reserved_1 : 1;
        UCHAR   PF         : 1;
        UCHAR   LUN        : 3;

        UCHAR   reserved_2;
        union
        USHORTB parm_length;
        UCHAR   control;
};


/************************************************
 * SCSI Prevent Allow Medium Removal (0x1E)     *
 ************************************************/

struct CDB_PreventAllowRemoval {

        UCHAR   OpCode;

        UCHAR   reserved_1    : 5;
        UCHAR   LUN           : 3;

        UCHAR   reserved_2;
        UCHAR   reserved_3;

        UCHAR   prevent       : 1;
        UCHAR   reserved_4    : 7;

        UCHAR   control;

};

/************************************************
 * SCSI Read Capacity Command (0x25)            *
 ************************************************/

struct CDB_ReadCapacity {

        UCHAR   OpCode;

        UCHAR   RelAdr     : 1;
        UCHAR   reserved_1 : 4;
        UCHAR   LUN        : 3;

        union
        ULONGB  LBA;
        UCHAR   reserved_2;
        UCHAR   reserved_3;

        UCHAR   PMI        : 1;
        UCHAR   reserved_4 : 7;

        UCHAR   control;
};


struct ReadCapacity_Data {
        union
        ULONGB  capacity_LBA;
        union
        ULONGB  capacity_block_length;
};



struct DefectListHeader {
                    UCHAR   reserved;
                    UCHAR   reserved2;
                    UCHAR   list_length_msb;
                    UCHAR   list_length_lsb;
};


struct ModeSenseHeader {
                    UCHAR   length;
                    UCHAR   medium_type;
                    UCHAR   reserved2;
                    UCHAR   block_descriptor_length;
};

struct ModeSensePage0 {
                    UCHAR   page_code;
                    UCHAR   page_length;
                    UCHAR   flags;
};

struct ModeSensePage0MaxSize {
                    struct
                    ModeSenseHeader     header;
                    struct
                    BlockDescriptor     block1;
                    struct
                    BlockDescriptor     block2;
                    struct
                    ModeSensePage0      page0;
};

struct CDB_FormatUnit {
        UCHAR   OpCode;
        union {
              UCHAR  byte;
              struct {
                      UCHAR   DefectListFormat: 3;
                      UCHAR   CmpLst     : 1;
                      UCHAR   FmtData    : 1;
                      UCHAR   LUN        :3;
                      } bits;
              } byte_1;


        UCHAR   VendorSpecific;

        union   USHORTB Interleave;

        UCHAR   control;
};




/***********************************************************************
 * ADAPTER PASS THROUGH IORB           (for IOCC_ADAPTER_PASSTHRU)     *
 ***********************************************************************/
#define FILTER_WORKSPACE_SIZE   24

typedef struct _IORB_CDB           {  /* IOCDB */

  IORB_ADAPTER_PASSTHRU  apt;
  SCSI_STATUS_BLOCK      status_block;
  UCHAR                  pad;
  struct Sense_Data      sense_data;
  struct SCSI_command    CDB;
  UCHAR                  CDB_data[64];
  UCHAR                  filter_workspace[FILTER_WORKSPACE_SIZE];

} IORB_CDB, FAR *PIORB_CDB, *NPIORB_CDB;




