将来ドライバ開発をしたいので景気づけに光学ドライブに命令を送り直接情報を受け取って見る
linuxlite ~ kaihatsu gcc inquiry.c -o inquiry
linuxlite ~ kaihatsu ./inquiry
Vendor : PLDS
Product: DVD+-RW DS-8A8SH
Rev : KD11
linuxlite ~ kaihatsu
inquiry.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#define INQ_REPLY_LEN 36 // ドライブから返るバッファの大きさ
int main(void)
{
int fd;
// 光学ドライブへ送る命令
unsigned char inquiry_cmd[6] = {
0x12, // INQUIRY
0x00,
0x00,
0x00,
INQ_REPLY_LEN,
0x00
};
unsigned char inquiry_reply[INQ_REPLY_LEN]; // ドライブから返るバッファ
unsigned char sense_buffer[32]; // エラー情報用バッファ
sg_io_hdr_t io_hdr;
// 全バイト埋まらない場合にゴミデータが残らないように0埋め
memset(inquiry_reply, 0, sizeof(inquiry_reply));
memset(sense_buffer, 0, sizeof(sense_buffer));
memset(&io_hdr, 0, sizeof(io_hdr));
fd = open("/dev/sr0", O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
io_hdr.interface_id = 'S';
io_hdr.cmdp = inquiry_cmd; // 送信する命令の位置
io_hdr.cmd_len = sizeof(inquiry_cmd); // 命令の長さ
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; // 装置→PC 読み込み
io_hdr.dxferp = inquiry_reply; // ドライブから返るデータのバッファ位置
io_hdr.dxfer_len = sizeof(inquiry_reply); // 最大受信の大きさ
io_hdr.sbp = sense_buffer; // エラー情報を書き込む場所
io_hdr.mx_sb_len = sizeof(sense_buffer); // エラー情報の最大の大きさ
io_hdr.timeout = 5000;
if (ioctl(fd, SG_IO, &io_hdr) < 0) { // ドライブへ命令を送るシステムコール
perror("SG_IO");
close(fd);
return 1;
}
printf("Vendor : %.8s\n", inquiry_reply + 8);
printf("Product: %.16s\n", inquiry_reply + 16);
printf("Rev : %.4s\n", inquiry_reply + 32);
close(fd);
return 0;
}
開発環境
機種 : VOSTRO 1540
CPU : Intel(R) Celeron(R) CPU P4600 @ 2.00GHz
MEM : 1.8Gi
OS : Linux Lite 6.6
GCC : 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)