[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


11    Programmer-Defined SCSI/CAM Device Drivers

This chapter describes how programmers can use a combination of common data structures and routines provided by Digital and programmer-defined routines and data structures to write their own device drivers for SCSI/CAM peripheral devices. This chapter describes only the programmer-defined data structures and routines. See Chapter 3 for a description of the common data structures and routines.

The chapter also describes how to add a programmer-defined device driver to the S/CA system.


[Return to Library] [Contents] [Previous Chapter] [Next Section] [Next Chapter] [Index] [Help]


11.1    Programmer-Defined SCSI/CAM Data Structures

This section describes the SCSI/CAM peripheral data structures programmers must use if they write their own device drivers. The following data structures are described:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.1    Programmer-Defined Peripheral Device Unit Table

The Peripheral Device Unit Table is an array of SCSI/CAM peripheral device unit elements. The size of the array is the maximum number of possible devices, which is determined by the maximum number of SCSI controllers allowed for the system. The structure is allocated statically and is defined as follows:

typedef struct pdrv_unit_elem {
        PDRV_DEVICE *pu_device;
                           /* Pointer to peripheral device structure */
        u_short pu_opens;  /* Total number of opens against unit */
        u_short pu_config;
                           /* Indicates whether the device type */
                           /* configured at this address */
        u_char  pu_type;   /* Device type - byte 0 from inquiry data */
}    PDRV_UNIT_ELEM;


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.1.1    The pu_device Member

The pu_device field is filled in with a pointer to a CAM-allocated peripheral SCSI device (PDRV_DEVICE) structure when the first call to the ccmn_open_unit routine is issued for a SCSI device that exists.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.1.2    The pu_opens Member

The pu_opens member specifies the total number of opens against the unit.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.1.3    The pu_config Member

The pu_config Indicates whether a device of the specified type is configured at this bus/target/LUN.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.1.4    The pu_type Member

The pu_type member specifies the device type from byte 0 (zero) of the Inquiry data.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.2    Programmer-Defined Peripheral Device Structure

A SCSI/CAM Peripheral Device structure, PDRV_DEVICE, is allocated for each SCSI device that exists in the system. The PDRV_DEVICE structure is defined as follows:

typedef struct pdrv_device {
        PD_LIST pd_active_list;
                         /* Forward active pointer of CCBs */
                         /* which have been sent to the XPT */
        U32  	pd_active_ccb;
                         /* Number of active CCBs on queue */
        U32  	pd_que_depth;
                         /* Tagged queue depth - indicates the */
                         /* maximum number of commands the unit */
                         /* can store internally */
        PD_LIST pd_pend_list;
                         /* Forward active pointer of pending CCBs */
                         /* which have not been sent to the XPT due */
                         /* to a full queue for tagged requests */
        U32  	pd_pend_ccb;
                         /* Number of pending CCBs */
        dev_t   pd_dev;  /* CAM major/minor number */
        u_char  pd_bus;  /* SCSI controller number */
        u_char  pd_target;
                         /* SCSI target id */
        u_char  pd_lun;  /* SCSI target lun */
        u_char  pd_unit; /* Unit number */
        U32     pd_log_unit;
                         /* Logical Unit number */
        U32  	pd_soft_err;
                         /* Number of soft errors */
        U32  	pd_hard_err;
                         /* Number of hard errors */
        u_short pd_soft_err_limit;
                         /* Max no. of soft errors to report */
        u_short pd_hard_err_limit;
                         /* Max no. of hard errors to report */
        U32  	pd_flags;
                         /* Specific to peripheral drivers */
        u_char  pd_state;
                         /* Specific to peripheral drivers - can */
                         /* be used for recovery */
        u_char  pd_abort_cnt;
                         /* Specific to peripheral drivers - can */
                         /* be used for recovery */
        U32  	pd_cam_flags;
                         /* Used to hold the default settings */
                         /* for the cam_flags field in CCBs */
        u_char  pd_tag_action;
                         /* Used to hold the default settings for */
                         /* the cam_tag_action field of the SCSI */
                         /* I/O CCB */
        u_char  pd_dev_inq[INQLEN];
                         /* Inquiry data obtained from GET */
                         /* DEVICE TYPE CCB */
        U32  	pd_ms_index;
                         /* Contains the current index into the */
                         /* Mode Select Table when sending Mode */
                         /* Select data on first open */
        DEV_DESC  *pd_dev_desc;
                         /* Pointer to our device descriptor */
        caddr_t pd_specific;
                         /* Pointer to device specific info */
        u_short pd_spec_size;
                         /* Size of device specific info */
        caddr_t pd_sense_ptr;
                         /* Pointer to the last sense data */
                         /* bytes retrieved from device */
        u_short pd_sense_len;
                         /* Length of last sense data */
        void    (*pd_recov_hand)();
                         /* Specific to peripheral drivers - can */
                         /* be used to point to the recovery */
                         /* handler for the device */
        U32 	pd_read_count;
                         /* Number of reads to device */
        U32 	pd_write_count;
                         /* Number of writes to device */
        U32 	pd_read_bytes;
                         /* Number of bytes read from device */
        U32 	pd_write_bytes;
                         /* Number of bytes written to device */
        dev_t 	pd_bmajor;
                         /* Block major number for loadables */
        dev_t 	pd_cmajor;
                         /* Char major number for loadables */
        BOP_LOCK_STRUCT pd_lk_device;
                         /* SMP lock for the device */
} PDRV_DEVICE

The structure members and their descriptions follow:
Structure Member Description
pd_active_list A pointer to the first CCB on the active queue.
pd_active_ccb The number of CCBs on the active queue.
pd_que_depth The depth of the tagged queue, which is the maximum number of commands that the peripheral driver will send to the SCSI device.
pd_pend_list A pointer to the first CCB on the pending queue.
pd_pend_ccb The number of CCBs on the pending queue.
pd_dev The major/minor device number pair that identifies the bus number, target ID, and LUN associated with this SCSI device.
pd_bus The SCSI target's bus controller number.
pd_target The SCSI target's ID number.
pd_lun The SCSI target's logical unit number.
pd_unit The SCSI device's unit number.
pd_log_unit The logical unit number.
pd_soft_err The number of soft errors reported by each SCSI unit.
pd_hard_err The number of hard errors reported by each SCSI unit.
pd_soft_err_limit The maximum number of soft errors that can be reported by each SCSI unit.
pd_hard_err_limit The maximum number of hard errors that can be reported by each SCSI unit.
pd_flags and pd_state These are specific to SCSI/CAM peripheral device drivers and are used for recovery.
pd_abort_cnt This is specific to SCSI/CAM peripheral device drivers and is used for recovery.
pd_cam_flags This contains the default settings for the cam_flags field in the CAM control block (CCB) header structure. The flags are defined in the /usr/sys/include/io/cam/cam.h file.
pd_tag_action This contains the default settings for the HBA/SIM queue actions field, cam_tag_action, in the SCSI I/O CCB structure. The queue actions are defined in the /usr/sys/include/io/cam/cam.h file.
pd_dev_inq This is inquiry data.
pd_ms_index The current index into the Mode Select Table that is pointed to in the Device Descriptor structure.
pd_dev_desc A pointer to the DEV_DESC structure for the SCSI device.
pd_specific A pointer to a device-specific structure filled in by the ccmn_open_unit routine.
pd_spec_size The size of the device-specific information.
pd_sense_ptr A pointer to the last sense data bytes retrieved from the device.
pd_sense_len The length (in bytes) of the last sense data retrieved from the device.
pd_recov_hand This is specific to SCSI/CAM peripheral device drivers. It can be used to point to the recovery handler for the device.
pd_read_count The number of read operations from the device. Used for performance statistics.
pd_write_count The number of write operations to the device. Used for performance statistics.
pd_read_bytes The total number of bytes read from the device. Used for performance statistics.
pd_write_bytes The total number of bytes written to the device. Used for performance statistics.
pd_bmajor The block device major number for loadable drivers.
pd_cmajor The character device major number for loadable drivers.
pd_lk_device The lock structure.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3    Programmer-Defined Device Descriptor Structure

A Device Descriptor structure entry DEV_DESC must be added to the cam_devdesc_tab for each programmer-defined SCSI device that exists in the system. The file /usr/sys/data/cam_data.c contains examples of entries supplied by Digital. The DEV_DESC structure is defined as follows:

typedef struct dev_desc {
        u_char  dd_pv_name[IDSTRING_SIZE];
                                /* Product ID and vendor string from */
                                /* Inquiry data */
        u_char  dd_length;      /* Length of dd_pv_name string */
        u_char  dd_dev_name[DEV_NAME_SIZE];
                                /* Device name string - see defines */
                                /* in devio.h */
        U32   	dd_device_type; /* Bits 0 - 23 contain the device */
                                /* class, bits 24-31 contain the */
                                /* SCSI device type */
        struct  pt_info *dd_def_partition;
                                /* Default partition sizes - disks */
        U32  	dd_block_size;  /* Block/sector size  */
        U32  	dd_max_record;  /* Maximun transfer size in bytes */
                                /* allowed for the device */
        DENSITY_TBL *dd_density_tbl;
                                /* Pointer to density table - tapes */
        MODESEL_TBL *dd_modesel_tbl;
                                /* Mode select table pointer - used */
                                /* on open and recovery */
        U32  	dd_flags;       /* Option flags (bbr, etc) */
        U32  	dd_scsi_optcmds;/* Optional commands supported */
        U32  	dd_ready_time;
                          /* Time in seconds for powerup dev ready */
        u_short dd_que_depth;   /* Device queue depth for devices */
                                /* which support command queueing */
        u_char  dd_valid;       /* Indicates which data length */
                                /* fields are valid */
        u_char  dd_inq_len;     /* Inquiry data length for device */
        u_char  dd_req_sense_len;
                                /* Request sense data length for */
                                /* this device */
}DEV_DESC;


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.1    The dd_pv_name Member

The dd_pv_name member specifies the product ID and vendor returned string identifying the drive obtained from the Inquiry data. The product ID makes up the first eight characters of the string. The IDSTRING_SIZE constant is defined in the /usr/sys/include/io/cam/pdrv.h file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.2    The dd_length Member

The dd_length member specifies the length of the string associated with the dd_pv_name member. The match is made on the total string returned by the unit.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.3    The dd_dev_name Member

The dd_dev_name member specifies the Digital UNIX device name string, which is defined in the /usr/sys/include/io/common/devio.h file. A generic name of DEV_RZxx should be used for non-Digital disk devices. The following generic names are provided for tapes: DEV_TZQIC, for 1/4-inch cartridge tape units; DEV_TZ9TK, for 9-track tape units; DEV_TZ8MM, for 8-millimeter tape units; DEV_TZRDAT, for RDAT tape units; DEV_TZ3480, for IBM 3480-compatible tape units; and DEV_TZxx, for tape units that do not fit into any of the predefined generic categories.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.4    The dd_device_type Member

The dd_device_type member specifies the device class and device type. Bits 24-31 contain the SCSI device class, for example, ALL_DTYPE_DIRECT, which is defined in the /usr/sys/include/io/cam/scsi_all.h file. The bits 0-23 contain the device subclass, for example, SZ_HARD_DISK, which is defined in the /usr/sys/include/io/cam/pdrv.h file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.5    The dd_def_partition Member

The dd_def_partition specifies a pointer to the default partition sizes for disks, which are defined in the /usr/sys/data/cam_data.c file. Tape devices should define this as sz_null_sizes. Disk devices may use sz_rzxx_sizes, which assumes that the disk has at least 48 Mbytes. The sz_rzxx_sizes should not be modified. If you want to create your own partition table, make an entry for your device in the device descriptor table in the /usr/sys/data/cam_data.c file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.6    The dd_block_size Member

The dd_block_size member specifies the block or sector size of the unit (in bytes) for disks and CD-ROMs. You can obtain the correct number of bytes from the documentation for your device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.7    The dd_max_record Member

The dd_max_record member specifies the maximum number of bytes that can be transferred in one request for raw I/O. Errors result if your system does not have enough physical memory or if the unit cannot handle the size of the transfer specified.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.8    The dd_density_tbl Member

The dd_density_tbl member specifies a pointer to the Density Table structure entry for a tape device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.9    The dd_modesel_tbl Member

The dd_modesel_tbl member specifies a pointer to the Mode Select Table structure entry for the devices. The Mode Select Table structure is read and sent to the SCSI device when the first open call is issued and during recovery. This field is optional and should be used only for advanced SCSI device customization.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.10    The dd_flags Member

The dd_flags member specifies the option flags, which can be SZ_NOSYNC, indicating that the device cannot handle synchronous transfers; SZ_BBR, indicating that the device allows bad block recovery; SZ_NO_DISC, indicating that the device cannot handle disconnects; and SZ_NO_TAG, indicating tagged queueing is not allowed. SZ_NO_TAG overrides inquiry data. The flags are defined in the /usr/sys/include/io/cam/pdrv.h file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.11    The dd_scsi_optcmds Member

The dd_scsi_optcmds member specifies the optional SCSI commands that are supported, as defined in the /usr/sys/include/io/cam/pdrv.h file. The possible commands are NO_OPT_CMDS; SZ_RW10, which enables reading and writing 10-byte CDBs; SZ_PREV_ALLOW, which prevents or allows media removal; and SZ_EXT_RESRV, which enables reserving or releasing file extents.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.12    The dd_ready_time Member

The dd_ready_time member specifies the maximum time (in seconds) allowed for the device to powerup. For disks, this represents power-up and spin-up time. For tapes, it represents power-up, load, and rewind to beginning of tape.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.13    The dd_que_depth Member

The dd_que_depth member specifies the maximum number of queued requests for devices that support queueing. Refer to the documentation for your device to determine if your device supports tag queuing and, if so, the depth of the queue.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.14    The dd_valid Member

The dd_valid member indicates which data length fields are valid. The data length bits, DD_REQSNS_VAL and DD_INQ_VAL, are defined in the /usr/sys/include/io/cam/pdrv.h file.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.15    The dd_inq_len Member

The dd_inq_len member specifies the inquiry data length for the device. This field must be used in conjunction with the DD_INQ_VAL flag.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.3.16    The dd_req_sense_len Member

The dd_req_sense_len member specifies the request sense data length for the device. This field must be used in conjunction with the DD_REQSNS_VAL flag.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4    Programmer-Defined Density Table Structure

The Density Table structure allows for the definition of eight densities for each type of SCSI tape device unit. A density is defined by using the lower 3 bits of the unit's minor number. Refer to the SCSI tape device unit documentation for the density code, compression code, and blocking factor for each density.

The /usr/sys/data/cam_data.c file contains Density Table structure entries for all devices known to Digital. Programmers can add entries for other SCSI tape devices at the end of the Digital entries. The definition for the Density Table structure, DENSITY_TBL, follows:

typedef struct density_tbl {
        struct density{
           u_char    den_flags;         /* VALID, ONE_FM etc */
           u_char    den_density_code;
           u_char    den_compress_code;
                                  /* Compression code if supported */
           u_char    den_speed_setting; /* for this density */
           u_char    den_buffered_setting;
                                        /* Buffer control setting */
           u_long    den_blocking;      /* 0 variable etc. */
        }density[MAX_TAPE_DENSITY];
}DENSITY_TBL;


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.1    The den_flags Member

The den_flags member indicates which fields in the DENSITY_TBL structure are valid for this density. The flags are: DENS_VALID, to indicate whether the structure is valid; ONE_FM, to write one file mark on closing for QIC tape units; DENS_SPEED_VALID, to indicate the speed setting is valid for multispeed tapes; DENS_BUF_VALID, to run in buffered mode; and DENS_COMPRESS_VALID, to indicate compression code, if supported.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.2    The den_density_code Member

The den_density_code member contains the SCSI density code for this density.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.3    The den_compress_code Member

The den_compress_code member contains the SCSI compression code for this density, if the unit supports compression.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.4    The den_speed_setting Member

The den_speed_setting member contains the speed setting for this density. Some units support variable speed for certain densities.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.5    The den_buffered_setting Member

The den_buffered_setting member contains the buffer control setting for this density.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.6    The den_blocking Member

The den_blocking member contains the blocking factor for this SCSI tape device. A NULL (0) setting specifies that the blocking factor is variable. A positive value represents the number of bytes in a block, for example, 512 or 1024.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.4.7    Sample Density Table Structure Entry

This section contains a portion of a Density Table structure entry for the TZK10 SCSI tape device, which supports both fixed and variable length records:

DENSITY_TBL
tzk10_dens = {
{ Minor 00

 
Flags DENS_VALID | DENS_BUF_VALID |ONE_FM ,
 
Density code Compression code Speed setting SEQ_8000R_BPI, NULL, NULL,
 
Buffered setting Blocking 1, 512 },
.
.
.
{ Minor 06
 
Flags DENS_VALID | DENS_BUF_VALID |ONE_FM ,
 
Density code Compression code Speed setting SEQ_QIC320, NULL, NULL,
 
Buffered setting Blocking 1, 1024 }, { Minor 07
 
Flags DENS_VALID | DENS_BUF_VALID |ONE_FM ,
 
Density code Compression code Speed setting SEQ_QIC320, NULL, NULL,
 
Buffered setting Blocking 1, NULL } }; end of tzk10_dens


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5    Programmer-Defined Mode Select Table Structure

The Mode Select Table structure is read and sent to the SCSI device when the first call to the SCSI/CAM peripheral open routine is issued on a SCSI device. There can be a maximum of eight entries in the Mode Select Table structure. The definition for the Mode Select Table structure, MODESEL_TBL, follows:

typedef struct modesel_tbl {
        struct ms_entry{
           u_char  ms_page;     /* Page number */
           u_char  *ms_data;    /* Pointer to Mode Select data */
           u_char  ms_data_len; /* Mode Select data length */
           u_char  ms_ent_sp_pf;/* Save Page and Page format bits */
                                /* BIT 0   1=Save Page, */
                                /*         0=Don't Save Page */
                                /* BIT 1  1=SCSI-2, 0=SCSI-1 */
	}ms_entry[MAX_OPEN_SELS];
}MODESEL_TBL;


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5.1    The ms_page Member

The ms_page member contains the SCSI page number for the device type. For example, the page number would be 0x10 for the device configuration page for a SCSI tape device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5.2    The ms_data Member

The ms_data member contains a pointer to the mode select data for the device. You set up the page data and place the address of the page structure in this field. A sample page definition for page 0x10 for the TZK10 follows:

SEQ_MODE_DATA6
tzk10_page10 = {

 
{ Parameter header
 
mode_len medium type speed NULL, NULL, NULL,
 
Buf_mode wp blk_desc_len 0x01, NULL, sizeof(SEQ_MODE_DESC) }, { Mode descriptor
 
Density num_blks2 num_blks1 NULL, NULL, NULL,
 
num_blks0 reserved blk_len2 NULL, NULL,
 
blk_len1 blk_len0 NULL, NULL }, { Page data for page 0x2
 
PAGE header byte0 byte1 0x10, 0x0e,
 
byte2 byte3 byte4 byte5 byte6 0x00, 0x00, 40, 40, NULL,
 
byte7 byte8 byte9 byte10 byte11 NULL, 0xe0, NULL, 0x38, NULL,
 
byte12 byte13 byte14 byte15 NULL, NULL, NULL, NULL } };


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5.3    The ms_data_len Member

The ms_data_len member contains the length of a page, which is the number of bytes to be sent to the device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5.4    The ms_ent_sp_pf Member

The ms_ent_sp_pf member contains flags for the MODE SELECT CDB that the device driver formats.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.1.5.5    Sample Mode Select Table Structure Entry

The following is a sample portion of a Mode Select Table structure entry for the TZK10 SCSI tape device:

MODESEL_TBL
tzk10_mod = {
{ MODE PAGE ENTRY 1

 
Page number The data pointer 0x02, (u_char *)&tzk10_page2,
 
Data len SCSI2?? 28, 0x2 },
.
.
.
{ MODE PAGE ENTRY 8
 
Page number The data pointer NULL, (u_char *)NULL,
 
Data len SCSI2?? NULL, NULL }, };


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2    Sample SCSI/CAM Device-Specific Data Structures

This section provides samples of the SCSI/CAM peripheral data structures programmers must define if they write their own device drivers. The following data structures are described:


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1    Programmer-Defined Tape-Specific Structure

SCSI/CAM peripheral device driver writers can create their own tape-specific data structures. The following is a sample TAPE_SPECIFIC structure for a SCSI tape device, as defined in the /usr/sys/include/io/cam/cam_tape.h file:

typedef struct {
        u_long  ts_flags;       /* Tape flags - BOM,EOT */
        u_long  ts_state_flags; /* STATE - UNIT_ATTEN, RESET etc. */
        u_long  ts_resid;       /* Last operation residual count */
        u_long  ts_block_size;  /* See below for a complete desc. */
        u_long  ts_density;     /* What density are we running at */
        u_long  ts_records;
                           /* How many records in since last tpmark */
        u_long  ts_num_filemarks; /* number of file marks into tape */
}TAPE_SPECIFIC;


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.1    The ts_flags Member

The ts_flags member contains tape flags bits used to indicate tape condition. The possible flags bits are:
Flag Name Description
CTAPE_BOM The tape is positioned at the beginning.
CTAPE_EOM The unit is positioned at the end of the media.
CTAPE_OFFLINE The device is returning DEVICE NOT READY in response to a command. The media is either not loaded or is being loaded.
CTAPE_WRT_PROT The unit is either write protected or is opened for read only.
CTAPE_BLANK The tape is blank.
CTAPE_WRITTEN The tape has been written during this procedure.
CTAPE_CSE Clear a serious exception.
CTAPE_SOFTERR A soft error has been reported by the SCSI unit.
CTAPE_HARDERR A hard error has been reported by the SCSI unit. It can be reported either through an ioctl command or by marking the buf structure as EIO.
CTAPE_DONE The tape procedure is finished.
CTAPE_RETRY Indicates a retry can be attempted.
CTAPE_ERASED The tape has been erased.
CTAPE_TPMARK A tape mark has been detected during a read operation. This cannot occur during a write operation.
CTAPE_SHRTREC The size of the record retrieved is less than the size requested. It can be reported using an ioctl command.
CTAPE_RDOPP Reading in the reverse direction. This is not implemented.
CTAPE_REWINDING The tape is rewinding.
CTAPE_TPMARK_PENDING The tape mark is to be reported on the next I/O operation.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.2    The ts_state_flags Member

The ts_state_flags member specifies flags bits used to indicate tape state. The possible flags bits include:
Flag Name Description
CTAPE_NOT_READY_STATE  
  The unit was opened with the FNDELAY flag. The unit was detected, but the open failed.
CTAPE_UNIT_ATTEN_STATE  
  A check condition occurred and the sense key was UNIT ATTENTION. This usually indicates that the media was changed. The current tape position is lost.
CTAPE_RESET_STATE  
  Indicates a reset condition on the device or on the bus.
CTAPE_RESET_PENDING_STATE  
  A reset is pending.
CTAPE_OPENED_STATE  
  The unit is opened.
CTAPE_DISEOT_STATE  
  No notification of end of media is required.
CTAPE_ABORT_TPPEND_STATE  
  Indicates that a tape mark was detected for a fixed block operation with nonbuffered I/O. The queue is aborted.
CTAPE_AUTO_DENSITY_VALID_STATE  
  Directs the open routine to call the ctz_auto_density routine when a unit attention is noticed because tape density has been determined and all reads are to occur at that density.
CTAPE_ORPHAN_CMD_STATE  
  This flag is set when a command is orphaned. The process does not wait for completion, such as a rewind operation.
CTAPE_POSITION_LOST_STATE  
  The tape position is lost due to command failure.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.3    The ts_resid Member

The ts_resid member specifies the residual count from the last tape command.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.4    The ts_block_size Member

The ts_block_size member is used to distinguish between blocks and bytes for fixed-block tapes. Commands for devices like 9-track tape, which have variable length records, assume bytes.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.5    The ts_density Member

The ts_density member specifies the current density at which the SCSI tape device is operating.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.6    The ts_records Member

The ts_records member specifies the number of records read since the last tape mark.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.1.7    The ts_num_filemarks Member

The ts_num_filemarks member specifies the number of file marks encountered since starting to read the tape.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.2    Programmer-Defined Disk-Specific and CD-ROM-Specific Structure

SCSI/CAM peripheral device driver writers can create their own disk- and CD-ROM-specific data structures. A sample DISK_SPECIFIC structure for a SCSI disk device, as defined in the /usr/sys/include/io/cam/cam_disk.h file, follows:

typedef struct disk_specific  {
    struct buf *ds_bufhd;           /* Anchor for requests which come */
                                    /* into strategy that cannot be */
                                    /* started due to error recovery */
                                    /* in progress. */
    int        ds_dkn;              /* Used for system statistics */
    U32        ds_bbr_state;        /* Used indicate the current */
                                    /* BBR state if active */
    U32        ds_bbr_retry;        /* BBR retries for reassignment */
    u_char     *ds_bbr_buf;         /* Points to read/write and */
                                    /* reassign data buffer */
    CCB_SCSIIO *ds_bbr_rwccb;       /* R/W ccb used for BBR */
    CCB_SCSIIO *ds_bbr_reasccb;     /* Reassign ccb used for BBR */
    CCB_SCSIIO *ds_bbr_origccb;     /* Ccb which encountered bad block */
    CCB_SCSIIO *ds_tur_ccb;         /* SCSI I/O CCB for tur cmd */
                                    /* during recovery */
    CCB_SCSIIO *ds_start_ccb;       /* SCSI I/O CCB for start unit */
                                    /* cmd during recovery */
    CCB_SCSIIO *ds_mdsel_ccb;       /* SCSI I/O CCB for mode select */
                                    /* cmd during recovery */
    CCB_SCSIIO *ds_rdcp_ccb;        /* SCSI I/O CCB for read capacity */
                                    /* cmd during recovery */
    CCB_SCSIIO *ds_read_ccb;        /* SCSI I/O CCB for Read cmd */
                                    /* during recovery */
    CCB_SCSIIO *ds_prev_ccb;        /* SCSI I/O CCB for Prevent */
                                    /* Media Removal cmd during recovery */
    U32        ds_block_size;       /* This units block size */
    U32        ds_tot_size;         /* Total disk size in blocks */
    U32        ds_media_changes;    /* Number of times media was */
                                    /* changed - removables */
    struct pt  ds_pt;               /* Partition structure */
    U32        ds_openpart;         /* Bit mask of open parts */
    U32        ds_bopenpart;        /* No of block opens */
    U32        ds_copenpart;        /* No of char opens */
    U32        ds_wlabel;           /* Write enable label */
    struct disklabel ds_label;      /* Disk label on device */
}DISK_SPECIFIC;

The structure members and their descriptions follow:
Structure Member Description
ds_bufhd Pointer to a buffer header structure to contain requests that come to the driver but cannot be started due to error recovery in progress. The requests are issued when error recovery is complete.
ds_dkn Used for system statistics.
ds_bbr_state Used to indicate the current state if bad block recovery (BBR) is active.
ds_bbr_retry Number of retries to attempt for reassignment of bad blocks.
ds_bbr_buf Pointer to the read/write and the reassign data buffers.
ds_bbr_rwccb Pointer to the SCSI I/O CCB for the Read/Write command used for recovery.
ds_bbr_reasccb Pointer to the SCSI I/O CCB for the Reassign command used for recovery.
ds_bbr_origccb A CCB that encountered a bad block.
ds_tur_ccb Pointer to the SCSI I/O CCB for the TEST UNIT READY command used for recovery.
ds_start_ccb Pointer to the SCSI I/O CCB for the START UNIT command used for recovery.
ds_mdsel_ccb Pointer to the SCSI I/O CCB for the MODE SELECT command used for recovery.
ds_rdcp_ccb Pointer to the SCSI I/O CCB for the Read Capacity command used for recovery.
ds_read_ccb Pointer to the SCSI I/O CCB for the Read command used for recovery.
ds_prev_ccb Pointer to the SCSI I/O CCB for the Prevent Removal command during recovery.
ds_block_size This SCSI disk device's block size (in bytes).
ds_tot_size Total SCSI disk device size (in blocks).
ds_media_changes For removable media, the number of times the media was changed.
ds_pt Structure defining the current disk partition layout.
ds_openpart Bit mask of open partitions.
ds_bopenpart Number of block opens.
ds_copenpart Number of character opens.
ds_wlabel Write-enable label.
ds_label Disk label on device.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3    SCSI/CAM CD-ROM/AUDIO I/O Control Commands

This section describes the standard and vendor-unique I/O control commands to use for SCSI CD-ROM/AUDIO devices. The commands are defined in the /usr/sys/include/io/cam/cdrom.h file. See Chapter 13 of the American National Standard for Information Systems, Small Computer Systems Interface - 2 (SCSI - 2), X3.131-199X for general information about the CD-ROM device model. Table 11-1 lists the name of each command and describes its function.

Table 11-1: SCSI/CAM CD-ROM/AUDIO I/O Control Commands

Command Description
Standard Commands  
CDROM_PAUSE_PLAY Pauses audio operation.
CDROM_RESUME_PLAY Resumes audio operation.
CDROM_PLAY_AUDIO Plays audio in Logical Block Address (LBA) format.
CDROM_PLAY_AUDIO_MSF Plays audio in minute-/second-/frame-units (MSF) format.
CDROM_PLAY_AUDIO_TI Plays audio track or index.
CDROM_PLAY_AUDIO_TR Plays audio track relative.
CDROM_TOC_HEADER Reads table of contents (TOC) header.
CDROM_TOC_ENTRYS Reads table of contents (TOC) entries.
CDROM_EJECT_CADDY Ejects the CD-ROM caddy.
CDROM_READ_SUBCHANNEL Reads subchannel data.
CDROM_READ_HEADER Reads track header.
Vendor-Unique Commands  
CDROM_PLAY_VAUDIO Plays audio in LBA format.
CDROM_PLAY_MSF Plays audio in MSF format.
CDROM_PLAY_TRACK Plays audio track.
CDROM_PLAYBACK_CONTROL Controls playback.
CDROM_PLAYBACK_STATUS Checks playback status.
CDROM_SET_ADDRESS_FORMAT Sets address format.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1    Structures That SCSI/CAM CD-ROM/AUDIO I/O Control Commands Use

Some of the SCSI CD-ROM/AUDIO device I/O control commands use data structures. This section describes those data structures. The structures are defined in the /usr/sys/include/io/cam/cam_disk.h file. Table 11-2 lists the name of each structure and the commands that use it.

Table 11-2: Structures That SCSI/CAM CD-ROM/AUDIO I/O Control Commands Use

Structure Command
cd_address All
cd_play_audio CDROM_PLAY_AUDIO
  CDROM_PLAY_VAUDIO
cd_play_audio_msf CDROM_PLAY_AUDIO_MSF
  CDROM_PLAY_MSF
cd_play_audio_ti CDROM_PLAY_AUDIO_TI
cd_play_track CDROM_PLAY_AUDIO_TR
  CDROM_PLAY_TRACK
cd_toc_header CDROM_TOC_HEADER
cd_toc CDROM_TOC_ENTRYS
cd_toc_entry CDROM_TOC_ENTRYS
cd_sub_channel CDROM_READ_SUBCHANNEL
cd_subc_position CDROM_READ_SUBCHANNEL
cd_subc_media_catalog CDROM_READ_SUBCHANNEL
cd_subc_isrc_data CDROM_READ_SUBCHANNEL
cd_subc_header CDROM_READ_SUBCHANNEL
cd_subc_channel_data CDROM_READ_SUBCHANNEL
cd_subc_information CDROM_READ_SUBCHANNEL
cd_read_header CDROM_READ_HEADER
cd_read_header_data CDROM_READ_HEADER
cd_playback CDROM_PLAYBACK_CONTROL
  CDROM_PLAYBACK_STATUS


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.1    Structure That All SCSI/CAM CD-ROM/AUDIO I/O Control Commands Use

This section describes the cd_address union that defines the SCSI CD-ROM/AUDIO device Track Address structure and that all the SCSI CD-ROM/AUDIO device I/O control commands use. The SCSI CD-ROM/AUDIO device returns track addresses in either LBA or MSF format.

union cd_address {
	struct {
		u_char		: 8;
		u_char	m_units;
		u_char	s_units;
		u_char	f_units;
	} msf;			/* Minutes/Seconds/Frame format	*/
	    struct {
		u_char	addr3;
		u_char	addr2;
		u_char	addr1;
		u_char	addr0;
	} lba;			/* Logical Block Address format	*/
};

/* * CD-ROM Address Format Definitions. */ #define CDROM_LBA_FORMAT 0 /* Logical Block Address format */ #define CDROM_MSF_FORMAT 1 /* Minute Second Frame format */

The structure members and their descriptions follow:
Structure Member Description
m_units The minute-units binary number of the MSF format for CD-ROM media.
s_units The second-units binary number of the MSF format for CD-ROM media.
f_units The frame-units binary number of the MSF format for CD-ROM media.
addr3 The fourth logical block address of LBA format for disk media.
addr2 The third logical block address of LBA format for disk media.
addr1 The second logical block address of LBA format for disk media.
addr0 The first logical block address of LBA format for disk media.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.2    Structure That the CDROM_PLAY_AUDIO and CDROM_PLAY_VAUDIO Commands Use

This section describes the structure that the CDROM_PLAY_AUDIO and CDROM_PLAY_VAUDIO commands use. The structure is defined as follows:

struct cd_play_audio {
        u_long  pa_lba;	/* Logical block address. */
        u_long  pa_length;	/* Transfer length in blocks. */
};

The structure members and their descriptions follow:
Structure Member Description
pa_lba The LBA where the audio playback operation is to begin.
pa_length The number of contiguous logical blocks to be played.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.3    Structure That the CDROM_PLAY_AUDIO_MSF and CDROM_PLAY_MSF Commands Use

This section describes the structure that the CDROM_PLAY_AUDIO_MSF and CDROM_PLAY_MSF commands use. The structure is defined as follows:

struct cd_play_audio_msf {
        u_char msf_starting_M_unit;     /* Starting M-unit */
        u_char msf_starting_S_unit;     /* Starting S-unit */
        u_char msf_starting_F_unit;     /* Starting F-unit */
        u_char msf_ending_M_unit;       /* Ending M-unit */
        u_char msf_ending_S_unit;       /* Ending S-unit */
        u_char msf_ending_F_unit;       /* Ending F-unit */
};

The structure members and their descriptions follow:
Structure Member Description
msf_starting_M_unit The minute-unit field of the absolute MSF address at which the audio play operation is to begin.
msf_starting_S_unit The second-unit field of the absolute MSF address at which the audio play operation is to begin.
msf_starting_F_unit The frame-unit field of the absolute MSF address at which the audio play operation is to begin.
msf_ending_M_unit The minute-unit field of the absolute MSF address at which the audio play operation is to end.
msf_ending_S_unit The second-unit field of the absolute MSF address at which the audio play operation is to end.
msf_ending_F_unit The frame-unit field of the absolute MSF address at which the audio play operation is to end.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.4    Structure That the CDROM_PLAY_AUDIO_TI Command Uses

This section describes the structure that the CDROM_PLAY_AUDIO_TI command uses. The structure is defined as follows:

/*
 * Define Minimum and Maximum Values for Track & Index.
 */
#define CDROM_MIN_TRACK         1       /* Minimum track number */
#define CDROM_MAX_TRACK         99      /* Maximum track number */
#define CDROM_MIN_INDEX         1       /* Minimum index value */
#define CDROM_MAX_INDEX         99      /* Maximum index value */

 
struct cd_play_audio_ti { u_char ti_starting_track; /* Starting track number */ u_char ti_starting_index; /* Starting index value */ u_char ti_ending_track; /* Ending track number */ u_char ti_ending_index; /* Ending index value */ };

The structure members and their descriptions follow:
Structure Member Description
ti_starting_track The track number at which the audio play operation starts.
ti_starting_index The index number within the track at which the audio play operation starts.
ti_ending_track The track number at which the audio play operation ends.
ti_ending_index The index number within the track at which the audio play operation ends.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.5    Structure That the CDROM_PLAY_AUDIO_TR Command Uses

This section describes the structure that the CDROM_PLAY_AUDIO_TR command uses. The structure is defined as follows:

struct cd_play_audio_tr {
        u_long  tr_lba;                 /* Track relative LBA */
        u_char  tr_starting_track;      /* Starting track number */
        u_short tr_xfer_length;         /* Transfer length */
};

The structure members and their descriptions follow:
Structure Member Description
tr_lba The logical block address relative to the track being played. A negative value indicates a start location within the audio pause area at the beginning of the track.
tr_starting_track The track number at which play is to start.
tr_xfer_length The number of contiguous logical blocks to be output as audio data.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.6    Structure That the CDROM_TOC_HEADER Command Uses

This section describes the structure that the CDROM_TOC_HEADER command uses. The structure is defined as follows:

struct cd_toc_header {
        u_char  th_data_len1;           /* TOC data length MSB */
        u_char  th_data_len0;           /* TOC data length LSB */
        u_char  th_starting_track;      /* Starting track number */
        u_char  th_ending_track;        /* Ending track number */
};

The structure members and their descriptions follow:
Structure Member Description
th_data_len1 The total number of bytes in the table of contents for the MSF format.
th_data_len0 The total number of bytes in the table of contents for the LBA format.
th_starting_track The starting track number for which data is to be returned. If the value is 0 (zero), data is to be returned starting with the first track on the medium.
th_ending_track The track number at which the audio play operation ends.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.7    Structures That the CDROM_TOC_ENTRYS Command Uses

This section describes the structures that the CDROM_TOC_ENTRYS command uses. The structures are defined as follows:

struct cd_toc {
        u_char  toc_address_format;     /* Address format to return */
        u_char  toc_starting_track;     /* Starting track number */
        u_short toc_alloc_length;       /* Allocation length */
        caddr_t toc_buffer;             /* Pointer to TOC buffer */
};

The structure members and their descriptions follow:
Structure Member Description
toc_address_format The address format, LBA or MSF.
toc_starting_track The track number at which the audio play operation starts.
toc_alloc_length The allocation length of the table of contents buffer (in bytes).
toc_buffer A pointer to the TOC buffer.

struct cd_toc_entry {
        u_char                  : 8;    /* Reserved */
        u_char  te_control      : 4;    /* Control field (attributes) */
        u_char  te_addr_type    : 4;    /* Address type information */
        u_char  te_track_number;        /* The track number */
        u_char                  : 8;    /* Reserved */
        union cd_address te_absaddr;    /* Absolute CD-ROM Address */
};

The structure members and their descriptions follow:
Structure Member Description
te_control The control field containing attributes. [Table Note 1]
te_addr_type Address-type information, MSF or LBA format.
te_track_number The current track number that is being played.
te_absaddr The absolute address of the audio track, MSF or LBA format.

Table Note:

  1. Bit Settings
    Bit No. Set to 0 (Zero) Set to 1
    0 Audio without preemphasis Audio with preemphasis
    1 Digital copy prohibited Digital copy permitted
    2 Audio track Data track
    3 Two-channel audio Four-channel audio


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.8    Structures That the CDROM_READ_SUBCHANNEL Command Uses

The CDROM_READ_SUBCHANNEL command requests subchannel data and the state of audio play operations from the target device. This section describes the structure that the CDROM_READ_SUBCHANNEL command uses. The structure is defined as follows:

/*
 * CD-ROM Sub-Channel Q Address Field Definitions.
 */
#define CDROM_NO_INFO_SUPPLIED  0x0   /* Information not supplied */
#define CDROM_CURRENT_POS_DATA  0x1   /* Encodes current position data */
#define CDROM_MEDIA_CATALOG_NUM 0x2   /* Encodes media catalog number */
#define CDROM_ENCODES_ISRC      0x3   /* Encodes ISRC */
                                      /* ISRC=International-Standard- */
                                      /*              Recording-Code */
/* Codes 0x4 through 0x7 are Reserved */

 
/* * CD-ROM Data Track Definitions */ #define CDROM_AUDIO_PREMPH 0x01 /* 0/1 = Without/With Pre-emphasis */ #define CDROM_COPY_PERMITTED 0x02 /* 0/1 = Copy Prohibited/Allowed */ #define CDROM_DATA_TRACK 0x04 /* 0 = Audio, 1 = Data track */ #define CDROM_FOUR_CHAN_AUDIO 0x10 /* 0 = 2 Channel, 1 = 4 Channel */
 
/* * Sub-Channel Data Format Codes */ #define CDROM_SUBQ_DATA 0x00 /* Sub-Channel data information */ #define CDROM_CURRENT_POSITION 0x01 /* Current position information */ #define CDROM_MEDIA_CATALOG 0x02 /* Media catalog number */ #define CDROM_ISRC 0x03 /* ISRC information */ /* ISRC=International-Standard- */ /* Recording-Code */ /* Codes 0x4 through 0xEF are Reserved */ /* Codes 0xF0 through 0xFF are Vendor Specific */
 
/* * Audio Status Definitions returned by Read Sub-Channel Data Command */ #define AS_AUDIO_INVALID 0x00 /* Audio status not supported */ #define AS_PLAY_IN_PROGRESS 0x11 /* Audio play operation in prog */ #define AS_PLAY_PAUSED 0x12 /* Audio play operation paused */ #define AS_PLAY_COMPLETED 0x13 /* Audio play completed */ #define AS_PLAY_COMPLETED 0x13 /* Audio play completed */ #define AS_PLAY_ERROR 0x14 /* Audio play stopped by error */ #define AS_NO_STATUS 0x15 /* No current audio status */
 
struct cd_sub_channel { u_char sch_address_format; /* Address format to return */ u_char sch_data_format; /* Sub-channel data format code */ u_char sch_track_number; /* Track number */ u_short sch_alloc_length; /* Allocation length */ caddr_t sch_buffer; /* Pointer to SUBCHAN buffer */ };

The structure members and their descriptions follow:
Structure Member Description
sch_address_format The address format, LBA or MSF.
sch_data_format The type of subchannel data to be returned.
sch_track_number The track from which ISRC data is read.
sch_alloc_length The allocation length of the table of contents buffer (in bytes).
sch_buffer A pointer to the SUBCHAN buffer defined by the sch_data_format member.

struct cd_subc_position {
        u_char  scp_data_format;        /* Data Format code */
        u_char  scp_control     : 4;    /* Control field (attributes) */
        u_char  scp_addr_type   : 4;    /* Address type information */
        u_char  scp_track_number;       /* The track number */
        u_char  scp_index_number;       /* The index number */
        union cd_address scp_absaddr;   /* Absolute CD-ROM Address */
        union cd_address scp_reladdr;   /* Relative CD-ROM Address */
};

 
#define scp_absmsf scp_absaddr.msf #define scp_abslba scp_absaddr.lba #define scp_relmsf scp_reladdr.msf #define scp_rellba scp_reladdr.lba

The structure members and their descriptions follow:
Structure Member Description
scp_data_format The data format code.
scp_control The control field that contains attributes. [Table Note 1]
scp_addr_type Address-type information, MSF or LBA format.
scp_track_number The current track number that is being played.
scp_index_number The index number within an audio track.
scp_absaddr The absolute address of the audio track, MSF or LBA format.
scp_reladdr The CD-ROM address relative to the track being played.

Table Note:

  1. Bit Settings
    Bit No. Set to 0 (Zero) Set to 1
    0 Audio without preemphasis Audio with preemphasis
    1 Digital copy prohibited Digital copy permitted
    2 Audio track Data track
    3 Two-channel audio Four-channel audio

struct cd_subc_media_catalog {
        u_char  smc_data_format;       /* Data Format code */
        u_char                  : 8;   /* Reserved */
        u_char                  : 8;   /* Reserved */
        u_char                  : 8;   /* Reserved */
        u_char                  : 7,   /* Reserved */

smc_mc_valid : 1; /* Media catalog valid 1 = True */ u_char smc_mc_number[15]; /* Media catalog number ASCII */ };

The structure members and their descriptions follow:
Structure Member Description
smc_data_format The data format code.
smc_mc_valid The media catalog number is valid.
smc_mc_number The media catalog number.

struct cd_subc_isrc_data {
        u_char  sid_data_format;        /* Data Format code */
        u_char                  : 8;    /* Reserved */
        u_char  sid_track_number;       /* The track number */
        u_char                  : 8;    /* Reserved */
        u_char                  : 7,    /* Reserved */
                sid_tc_valid    : 1;    /* Track code valid, 1 = True */
        u_char  sid_tc_number[15];      /* International-Standard- */
                                        /*   Recording-Code (ASCII) */
};

The structure members and their descriptions follow:
Structure Member Description
sid_data_format The data format code.
sid_track_number The current track number at which the track International-Standard-Recording-Code (ISRC) is located.
sid_tc_valid The track code is valid.
sid_tc_number[15] The track code number.

struct cd_subc_header {
        u_char                  : 8;   /* Reserved */
        u_char  sh_audio_status;       /* Audio status */
        u_char  sh_data_len1;          /* Sub-Channel Data length MSB */
        u_char  sh_data_len0;          /* Sub-Channel Data length LSB */
};

The structure members and their descriptions follow:
Structure Member Description
sh_audio_status The audio status code.
sh_data_len1 The subchannel data length for MSF format.
sh_data_len0 The subchannel data length for LBA format.

struct cd_subc_channel_data {
        struct cd_subc_header scd_header;
        struct cd_subc_position scd_position_data;
        struct cd_subc_media_catalog scd_media_catalog;
        struct cd_subc_isrc_data scd_isrc_data;
};

The structure members and their descriptions follow:
Structure Member Description
scd_header The subchannel data header, which is 4 bytes.
scd_position_data The CD-ROM current-position data information.
scd_media_catalog The Media Catalog Number data information.
scd_isrc_data The track ISRC data information.

struct cd_subc_information {
        struct cd_subc_header sci_header;
        union {
                struct cd_subc_channel_data sci_channel_data;
                struct cd_subc_position sci_position_data;
                struct cd_subc_media_catalog sci_media_catalog;
                struct cd_subc_isrc_data sci_isrc_data;
        } sci_data;
};

 
#define sci_scd sci_data.sci_channel_data #define sci_scp sci_data.sci_position_data #define sci_smc sci_data.sci_media_catalog #define sci_sid sci_data.sci_isrc_data
 
#define CDROM_DATA_MODE_ZERO 0 /* All bytes zero */ #define CDROM_DATA_MODE_ONE 1 /* Data mode one format */ #define CDROM_DATA_MODE_TWO 2 /* Data mode two format */ /* Modes 0x03-0xFF are reserved. */

This structure is used to allocate data space. The structure members and their descriptions follow:
Structure Member Description
sci_channel_data Space for channel data.
sci_position_data Space for current position data.
sci_media_catalog Space for Media Catalog data.
sci_isrc_data Space for ISRC data.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.9    Structures That the CDROM_READ_HEADER Command Uses

This section describes the structures that the CDROM_READ_HEADER command uses. The structures are defined as follows:

struct cd_read_header {
        u_char  rh_address_format;      /* Address format to return */
        u_long  rh_lba;                 /* Logical block address */
        u_short rh_alloc_length;        /* Allocation length */
        caddr_t rh_buffer;              /* Pointer to header buffer */
};

The structure members and their descriptions follow:
Structure Member Description
rh_address_format The address format, LBA or MSF format.
rh_lba The logical block address for LBA format.
rh_alloc_length The allocation length of the header buffer.
rh_buffer A pointer to the header buffer.

struct cd_read_header_data {
        u_char  rhd_data_mode;          /* CD-ROM data mode */
        u_char                  : 8;    /* Reserved */
        u_char                  : 8;    /* Reserved */
        u_char                  : 8;    /* Reserved */
        union cd_address rhd_absaddr;   /* Absolute CD-ROM address */
};

 
#define rhd_msf rhd_absaddr.msf #define rhd_lba rhd_absaddr.lba

The structure members and their descriptions follow:
Structure Member Description
rhd_data_mode The CD-ROM data mode type.
rhd_absaddr The absolute address of the audio track, MSF or LBA format.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.10    Structure That the CDROM_PLAY_TRACK Command Uses

This section describes the structure that the CDROM_PLAY_TRACK command uses. The structure is defined as follows:

struct cd_play_track {
        u_char  pt_starting_track;      /* Starting track number */
        u_char  pt_starting_index;      /* Starting index value */
        u_char  pt_number_indexes;      /* Number of indexes */
};

The structure members and their descriptions follow:
Structure Member Description
pt_starting_track The track number at which the audio play operation starts.
pt_starting_index The index number within the track at which the audio play operation starts.
pt_number_indexes The number of index values in the audio encoding on CD-ROM media.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.11    Structure That the CDROM_PLAYBACK_CONTROL and CDROM_PLAYBACK_STATUS Commands Use

This section describes the structures that the CDROM_PLAYBACK_CONTROL and CDROM_PLAYBACK_STATUS commands use. The structures are defined as follows:

/*
 * Definitions for Playback Control/Playback Status Output Selection
Codes */
#define CDROM_MIN_VOLUME        0x0    /* Minimum volume level */
#define CDROM_MAX_VOLUME        0xFF   /* Maximum volume level */
#define CDROM_PORT_MUTED        0x0    /* Output port is muted */
#define CDROM_CHANNEL_0         0x1    /* Channel 0 to output port */
#define CDROM_CHANNEL_1         0x2    /* Channel 1 to output port */
#define CDROM_CHANNEL_0_1       0x3    /* Channel 0 & 1 to output port */

 
struct cd_playback { u_short pb_alloc_length; /* Allocation length */ caddr_t pb_buffer; /* Pointer to playback buffer */ };

The structure members and their descriptions follow:
Structure Member Description
pb_alloc_length The allocation length of the playback buffer.
pb_buffer A pointer to the playback buffer.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.12    Structure That the CDROM_PLAYBACK_CONTROL Command Uses

This section describes the structure that the CDROM_PLAYBACK_CONTROL command uses. The structure is defined as follows:

struct cd_playback_control {
        u_char  pc_reserved[10];        /* Reserved */
        u_char  pc_chan0_select : 4,    /* Channel 0 selection code */
                                : 4;    /* Reserved */
        u_char  pc_chan0_volume;        /* Channel 0 volume level */
        u_char  pc_chan1_select : 4,    /* Channel 1 selection code */
                                : 4;    /* Reserved */
        u_char  pc_chan1_volume;        /* Channel 1 volume level */
        u_char  pc_chan2_select : 4,    /* Channel 2 selection code */
                                : 4;    /* Reserved */
        u_char  pc_chan2_volume;        /* Channel 2 volume level */
        u_char  pc_chan3_select : 4,    /* Channel 3 selection code */
                                : 4;    /* Reserved */
        u_char  pc_chan3_volume;        /* Channel 3 volume level */
};

The structure members and their descriptions follow:
Structure Member Description
pc_chan0_select The selection code for Channel 0. The low 4 bits are reserved.
pc_chan0_volume The volume level value for Channel 0.
pc_chan1_select The selection code for Channel 1. The low 4 bits are reserved.
pc_chan1_volume The volume level value for Channel 1.
pc_chan2_select The selection code for Channel 2. The low 4 bits are reserved.
pc_chan2_volume The volume level value for Channel 2.
pc_chan3_select The selection code for Channel 3. The low 4 bits are reserved.
pc_chan3_volume The volume level value for Channel 3.


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Section] [Next Chapter] [Index] [Help]


