Revision 74382217

b/hw/scsi-bus.c
156 156
    return req->dev->info->get_buf(req);
157 157
}
158 158

  
159
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
160
{
161
    if (req->dev->info->get_sense) {
162
        return req->dev->info->get_sense(req, buf, len);
163
    } else {
164
        return 0;
165
    }
166
}
167

  
159 168
int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
160 169
{
161 170
    int32_t rc;
b/hw/scsi-disk.c
340 340
    return (uint8_t *)r->iov.iov_base;
341 341
}
342 342

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

  
348
    return scsi_build_sense(s->sense, outbuf, len, len > 14);
349
}
350

  
343 351
static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
344 352
{
345 353
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
......
1257 1265
        .write_data   = scsi_write_data,
1258 1266
        .cancel_io    = scsi_cancel_io,
1259 1267
        .get_buf      = scsi_get_buf,
1268
        .get_sense    = scsi_get_sense,
1260 1269
        .qdev.props   = (Property[]) {
1261 1270
            DEFINE_SCSI_DISK_PROPERTIES(),
1262 1271
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
......
1277 1286
        .write_data   = scsi_write_data,
1278 1287
        .cancel_io    = scsi_cancel_io,
1279 1288
        .get_buf      = scsi_get_buf,
1289
        .get_sense    = scsi_get_sense,
1280 1290
        .qdev.props   = (Property[]) {
1281 1291
            DEFINE_SCSI_DISK_PROPERTIES(),
1282 1292
            DEFINE_PROP_END_OF_LIST(),
......
1296 1306
        .write_data   = scsi_write_data,
1297 1307
        .cancel_io    = scsi_cancel_io,
1298 1308
        .get_buf      = scsi_get_buf,
1309
        .get_sense    = scsi_get_sense,
1299 1310
        .qdev.props   = (Property[]) {
1300 1311
            DEFINE_SCSI_DISK_PROPERTIES(),
1301 1312
            DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
b/hw/scsi-generic.c
79 79
    s->driver_status = 0;
80 80
}
81 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

  
82 99
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun)
83 100
{
84 101
    SCSIRequest *req;
......
535 552
    .write_data   = scsi_write_data,
536 553
    .cancel_io    = scsi_cancel_io,
537 554
    .get_buf      = scsi_get_buf,
555
    .get_sense    = scsi_get_sense,
538 556
    .qdev.props   = (Property[]) {
539 557
        DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
540 558
        DEFINE_PROP_END_OF_LIST(),
b/hw/scsi.h
80 80
    int (*write_data)(SCSIRequest *req);
81 81
    void (*cancel_io)(SCSIRequest *req);
82 82
    uint8_t *(*get_buf)(SCSIRequest *req);
83
    int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len);
83 84
};
84 85

  
85 86
struct SCSIBusOps {
......
155 156
void scsi_req_data(SCSIRequest *req, int len);
156 157
void scsi_req_complete(SCSIRequest *req);
157 158
uint8_t *scsi_req_get_buf(SCSIRequest *req);
159
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
158 160
void scsi_req_abort(SCSIRequest *req, int status);
159 161
void scsi_req_cancel(SCSIRequest *req);
160 162
void scsi_device_purge_requests(SCSIDevice *sdev);
b/hw/spapr_vscsi.c
450 450
    uint8_t *cdb = req->iu.srp.cmd.cdb;
451 451
    int n;
452 452

  
453
    n = scsi_req_get_sense(req->sreq, req->sense, sizeof(req->sense));
454
    if (n) {
455
        req->senselen = n;
456
        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
457
        vscsi_put_req(s, req);
458
        return;
459
    }
460

  
461
    dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
453 462
    cdb[0] = 3;
454 463
    cdb[1] = 0;
455 464
    cdb[2] = 0;
......
522 531
            }
523 532
            vscsi_send_rsp(s, req, 0, res_in, res_out);
524 533
        } else if (arg == CHECK_CONDITION) {
525
            dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
526 534
            vscsi_send_request_sense(s, req);
527 535
            return;
528 536
        } else {

Also available in: Unified diff