aboutsummaryrefslogtreecommitdiff
path: root/hw/lsi53c895a.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2011-04-22 12:27:30 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2011-05-26 12:14:17 +0200
commitc6df7102f5ebf3c9008718d044b78f1ae57aa627 (patch)
tree9323e5b386bf7749e03e3b010b044fa4c0fb029a /hw/lsi53c895a.c
parent3944966d957c361a2c1eb853ebfaa51287a5f125 (diff)
scsi: split command_complete callback in two
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Cc: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'hw/lsi53c895a.c')
-rw-r--r--hw/lsi53c895a.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 43113a17a7..c965ed40d8 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -711,32 +711,37 @@ static int lsi_queue_tag(LSIState *s, uint32_t tag, uint32_t arg)
return 1;
}
}
- /* Callback to indicate that the SCSI layer has completed a transfer. */
-static void lsi_command_complete(SCSIRequest *req, int reason, uint32_t arg)
+
+ /* Callback to indicate that the SCSI layer has completed a command. */
+static void lsi_command_complete(SCSIRequest *req, uint32_t arg)
{
LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
int out;
out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
- if (reason == SCSI_REASON_DONE) {
- DPRINTF("Command complete status=%d\n", (int)arg);
- s->status = arg;
- s->command_complete = 2;
- if (s->waiting && s->dbc != 0) {
- /* Raise phase mismatch for short transfers. */
- lsi_bad_phase(s, out, PHASE_ST);
- } else {
- lsi_set_phase(s, PHASE_ST);
- }
+ DPRINTF("Command complete status=%d\n", (int)arg);
+ s->status = arg;
+ s->command_complete = 2;
+ if (s->waiting && s->dbc != 0) {
+ /* Raise phase mismatch for short transfers. */
+ lsi_bad_phase(s, out, PHASE_ST);
+ } else {
+ lsi_set_phase(s, PHASE_ST);
+ }
- if (s->current && req == s->current->req) {
- scsi_req_unref(s->current->req);
- qemu_free(s->current);
- s->current = NULL;
- }
- lsi_resume_script(s);
- return;
+ if (s->current && req == s->current->req) {
+ scsi_req_unref(s->current->req);
+ qemu_free(s->current);
+ s->current = NULL;
}
+ lsi_resume_script(s);
+}
+
+ /* Callback to indicate that the SCSI layer has completed a transfer. */
+static void lsi_transfer_data(SCSIRequest *req, uint32_t arg)
+{
+ LSIState *s = DO_UPCAST(LSIState, dev.qdev, req->bus->qbus.parent);
+ int out;
if (s->waiting == 1 || !s->current || req->tag != s->current->tag ||
(lsi_irq_on_rsl(s) && !(s->scntl1 & LSI_SCNTL1_CON))) {
@@ -745,16 +750,18 @@ static void lsi_command_complete(SCSIRequest *req, int reason, uint32_t arg)
}
}
+ out = (s->sstat1 & PHASE_MASK) == PHASE_DO;
+
/* host adapter (re)connected */
DPRINTF("Data ready tag=0x%x len=%d\n", req->tag, arg);
s->current->dma_len = arg;
s->command_complete = 1;
- if (!s->waiting)
- return;
- if (s->waiting == 1 || s->dbc == 0) {
- lsi_resume_script(s);
- } else {
- lsi_do_dma(s, out);
+ if (s->waiting) {
+ if (s->waiting == 1 || s->dbc == 0) {
+ lsi_resume_script(s);
+ } else {
+ lsi_do_dma(s, out);
+ }
}
}
@@ -2239,6 +2246,7 @@ static int lsi_scsi_uninit(PCIDevice *d)
}
static const struct SCSIBusOps lsi_scsi_ops = {
+ .transfer_data = lsi_transfer_data,
.complete = lsi_command_complete,
.cancel = lsi_request_cancelled
};