Revision b45ef674

b/hw/scsi-bus.c
7 7
#include "trace.h"
8 8

  
9 9
static char *scsibus_get_fw_dev_path(DeviceState *dev);
10
static int scsi_build_sense(uint8_t *in_buf, int in_len,
11
                            uint8_t *buf, int len, bool fixed);
10 12

  
11 13
static struct BusInfo scsi_bus_info = {
12 14
    .name  = "SCSI",
......
144 146
    req->lun = lun;
145 147
    req->hba_private = hba_private;
146 148
    req->status = -1;
149
    req->sense_len = 0;
147 150
    trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
148 151
    return req;
149 152
}
......
161 164

  
162 165
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
163 166
{
164
    if (req->dev->info->get_sense) {
165
        return req->dev->info->get_sense(req, buf, len);
166
    } else {
167
    assert(len >= 14);
168
    if (!req->sense_len) {
167 169
        return 0;
168 170
    }
171
    return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
172
}
173

  
174
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
175
{
176
    return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed);
177
}
178

  
179
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
180
{
181
    trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
182
                               sense.key, sense.asc, sense.ascq);
183
    memset(req->sense, 0, 18);
184
    req->sense[0] = 0xf0;
185
    req->sense[2] = sense.key;
186
    req->sense[12] = sense.asc;
187
    req->sense[13] = sense.ascq;
188
    req->sense_len = 18;
169 189
}
170 190

  
171 191
int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
......
484 504
/*
485 505
 * scsi_build_sense
486 506
 *
487
 * Build a sense buffer
507
 * Convert between fixed and descriptor sense buffers
488 508
 */
489
int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed)
509
int scsi_build_sense(uint8_t *in_buf, int in_len,
510
                     uint8_t *buf, int len, bool fixed)
490 511
{
512
    bool fixed_in;
513
    SCSISense sense;
491 514
    if (!fixed && len < 8) {
492 515
        return 0;
493 516
    }
494 517

  
518
    if (in_len == 0) {
519
        sense.key = NO_SENSE;
520
        sense.asc = 0;
521
        sense.ascq = 0;
522
    } else {
523
        fixed_in = (in_buf[0] & 2) == 0;
524

  
525
        if (fixed == fixed_in) {
526
            memcpy(buf, in_buf, MIN(len, in_len));
527
            return MIN(len, in_len);
528
        }
529

  
530
        if (fixed_in) {
531
            sense.key = in_buf[2];
532
            sense.asc = in_buf[12];
533
            sense.ascq = in_buf[13];
534
        } else {
535
            sense.key = in_buf[1];
536
            sense.asc = in_buf[2];
537
            sense.ascq = in_buf[3];
538
        }
539
    }
540

  
495 541
    memset(buf, 0, len);
496 542
    if (fixed) {
497 543
        /* Return fixed format sense buffer */
......
686 732
{
687 733
    assert(req->status == -1);
688 734
    req->status = status;
735

  
736
    assert(req->sense_len < sizeof(req->sense));
737
    if (status == GOOD) {
738
        req->sense_len = 0;
739
    }
740

  
741
    if (req->sense_len) {
742
        memcpy(req->dev->sense, req->sense, req->sense_len);
743
    }
744
    req->dev->sense_len = req->sense_len;
745

  
689 746
    scsi_req_ref(req);
690 747
    scsi_req_dequeue(req);
691 748
    req->bus->ops->complete(req, req->status);
b/hw/scsi-disk.c
71 71
    QEMUBH *bh;
72 72
    char *version;
73 73
    char *serial;
74
    SCSISense sense;
75 74
};
76 75

  
77 76
static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
......
97 96
    qemu_vfree(r->iov.iov_base);
98 97
}
99 98

  
100
static void scsi_disk_clear_sense(SCSIDiskState *s)
99
/* Helper function for command completion with sense.  */
100
static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
101 101
{
102
    memset(&s->sense, 0, sizeof(s->sense));
103
}
104

  
105
/* Helper function for command completion.  */
106
static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
107
{
108
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
109

  
110 102
    DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
111 103
            r->req.tag, status, sense.key, sense.asc, sense.ascq);
112
    s->sense = sense;
113
    scsi_req_complete(&r->req, status);
104
    scsi_req_build_sense(&r->req, sense);
105
    scsi_req_complete(&r->req, CHECK_CONDITION);
114 106
}
115 107

  
116 108
/* Cancel a pending data transfer.  */
......
162 154
    }
163 155
    DPRINTF("Read sector_count=%d\n", r->sector_count);
