home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / doc / sg3-utils / examples / scsi_inquiry.c < prev    next >
Encoding:
C/C++ Source or Header  |  2007-01-21  |  4.0 KB  |  129 lines

  1. #include <unistd.h>
  2. #include <signal.h>
  3. #include <fcntl.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <errno.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <scsi/scsi.h>
  12. /* #include <scsi/scsi_ioctl.h> */ /* glibc hides this file sometimes */
  13.  
  14. /* Test code for D. Gilbert's extensions to the Linux OS SCSI generic ("sg")
  15.    device driver.
  16. *  Copyright (C) 1999 D. Gilbert
  17. *  This program is free software; you can redistribute it and/or modify
  18. *  it under the terms of the GNU General Public License as published by
  19. *  the Free Software Foundation; either version 2, or (at your option)
  20. *  any later version.
  21.  
  22.    This program does a SCSI inquiry command on the given device and 
  23.    outputs some of the result. This program highlights the use of the
  24.    SCSI_IOCTL_SEND_COMMAND ioctl. This should be able to be applied to 
  25.    any SCSI device file descriptor (not just one related to sg). [Whether
  26.    this is a good idea on a disk while it is mounted is debatable.
  27.    No detrimental effects when this was tested ...]
  28.  
  29. Version 0.14 20011218
  30. */
  31.         
  32.  
  33. typedef struct my_scsi_ioctl_command {
  34.         unsigned int inlen;  /* _excluding_ scsi command length */
  35.         unsigned int outlen;
  36.         unsigned char data[1];  /* was 0 but that's not ISO C!! */
  37.                 /* on input, scsi command starts here then opt. data */
  38. } My_Scsi_Ioctl_Command;
  39.  
  40. #define OFF (2 * sizeof(unsigned int))
  41.  
  42. #ifndef SCSI_IOCTL_SEND_COMMAND
  43. #define SCSI_IOCTL_SEND_COMMAND 1
  44. #endif
  45.  
  46. #define INQUIRY_CMD     0x12
  47. #define INQUIRY_CMDLEN  6
  48. #define INQUIRY_REPLY_LEN 96
  49.  
  50.  
  51. int main(int argc, char * argv[])
  52. {
  53.     int s_fd, res, k, to;
  54.     unsigned char inqCmdBlk [INQUIRY_CMDLEN] = {INQUIRY_CMD, 0, 0, 0,
  55.                                                 INQUIRY_REPLY_LEN, 0};
  56.     unsigned char * inqBuff = (unsigned char *)
  57.                                 malloc(OFF + sizeof(inqCmdBlk) + 512);
  58.     unsigned char * buffp = inqBuff + OFF;
  59.     My_Scsi_Ioctl_Command * ishp = (My_Scsi_Ioctl_Command *)inqBuff;
  60.     char * file_name = 0;
  61.     int do_nonblock = 0;
  62.     int oflags = 0;
  63.  
  64.     for (k = 1; k < argc; ++k) {
  65.         if (0 == strcmp(argv[k], "-n"))
  66.             do_nonblock = 1;
  67.         else if (*argv[k] != '-')
  68.             file_name = argv[k];
  69.         else {
  70.             printf("Unrecognized argument '%s'\n", argv[k]);
  71.             file_name = 0;
  72.             break;
  73.         }
  74.     }
  75.     if (0 == file_name) {
  76.         printf("Usage: 'scsi_inquiry [-n] <scsi_device>'\n");
  77.         printf("     where: -n   open device in non-blocking mode\n");
  78.         printf("  Examples: scsi_inquiry /dev/sda\n");
  79.         printf("            scsi_inquiry /dev/sg0\n");
  80.         printf("            scsi_inquiry -n /dev/scd0\n");
  81.         return 1;
  82.     }
  83.     
  84.     if (do_nonblock)
  85.         oflags = O_NONBLOCK;
  86.     s_fd = open(file_name, oflags | O_RDWR);
  87.     if (s_fd < 0) {
  88.         if ((EROFS == errno) || (EACCES == errno)) {
  89.             s_fd = open(file_name, oflags | O_RDONLY);
  90.             if (s_fd < 0) {
  91.                 perror("scsi_inquiry: open error");
  92.                 return 1;
  93.             }
  94.         }
  95.         else {
  96.             perror("scsi_inquiry: open error");
  97.             return 1;
  98.         }
  99.     }
  100.     /* Don't worry, being very careful not to write to a none-scsi file ... */
  101.     res = ioctl(s_fd, SCSI_IOCTL_GET_BUS_NUMBER, &to);
  102.     if (res < 0) {
  103.         /* perror("ioctl on scsi device, error"); */
  104.         printf("scsi_inquiry: not a scsi device\n");
  105.         return 1;
  106.     }
  107.  
  108.     ishp->inlen = 0;
  109.     ishp->outlen = INQUIRY_REPLY_LEN;
  110.     memcpy(buffp, inqCmdBlk, INQUIRY_CMDLEN);
  111.     res = ioctl(s_fd, SCSI_IOCTL_SEND_COMMAND, inqBuff);
  112.     if (0 == res) {
  113.         to = (int)*(buffp + 7);
  114.         printf("    %.8s  %.16s  %.4s, byte_7=0x%x\n", buffp + 8,
  115.                buffp + 16, buffp + 32, to);
  116.     }
  117.     else if (res < 0)
  118.         perror("scsi_inquiry: SCSI_IOCTL_SEND_COMMAND err");
  119.     else 
  120.         printf("scsi_inquiry: SCSI_IOCTL_SEND_COMMAND status=0x%x\n", res);
  121.  
  122.     res = close(s_fd);
  123.     if (res < 0) {
  124.         perror("scsi_inquiry: close error");
  125.         return 1;
  126.     }
  127.     return 0;
  128. }
  129.