Revision aba1f023
b/hw/esp.c | ||
---|---|---|
395 | 395 |
esp_dma_done(s); |
396 | 396 |
} |
397 | 397 |
|
398 |
static void esp_command_complete(SCSIRequest *req, uint32_t arg)
|
|
398 |
static void esp_command_complete(SCSIRequest *req, uint32_t status)
|
|
399 | 399 |
{ |
400 | 400 |
ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); |
401 | 401 |
|
... | ... | |
406 | 406 |
s->ti_size = 0; |
407 | 407 |
s->dma_left = 0; |
408 | 408 |
s->async_len = 0; |
409 |
if (arg) {
|
|
409 |
if (status) {
|
|
410 | 410 |
DPRINTF("Command failed\n"); |
411 | 411 |
} |
412 |
s->status = arg;
|
|
412 |
s->status = status;
|
|
413 | 413 |
s->rregs[ESP_RSTAT] = STAT_ST; |
414 | 414 |
esp_dma_done(s); |
415 | 415 |
if (s->current_req) { |
... | ... | |
419 | 419 |
} |
420 | 420 |
} |
421 | 421 |
|
422 |
static void esp_transfer_data(SCSIRequest *req, uint32_t arg)
|
|
422 |
static void esp_transfer_data(SCSIRequest *req, uint32_t len)
|
|
423 | 423 |
{ |
424 | 424 |
ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); |
425 | 425 |
|
426 | 426 |
DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); |
427 |
s->async_len = arg;
|
|
427 |
s->async_len = len;
|
|
428 | 428 |
s->async_buf = scsi_req_get_buf(req); |
429 | 429 |
if (s->dma_left) { |
430 | 430 |
esp_do_dma(s); |
b/hw/lsi53c895a.c | ||
---|---|---|
680 | 680 |
|
681 | 681 |
/* Record that data is available for a queued command. Returns zero if |
682 | 682 |
the device was reselected, nonzero if the IO is deferred. */ |
683 |
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
|
|
683 |
static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t len)
|
|
684 | 684 |
{ |
685 | 685 |
lsi_request *p; |
686 | 686 |
|
... | ... | |
693 | 693 |
if (p->pending) { |
694 | 694 |
BADF("Multiple IO pending for tag %d\n", tag); |
695 | 695 |
} |
696 |
p->pending = arg;
|
|
696 |
p->pending = len;
|
|
697 | 697 |
/* Reselect if waiting for it, or if reselection triggers an IRQ |
698 | 698 |
and the bus is free. |
699 | 699 |
Since no interrupt stacking is implemented in the emulation, it |
... | ... | |
707 | 707 |
return 0; |
708 | 708 |
} else { |
709 | 709 |
DPRINTF("Queueing IO tag=0x%x\n", tag); |
710 |
p->pending = arg;
|
|
710 |
p->pending = len;
|
|
711 | 711 |
return 1; |
712 | 712 |
} |
713 | 713 |
} |
714 | 714 |
|
715 | 715 |
/* Callback to indicate that the SCSI layer has completed a command. */ |
716 |
static void lsi_command_complete(SCSIRequest *req, uint32_t arg)
|
|
716 |
static void lsi_command_complete(SCSIRequest *req, uint32_t status)
|
|
717 | 717 |
{ |
718 | 718 |
LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); |
719 | 719 |
int out; |
720 | 720 |
|
721 | 721 |
out = (s->sstat1 & PHASE_MASK) == PHASE_DO; |
722 |
DPRINTF("Command complete status=%d\n", (int)arg);
|
|
723 |
s->status = arg;
|
|
722 |
DPRINTF("Command complete status=%d\n", (int)status);
|
|
723 |
s->status = status;
|
|
724 | 724 |
s->command_complete = 2; |
725 | 725 |
if (s->waiting && s->dbc != 0) { |
726 | 726 |
/* Raise phase mismatch for short transfers. */ |
... | ... | |
738 | 738 |
} |
739 | 739 |
|
740 | 740 |
/* Callback to indicate that the SCSI layer has completed a transfer. */ |
741 |
static void lsi_transfer_data(SCSIRequest *req, uint32_t arg)
|
|
741 |
static void lsi_transfer_data(SCSIRequest *req, uint32_t len)
|
|
742 | 742 |
{ |
743 | 743 |
LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent); |
744 | 744 |
int out; |
745 | 745 |
|
746 | 746 |
if (s->waiting == 1 || !s->current || req->tag != s->current->tag || |
747 | 747 |
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) { |
748 |
if (lsi_queue_tag(s, req->tag, arg)) {
|
|
748 |
if (lsi_queue_tag(s, req->tag, len)) {
|
|
749 | 749 |
return; |
750 | 750 |
} |
751 | 751 |
} |
... | ... | |
753 | 753 |
out = (s->sstat1 & PHASE_MASK) == PHASE_DO; |
754 | 754 |
|
755 | 755 |
/* host adapter (re)connected */ |
756 |
DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, arg);
|
|
757 |
s->current->dma_len = arg;
|
|
756 |
DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, len);
|
|
757 |
s->current->dma_len = len;
|
|
758 | 758 |
s->command_complete = 1; |
759 | 759 |
if (s->waiting) { |
760 | 760 |
if (s->waiting == 1 || s->dbc == 0) { |
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_transfer_data(SCSIRequest *sreq, uint32_t arg)
|
|
483 |
static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
|
|
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 |
int len, rc = 0;
|
|
488 |
int rc = 0; |
|
489 | 489 |
|
490 |
dprintf("VSCSI: SCSI xfer complete tag=0x%x arg=0x%x, req=%p\n",
|
|
491 |
sreq->tag, arg, req);
|
|
490 |
dprintf("VSCSI: SCSI xfer complete tag=0x%x len=0x%x, req=%p\n",
|
|
491 |
sreq->tag, len, req);
|
|
492 | 492 |
if (req == NULL) { |
493 | 493 |
fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag); |
494 | 494 |
return; |
... | ... | |
497 | 497 |
if (req->sensing) { |
498 | 498 |
uint8_t *buf = scsi_req_get_buf(sreq); |
499 | 499 |
|
500 |
len = MIN(arg, SCSI_SENSE_BUF_SIZE);
|
|
500 |
len = MIN(len, SCSI_SENSE_BUF_SIZE);
|
|
501 | 501 |
dprintf("VSCSI: Sense data, %d bytes:\n", len); |
502 | 502 |
dprintf(" %02x %02x %02x %02x %02x %02x %02x %02x\n", |
503 | 503 |
buf[0], buf[1], buf[2], buf[3], |
... | ... | |
511 | 511 |
return; |
512 | 512 |
} |
513 | 513 |
|
514 |
/* "arg" is how much we have read for reads and how much we want |
|
515 |
* to write for writes (ie, how much is to be DMA'd) |
|
516 |
*/ |
|
517 |
if (arg) { |
|
514 |
if (len) { |
|
518 | 515 |
buf = scsi_req_get_buf(sreq); |
519 |
rc = vscsi_srp_transfer_data(s, req, req->writing, buf, arg);
|
|
516 |
rc = vscsi_srp_transfer_data(s, req, req->writing, buf, len);
|
|
520 | 517 |
} |
521 | 518 |
if (rc < 0) { |
522 | 519 |
fprintf(stderr, "VSCSI: RDMA error rc=%d!\n", rc); |
... | ... | |
531 | 528 |
} |
532 | 529 |
|
533 | 530 |
/* Callback to indicate that the SCSI layer has completed a transfer. */ |
534 |
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t arg)
|
|
531 |
static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
|
|
535 | 532 |
{ |
536 | 533 |
VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent); |
537 | 534 |
vscsi_req *req = vscsi_find_req(s, sreq); |
538 | 535 |
int32_t res_in = 0, res_out = 0; |
539 | 536 |
|
540 |
dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x arg=0x%x, req=%p\n",
|
|
541 |
reason, sreq->tag, arg, req);
|
|
537 |
dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x status=0x%x, req=%p\n",
|
|
538 |
reason, sreq->tag, status, req);
|
|
542 | 539 |
if (req == NULL) { |
543 | 540 |
fprintf(stderr, "VSCSI: Can't find request for tag 0x%x\n", sreq->tag); |
544 | 541 |
return; |
545 | 542 |
} |
546 | 543 |
|
547 |
if (!req->sensing && arg == CHECK_CONDITION) {
|
|
544 |
if (!req->sensing && status == CHECK_CONDITION) {
|
|
548 | 545 |
vscsi_send_request_sense(s, req); |
549 | 546 |
return; |
550 | 547 |
} |
551 | 548 |
|
552 | 549 |
if (req->sensing) { |
553 | 550 |
dprintf("VSCSI: Sense done !\n"); |
554 |
arg = CHECK_CONDITION;
|
|
551 |
status = CHECK_CONDITION;
|
|
555 | 552 |
} else { |
556 |
dprintf("VSCSI: Command complete err=%d\n", arg);
|
|
557 |
if (arg == 0) {
|
|
553 |
dprintf("VSCSI: Command complete err=%d\n", status);
|
|
554 |
if (status == 0) {
|
|
558 | 555 |
/* We handle overflows, not underflows for normal commands, |
559 | 556 |
* but hopefully nobody cares |
560 | 557 |
*/ |
b/hw/usb-msd.c | ||
---|---|---|
208 | 208 |
memcpy(p->data, &csw, len); |
209 | 209 |
} |
210 | 210 |
|
211 |
static void usb_msd_transfer_data(SCSIRequest *req, uint32_t arg)
|
|
211 |
static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
|
|
212 | 212 |
{ |
213 | 213 |
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); |
214 | 214 |
USBPacket *p = s->packet; |
... | ... | |
218 | 218 |
} |
219 | 219 |
|
220 | 220 |
assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); |
221 |
s->scsi_len = arg;
|
|
221 |
s->scsi_len = len;
|
|
222 | 222 |
s->scsi_buf = scsi_req_get_buf(req); |
223 | 223 |
if (p) { |
224 | 224 |
usb_msd_copy_data(s); |
... | ... | |
233 | 233 |
} |
234 | 234 |
} |
235 | 235 |
|
236 |
static void usb_msd_command_complete(SCSIRequest *req, uint32_t arg)
|
|
236 |
static void usb_msd_command_complete(SCSIRequest *req, uint32_t status)
|
|
237 | 237 |
{ |
238 | 238 |
MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); |
239 | 239 |
USBPacket *p = s->packet; |
... | ... | |
241 | 241 |
if (req->tag != s->tag) { |
242 | 242 |
fprintf(stderr, "usb-msd: Unexpected SCSI Tag 0x%x\n", req->tag); |
243 | 243 |
} |
244 |
DPRINTF("Command complete %d\n", arg);
|
|
244 |
DPRINTF("Command complete %d\n", status);
|
|
245 | 245 |
s->residue = s->data_len; |
246 |
s->result = arg != 0;
|
|
246 |
s->result = status != 0;
|
|
247 | 247 |
if (s->packet) { |
248 | 248 |
if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { |
249 | 249 |
/* A deferred packet with no write data remaining must be |
Also available in: Unified diff