~ubuntu-branches/debian/jessie/qemu/jessie

« back to all changes in this revision

Viewing changes to hw/esp.c

  • Committer: Package Import Robot
  • Author(s): Vagrant Cascadian
  • Date: 2011-10-03 12:29:18 UTC
  • mfrom: (1.2.13) (10.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20111003122918-zc4kv6epchrbgdta
Tags: 0.15.0+dfsg-1
* New upstream version.
* Install new qemu-system, qemu-user and qemu-user-static variants: 
  lm32, microblazeel, s390x, unicore32
* Patch from upstream to set QEMU_INCLUDES before QEMU_CFLAGS.
* Update debian/watch to check http://qemu.org/download.

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
    int32_t ti_size;
62
62
    uint32_t ti_rptr, ti_wptr;
63
63
    uint8_t ti_buf[TI_BUFSZ];
64
 
    uint32_t sense;
 
64
    uint32_t status;
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;
187
188
    }
188
189
}
189
190
 
 
191
static void esp_request_cancelled(SCSIRequest *req)
 
192
{
 
193
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
194
 
 
195
    if (req == s->current_req) {
 
196
        scsi_req_unref(s->current_req);
 
197
        s->current_req = NULL;
 
198
        s->current_dev = NULL;
 
199
    }
 
200
}
 
201
 
190
202
static uint32_t get_cmd(ESPState *s, uint8_t *buf)
191
203
{
192
204
    uint32_t dmalen;
199
211
    } else {
200
212
        dmalen = s->ti_size;
201
213
        memcpy(buf, s->ti_buf, dmalen);
202
 
        buf[0] = 0;
 
214
        buf[0] = buf[2] >> 5;
203
215
    }
204
216
    DPRINTF("get_cmd: len %d target %d\n", dmalen, target);
205
217
 
207
219
    s->ti_rptr = 0;
208
220
    s->ti_wptr = 0;
209
221
 
