typedef union
{
    struct
    {
        unsigned : 8;
        unsigned m : 8;
        unsigned s : 8;
        unsigned f : 8;
    } msf;
    struct
    {
        unsigned lba3 : 8;
        unsigned lba2 : 8;
        unsigned lba1 : 8;
        unsigned lba0 : 8;
    } lba;
} cd_address;


typedef struct
{
    unsigned error_code : 7;
    unsigned valid : 1;
    unsigned segment_number : 8;
    unsigned sense_key : 4;
    unsigned : 1;
    unsigned ili : 1;
    unsigned eom : 1;
    unsigned filemark : 1;
    unsigned char information[4];
    unsigned additional_sense_length : 8; /* (n-7) */
    unsigned char command_specific_info[4];
    unsigned asc : 8;   /* additional sense code */
    unsigned ascq : 8;  /* additional sense code qualifier */
    unsigned fru_code : 8;
    union
    {
        struct
        {
            unsigned sense_key_specific2 : 7;
            unsigned sksv : 1;
            unsigned sense_key_specific1 : 8;
            unsigned sense_key_specific0 : 8;
        } generic;
        struct
        {
            unsigned bit_pointer : 3;
            unsigned bpv : 1;
            unsigned : 2;
            unsigned c_or_d : 1;
            unsigned sksv : 1;
                     char field_pointer1;
            unsigned char field_pointer0;
        } illegal_request;
        /* etc.. see section 7.14.1 */
        struct
        {
            unsigned : 7;
            unsigned sksv : 1;
                     char actual_retry_count1;
            unsigned char actual_retry_count0;
        } recovered_error; /* or hardware error or medium error */
        struct
        {
            unsigned : 7;
            unsigned sksv : 1;
                     char progress1;
            unsigned char progress0;
        } not_ready;
    } sense_key_specific_value;
} scsi_request_sense_data;

#define SENSE_KEY_NO_SENSE          0x00
#define SENSE_KEY_RECOVERED_ERROR   0x01
#define SENSE_KEY_NOT_READY         0x02
#define SENSE_KEY_MEDIUM_ERROR      0x03
#define SENSE_KEY_HARDWARE_ERROR    0x04
#define SENSE_KEY_ILLEGAL_REQUEST   0x05
#define SENSE_KEY_UNIT_ATTENTION    0x06
#define SENSE_KEY_DATA_PROTECT      0x07
#define SENSE_KEY_BLANK_CHECK       0x08
#define SENSE_KEY_VENDOR_SPECIFIC   0x09
#define SENSE_KEY_COPY_ABORTED      0x0A
#define SENSE_KEY_ABORTED_COMMAND   0x0B
#define SENSE_KEY_EQUAL             0x0C
#define SENSE_KEY_VOLUME_OVERFLOW   0x0D
#define SENSE_KEY_MISCOMPARE        0x0E
#define SENSE_KEY_RESERVED          0x0F

#define STATUS_GOOD                         0x00
#define STATUS_CHECK_CONDITION              0x02
#define STATUS_CONDITION_MET                0x04
#define STATUS_BUSY                         0x08
#define STATUS_INTERMEDIATE                 0x10
#define STATUS_INTERMEDIATE_CONDITION_MET   0x14
#define STATUS_RESERVATION_CONFLICT         0x18
#define STATUS_COMMAND_TERMINATED           0x22
#define STATUS_QUEUE_FULL                   0x24

typedef struct
{
    unsigned device_type : 5;
    unsigned qualifier : 3;

    unsigned modifier : 7;
    unsigned removable : 1;

    unsigned ansi_approved_version : 3;
    unsigned ecma_version : 3;
    unsigned iso_version :  2;

    unsigned response_data_format : 4;
    unsigned : 2;
    unsigned terminate_io_process : 1;
    unsigned asynch_event_notification : 1;

    unsigned additional_length : 8; /* (n-4) ? */
    unsigned : 8;
    unsigned : 8;

    unsigned soft_reset : 1;
    unsigned command_queueing : 1;
    unsigned : 1;
    unsigned linked_command : 1;
    unsigned synch_transfer : 1;
    unsigned wide_bus_16 : 1;
    unsigned wide_bus_32 : 1;
    unsigned relative_addressing : 1;

    unsigned char vendor_id[8];
    unsigned char product_id[16];
    unsigned char product_rev_level[4];
    unsigned char vendor_specific[20];
    unsigned char reserved[40];
} scsi_inquiry_data;

