CD(4)

명칭
cd - SCSI CD-ROM 드라이버

서식
device cd device cd1 at scbus0 target 4 lun 0 options CHANGER_MIN_BUSY_SECONDS=3 options CHANGER_MAX_BUSY_SECONDS=11

해설
cd 드라이버는, SCSI CD-ROM (콤팩트 디스크-읽어내기 전용 메모리) 드라이브를 서포트합니다. 통상 디스크와 같이 보이기 위해서(때문에), cd 드라이버는, CD-ROM 전체를 커버하는 1 개의 파티션으로부터 된다 파티션 테이블을 합성합니다. 이 파티션 테이블을 disklabel(8) (을)를 이용해 수정하는 것은 가능합니다만, 그 수정은 CD-ROM (을)를 언마운트 할 때까지 만 유효합니다. 일반적으로, 이 인터페이스는 wd(4) (이)나 da(4) 그리고 진술되고 있는 것과 같습니다.

SCSI 어댑터가 부트중에 프로브 될 때, SCSI 버스상의 디바이스가 주사 됩니다. 발견된 디바이스 가운데, 타입 CDROM (타입 5) 혹은 WORM (타입 4)라고 응답한 것은 cd 드라이버에 아탓치 됩니다. FreeBSD 2.1 이전의 버젼에서는, 최초로 발견된 디바이스는 cd0 (으)로서 아탓치 되어 그 다음이 cd1 (와)과 같이 되어 있었습니다. FreeBSD 2.1 (으)로부터는, 디바이스가 몇 번의 cd 유니트가 되어야할 것인가 지정할 수 있습니다. 커널 설정의 상세한 것에 대하여는 scsi(4) (을)를 참조해 주세요.

시스템 유틸리티 disklabel(8) (을)를 이용해, 합성된 디스크 label 구조체를 읽어낼 수 있습니다. 이 구조체에는, 필요하다 CD-ROM 의 사이즈에 관한 올바른 값이 포함됩니다.

커널 설정
시스템 설정에 관련되지 않고, 임의의 수의 CD-ROM 디바이스를 시스템에 아탓치 할 수 있습니다. 모든 리소스는 동적으로 allocate 됩니다.

IOCTL
SCSI CD-ROM 드라이브에 적용되는 이하의 ioctl(2) 호출이, 헤더 파일 <sys/cdio.h> (와)과 <sys/disklabel.h> 그리고 정의되고 있습니다.

DIOCGDINFO
DIOCSDINFO
    (struct disklabel) 해당 드라이브에 대한 디스크 label의 커널내 카피를 읽고 쓰기합니다. 디스크 label는 scsi inquiry 명령로부터 읽어낸 정보로 초기화됩니다. 그 값은 부트시에 표시된 것과 동일한은 두입니다. 이 구조체는 disklabel(5) 그리고 정의되고 있습니다.
CDIOCCAPABILITY
    (struct ioc_capability) 해당 드라이브가 서포트하고 있는 기능에 관한 정보를 꺼냅니다. 정보는 이하의 구조체로 돌려주어집니다.

        struct ioc_capability {
        	u_long	play_function;
        #define CDDOPLAYTRK	0x00000001
        	/* tracks/index 지정으로 재생 가능 */
        #define	CDDOPLAYMSF	0x00000002
        	/* msf (분초 프레임) 지정으로 재생 가능 */
        #define	CDDOPLAYBLOCKS	0x00000004
        	/* 블록 지정으로 재생 가능 */
        #define	CDDOPAUSE	0x00000100
        	/* 출력을 일시정지 가능 */
        #define	CDDORESUME	0x00000200
        	/* 출력을 재개 가능 */
        #define	CDDORESET	0x00000400
        	/* 드라이브를 완전하게 리셋트 가능 */
        #define	CDDOSTART	0x00000800
        	/* 오디오 개시 가능 */
        #define CDDOSTOP	0x00001000
        	/* 오디오 정지 가능 */
        #define CDDOPITCH	0x00002000
        	/* 오디오 피치 조정 가능 */
        	u_long	routing_function;
        #define CDREADVOLUME	0x00000001
        	/* 볼륨 설정의 읽기 가능 */
        #define CDSETVOLUME	0x00000002
        	/* 볼륨의 설정 가능 */
        #define	CDSETMONO	0x00000100
        	/* 출력을 단청의로 설정 가능 */
        #define CDSETSTEREO	0x00000200
        	/* 출력을 스테레오로 설정 가능 (디폴트) */
        #define	CDSETLEFT	0x00000400
        	/* 출력을 왼쪽에만 설정 가능 */
        #define	CDSETRIGHT	0x00000800
        	/* 출력을 오른쪽에만 설정 가능 */
        #define	CDSETMUTE	0x00001000
        	/* 출력의 뮤트 가능 */
        #define CDSETPATCH	0x00008000
        	/* 다이렉트 루팅 제어 가능 */
        	u_long	special_function;
        #define	CDDOEJECT	0x00000001
        	/* 트레이의 오픈 가능 */
        #define	CDDOCLOSE	0x00000002
        	/* 트레이의 클로우즈 가능 */
        #define	CDDOLOCK	0x00000004
        	/* 트레이의 락 가능 */
        #define CDREADHEADER	0x00000100
        	/* 목차의 읽기 가능 */
        #define	CDREADENTRIES	0x00000200
        	/* 목차 엔트리의 읽기 가능 */
        #define	CDREADSUBQ	0x00000200
        	/* 서브 채널 정보의 읽기 가능 */
        #define CDREADRW	0x00000400
        	/* 서브 코드 R-W 의 읽기 가능 */
        #define	CDHASDEBUG	0x00004000
        	/* 트레이가 다이나믹 디버그 기능을 가진다 */
        };

