Lines Matching +full:- +full:s

4  * Copyright (c) 2005-2006 Fabrice Bellard
6 * Copyright (c) 2023 Mark Cave-Ayland
39 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C100.txt
41 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt
46 static void esp_raise_irq(ESPState *s) in esp_raise_irq() argument
48 if (!(s->rregs[ESP_RSTAT] & STAT_INT)) { in esp_raise_irq()
49 s->rregs[ESP_RSTAT] |= STAT_INT; in esp_raise_irq()
50 qemu_irq_raise(s->irq); in esp_raise_irq()
55 static void esp_lower_irq(ESPState *s) in esp_lower_irq() argument
57 if (s->rregs[ESP_RSTAT] & STAT_INT) { in esp_lower_irq()
58 s->rregs[ESP_RSTAT] &= ~STAT_INT; in esp_lower_irq()
59 qemu_irq_lower(s->irq); in esp_lower_irq()
64 static void esp_raise_drq(ESPState *s) in esp_raise_drq() argument
66 if (!(s->drq_state)) { in esp_raise_drq()
67 qemu_irq_raise(s->drq_irq); in esp_raise_drq()
69 s->drq_state = true; in esp_raise_drq()
73 static void esp_lower_drq(ESPState *s) in esp_lower_drq() argument
75 if (s->drq_state) { in esp_lower_drq()
76 qemu_irq_lower(s->drq_irq); in esp_lower_drq()
78 s->drq_state = false; in esp_lower_drq()
87 static void esp_set_phase(ESPState *s, uint8_t phase) in esp_set_phase() argument
89 s->rregs[ESP_RSTAT] &= ~7; in esp_set_phase()
90 s->rregs[ESP_RSTAT] |= phase; in esp_set_phase()
95 static uint8_t esp_get_phase(ESPState *s) in esp_get_phase() argument
97 return s->rregs[ESP_RSTAT] & 7; in esp_get_phase()
100 void esp_dma_enable(ESPState *s, int irq, int level) in esp_dma_enable() argument
103 s->dma_enabled = 1; in esp_dma_enable()
105 if (s->dma_cb) { in esp_dma_enable()
106 s->dma_cb(s); in esp_dma_enable()
107 s->dma_cb = NULL; in esp_dma_enable()
111 s->dma_enabled = 0; in esp_dma_enable()
117 ESPState *s = req->hba_private; in esp_request_cancelled() local
119 if (req == s->current_req) { in esp_request_cancelled()
120 scsi_req_unref(s->current_req); in esp_request_cancelled()
121 s->current_req = NULL; in esp_request_cancelled()
122 s->current_dev = NULL; in esp_request_cancelled()
123 s->async_len = 0; in esp_request_cancelled()
127 static void esp_update_drq(ESPState *s) in esp_update_drq() argument
131 switch (esp_get_phase(s)) { in esp_update_drq()
148 if (s->dma) { in esp_update_drq()
151 if (fifo8_num_free(&s->fifo) < 2) { in esp_update_drq()
152 esp_lower_drq(s); in esp_update_drq()
154 esp_raise_drq(s); in esp_update_drq()
157 if (fifo8_num_used(&s->fifo) < 2) { in esp_update_drq()
158 esp_lower_drq(s); in esp_update_drq()
160 esp_raise_drq(s); in esp_update_drq()
165 esp_lower_drq(s); in esp_update_drq()
169 static void esp_fifo_push(ESPState *s, uint8_t val) in esp_fifo_push() argument
171 if (fifo8_num_used(&s->fifo) == s->fifo.capacity) { in esp_fifo_push()
174 fifo8_push(&s->fifo, val); in esp_fifo_push()
177 esp_update_drq(s); in esp_fifo_push()
180 static void esp_fifo_push_buf(ESPState *s, uint8_t *buf, int len) in esp_fifo_push_buf() argument
182 fifo8_push_all(&s->fifo, buf, len); in esp_fifo_push_buf()
183 esp_update_drq(s); in esp_fifo_push_buf()
186 static uint8_t esp_fifo_pop(ESPState *s) in esp_fifo_pop() argument
190 if (fifo8_is_empty(&s->fifo)) { in esp_fifo_pop()
193 val = fifo8_pop(&s->fifo); in esp_fifo_pop()
196 esp_update_drq(s); in esp_fifo_pop()
200 static uint32_t esp_fifo_pop_buf(ESPState *s, uint8_t *dest, int maxlen) in esp_fifo_pop_buf() argument
202 uint32_t len = fifo8_pop_buf(&s->fifo, dest, maxlen); in esp_fifo_pop_buf()
204 esp_update_drq(s); in esp_fifo_pop_buf()
208 static uint32_t esp_get_tc(ESPState *s) in esp_get_tc() argument
212 dmalen = s->rregs[ESP_TCLO]; in esp_get_tc()
213 dmalen |= s->rregs[ESP_TCMID] << 8; in esp_get_tc()
214 dmalen |= s->rregs[ESP_TCHI] << 16; in esp_get_tc()
219 static void esp_set_tc(ESPState *s, uint32_t dmalen) in esp_set_tc() argument
221 uint32_t old_tc = esp_get_tc(s); in esp_set_tc()
223 s->rregs[ESP_TCLO] = dmalen; in esp_set_tc()
224 s->rregs[ESP_TCMID] = dmalen >> 8; in esp_set_tc()
225 s->rregs[ESP_TCHI] = dmalen >> 16; in esp_set_tc()
228 s->rregs[ESP_RSTAT] |= STAT_TC; in esp_set_tc()
232 static uint32_t esp_get_stc(ESPState *s) in esp_get_stc() argument
236 dmalen = s->wregs[ESP_TCLO]; in esp_get_stc()
237 dmalen |= s->wregs[ESP_TCMID] << 8; in esp_get_stc()
238 dmalen |= s->wregs[ESP_TCHI] << 16; in esp_get_stc()
243 static uint8_t esp_pdma_read(ESPState *s) in esp_pdma_read() argument
247 val = esp_fifo_pop(s); in esp_pdma_read()
251 static void esp_pdma_write(ESPState *s, uint8_t val) in esp_pdma_write() argument
253 uint32_t dmalen = esp_get_tc(s); in esp_pdma_write()
255 esp_fifo_push(s, val); in esp_pdma_write()
257 if (dmalen && s->drq_state) { in esp_pdma_write()
258 dmalen--; in esp_pdma_write()
259 esp_set_tc(s, dmalen); in esp_pdma_write()
263 static int esp_select(ESPState *s) in esp_select() argument
267 target = s->wregs[ESP_WBUSID] & BUSID_DID; in esp_select()
269 s->ti_size = 0; in esp_select()
270 s->rregs[ESP_RSEQ] = SEQ_0; in esp_select()
272 if (s->current_req) { in esp_select()
274 scsi_req_cancel(s->current_req); in esp_select()
277 s->current_dev = scsi_device_find(&s->bus, 0, target, 0); in esp_select()
278 if (!s->current_dev) { in esp_select()
280 s->rregs[ESP_RSTAT] = 0; in esp_select()
281 s->rregs[ESP_RINTR] = INTR_DC; in esp_select()
282 esp_raise_irq(s); in esp_select()
283 return -1; in esp_select()
293 static void esp_do_dma(ESPState *s);
294 static void esp_do_nodma(ESPState *s);
296 static void do_command_phase(ESPState *s) in do_command_phase() argument
303 trace_esp_do_command_phase(s->lun); in do_command_phase()
304 cmdlen = fifo8_num_used(&s->cmdfifo); in do_command_phase()
305 if (!cmdlen || !s->current_dev) { in do_command_phase()
308 fifo8_pop_buf(&s->cmdfifo, buf, cmdlen); in do_command_phase()
310 current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, s->lun); in do_command_phase()
313 s->rregs[ESP_RSTAT] = 0; in do_command_phase()
314 s->rregs[ESP_RINTR] = INTR_DC; in do_command_phase()
315 s->rregs[ESP_RSEQ] = SEQ_0; in do_command_phase()
316 esp_raise_irq(s); in do_command_phase()
320 s->current_req = scsi_req_new(current_lun, 0, s->lun, buf, cmdlen, s); in do_command_phase()
321 datalen = scsi_req_enqueue(s->current_req); in do_command_phase()
322 s->ti_size = datalen; in do_command_phase()
323 fifo8_reset(&s->cmdfifo); in do_command_phase()
324 s->data_ready = false; in do_command_phase()
331 esp_set_phase(s, STAT_DI); in do_command_phase()
333 esp_set_phase(s, STAT_DO); in do_command_phase()
335 scsi_req_continue(s->current_req); in do_command_phase()
340 static void do_message_phase(ESPState *s) in do_message_phase() argument
342 if (s->cmdfifo_cdb_offset) { in do_message_phase()
343 uint8_t message = fifo8_is_empty(&s->cmdfifo) ? 0 : in do_message_phase()
344 fifo8_pop(&s->cmdfifo); in do_message_phase()
347 s->lun = message & 7; in do_message_phase()
348 s->cmdfifo_cdb_offset--; in do_message_phase()
352 if (s->cmdfifo_cdb_offset) { in do_message_phase()
353 int len = MIN(s->cmdfifo_cdb_offset, fifo8_num_used(&s->cmdfifo)); in do_message_phase()
354 fifo8_drop(&s->cmdfifo, len); in do_message_phase()
355 s->cmdfifo_cdb_offset = 0; in do_message_phase()
359 static void do_cmd(ESPState *s) in do_cmd() argument
361 do_message_phase(s); in do_cmd()
362 assert(s->cmdfifo_cdb_offset == 0); in do_cmd()
363 do_command_phase(s); in do_cmd()
366 static void handle_satn(ESPState *s) in handle_satn() argument
368 if (s->dma && !s->dma_enabled) { in handle_satn()
369 s->dma_cb = handle_satn; in handle_satn()
373 if (esp_select(s) < 0) { in handle_satn()
377 esp_set_phase(s, STAT_MO); in handle_satn()
379 if (s->dma) { in handle_satn()
380 esp_do_dma(s); in handle_satn()
382 esp_do_nodma(s); in handle_satn()
386 static void handle_s_without_atn(ESPState *s) in handle_s_without_atn() argument
388 if (s->dma && !s->dma_enabled) { in handle_s_without_atn()
389 s->dma_cb = handle_s_without_atn; in handle_s_without_atn()
393 if (esp_select(s) < 0) { in handle_s_without_atn()
397 esp_set_phase(s, STAT_CD); in handle_s_without_atn()
398 s->cmdfifo_cdb_offset = 0; in handle_s_without_atn()
400 if (s->dma) { in handle_s_without_atn()
401 esp_do_dma(s); in handle_s_without_atn()
403 esp_do_nodma(s); in handle_s_without_atn()
407 static void handle_satn_stop(ESPState *s) in handle_satn_stop() argument
409 if (s->dma && !s->dma_enabled) { in handle_satn_stop()
410 s->dma_cb = handle_satn_stop; in handle_satn_stop()
414 if (esp_select(s) < 0) { in handle_satn_stop()
418 esp_set_phase(s, STAT_MO); in handle_satn_stop()
419 s->cmdfifo_cdb_offset = 0; in handle_satn_stop()
421 if (s->dma) { in handle_satn_stop()
422 esp_do_dma(s); in handle_satn_stop()
424 esp_do_nodma(s); in handle_satn_stop()
428 static void handle_pad(ESPState *s) in handle_pad() argument
430 if (s->dma) { in handle_pad()
431 esp_do_dma(s); in handle_pad()
433 esp_do_nodma(s); in handle_pad()
437 static void write_response(ESPState *s) in write_response() argument
439 trace_esp_write_response(s->status); in write_response()
441 if (s->dma) { in write_response()
442 esp_do_dma(s); in write_response()
444 esp_do_nodma(s); in write_response()
448 static bool esp_cdb_ready(ESPState *s) in esp_cdb_ready() argument
450 int len = fifo8_num_used(&s->cmdfifo) - s->cmdfifo_cdb_offset; in esp_cdb_ready()
459 pbuf = fifo8_peek_bufptr(&s->cmdfifo, len, &n); in esp_cdb_ready()
469 cdblen = scsi_cdb_length((uint8_t *)&pbuf[s->cmdfifo_cdb_offset]); in esp_cdb_ready()
474 static void esp_dma_ti_check(ESPState *s) in esp_dma_ti_check() argument
476 if (esp_get_tc(s) == 0 && fifo8_num_used(&s->fifo) < 2) { in esp_dma_ti_check()
477 s->rregs[ESP_RINTR] |= INTR_BS; in esp_dma_ti_check()
478 esp_raise_irq(s); in esp_dma_ti_check()
482 static void esp_do_dma(ESPState *s) in esp_do_dma() argument
487 len = esp_get_tc(s); in esp_do_dma()
489 switch (esp_get_phase(s)) { in esp_do_dma()
491 if (s->dma_memory_read) { in esp_do_dma()
492 len = MIN(len, fifo8_num_free(&s->cmdfifo)); in esp_do_dma()
493 s->dma_memory_read(s->dma_opaque, buf, len); in esp_do_dma()
494 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
496 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_dma()
497 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_dma()
500 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_dma()
501 s->cmdfifo_cdb_offset += len; in esp_do_dma()
503 switch (s->rregs[ESP_CMD]) { in esp_do_dma()
505 if (fifo8_num_used(&s->cmdfifo) >= 1) { in esp_do_dma()
507 esp_set_phase(s, STAT_CD); in esp_do_dma()
508 s->rregs[ESP_RSEQ] = SEQ_CD; in esp_do_dma()
509 s->cmdfifo_cdb_offset = 1; in esp_do_dma()
511 if (fifo8_num_used(&s->cmdfifo) > 1) { in esp_do_dma()
513 esp_do_dma(s); in esp_do_dma()
519 if (fifo8_num_used(&s->cmdfifo) == 1) { in esp_do_dma()
521 s->rregs[ESP_RSEQ] = SEQ_MO; in esp_do_dma()
522 s->cmdfifo_cdb_offset = 1; in esp_do_dma()
525 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; in esp_do_dma()
526 esp_raise_irq(s); in esp_do_dma()
532 if (esp_get_tc(s) == 0) { in esp_do_dma()
533 esp_set_phase(s, STAT_CD); in esp_do_dma()
534 s->rregs[ESP_CMD] = 0; in esp_do_dma()
535 s->rregs[ESP_RINTR] |= INTR_BS; in esp_do_dma()
536 esp_raise_irq(s); in esp_do_dma()
543 cmdlen = fifo8_num_used(&s->cmdfifo); in esp_do_dma()
545 if (s->dma_memory_read) { in esp_do_dma()
546 len = MIN(len, fifo8_num_free(&s->cmdfifo)); in esp_do_dma()
547 s->dma_memory_read(s->dma_opaque, buf, len); in esp_do_dma()
548 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_dma()
549 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
551 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_dma()
552 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_dma()
553 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_dma()
556 s->ti_size = 0; in esp_do_dma()
557 if (esp_get_tc(s) == 0) { in esp_do_dma()
559 do_cmd(s); in esp_do_dma()
564 if (!s->current_req) { in esp_do_dma()
567 if (s->async_len == 0 && esp_get_tc(s)) { in esp_do_dma()
571 if (len > s->async_len) { in esp_do_dma()
572 len = s->async_len; in esp_do_dma()
575 switch (s->rregs[ESP_CMD]) { in esp_do_dma()
577 if (s->dma_memory_read) { in esp_do_dma()
578 s->dma_memory_read(s->dma_opaque, s->async_buf, len); in esp_do_dma()
579 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
582 len = MIN(s->async_len, ESP_FIFO_SZ); in esp_do_dma()
583 len = MIN(len, fifo8_num_used(&s->fifo)); in esp_do_dma()
584 len = esp_fifo_pop_buf(s, s->async_buf, len); in esp_do_dma()
587 s->async_buf += len; in esp_do_dma()
588 s->async_len -= len; in esp_do_dma()
589 s->ti_size += len; in esp_do_dma()
594 if (!s->dma_memory_read) { in esp_do_dma()
595 len = MIN(s->async_len, ESP_FIFO_SZ); in esp_do_dma()
596 len = MIN(len, fifo8_num_free(&s->fifo)); in esp_do_dma()
599 memset(s->async_buf, 0, len); in esp_do_dma()
601 s->async_buf += len; in esp_do_dma()
602 s->async_len -= len; in esp_do_dma()
603 s->ti_size += len; in esp_do_dma()
607 if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) { in esp_do_dma()
609 scsi_req_continue(s->current_req); in esp_do_dma()
613 esp_dma_ti_check(s); in esp_do_dma()
617 if (!s->current_req) { in esp_do_dma()
620 if (s->async_len == 0 && esp_get_tc(s)) { in esp_do_dma()
624 if (len > s->async_len) { in esp_do_dma()
625 len = s->async_len; in esp_do_dma()
628 switch (s->rregs[ESP_CMD]) { in esp_do_dma()
630 if (s->dma_memory_write) { in esp_do_dma()
631 s->dma_memory_write(s->dma_opaque, s->async_buf, len); in esp_do_dma()
634 len = MIN(len, fifo8_num_free(&s->fifo)); in esp_do_dma()
635 esp_fifo_push_buf(s, s->async_buf, len); in esp_do_dma()
638 s->async_buf += len; in esp_do_dma()
639 s->async_len -= len; in esp_do_dma()
640 s->ti_size -= len; in esp_do_dma()
641 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
646 if (!s->dma_memory_write) { in esp_do_dma()
647 len = MIN(len, fifo8_num_free(&s->fifo)); in esp_do_dma()
650 s->async_buf += len; in esp_do_dma()
651 s->async_len -= len; in esp_do_dma()
652 s->ti_size -= len; in esp_do_dma()
653 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
657 if (s->async_len == 0 && s->ti_size == 0 && esp_get_tc(s)) { in esp_do_dma()
659 scsi_req_continue(s->current_req); in esp_do_dma()
663 if (s->async_len == 0 && fifo8_num_used(&s->fifo) < 2) { in esp_do_dma()
665 scsi_req_continue(s->current_req); in esp_do_dma()
669 esp_dma_ti_check(s); in esp_do_dma()
673 switch (s->rregs[ESP_CMD]) { in esp_do_dma()
678 buf[0] = s->status; in esp_do_dma()
680 if (s->dma_memory_write) { in esp_do_dma()
681 s->dma_memory_write(s->dma_opaque, buf, len); in esp_do_dma()
683 esp_fifo_push_buf(s, buf, len); in esp_do_dma()
686 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
687 esp_set_phase(s, STAT_MI); in esp_do_dma()
689 if (esp_get_tc(s) > 0) { in esp_do_dma()
691 esp_do_dma(s); in esp_do_dma()
698 if (fifo8_num_used(&s->fifo) < 2) { in esp_do_dma()
699 s->rregs[ESP_RINTR] |= INTR_BS; in esp_do_dma()
700 esp_raise_irq(s); in esp_do_dma()
707 switch (s->rregs[ESP_CMD]) { in esp_do_dma()
714 if (s->dma_memory_write) { in esp_do_dma()
715 s->dma_memory_write(s->dma_opaque, buf, len); in esp_do_dma()
717 esp_fifo_push_buf(s, buf, len); in esp_do_dma()
720 esp_set_tc(s, esp_get_tc(s) - len); in esp_do_dma()
723 s->rregs[ESP_RINTR] |= INTR_FC; in esp_do_dma()
724 esp_raise_irq(s); in esp_do_dma()
732 static void esp_nodma_ti_dataout(ESPState *s) in esp_nodma_ti_dataout() argument
736 if (!s->current_req) { in esp_nodma_ti_dataout()
739 if (s->async_len == 0) { in esp_nodma_ti_dataout()
743 len = MIN(s->async_len, ESP_FIFO_SZ); in esp_nodma_ti_dataout()
744 len = MIN(len, fifo8_num_used(&s->fifo)); in esp_nodma_ti_dataout()
745 esp_fifo_pop_buf(s, s->async_buf, len); in esp_nodma_ti_dataout()
746 s->async_buf += len; in esp_nodma_ti_dataout()
747 s->async_len -= len; in esp_nodma_ti_dataout()
748 s->ti_size += len; in esp_nodma_ti_dataout()
750 if (s->async_len == 0) { in esp_nodma_ti_dataout()
751 scsi_req_continue(s->current_req); in esp_nodma_ti_dataout()
755 s->rregs[ESP_RINTR] |= INTR_BS; in esp_nodma_ti_dataout()
756 esp_raise_irq(s); in esp_nodma_ti_dataout()
759 static void esp_do_nodma(ESPState *s) in esp_do_nodma() argument
765 switch (esp_get_phase(s)) { in esp_do_nodma()
767 switch (s->rregs[ESP_CMD]) { in esp_do_nodma()
770 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_nodma()
771 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
772 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
774 if (fifo8_num_used(&s->cmdfifo) >= 1) { in esp_do_nodma()
776 esp_set_phase(s, STAT_CD); in esp_do_nodma()
777 s->rregs[ESP_RSEQ] = SEQ_CD; in esp_do_nodma()
778 s->cmdfifo_cdb_offset = 1; in esp_do_nodma()
780 if (fifo8_num_used(&s->cmdfifo) > 1) { in esp_do_nodma()
782 esp_do_nodma(s); in esp_do_nodma()
789 len = esp_fifo_pop_buf(s, buf, in esp_do_nodma()
790 MIN(fifo8_num_used(&s->fifo), 1)); in esp_do_nodma()
791 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
792 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
794 if (fifo8_num_used(&s->cmdfifo) >= 1) { in esp_do_nodma()
796 s->rregs[ESP_RSEQ] = SEQ_MO; in esp_do_nodma()
797 s->cmdfifo_cdb_offset = 1; in esp_do_nodma()
800 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; in esp_do_nodma()
801 esp_raise_irq(s); in esp_do_nodma()
807 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_nodma()
808 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
809 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
812 s->cmdfifo_cdb_offset = fifo8_num_used(&s->cmdfifo); in esp_do_nodma()
813 esp_set_phase(s, STAT_CD); in esp_do_nodma()
814 s->rregs[ESP_CMD] = 0; in esp_do_nodma()
815 s->rregs[ESP_RINTR] |= INTR_BS; in esp_do_nodma()
816 esp_raise_irq(s); in esp_do_nodma()
822 switch (s->rregs[ESP_CMD]) { in esp_do_nodma()
825 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_nodma()
826 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
827 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
829 cmdlen = fifo8_num_used(&s->cmdfifo); in esp_do_nodma()
833 if (esp_cdb_ready(s)) { in esp_do_nodma()
835 do_cmd(s); in esp_do_nodma()
844 s->rregs[ESP_RINTR] |= INTR_BS; in esp_do_nodma()
845 esp_raise_irq(s); in esp_do_nodma()
853 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_nodma()
854 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
855 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
857 /* Handle when DMA transfer is terminated by non-DMA FIFO write */ in esp_do_nodma()
858 if (esp_cdb_ready(s)) { in esp_do_nodma()
860 do_cmd(s); in esp_do_nodma()
867 len = esp_fifo_pop_buf(s, buf, fifo8_num_used(&s->fifo)); in esp_do_nodma()
868 len = MIN(fifo8_num_free(&s->cmdfifo), len); in esp_do_nodma()
869 fifo8_push_all(&s->cmdfifo, buf, len); in esp_do_nodma()
871 do_cmd(s); in esp_do_nodma()
877 /* Accumulate data in FIFO until non-DMA TI is executed */ in esp_do_nodma()
881 if (!s->current_req) { in esp_do_nodma()
884 if (s->async_len == 0) { in esp_do_nodma()
888 if (fifo8_is_empty(&s->fifo)) { in esp_do_nodma()
889 esp_fifo_push(s, s->async_buf[0]); in esp_do_nodma()
890 s->async_buf++; in esp_do_nodma()
891 s->async_len--; in esp_do_nodma()
892 s->ti_size--; in esp_do_nodma()
895 if (s->async_len == 0) { in esp_do_nodma()
896 scsi_req_continue(s->current_req); in esp_do_nodma()
901 if (s->rregs[ESP_CMD] != CMD_TI) { in esp_do_nodma()
905 s->rregs[ESP_RINTR] |= INTR_BS; in esp_do_nodma()
906 esp_raise_irq(s); in esp_do_nodma()
910 switch (s->rregs[ESP_CMD]) { in esp_do_nodma()
912 esp_fifo_push(s, s->status); in esp_do_nodma()
913 esp_set_phase(s, STAT_MI); in esp_do_nodma()
916 esp_do_nodma(s); in esp_do_nodma()
922 switch (s->rregs[ESP_CMD]) { in esp_do_nodma()
924 esp_fifo_push(s, 0); in esp_do_nodma()
927 s->rregs[ESP_RINTR] |= INTR_FC; in esp_do_nodma()
928 esp_raise_irq(s); in esp_do_nodma()
937 ESPState *s = req->hba_private; in esp_command_complete() local
938 int to_device = (esp_get_phase(s) == STAT_DO); in esp_command_complete()
943 * Non-DMA transfers from the target will leave the last byte in in esp_command_complete()
946 if (s->dma || to_device) { in esp_command_complete()
947 if (s->ti_size != 0) { in esp_command_complete()
952 s->async_len = 0; in esp_command_complete()
953 if (req->status) { in esp_command_complete()
956 s->status = req->status; in esp_command_complete()
959 * Switch to status phase. For non-DMA transfers from the target the last in esp_command_complete()
962 s->ti_size = 0; in esp_command_complete()
964 switch (s->rregs[ESP_CMD]) { in esp_command_complete()
973 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; in esp_command_complete()
974 s->rregs[ESP_RSEQ] = SEQ_CD; in esp_command_complete()
979 s->rregs[ESP_CMD] = 0; in esp_command_complete()
984 esp_set_phase(s, STAT_ST); in esp_command_complete()
985 s->rregs[ESP_RINTR] |= INTR_BS; in esp_command_complete()
986 esp_raise_irq(s); in esp_command_complete()
988 if (s->current_req) { in esp_command_complete()
989 scsi_req_unref(s->current_req); in esp_command_complete()
990 s->current_req = NULL; in esp_command_complete()
991 s->current_dev = NULL; in esp_command_complete()
997 ESPState *s = req->hba_private; in esp_transfer_data() local
998 uint32_t dmalen = esp_get_tc(s); in esp_transfer_data()
1000 trace_esp_transfer_data(dmalen, s->ti_size); in esp_transfer_data()
1001 s->async_len = len; in esp_transfer_data()
1002 s->async_buf = scsi_req_get_buf(req); in esp_transfer_data()
1004 if (!s->data_ready) { in esp_transfer_data()
1005 s->data_ready = true; in esp_transfer_data()
1007 switch (s->rregs[ESP_CMD]) { in esp_transfer_data()
1016 s->rregs[ESP_RINTR] |= INTR_BS | INTR_FC; in esp_transfer_data()
1017 s->rregs[ESP_RSEQ] = SEQ_CD; in esp_transfer_data()
1026 s->rregs[ESP_RINTR] |= INTR_BS; in esp_transfer_data()
1027 s->rregs[ESP_RSEQ] = SEQ_MO; in esp_transfer_data()
1036 s->rregs[ESP_CMD] = 0; in esp_transfer_data()
1037 s->rregs[ESP_RINTR] |= INTR_BS; in esp_transfer_data()
1041 esp_raise_irq(s); in esp_transfer_data()
1046 * command to ensure the DMA/non-DMA status of the command is correct. in esp_transfer_data()
1047 * It is not possible to use s->dma directly in the section below as in esp_transfer_data()
1048 * some OSs send non-DMA NOP commands after a DMA transfer. Hence if the in esp_transfer_data()
1049 * async data transfer is delayed then s->dma is set incorrectly. in esp_transfer_data()
1052 if (s->rregs[ESP_CMD] == (CMD_TI | CMD_DMA)) { in esp_transfer_data()
1054 esp_dma_ti_check(s); in esp_transfer_data()
1056 esp_do_dma(s); in esp_transfer_data()
1057 } else if (s->rregs[ESP_CMD] == CMD_TI) { in esp_transfer_data()
1058 esp_do_nodma(s); in esp_transfer_data()
1062 static void handle_ti(ESPState *s) in handle_ti() argument
1066 if (s->dma && !s->dma_enabled) { in handle_ti()
1067 s->dma_cb = handle_ti; in handle_ti()
1071 if (s->dma) { in handle_ti()
1072 dmalen = esp_get_tc(s); in handle_ti()
1074 esp_do_dma(s); in handle_ti()
1076 trace_esp_handle_ti(s->ti_size); in handle_ti()
1077 esp_do_nodma(s); in handle_ti()
1079 if (esp_get_phase(s) == STAT_DO) { in handle_ti()
1080 esp_nodma_ti_dataout(s); in handle_ti()
1085 void esp_hard_reset(ESPState *s) in esp_hard_reset() argument
1087 memset(s->rregs, 0, ESP_REGS); in esp_hard_reset()
1088 memset(s->wregs, 0, ESP_REGS); in esp_hard_reset()
1089 s->tchi_written = 0; in esp_hard_reset()
1090 s->ti_size = 0; in esp_hard_reset()
1091 s->async_len = 0; in esp_hard_reset()
1092 fifo8_reset(&s->fifo); in esp_hard_reset()
1093 fifo8_reset(&s->cmdfifo); in esp_hard_reset()
1094 s->dma = 0; in esp_hard_reset()
1095 s->dma_cb = NULL; in esp_hard_reset()
1097 s->rregs[ESP_CFG1] = 7; in esp_hard_reset()
1100 static void esp_soft_reset(ESPState *s) in esp_soft_reset() argument
1102 qemu_irq_lower(s->irq); in esp_soft_reset()
1103 qemu_irq_lower(s->drq_irq); in esp_soft_reset()
1104 esp_hard_reset(s); in esp_soft_reset()
1107 static void esp_bus_reset(ESPState *s) in esp_bus_reset() argument
1109 bus_cold_reset(BUS(&s->bus)); in esp_bus_reset()
1112 static void parent_esp_reset(ESPState *s, int irq, int level) in parent_esp_reset() argument
1115 esp_soft_reset(s); in parent_esp_reset()
1119 static void esp_run_cmd(ESPState *s) in esp_run_cmd() argument
1121 uint8_t cmd = s->rregs[ESP_CMD]; in esp_run_cmd()
1124 s->dma = 1; in esp_run_cmd()
1126 if (esp_get_stc(s) == 0) { in esp_run_cmd()
1127 esp_set_tc(s, 0x10000); in esp_run_cmd()
1129 esp_set_tc(s, esp_get_stc(s)); in esp_run_cmd()
1132 s->dma = 0; in esp_run_cmd()
1140 fifo8_reset(&s->fifo); in esp_run_cmd()
1144 esp_soft_reset(s); in esp_run_cmd()
1148 esp_bus_reset(s); in esp_run_cmd()
1149 if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { in esp_run_cmd()
1150 s->rregs[ESP_RINTR] |= INTR_RST; in esp_run_cmd()
1151 esp_raise_irq(s); in esp_run_cmd()
1156 handle_ti(s); in esp_run_cmd()
1160 write_response(s); in esp_run_cmd()
1164 s->rregs[ESP_RINTR] |= INTR_DC; in esp_run_cmd()
1165 s->rregs[ESP_RSEQ] = 0; in esp_run_cmd()
1166 s->rregs[ESP_RFLAGS] = 0; in esp_run_cmd()
1167 esp_raise_irq(s); in esp_run_cmd()
1171 handle_pad(s); in esp_run_cmd()
1181 handle_s_without_atn(s); in esp_run_cmd()
1185 handle_satn(s); in esp_run_cmd()
1189 handle_satn_stop(s); in esp_run_cmd()
1193 s->rregs[ESP_RINTR] = 0; in esp_run_cmd()
1197 s->rregs[ESP_RINTR] = 0; in esp_run_cmd()
1198 esp_raise_irq(s); in esp_run_cmd()
1206 uint64_t esp_reg_read(ESPState *s, uint32_t saddr) in esp_reg_read() argument
1212 s->rregs[ESP_FIFO] = esp_fifo_pop(s); in esp_reg_read()
1213 val = s->rregs[ESP_FIFO]; in esp_reg_read()
1220 val = s->rregs[ESP_RINTR]; in esp_reg_read()
1221 s->rregs[ESP_RINTR] = 0; in esp_reg_read()
1222 esp_lower_irq(s); in esp_reg_read()
1223 s->rregs[ESP_RSTAT] &= STAT_TC | 7; in esp_reg_read()
1231 * s->rregs[ESP_RSEQ] = SEQ_0; in esp_reg_read()
1236 if (!s->tchi_written) { in esp_reg_read()
1237 val = s->chip_id; in esp_reg_read()
1239 val = s->rregs[saddr]; in esp_reg_read()
1244 val = fifo8_num_used(&s->fifo); in esp_reg_read()
1247 val = s->rregs[saddr]; in esp_reg_read()
1255 void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val) in esp_reg_write() argument
1257 trace_esp_mem_writeb(saddr, s->wregs[saddr], val); in esp_reg_write()
1260 s->tchi_written = true; in esp_reg_write()
1264 s->rregs[ESP_RSTAT] &= ~STAT_TC; in esp_reg_write()
1267 if (!fifo8_is_full(&s->fifo)) { in esp_reg_write()
1268 esp_fifo_push(s, val); in esp_reg_write()
1270 esp_do_nodma(s); in esp_reg_write()
1273 s->rregs[saddr] = val; in esp_reg_write()
1274 esp_run_cmd(s); in esp_reg_write()
1281 s->rregs[saddr] = val; in esp_reg_write()
1289 s->wregs[saddr] = val; in esp_reg_write()
1301 ESPState *s = ESP(opaque); in esp_is_before_version_5() local
1303 version_id = MIN(version_id, s->mig_version_id); in esp_is_before_version_5()
1309 ESPState *s = ESP(opaque); in esp_is_version_5() local
1311 version_id = MIN(version_id, s->mig_version_id); in esp_is_version_5()
1317 ESPState *s = ESP(opaque); in esp_is_version_6() local
1319 version_id = MIN(version_id, s->mig_version_id); in esp_is_version_6()
1325 ESPState *s = ESP(opaque); in esp_is_between_version_5_and_6() local
1327 version_id = MIN(version_id, s->mig_version_id); in esp_is_between_version_5_and_6()
1333 ESPState *s = ESP(object_resolve_path_component( in esp_pre_save() local
1336 s->mig_version_id = vmstate_esp.version_id; in esp_pre_save()
1342 ESPState *s = ESP(opaque); in esp_post_load() local
1345 version_id = MIN(version_id, s->mig_version_id); in esp_post_load()
1348 esp_set_tc(s, s->mig_dma_left); in esp_post_load()
1351 len = s->mig_ti_wptr - s->mig_ti_rptr; in esp_post_load()
1353 fifo8_push(&s->fifo, s->mig_ti_buf[i]); in esp_post_load()
1357 for (i = 0; i < s->mig_cmdlen; i++) { in esp_post_load()
1358 fifo8_push(&s->cmdfifo, s->mig_cmdbuf[i]); in esp_post_load()
1362 s->mig_version_id = vmstate_esp.version_id; in esp_post_load()
1408 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_mem_write() local
1411 saddr = addr >> sysbus->it_shift; in sysbus_esp_mem_write()
1412 esp_reg_write(s, saddr, val); in sysbus_esp_mem_write()
1419 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_mem_read() local
1422 saddr = addr >> sysbus->it_shift; in sysbus_esp_mem_read()
1423 return esp_reg_read(s, saddr); in sysbus_esp_mem_read()
1437 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_pdma_write() local
1443 esp_pdma_write(s, val); in sysbus_esp_pdma_write()
1446 esp_pdma_write(s, val >> 8); in sysbus_esp_pdma_write()
1447 esp_pdma_write(s, val); in sysbus_esp_pdma_write()
1450 esp_do_dma(s); in sysbus_esp_pdma_write()
1457 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_pdma_read() local
1464 val = esp_pdma_read(s); in sysbus_esp_pdma_read()
1467 val = esp_pdma_read(s); in sysbus_esp_pdma_read()
1468 val = (val << 8) | esp_pdma_read(s); in sysbus_esp_pdma_read()
1471 esp_do_dma(s); in sysbus_esp_pdma_read()
1477 ESPState *s = container_of(req->bus, ESPState, bus); in esp_load_request() local
1480 s->current_req = req; in esp_load_request()
1481 return s; in esp_load_request()
1508 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_gpio_demux() local
1512 parent_esp_reset(s, irq, level); in sysbus_esp_gpio_demux()
1515 esp_dma_enable(s, irq, level); in sysbus_esp_gpio_demux()
1524 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_realize() local
1526 if (!qdev_realize(DEVICE(s), NULL, errp)) { in sysbus_esp_realize()
1530 sysbus_init_irq(sbd, &s->irq); in sysbus_esp_realize()
1531 sysbus_init_irq(sbd, &s->drq_irq); in sysbus_esp_realize()
1532 assert(sysbus->it_shift != -1); in sysbus_esp_realize()
1534 s->chip_id = TCHI_FAS100A; in sysbus_esp_realize()
1535 memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_ops, in sysbus_esp_realize()
1536 sysbus, "esp-regs", ESP_REGS << sysbus->it_shift); in sysbus_esp_realize()
1537 sysbus_init_mmio(sbd, &sysbus->iomem); in sysbus_esp_realize()
1538 memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_ops, in sysbus_esp_realize()
1539 sysbus, "esp-pdma", 4); in sysbus_esp_realize()
1540 sysbus_init_mmio(sbd, &sysbus->pdma); in sysbus_esp_realize()
1544 scsi_bus_init(&s->bus, sizeof(s->bus), dev, &esp_scsi_info); in sysbus_esp_realize()
1550 ESPState *s = ESP(&sysbus->esp); in sysbus_esp_hard_reset() local
1552 esp_hard_reset(s); in sysbus_esp_hard_reset()
1559 object_initialize_child(obj, "esp", &sysbus->esp, TYPE_ESP); in sysbus_esp_init()
1578 dc->realize = sysbus_esp_realize; in sysbus_esp_class_init()
1580 dc->vmsd = &vmstate_sysbus_esp_scsi; in sysbus_esp_class_init()
1581 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); in sysbus_esp_class_init()
1586 ESPState *s = ESP(obj); in esp_finalize() local
1588 fifo8_destroy(&s->fifo); in esp_finalize()
1589 fifo8_destroy(&s->cmdfifo); in esp_finalize()
1594 ESPState *s = ESP(obj); in esp_init() local
1596 fifo8_create(&s->fifo, ESP_FIFO_SZ); in esp_init()
1597 fifo8_create(&s->cmdfifo, ESP_CMDFIFO_SZ); in esp_init()
1604 /* internal device for sysbusesp/pciespscsi, not user-creatable */ in esp_class_init()
1605 dc->user_creatable = false; in esp_class_init()
1606 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); in esp_class_init()