8 #include "sg_include.h"
10 #define FILE_NAME_SIZE 255
13 basename(char * str1, char * str2)
15 char *p = str1 + (strlen(str1) - 1);
23 do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op,
24 void *resp, int mx_resp_len, int noisy)
26 unsigned char inqCmdBlk[INQUIRY_CMDLEN] =
27 { INQUIRY_CMD, 0, 0, 0, 0, 0 };
28 unsigned char sense_b[SENSE_BUFF_LEN];
29 struct sg_io_hdr io_hdr;
35 inqCmdBlk[2] = (unsigned char) pg_op;
36 inqCmdBlk[4] = (unsigned char) mx_resp_len;
37 memset(&io_hdr, 0, sizeof (struct sg_io_hdr));
38 io_hdr.interface_id = 'S';
39 io_hdr.cmd_len = sizeof (inqCmdBlk);
40 io_hdr.mx_sb_len = sizeof (sense_b);
41 io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
42 io_hdr.dxfer_len = mx_resp_len;
44 io_hdr.cmdp = inqCmdBlk;
46 io_hdr.timeout = DEF_TIMEOUT;
48 if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
49 perror("SG_IO (inquiry) error");
53 /* treat SG_ERR here to get rid of sg_err.[ch] */
54 io_hdr.status &= 0x7e;
55 if ((0 == io_hdr.status) && (0 == io_hdr.host_status) &&
56 (0 == io_hdr.driver_status))
58 if ((SCSI_CHECK_CONDITION == io_hdr.status) ||
59 (SCSI_COMMAND_TERMINATED == io_hdr.status) ||
60 (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) {
61 if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) {
63 unsigned char * sense_buffer = io_hdr.sbp;
64 if (sense_buffer[0] & 0x2)
65 sense_key = sense_buffer[1] & 0xf;
67 sense_key = sense_buffer[2] & 0xf;
68 if(RECOVERED_ERROR == sense_key)
76 get_serial (char * str, char * devname)
80 char buff[MX_ALLOC_LEN + 1];
82 if ((fd = open(devname, O_RDONLY)) < 0)
85 if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) {
88 memcpy(str, buff + 4, len);
99 get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname)
103 char attr_path[FILE_NAME_SIZE];
104 char sysfs_path[FILE_NAME_SIZE];
105 char basedev[FILE_NAME_SIZE];
107 if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) {
109 basename(devname, basedev);
111 sprintf(attr_path, "%s/block/%s/device/vendor",
112 sysfs_path, basedev);
113 if (0 > sysfs_read_attribute_value(attr_path,
114 vendor_id, 8)) return 0;
116 sprintf(attr_path, "%s/block/%s/device/model",
117 sysfs_path, basedev);
118 if (0 > sysfs_read_attribute_value(attr_path,
119 product_id, 16)) return 0;
121 sprintf(attr_path, "%s/block/%s/device/rev",
122 sysfs_path, basedev);
123 if (0 > sysfs_read_attribute_value(attr_path,
127 if ((fd = open(devname, O_RDONLY)) < 0)
129 if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1))
131 memcpy(vendor_id, &buff[8], 8);
132 memcpy(product_id, &buff[16], 16);
133 memcpy(rev, &buff[32], 4);
141 sprint_wwid(char * buff, const char * str)
150 for (i = 0; i <= WWID_SIZE / 2 - 1; i++) {
152 sprintf(cursor, "%.2x", (int) (unsigned char) c);
155 buff[WWID_SIZE - 1] = '\0';
158 /* get EVPD page 0x83 off 8 */
159 /* tested ok with StorageWorks */
161 get_evpd_wwid(char * devname, char * wwid)
166 if ((fd = open(devname, O_RDONLY)) < 0)
169 if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) {
170 sprint_wwid(wwid, &buff[8]);
172 return 1; /* success */
175 return 0; /* not good */
179 get_disk_size (char * devname) {
182 char attr_path[FILE_NAME_SIZE];
183 char sysfs_path[FILE_NAME_SIZE];
184 char buff[FILE_NAME_SIZE];
185 char basedev[FILE_NAME_SIZE];
187 if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) {
188 basename(devname, basedev);
189 sprintf(attr_path, "%s/block/%s/size",
190 sysfs_path, basedev);
191 if (0 > sysfs_read_attribute_value(attr_path, buff,
192 FILE_NAME_SIZE * sizeof(char)))
197 if ((fd = open(devname, O_RDONLY)) < 0)
199 if(!ioctl(fd, BLKGETSIZE, &size))