11.2.3.1.13    Structure That the CDROM_PLAYBACK_STATUS Command Uses

This section describes the structure that the CDROM_PLAYBACK_STATUS command uses. The structure is defined as follows:

/*
 * Audio status return by Playback Status Command.
 */
#define PS_PLAY_IN_PROGRESS     0x00  /* Audio Play Oper In Progress */
#define PS_PLAY_PAUSED          0x01  /* Audio Pause Oper In Progress */
#define PS_MUTING_ON            0x02  /* Audio Muting On */
#define PS_PLAY_COMPLETED       0x03  /* Audio Play Oper Completed */
#define PS_PLAY_ERROR           0x04  /* Error Occurred During Play */
#define PS_PLAY_NOT_REQUESTED   0x05  /* Audio Play Oper Not Requested */

 
/* * Data structure returned by Playback Status Command. */ struct cd_playback_status { u_char : 8; /* Reserved */ u_char ps_lbamsf : 1, /* Address format 0/1 = LBA/MSF */ : 7; /* Reserved */ u_char ps_data_len1; /* Audio data length MSB */ u_char ps_data_len0; /* Audio data length LSB */ u_char ps_audio_status; /* Audio status */ u_char ps_control : 4, /* Control field (attributes) */ : 4; /* Reserved */ union cd_address ps_absaddr; /* Absolute CD-ROM address */ u_char ps_chan0_select : 4, /* Channel 0 selection code */ : 4; /* Reserved */ u_char ps_chan0_volume; /* Channel 0 volume level */ u_char ps_chan1_select : 4, /* Channel 1 selection code */ : 4; /* Reserved */ u_char ps_chan1_volume; /* Channel 1 volume level */ u_char ps_chan2_select : 4, /* Channel 2 selection code */ : 4; /* Reserved */ u_char ps_chan2_volume; /* Channel 2 volume level */ u_char ps_chan3_select : 4, /* Channel 3 selection code */ : 4; /* Reserved */ u_char ps_chan3_volume; /* Channel 3 volume level */ };


