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->tchi_written = 0;
 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    case ESP_TCHI:
 426        /* Return the unique id if the value has never been written */
 427        if (!s->tchi_written) {
 428            return s->chip_id;
 429        }
 430    default:
 431        break;
 432    }
 433    return s->rregs[saddr];
 434}
 435
 436void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
 437{
 438    trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
 439    switch (saddr) {
 440    case ESP_TCHI:
 441        s->tchi_written = true;
 442        /* fall through */
 443    case ESP_TCLO:
 444    case ESP_TCMID:
 445        s->rregs[ESP_RSTAT] &= ~STAT_TC;
 446        break;
 447    case ESP_FIFO:
 448        if (s->do_cmd) {
 449            s->cmdbuf[s->cmdlen++] = val & 0xff;
 450        } else if (s->ti_size == TI_BUFSZ - 1) {
 451            trace_esp_error_fifo_overrun();
 452        } else {
 453            s->ti_size++;
 454            s->ti_buf[s->ti_wptr++] = val & 0xff;
 455        }
 456        break;
 457    case ESP_CMD:
 458        s->rregs[saddr] = val;
 459        if (val & CMD_DMA) {
 460            s->dma = 1;
 461            /* Reload DMA counter.  */
 462            s->rregs[ESP_TCLO] = s->wregs[ESP_TCLO];
 463            s->rregs[ESP_TCMID] = s->wregs[ESP_TCMID];
 464            s->rregs[ESP_TCHI] = s->wregs[ESP_TCHI];
 465        } else {
 466            s->dma = 0;
 467        }
 468        switch(val & CMD_CMD) {
 469        case CMD_NOP:
 470            trace_esp_mem_writeb_cmd_nop(val);
 471            break;
 472        case CMD_FLUSH:
 473            trace_esp_mem_writeb_cmd_flush(val);
 474            //s->ti_size = 0;
 475            s->rregs[ESP_RINTR] = INTR_FC;
 476            s->rregs[ESP_RSEQ] = 0;
 477            s->rregs[ESP_RFLAGS] = 0;
 478            break;
 479        case CMD_RESET:
 480            trace_esp_mem_writeb_cmd_reset(val);
 481            esp_soft_reset(s);
 482            break;
 483        case CMD_BUSRESET:
 484            trace_esp_mem_writeb_cmd_bus_reset(val);
 485            s->rregs[ESP_RINTR] = INTR_RST;
 486            if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
 487                esp_raise_irq(s);
 488            }
 489            break;
 490        case CMD_TI:
 491            handle_ti(s);
 492            break;
 493        case CMD_ICCS:
 494            trace_esp_mem_writeb_cmd_iccs(val);
 495            write_response(s);
 496            s->rregs[ESP_RINTR] = INTR_FC;
 497            s->rregs[ESP_RSTAT] |= STAT_MI;
 498            break;
 499        case CMD_MSGACC:
 500            trace_esp_mem_writeb_cmd_msgacc(val);
 501            s->rregs[ESP_RINTR] = INTR_DC;
 502            s->rregs[ESP_RSEQ] = 0;
 503            s->rregs[ESP_RFLAGS] = 0;
 504            esp_raise_irq(s);
 505            break;
 506        case CMD_PAD:
 507            trace_esp_mem_writeb_cmd_pad(val);
 508            s->rregs[ESP_RSTAT] = STAT_TC;
 509            s->rregs[ESP_RINTR] = INTR_FC;
 510            s->rregs[ESP_RSEQ] = 0;
 511            break;
 512        case CMD_SATN:
 513            trace_esp_mem_writeb_cmd_satn(val);
 514            break;
 515        case CMD_RSTATN:
 516            trace_esp_mem_writeb_cmd_rstatn(val);
 517            break;
 518        case CMD_SEL:
 519            trace_esp_mem_writeb_cmd_sel(val);
 520            handle_s_without_atn(s);
 521            break;
 522        case CMD_SELATN:
 523            trace_esp_mem_writeb_cmd_selatn(val);
 524            handle_satn(s);
 525            break;
 526        case CMD_SELATNS:
 527            trace_esp_mem_writeb_cmd_selatns(val);
 528            handle_satn_stop(s);
 529            break;
 530        case CMD_ENSEL:
 531            trace_esp_mem_writeb_cmd_ensel(val);
 532            s->rregs[ESP_RINTR] = 0;
 533            break;
 534        case CMD_DISSEL:
 535            trace_esp_mem_writeb_cmd_dissel(val);
 536            s->rregs[ESP_RINTR] = 0;
 537            esp_raise_irq(s);
 538            break;
 539        default:
 540            trace_esp_error_unhandled_command(val);
 541            break;
 542        }
 543        break;
 544    case ESP_WBUSID ... ESP_WSYNO:
 545        break;
 546    case ESP_CFG1:
 547    case ESP_CFG2: case ESP_CFG3:
 548    case ESP_RES3: case ESP_RES4:
 549        s->rregs[saddr] = val;
 550        break;
 551    case ESP_WCCF ... ESP_WTEST:
 552        break;
 553    default:
 554        trace_esp_error_invalid_write(val, saddr);
 555        return;
 556    }
 557    s->wregs[saddr] = val;
 558}
 559
 560static bool esp_mem_accepts(void *opaque, hwaddr addr,
 561                            unsigned size, bool is_write)
 562{
 563    return (size == 1) || (is_write && size == 4);
 564}
 565
 566const VMStateDescription vmstate_esp = {
 567    .name ="esp",
 568    .version_id = 3,
 569    .minimum_version_id = 3,
 570    .fields = (VMStateField[]) {
 571        VMSTATE_BUFFER(rregs, ESPState),
 572        VMSTATE_BUFFER(wregs, ESPState),
 573        VMSTATE_INT32(ti_size, ESPState),
 574        VMSTATE_UINT32(ti_rptr, ESPState),
 575        VMSTATE_UINT32(ti_wptr, ESPState),
 576        VMSTATE_BUFFER(ti_buf, ESPState),
 577        VMSTATE_UINT32(status, ESPState),
 578        VMSTATE_UINT32(dma, ESPState),
 579        VMSTATE_BUFFER(cmdbuf, ESPState),
 580        VMSTATE_UINT32(cmdlen, ESPState),
 581        VMSTATE_UINT32(do_cmd, ESPState),
 582        VMSTATE_UINT32(dma_left, ESPState),
 583        VMSTATE_END_OF_LIST()
 584    }
 585};
 586
 587#define TYPE_ESP "esp"
 588#define ESP(obj) OBJECT_CHECK(SysBusESPState, (obj), TYPE_ESP)
 589
 590typedef struct {
 591    /*< private >*/
 592    SysBusDevice parent_obj;
 593    /*< public >*/
 594
 595    MemoryRegion iomem;
 596    uint32_t it_shift;
 597    ESPState esp;
 598} SysBusESPState;
 599
 600static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
 601                                 uint64_t val, unsigned int size)
 602{
 603    SysBusESPState *sysbus = opaque;
 604    uint32_t saddr;
 605
 606    saddr = addr >> sysbus->it_shift;
 607    esp_reg_write(&sysbus->esp, saddr, val);
 608}
 609
 610static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
 611                                    unsigned int size)
 612{
 613    SysBusESPState *sysbus = opaque;
 614    uint32_t saddr;
 615
 616    saddr = addr >> sysbus->it_shift;
 617    return esp_reg_read(&sysbus->esp, saddr);
 618}
 619
 620static const MemoryRegionOps sysbus_esp_mem_ops = {
 621    .read = sysbus_esp_mem_read,
 622    .write = sysbus_esp_mem_write,
 623    .endianness = DEVICE_NATIVE_ENDIAN,
 624    .valid.accepts = esp_mem_accepts,
 625};
 626
 627void esp_init(hwaddr espaddr, int it_shift,
 628              ESPDMAMemoryReadWriteFunc dma_memory_read,
 629              ESPDMAMemoryReadWriteFunc dma_memory_write,
 630              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
 631              qemu_irq *dma_enable)
 632{
 633    DeviceState *dev;
 634    SysBusDevice *s;
 635    SysBusESPState *sysbus;
 636    ESPState *esp;
 637
 638    dev = qdev_create(NULL, TYPE_ESP);
 639    sysbus = ESP(dev);
 640    esp = &sysbus->esp;
 641    esp->dma_memory_read = dma_memory_read;
 642    esp->dma_memory_write = dma_memory_write;
 643    esp->dma_opaque = dma_opaque;
 644    sysbus->it_shift = it_shift;
 645    /* XXX for now until rc4030 has been changed to use DMA enable signal */
 646    esp->dma_enabled = 1;
 647    qdev_init_nofail(dev);
 648    s = SYS_BUS_DEVICE(dev);
 649    sysbus_connect_irq(s, 0, irq);
 650    sysbus_mmio_map(s, 0, espaddr);
 651    *reset = qdev_get_gpio_in(dev, 0);
 652    *dma_enable = qdev_get_gpio_in(dev, 1);
 653}
 654
 655static const struct SCSIBusInfo esp_scsi_info = {
 656    .tcq = false,
 657    .max_target = ESP_MAX_DEVS,
 658    .max_lun = 7,
 659
 660    .transfer_data = esp_transfer_data,
 661    .complete = esp_command_complete,
 662    .cancel = esp_request_cancelled
 663};
 664
 665static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
 666{
 667    SysBusESPState *sysbus = ESP(opaque);
 668    ESPState *s = &sysbus->esp;
 669
 670    switch (irq) {
 671    case 0:
 672        parent_esp_reset(s, irq, level);
 673        break;
 674    case 1:
 675        esp_dma_enable(opaque, irq, level);
 676        break;
 677    }
 678}
 679
 680static void sysbus_esp_realize(DeviceState *dev, Error **errp)
 681{
 682    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 683    SysBusESPState *sysbus = ESP(dev);
 684    ESPState *s = &sysbus->esp;
 685    Error *err = NULL;
 686
 687    sysbus_init_irq(sbd, &s->irq);
 688    assert(sysbus->it_shift != -1);
 689
 690    s->chip_id = TCHI_FAS100A;
 691    memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops,
 692                          sysbus, "esp", ESP_REGS << sysbus->it_shift);
 693    sysbus_init_mmio(sbd, &sysbus->iomem);
 694
 695    qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
 696
 697    scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
 698    scsi_bus_legacy_handle_cmdline(&s->bus, &err);
 699    if (err != NULL) {
 700        error_propagate(errp, err);
 701        return;
 702    }
 703}
 704
 705static void sysbus_esp_hard_reset(DeviceState *dev)
 706{
 707    SysBusESPState *sysbus = ESP(dev);
 708    esp_hard_reset(&sysbus->esp);
 709}
 710
 711static const VMStateDescription vmstate_sysbus_esp_scsi = {
 712    .name = "sysbusespscsi",
 713    .version_id = 0,
 714    .minimum_version_id = 0,
 715    .fields = (VMStateField[]) {
 716        VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
 717        VMSTATE_END_OF_LIST()
 718    }
 719};
 720
 721static void sysbus_esp_class_init(ObjectClass *klass, void *data)
 722{
 723    DeviceClass *dc = DEVICE_CLASS(klass);
 724
 725    dc->realize = sysbus_esp_realize;
 726    dc->reset = sysbus_esp_hard_reset;
 727    dc->vmsd = &vmstate_sysbus_esp_scsi;
 728    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
 729}
 730
 731static const TypeInfo sysbus_esp_info = {
 732    .name          = TYPE_ESP,
 733    .parent        = TYPE_SYS_BUS_DEVICE,
 734    .instance_size = sizeof(SysBusESPState),
 735    .class_init    = sysbus_esp_class_init,
 736};
 737
 738static void esp_register_types(void)
 739{
 740    type_register_static(&sysbus_esp_info);
 741}
 742
 743type_init(esp_register_types)
 744