static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)

{

    uint32_t dmalen;

    int target;



    target = s->wregs[ESP_WBUSID] & BUSID_DID;

    if (s->dma) {

        dmalen = s->rregs[ESP_TCLO];

        dmalen |= s->rregs[ESP_TCMID] << 8;

        dmalen |= s->rregs[ESP_TCHI] << 16;

        if (dmalen > buflen) {



        s->dma_memory_read(s->dma_opaque, buf, dmalen);

    } else {

        dmalen = s->ti_size;




        memcpy(buf, s->ti_buf, dmalen);

        buf[0] = buf[2] >> 5;


    trace_esp_get_cmd(dmalen, target);



    s->ti_size = 0;

    s->ti_rptr = 0;

    s->ti_wptr = 0;



    if (s->current_req) {

        /* Started a new command before the old one finished.  Cancel it.  */

        scsi_req_cancel(s->current_req);

        s->async_len = 0;




    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);

    if (!s->current_dev) {

        // No such drive

        s->rregs[ESP_RSTAT] = 0;

        s->rregs[ESP_RINTR] = INTR_DC;

        s->rregs[ESP_RSEQ] = SEQ_0;

        esp_raise_irq(s);



    return dmalen;