CDIOCPLAYTRACKS
    (struct ioc_play_track) 지정된 트럭 주소 및 길이에 근거해 오디오의 재생을 개시합니다. 이 구조체는 이하와 같이 정의됩니다:

        struct ioc_play_track
        {
        	u_char	start_track;
        	u_char	start_index;
        	u_char	end_track;
        	u_char	end_index;
        };

CDIOCPLAYBLOCKS
    (struct ioc_play_blocks) 지정된 블록 주소 및 길이에 근거해 오디오의 재생을 개시합니다. 이 구조체는 이하와 같이 정의됩니다:

        struct ioc_play_blocks
        {
        	int	blk;
        	int	len;
        };

CDIOCPLAYMSF
    (struct ioc_play_msf) 지정된 「분 -초-프레임」이라고 길이에 근거해 오디오의 재생을 개시합니다. 이 구조체는 이하와 같이 정의됩니다:

        struct ioc_play_msf
        {
        	u_char	start_m;
        	u_char	start_s;
        	u_char	start_f;
        	u_char	end_m;
        	u_char	end_s;
        	u_char	end_f;
        };

CDIOCREADSUBCHANNEL
    (struct ioc_read_subchannel) 이 구조체로 지정된 로케이션의 서브 채널로부터 정보를 읽어냅니다.

        struct ioc_read_subchannel {
        	u_char address_format;
        #define CD_LBA_FORMAT	1
        #define CD_MSF_FORMAT	2
        	u_char data_format;
        #define CD_SUBQ_DATA		0
        #define CD_CURRENT_POSITION	1
        #define CD_MEDIA_CATALOG	2
        #define CD_TRACK_INFO		3
        	u_char track;
        	int	data_len;
        	struct  cd_sub_channel_info *data;
        };

CDIOREADTOCHEADER
    (struct ioc_toc_header) mount 되었다 CD-ROM 의 목차에 관한 정보의 요약을 돌려줍니다. 이 정보는 이하의 구조체에 격납해 돌려주어집니다.

        struct ioc_toc_header {
        	u_short len;
        	u_char  starting_track;
        	u_char  ending_track;
        };

CDIOREADTOCENTRYS
    (struct ioc_read_toc_entry) 지정된 목차 엔트리로부터의 정보를 돌려줍니다. (그렇게, 이 명령명의 스펠은 잘못되어 있습니다. ) 인수의 구조체는 이하와 같이 됩니다:

        struct ioc_read_toc_entry {
        	u_char	address_format;
        	u_char	starting_track;
        	u_short	data_len;
        	struct  cd_toc_entry *data;
        };

    요구 데이터는, data 하지만 가리키는 크기 data_len 의 area에 격납됩니다.
CDIOCSETPATCH
    (struct ioc_patch) 여러가지 오디오 채널을 여러가지 출력 채널에 할당합니다. 인수의 구조체는 다음과 같이 정의됩니다:

        struct ioc_patch {
        	u_char	patch[4];
        	/* 각 채널에 대해 1 요소가 대응 */
        };

