免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2487 | 回复: 0
打印 上一主题 下一主题

linux下读取sata硬盘序列号 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-05-29 20:06 |只看该作者 |倒序浏览
   今天一直在找sata硬盘序列号的C读取方法, 找了良久, 终于找到一份可行的代码, 遂改之, 下面这段代码在as4测试通过, (此篇文章修改自: http://samba.org/~tridge/ctdb/utils/scsi_io/scsi_io.c)
#include unistd.h>
#include fcntl.h>
#include stdio.h>
#include string.h>
#include errno.h>
#include sys/ioctl.h>
#include scsi/sg.h>
#define SCSI_TIMEOUT 5000 /* ms */
static char *device  = "/dev/sda";
int scsi_io(int fd, unsigned char *cdb, unsigned char cdb_size, int xfer_dir,
            unsigned char *data, unsigned int *data_size,
            unsigned char *sense, unsigned int *sense_len)
{
    sg_io_hdr_t io_hdr;
    memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
    io_hdr.interface_id = 'S';
    /* CDB */
    io_hdr.cmdp = cdb;
    io_hdr.cmd_len = cdb_size;
    /* Where to store the sense_data, if there was an error */
    io_hdr.sbp = sense;
    io_hdr.mx_sb_len = *sense_len;
    *sense_len=0;
    /* Transfer direction, either in or out. Linux does not yet
       support bidirectional SCSI transfers ?
     */
    io_hdr.dxfer_direction = xfer_dir;
    /* Where to store the DATA IN/OUT from the device and how big the
       buffer is
     */
    io_hdr.dxferp = data;
    io_hdr.dxfer_len = *data_size;
    /* SCSI timeout in ms */
    io_hdr.timeout = SCSI_TIMEOUT;
    if(ioctl(fd, SG_IO, &io_hdr)  0){
        perror("SG_IO ioctl failed");
        return -1;
    }
    /* now for the error processing */
    if((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK){
        if(io_hdr.sb_len_wr > 0){
            *sense_len=io_hdr.sb_len_wr;
            return 0;
        }
    }
    if(io_hdr.masked_status){
        printf("status=0x%x\n", io_hdr.status);
        printf("masked_status=0x%x\n", io_hdr.masked_status);
        return -2;
    }
    if(io_hdr.host_status){
        printf("host_status=0x%x\n", io_hdr.host_status);
        return -3;
    }
    if(io_hdr.driver_status){
        printf("driver_status=0x%x\n", io_hdr.driver_status);
        return -4;
    }
    return 0;
}
int scsi_inquiry_unit_serial_number(int fd)
{
    unsigned char cdb[]={0x12,0x01,0x80,0,0,0};
    unsigned int data_size=0x00ff;
    unsigned char data[data_size];
    unsigned int sense_len=32;
    unsigned char sense[sense_len];
    int res, pl, i;
    cdb[3]=(data_size>>8)&0xff;
    cdb[4]=data_size&0xff;
    printf("INQUIRY Unit Serial Number:\n");
    res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len);
    if(res){
        printf("SCSI_IO failed\n");
        return -1;
    }
    if(sense_len){
        return -1;
    }
    /* Page Length */
    pl=data[3];
    /* Unit Serial Number */
    printf("Unit Serial Number:");
    for(i=4;i(pl+4);i++)printf("%c",data&0xff);printf("\n");
    return 0;
}
int open_scsi_device(const char *dev)
{
    int fd, vers;
    if((fd=open(dev, O_RDWR))0){
        printf("ERROR could not open device %s\n", dev);
        return -1;
    }
    if ((ioctl(fd, SG_GET_VERSION_NUM, &vers)  0) || (vers  30000)) {
        printf("/dev is not an sg device, or old sg driver\n");
        close(fd);
        return -1;
    }
    return fd;
}
int main(int argc, const char *argv[])
{
    int fd;
    fd=open_scsi_device(device);
    if(fd0){
        printf("Could not open SCSI device %s\n",device);
        _exit(10);
    }
    scsi_inquiry_unit_serial_number(fd);
    return 0;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/54338/showart_1948376.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP