#include #include #include #include #include #include #include #include #include #include #include #include static void dump(const unsigned char *b, int l) { int i; while (l) { for (i = 0; i < l && i < 16; ++i) printf("%02x ", b[i]); printf(" "); for (i = 0; i < l && i < 16; ++i) { if (b[i] < 0x20 || b[i] > 0x7e) { printf("."); } else { printf("%c", b[i]); } } printf("\n"); b += i; l -= i; } } enum { INQ_REPLY_LEN = 96, INQ_CMD_CODE = 0x12, INQ_CMD_LEN = 6 }; static void hdd_ident(const char *device) { unsigned char inqCmdBlk[INQ_CMD_LEN] = { INQ_CMD_CODE, 0, 0, 0, INQ_REPLY_LEN, 0 }; unsigned char inqBuff[INQ_REPLY_LEN]; unsigned char sense_buffer[32]; union { struct hd_driveid drv; sg_io_hdr_t sg; } u; int fd; int k; fd = open(device, O_RDONLY); if (fd < 0) error(1, errno, "couldn't open %s", device); if (ioctl(fd, HDIO_GET_IDENTITY, &u.drv) >= 0) { printf("serial: '%.*s'\n", sizeof u.drv.serial_no, u.drv.serial_no); printf("model: '%.*s'\n", sizeof u.drv.model, u.drv.model); } else if (ioctl(fd, SG_GET_VERSION_NUM, &k) < 0 || k < 30000) { error(1, 0, "device %s isn't an IDE or SCSI device", device); } else { memset(&u.sg, 0, sizeof u.sg); memset(inqBuff, 0, sizeof inqBuff); memset(sense_buffer, 0, sizeof sense_buffer); u.sg.interface_id = 'S'; u.sg.cmd_len = sizeof(inqCmdBlk); /* u.sg.iovec_count = 0; */ /* memset takes care of this */ u.sg.mx_sb_len = sizeof(sense_buffer); u.sg.dxfer_direction = SG_DXFER_FROM_DEV; u.sg.dxfer_len = INQ_REPLY_LEN; u.sg.dxferp = inqBuff; u.sg.cmdp = inqCmdBlk; u.sg.sbp = sense_buffer; u.sg.timeout = 20000; /* 20000 millisecs == 20 seconds */ /* u.sg.flags = 0; */ /* take defaults: indirect IO, etc */ /* u.sg.pack_id = 0; */ /* u.sg.usr_ptr = NULL; */ if (ioctl(fd, SG_IO, &u.sg) < 0) error(1, errno, "couldn't inquire %s", device); /* now for the error processing */ if ((u.sg.info & SG_INFO_OK_MASK) != SG_INFO_OK) { if (u.sg.sb_len_wr > 0) { printf("INQUIRY sense data: "); for (k = 0; k < u.sg.sb_len_wr; ++k) { if ((k > 0) && (0 == (k % 10))) printf("\n "); printf("0x%02x ", sense_buffer[k]); } printf("\n"); } if (u.sg.masked_status) printf("INQUIRY SCSI status=0x%x\n", u.sg.status); if (u.sg.host_status) printf("INQUIRY host_status=0x%x\n", u.sg.host_status); if (u.sg.driver_status) printf("INQUIRY driver_status=0x%x\n", u.sg.driver_status); } else { /* assume INQUIRY response is present */ printf("Some of the INQUIRY command's response:\n"); dump(inqBuff, sizeof inqBuff); printf("INQUIRY duration=%u millisecs, resid=%d\n", u.sg.duration, u.sg.resid); } } close(fd); } int main(int argc, char *argv[]) { char *device; char *eeprom; while (*++argv) { hdd_ident(*argv); } return 0; }