The structure members and their descriptions follow:
Structure Member Description
ps_lbamsf The address format: a 0 (zero) means LBA format; a 1 means MSF format.
ps_data_len1 The audio data length if the address format is MSF format.
ps_data_len0 The audio data length if the address format is LBA format.
ps_audio_status The audio status.
ps_control The control field that contains attributes. [Table Note 1]
  The low 4 bits are reserved.
ps_absaddr The absolute address of the audio track, MSF or LBA format.
ps_chan0_select The selection code for Channel 0. The low 4 bits are reserved.
ps_chan0_volume The volume level setting for Channel 0.
ps_chan0_select The selection code for Channel 0. The low 4 bits are reserved.
ps_chan1_volume The volume level setting for Channel 1.
ps_chan1_select The selection code for Channel 1. The low 4 bits are reserved.
ps_chan2_volume The volume level setting for Channel 2.
ps_chan2_select The selection code for Channel 2. The low 4 bits are reserved.
ps_chan3_volume The volume level setting for Channel 3.

Table Note:

  1. Bit Settings
    Bit No. Set to 0 (Zero) Set to 1
    0 Audio without preemphasis Audio with preemphasis
    1 Digital copy prohibited Digital copy permitted
    2 Audio track Data track
    3 Two-channel audio Four-channel audio


[Return to Library] [Contents] [Previous Chapter] [Previous Section] [Next Chapter] [Index] [Help]


11.3    Adding a Programmer-Defined SCSI/CAM Device

The procedure for installing device drivers described in Writing Device Drivers: Tutorial applies to adding SCSI/CAM peripheral device drivers to your system. Follow that procedure after completing the entries to the SCSI/CAM-specific structures described in this chapter and in Chapter 3.