CDIOCGETVOL
CDIOCSETVOL
    (struct ioc_vol) 출력 채널의 볼륨 설정에 관한 정보를 취득 (혹은 설정)합니다. 인수의 구조체는 다음과 같습니다:

        struct	ioc_vol
        {
        	u_char	vol[4];
        	/* 각 채널에 대해 1 요소가 대응 */
        };

CDIOCSETMONO
    모든 출력 채널을 모든 입력 채널에 할당합니다.
CDIOCSETSTEREO
    왼쪽 입력 채널을 왼쪽 출력 채널에, 오른쪽 입력 채널을 오른쪽 출력 채널에, 각각 할당합니다.
CDIOCSETMUTE
    볼륨 설정을 변경하지 않고 출력을 뮤트 합니다.
CDIOCSETLEFT
CDIOCSETRIGHT
    양쪽 모두의 출력 채널을 왼쪽 (또는 오른쪽) 입력 채널에 할당합니다.
CDIOCSETDEBUG
CDIOCCLRDEBUG
    대응하는 디바이스에 대한 디버그 기능을 온 (또는 오프)으로 합니다.
CDIOCPAUSE
CDIOCRESUME
    오디오 재생을 일시정지 (또는 재개)합니다. 읽기 헤드의 위치는 리셋트 하지 않습니다.
CDIOCRESET
    드라이브를 리셋트 합니다.
CDIOCSTART
CDIOCSTOP
    드라이브에 대해, CD-ROM 의 회전 개시 (또는 정지)를 지시합니다.
CDIOCALLOW
CDIOCPREVENT
    드라이브에 대해, CD-ROM 디스크의 수동에 의한 취득을 허가 (또는 금지)합니다. 이 기능을 서포트하지 않는 드라이브가 있습니다.
CDIOCEJECT
    CD-ROM (을)를 꺼냅니다.
CDIOCCLOSE
    드라이브에 대해, 문을 닫고 미디어를 로드하도록 지시합니다. 이 기능을 서포트하지 않는 드라이브가 있습니다.
CDIOCPITCH
    (struct ioc_pitch) 이 기능을 서포트하는 드라이브에 대해, 오디오를 통상보다 빠른 속도내지 늦은 속도로 재생하도록 지시합니다. speed 의 값이 -32767 로부터 -1 까지의 사이라면 늦은 속도로 재생합니다. 값이 0 이라면 통상 속도입니다. 값이 1 에서 32767 의 경우는 빠른 속도로 재생합니다. 분해가능이 16 비트 미만의 드라이브의 경우, 에러를 내지 않고, 단지 하위 비트가 무시됩니다. 이 구조체는 다음과 같이 정의됩니다:

        struct	ioc_pitch
        {
        	short	speed;
        };

주의
cd 드라이버로 제어되고 있는 드라이브중의 CD-ROM 하지만 바꿔 넣을 수 있었을 경우, 미디어 교환 조작에 의해 커널내의 디스크 label와 관련 정보가 무효화됩니다. 데이터 파손을 피하기 (위해)때문에, 해당 디바이스를 참조하는 오픈 파일 데스크리프타가 없어질 때까지, 해당 디바이스에 대한 액세스는 모두 파기됩니다. 이전, 새로운 오픈 조작은 모두 거부됩니다. 해당 디바이스를 참조하는 오픈 file descripter가 없어지면(자), 후속의 최초의 오픈 조작에 의해, 해당 드라이브에 대한 새롭다 파라미터 일식 (디스크 label를 포함한다)이 로드 됩니다.

cd 드라이버중의 오디오 코드는 SCSI-2 표준의 오디오 명령만 서포트합니다. 많은 CD-ROM 제조업자는 이 표준 표준에 따르지 않기 때문에, 오디오가 동작하지 않는다 CD-ROM 드라이브가 많이 존재합니다. 보다 일반적인 「안된」 CD-ROM 드라이브를 서포트하는 작업도 계획되고 있습니다만, 아직 실행에 옮겨지고 있지 않습니다.

