Revision 5c6c0e51 hw/esp.c
b/hw/esp.c | ||
---|---|---|
65 | 65 |
uint32_t dma; |
66 | 66 |
SCSIBus bus; |
67 | 67 |
SCSIDevice *current_dev; |
68 |
SCSIRequest *current_req; |
|
68 | 69 |
uint8_t cmdbuf[TI_BUFSZ]; |
69 | 70 |
uint32_t cmdlen; |
70 | 71 |
uint32_t do_cmd; |
... | ... | |
209 | 210 |
|
210 | 211 |
if (s->current_dev) { |
211 | 212 |
/* Started a new command before the old one finished. Cancel it. */ |
212 |
s->current_dev->info->cancel_io(s->current_dev, 0);
|
|
213 |
s->current_dev->info->cancel_io(s->current_req);
|
|
213 | 214 |
s->async_len = 0; |
214 | 215 |
} |
215 | 216 |
|
... | ... | |
232 | 233 |
|
233 | 234 |
DPRINTF("do_busid_cmd: busid 0x%x\n", busid); |
234 | 235 |
lun = busid & 7; |
235 |
datalen = s->current_dev->info->send_command(s->current_dev, 0, buf, lun); |
|
236 |
s->current_req = s->current_dev->info->alloc_req(s->current_dev, 0, lun); |
|
237 |
datalen = s->current_dev->info->send_command(s->current_req, buf); |
|
236 | 238 |
s->ti_size = datalen; |
237 | 239 |
if (datalen != 0) { |
238 | 240 |
s->rregs[ESP_RSTAT] = STAT_TC; |
... | ... | |
240 | 242 |
s->dma_counter = 0; |
241 | 243 |
if (datalen > 0) { |
242 | 244 |
s->rregs[ESP_RSTAT] |= STAT_DI; |
243 |
s->current_dev->info->read_data(s->current_dev, 0);
|
|
245 |
s->current_dev->info->read_data(s->current_req);
|
|
244 | 246 |
} else { |
245 | 247 |
s->rregs[ESP_RSTAT] |= STAT_DO; |
246 |
s->current_dev->info->write_data(s->current_dev, 0);
|
|
248 |
s->current_dev->info->write_data(s->current_req);
|
|
247 | 249 |
} |
248 | 250 |
} |
249 | 251 |
s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; |
... | ... | |
372 | 374 |
if (s->async_len == 0) { |
373 | 375 |
if (to_device) { |
374 | 376 |
// ti_size is negative |
375 |
s->current_dev->info->write_data(s->current_dev, 0);
|
|
377 |
s->current_dev->info->write_data(s->current_req);
|
|
376 | 378 |
} else { |
377 |
s->current_dev->info->read_data(s->current_dev, 0);
|
|
379 |
s->current_dev->info->read_data(s->current_req);
|
|
378 | 380 |
/* If there is still data to be read from the device then |
379 | 381 |
complete the DMA operation immediately. Otherwise defer |
380 | 382 |
until the scsi layer has completed. */ |
... | ... | |
388 | 390 |
} |
389 | 391 |
} |
390 | 392 |
|
391 |
static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag, |
|
392 |
uint32_t arg) |
|
393 |
static void esp_command_complete(SCSIRequest *req, int reason, uint32_t arg) |
|
393 | 394 |
{ |
394 |
ESPState *s = DO_UPCAST(ESPState, busdev.qdev, bus->qbus.parent); |
|
395 |
ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
|
|
395 | 396 |
|
396 | 397 |
if (reason == SCSI_REASON_DONE) { |
397 | 398 |
DPRINTF("SCSI Command complete\n"); |
... | ... | |
405 | 406 |
s->sense = arg; |
406 | 407 |
s->rregs[ESP_RSTAT] = STAT_ST; |
407 | 408 |
esp_dma_done(s); |
408 |
s->current_dev = NULL; |
|
409 |
if (s->current_req) { |
|
410 |
scsi_req_unref(s->current_req); |
|
411 |
s->current_req = NULL; |
|
412 |
s->current_dev = NULL; |
|
413 |
} |
|
409 | 414 |
} else { |
410 | 415 |
DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); |
411 | 416 |
s->async_len = arg; |
412 |
s->async_buf = s->current_dev->info->get_buf(s->current_dev, 0);
|
|
417 |
s->async_buf = s->current_dev->info->get_buf(req);
|
|
413 | 418 |
if (s->dma_left) { |
414 | 419 |
esp_do_dma(s); |
415 | 420 |
} else if (s->dma_counter != 0 && s->ti_size <= 0) { |
Also available in: Unified diff