~ubuntu-branches/ubuntu/intrepid/sg3-utils/intrepid

« back to all changes in this revision

Viewing changes to examples/sg_sat_chk_power.c

  • Committer: Bazaar Package Importer
  • Author(s): Luk Claes
  • Date: 2006-11-05 17:23:29 UTC
  • mfrom: (1.1.4 upstream) (3.1.2 edgy)
  • Revision ID: james.westby@ubuntu.com-20061105172329-l4loha00sk36qz6k
* Non-maintainer upload.
* Fix FTBFS due to old syscall usage (Closes: #395512).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006 Douglas Gilbert.
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 * 3. The name of the author may not be used to endorse or promote products
 
14
 *    derived from this software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
26
 * SUCH DAMAGE.
 
27
 *
 
28
 */
 
29
 
 
30
#include <unistd.h>
 
31
#include <fcntl.h>
 
32
#include <stdio.h>
 
33
#include <stdlib.h>
 
34
#include <string.h>
 
35
#include <errno.h>
 
36
#include <sys/ioctl.h>
 
37
#include <sys/types.h>
 
38
#include <sys/stat.h>
 
39
#include "sg_lib.h"
 
40
#include "sg_io_linux.h"
 
41
 
 
42
/* This program performs a ATA PASS THROUGH (16) SCSI command in order
 
43
   to perform an ATA CHECK POWER MODE command. See http://www.t10.org
 
44
   SAT draft at time of writing: sat-r08.pdf
 
45
 
 
46
   Invocation: sg_sat_chk_power [-v] [-V] <device>
 
47
 
 
48
*/
 
49
 
 
50
#define SAT_ATA_PASS_THROUGH16 0x85
 
51
#define SAT_ATA_PASS_THROUGH16_LEN 16
 
52
#define SAT_STATUS_RETURN_DESC 9  /* ATA status return (sense) descriptor */
 
53
 
 
54
#define ATA_CHECK_POWER_MODE 0xe5
 
55
 
 
56
#define EBUFF_SZ 256
 
57
 
 
58
static char * version_str = "1.02 20060629";
 
59
 
 
60
int main(int argc, char * argv[])
 
61
{
 
62
    int sg_fd, k;
 
63
    unsigned char aptCmdBlk[SAT_ATA_PASS_THROUGH16_LEN] =
 
64
                {SAT_ATA_PASS_THROUGH16, 0, 0, 0, 0, 0, 0, 0,
 
65
                 0, 0, 0, 0, 0, 0, 0, 0};
 
66
    sg_io_hdr_t io_hdr;
 
67
    char * file_name = 0;
 
68
    char ebuff[EBUFF_SZ];
 
69
    unsigned char sense_buffer[64];
 
70
    int verbose = 0;
 
71
    int extend = 0;
 
72
    int chk_cond = 1;   /* set to 1 to read register(s) back */
 
73
    int protocol = 3;   /* non-dat data-in */
 
74
    int t_dir = 1;      /* 0 -> to device, 1 -> from device */
 
75
    int byte_block = 1; /* 0 -> bytes, 1 -> 512 byte blocks */
 
76
    int t_length = 0;   /* 0 -> no data transferred, 2 -> sector count */
 
77
    const unsigned char * ucp = NULL;
 
78
 
 
79
    for (k = 1; k < argc; ++k) {
 
80
        if (0 == strcmp(argv[k], "-v"))
 
81
            ++verbose;
 
82
        else if (0 == strcmp(argv[k], "-vv"))
 
83
            verbose += 2;
 
84
        else if (0 == strcmp(argv[k], "-V")) {
 
85
            fprintf(stderr, "version: %s\n", version_str);
 
86
            exit(0);
 
87
        } else if (*argv[k] == '-') {
 
88
            printf("Unrecognized switch: %s\n", argv[k]);
 
89
            file_name = 0;
 
90
            break;
 
91
        }
 
92
        else if (0 == file_name)
 
93
            file_name = argv[k];
 
94
        else {
 
95
            printf("too many arguments\n");
 
96
            file_name = 0;
 
97
            break;
 
98
        }
 
99
    }
 
100
    if (0 == file_name) {
 
101
        printf("Usage: 'sg_sat_chk_power [-v] [-V] <device>'\n");
 
102
        return 1;
 
103
    }
 
104
 
 
105
    if ((sg_fd = open(file_name, O_RDWR)) < 0) {
 
106
        snprintf(ebuff, EBUFF_SZ,
 
107
                 "sg_sat_chk_power: error opening file: %s", file_name);
 
108
        perror(ebuff);
 
109
        return 1;
 
110
    }
 
111
 
 
112
    /* Prepare ATA PASS THROUGH COMMAND (16) command */
 
113
    aptCmdBlk[14] = ATA_CHECK_POWER_MODE;
 
114
    aptCmdBlk[1] = (protocol << 1) | extend;
 
115
    aptCmdBlk[2] = (chk_cond << 5) | (t_dir << 3) |
 
116
                   (byte_block << 2) | t_length;
 
117
    if (verbose) {
 
118
        fprintf(stderr, "    ata pass through(16) cdb: ");
 
119
        for (k = 0; k < SAT_ATA_PASS_THROUGH16_LEN; ++k)
 
120
            fprintf(stderr, "%02x ", aptCmdBlk[k]);
 
121
        fprintf(stderr, "\n");
 
122
    }
 
123
 
 
124
    memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
 
125
    io_hdr.interface_id = 'S';
 
126
    io_hdr.cmd_len = sizeof(aptCmdBlk);
 
127
    /* io_hdr.iovec_count = 0; */  /* memset takes care of this */
 
128
    io_hdr.mx_sb_len = sizeof(sense_buffer);
 
129
    io_hdr.dxfer_direction = SG_DXFER_NONE;
 
130
    io_hdr.dxfer_len = 0;
 
131
    io_hdr.dxferp = NULL;
 
132
    io_hdr.cmdp = aptCmdBlk;
 
133
    io_hdr.sbp = sense_buffer;
 
134
    io_hdr.timeout = 20000;     /* 20000 millisecs == 20 seconds */
 
135
    /* io_hdr.flags = 0; */     /* take defaults: indirect IO, etc */
 
136
    /* io_hdr.pack_id = 0; */
 
137
    /* io_hdr.usr_ptr = NULL; */
 
138
 
 
139
    if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
 
140
        perror("sg_sat_chk_power: SG_IO ioctl error");
 
141
        close(sg_fd);
 
142
        return 1;
 
143
    }
 
144
 
 
145
    /* error processing: N.B. expect check condition, no sense ... !! */
 
146
    switch (sg_err_category3(&io_hdr)) {
 
147
    case SG_LIB_CAT_CLEAN:
 
148
        break;
 
149
    case SG_LIB_CAT_RECOVERED:
 
150
    case SG_LIB_CAT_NO_SENSE:
 
151
        /* XXX: Until the spec decides which one to go with. 20060607 */
 
152
        ucp = sg_scsi_sense_desc_find(sense_buffer, sizeof(sense_buffer),
 
153
                                      SAT_STATUS_RETURN_DESC);
 
154
        if (NULL == ucp)
 
155
            sg_chk_n_print3("ATA_16 command error", &io_hdr, 1);
 
156
        else if (verbose)
 
157
            sg_chk_n_print3("status return descriptor, as expected",
 
158
                             &io_hdr, 1);
 
159
        if (ucp && ucp[3]) {
 
160
            if (ucp[3] & 0x4)
 
161
                printf("error in returned FIS: aborted command\n");
 
162
            else
 
163
                printf("error=0x%x, status=0x%x\n", ucp[3], ucp[13]);
 
164
        }
 
165
        break;
 
166
    default:
 
167
        fprintf(stderr, "unexpected SCSI sense category\n");
 
168
        ucp = sg_scsi_sense_desc_find(sense_buffer, sizeof(sense_buffer),
 
169
                                      SAT_STATUS_RETURN_DESC);
 
170
        if (NULL == ucp)
 
171
            sg_chk_n_print3("ATA_16 command error", &io_hdr, 1);
 
172
        else if (verbose)
 
173
            sg_chk_n_print3("status return descriptor, as expected",
 
174
                             &io_hdr, 1);
 
175
        if (ucp && ucp[3]) {
 
176
            if (ucp[3] & 0x4)
 
177
                printf("error in returned FIS: aborted command\n");
 
178
            else
 
179
                printf("error=0x%x, status=0x%x\n", ucp[3], ucp[13]);
 
180
        }
 
181
        break;
 
182
    }
 
183
 
 
184
    if (ucp) {
 
185
        switch (ucp[5]) {       /* sector_count (7:0) */
 
186
        case 0xff:
 
187
            printf("In active mode or idle mode\n");
 
188
            break;
 
189
        case 0x80:
 
190
            printf("In idle mode\n");
 
191
            break;
 
192
        case 0x41:
 
193
            printf("In NV power mode and spindle is spun or spinning up\n");
 
194
            break;
 
195
        case 0x40:
 
196
            printf("In NV power mode and spindle is spun or spinning down\n");
 
197
            break;
 
198
        case 0x0:
 
199
            printf("In standby mode\n");
 
200
            break;
 
201
        default:
 
202
            printf("unknown power mode (sector count) value=0x%x\n", ucp[5]);
 
203
            break;
 
204
        }
 
205
    } else
 
206
        fprintf(stderr, "Expecting a special error return and didn't "
 
207
                "receive it\n");
 
208
 
 
209
    close(sg_fd);
 
210
    return 0;
 
211
}