Revision ad2d30f7 hw/scsi-bus.c
b/hw/scsi-bus.c | ||
---|---|---|
136 | 136 |
SCSIRequest *req; |
137 | 137 |
|
138 | 138 |
req = qemu_mallocz(size); |
139 |
/* Two references: one is passed back to the HBA, one is in d->requests. */ |
|
140 |
req->refcount = 2; |
|
139 | 141 |
req->bus = scsi_bus_from_device(d); |
140 | 142 |
req->dev = d; |
141 | 143 |
req->tag = tag; |
... | ... | |
159 | 161 |
return NULL; |
160 | 162 |
} |
161 | 163 |
|
162 |
static void scsi_req_dequeue(SCSIRequest *req)
|
|
164 |
void scsi_req_dequeue(SCSIRequest *req) |
|
163 | 165 |
{ |
164 | 166 |
trace_scsi_req_dequeue(req->dev->id, req->lun, req->tag); |
165 | 167 |
if (req->enqueued) { |
166 | 168 |
QTAILQ_REMOVE(&req->dev->requests, req, next); |
167 | 169 |
req->enqueued = false; |
170 |
scsi_req_unref(req); |
|
168 | 171 |
} |
169 | 172 |
} |
170 | 173 |
|
171 |
void scsi_req_free(SCSIRequest *req) |
|
172 |
{ |
|
173 |
scsi_req_dequeue(req); |
|
174 |
qemu_free(req); |
|
175 |
} |
|
176 |
|
|
177 | 174 |
static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) |
178 | 175 |
{ |
179 | 176 |
switch (cmd[0] >> 5) { |
... | ... | |
495 | 492 |
return names[cmd]; |
496 | 493 |
} |
497 | 494 |
|
495 |
SCSIRequest *scsi_req_ref(SCSIRequest *req) |
|
496 |
{ |
|
497 |
req->refcount++; |
|
498 |
return req; |
|
499 |
} |
|
500 |
|
|
501 |
void scsi_req_unref(SCSIRequest *req) |
|
502 |
{ |
|
503 |
if (--req->refcount == 0) { |
|
504 |
if (req->dev->info->free_req) { |
|
505 |
req->dev->info->free_req(req); |
|
506 |
} |
|
507 |
qemu_free(req); |
|
508 |
} |
|
509 |
} |
|
510 |
|
|
498 | 511 |
/* Called by the devices when data is ready for the HBA. The HBA should |
499 | 512 |
start a DMA operation to read or fill the device's data buffer. |
500 | 513 |
Once it completes, calling one of req->dev->info->read_data or |
... | ... | |
537 | 550 |
void scsi_req_complete(SCSIRequest *req) |
538 | 551 |
{ |
539 | 552 |
assert(req->status != -1); |
553 |
scsi_req_ref(req); |
|
540 | 554 |
scsi_req_dequeue(req); |
541 | 555 |
req->bus->ops->complete(req->bus, SCSI_REASON_DONE, |
542 | 556 |
req->tag, |
543 | 557 |
req->status); |
558 |
scsi_req_unref(req); |
|
544 | 559 |
} |
545 | 560 |
|
546 | 561 |
static char *scsibus_get_fw_dev_path(DeviceState *dev) |
Also available in: Unified diff