esp: remove old deferred command completion mechanism
[qemu/kevin.git] / hw / scsi / esp.c
blobeb6681ca6610229b3d4fd306455c5254f2e1b887
1 /*
2 * QEMU ESP/NCR53C9x emulation
4 * Copyright (c) 2005-2006 Fabrice Bellard
5 * Copyright (c) 2012 Herve Poussineau
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
26 #include "qemu/osdep.h"
27 #include "hw/sysbus.h"
28 #include "migration/vmstate.h"
29 #include "hw/irq.h"
30 #include "hw/scsi/esp.h"
31 #include "trace.h"
32 #include "qemu/log.h"
33 #include "qemu/module.h"
36 * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O),
37 * also produced as NCR89C100. See
38 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
39 * and
40 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
42 * On Macintosh Quadra it is a NCR53C96.
45 static void esp_raise_irq(ESPState *s)
47 if (!(s->rregs[ESP_RSTAT] & STAT_INT)) {
48 s->rregs[ESP_RSTAT] |= STAT_INT;
49 qemu_irq_raise(s->irq);
50 trace_esp_raise_irq();
54 static void esp_lower_irq(ESPState *s)
56 if (s->rregs[ESP_RSTAT] & STAT_INT) {
57 s->rregs[ESP_RSTAT] &= ~STAT_INT;
58 qemu_irq_lower(s->irq);
59 trace_esp_lower_irq();
63 static void esp_raise_drq(ESPState *s)
65 qemu_irq_raise(s->irq_data);
66 trace_esp_raise_drq();
69 static void esp_lower_drq(ESPState *s)
71 qemu_irq_lower(s->irq_data);
72 trace_esp_lower_drq();
75 void esp_dma_enable(ESPState *s, int irq, int level)
77 if (level) {
78 s->dma_enabled = 1;
79 trace_esp_dma_enable();
80 if (s->dma_cb) {
81 s->dma_cb(s);
82 s->dma_cb = NULL;
84 } else {
85 trace_esp_dma_disable();
86 s->dma_enabled = 0;
90 void esp_request_cancelled(SCSIRequest *req)
92 ESPState *s = req->hba_private;
94 if (req == s->current_req) {
95 scsi_req_unref(s->current_req);
96 s->current_req = NULL;
97 s->current_dev = NULL;
101 static uint32_t esp_get_tc(ESPState *s)
103 uint32_t dmalen;
105 dmalen = s->rregs[ESP_TCLO];
106 dmalen |= s->rregs[ESP_TCMID] << 8;
107 dmalen |= s->rregs[ESP_TCHI] << 16;
109 return dmalen;
112 static void esp_set_tc(ESPState *s, uint32_t dmalen)
114 s->rregs[ESP_TCLO] = dmalen;
115 s->rregs[ESP_TCMID] = dmalen >> 8;
116 s->rregs[ESP_TCHI] = dmalen >> 16;
119 static uint32_t esp_get_stc(ESPState *s)
121 uint32_t dmalen;
123 dmalen = s->wregs[ESP_TCLO];
124 dmalen |= s->wregs[ESP_TCMID] << 8;
125 dmalen |= s->wregs[ESP_TCHI] << 16;
127 return dmalen;
130 static uint8_t esp_pdma_read(ESPState *s)
132 uint8_t val;
134 if (s->do_cmd) {
135 val = s->cmdbuf[s->cmdlen++];
136 } else {
137 val = s->ti_buf[s->ti_rptr++];
140 return val;
143 static void esp_pdma_write(ESPState *s, uint8_t val)
145 uint32_t dmalen = esp_get_tc(s);
147 if (dmalen == 0) {
148 return;
151 if (s->do_cmd) {
152 s->cmdbuf[s->cmdlen++] = val;
153 } else {
154 s->ti_buf[s->ti_wptr++] = val;
157 dmalen--;
158 esp_set_tc(s, dmalen);
161 static int esp_select(ESPState *s)
163 int target;
165 target = s->wregs[ESP_WBUSID] & BUSID_DID;
167 s->ti_size = 0;
168 s->ti_rptr = 0;
169 s->ti_wptr = 0;
171 if (s->current_req) {
172 /* Started a new command before the old one finished. Cancel it. */
173 scsi_req_cancel(s->current_req);
174 s->async_len = 0;
177 s->current_dev = scsi_device_find(&s->bus, 0, target, 0);
178 if (!s->current_dev) {
179 /* No such drive */
180 s->rregs[ESP_RSTAT] = 0;
181 s->rregs[ESP_RINTR] |= INTR_DC;
182 s->rregs[ESP_RSEQ] = SEQ_0;
183 esp_raise_irq(s);
184 return -1;
188 * Note that we deliberately don't raise the IRQ here: this will be done
189 * either in do_busid_cmd() for DATA OUT transfers or by the deferred
190 * IRQ mechanism in esp_transfer_data() for DATA IN transfers
192 s->rregs[ESP_RINTR] |= INTR_FC;
193 s->rregs[ESP_RSEQ] = SEQ_CD;
194 return 0;
197 static uint32_t get_cmd(ESPState *s)
199 uint8_t *buf = s->cmdbuf;
200 uint32_t dmalen;
201 int target;
203 target = s->wregs[ESP_WBUSID] & BUSID_DID;
204 if (s->dma) {
205 dmalen = esp_get_tc(s);
206 if (dmalen > ESP_CMDBUF_SZ) {
207 return 0;
209 if (s->dma_memory_read) {
210 s->dma_memory_read(s->dma_opaque, buf, dmalen);
211 } else {
212 if (esp_select(s) < 0) {
213 return -1;
215 esp_raise_drq(s);
216 return 0;
218 } else {
219 dmalen = s->ti_size;
220 if (dmalen > TI_BUFSZ) {
221 return 0;
223 memcpy(buf, s->ti_buf, dmalen);
224 buf[0] = buf[2] >> 5;
226 trace_esp_get_cmd(dmalen, target);
228 if (esp_select(s) < 0) {
229 return -1;
231 return dmalen;
234 static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
236 int32_t datalen;
237 int lun;
238 SCSIDevice *current_lun;
240 trace_esp_do_busid_cmd(busid);
241 lun = busid & 7;
242 current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun);
243 s->current_req = scsi_req_new(current_lun, 0, lun, buf, s);
244 datalen = scsi_req_enqueue(s->current_req);
245 s->ti_size = datalen;
246 if (datalen != 0) {
247 s->rregs[ESP_RSTAT] = STAT_TC;
248 s->rregs[ESP_RSEQ] = SEQ_CD;
249 esp_set_tc(s, 0);
250 if (datalen > 0) {
252 * Switch to DATA IN phase but wait until initial data xfer is
253 * complete before raising the command completion interrupt
255 s->data_in_ready = false;
256 s->rregs[ESP_RSTAT] |= STAT_DI;
257 } else {
258 s->rregs[ESP_RSTAT] |= STAT_DO;
259 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
260 esp_raise_irq(s);
261 esp_lower_drq(s);
263 scsi_req_continue(s->current_req);
264 return;
268 static void do_cmd(ESPState *s)
270 uint8_t *buf = s->cmdbuf;
271 uint8_t busid = buf[0];
273 do_busid_cmd(s, &buf[1], busid);
276 static void satn_pdma_cb(ESPState *s)
278 s->do_cmd = 0;
279 if (s->cmdlen) {
280 do_cmd(s);
284 static void handle_satn(ESPState *s)
286 int32_t cmdlen;
288 if (s->dma && !s->dma_enabled) {
289 s->dma_cb = handle_satn;
290 return;
292 s->pdma_cb = satn_pdma_cb;
293 cmdlen = get_cmd(s);
294 if (cmdlen > 0) {
295 s->cmdlen = cmdlen;
296 do_cmd(s);
297 } else if (cmdlen == 0) {
298 s->cmdlen = 0;
299 s->do_cmd = 1;
300 /* Target present, but no cmd yet - switch to command phase */
301 s->rregs[ESP_RSEQ] = SEQ_CD;
302 s->rregs[ESP_RSTAT] = STAT_CD;
306 static void s_without_satn_pdma_cb(ESPState *s)
308 s->do_cmd = 0;
309 if (s->cmdlen) {
310 do_busid_cmd(s, s->cmdbuf, 0);
314 static void handle_s_without_atn(ESPState *s)
316 int32_t cmdlen;
318 if (s->dma && !s->dma_enabled) {
319 s->dma_cb = handle_s_without_atn;
320 return;
322 s->pdma_cb = s_without_satn_pdma_cb;
323 cmdlen = get_cmd(s);
324 if (cmdlen > 0) {
325 s->cmdlen = cmdlen;
326 do_busid_cmd(s, s->cmdbuf, 0);
327 } else if (cmdlen == 0) {
328 s->cmdlen = 0;
329 s->do_cmd = 1;
330 /* Target present, but no cmd yet - switch to command phase */
331 s->rregs[ESP_RSEQ] = SEQ_CD;
332 s->rregs[ESP_RSTAT] = STAT_CD;
336 static void satn_stop_pdma_cb(ESPState *s)
338 s->do_cmd = 0;
339 if (s->cmdlen) {
340 trace_esp_handle_satn_stop(s->cmdlen);
341 s->do_cmd = 1;
342 s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD;
343 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
344 s->rregs[ESP_RSEQ] = SEQ_CD;
345 esp_raise_irq(s);
349 static void handle_satn_stop(ESPState *s)
351 int32_t cmdlen;
353 if (s->dma && !s->dma_enabled) {
354 s->dma_cb = handle_satn_stop;
355 return;
357 s->pdma_cb = satn_stop_pdma_cb;
358 cmdlen = get_cmd(s);
359 if (cmdlen > 0) {
360 trace_esp_handle_satn_stop(s->cmdlen);
361 s->cmdlen = cmdlen;
362 s->do_cmd = 1;
363 s->rregs[ESP_RSTAT] = STAT_CD;
364 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
365 s->rregs[ESP_RSEQ] = SEQ_CD;
366 esp_raise_irq(s);
367 } else if (cmdlen == 0) {
368 s->cmdlen = 0;
369 s->do_cmd = 1;
370 /* Target present, but no cmd yet - switch to command phase */
371 s->rregs[ESP_RSEQ] = SEQ_CD;
372 s->rregs[ESP_RSTAT] = STAT_CD;
376 static void write_response_pdma_cb(ESPState *s)
378 s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
379 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
380 s->rregs[ESP_RSEQ] = SEQ_CD;
381 esp_raise_irq(s);
384 static void write_response(ESPState *s)
386 trace_esp_write_response(s->status);
387 s->ti_buf[0] = s->status;
388 s->ti_buf[1] = 0;
389 if (s->dma) {
390 if (s->dma_memory_write) {
391 s->dma_memory_write(s->dma_opaque, s->ti_buf, 2);
392 s->rregs[ESP_RSTAT] = STAT_TC | STAT_ST;
393 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC;
394 s->rregs[ESP_RSEQ] = SEQ_CD;
395 } else {
396 s->pdma_cb = write_response_pdma_cb;
397 esp_raise_drq(s);
398 return;
400 } else {
401 s->ti_size = 2;
402 s->ti_rptr = 0;
403 s->ti_wptr = 2;
404 s->rregs[ESP_RFLAGS] = 2;
406 esp_raise_irq(s);
409 static void esp_dma_done(ESPState *s)
411 s->rregs[ESP_RSTAT] |= STAT_TC;
412 s->rregs[ESP_RINTR] |= INTR_BS;
413 s->rregs[ESP_RSEQ] = 0;
414 s->rregs[ESP_RFLAGS] = 0;
415 esp_set_tc(s, 0);
416 esp_raise_irq(s);
419 static void do_dma_pdma_cb(ESPState *s)
421 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
422 int len;
424 if (s->do_cmd) {
425 s->ti_size = 0;
426 s->cmdlen = 0;
427 s->do_cmd = 0;
428 do_cmd(s);
429 esp_lower_drq(s);
430 return;
433 if (to_device) {
434 /* Copy FIFO data to device */
435 len = MIN(s->ti_wptr, TI_BUFSZ);
436 memcpy(s->async_buf, s->ti_buf, len);
437 s->ti_wptr = 0;
438 s->ti_rptr = 0;
439 s->async_buf += len;
440 s->async_len -= len;
441 s->ti_size += len;
442 if (s->async_len == 0) {
443 scsi_req_continue(s->current_req);
444 return;
447 if (esp_get_tc(s) == 0) {
448 esp_lower_drq(s);
449 esp_dma_done(s);
452 return;
453 } else {
454 if (s->async_len == 0) {
455 if (s->current_req) {
456 /* Defer until the scsi layer has completed */
457 scsi_req_continue(s->current_req);
458 s->data_in_ready = false;
460 return;
463 if (esp_get_tc(s) != 0) {
464 /* Copy device data to FIFO */
465 s->ti_wptr = 0;
466 s->ti_rptr = 0;
467 len = MIN(s->async_len, TI_BUFSZ);
468 memcpy(s->ti_buf, s->async_buf, len);
469 s->ti_wptr += len;
470 s->async_buf += len;
471 s->async_len -= len;
472 s->ti_size -= len;
473 esp_set_tc(s, esp_get_tc(s) - len);
474 return;
477 /* Partially filled a scsi buffer. Complete immediately. */
478 esp_lower_drq(s);
479 esp_dma_done(s);
483 static void esp_do_dma(ESPState *s)
485 uint32_t len;
486 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
488 len = esp_get_tc(s);
489 if (s->do_cmd) {
491 * handle_ti_cmd() case: esp_do_dma() is called only from
492 * handle_ti_cmd() with do_cmd != NULL (see the assert())
494 trace_esp_do_dma(s->cmdlen, len);
495 assert(s->cmdlen <= sizeof(s->cmdbuf) &&
496 len <= sizeof(s->cmdbuf) - s->cmdlen);
497 if (s->dma_memory_read) {
498 s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
499 } else {
500 s->pdma_cb = do_dma_pdma_cb;
501 esp_raise_drq(s);
502 return;
504 trace_esp_handle_ti_cmd(s->cmdlen);
505 s->ti_size = 0;
506 s->cmdlen = 0;
507 s->do_cmd = 0;
508 do_cmd(s);
509 return;
511 if (s->async_len == 0) {
512 /* Defer until data is available. */
513 return;
515 if (len > s->async_len) {
516 len = s->async_len;
518 if (to_device) {
519 if (s->dma_memory_read) {
520 s->dma_memory_read(s->dma_opaque, s->async_buf, len);
521 } else {
522 s->pdma_cb = do_dma_pdma_cb;
523 esp_raise_drq(s);
524 return;
526 } else {
527 if (s->dma_memory_write) {
528 s->dma_memory_write(s->dma_opaque, s->async_buf, len);
529 } else {
530 /* Copy device data to FIFO */
531 len = MIN(len, TI_BUFSZ - s->ti_wptr);
532 memcpy(&s->ti_buf[s->ti_wptr], s->async_buf, len);
533 s->ti_wptr += len;
534 s->async_buf += len;
535 s->async_len -= len;
536 s->ti_size -= len;
537 esp_set_tc(s, esp_get_tc(s) - len);
538 s->pdma_cb = do_dma_pdma_cb;
539 esp_raise_drq(s);
541 /* Indicate transfer to FIFO is complete */
542 s->rregs[ESP_RSTAT] |= STAT_TC;
543 return;
546 esp_set_tc(s, esp_get_tc(s) - len);
547 s->async_buf += len;
548 s->async_len -= len;
549 if (to_device) {
550 s->ti_size += len;
551 } else {
552 s->ti_size -= len;
554 if (s->async_len == 0) {
555 scsi_req_continue(s->current_req);
557 * If there is still data to be read from the device then
558 * complete the DMA operation immediately. Otherwise defer
559 * until the scsi layer has completed.
561 if (to_device || esp_get_tc(s) != 0 || s->ti_size == 0) {
562 return;
566 /* Partially filled a scsi buffer. Complete immediately. */
567 esp_dma_done(s);
568 esp_lower_drq(s);
571 void esp_command_complete(SCSIRequest *req, size_t resid)
573 ESPState *s = req->hba_private;
575 trace_esp_command_complete();
576 if (s->ti_size != 0) {
577 trace_esp_command_complete_unexpected();
579 s->ti_size = 0;
580 s->async_len = 0;
581 if (req->status) {
582 trace_esp_command_complete_fail();
584 s->status = req->status;
585 s->rregs[ESP_RSTAT] = STAT_ST;
586 esp_dma_done(s);
587 esp_lower_drq(s);
588 if (s->current_req) {
589 scsi_req_unref(s->current_req);
590 s->current_req = NULL;
591 s->current_dev = NULL;
595 void esp_transfer_data(SCSIRequest *req, uint32_t len)
597 ESPState *s = req->hba_private;
598 int to_device = ((s->rregs[ESP_RSTAT] & 7) == STAT_DO);
599 uint32_t dmalen = esp_get_tc(s);
601 assert(!s->do_cmd);
602 trace_esp_transfer_data(dmalen, s->ti_size);
603 s->async_len = len;
604 s->async_buf = scsi_req_get_buf(req);
606 if (!to_device && !s->data_in_ready) {
608 * Initial incoming data xfer is complete so raise command
609 * completion interrupt
611 s->data_in_ready = true;
612 s->rregs[ESP_RSTAT] |= STAT_TC;
613 s->rregs[ESP_RINTR] |= INTR_BS;
614 esp_raise_irq(s);
617 * If data is ready to transfer and the TI command has already
618 * been executed, start DMA immediately. Otherwise DMA will start
619 * when host sends the TI command
621 if (s->ti_size && (s->rregs[ESP_CMD] == (CMD_TI | CMD_DMA))) {
622 esp_do_dma(s);
624 return;
627 if (dmalen) {
628 esp_do_dma(s);
629 } else if (s->ti_size <= 0) {
631 * If this was the last part of a DMA transfer then the
632 * completion interrupt is deferred to here.
634 esp_dma_done(s);
635 esp_lower_drq(s);
639 static void handle_ti(ESPState *s)
641 uint32_t dmalen;
643 if (s->dma && !s->dma_enabled) {
644 s->dma_cb = handle_ti;
645 return;
648 dmalen = esp_get_tc(s);
649 if (s->dma) {
650 trace_esp_handle_ti(dmalen);
651 s->rregs[ESP_RSTAT] &= ~STAT_TC;
652 esp_do_dma(s);
653 } else if (s->do_cmd) {
654 trace_esp_handle_ti_cmd(s->cmdlen);
655 s->ti_size = 0;
656 s->cmdlen = 0;
657 s->do_cmd = 0;
658 do_cmd(s);
662 void esp_hard_reset(ESPState *s)
664 memset(s->rregs, 0, ESP_REGS);
665 memset(s->wregs, 0, ESP_REGS);
666 s->tchi_written = 0;
667 s->ti_size = 0;
668 s->ti_rptr = 0;
669 s->ti_wptr = 0;
670 s->dma = 0;
671 s->do_cmd = 0;
672 s->dma_cb = NULL;
674 s->rregs[ESP_CFG1] = 7;
677 static void esp_soft_reset(ESPState *s)
679 qemu_irq_lower(s->irq);
680 qemu_irq_lower(s->irq_data);
681 esp_hard_reset(s);
684 static void parent_esp_reset(ESPState *s, int irq, int level)
686 if (level) {
687 esp_soft_reset(s);
691 uint64_t esp_reg_read(ESPState *s, uint32_t saddr)
693 uint32_t val;
695 switch (saddr) {
696 case ESP_FIFO:
697 if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) {
698 /* Data out. */
699 qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n");
700 s->rregs[ESP_FIFO] = 0;
701 } else if (s->ti_rptr < s->ti_wptr) {
702 s->ti_size--;
703 s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++];
705 if (s->ti_rptr == s->ti_wptr) {
706 s->ti_rptr = 0;
707 s->ti_wptr = 0;
709 val = s->rregs[ESP_FIFO];
710 break;
711 case ESP_RINTR:
713 * Clear sequence step, interrupt register and all status bits
714 * except TC
716 val = s->rregs[ESP_RINTR];
717 s->rregs[ESP_RINTR] = 0;
718 s->rregs[ESP_RSTAT] &= ~STAT_TC;
719 s->rregs[ESP_RSEQ] = SEQ_0;
720 esp_lower_irq(s);
721 break;
722 case ESP_TCHI:
723 /* Return the unique id if the value has never been written */
724 if (!s->tchi_written) {
725 val = s->chip_id;
726 } else {
727 val = s->rregs[saddr];
729 break;
730 default:
731 val = s->rregs[saddr];
732 break;
735 trace_esp_mem_readb(saddr, val);
736 return val;
739 void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
741 trace_esp_mem_writeb(saddr, s->wregs[saddr], val);
742 switch (saddr) {
743 case ESP_TCHI:
744 s->tchi_written = true;
745 /* fall through */
746 case ESP_TCLO:
747 case ESP_TCMID:
748 s->rregs[ESP_RSTAT] &= ~STAT_TC;
749 break;
750 case ESP_FIFO:
751 if (s->do_cmd) {
752 if (s->cmdlen < ESP_CMDBUF_SZ) {
753 s->cmdbuf[s->cmdlen++] = val & 0xff;
754 } else {
755 trace_esp_error_fifo_overrun();
757 } else if (s->ti_wptr == TI_BUFSZ - 1) {
758 trace_esp_error_fifo_overrun();
759 } else {
760 s->ti_size++;
761 s->ti_buf[s->ti_wptr++] = val & 0xff;
763 break;
764 case ESP_CMD:
765 s->rregs[saddr] = val;
766 if (val & CMD_DMA) {
767 s->dma = 1;
768 /* Reload DMA counter. */
769 if (esp_get_stc(s) == 0) {
770 esp_set_tc(s, 0x10000);
771 } else {
772 esp_set_tc(s, esp_get_stc(s));
774 } else {
775 s->dma = 0;
777 switch (val & CMD_CMD) {
778 case CMD_NOP:
779 trace_esp_mem_writeb_cmd_nop(val);
780 break;
781 case CMD_FLUSH:
782 trace_esp_mem_writeb_cmd_flush(val);
783 /*s->ti_size = 0;*/
784 s->ti_wptr = 0;
785 s->ti_rptr = 0;
786 break;
787 case CMD_RESET:
788 trace_esp_mem_writeb_cmd_reset(val);
789 esp_soft_reset(s);
790 break;
791 case CMD_BUSRESET:
792 trace_esp_mem_writeb_cmd_bus_reset(val);
793 if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) {
794 s->rregs[ESP_RINTR] |= INTR_RST;
795 esp_raise_irq(s);
797 break;
798 case CMD_TI:
799 trace_esp_mem_writeb_cmd_ti(val);
800 handle_ti(s);
801 break;
802 case CMD_ICCS:
803 trace_esp_mem_writeb_cmd_iccs(val);
804 write_response(s);
805 s->rregs[ESP_RINTR] |= INTR_FC;
806 s->rregs[ESP_RSTAT] |= STAT_MI;
807 break;
808 case CMD_MSGACC:
809 trace_esp_mem_writeb_cmd_msgacc(val);
810 s->rregs[ESP_RINTR] |= INTR_DC;
811 s->rregs[ESP_RSEQ] = 0;
812 s->rregs[ESP_RFLAGS] = 0;
813 esp_raise_irq(s);
814 break;
815 case CMD_PAD:
816 trace_esp_mem_writeb_cmd_pad(val);
817 s->rregs[ESP_RSTAT] = STAT_TC;
818 s->rregs[ESP_RINTR] |= INTR_FC;
819 s->rregs[ESP_RSEQ] = 0;
820 break;
821 case CMD_SATN:
822 trace_esp_mem_writeb_cmd_satn(val);
823 break;
824 case CMD_RSTATN:
825 trace_esp_mem_writeb_cmd_rstatn(val);
826 break;
827 case CMD_SEL:
828 trace_esp_mem_writeb_cmd_sel(val);
829 handle_s_without_atn(s);
830 break;
831 case CMD_SELATN:
832 trace_esp_mem_writeb_cmd_selatn(val);
833 handle_satn(s);
834 break;
835 case CMD_SELATNS:
836 trace_esp_mem_writeb_cmd_selatns(val);
837 handle_satn_stop(s);
838 break;
839 case CMD_ENSEL:
840 trace_esp_mem_writeb_cmd_ensel(val);
841 s->rregs[ESP_RINTR] = 0;
842 break;
843 case CMD_DISSEL:
844 trace_esp_mem_writeb_cmd_dissel(val);
845 s->rregs[ESP_RINTR] = 0;
846 esp_raise_irq(s);
847 break;
848 default:
849 trace_esp_error_unhandled_command(val);
850 break;
852 break;
853 case ESP_WBUSID ... ESP_WSYNO:
854 break;
855 case ESP_CFG1:
856 case ESP_CFG2: case ESP_CFG3:
857 case ESP_RES3: case ESP_RES4:
858 s->rregs[saddr] = val;
859 break;
860 case ESP_WCCF ... ESP_WTEST:
861 break;
862 default:
863 trace_esp_error_invalid_write(val, saddr);
864 return;
866 s->wregs[saddr] = val;
869 static bool esp_mem_accepts(void *opaque, hwaddr addr,
870 unsigned size, bool is_write,
871 MemTxAttrs attrs)
873 return (size == 1) || (is_write && size == 4);
876 static bool esp_is_before_version_5(void *opaque, int version_id)
878 ESPState *s = ESP(opaque);
880 version_id = MIN(version_id, s->mig_version_id);
881 return version_id < 5;
884 static bool esp_is_version_5(void *opaque, int version_id)
886 ESPState *s = ESP(opaque);
888 version_id = MIN(version_id, s->mig_version_id);
889 return version_id == 5;
892 static int esp_pre_save(void *opaque)
894 ESPState *s = ESP(opaque);
896 s->mig_version_id = vmstate_esp.version_id;
897 return 0;
900 static int esp_post_load(void *opaque, int version_id)
902 ESPState *s = ESP(opaque);
904 version_id = MIN(version_id, s->mig_version_id);
906 if (version_id < 5) {
907 esp_set_tc(s, s->mig_dma_left);
910 s->mig_version_id = vmstate_esp.version_id;
911 return 0;
914 const VMStateDescription vmstate_esp = {
915 .name = "esp",
916 .version_id = 5,
917 .minimum_version_id = 3,
918 .pre_save = esp_pre_save,
919 .post_load = esp_post_load,
920 .fields = (VMStateField[]) {
921 VMSTATE_BUFFER(rregs, ESPState),
922 VMSTATE_BUFFER(wregs, ESPState),
923 VMSTATE_INT32(ti_size, ESPState),
924 VMSTATE_UINT32(ti_rptr, ESPState),
925 VMSTATE_UINT32(ti_wptr, ESPState),
926 VMSTATE_BUFFER(ti_buf, ESPState),
927 VMSTATE_UINT32(status, ESPState),
928 VMSTATE_UINT32_TEST(mig_deferred_status, ESPState,
929 esp_is_before_version_5),
930 VMSTATE_BOOL_TEST(mig_deferred_complete, ESPState,
931 esp_is_before_version_5),
932 VMSTATE_UINT32(dma, ESPState),
933 VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16),
934 VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
935 VMSTATE_UINT32(cmdlen, ESPState),
936 VMSTATE_UINT32(do_cmd, ESPState),
937 VMSTATE_UINT32_TEST(mig_dma_left, ESPState, esp_is_before_version_5),
938 VMSTATE_BOOL_TEST(data_in_ready, ESPState, esp_is_version_5),
939 VMSTATE_END_OF_LIST()
943 static void sysbus_esp_mem_write(void *opaque, hwaddr addr,
944 uint64_t val, unsigned int size)
946 SysBusESPState *sysbus = opaque;
947 ESPState *s = ESP(&sysbus->esp);
948 uint32_t saddr;
950 saddr = addr >> sysbus->it_shift;
951 esp_reg_write(s, saddr, val);
954 static uint64_t sysbus_esp_mem_read(void *opaque, hwaddr addr,
955 unsigned int size)
957 SysBusESPState *sysbus = opaque;
958 ESPState *s = ESP(&sysbus->esp);
959 uint32_t saddr;
961 saddr = addr >> sysbus->it_shift;
962 return esp_reg_read(s, saddr);
965 static const MemoryRegionOps sysbus_esp_mem_ops = {
966 .read = sysbus_esp_mem_read,
967 .write = sysbus_esp_mem_write,
968 .endianness = DEVICE_NATIVE_ENDIAN,
969 .valid.accepts = esp_mem_accepts,
972 static void sysbus_esp_pdma_write(void *opaque, hwaddr addr,
973 uint64_t val, unsigned int size)
975 SysBusESPState *sysbus = opaque;
976 ESPState *s = ESP(&sysbus->esp);
977 uint32_t dmalen;
979 trace_esp_pdma_write(size);
981 switch (size) {
982 case 1:
983 esp_pdma_write(s, val);
984 break;
985 case 2:
986 esp_pdma_write(s, val >> 8);
987 esp_pdma_write(s, val);
988 break;
990 dmalen = esp_get_tc(s);
991 if (dmalen == 0 || (s->ti_wptr == TI_BUFSZ)) {
992 s->pdma_cb(s);
996 static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr,
997 unsigned int size)
999 SysBusESPState *sysbus = opaque;
1000 ESPState *s = ESP(&sysbus->esp);
1001 uint64_t val = 0;
1003 trace_esp_pdma_read(size);
1005 switch (size) {
1006 case 1:
1007 val = esp_pdma_read(s);
1008 break;
1009 case 2:
1010 val = esp_pdma_read(s);
1011 val = (val << 8) | esp_pdma_read(s);
1012 break;
1014 if (s->ti_rptr == s->ti_wptr) {
1015 s->ti_wptr = 0;
1016 s->ti_rptr = 0;
1017 s->pdma_cb(s);
1019 return val;
1022 static const MemoryRegionOps sysbus_esp_pdma_ops = {
1023 .read = sysbus_esp_pdma_read,
1024 .write = sysbus_esp_pdma_write,
1025 .endianness = DEVICE_NATIVE_ENDIAN,
1026 .valid.min_access_size = 1,
1027 .valid.max_access_size = 4,
1028 .impl.min_access_size = 1,
1029 .impl.max_access_size = 2,
1032 static const struct SCSIBusInfo esp_scsi_info = {
1033 .tcq = false,
1034 .max_target = ESP_MAX_DEVS,
1035 .max_lun = 7,
1037 .transfer_data = esp_transfer_data,
1038 .complete = esp_command_complete,
1039 .cancel = esp_request_cancelled
1042 static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
1044 SysBusESPState *sysbus = SYSBUS_ESP(opaque);
1045 ESPState *s = ESP(&sysbus->esp);
1047 switch (irq) {
1048 case 0:
1049 parent_esp_reset(s, irq, level);
1050 break;
1051 case 1:
1052 esp_dma_enable(opaque, irq, level);
1053 break;
1057 static void sysbus_esp_realize(DeviceState *dev, Error **errp)
1059 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1060 SysBusESPState *sysbus = SYSBUS_ESP(dev);
1061 ESPState *s = ESP(&sysbus->esp);
1063 if (!qdev_realize(DEVICE(s), NULL, errp)) {
1064 return;
1067 sysbus_init_irq(sbd, &s->irq);
1068 sysbus_init_irq(sbd, &s->irq_data);
1069 assert(sysbus->it_shift != -1);
1071 s->chip_id = TCHI_FAS100A;
1072 memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops,
1073 sysbus, "esp-regs", ESP_REGS << sysbus->it_shift);
1074 sysbus_init_mmio(sbd, &sysbus->iomem);
1075 memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_ops,
1076 sysbus, "esp-pdma", 4);
1077 sysbus_init_mmio(sbd, &sysbus->pdma);
1079 qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
1081 scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
1084 static void sysbus_esp_hard_reset(DeviceState *dev)
1086 SysBusESPState *sysbus = SYSBUS_ESP(dev);
1087 ESPState *s = ESP(&sysbus->esp);
1089 esp_hard_reset(s);
1092 static void sysbus_esp_init(Object *obj)
1094 SysBusESPState *sysbus = SYSBUS_ESP(obj);
1096 object_initialize_child(obj, "esp", &sysbus->esp, TYPE_ESP);
1099 static const VMStateDescription vmstate_sysbus_esp_scsi = {
1100 .name = "sysbusespscsi",
1101 .version_id = 2,
1102 .minimum_version_id = 1,
1103 .fields = (VMStateField[]) {
1104 VMSTATE_UINT8_V(esp.mig_version_id, SysBusESPState, 2),
1105 VMSTATE_STRUCT(esp, SysBusESPState, 0, vmstate_esp, ESPState),
1106 VMSTATE_END_OF_LIST()
1110 static void sysbus_esp_class_init(ObjectClass *klass, void *data)
1112 DeviceClass *dc = DEVICE_CLASS(klass);
1114 dc->realize = sysbus_esp_realize;
1115 dc->reset = sysbus_esp_hard_reset;
1116 dc->vmsd = &vmstate_sysbus_esp_scsi;
1117 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1120 static const TypeInfo sysbus_esp_info = {
1121 .name = TYPE_SYSBUS_ESP,
1122 .parent = TYPE_SYS_BUS_DEVICE,
1123 .instance_init = sysbus_esp_init,
1124 .instance_size = sizeof(SysBusESPState),
1125 .class_init = sysbus_esp_class_init,
1128 static void esp_class_init(ObjectClass *klass, void *data)
1130 DeviceClass *dc = DEVICE_CLASS(klass);
1132 /* internal device for sysbusesp/pciespscsi, not user-creatable */
1133 dc->user_creatable = false;
1134 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1137 static const TypeInfo esp_info = {
1138 .name = TYPE_ESP,
1139 .parent = TYPE_DEVICE,
1140 .instance_size = sizeof(ESPState),
1141 .class_init = esp_class_init,
1144 static void esp_register_types(void)
1146 type_register_static(&sysbus_esp_info);
1147 type_register_static(&esp_info);
1150 type_init(esp_register_types)