첸쟈 조작
이 드라이버는 LUN 베이스의 CD 첸쟈의 서포트를 내장하고 있습니다. LUN 베이스의 CD 첸쟈란, 2 개(살) 이상의 CD 를 보관 유지할 수 있지만, CD 재생 기구를 1조 밖에 가지지 않는 드라이브입니다. 이 드라이브내의 각 CD 는, SCSI 버스상의 다른 논리 유니트로서 나타납니다. 이 cd 드라이버는 자동적으로 LUN 베이스의 첸쟈를 인식해, 내부의 스케쥴러를 통해 첸쟈에 대한 명령을 배웅합니다. 이 스케쥴러는, 첸쟈중이 다른 LUN 에 동시에 명령을 보내는 것으로 일으켜지는, 첸쟈의 「스래싱」을 막습니다.

스케쥴러는, 드라이버가 특정의 LUN 로 소비하는 타임 콴텀의 최소치와 최대치를 관리합니다. 최소치란, 비록 그 LUN 에 처리중의 I/O 가 없는 경우에서도, 그 LUN 로 비 일이 프로텍션되고 있는 최소 시간량입니다. 최대치란, 다른 LUN 에 처리중의 I/O 가 있는 경우에, 어느 LUN 로 첸쟈가 비 최대 시간량입니다. 다른 LUN 에 처리중의 I/O 가 없는 경우는, 드라이버는 있는 LUN 에 대한 액세스에 상한을 마련하지 않습니다.

최소 및 최대 타임 콴텀은 커널 옵션이나 sysctl 변수를 통해 변경할 수 있습니다. 커널 옵션은 이하와 같다:
options CHANGER_MIN_BUSY_SECONDS=3
options CHANGER_MAX_BUSY_SECONDS=11

sysctl 변수는 이하와 같다:

kern.cam.cd.changer.min_busy_seconds
kern.cam.cd.changer.max_busy_seconds

유저는, sysctl 변수를 통해서 최소 및 최대 타임 아웃을 시험해, 자신의 첸쟈에 최적인 값을 찾아내면(자) 좋을 것입니다. 일단, 자신의 첸쟈에 대한 최적 타임 아웃이 정해지면, 그것을 커널 설정 파일에 기술할 수 있습니다.

자신의 시스템에 LUN 베이스의 첸쟈가 존재하면, 부트 프로세스가 진행되는에 따라, 그 첸쟈의 여러가지 LUN 에 대한다 프로브 메세지가 표시되는 것에 눈치채겠지요. 이것은 정상적이고, 첸쟈의 스케줄링 코드에 의해 일으켜집니다.

관련 파일
/dev/cd[0-9][a-h]
    블록 모드 CD-ROM 디바이스
/dev/rcd[0-9][a-h]
    raw 모드 CD-ROM 디바이스

진단
없습니다.

관련 항목
scsi(4), da(4), disklabel(5), disklabel(8), cd(9)

버그
ioctl() 에 대한 3 번째의 인수에 이용되는 구조체의 이름은 적당하지는 않습니다. 또, ioctl() 명령안에는 스펠 미스가 얼마든지 남아 있습니다.

현재로서는, 다른 CD 첸쟈에 대해서 다른 최소 및 최대 타임 아웃치를 설정하는 기구는 없습니다. 커널 옵션 혹은 sysctl 변수로 설정한 타임 아웃치는 시스템에 있는 LUN 베이스의 CD 첸쟈 모두에 적용됩니다. 이러한 서포트를 실장하는 것은 가능합니다만, 적어도 sysctl 에 의한 실장은 별로 우아하지는 않습니다. 그렇다고 하는 것은, 현재의 sysctl 코드에서는 컴파일 후의 노드 추가를 취급할 수가 없기 때문입니다. 그러므로, 동적으로 크기를 결정하는 sysctl 변수를 준비해, 유저 레벨의 유틸리티를 이용해 타임 아웃치를 취득내지 설정한다 되겠지요. 커널 설정 파일중에서, 다른 CD 디바이스에 대해서 다른 타임 아웃을 지정할 수 있도록(듯이) 하려면 , config(8) (을)를 수정해, 고정적으로 기술했다 cd 디바이스에 2 개의 타임 아웃치를 서포트하도록(듯이) 하지 않으면 안 될지도 모릅니다.

역사
본 cd 드라이버는, Julian Ellischer 가 기술해 386BSD 0.1 에 등장했다 cd 드라이버를 베이스로 하고 있습니다. cd 드라이버의 CAM 버젼은 Kenneth Merry 가 기술해, FreeBSD 3.0 그리고 최초로 등장했습니다.