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