From nobody Tue Nov 4 15:28:36 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530142865453939.2520988144001; Wed, 27 Jun 2018 16:41:05 -0700 (PDT) Received: from localhost ([::1]:33675 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYK3c-0006yk-MF for importer@patchew.org; Wed, 27 Jun 2018 19:41:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48643) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fYJtZ-00086g-6h for qemu-devel@nongnu.org; Wed, 27 Jun 2018 19:30:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fYJtW-0003nC-1B for qemu-devel@nongnu.org; Wed, 27 Jun 2018 19:30:41 -0400 Received: from mout.kundenserver.de ([212.227.126.130]:50040) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fYJtP-0003kK-91; Wed, 27 Jun 2018 19:30:31 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue001 [212.227.15.167]) with ESMTPSA (Nemesis) id 0Ls3iR-1gITB424f1-013ys9; Thu, 28 Jun 2018 01:30:06 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Thu, 28 Jun 2018 01:29:47 +0200 Message-Id: <20180627232951.14725-7-laurent@vivier.eu> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180627232951.14725-1-laurent@vivier.eu> References: <20180627232951.14725-1-laurent@vivier.eu> X-Provags-ID: V03:K1:Rx5gnj0f0eklEE9LGJePg5TmwiqyWkA3cAbrXYhvmCSa6/22WdP bH+nnGc2uCvsH5KQoUPxK4FqHSX0Tz1uxFw0pXvT49p+k+Jr6ENwdgtnHTU3MeYWqTQ7JSD +0nUNOC/VU8Tc7Iapw46eozFT8xueLBamfKCq5SxLaGl4pk//y5km3nztbgfoDAjTf4LWyt 18rkHsqxD+5TEu1yldu/Q== X-UI-Out-Filterresults: notjunk:1;V01:K0:tiq+qG+0HiQ=:RP7cv7ZFQ5NcFNiDhWfTDl 8OoP0QxosMeYcTpiA/a45nSxyszJjgfJnwKI7UK/JqTndIfoF2Hj+apzgoWH2Zu+WbTw63hUT zp+BhJq1vt291hrk7u+dwheSZjeStU7lFCYQZs4llJKzY0o5j72F3Gh6DgJKiKLgTpP4iuNEL jBTDpVDXHBG+HSBJCShUQJTLBMlkEMyqujiKWoxtjxwffw4xrMo7U2MLpV6HkdTgm5SLoFdqU t+Z5vVdrBLfruLdCQaaoIVmn79Vj9Zm2O/oERhSwLRfXiyKpUgr4rna0EMRNlZFhaFWyKnDth rJHmiw0eIrEdwLkk70Ptt/EKbaw11fg1b/FNKN5LhHTodBBn2xexrT+BZP+zO6MJR0SVG4JTn k2+1+hqrsBqrb4aBCw3teKBWsWeGWxEfQoyONITXvLFR5q0NK/7w144VAie7RRNEsCGz7fOKm IPAucTFNoyyU32+YWucy8J9mc67DueHjeNyh7Xq/03l3AA7sChFfIIaD/wVwV3dxVLlgpfbPn QGb3tWGv2SSc5l6JZ5Y1tWoFV3tM4OeSyUdLoz3siqm1Ss+Rmlf4OhsCltGySEdkWlAqhJm1k 2Dl4m4l0Gx4FPmxNvTNdksby+wN/U1muaFjwDkHPIBrihtOxph3HvdX2TmM7W1W+0D/IIKZG8 bQQ9bp4mV/p+FeJCAhYZRHinLqtsRZNSD6RU8Q/eE/FMT9YSftR1afsh3ajU3d3NdiBM= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.130 Subject: [Qemu-devel] [RFC v3 06/10] ESP: add pseudo-DMA as used by Macintosh X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Jason Wang , Mark Cave-Ayland , "Dr. David Alan Gilbert" , Laurent Vivier , =?UTF-8?q?Herv=C3=A9=20Poussineau?= , Gerd Hoffmann , Paolo Bonzini , Max Reitz , Yongbok Kim , =?UTF-8?q?Andreas=20F=C3=A4rber?= , Aurelien Jarno Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Co-developed-by: Mark Cave-Ayland Signed-off-by: Mark Cave-Ayland Signed-off-by: Laurent Vivier --- hw/mips/mips_jazz.c | 2 +- hw/scsi/esp.c | 297 ++++++++++++++++++++++++++++++++++++++++++++--= ---- include/hw/scsi/esp.h | 11 +- 3 files changed, 276 insertions(+), 34 deletions(-) diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 90cb306f53..87118f2d03 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -282,7 +282,7 @@ static void mips_jazz_init(MachineState *machine, =20 /* SCSI adapter */ esp =3D esp_init(0x80002000, 0, rc4030_dma_read, rc4030_dma_write, dma= s[0], - qdev_get_gpio_in(rc4030, 5), &esp_reset, &dma_enable); + qdev_get_gpio_in(rc4030, 5), NULL, &esp_reset, &dma_ena= ble); scsi_bus_legacy_handle_cmdline(&esp->bus); =20 /* Floppy */ diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 9ed9727744..8270abe298 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -37,6 +37,8 @@ * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR53C9= X.txt */ =20 +/* on Macintosh Quadra it is a NCR53C96 */ + static void esp_raise_irq(ESPState *s) { if (!(s->rregs[ESP_RSTAT] & STAT_INT)) { @@ -55,6 +57,16 @@ static void esp_lower_irq(ESPState *s) } } =20 +static void esp_raise_drq(ESPState *s) +{ + qemu_irq_raise(s->irq_data); +} + +static void esp_lower_drq(ESPState *s) +{ + qemu_irq_lower(s->irq_data); +} + void esp_dma_enable(ESPState *s, int irq, int level) { if (level) { @@ -81,29 +93,11 @@ void esp_request_cancelled(SCSIRequest *req) } } =20 -static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen) +static int get_cmd_cb(ESPState *s) { - uint32_t dmalen; int target; =20 target =3D s->wregs[ESP_WBUSID] & BUSID_DID; - if (s->dma) { - dmalen =3D s->rregs[ESP_TCLO]; - dmalen |=3D s->rregs[ESP_TCMID] << 8; - dmalen |=3D s->rregs[ESP_TCHI] << 16; - if (dmalen > buflen) { - return 0; - } - s->dma_memory_read(s->dma_opaque, buf, dmalen); - } else { - dmalen =3D s->ti_size; - if (dmalen > TI_BUFSZ) { - return 0; - } - memcpy(buf, s->ti_buf, dmalen); - buf[0] =3D buf[2] >> 5; - } - trace_esp_get_cmd(dmalen, target); =20 s->ti_size =3D 0; s->ti_rptr =3D 0; @@ -122,8 +116,48 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uin= t8_t buflen) s->rregs[ESP_RINTR] =3D INTR_DC; s->rregs[ESP_RSEQ] =3D SEQ_0; esp_raise_irq(s); + return -1; + } + return 0; +} + +static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen) +{ + int target; + uint32_t dmalen; + + target =3D s->wregs[ESP_WBUSID] & BUSID_DID; + if (s->dma) { + dmalen =3D s->rregs[ESP_TCLO]; + dmalen |=3D s->rregs[ESP_TCMID] << 8; + dmalen |=3D s->rregs[ESP_TCHI] << 16; + if (dmalen > buflen) { + return 0; + } + if (s->dma_memory_read) { + s->dma_memory_read(s->dma_opaque, buf, dmalen); + } else { + memcpy(s->pdma_buf, buf, dmalen); + s->pdma_len =3D dmalen; + s->pdma_start =3D s->pdma_buf; + s->pdma_cur =3D s->pdma_buf; + esp_raise_drq(s); + return 0; + } + } else { + dmalen =3D s->ti_size; + if (dmalen > TI_BUFSZ) { + return 0; + } + memcpy(buf, s->ti_buf, dmalen); + buf[0] =3D buf[2] >> 5; + } + trace_esp_get_cmd(dmalen, target); + + if (get_cmd_cb(s) < 0) { return 0; } + return dmalen; } =20 @@ -162,6 +196,15 @@ static void do_cmd(ESPState *s, uint8_t *buf) do_busid_cmd(s, &buf[1], busid); } =20 +static void satn_pdma_cb(ESPState *s) +{ + if (get_cmd_cb(s) < 0) { + return; + } + if (s->pdma_cur !=3D s->pdma_start) + do_cmd(s, s->pdma_start); +} + static void handle_satn(ESPState *s) { uint8_t buf[32]; @@ -171,11 +214,21 @@ static void handle_satn(ESPState *s) s->dma_cb =3D handle_satn; return; } + s->pdma_cb =3D satn_pdma_cb; len =3D get_cmd(s, buf, sizeof(buf)); if (len) do_cmd(s, buf); } =20 +static void s_without_satn_pdma_cb(ESPState *s) +{ + if (get_cmd_cb(s) < 0) { + return; + } + if (s->pdma_cur !=3D s->pdma_start) + do_busid_cmd(s, s->pdma_start, 0); +} + static void handle_s_without_atn(ESPState *s) { uint8_t buf[32]; @@ -185,18 +238,36 @@ static void handle_s_without_atn(ESPState *s) s->dma_cb =3D handle_s_without_atn; return; } + s->pdma_cb =3D s_without_satn_pdma_cb; len =3D get_cmd(s, buf, sizeof(buf)); if (len) { do_busid_cmd(s, buf, 0); } } =20 +static void satn_stop_pdma_cb(ESPState *s) +{ + if (get_cmd_cb(s) < 0) { + return; + } + s->cmdlen =3D s->pdma_cur - s->pdma_start; + if (s->cmdlen) { + trace_esp_handle_satn_stop(s->cmdlen); + s->do_cmd =3D 1; + s->rregs[ESP_RSTAT] =3D STAT_TC | STAT_CD; + s->rregs[ESP_RINTR] =3D INTR_BS | INTR_FC; + s->rregs[ESP_RSEQ] =3D SEQ_CD; + esp_raise_irq(s); + } +} + static void handle_satn_stop(ESPState *s) { if (s->dma && !s->dma_enabled) { s->dma_cb =3D handle_satn_stop; return; } + s->pdma_cb =3D satn_stop_pdma_cb;; s->cmdlen =3D get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf)); if (s->cmdlen) { trace_esp_handle_satn_stop(s->cmdlen); @@ -208,16 +279,33 @@ static void handle_satn_stop(ESPState *s) } } =20 +static void write_response_pdma_cb(ESPState *s) +{ + s->rregs[ESP_RSTAT] =3D STAT_TC | STAT_ST; + s->rregs[ESP_RINTR] =3D INTR_BS | INTR_FC; + s->rregs[ESP_RSEQ] =3D SEQ_CD; + esp_raise_irq(s); +} + static void write_response(ESPState *s) { trace_esp_write_response(s->status); s->ti_buf[0] =3D s->status; s->ti_buf[1] =3D 0; if (s->dma) { - s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); - s->rregs[ESP_RSTAT] =3D STAT_TC | STAT_ST; - s->rregs[ESP_RINTR] =3D INTR_BS | INTR_FC; - s->rregs[ESP_RSEQ] =3D SEQ_CD; + if (s->dma_memory_write) { + s->dma_memory_write(s->dma_opaque, s->ti_buf, 2); + s->rregs[ESP_RSTAT] =3D STAT_TC | STAT_ST; + s->rregs[ESP_RINTR] =3D INTR_BS | INTR_FC; + s->rregs[ESP_RSEQ] =3D SEQ_CD; + } else { + s->pdma_len =3D 2; + s->pdma_start =3D s->ti_buf; + s->pdma_cur =3D s->ti_buf; + s->pdma_cb =3D write_response_pdma_cb; + esp_raise_drq(s); + return; + } } else { s->ti_size =3D 2; s->ti_rptr =3D 0; @@ -239,6 +327,39 @@ static void esp_dma_done(ESPState *s) esp_raise_irq(s); } =20 +static void do_dma_pdma_cb(ESPState *s) +{ + int to_device =3D (s->ti_size < 0); + int len =3D s->pdma_cur - s->pdma_start; + if (s->do_cmd) { + s->ti_size =3D 0; + s->cmdlen =3D 0; + s->do_cmd =3D 0; + do_cmd(s, s->cmdbuf); + return; + } + s->dma_left -=3D len; + s->async_buf +=3D len; + s->async_len -=3D len; + if (to_device) { + s->ti_size +=3D len; + } else { + s->ti_size -=3D len; + } + if (s->async_len =3D=3D 0) { + scsi_req_continue(s->current_req); + /* If there is still data to be read from the device then + complete the DMA operation immediately. Otherwise defer + until the scsi layer has completed. */ + if (to_device || s->dma_left !=3D 0 || s->ti_size =3D=3D 0) { + return; + } + } + + /* Partially filled a scsi buffer. Complete immediately. */ + esp_dma_done(s); +} + static void esp_do_dma(ESPState *s) { uint32_t len; @@ -249,10 +370,26 @@ static void esp_do_dma(ESPState *s) trace_esp_do_dma(s->cmdlen, len); assert (s->cmdlen <=3D sizeof(s->cmdbuf) && len <=3D sizeof(s->cmdbuf) - s->cmdlen); - s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); + if (s->dma_memory_read) { + s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); + } else { + s->pdma_len =3D len; + s->pdma_start =3D &s->cmdbuf[s->cmdlen]; + s->pdma_cur =3D &s->cmdbuf[s->cmdlen]; + s->pdma_cb =3D do_dma_pdma_cb; + esp_raise_drq(s); + return; + } + s->ti_size =3D 0; + s->cmdlen =3D 0; + s->do_cmd =3D 0; + do_cmd(s, s->cmdbuf); return; } if (s->async_len =3D=3D 0) { + if (s->dma_left =3D=3D 0) { + esp_dma_done(s); + } /* Defer until data is available. */ return; } @@ -261,9 +398,27 @@ static void esp_do_dma(ESPState *s) } to_device =3D (s->ti_size < 0); if (to_device) { - s->dma_memory_read(s->dma_opaque, s->async_buf, len); + if (s->dma_memory_read) { + s->dma_memory_read(s->dma_opaque, s->async_buf, len); + } else { + s->pdma_len =3D len; + s->pdma_start =3D s->async_buf; + s->pdma_cur =3D s->async_buf; + s->pdma_cb =3D do_dma_pdma_cb; + esp_raise_drq(s); + return; + } } else { - s->dma_memory_write(s->dma_opaque, s->async_buf, len); + if (s->dma_memory_write) { + s->dma_memory_write(s->dma_opaque, s->async_buf, len); + } else { + s->pdma_len =3D len; + s->pdma_start =3D s->async_buf; + s->pdma_cur =3D s->async_buf; + s->pdma_cb =3D do_dma_pdma_cb; + esp_raise_drq(s); + return; + } } s->dma_left -=3D len; s->async_buf +=3D len; @@ -356,8 +511,7 @@ static void handle_ti(ESPState *s) s->dma_left =3D minlen; s->rregs[ESP_RSTAT] &=3D ~STAT_TC; esp_do_dma(s); - } - if (s->do_cmd) { + } else if (s->do_cmd) { trace_esp_handle_ti_cmd(s->cmdlen); s->ti_size =3D 0; s->cmdlen =3D 0; @@ -384,6 +538,7 @@ void esp_hard_reset(ESPState *s) static void esp_soft_reset(ESPState *s) { qemu_irq_lower(s->irq); + qemu_irq_lower(s->irq_data); esp_hard_reset(s); } =20 @@ -409,6 +564,7 @@ uint64_t esp_reg_read(ESPState *s, uint32_t saddr) s->ti_size--; s->rregs[ESP_FIFO] =3D s->ti_buf[s->ti_rptr++]; } + esp_raise_irq(s); if (s->ti_rptr =3D=3D s->ti_wptr) { s->ti_rptr =3D 0; s->ti_wptr =3D 0; @@ -619,11 +775,85 @@ static const MemoryRegionOps sysbus_esp_mem_ops =3D { .valid.accepts =3D esp_mem_accepts, }; =20 +static void sysbus_esp_pdma_write(void *opaque, hwaddr addr, + uint64_t val, unsigned int size) +{ + SysBusESPState *sysbus =3D opaque; + ESPState *s =3D &sysbus->esp; + uint32_t dmalen; + + dmalen =3D s->rregs[ESP_TCLO]; + dmalen |=3D s->rregs[ESP_TCMID] << 8; + dmalen |=3D s->rregs[ESP_TCHI] << 16; + if (dmalen =3D=3D 0 || s->pdma_len =3D=3D 0) { + return; + } + switch (size) { + case 1: + *s->pdma_cur++ =3D val; + s->pdma_len--; + dmalen--; + break; + case 2: + *s->pdma_cur++ =3D val >> 8; + *s->pdma_cur++ =3D val; + s->pdma_len -=3D 2; + dmalen -=3D 2; + break; + } + s->rregs[ESP_TCLO] =3D dmalen & 0xff; + s->rregs[ESP_TCMID] =3D dmalen >> 8; + s->rregs[ESP_TCHI] =3D dmalen >> 16; + if (s->pdma_len =3D=3D 0 && s->pdma_cb) { + esp_lower_drq(s); + s->pdma_cb(s); + s->pdma_cb =3D NULL; + } +} + +static uint64_t sysbus_esp_pdma_read(void *opaque, hwaddr addr, + unsigned int size) +{ + SysBusESPState *sysbus =3D opaque; + ESPState *s =3D &sysbus->esp; + uint64_t val =3D 0; + + if (s->pdma_len =3D=3D 0) { + return 0; + } + switch (size) { + case 1: + val =3D *s->pdma_cur++; + s->pdma_len--; + break; + case 2: + val =3D *s->pdma_cur++; + val =3D (val << 8) | *s->pdma_cur++; + s->pdma_len -=3D 2; + break; + } + + if (s->pdma_len =3D=3D 0 && s->pdma_cb) { + esp_lower_drq(s); + s->pdma_cb(s); + s->pdma_cb =3D NULL; + } + return val; +} + +static const MemoryRegionOps sysbus_esp_pdma_ops =3D { + .read =3D sysbus_esp_pdma_read, + .write =3D sysbus_esp_pdma_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .valid.min_access_size =3D 1, + .valid.max_access_size =3D 2, +}; + ESPState *esp_init(hwaddr espaddr, int it_shift, ESPDMAMemoryReadWriteFunc dma_memory_read, ESPDMAMemoryReadWriteFunc dma_memory_write, - void *dma_opaque, qemu_irq irq, qemu_irq *reset, - qemu_irq *dma_enable) + void *dma_opaque, qemu_irq irq, qemu_irq irq_data, + qemu_irq *reset, qemu_irq *dma_enable) { DeviceState *dev; SysBusDevice *s; @@ -642,6 +872,7 @@ ESPState *esp_init(hwaddr espaddr, int it_shift, qdev_init_nofail(dev); s =3D SYS_BUS_DEVICE(dev); sysbus_connect_irq(s, 0, irq); + sysbus_connect_irq(s, 1, irq_data); sysbus_mmio_map(s, 0, espaddr); *reset =3D qdev_get_gpio_in(dev, 0); *dma_enable =3D qdev_get_gpio_in(dev, 1); @@ -681,12 +912,16 @@ static void sysbus_esp_realize(DeviceState *dev, Erro= r **errp) ESPState *s =3D &sysbus->esp; =20 sysbus_init_irq(sbd, &s->irq); + sysbus_init_irq(sbd, &s->irq_data); assert(sysbus->it_shift !=3D -1); =20 s->chip_id =3D TCHI_FAS100A; memory_region_init_io(&sysbus->iomem, OBJECT(sysbus), &sysbus_esp_mem_= ops, - sysbus, "esp", ESP_REGS << sysbus->it_shift); + sysbus, "esp-regs", ESP_REGS << sysbus->it_shift= ); sysbus_init_mmio(sbd, &sysbus->iomem); + memory_region_init_io(&sysbus->pdma, OBJECT(sysbus), &sysbus_esp_pdma_= ops, + sysbus, "esp-pdma", 2); + sysbus_init_mmio(sbd, &sysbus->pdma); =20 qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2); =20 diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h index 93fdaced67..43312e4bc8 100644 --- a/include/hw/scsi/esp.h +++ b/include/hw/scsi/esp.h @@ -18,6 +18,7 @@ struct ESPState { uint8_t rregs[ESP_REGS]; uint8_t wregs[ESP_REGS]; qemu_irq irq; + qemu_irq irq_data; uint8_t chip_id; bool tchi_written; int32_t ti_size; @@ -46,6 +47,11 @@ struct ESPState { ESPDMAMemoryReadWriteFunc dma_memory_write; void *dma_opaque; void (*dma_cb)(ESPState *s); + uint8_t pdma_buf[32]; + uint32_t pdma_len; + uint8_t *pdma_start; + uint8_t *pdma_cur; + void (*pdma_cb)(ESPState *s); }; =20 #define TYPE_ESP "esp" @@ -57,6 +63,7 @@ typedef struct { /*< public >*/ =20 MemoryRegion iomem; + MemoryRegion pdma; uint32_t it_shift; ESPState esp; } SysBusESPState; @@ -134,8 +141,8 @@ typedef struct { ESPState *esp_init(hwaddr espaddr, int it_shift, ESPDMAMemoryReadWriteFunc dma_memory_read, ESPDMAMemoryReadWriteFunc dma_memory_write, - void *dma_opaque, qemu_irq irq, qemu_irq *reset, - qemu_irq *dma_enable); + void *dma_opaque, qemu_irq irq, qemu_irq irq_data, + qemu_irq *reset, qemu_irq *dma_enable); void esp_dma_enable(ESPState *s, int irq, int level); void esp_request_cancelled(SCSIRequest *req); void esp_command_complete(SCSIRequest *req, uint32_t status, size_t resid); --=20 2.14.4