Revision c6df7102 hw/spapr_vscsi.c
b/hw/spapr_vscsi.c | ||
---|---|---|
480 | 480 |
} |
481 | 481 |
|
482 | 482 |
/* Callback to indicate that the SCSI layer has completed a transfer. */ |
483 |
static void vscsi_command_complete(SCSIRequest *sreq, int reason, uint32_t arg)
|
|
483 |
static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t arg)
|
|
484 | 484 |
{ |
485 | 485 |
VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); |
486 | 486 |
vscsi_req *req = vscsi_find_req(s, sreq); |
487 | 487 |
uint8_t *buf; |
488 |
int32_t res_in = 0, res_out = 0; |
|
489 | 488 |
int len, rc = 0; |
490 | 489 |
|
491 |
dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x arg=0x%x, req=%p\n",
|
|
492 |
reason, sreq->tag, arg, req);
|
|
490 |
dprintf("VSCSI: SCSI xfer complete tag=0x%x arg=0x%x, req=%p\n",
|
|
491 |
sreq->tag, arg, req); |
|
493 | 492 |
if (req == NULL) { |
494 | 493 |
fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag); |
495 | 494 |
return; |
496 | 495 |
} |
497 | 496 |
|
498 | 497 |
if (req->sensing) { |
499 |
if (reason == SCSI_REASON_DONE) { |
|
500 |
dprintf("VSCSI: Sense done !\n"); |
|
501 |
vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0); |
|
502 |
vscsi_put_req(s, req); |
|
503 |
} else { |
|
504 |
uint8_t *buf = scsi_req_get_buf(sreq); |
|
505 |
|
|
506 |
len = MIN(arg, SCSI_SENSE_BUF_SIZE); |
|
507 |
dprintf("VSCSI: Sense data, %d bytes:\n", len); |
|
508 |
dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
509 |
buf[0], buf[1], buf[2], buf[3], |
|
510 |
buf[4], buf[5], buf[6], buf[7]); |
|
511 |
dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
512 |
buf[8], buf[9], buf[10], buf[11], |
|
513 |
buf[12], buf[13], buf[14], buf[15]); |
|
514 |
memcpy(req->sense, buf, len); |
|
515 |
req->senselen = len; |
|
516 |
scsi_req_continue(req->sreq); |
|
517 |
} |
|
518 |
return; |
|
519 |
} |
|
520 |
|
|
521 |
if (reason == SCSI_REASON_DONE) { |
|
522 |
dprintf("VSCSI: Command complete err=%d\n", arg); |
|
523 |
if (arg == 0) { |
|
524 |
/* We handle overflows, not underflows for normal commands, |
|
525 |
* but hopefully nobody cares |
|
526 |
*/ |
|
527 |
if (req->writing) { |
|
528 |
res_out = req->data_len; |
|
529 |
} else { |
|
530 |
res_in = req->data_len; |
|
531 |
} |
|
532 |
vscsi_send_rsp(s, req, 0, res_in, res_out); |
|
533 |
} else if (arg == CHECK_CONDITION) { |
|
534 |
vscsi_send_request_sense(s, req); |
|
535 |
return; |
|
536 |
} else { |
|
537 |
vscsi_send_rsp(s, req, arg, 0, 0); |
|
538 |
} |
|
539 |
vscsi_put_req(s, req); |
|
498 |
uint8_t *buf = scsi_req_get_buf(sreq); |
|
499 |
|
|
500 |
len = MIN(arg, SCSI_SENSE_BUF_SIZE); |
|
501 |
dprintf("VSCSI: Sense data, %d bytes:\n", len); |
|
502 |
dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
503 |
buf[0], buf[1], buf[2], buf[3], |
|
504 |
buf[4], buf[5], buf[6], buf[7]); |
|
505 |
dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n", |
|
506 |
buf[8], buf[9], buf[10], buf[11], |
|
507 |
buf[12], buf[13], buf[14], buf[15]); |
|
508 |
memcpy(req->sense, buf, len); |
|
509 |
req->senselen = len; |
|
510 |
scsi_req_continue(req->sreq); |
|
540 | 511 |
return; |
541 | 512 |
} |
542 | 513 |
|
... | ... | |
559 | 530 |
scsi_req_continue(sreq); |
560 | 531 |
} |
561 | 532 |
|
533 |
/* Callback to indicate that the SCSI layer has completed a transfer. */ |
|
534 |
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t arg) |
|
535 |
{ |
|
536 |
VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); |
|
537 |
vscsi_req *req = vscsi_find_req(s, sreq); |
|
538 |
int32_t res_in = 0, res_out = 0; |
|
539 |
|
|
540 |
dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x arg=0x%x, req=%p\n", |
|
541 |
reason, sreq->tag, arg, req); |
|
542 |
if (req == NULL) { |
|
543 |
fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag); |
|
544 |
return; |
|
545 |
} |
|
546 |
|
|
547 |
if (!req->sensing && arg == CHECK_CONDITION) { |
|
548 |
vscsi_send_request_sense(s, req); |
|
549 |
return; |
|
550 |
} |
|
551 |
|
|
552 |
if (req->sensing) { |
|
553 |
dprintf("VSCSI: Sense done !\n"); |
|
554 |
arg = CHECK_CONDITION; |
|
555 |
} else { |
|
556 |
dprintf("VSCSI: Command complete err=%d\n", arg); |
|
557 |
if (arg == 0) { |
|
558 |
/* We handle overflows, not underflows for normal commands, |
|
559 |
* but hopefully nobody cares |
|
560 |
*/ |
|
561 |
if (req->writing) { |
|
562 |
res_out = req->data_len; |
|
563 |
} else { |
|
564 |
res_in = req->data_len; |
|
565 |
} |
|
566 |
} |
|
567 |
} |
|
568 |
vscsi_send_rsp(s, req, 0, res_in, res_out); |
|
569 |
vscsi_put_req(s, req); |
|
570 |
} |
|
571 |
|
|
562 | 572 |
static void vscsi_request_cancelled(SCSIRequest *sreq) |
563 | 573 |
{ |
564 | 574 |
VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); |
... | ... | |
916 | 926 |
} |
917 | 927 |
|
918 | 928 |
static const struct SCSIBusOps vscsi_scsi_ops = { |
929 |
.transfer_data = vscsi_transfer_data, |
|
919 | 930 |
.complete = vscsi_command_complete, |
920 | 931 |
.cancel = vscsi_request_cancelled |
921 | 932 |
}; |
Also available in: Unified diff