typedef struct
{
    unsigned : 8;
    unsigned audio_status : 8;
    unsigned char data_length1;
    unsigned char data_length0;
    unsigned data_format_code : 8;
    unsigned control : 4;
    unsigned adr : 4;
    unsigned track_number : 8;
    unsigned index_number : 8;
    cd_address absolute_address;
    cd_address track_relative_address;
    unsigned : 7;
    unsigned media_catalog_valid : 1;
    unsigned char media_catalog_number[15];
    unsigned : 7;
    unsigned track_isrc_valid : 1;
    unsigned char track_isrc[15];
} scsi_read_subchan_data;

typedef struct
{
    unsigned : 8;
    unsigned audio_status : 8;
    unsigned char data_length1;
    unsigned char data_length0;
    unsigned data_format_code : 8;
    unsigned control : 4;
    unsigned adr : 4;
    unsigned track_number : 8;
    unsigned index_number : 8;
    cd_address absolute_address;
    cd_address track_relative_address;
} scsi_current_position_data;

typedef struct
{
    unsigned toc_data_length1 : 8;
    unsigned toc_data_length0 : 8;
    unsigned first_track : 8;
    unsigned last_track : 8;
} scsi_read_toc_header_data;

typedef struct
{
    unsigned : 8;
    unsigned control : 4;
    unsigned adr : 4;
    unsigned track_number : 8;
    unsigned : 8;
    cd_address absolute_address;
} scsi_read_toc_track_data;

typedef struct
{
    scsi_read_toc_header_data header;
    scsi_read_toc_track_data  track[100];
} scsi_read_toc_data;

typedef struct
{
    unsigned mode_data_length : 8;
    unsigned medium_type : 8;
    unsigned device_specific_parameter : 8;
    unsigned block_descriptor_length : 8;
} scsi_mode_header_6;

typedef struct
{
    unsigned mode_data_length1 : 8;
    unsigned mode_data_length0 : 8;
    unsigned medium_type : 8;
    unsigned device_specific_parameter : 8;
    unsigned : 8;
    unsigned : 8;
    unsigned block_descriptor_length1 : 8;
    unsigned block_descriptor_length0 : 8;
} scsi_mode_header_10;

typedef struct
{
    unsigned density_code : 8;
    unsigned number_of_blocks2 : 8;
    unsigned number_of_blocks1 : 8;
    unsigned number_of_blocks0 : 8;
    unsigned : 8;
    unsigned block_length2 : 8;
    unsigned block_length1 : 8;
    unsigned block_length0 : 8;
} scsi_mode_block_descriptor;

typedef struct
{
    unsigned page_code : 6;
    unsigned : 1;
    unsigned ps : 1;
    unsigned page_length;
    /* ... mode parameters ... */
    /* unsigned char mode_parameters[]; */
} scsi_mode_page;

typedef struct
{
    unsigned page_code : 6;         /* 0x0e */
    unsigned : 1;
    unsigned ps : 1;
    unsigned parameter_length : 8;  /* 0x0e */
    unsigned : 1;
    unsigned sotc : 1;
    unsigned immediate : 1;
    unsigned : 5;
    unsigned : 8;
    unsigned : 8;
    unsigned format_lbas_per_second: 4;
    unsigned : 3;
    unsigned audio_playback_rate_valid : 1;
    unsigned format_lbas_per_second1: 8;
    unsigned format_lbas_per_second0: 8;
    unsigned port_0_channel_selection : 4;
    unsigned : 4;
    unsigned port_0_volume : 8;
    unsigned port_1_channel_selection : 4;
    unsigned : 4;
    unsigned port_1_volume : 8;
    unsigned port_2_channel_selection : 4;
    unsigned : 4;
    unsigned port_2_volume : 8;
    unsigned port_3_channel_selection : 4;
    unsigned : 4;
    unsigned port_3_volume : 8;
} scsi_param_audio_control;