210
 
    if (s->current_dev) {
 
222
    if (s->current_req) {
211
223
        /* Started a new command before the old one finished.  Cancel it.  */
212
 
        s->current_dev->info->cancel_io(s->current_dev, 0);
 
224
        scsi_req_cancel(s->current_req);
213
225
        s->async_len = 0;
214
226
    }
215
227
 
232
244
 
233
245
    DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
234
246
    lun = busid & 7;
235
 
    datalen = s->current_dev->info->send_command(s->current_dev, 0, buf, lun);
 
247
    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
 
248
    datalen = scsi_req_enqueue(s->current_req, buf);
236
249
    s->ti_size = datalen;
237
250
    if (datalen != 0) {
238
251
        s->rregs[ESP_RSTAT] = STAT_TC;
240
253
        s->dma_counter = 0;
241
254
        if (datalen > 0) {
242
255
            s->rregs[ESP_RSTAT] |= STAT_DI;
243
 
            s->current_dev->info->read_data(s->current_dev, 0);
244
256
        } else {
245
257
            s->rregs[ESP_RSTAT] |= STAT_DO;
246
 
            s->current_dev->info->write_data(s->current_dev, 0);
247
258
        }
 
259
        scsi_req_continue(s->current_req);
248
260
    }
249
261
    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
250
262
    s->rregs[ESP_RSEQ] = SEQ_CD;
306
318
 
307
319
static void write_response(ESPState *s)
308
320
{
309
 
    DPRINTF("Transfer status (sense=%d)\n", s->sense);
310
 
    s->ti_buf[0] = s->sense;
 
321
    DPRINTF("Transfer status (status=%d)\n", s->status);
 
322
    s->ti_buf[0] = s->status;
311
323
    s->ti_buf[1] = 0;
312
324
    if (s->dma) {
313
325
        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
370
382
    else
371
383
        s->ti_size -= len;
372
384
    if (s->async_len == 0) {
373
 
        if (to_device) {
374
 
            // ti_size is negative
375
 
            s->current_dev->info->write_data(s->current_dev, 0);
376
 
        } else {
377
 
            s->current_dev->info->read_data(s->current_dev, 0);
378
 
            /* If there is still data to be read from the device then
379
 
               complete the DMA operation immediately.  Otherwise defer
380
 
               until the scsi layer has completed.  */
381
 
            if (s->dma_left == 0 && s->ti_size > 0) {
382
 
                esp_dma_done(s);
383
 
            }
 
385
        scsi_req_continue(s->current_req);
 
386
        /* If there is still data to be read from the device then
 
387
           complete the DMA operation immediately.  Otherwise defer
 
388
           until the scsi layer has completed.  */
 
389
        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
 
390
            return;
384
391
        }
385
 
    } else {
386
 
        /* Partially filled a scsi buffer. Complete immediately.  */
387
 
        esp_dma_done(s);
388
392
    }
 
393
 
 
394
    /* Partially filled a scsi buffer. Complete immediately.  */
 
395
    esp_dma_done(s);
389
396
}
390
397
 
391
 
static void esp_command_complete(SCSIBus *bus, int reason, uint32_t tag,
392
 
                                 uint32_t arg)
 
398
static void esp_command_complete(SCSIRequest *req, uint32_t status)
393
399
{
394
 
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, bus->qbus.parent);
 
400
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
395
401
 
396
 
    if (reason == SCSI_REASON_DONE) {
397
 
        DPRINTF("SCSI Command complete\n");
398
 
        if (s->ti_size != 0)
399
 
            DPRINTF("SCSI command completed unexpectedly\n");
400
 
        s->ti_size = 0;
401
 
        s->dma_left = 0;
402
 
        s->async_len = 0;
403
 
        if (arg)
404
 
            DPRINTF("Command failed\n");
405
 
        s->sense = arg;
406
 
        s->rregs[ESP_RSTAT] = STAT_ST;
407
 
        esp_dma_done(s);
 
402
    DPRINTF("SCSI Command complete\n");
 
403
    if (s->ti_size != 0) {
 
404
        DPRINTF("SCSI command completed unexpectedly\n");
 
405
    }
 
406
    s->ti_size = 0;
 
407
    s->dma_left = 0;
 
408
    s->async_len = 0;
 
409
    if (status) {
 
410
        DPRINTF("Command failed\n");
 
411
    }
 
412
    s->status = status;
 
413
    s->rregs[ESP_RSTAT] = STAT_ST;
 
414
    esp_dma_done(s);
 
415
    if (s->current_req) {
 
416
        scsi_req_unref(s->current_req);
 
417
        s->current_req = NULL;
408
418
        s->current_dev = NULL;
409
 
    } else {
410
 
        DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
411
 
        s->async_len = arg;
412
 
        s->async_buf = s->current_dev->info->get_buf(s->current_dev, 0);
413
 
        if (s->dma_left) {
414
 
            esp_do_dma(s);
415
 
        } else if (s->dma_counter != 0 && s->ti_size <= 0) {
416
 
            /* If this was the last part of a DMA transfer then the
417
 
               completion interrupt is deferred to here.  */
418
 
            esp_dma_done(s);
419
 
        }
 
419
    }
 
420
}
 
421
 
 
422
static void esp_transfer_data(SCSIRequest *req, uint32_t len)
 
423
{
 
424
    ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent);
 
425
 
 
426
    DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
 
427
    s->async_len = len;
 
428
    s->async_buf = scsi_req_get_buf(req);
 
429
    if (s->dma_left) {
 
430
        esp_do_dma(s);
 
431
    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
 
432
        /* If this was the last part of a DMA transfer then the
 
433
           completion interrupt is deferred to here.  */
 
434
        esp_dma_done(s);
420
435
    }
421
436
}
422
437
 
678
693
        VMSTATE_UINT32(ti_rptr, ESPState),
679
694
        VMSTATE_UINT32(ti_wptr, ESPState),
680
695
        VMSTATE_BUFFER(ti_buf, ESPState),
681
 
        VMSTATE_UINT32(sense, ESPState),
 
696
        VMSTATE_UINT32(status, ESPState),
682
697
        VMSTATE_UINT32(dma, ESPState),
683
698
        VMSTATE_BUFFER(cmdbuf, ESPState),
684
699
        VMSTATE_UINT32(cmdlen, ESPState),
714
729
    *dma_enable = qdev_get_gpio_in(dev, 1);
715
730
}
716
731
 
 
732
static const struct SCSIBusOps esp_scsi_ops = {
 
733
    .transfer_data = esp_transfer_data,
 
734
    .complete = esp_command_complete,
 
735
    .cancel = esp_request_cancelled
 
736
};
 
737
 
717
738
static int esp_init1(SysBusDevice *dev)
718
739
{
719
740
    ESPState *s = FROM_SYSBUS(ESPState, dev);
728
749
 
729
750
    qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2);
730
751
 
731
 
    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, esp_command_complete);
 
752
    scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops);
732
753
    return scsi_bus_legacy_handle_cmdline(&s->bus);
733
754
}
734
755