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

  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. #include "sg_lib.h"
  7. #include "sg_pt.h"
  8.  
  9. /* This is a simple program executing a SCSI INQUIRY command and a
  10.    TEST UNIT READY command using the SCSI generic pass through
  11.    interface. This allows this example program to be ported to
  12.    OSes other than linux.
  13.  
  14. *  Copyright (C) 2006-2007 D. Gilbert
  15. *  This program is free software; you can redistribute it and/or modify
  16. *  it under the terms of the GNU General Public License as published by
  17. *  the Free Software Foundation; either version 2, or (at your option)
  18. *  any later version.
  19.  
  20.    Invocation: sg_simple5 [-x] <scsi_device>
  21.  
  22.    Version 1.01 (20070331)
  23.  
  24. */
  25.  
  26. #define INQ_REPLY_LEN 96
  27. #define INQ_CMD_LEN 6
  28. #define TUR_CMD_LEN 6
  29.  
  30. #define CMD_TIMEOUT_SECS 60
  31.  
  32.  
  33. int main(int argc, char * argv[])
  34. {
  35.     int sg_fd, k, ok, dsize, res, duration, resid, cat, got, slen;
  36.     unsigned char inqCmdBlk [INQ_CMD_LEN] =
  37.                                 {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
  38.     unsigned char turCmdBlk [TUR_CMD_LEN] =
  39.                                 {0x00, 0, 0, 0, 0, 0};
  40.     unsigned char inqBuff[INQ_REPLY_LEN];
  41.     char * file_name = 0;
  42.     char b[512];
  43.     unsigned char sense_b[32];
  44.     int verbose = 0;
  45.     struct sg_pt_base * ptvp;
  46.  
  47.     for (k = 1; k < argc; ++k) {
  48.         if (0 == strcmp("-v", argv[k]))
  49.             verbose = 1;
  50.         else if (0 == strcmp("-vv", argv[k]))
  51.             verbose = 2;
  52.         else if (0 == strcmp("-vvv", argv[k]))
  53.             verbose = 3;
  54.         else if (*argv[k] == '-') {
  55.             printf("Unrecognized switch: %s\n", argv[k]);
  56.             file_name = 0;
  57.             break;
  58.         }
  59.         else if (0 == file_name)
  60.             file_name = argv[k];
  61.         else {
  62.             printf("too many arguments\n");
  63.             file_name = 0;
  64.             break;
  65.         }
  66.     }
  67.     if (0 == file_name) {
  68.         printf("Usage: 'sg_simple5 [-v|-vv|-vvv] <device>'\n");
  69.         return 1;
  70.     }
  71.  
  72.     sg_fd = scsi_pt_open_device(file_name, 1 /* ro */, 0);
  73.     /* N.B. An access mode of O_RDWR is required for some SCSI commands */
  74.     if (sg_fd < 0) {
  75.         fprintf(stderr, "error opening file: %s: %s\n",
  76.                 file_name, safe_strerror(-sg_fd));
  77.         return 1;
  78.     }
  79.  
  80.     dsize = sizeof(inqBuff);
  81.     ok = 0;
  82.  
  83.     ptvp = construct_scsi_pt_obj();     /* one object per command */
  84.     if (NULL == ptvp) {
  85.         fprintf(stderr, "sg_simple5: out of memory\n");
  86.         return -1;
  87.     }
  88.     set_scsi_pt_cdb(ptvp, inqCmdBlk, sizeof(inqCmdBlk));
  89.     set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
  90.     set_scsi_pt_data_in(ptvp, inqBuff, dsize);
  91.     res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
  92.     if (res < 0) {
  93.         fprintf(stderr, "  pass through os error: %s\n",
  94.                 safe_strerror(-res));
  95.         goto finish_inq;
  96.     } else if (SCSI_PT_DO_BAD_PARAMS == res) {
  97.         fprintf(stderr, "  bad pass through setup\n");
  98.         goto finish_inq;
  99.     } else if (SCSI_PT_DO_TIMEOUT == res) {
  100.         fprintf(stderr, "  pass through timeout\n");
  101.         goto finish_inq;
  102.     }
  103.     if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
  104.         fprintf(stderr, "      duration=%d ms\n", duration);
  105.     resid = get_scsi_pt_resid(ptvp);
  106.     switch ((cat = get_scsi_pt_result_category(ptvp))) {
  107.     case SCSI_PT_RESULT_GOOD:
  108.         got = dsize - resid;
  109.         if (verbose && (resid > 0))
  110.             fprintf(stderr, "    requested %d bytes but "
  111.                     "got %d bytes)\n", dsize, got);
  112.         break;
  113.     case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
  114.         if (verbose) {
  115.             sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
  116.                                    sizeof(b), b);
  117.             fprintf(stderr, "  scsi status: %s\n", b);
  118.         }
  119.         goto finish_inq;
  120.     case SCSI_PT_RESULT_SENSE:
  121.         slen = get_scsi_pt_sense_len(ptvp);
  122.         if (verbose) {
  123.             sg_get_sense_str("", sense_b, slen, (verbose > 1),
  124.                              sizeof(b), b);
  125.             fprintf(stderr, "%s", b);
  126.         }
  127.         if (verbose && (resid > 0)) {
  128.             got = dsize - resid;
  129.             if ((verbose) || (got > 0))
  130.                 fprintf(stderr, "    requested %d bytes but "
  131.                         "got %d bytes\n", dsize, got);
  132.         }
  133.         goto finish_inq;
  134.     case SCSI_PT_RESULT_TRANSPORT_ERR:
  135.         if (verbose) {
  136.             get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
  137.             fprintf(stderr, "  transport: %s", b);
  138.         }
  139.         goto finish_inq;
  140.     case SCSI_PT_RESULT_OS_ERR:
  141.         if (verbose) {
  142.             get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
  143.             fprintf(stderr, "  os: %s", b);
  144.         }
  145.         goto finish_inq;
  146.     default:
  147.         fprintf(stderr, "  unknown pass through result "
  148.                 "category (%d)\n", cat);
  149.         goto finish_inq;
  150.     }
  151.  
  152.     ok = 1;
  153. finish_inq:
  154.     destruct_scsi_pt_obj(ptvp);
  155.  
  156.     if (ok) { /* output result if it is available */
  157.         char * p = (char *)inqBuff;
  158.  
  159.         printf("Some of the INQUIRY command's results:\n");
  160.         printf("    %.8s  %.16s  %.4s\n", p + 8, p + 16, p + 32);
  161.     }
  162.     ok = 0;
  163.  
  164.  
  165.     /* Now prepare TEST UNIT READY command */
  166.     ptvp = construct_scsi_pt_obj();     /* one object per command */
  167.     if (NULL == ptvp) {
  168.         fprintf(stderr, "sg_simple5: out of memory\n");
  169.         return -1;
  170.     }
  171.     set_scsi_pt_cdb(ptvp, turCmdBlk, sizeof(turCmdBlk));
  172.     set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
  173.     /* no data in or out */
  174.     res = do_scsi_pt(ptvp, sg_fd, CMD_TIMEOUT_SECS, verbose);
  175.     if (res < 0) {
  176.         fprintf(stderr, "  pass through os error: %s\n",
  177.                 safe_strerror(-res));
  178.         goto finish_inq;
  179.     } else if (SCSI_PT_DO_BAD_PARAMS == res) {
  180.         fprintf(stderr, "  bad pass through setup\n");
  181.         goto finish_inq;
  182.     } else if (SCSI_PT_DO_TIMEOUT == res) {
  183.         fprintf(stderr, "  pass through timeout\n");
  184.         goto finish_inq;
  185.     }
  186.     if ((verbose > 1) && ((duration = get_scsi_pt_duration_ms(ptvp)) >= 0))
  187.         fprintf(stderr, "      duration=%d ms\n", duration);
  188.     resid = get_scsi_pt_resid(ptvp);
  189.     switch ((cat = get_scsi_pt_result_category(ptvp))) {
  190.     case SCSI_PT_RESULT_GOOD:
  191.         break;
  192.     case SCSI_PT_RESULT_STATUS: /* other than GOOD and CHECK CONDITION */
  193.         if (verbose) {
  194.             sg_get_scsi_status_str(get_scsi_pt_status_response(ptvp),
  195.                                    sizeof(b), b);
  196.             fprintf(stderr, "  scsi status: %s\n", b);
  197.         }
  198.         goto finish_tur;
  199.     case SCSI_PT_RESULT_SENSE:
  200.         slen = get_scsi_pt_sense_len(ptvp);
  201.         if (verbose) {
  202.             sg_get_sense_str("", sense_b, slen, (verbose > 1),
  203.                              sizeof(b), b);
  204.             fprintf(stderr, "%s", b);
  205.         }
  206.         goto finish_tur;
  207.     case SCSI_PT_RESULT_TRANSPORT_ERR:
  208.         if (verbose) {
  209.             get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
  210.             fprintf(stderr, "  transport: %s", b);
  211.         }
  212.         goto finish_tur;
  213.     case SCSI_PT_RESULT_OS_ERR:
  214.         if (verbose) {
  215.             get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
  216.             fprintf(stderr, "  os: %s", b);
  217.         }
  218.         goto finish_tur;
  219.     default:
  220.         fprintf(stderr, "  unknown pass through result "
  221.                 "category (%d)\n", cat);
  222.         goto finish_tur;
  223.     }
  224.  
  225.     ok = 1;
  226. finish_tur:
  227.     destruct_scsi_pt_obj(ptvp);
  228.  
  229.     if (ok)
  230.         printf("Test Unit Ready successful so unit is ready!\n");
  231.     else
  232.         printf("Test Unit Ready failed so unit may _not_ be ready!\n");
  233.  
  234.     scsi_pt_close_device(sg_fd);
  235.     return 0;
  236. }
  237.