]>
Commit | Line | Data |
---|---|---|
cdddbdbc | 1 | /* |
a54d5262 | 2 | * Copyright (C) 2007-2008 Intel Corporation |
cdddbdbc | 3 | * |
1011e834 | 4 | * Retrieve drive serial numbers for scsi disks |
cdddbdbc DW |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms and conditions of the GNU General Public License, | |
8 | * version 2, as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along with | |
16 | * this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | */ | |
19 | #include <string.h> | |
20 | #include <scsi/scsi.h> | |
21 | #include <scsi/sg.h> | |
22 | #include <sys/ioctl.h> | |
23 | ||
24 | int scsi_get_serial(int fd, void *buf, size_t buf_len) | |
25 | { | |
21e9380b AP |
26 | unsigned char rsp_buf[255]; |
27 | unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, sizeof(rsp_buf), 0}; | |
cdddbdbc DW |
28 | unsigned char sense[32]; |
29 | struct sg_io_hdr io_hdr; | |
21e9380b AP |
30 | int rv; |
31 | unsigned int rsp_len; | |
cdddbdbc DW |
32 | |
33 | memset(&io_hdr, 0, sizeof(io_hdr)); | |
34 | io_hdr.interface_id = 'S'; | |
35 | io_hdr.cmdp = inq_cmd; | |
36 | io_hdr.cmd_len = sizeof(inq_cmd); | |
21e9380b AP |
37 | io_hdr.dxferp = rsp_buf; |
38 | io_hdr.dxfer_len = sizeof(rsp_buf); | |
cdddbdbc DW |
39 | io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; |
40 | io_hdr.sbp = sense; | |
41 | io_hdr.mx_sb_len = sizeof(sense); | |
42 | io_hdr.timeout = 5000; | |
43 | ||
21e9380b AP |
44 | rv = ioctl(fd, SG_IO, &io_hdr); |
45 | ||
46 | if (rv) | |
47 | return rv; | |
48 | ||
01a052b9 AP |
49 | if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) |
50 | return -1; | |
51 | ||
21e9380b AP |
52 | rsp_len = rsp_buf[3]; |
53 | ||
54 | if (!rsp_len || buf_len < rsp_len) | |
55 | return -1; | |
56 | ||
57 | memcpy(buf, &rsp_buf[4], rsp_len); | |
58 | ||
59 | return 0; | |
cdddbdbc | 60 | } |