Revision aa5dbdc1 hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
306 | 306 |
return (uint8_t *)r->iov.iov_base; |
307 | 307 |
} |
308 | 308 |
|
309 |
static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) |
|
310 |
{ |
|
311 |
BlockDriverState *bdrv = req->dev->dinfo->bdrv; |
|
312 |
int buflen = 0; |
|
313 |
|
|
314 |
switch (req->cmd.buf[0]) { |
|
315 |
case TEST_UNIT_READY: |
|
316 |
if (!bdrv_is_inserted(bdrv)) |
|
317 |
goto not_ready; |
|
318 |
break; |
|
319 |
default: |
|
320 |
goto illegal_request; |
|
321 |
} |
|
322 |
scsi_req_set_status(req, GOOD, NO_SENSE); |
|
323 |
return buflen; |
|
324 |
|
|
325 |
not_ready: |
|
326 |
scsi_req_set_status(req, CHECK_CONDITION, NOT_READY); |
|
327 |
return 0; |
|
328 |
|
|
329 |
illegal_request: |
|
330 |
scsi_req_set_status(req, CHECK_CONDITION, ILLEGAL_REQUEST); |
|
331 |
return 0; |
|
332 |
} |
|
333 |
|
|
309 | 334 |
/* Execute a scsi command. Returns the length of the data expected by the |
310 | 335 |
command. This will be Positive for data transfers from the device |
311 | 336 |
(eg. disk reads), negative for transfers to the device (eg. disk writes), |
... | ... | |
323 | 348 |
uint8_t command; |
324 | 349 |
uint8_t *outbuf; |
325 | 350 |
SCSIDiskReq *r; |
351 |
int rc; |
|
326 | 352 |
|
327 | 353 |
command = buf[0]; |
328 | 354 |
r = scsi_find_request(s, tag); |
... | ... | |
377 | 403 |
printf("\n"); |
378 | 404 |
} |
379 | 405 |
#endif |
406 |
|
|
407 |
if (scsi_req_parse(&r->req, buf) != 0) { |
|
408 |
BADF("Unsupported command length, command %x\n", command); |
|
409 |
goto fail; |
|
410 |
} |
|
411 |
assert(r->req.cmd.len == cmdlen); |
|
412 |
assert(r->req.cmd.lba == lba); |
|
413 |
|
|
380 | 414 |
if (lun || buf[1] >> 5) { |
381 | 415 |
/* Only LUN 0 supported. */ |
382 | 416 |
DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); |
... | ... | |
385 | 419 |
} |
386 | 420 |
switch (command) { |
387 | 421 |
case TEST_UNIT_READY: |
388 |
DPRINTF("Test Unit Ready\n"); |
|
389 |
if (!bdrv_is_inserted(s->qdev.dinfo->bdrv)) |
|
390 |
goto notready; |
|
391 |
break; |
|
422 |
rc = scsi_disk_emulate_command(&r->req, outbuf); |
|
423 |
if (rc > 0) { |
|
424 |
r->iov.iov_len = rc; |
|
425 |
} else { |
|
426 |
scsi_req_complete(&r->req); |
|
427 |
scsi_remove_request(r); |
|
428 |
} |
|
429 |
return rc; |
|
392 | 430 |
case REQUEST_SENSE: |
393 | 431 |
DPRINTF("Request Sense (len %d)\n", len); |
394 | 432 |
if (len < 4) |
... | ... | |
761 | 799 |
outbuf[7] = 0; |
762 | 800 |
r->iov.iov_len = 8; |
763 | 801 |
} else { |
764 |
notready: |
|
765 | 802 |
scsi_command_complete(r, CHECK_CONDITION, NOT_READY); |
766 | 803 |
return 0; |
767 | 804 |
} |
Also available in: Unified diff