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
 581typedef struct {
 582    SysBusDevice busdev;
 583    MemoryRegion iomem;
 584    uint32_t it_shift;
 585    ESPState esp;
 586} SysBusESPState;
 587
 588static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
 589                                 uint64_t val, unsigned int size)
 590{
 591    SysBusESPState *sysbus = opaque;
 592    uint32_t saddr;
 593
 594    saddr = addr >> sysbus->it_shift;
 595    esp_reg_write(&sysbus->esp, saddr, val);
 596}
 597
 598static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
 599                                    unsigned int size)
 600{
 601    SysBusESPState *sysbus = opaque;
 602    uint32_t saddr;
 603
 604    saddr = addr >> sysbus->it_shift;
 605    return esp_reg_read(&sysbus->esp, saddr);
 606}
 607
 608static const MemoryRegionOps sysbus_esp_mem_ops = {
 609    .read = sysbus_esp_mem_read,
 610    .write = sysbus_esp_mem_write,
 611    .endianness = DEVICE_NATIVE_ENDIAN,
 612    .valid.accepts = esp_mem_accepts,
 613};
 614
 615void esp_init(hwaddr espaddr, int it_shift,
 616              ESPDMAMemoryReadWriteFunc dma_memory_read,
 617              ESPDMAMemoryReadWriteFunc dma_memory_write,
 618              void *dma_opaque, qemu_irq irq, qemu_irq *reset,
 619              qemu_irq *dma_enable)
 620{
 621    DeviceState *dev;
 622    SysBusDevice *s;
 623    SysBusESPState *sysbus;
 624    ESPState *esp;
 625
 626    dev = qdev_create(NULL, "esp");
 627    sysbus = DO_UPCAST(SysBusESPState, busdev.qdev, dev);
 628    esp = &sysbus->esp;
 629    esp->dma_memory_read = dma_memory_read;
 630    esp->dma_memory_write = dma_memory_write;
 631    esp->dma_opaque = dma_opaque;
 632    sysbus->it_shift = it_shift;
 633    /* XXX for now until rc4030 has been changed to use DMA enable signal */
 634    esp->dma_enabled = 1;
 635    qdev_init_nofail(dev);
 636    s = SYS_BUS_DEVICE(dev);
 637    sysbus_connect_irq(s, 0, irq);
 638    sysbus_mmio_map(s, 0, espaddr);
 639    *reset = qdev_get_gpio_in(dev, 0);
 640    *dma_enable = qdev_get_gpio_in(dev, 1);
 641}
 642
 643static const struct SCSIBusInfo esp_scsi_info = {
 644    .tcq = false,
 645    .max_target = ESP_MAX_DEVS,
 646    .max_lun = 7,
 647
 648    .transfer_data = esp_transfer_data,
 649    .complete = esp_command_complete,
 650    .cancel = esp_request_cancelled
 651};
 652
 653static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
 654{
 655    DeviceState *d = opaque;
 656    SysBusESPState *sysbus = container_of(d, SysBusESPState, busdev.qdev);
 657    ESPState *s = &sysbus->esp;
 658
 659    switch (irq) {
 660    case 0:
 661        parent_esp_reset(s, irq, level);
 662        break;
 663    case 1:
 664        esp_dma_enable(opaque, irq, level);
 665        break;
 666    }
 667}
 668
 669static int sysbus_esp_init(SysBusDevice *dev)
 670{
 671    SysBusESPState *sysbus = FROM_SYSBUS(SysBusESPState, dev);
 672    ESPState *s = &sysbus->esp;
 673
 674    sysbus_init_irq(dev, &s->irq);
 675    assert(sysbus->it_shift != -1);
 676
 677    s->chip_id = TCHI_FAS100A;
 678    memory_region_init_io(&sysbus->iomem, &sysbus_esp_mem_ops, sysbus,
 679                          "esp", ESP_REGS << sysbus->it_shift);
 680    sysbus_init_mmio(dev, &sysbus->iomem);
 681
 682    qdev_init_gpio_in(&dev->qdev, sysbus_esp_gpio_demux, 2);
 683
 684    scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info, NULL);
 685    return scsi_bus_legacy_handle_cmdline(&s->bus);
 686}
 687
 688static void sysbus_esp_hard_reset(DeviceState *dev)
 689{
 690    SysBusESPState *sysbus = DO_UPCAST(SysBusESPState, busdev.qdev, dev);
 691    esp_hard_reset(&sysbus->esp);
 692}
 693
 694static const VMStateDescription vmstate_sysbus_esp_scsi = {
 695    .name = "sysbusespscsi",
 696    .version_id = 0,
 697    .minimum_version_id = 0,
 698    .minimum_version_id_old = 0,
 699    .fields = (VMStateField[]) {
 700        VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
 701        VMSTATE_END_OF_LIST()
 702    }
 703};
 704
 705static void sysbus_esp_class_init(ObjectClass *klass, void *data)
 706{
 707    DeviceClass *dc = DEVICE_CLASS(klass);
 708    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 709
 710    k->init = sysbus_esp_init;
 711    dc->reset = sysbus_esp_hard_reset;
 712    dc->vmsd = &vmstate_sysbus_esp_scsi;
 713}
 714
 715static const TypeInfo sysbus_esp_info = {
 716    .name          = "esp",
 717    .parent        = TYPE_SYS_BUS_DEVICE,
 718    .instance_size = sizeof(SysBusESPState),
 719    .class_init    = sysbus_esp_class_init,
 720};
 721
 722static void esp_register_types(void)
 723{
 724    type_register_static(&sysbus_esp_info);
 725}
 726
 727type_init(esp_register_types)
 728