~ubuntu-branches/debian/sid/sg3-utils/sid

« back to all changes in this revision

Viewing changes to lib/sg_cmds_extra.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Biebl
  • Date: 2009-11-05 20:42:13 UTC
  • mfrom: (5.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091105204213-ug7wrb6m7l9kmvyg
* QA upload.
* Add libsgutils2-2.symbols.kfreebsd. Some of the symbols are Linux
  specific causing FTBFS on kfreebsd.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (c) 1999-2008 Douglas Gilbert.
 
2
 * Copyright (c) 1999-2009 Douglas Gilbert.
3
3
 * All rights reserved.
4
4
 *
5
5
 * Redistribution and use in source and binary forms, with or without
39
39
#include "sg_cmds_extra.h"
40
40
#include "sg_pt.h"
41
41
 
 
42
#ifdef HAVE_CONFIG_H
 
43
#include "config.h"
 
44
#endif
 
45
 
42
46
 
43
47
 
44
48
#define SENSE_BUFF_LEN 32       /* Arbitrary, could be larger */
65
69
#define PERSISTENT_RESERVE_IN_CMDLEN 10
66
70
#define PERSISTENT_RESERVE_OUT_CMD 0x5f
67
71
#define PERSISTENT_RESERVE_OUT_CMDLEN 10
 
72
#define READ_BLOCK_LIMITS_CMD 0x5
 
73
#define READ_BLOCK_LIMITS_CMDLEN 6
68
74
#define READ_BUFFER_CMD 0x3c
69
75
#define READ_BUFFER_CMDLEN 10
70
76
#define READ_DEFECT10_CMD     0x37
79
85
#define SERVICE_ACTION_IN_12_CMDLEN 12
80
86
#define READ_LONG10_CMD 0x3e
81
87
#define READ_LONG10_CMDLEN 10
 
88
#define UNMAP_CMD 0x42
 
89
#define UNMAP_CMDLEN 10
 
90
#define VERIFY10_CMD 0x2f
 
91
#define VERIFY10_CMDLEN 10
82
92
#define WRITE_LONG10_CMD 0x3f
83
93
#define WRITE_LONG10_CMDLEN 10
84
94
#define WRITE_BUFFER_CMD 0x3b
85
95
#define WRITE_BUFFER_CMDLEN 10
86
 
#define VERIFY10_CMD 0x2f
87
 
#define VERIFY10_CMDLEN 10
88
96
 
 
97
#define GET_LBA_STATUS_SA 0x12
89
98
#define READ_LONG_16_SA 0x11
90
99
#define READ_MEDIA_SERIAL_NUM_SA 0x1
91
100
#define REPORT_IDENTIFYING_INFORMATION_SA 0x5
95
104
#define WRITE_LONG_16_SA 0x11
96
105
 
97
106
 
 
107
/* Invokes a SCSI GET LBA STATUS command (SBC). Returns 0 -> success,
 
108
 * SG_LIB_CAT_INVALID_OP -> GET LBA STATUS not supported,
 
109
 * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
 
110
 * SG_LIB_CAT_NOT_READY -> device not ready, -1 -> other failure */
 
111
int
 
112
sg_ll_get_lba_status(int sg_fd, uint64_t start_llba, void * resp,
 
113
                     int alloc_len, int noisy, int verbose)
 
114
{
 
115
    int k, res, sense_cat, ret;
 
116
    unsigned char getLbaStatCmd[SERVICE_ACTION_IN_16_CMDLEN];
 
117
    unsigned char sense_b[SENSE_BUFF_LEN];
 
118
    struct sg_pt_base * ptvp;
 
119
 
 
120
    memset(getLbaStatCmd, 0, sizeof(getLbaStatCmd));
 
121
    getLbaStatCmd[0] = SERVICE_ACTION_IN_16_CMD;
 
122
    getLbaStatCmd[1] = GET_LBA_STATUS_SA;
 
123
 
 
124
    getLbaStatCmd[2] = (start_llba >> 56) & 0xff;
 
125
    getLbaStatCmd[3] = (start_llba >> 48) & 0xff;
 
126
    getLbaStatCmd[4] = (start_llba >> 40) & 0xff;
 
127
    getLbaStatCmd[5] = (start_llba >> 32) & 0xff;
 
128
    getLbaStatCmd[6] = (start_llba >> 24) & 0xff;
 
129
    getLbaStatCmd[7] = (start_llba >> 16) & 0xff;
 
130
    getLbaStatCmd[8] = (start_llba >> 8) & 0xff;
 
131
    getLbaStatCmd[9] = start_llba & 0xff;
 
132
    getLbaStatCmd[10] = (alloc_len >> 24) & 0xff;
 
133
    getLbaStatCmd[11] = (alloc_len >> 16) & 0xff;
 
134
    getLbaStatCmd[12] = (alloc_len >> 8) & 0xff;
 
135
    getLbaStatCmd[13] = alloc_len & 0xff;
 
136
    if (NULL == sg_warnings_strm)
 
137
        sg_warnings_strm = stderr;
 
138
    if (verbose) {
 
139
        fprintf(sg_warnings_strm, "    Get LBA status cmd: ");
 
140
        for (k = 0; k < SERVICE_ACTION_IN_16_CMDLEN; ++k)
 
141
            fprintf(sg_warnings_strm, "%02x ", getLbaStatCmd[k]);
 
142
        fprintf(sg_warnings_strm, "\n");
 
143
    }
 
144
 
 
145
    ptvp = construct_scsi_pt_obj();
 
146
    if (NULL == ptvp) {
 
147
        fprintf(sg_warnings_strm, "get LBA status: out of memory\n");
 
148
        return -1;
 
149
    }
 
150
    set_scsi_pt_cdb(ptvp, getLbaStatCmd, sizeof(getLbaStatCmd));
 
151
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
 
152
    set_scsi_pt_data_in(ptvp, (unsigned char *)resp, alloc_len);
 
153
    res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
 
154
    ret = sg_cmds_process_resp(ptvp, "get LBA status", res, alloc_len,
 
155
                               sense_b, noisy, verbose, &sense_cat);
 
156
    if (-1 == ret)
 
157
        ;
 
158
    else if (-2 == ret) {
 
159
        switch (sense_cat) {
 
160
        case SG_LIB_CAT_NOT_READY:
 
161
        case SG_LIB_CAT_ILLEGAL_REQ:
 
162
        case SG_LIB_CAT_INVALID_OP:
 
163
        case SG_LIB_CAT_UNIT_ATTENTION:
 
164
        case SG_LIB_CAT_ABORTED_COMMAND:
 
165
            ret = sense_cat;
 
166
            break;
 
167
        case SG_LIB_CAT_RECOVERED:
 
168
        case SG_LIB_CAT_NO_SENSE:
 
169
            ret = 0;
 
170
            break;
 
171
        default:
 
172
            ret = -1;
 
173
            break;
 
174
        }
 
175
    } else
 
176
        ret = 0;
 
177
    destruct_scsi_pt_obj(ptvp);
 
178
    return ret;
 
179
}
 
180
 
98
181
/* Invokes a SCSI REPORT TARGET PORT GROUPS command. Return of 0 -> success,
99
182
 * SG_LIB_CAT_INVALID_OP -> Report Target Port Groups not supported,
100
183
 * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
1760
1843
    destruct_scsi_pt_obj(ptvp);
1761
1844
    return ret;
1762
1845
}
 
1846
 
 
1847
/* Invokes a SCSI UNMAP command. Return of 0 -> success,
 
1848
 * SG_LIB_CAT_INVALID_OP -> command not supported,
 
1849
 * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb, SG_LIB_CAT_ABORTED_COMMAND,
 
1850
 * SG_LIB_CAT_UNIT_ATTENTION, -1 -> other failure */
 
1851
int
 
1852
sg_ll_unmap(int sg_fd, int group_num, int timeout_secs, void * paramp,
 
1853
            int param_len, int noisy, int verbose)
 
1854
{
 
1855
    int k, res, ret, sense_cat, tmout;
 
1856
    unsigned char uCmdBlk[UNMAP_CMDLEN] =
 
1857
                         {UNMAP_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
1858
    unsigned char sense_b[SENSE_BUFF_LEN];
 
1859
    struct sg_pt_base * ptvp;
 
1860
 
 
1861
    tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
 
1862
    uCmdBlk[7] = group_num & 0x1f;
 
1863
    uCmdBlk[7] = (param_len >> 8) & 0xff;
 
1864
    uCmdBlk[8] = param_len & 0xff;
 
1865
    if (NULL == sg_warnings_strm)
 
1866
        sg_warnings_strm = stderr;
 
1867
    if (verbose) {
 
1868
        fprintf(sg_warnings_strm, "    unmap cdb: ");
 
1869
        for (k = 0; k < UNMAP_CMDLEN; ++k)
 
1870
            fprintf(sg_warnings_strm, "%02x ", uCmdBlk[k]);
 
1871
        fprintf(sg_warnings_strm, "\n");
 
1872
        if ((verbose > 1) && paramp && param_len) {
 
1873
            fprintf(sg_warnings_strm, "    unmap parameter list:\n");
 
1874
            dStrHex((const char *)paramp, param_len, -1);
 
1875
        }
 
1876
    }
 
1877
 
 
1878
    ptvp = construct_scsi_pt_obj();
 
1879
    if (NULL == ptvp) {
 
1880
        fprintf(sg_warnings_strm, "unmap: out of memory\n");
 
1881
        return -1;
 
1882
    }
 
1883
    set_scsi_pt_cdb(ptvp, uCmdBlk, sizeof(uCmdBlk));
 
1884
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
 
1885
    set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, param_len);
 
1886
    res = do_scsi_pt(ptvp, sg_fd, tmout, verbose);
 
1887
    ret = sg_cmds_process_resp(ptvp, "unmap", res, 0,
 
1888
                               sense_b, noisy, verbose, &sense_cat);
 
1889
    if (-1 == ret)
 
1890
        ;
 
1891
    else if (-2 == ret) {
 
1892
        switch (sense_cat) {
 
1893
        case SG_LIB_CAT_INVALID_OP:
 
1894
        case SG_LIB_CAT_ILLEGAL_REQ:
 
1895
        case SG_LIB_CAT_UNIT_ATTENTION:
 
1896
        case SG_LIB_CAT_ABORTED_COMMAND:
 
1897
            ret = sense_cat;
 
1898
            break;
 
1899
        case SG_LIB_CAT_RECOVERED:
 
1900
        case SG_LIB_CAT_NO_SENSE:
 
1901
            ret = 0;
 
1902
            break;
 
1903
        default:
 
1904
            ret = -1;
 
1905
            break;
 
1906
        }
 
1907
    } else
 
1908
        ret = 0;
 
1909
    destruct_scsi_pt_obj(ptvp);
 
1910
    return ret;
 
1911
}
 
1912
 
 
1913
/* Invokes a SCSI READ BLOCK LIMITS command. Return of 0 -> success,
 
1914
 * SG_LIB_CAT_INVALID_OP -> Read block limits not supported,
 
1915
 * SG_LIB_CAT_ILLEGAL_REQ -> bad field in cdb,
 
1916
 * SG_LIB_CAT_ABORTED_COMMAND,
 
1917
 * SG_LIB_NOT_READY (shouldn't happen), -1 -> other failure */
 
1918
int
 
1919
sg_ll_read_block_limits(int sg_fd, void * resp, int mx_resp_len,
 
1920
                        int noisy, int verbose)
 
1921
{
 
1922
    int k, ret, res, sense_cat;
 
1923
    unsigned char rlCmdBlk[READ_BLOCK_LIMITS_CMDLEN] = 
 
1924
      {READ_BLOCK_LIMITS_CMD, 0, 0, 0, 0, 0};
 
1925
    unsigned char sense_b[SENSE_BUFF_LEN];
 
1926
    struct sg_pt_base * ptvp;
 
1927
 
 
1928
    if (NULL == sg_warnings_strm)
 
1929
        sg_warnings_strm = stderr;
 
1930
    if (verbose) {
 
1931
        fprintf(sg_warnings_strm, "    read block limits cdb: ");
 
1932
        for (k = 0; k < READ_BLOCK_LIMITS_CMDLEN; ++k)
 
1933
            fprintf(sg_warnings_strm, "%02x ", rlCmdBlk[k]);
 
1934
        fprintf(sg_warnings_strm, "\n");
 
1935
    }
 
1936
 
 
1937
    ptvp = construct_scsi_pt_obj();
 
1938
    if (NULL == ptvp) {
 
1939
        fprintf(sg_warnings_strm, "read block limits: out of memory\n");
 
1940
        return -1;
 
1941
    }
 
1942
    set_scsi_pt_cdb(ptvp, rlCmdBlk, sizeof(rlCmdBlk));
 
1943
    set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
 
1944
    set_scsi_pt_data_in(ptvp, (unsigned char *)resp, mx_resp_len);
 
1945
    res = do_scsi_pt(ptvp, sg_fd, DEF_PT_TIMEOUT, verbose);
 
1946
    ret = sg_cmds_process_resp(ptvp, "read block limits", res, mx_resp_len,
 
1947
                               sense_b, noisy, verbose, &sense_cat);
 
1948
    if (-1 == ret)
 
1949
        ;
 
1950
    else if (-2 == ret) {
 
1951
        switch (sense_cat) {
 
1952
        case SG_LIB_CAT_INVALID_OP:
 
1953
        case SG_LIB_CAT_ILLEGAL_REQ:
 
1954
        case SG_LIB_CAT_ABORTED_COMMAND:
 
1955
        case SG_LIB_CAT_NOT_READY:      /* shouldn't happen ?? */
 
1956
            ret = sense_cat;
 
1957
            break;
 
1958
        case SG_LIB_CAT_RECOVERED:
 
1959
        case SG_LIB_CAT_NO_SENSE:
 
1960
            ret = 0;
 
1961
            break;
 
1962
        default:
 
1963
            ret = -1;
 
1964
            break;
 
1965
        }
 
1966
    } else
 
1967
        ret = 0;
 
1968
    destruct_scsi_pt_obj(ptvp);
 
1969
    return ret;
 
1970
}
 
1971