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