164 156
    if (r->sector_count == 0) {
165
        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
157
        /* This also clears the sense buffer for REQUEST SENSE.  */
158
        scsi_req_complete(&r->req, GOOD);
166 159
        return;
167 160
    }
168 161

  
......
210 203
    } else {
211 204
        switch (error) {
212 205
        case ENOMEM:
213
            scsi_command_complete(r, CHECK_CONDITION,
214
                                  SENSE_CODE(TARGET_FAILURE));
206
            scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
215 207
            break;
216 208
        case EINVAL:
217
            scsi_command_complete(r, CHECK_CONDITION,
218
                                  SENSE_CODE(INVALID_FIELD));
209
            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
219 210
            break;
220 211
        default:
221
            scsi_command_complete(r, CHECK_CONDITION,
222
                                  SENSE_CODE(IO_ERROR));
212
            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
223 213
            break;
224 214
        }
225 215
        bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
......
245 235
    r->sector += n;
246 236
    r->sector_count -= n;
247 237
    if (r->sector_count == 0) {
248
        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
238
        scsi_req_complete(&r->req, GOOD);
249 239
    } else {
250 240
        len = r->sector_count * 512;
251 241
        if (len > SCSI_DMA_BUF_SIZE) {
......
314 304
            case SCSI_REQ_STATUS_RETRY_FLUSH:
315 305
                ret = scsi_disk_emulate_command(r, r->iov.iov_base);
316 306
                if (ret == 0) {
317
                    scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
307
                    scsi_req_complete(&r->req, GOOD);
318 308
                }
319 309
            }
320 310
        }
......
342 332
    return (uint8_t *)r->iov.iov_base;
343 333
}
344 334

  
345
/* Copy sense information into the provided buffer */
346
static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
347
{
348
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
349

  
350
    return scsi_build_sense(s->sense, outbuf, len, len > 14);
351
}
352

  
353 335
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
354 336
{
355 337
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
......
827 809
    case REQUEST_SENSE:
828 810
        if (req->cmd.xfer < 4)
829 811
            goto illegal_request;
830
        buflen = scsi_build_sense(s->sense, outbuf, req->cmd.xfer,
831
                                  req->cmd.xfer > 13);
832
        scsi_disk_clear_sense(s);
812
        buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
813
                                       (req->cmd.buf[1] & 1) == 0);
833 814
        break;
834 815
    case INQUIRY:
835 816
        buflen = scsi_disk_emulate_inquiry(req, outbuf);
......
960 941
    case VERIFY_10:
961 942
        break;
962 943
    default:
963
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
944
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
964 945
        return -1;
965 946
    }
966 947
    return buflen;
967 948

  
968 949
not_ready:
969 950
    if (!bdrv_is_inserted(s->bs)) {
970
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(NO_MEDIUM));
951
        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
971 952
    } else {
972
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LUN_NOT_READY));
953
        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
973 954
    }
974 955
    return -1;
975 956

  
976 957
illegal_request:
977
    scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
958
    scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
978 959
    return -1;
979 960
}
980 961

  
......
998 979

  
999 980
    if (scsi_req_parse(&r->req, buf) != 0) {
1000 981
        BADF("Unsupported command length, command %x\n", command);
1001
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
982
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1002 983
        return 0;
1003 984
    }
1004 985
#ifdef DEBUG_SCSI
......
1015 996
        /* Only LUN 0 supported.  */
1016 997
        DPRINTF("Unimplemented LUN %d\n", req->lun);
1017 998
        if (command != REQUEST_SENSE && command != INQUIRY) {
1018
            scsi_command_complete(r, CHECK_CONDITION,
1019
                                  SENSE_CODE(LUN_NOT_SUPPORTED));
999
            scsi_check_condition(r, SENSE_CODE(LUN_NOT_SUPPORTED));
1020 1000
            return 0;
1021 1001
        }
1022 1002
    }
......
1124 1104
        break;
1125 1105
    default:
1126 1106
        DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
1127
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
1107
        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
1128 1108
        return 0;
1129 1109
    fail:
1130
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
1110
        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
1131 1111
        return 0;
1132 1112
    illegal_lba:
1133
        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LBA_OUT_OF_RANGE));
1113
        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
1134 1114
        return 0;
1135 1115
    }
1136 1116
    if (r->sector_count == 0 && r->iov.iov_len == 0) {
1137
        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
1117
        scsi_req_complete(&r->req, GOOD);
1138 1118
    }
1139 1119
    len = r->sector_count * 512 + r->iov.iov_len;
