--- qemu/hw/esp.c 2018/04/24 19:01:38 1.1.1.12 +++ qemu/hw/esp.c 2018/04/24 19:29:33 1.1.1.13 @@ -25,9 +25,7 @@ #include "sysbus.h" #include "scsi.h" #include "esp.h" - -/* debug ESP card */ -//#define DEBUG_ESP +#include "trace.h" /* * On Sparc32, this is the ESP (NCR53C90) part of chip STP2000 (Master I/O), @@ -37,13 +35,6 @@ * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9X.txt */ -#ifdef DEBUG_ESP -#define DPRINTF(fmt, ...) \ - do { printf("ESP: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif - #define ESP_ERROR(fmt, ...) \ do { printf("ESP ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } while (0) @@ -54,15 +45,15 @@ typedef struct ESPState ESPState; struct ESPState { SysBusDevice busdev; - uint32_t it_shift; - qemu_irq irq; uint8_t rregs[ESP_REGS]; uint8_t wregs[ESP_REGS]; + qemu_irq irq; + uint32_t it_shift; int32_t ti_size; uint32_t ti_rptr, ti_wptr; - uint8_t ti_buf[TI_BUFSZ]; uint32_t status; uint32_t dma; + uint8_t ti_buf[TI_BUFSZ]; SCSIBus bus; SCSIDevice *current_dev; SCSIRequest *current_req; @@ -75,13 +66,14 @@ struct ESPState { /* The size of the current DMA transfer. Zero if no transfer is in progress. */ uint32_t dma_counter; - uint8_t *async_buf; + int dma_enabled; + uint32_t async_len; + uint8_t *async_buf; ESPDMAMemoryReadWriteFunc dma_memory_read; ESPDMAMemoryReadWriteFunc dma_memory_write; void *dma_opaque; - int dma_enabled; void (*dma_cb)(ESPState *s); }; @@ -157,7 +149,7 @@ static void esp_raise_irq(ESPState *s) if (!(s->rregs[ESP_RSTAT] & STAT_INT)) { s->rregs[ESP_RSTAT] |= STAT_INT; qemu_irq_raise(s->irq); - DPRINTF("Raise IRQ\n"); + trace_esp_raise_irq(); } } @@ -166,7 +158,7 @@ static void esp_lower_irq(ESPState *s) if (s->rregs[ESP_RSTAT] & STAT_INT) { s->rregs[ESP_RSTAT] &= ~STAT_INT; qemu_irq_lower(s->irq); - DPRINTF("Lower IRQ\n"); + trace_esp_lower_irq(); } } @@ -177,13 +169,13 @@ static void esp_dma_enable(void *opaque, if (level) { s->dma_enabled = 1; - DPRINTF("Raise enable\n"); + trace_esp_dma_enable(); if (s->dma_cb) { s->dma_cb(s); s->dma_cb = NULL; } } else { - DPRINTF("Lower enable\n"); + trace_esp_dma_disable(); s->dma_enabled = 0; } } @@ -213,7 +205,7 @@ static uint32_t get_cmd(ESPState *s, uin memcpy(buf, s->ti_buf, dmalen); buf[0] = buf[2] >> 5; } - DPRINTF("get_cmd: len %d target %d\n", dmalen, target); + trace_esp_get_cmd(dmalen, target); s->ti_size = 0; s->ti_rptr = 0; @@ -225,7 +217,8 @@ static uint32_t get_cmd(ESPState *s, uin s->async_len = 0; } - if (target >= ESP_MAX_DEVS || !s->bus.devs[target]) { + s->current_dev = scsi_device_find(&s->bus, 0, target, 0); + if (!s->current_dev) { // No such drive s->rregs[ESP_RSTAT] = 0; s->rregs[ESP_RINTR] = INTR_DC; @@ -233,7 +226,6 @@ static uint32_t get_cmd(ESPState *s, uin esp_raise_irq(s); return 0; } - s->current_dev = s->bus.devs[target]; return dmalen; } @@ -241,11 +233,13 @@ static void do_busid_cmd(ESPState *s, ui { int32_t datalen; int lun; + SCSIDevice *current_lun; - DPRINTF("do_busid_cmd: busid 0x%x\n", busid); + trace_esp_do_busid_cmd(busid); lun = busid & 7; - s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL); - datalen = scsi_req_enqueue(s->current_req, buf); + current_lun = scsi_device_find(&s->bus, 0, s->current_dev->id, lun); + s->current_req = scsi_req_new(current_lun, 0, lun, buf, NULL); + datalen = scsi_req_enqueue(s->current_req); s->ti_size = datalen; if (datalen != 0) { s->rregs[ESP_RSTAT] = STAT_TC; @@ -307,7 +301,7 @@ static void handle_satn_stop(ESPState *s } s->cmdlen = get_cmd(s, s->cmdbuf); if (s->cmdlen) { - DPRINTF("Set ATN & Stop: cmdlen %d\n", s->cmdlen); + trace_esp_handle_satn_stop(s->cmdlen); s->do_cmd = 1; s->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; @@ -318,7 +312,7 @@ static void handle_satn_stop(ESPState *s static void write_response(ESPState *s) { - DPRINTF("Transfer status (status=%d)\n", s->status); + trace_esp_write_response(s->status); s->ti_buf[0] = s->status; s->ti_buf[1] = 0; if (s->dma) { @@ -354,7 +348,7 @@ static void esp_do_dma(ESPState *s) to_device = (s->ti_size < 0); len = s->dma_left; if (s->do_cmd) { - DPRINTF("command len %d + %d\n", s->cmdlen, len); + trace_esp_do_dma(s->cmdlen, len); s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); s->ti_size = 0; s->cmdlen = 0; @@ -399,15 +393,15 @@ static void esp_command_complete(SCSIReq { ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); - DPRINTF("SCSI Command complete\n"); + trace_esp_command_complete(); if (s->ti_size != 0) { - DPRINTF("SCSI command completed unexpectedly\n"); + trace_esp_command_complete_unexpected(); } s->ti_size = 0; s->dma_left = 0; s->async_len = 0; if (status) { - DPRINTF("Command failed\n"); + trace_esp_command_complete_fail(); } s->status = status; s->rregs[ESP_RSTAT] = STAT_ST; @@ -423,7 +417,7 @@ static void esp_transfer_data(SCSIReques { ESPState *s = DO_UPCAST(ESPState, busdev.qdev, req->bus->qbus.parent); - DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); + trace_esp_transfer_data(s->dma_left, s->ti_size); s->async_len = len; s->async_buf = scsi_req_get_buf(req); if (s->dma_left) { @@ -451,13 +445,13 @@ static void handle_ti(ESPState *s) minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size; else minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size; - DPRINTF("Transfer Information len %d\n", minlen); + trace_esp_handle_ti(minlen); if (s->dma) { s->dma_left = minlen; s->rregs[ESP_RSTAT] &= ~STAT_TC; esp_do_dma(s); } else if (s->do_cmd) { - DPRINTF("command len %d\n", s->cmdlen); + trace_esp_handle_ti_cmd(s->cmdlen); s->ti_size = 0; s->cmdlen = 0; s->do_cmd = 0; @@ -516,7 +510,7 @@ static uint32_t esp_mem_readb(void *opaq uint32_t saddr, old_val; saddr = addr >> s->it_shift; - DPRINTF("read reg[%d]: 0x%2.2x\n", saddr, s->rregs[saddr]); + trace_esp_mem_readb(saddr, s->rregs[saddr]); switch (saddr) { case ESP_FIFO: if (s->ti_size > 0) { @@ -557,8 +551,7 @@ static void esp_mem_writeb(void *opaque, uint32_t saddr; saddr = addr >> s->it_shift; - DPRINTF("write reg[%d]: 0x%2.2x -> 0x%2.2x\n", saddr, s->wregs[saddr], - val); + trace_esp_mem_writeb(saddr, s->wregs[saddr], val); switch (saddr) { case ESP_TCLO: case ESP_TCMID: @@ -586,21 +579,21 @@ static void esp_mem_writeb(void *opaque, } switch(val & CMD_CMD) { case CMD_NOP: - DPRINTF("NOP (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_nop(val); break; case CMD_FLUSH: - DPRINTF("Flush FIFO (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_flush(val); //s->ti_size = 0; s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSEQ] = 0; s->rregs[ESP_RFLAGS] = 0; break; case CMD_RESET: - DPRINTF("Chip reset (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_reset(val); esp_soft_reset(&s->busdev.qdev); break; case CMD_BUSRESET: - DPRINTF("Bus reset (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_bus_reset(val); s->rregs[ESP_RINTR] = INTR_RST; if (!(s->wregs[ESP_CFG1] & CFG1_RESREPT)) { esp_raise_irq(s); @@ -610,41 +603,41 @@ static void esp_mem_writeb(void *opaque, handle_ti(s); break; case CMD_ICCS: - DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_iccs(val); write_response(s); s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSTAT] |= STAT_MI; break; case CMD_MSGACC: - DPRINTF("Message Accepted (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_msgacc(val); s->rregs[ESP_RINTR] = INTR_DC; s->rregs[ESP_RSEQ] = 0; s->rregs[ESP_RFLAGS] = 0; esp_raise_irq(s); break; case CMD_PAD: - DPRINTF("Transfer padding (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_pad(val); s->rregs[ESP_RSTAT] = STAT_TC; s->rregs[ESP_RINTR] = INTR_FC; s->rregs[ESP_RSEQ] = 0; break; case CMD_SATN: - DPRINTF("Set ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_satn(val); break; case CMD_SEL: - DPRINTF("Select without ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_sel(val); handle_s_without_atn(s); break; case CMD_SELATN: - DPRINTF("Select with ATN (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_selatn(val); handle_satn(s); break; case CMD_SELATNS: - DPRINTF("Select with ATN & stop (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_selatns(val); handle_satn_stop(s); break; case CMD_ENSEL: - DPRINTF("Enable selection (%2.2x)\n", val); + trace_esp_mem_writeb_cmd_ensel(val); s->rregs[ESP_RINTR] = 0; break; default: @@ -729,7 +722,11 @@ void esp_init(target_phys_addr_t espaddr *dma_enable = qdev_get_gpio_in(dev, 1); } -static const struct SCSIBusOps esp_scsi_ops = { +static const struct SCSIBusInfo esp_scsi_info = { + .tcq = false, + .max_target = ESP_MAX_DEVS, + .max_lun = 7, + .transfer_data = esp_transfer_data, .complete = esp_command_complete, .cancel = esp_request_cancelled @@ -749,7 +746,7 @@ static int esp_init1(SysBusDevice *dev) qdev_init_gpio_in(&dev->qdev, esp_gpio_demux, 2); - scsi_bus_new(&s->bus, &dev->qdev, 0, ESP_MAX_DEVS, &esp_scsi_ops); + scsi_bus_new(&s->bus, &dev->qdev, &esp_scsi_info); return scsi_bus_legacy_handle_cmdline(&s->bus); }