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.
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:
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;
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.
The pu_opens member specifies the total number of opens against the unit.
The pu_config Indicates whether a device of the specified type is configured at this bus/target/LUN.
The pu_type member specifies the device type from byte 0 (zero) of the Inquiry data.
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. |
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;
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.
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.
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.
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.
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.
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.
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.
The dd_density_tbl member specifies a pointer to the Density Table structure entry for a tape device.
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.
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.
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.
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.
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.
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.
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.
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.
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;
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.
The den_density_code member contains the SCSI density code for this density.
The den_compress_code member contains the SCSI compression code for this density, if the unit supports compression.
The den_speed_setting member contains the speed setting for this density. Some units support variable speed for certain densities.
The den_buffered_setting member contains the buffer control setting for this density.
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.
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
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;
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.
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 } };
The ms_data_len member contains the length of a page, which is the number of bytes to be sent to the device.
The ms_ent_sp_pf member contains flags for the MODE SELECT CDB that the device driver formats.
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 }, };
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:
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;
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. |
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. |
The ts_resid member specifies the residual count from the last tape command.
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.
The ts_density member specifies the current density at which the SCSI tape device is operating.
The ts_records member specifies the number of records read since the last tape mark.
The ts_num_filemarks member specifies the number of file marks encountered since starting to read the tape.
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. |
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.
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. |
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.
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 |
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. |
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. |
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. |
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. |
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. |
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. |
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. |
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:
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 |
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. |
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:
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. |
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. |
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. |
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. |
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. |
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. |
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:
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 |
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.