qemu/hw/scsi/esp.c
<<
>>
Prefs
   1/*
   2 * QEMU ESP/NCR53C9x emulation
   3 *
   4 * Copyright (c) 2005-2006 Fabrice Bellard
   5 * Copyright (c) 2012 Herve Poussineau
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25
  26#include "hw/sysbus.h"
  27#include "hw/scsi/esp.h"
  28#include "trace.h"
  29#include "qemu/log.h"
  30
  31/*
  32 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
  33 * also produced as NCR89C100. See
  34 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
  35 * and
  36 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
  37 */
  38
  39static void esp_raise_irq(ESPState *s)
  40{
  41    if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
  42        s->rregs[ESP_RSTAT] |= STAT_INT;
  43        qemu_irq_raise(s->irq);
  44        trace_esp_raise_irq();
  45    }
  46}
  47
  48static void esp_lower_irq(ESPState *s)
  49{
  50    if (s->rregs[ESP_RSTAT] & STAT_INT) {
  51        s->rregs[ESP_RSTAT] &= ~STAT_INT;
  52        qemu_irq_lower(s->irq);
  53        trace_esp_lower_irq();
  54    }
  55}
  56
  57void esp_dma_enable(ESPState *s, int irq, int level)
  58{
  59    if (level) {
  60        s->dma_enabled = 1;
  61        trace_esp_dma_enable();
  62        if (s->dma_cb) {
  63            s->dma_cb(s);
  64            s->dma_cb = NULL;
  65        }
  66    } else {
  67        trace_esp_dma_disable();
  68        s->dma_enabled = 0;
  69    }
  70}
  71
  72void esp_request_cancelled(SCSIRequest *req)
  73{
  74    ESPState *s = req->hba_private;
  75
  76    if (req == s->current_req) {
  77        scsi_req_unref(s->current_req);
  78        s->current_req = NULL;
  79        s->current_dev = NULL;
  80    }
  81}
  82
  83static uint32_t get_cmd(ESPState *s, uint8_t *buf)
  84{
  85    uint32_t dmalen;
  86    int target;
  87
  88    target = s->wregs[ESP_WBUSID] & BUSID_DID;
  89    if (s->dma) {
  90        dmalen = s->rregs[ESP_TCLO];
  91        dmalen |= s->rregs[ESP_TCMID] << 8;
  92        dmalen |= s->rregs[ESP_TCHI] << 16;
  93        s->dma_memory_read(s->dma_opaque, buf, dmalen);
  94    } else {
  95        dmalen = s->ti_size;
  96        memcpy(buf, s->ti_buf, dmalen);
  97        buf[0] = buf[2] >> 5;
  98    }
  99    trace_esp_get_cmd(dmalen, target);
 100
 101    s->ti_size = 0;
 102    s->ti_rptr = 0;
 103    s->ti_wptr = 0;
 104
 105    if (s->current_req) {
 106        /* Started a new command before the old one finished.  Cancel it.  */
 107        scsi_req_cancel(s->current_req);
 108        s->async_len = 0;
 109    }
 110
 111    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
 112    if (!s->current_dev) {
 113        // No such drive
 114        s->rregs[ESP_RSTAT] = 0;
 115        s->rregs[ESP_RINTR] = INTR_DC;
 116        s->rregs[ESP_RSEQ] = SEQ_0;
 117        esp_raise_irq(s);
 118        return 0;
 119    }
 120    return dmalen;
 121}
 122
 123static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
 124{
 125    int32_t datalen;
 126    int lun;
 127    SCSIDevice *current_lun;
 128
 129    trace_esp_do_busid_cmd(busid);
 130    lun = busid & 7;
 131    current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
 132    s->current_req = scsi_req_new(current_lun, 0, lun, buf, s);
 133    datalen = scsi_req_enqueue(s->current_req);
 134    s->ti_size = datalen;
 135    if (datalen != 0) {
 136        s->rregs[ESP_RSTAT] = STAT_TC;
 137        s->dma_left = 0;
 138        s->dma_counter = 0;
 139        if (datalen > 0) {
 140            s->rregs[ESP_RSTAT] |= STAT_DI;
 141        } else {
 142            s->rregs[ESP_RSTAT] |= STAT_DO;
 143        }
 144        scsi_req_continue(s->current_req);
 145    }
 146    s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 147    s->rregs[ESP_RSEQ] = SEQ_CD;
 148    esp_raise_irq(s);
 149}
 150
 151static void do_cmd(ESPState *s, uint8_t *buf)
 152{
 153    uint8_t busid = buf[0];
 154
 155    do_busid_cmd(s, &buf[1], busid);
 156}
 157
 158static void handle_satn(ESPState *s)
 159{
 160    uint8_t buf[32];
 161    int len;
 162
 163    if (s->dma && !s->dma_enabled) {
 164        s->dma_cb = handle_satn;
 165        return;
 166    }
 167    len = get_cmd(s, buf);
 168    if (len)
 169        do_cmd(s, buf);
 170}
 171
 172static void handle_s_without_atn(ESPState *s)
 173{
 174    uint8_t buf[32];
 175    int len;
 176
 177    if (s->dma && !s->dma_enabled) {
 178        s->dma_cb = handle_s_without_atn;
 179        return;
 180    }
 181    len = get_cmd(s, buf);
 182    if (len) {
 183        do_busid_cmd(s, buf, 0);
 184    }
 185}
 186
 187static void handle_satn_stop(ESPState *s)
 188{
 189    if (s->dma && !s->dma_enabled) {
 190        s->dma_cb = handle_satn_stop;
 191        return;
 192    }
 193    s->cmdlen = get_cmd(s, s->cmdbuf);
 194    if (s->cmdlen) {
 195        trace_esp_handle_satn_stop(s->cmdlen);
 196        s->do_cmd = 1;
 197        s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
 198        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 199        s->rregs[ESP_RSEQ] = SEQ_CD;
 200        esp_raise_irq(s);
 201    }
 202}
 203
 204static void write_response(ESPState *s)
 205{
 206    trace_esp_write_response(s->status);
 207    s->ti_buf[0] = s->status;
 208    s->ti_buf[1] = 0;
 209    if (s->dma) {
 210        s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
 211        s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
 212        s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
 213        s->rregs[ESP_RSEQ] = SEQ_CD;
 214    } else {
 215        s->ti_size = 2;
 216        s->ti_rptr = 0;
 217        s->ti_wptr = 0;
 218        s->rregs[ESP_RFLAGS] = 2;
 219    }
 220    esp_raise_irq(s);
 221}
 222
 223static void esp_dma_done(ESPState *s)
 224{
 225    s->rregs[ESP_RSTAT] |= STAT_TC;
 226    s->rregs[ESP_RINTR] = INTR_BS;
 227    s->rregs[ESP_RSEQ] = 0;
 228    s->rregs[ESP_RFLAGS] = 0;
 229    s->rregs[ESP_TCLO] = 0;
 230    s->rregs[ESP_TCMID] = 0;
 231    s->rregs[ESP_TCHI] = 0;
 232    esp_raise_irq(s);
 233}
 234
 235static void esp_do_dma(ESPState *s)
 236{
 237    uint32_t len;
 238    int to_device;
 239
 240    to_device = (s->ti_size < 0);
 241    len = s->dma_left;
 242    if (s->do_cmd) {
 243        trace_esp_do_dma(s->cmdlen, len);
 244        s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
 245        s->ti_size = 0;
 246        s->cmdlen = 0;
 247        s->do_cmd = 0;
 248        do_cmd(s, s->cmdbuf);
 249        return;
 250    }
 251    if (s->async_len == 0) {
 252        /* Defer until data is available.  */
 253        return;
 254    }
 255    if (len > s->async_len) {
 256        len = s->async_len;
 257    }
 258    if (to_device) {
 259        s->dma_memory_read(s->dma_opaque, s->async_buf, len);
 260    } else {
 261        s->dma_memory_write(s->dma_opaque, s->async_buf, len);
 262    }
 263    s->dma_left -= len;
 264    s->async_buf += len;
 265    s->async_len -= len;
 266    if (to_device)
 267        s->ti_size += len;
 268    else
 269        s->ti_size -= len;
 270    if (s->async_len == 0) {
 271        scsi_req_continue(s->current_req);
 272        /* If there is still data to be read from the device then
 273           complete the DMA operation immediately.  Otherwise defer
 274           until the scsi layer has completed.  */
 275        if (to_device || s->dma_left != 0 || s->ti_size == 0) {
 276            return;
 277        }
 278    }
 279
 280    /* Partially filled a scsi buffer. Complete immediately.  */
 281    esp_dma_done(s);
 282}
 283
 284void esp_command_complete(SCSIRequest *req, uint32_t status,
 285                                 size_t resid)
 286{
 287    ESPState *s = req->hba_private;
 288
 289    trace_esp_command_complete();
 290    if (s->ti_size != 0) {
 291        trace_esp_command_complete_unexpected();
 292    }
 293    s->ti_size = 0;
 294    s->dma_left = 0;
 295    s->async_len = 0;
 296    if (status) {
 297        trace_esp_command_complete_fail();
 298    }
 299    s->status = status;
 300    s->rregs[ESP_RSTAT] = STAT_ST;
 301    esp_dma_done(s);
 302    if (s->current_req) {
 303        scsi_req_unref(s->current_req);
 304        s->current_req = NULL;
 305        s->current_dev = NULL;
 306    }
 307}
 308
 309void esp_transfer_data(SCSIRequest *req, uint32_t len)
 310{
 311    ESPState *s = req->hba_private;
 312
 313    trace_esp_transfer_data(s->dma_left, s->ti_size);
 314    s->async_len = len;
 315    s->async_buf = scsi_req_get_buf(req);
 316    if (s->dma_left) {
 317        esp_do_dma(s);
 318    } else if (s->dma_counter != 0 && s->ti_size <= 0) {
 319        /* If this was the last part of a DMA transfer then the
 320           completion interrupt is deferred to here.  */
 321        esp_dma_done(s);
 322    }
 323}
 324
 325static void handle_ti(ESPState *s)
 326{
 327    uint32_t dmalen, minlen;
 328
 329    if (s->dma && !s->dma_enabled) {
 330        s->dma_cb = handle_ti;
 331        return;
 332    }
 333
 334    dmalen = s->rregs[ESP_TCLO];
 335    dmalen |= s->rregs[ESP_TCMID] << 8;
 336    dmalen |= s->rregs[ESP_TCHI] << 16;
 337    if (dmalen==0) {
 338      dmalen=0x10000;
 339    }
 340    s->dma_counter = dmalen;
 341
 342    if (s->do_cmd)
 343        minlen = (dmalen < 32) ? dmalen : 32;
 344    else if (s->ti_size < 0)
 345        minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
 346    else
 347        minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
 348    trace_esp_handle_ti(minlen);
 349    if (s->dma) {
 350        s->dma_left = minlen;
 351        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 352        esp_do_dma(s);
 353    } else if (s->do_cmd) {
 354        trace_esp_handle_ti_cmd(s->cmdlen);
 355        s->ti_size = 0;
 356        s->cmdlen = 0;
 357        s->do_cmd = 0;
 358        do_cmd(s, s->cmdbuf);
 359        return;
 360    }
 361}
 362
 363void esp_hard_reset(ESPState *s)
 364{
 365    memset(s->rregs, 0, ESP_REGS);
 366    memset(s->wregs, 0, ESP_REGS);
 367    s->rregs[ESP_TCHI] = s->chip_id;
 368    s->ti_size = 0;
 369    s->ti_rptr = 0;
 370    s->ti_wptr = 0;
 371    s->dma = 0;
 372    s->do_cmd = 0;
 373    s->dma_cb = NULL;
 374
 375    s->rregs[ESP_CFG1] = 7;
 376}
 377
 378static void esp_soft_reset(ESPState *s)
 379{
 380    qemu_irq_lower(s->irq);
 381    esp_hard_reset(s);
 382}
 383
 384static void parent_esp_reset(ESPState *s, int irq, int level)
 385{
 386    if (level) {
 387        esp_soft_reset(s);
 388    }
 389}
 390
 391uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
 392{
 393    uint32_t old_val;
 394
 395    trace_esp_mem_readb(saddr, s->rregs[saddr]);
 396    switch (saddr) {
 397    case ESP_FIFO:
 398        if (s->ti_size > 0) {
 399            s->ti_size--;
 400            if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
 401                /* Data out.  */
 402                qemu_log_mask(LOG_UNIMP,
 403                              "esp: PIO data read not implemented\n");
 404                s->rregs[ESP_FIFO] = 0;
 405            } else {
 406                s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
 407            }
 408            esp_raise_irq(s);
 409        }
 410        if (s->ti_size == 0) {
 411            s->ti_rptr = 0;
 412            s->ti_wptr = 0;
 413        }
 414        break;
 415    case ESP_RINTR:
 416        /* Clear sequence step, interrupt register and all status bits
 417           except TC */
 418        old_val = s->rregs[ESP_RINTR];
 419        s->rregs[ESP_RINTR] = 0;
 420        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 421        s->rregs[ESP_RSEQ] = SEQ_CD;
 422        esp_lower_irq(s);
 423
 424        return old_val;
 425    default:
 426        break;
 427    }
 428    return s->rregs[saddr];
 429}
 430
 431void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
 432{
 433    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
 434    switch (saddr) {
 435    case ESP_TCLO:
 436    case ESP_TCMID:
 437    case ESP_TCHI:
 438        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 439        break;
 440    case ESP_FIFO:
 441        if (s->do_cmd) {
 442            s->cmdbuf[s->cmdlen++] = val & 0xff;
 443        } else if (s->ti_size == TI_BUFSZ - 1) {
 444            trace_esp_error_fifo_overrun();
 445        } else {
 446            s->ti_size++;
 447            s->ti_buf[s->ti_wptr++] = val & 0xff;
 448        }
 449        break;
 450    case ESP_CMD:
 451        s->rregs[saddr] = val;
 452        if (val & CMD_DMA) {
 453            s->dma = 1;
 454            /* Reload DMA counter.  */
 455            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
 456            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
 457            s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
 458        } else {
 459            s->dma = 0;
 460        }
 461        switch(val & CMD_CMD) {
 462        case CMD_NOP:
 463            trace_esp_mem_writeb_cmd_nop(val);
 464            break;
 465        case CMD_FLUSH:
 466            trace_esp_mem_writeb_cmd_flush(val);
 467            //s->ti_size = 0;
 468            s->rregs[ESP_RINTR] = INTR_FC;
 469            s->rregs[ESP_RSEQ] = 0;
 470            s->rregs[ESP_RFLAGS] = 0;
 471            break;
 472        case CMD_RESET:
 473            trace_esp_mem_writeb_cmd_reset(val);
 474            esp_soft_reset(s);
 475            break;
 476        case CMD_BUSRESET:
 477            trace_esp_mem_writeb_cmd_bus_reset(val);
 478            s->rregs[ESP_RINTR] = INTR_RST;
 479            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
 480                esp_raise_irq(s);
 481            }
 482            break;
 483        case CMD_TI:
 484            handle_ti(s);
 485            break;
 486        case CMD_ICCS:
 487            trace_esp_mem_writeb_cmd_iccs(val);
 488            write_response(s);
 489            s->rregs[ESP_RINTR] = INTR_FC;
 490            s->rregs[ESP_RSTAT] |= STAT_MI;
 491            break;
 492        case CMD_MSGACC:
 493            trace_esp_mem_writeb_cmd_msgacc(val);
 494            s->rregs[ESP_RINTR] = INTR_DC;
 495            s->rregs[ESP_RSEQ] = 0;
 496            s->rregs[ESP_RFLAGS] = 0;
 497            esp_raise_irq(s);
 498            break;
 499        case CMD_PAD:
 500            trace_esp_mem_writeb_cmd_pad(val);
 501            s->rregs[ESP_RSTAT] = STAT_TC;
 502            s->rregs[ESP_RINTR] = INTR_FC;
 503            s->rregs[ESP_RSEQ] = 0;
 504            break;
 505        case CMD_SATN:
 506            trace_esp_mem_writeb_cmd_satn(val);
 507            break;
 508        case CMD_RSTATN:
 509            trace_esp_mem_writeb_cmd_rstatn(val);
 510            break;
 511        case CMD_SEL:
 512            trace_esp_mem_writeb_cmd_sel(val);
 513            handle_s_without_atn(s);
 514            break;
 515        case CMD_SELATN:
 516            trace_esp_mem_writeb_cmd_selatn(val);
 517            handle_satn(s);
 518            break;
 519        case CMD_SELATNS:
 520            trace_esp_mem_writeb_cmd_selatns(val);
 521            handle_satn_stop(s);
 522            break;
 523        case CMD_ENSEL:
 524            trace_esp_mem_writeb_cmd_ensel(val);
 525            s->rregs[ESP_RINTR] = 0;
 526            break;
 527        case CMD_DISSEL:
 528            trace_esp_mem_writeb_cmd_dissel(val);
 529            s->rregs[ESP_RINTR] = 0;
 530            esp_raise_irq(s);
 531            break;
 532        default:
 533            trace_esp_error_unhandled_command(val);
 534            break;
 535        }
 536        break;
 537    case ESP_WBUSID ... ESP_WSYNO:
 538        break;
 539    case ESP_CFG1:
 540    case ESP_CFG2: case ESP_CFG3:
 541    case ESP_RES3: case ESP_RES4:
 542        s->rregs[saddr] = val;
 543        break;
 544    case ESP_WCCF ... ESP_WTEST:
 545        break;
 546    default:
 547        trace_esp_error_invalid_write(val, saddr);
 548        return;
 549    }
 550    s->wregs[saddr] = val;
 551}
 552
 553static bool esp_mem_accepts(void *opaque, hwaddr addr,
 554                            unsigned size, bool is_write)
 555{
 556    return (size == 1) || (is_write && size == 4);
 557}
 558
 559const VMStateDescription vmstate_esp = {
 560    .name ="esp",
 561    .version_id = 3,
 562    .minimum_version_id = 3,
 563    .minimum_version_id_old = 3,
 564    .fields      = (VMStateField []) {
 565        VMSTATE_BUFFER(rregs, ESPState),
 566        VMSTATE_BUFFER(wregs, ESPState),
 567        VMSTATE_INT32(ti_size, ESPState),
 568        VMSTATE_UINT32(ti_rptr, ESPState),
 569        VMSTATE_UINT32(ti_wptr, ESPState),
 570        VMSTATE_BUFFER(ti_buf, ESPState),
 571        VMSTATE_UINT32(status, ESPState),
 572        VMSTATE_UINT32(dma, ESPState),
 573        VMSTATE_BUFFER(cmdbuf, ESPState),
 574        VMSTATE_UINT32(cmdlen, ESPState),
 575        VMSTATE_UINT32(do_cmd, ESPState),
 576        VMSTATE_UINT32(dma_left, ESPState),
 577        VMSTATE_END_OF_LIST()
 578    }
 579};
 580
 581#define TYPE_ESP "esp"
 582#define ESP(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
 583
 584typedef struct {
 585    /*< private >*/
 586    SysBusDevice parent_obj;
 587    /*< public >*/
 588
 589    MemoryRegion iomem;
 590    uint32_t it_shift;
 591    ESPState esp;
 592} SysBusESPState;
 593
 594static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
 595                                 uint64_t val, unsigned int size)
 596{
 597    SysBusESPState *sysbus = opaque;
 598    uint32_t saddr;
 599
 600    saddr = addr >> sysbus->it_shift;
 601    esp_reg_write(&sysbus->esp, saddr, val);
 602}
 603
 604static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
 605                                    unsigned int size)
 606{
 607    SysBusESPState *sysbus = opaque;
 608    uint32_t saddr;
 609
 610    saddr = addr >> sysbus->it_shift;
 611    return esp_reg_read(&sysbus->esp, saddr);
 612}
 613
 614static const MemoryRegionOps sysbus_esp_mem_ops = {
 615    .read = sysbus_esp_mem_read,
 616    .write = sysbus_esp_mem_write,
 617    .endianness = DEVICE_NATIVE_ENDIAN,
 618    .valid.accepts = esp_mem_accepts,
 619};
 620
 621void esp_init(hwaddr espaddr, int it_shift,
 622              ESPDMAMemoryReadWriteFunc dma_memory_read,
 623              ESPDMAMemoryReadWriteFunc dma_memory_write,
 624              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
 625              qemu_irq *dma_enable)
 626{
 627    DeviceState *dev;
 628    SysBusDevice *s;
 629    SysBusESPState *sysbus;
 630    ESPState *esp;
 631
 632    dev = qdev_create(NULL, TYPE_ESP);
 633    sysbus = ESP(dev);
 634    esp = &sysbus->esp;
 635    esp->dma_memory_read = dma_memory_read;
 636    esp->dma_memory_write = dma_memory_write;
 637    esp->dma_opaque = dma_opaque;
 638    sysbus->it_shift = it_shift;
 639    /* XXX for now until rc4030 has been changed to use DMA enable signal */
 640    esp->dma_enabled = 1;
 641    qdev_init_nofail(dev);
 642    s = SYS_BUS_DEVICE(dev);
 643    sysbus_connect_irq(s, 0, irq);
 644    sysbus_mmio_map(s, 0, espaddr);
 645    *reset = qdev_get_gpio_in(dev, 0);
 646    *dma_enable = qdev_get_gpio_in(dev, 1);
 647}
 648
 649static const struct SCSIBusInfo esp_scsi_info = {
 650    .tcq = false,
 651    .max_target = ESP_MAX_DEVS,
 652    .max_lun = 7,
 653
 654    .transfer_data = esp_transfer_data,
 655    .complete = esp_command_complete,
 656    .cancel = esp_request_cancelled
 657};
 658
 659static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
 660{
 661    SysBusESPState *sysbus = ESP(opaque);
 662    ESPState *s = &sysbus->esp;
 663
 664    switch (irq) {
 665    case 0:
 666        parent_esp_reset(s, irq, level);
 667        break;
 668    case 1:
 669        esp_dma_enable(opaque, irq, level);
 670        break;
 671    }
 672}
 673
 674static void sysbus_esp_realize(DeviceState *dev, Error **errp)
 675{
 676    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 677    SysBusESPState *sysbus = ESP(dev);
 678    ESPState *s = &sysbus->esp;
 679    Error *err = NULL;
 680
 681    sysbus_init_irq(sbd, &s->irq);
 682    assert(sysbus->it_shift != -1);
 683
 684    s->chip_id = TCHI_FAS100A;
 685    memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops,
 686                          sysbus, "esp", ESP_REGS << sysbus->it_shift);
 687    sysbus_init_mmio(sbd, &sysbus->iomem);
 688
 689    qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
 690
 691    scsi_bus_new(&s->bus, dev, &esp_scsi_info, NULL);
 692    scsi_bus_legacy_handle_cmdline(&s->bus, &err);
 693    if (err != NULL) {
 694        error_propagate(errp, err);
 695        return;
 696    }
 697}
 698
 699static void sysbus_esp_hard_reset(DeviceState *dev)
 700{
 701    SysBusESPState *sysbus = ESP(dev);
 702    esp_hard_reset(&sysbus->esp);
 703}
 704
 705static const VMStateDescription vmstate_sysbus_esp_scsi = {
 706    .name = "sysbusespscsi",
 707    .version_id = 0,
 708    .minimum_version_id = 0,
 709    .minimum_version_id_old = 0,
 710    .fields = (VMStateField[]) {
 711        VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
 712        VMSTATE_END_OF_LIST()
 713    }
 714};
 715
 716static void sysbus_esp_class_init(ObjectClass *klass, void *data)
 717{
 718    DeviceClass *dc = DEVICE_CLASS(klass);
 719
 720    dc->realize = sysbus_esp_realize;
 721    dc->reset = sysbus_esp_hard_reset;
 722    dc->vmsd = &vmstate_sysbus_esp_scsi;
 723    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 724}
 725
 726static const TypeInfo sysbus_esp_info = {
 727    .name          = TYPE_ESP,
 728    .parent        = TYPE_SYS_BUS_DEVICE,
 729    .instance_size = sizeof(SysBusESPState),
 730    .class_init    = sysbus_esp_class_init,
 731};
 732
 733static void esp_register_types(void)
 734{
 735    type_register_static(&sysbus_esp_info);
 736}
 737
 738type_init(esp_register_types)
 739