1140 1120
    if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
......
1266 1246
        .write_data   = scsi_write_data,
1267 1247
        .cancel_io    = scsi_cancel_io,
1268 1248
        .get_buf      = scsi_get_buf,
1269
        .get_sense    = scsi_get_sense,
1270 1249
        .qdev.props   = (Property[]) {
1271 1250
            DEFINE_SCSI_DISK_PROPERTIES(),
1272 1251
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
......
1287 1266
        .write_data   = scsi_write_data,
1288 1267
        .cancel_io    = scsi_cancel_io,
1289 1268
        .get_buf      = scsi_get_buf,
1290
        .get_sense    = scsi_get_sense,
1291 1269
        .qdev.props   = (Property[]) {
1292 1270
            DEFINE_SCSI_DISK_PROPERTIES(),
1293 1271
            DEFINE_PROP_END_OF_LIST(),
......
1307 1285
        .write_data   = scsi_write_data,
1308 1286
        .cancel_io    = scsi_cancel_io,
1309 1287
        .get_buf      = scsi_get_buf,
1310
        .get_sense    = scsi_get_sense,
1311 1288
        .qdev.props   = (Property[]) {
1312 1289
            DEFINE_SCSI_DISK_PROPERTIES(),
1313 1290
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
b/hw/scsi-generic.c
61 61
    SCSIDevice qdev;
62 62
    BlockDriverState *bs;
63 63
    int lun;
64
    int driver_status;
65
    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
66
    uint8_t senselen;
67 64
};
68 65

  
69
static void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
70
{
71
    s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
72
    s->driver_status = SG_ERR_DRIVER_SENSE;
73
}
74

  
75
static void scsi_clear_sense(SCSIGenericState *s)
76
{
77
    memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
78
    s->senselen = 0;
79
    s->driver_status = 0;
80
}
81

  
82
static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
83
{
84
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
85
    int size = SCSI_SENSE_BUF_SIZE;
86

  
87
    if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) {
88
        size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf,
89
                                SCSI_SENSE_BUF_SIZE, 0);
90
    }
91
    if (size > len) {
92
        size = len;
93
    }
94
    memcpy(outbuf, s->sensebuf, size);
95

  
96
    return size;
97
}
98

  
99 66
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
100 67
                                     void *hba_private)
101 68
{
......
117 84
{
118 85
    int status;
119 86
    SCSIGenericReq *r = (SCSIGenericReq *)opaque;
120
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
121 87

  
122 88
    r->req.aiocb = NULL;
123
    s->driver_status = r->io_header.driver_status;
124
    if (s->driver_status & SG_ERR_DRIVER_SENSE)
125
        s->senselen = r->io_header.sb_len_wr;
89
    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE)
90
        r->req.sense_len = r->io_header.sb_len_wr;
126 91

  
127 92
    if (ret != 0) {
128 93
        switch (ret) {
......
131 96
            break;
132 97
        case -EINVAL:
133 98
            status = CHECK_CONDITION;
134
            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
99
            scsi_req_build_sense(&r->req, SENSE_CODE(INVALID_FIELD));
135 100
            break;
136 101
        case -ENOMEM:
137 102
            status = CHECK_CONDITION;
138
            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
103
            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
139 104
            break;
140 105
        default:
141 106
            status = CHECK_CONDITION;
142
            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
107
            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
143 108
            break;
144 109
        }
145 110
    } else {
146
        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
111
        if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) {
147 112
            status = BUSY;
148 113
            BADF("Driver Timeout\n");
149 114
        } else if (r->io_header.status) {
150 115
            status = r->io_header.status;
151
        } else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
116
        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
152 117
            status = CHECK_CONDITION;
153 118
        } else {
154 119
            status = GOOD;
......
176 141
                           SCSIGenericReq *r, int direction,
177 142
			   BlockDriverCompletionFunc *complete)
178 143
{
179
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
180

  
181 144
    r->io_header.interface_id = 'S';
182 145
    r->io_header.dxfer_direction = direction;
183 146
    r->io_header.dxferp = r->buf;
184 147
    r->io_header.dxfer_len = r->buflen;
185 148
    r->io_header.cmdp = r->req.cmd.buf;
186 149
    r->io_header.cmd_len = r->req.cmd.len;
187
    r->io_header.mx_sb_len = sizeof(s->sensebuf);
188
    r->io_header.sbp = s->sensebuf;
150
    r->io_header.mx_sb_len = sizeof(r->req.sense);
151
    r->io_header.sbp = r->req.sense;
189 152
    r->io_header.timeout = MAX_UINT;
190 153
    r->io_header.usr_ptr = r;
191 154
    r->io_header.flags |= SG_FLAG_DIRECT_IO;
......
234 197
        return;
235 198
    }
236 199

  
237
    if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
238
    {
239
        s->senselen = MIN(r->len, s->senselen);
240
        memcpy(r->buf, s->sensebuf, s->senselen);
200
    if (r->req.cmd.buf[0] == REQUEST_SENSE) {
241 201
        r->io_header.driver_status = 0;
242 202
        r->io_header.status = 0;
243
        r->io_header.dxfer_len  = s->senselen;
203
        r->io_header.dxfer_len =
204
            scsi_device_get_sense(&s->qdev, r->buf, r->req.cmd.xfer,
205
                                  (r->req.cmd.buf[1] & 1) == 0);
244 206
        r->len = -1;
245
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
207
        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, r->io_header.dxfer_len);
246 208
        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
247 209
                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
248 210
                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
249
        scsi_req_data(&r->req, s->senselen);
250
        /* Clear sensebuf after REQUEST_SENSE */
251
        scsi_clear_sense(s);
211
        scsi_req_data(&r->req, r->io_header.dxfer_len);
212
        /* The sense buffer is cleared when we return GOOD */
252 213
        return;
253 214
    }
254 215

  
......
342 303

  
343 304
    if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
344 305
        DPRINTF("Unimplemented LUN %d\n", req->lun);
345
        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
306
        scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
346 307
        scsi_req_complete(&r->req, CHECK_CONDITION);
347 308
        return 0;
348 309
    }
......
533 494
        }
534 495
    }
535 496
    DPRINTF("block size %d\n", s->qdev.blocksize);
536
    s->driver_status = 0;
537
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
538 497
    bdrv_set_removable(s->bs, 0);
539 498
    return 0;
540 499
}
......
553 512
    .write_data   = scsi_write_data,
554 513
    .cancel_io    = scsi_cancel_io,
555 514
    .get_buf      = scsi_get_buf,
556
    .get_sense    = scsi_get_sense,
557 515
    .qdev.props   = (Property[]) {
558 516
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
559 517
        DEFINE_PROP_END_OF_LIST(),
b/hw/scsi.h
27 27
    uint8_t ascq;
28 28
} SCSISense;
29 29

  
30
#define SCSI_SENSE_BUF_SIZE 96
31

  
30 32
struct SCSIRequest {
31 33
    SCSIBus           *bus;
32 34
    SCSIDevice        *dev;
......
42 44
        enum SCSIXferMode mode;
43 45
    } cmd;
44 46
    BlockDriverAIOCB  *aiocb;
47
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
48
    uint32_t sense_len;
45 49
    bool enqueued;
46 50
    void *hba_private;
47 51
    QTAILQ_ENTRY(SCSIRequest) next;
......
53 57
    uint32_t id;
54 58
    BlockConf conf;
55 59
    SCSIDeviceInfo *info;
60
    uint8_t sense[SCSI_SENSE_BUF_SIZE];
61
    uint32_t sense_len;
56 62
    QTAILQ_HEAD(, SCSIRequest) requests;
57 63
    int blocksize;
58 64
    int type;
......
76 82
    void (*write_data)(SCSIRequest *req);
77 83
    void (*cancel_io)(SCSIRequest *req);
78 84
    uint8_t *(*get_buf)(SCSIRequest *req);
79
    int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len);
80 85
};
81 86

  
82 87
struct SCSIBusOps {
......
137 142

  
138 143
#define SENSE_CODE(x) sense_code_ ## x
139 144

  
140
int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
141 145
int scsi_sense_valid(SCSISense sense);
142 146

  
143 147
SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
......
149 153
SCSIRequest *scsi_req_ref(SCSIRequest *req);
150 154
void scsi_req_unref(SCSIRequest *req);
151 155

  
156
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
152 157
int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
153 158
void scsi_req_print(SCSIRequest *req);
154 159
void scsi_req_continue(SCSIRequest *req);
......
159 164
void scsi_req_abort(SCSIRequest *req, int status);
160 165
void scsi_req_cancel(SCSIRequest *req);
161 166
void scsi_device_purge_requests(SCSIDevice *sdev);
167
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
162 168

  
163 169
#endif
b/trace-events
251 251
disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
252 252
disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
253 253
disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
254
disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
254 255

  
255 256
# vl.c
256 257
disable vm_state_notify(int running, int reason) "running %d reason %d"

Also available in: Unified diff