From: Helge Deller <[email protected]>

Signed-off-by: Keith Monahan <[email protected]>
Signed-off-by: Helge Deller <[email protected]>
---
 hw/scsi/lasi_ncr710.c | 119 +++++++++++++++++-------------------------
 hw/scsi/lasi_ncr710.h |  30 ++---------
 hw/scsi/meson.build   |   2 +-
 3 files changed, 52 insertions(+), 99 deletions(-)

diff --git a/hw/scsi/lasi_ncr710.c b/hw/scsi/lasi_ncr710.c
index 4fde2265b5..42b0dcb626 100644
--- a/hw/scsi/lasi_ncr710.c
+++ b/hw/scsi/lasi_ncr710.c
@@ -1,19 +1,18 @@
 /*
- * LASI Wrapper for NCR710 SCSI Controller
+ * LASI wrapper for the NCR 53C710 SCSI controller
  *
  * Copyright (c) 2025 Soumyajyotii Ssarkar <[email protected]>
- * This driver was developed during the Google Summer of Code 2025 program.
- * Mentored by Helge Deller <[email protected]>
+ * Developed during Google Summer of Code 2025, mentored by
+ * Helge Deller <[email protected]>.
  *
- * NCR710 SCSI Controller implementation
- * Based on the NCR53C710 Technical Manual Version 3.2, December 2000
+ * LASI module glue around the 53C710 core in ncr53c710.c: it embeds one
+ * NCR710State by value and maps it onto the HP 715 (-M 715) LASI bus.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "qemu/osdep.h"
 #include "hw/scsi/lasi_ncr710.h"
-#include "hw/scsi/ncr53c710.h"
 #include "hw/core/sysbus.h"
 #include "qemu/timer.h"
 #include "qemu/log.h"
@@ -24,7 +23,6 @@
 #include "system/dma.h"
 
 #define LASI_710_SVERSION    0x00082
-#define SCNR                 0xBEEFBABE
 #define LASI_710_HVERSION    0x3D
 #define HPHW_FIO             5        /* Fixed I/O module */
 
@@ -34,8 +32,6 @@ static uint64_t lasi_ncr710_reg_read(void *opaque, hwaddr 
addr,
     LasiNCR710State *s = LASI_NCR710(opaque);
     uint64_t val = 0;
 
-    trace_lasi_ncr710_reg_read(addr, 0, size);
-
     if (addr == 0x00) {  /* Device ID */
         val = (HPHW_FIO << 24) | LASI_710_SVERSION;
         trace_lasi_ncr710_reg_read_id(HPHW_FIO, LASI_710_SVERSION, val);
@@ -51,22 +47,22 @@ static uint64_t lasi_ncr710_reg_read(void *opaque, hwaddr 
addr,
     if (addr >= 0x100) {
         hwaddr ncr_addr = addr - 0x100;
         if (size == 1) {
+            /*
+             * Single byte access: flip the byte lane (PA-RISC big endian
+             * access -> the chip's little endian register order).
+             */
             ncr_addr ^= 3;
-            NCR710_DPRINTF("Reading value to LASI WRAPPER == 0x%lx%s, "
-                           "val=0x%lx, size=%u\n",
-                           addr - 0x100, size == 1 ? " (XORed)" : "",
-                           val, size);
             val = ncr710_reg_read(&s->ncr710, ncr_addr, size);
         } else {
+            /*
+             * Multibyte access: gather little endian, no lane flip, so
+             * the 24/32 bit registers assemble correctly.
+             */
             val = 0;
             for (unsigned i = 0; i < size; i++) {
                 uint8_t byte_val = ncr710_reg_read(&s->ncr710, ncr_addr + i, 
1);
                 val |= ((uint64_t)byte_val) << (i * 8);
-                NCR710_DPRINTF("  Read byte %u from NCR addr 0x%lx: "
-                               "0x%02x\n", i, ncr_addr + i, byte_val);
             }
-            NCR710_DPRINTF("  Reconstructed %u-byte value: 0x%lx\n",
-                           size, val);
         }
 
         trace_lasi_ncr710_reg_forward_read(addr, val);
@@ -84,7 +80,13 @@ static void lasi_ncr710_reg_write(void *opaque, hwaddr addr,
 
     trace_lasi_ncr710_reg_write(addr, val, size);
 
-    if (addr <= 0x0F) {
+    /*
+     * 0x00..0x0f is the read only LASI module header (ID/SVERSION/HVERSION) 
and
+     * 0x10..0xff is unmapped module space; writes to both are ignored.  The
+     * SCSI bus reset is driven through the chip's SCNTL1.RST at forwarded
+     * offset 0x101 (see ncr53c710.c), not through this window.
+     */
+    if (addr <= 0x0f) {
         return;
     }
 
@@ -93,16 +95,10 @@ static void lasi_ncr710_reg_write(void *opaque, hwaddr addr,
 
         if (size == 1) {
             ncr_addr ^= 3;
-            NCR710_DPRINTF("Writing value to LASI WRAPPER == 0x%lx%s, "
-                           "val=0x%lx, size=%u\n",
-                           addr - 0x100, size == 1 ? " (XORed)" : "",
-                           val, size);
             ncr710_reg_write(&s->ncr710, ncr_addr, val, size);
         } else {
             for (unsigned i = 0; i < size; i++) {
                 uint8_t byte_val = (val >> (i * 8)) & 0xff;
-                 NCR710_DPRINTF("  Writing byte %u to NCR addr 0x%lx: 
0x%02x\n",
-                       i, ncr_addr + i, byte_val);
                 ncr710_reg_write(&s->ncr710, ncr_addr + i, byte_val, 1);
             }
         }
@@ -113,10 +109,7 @@ static void lasi_ncr710_reg_write(void *opaque, hwaddr 
addr,
     }
 }
 
-/*
- * req_cancelled, command_complete, transfer_data forwards
- * commands to its core counterparts.
- */
+/* SCSIBusInfo callbacks: trace, then forward to the ncr53c710 core. */
 static void lasi_ncr710_request_cancelled(SCSIRequest *req)
 {
     trace_lasi_ncr710_request_cancelled(req);
@@ -129,20 +122,27 @@ static void lasi_ncr710_command_complete(SCSIRequest 
*req, size_t resid)
     ncr710_command_complete(req, resid);
 }
 
- static void lasi_ncr710_transfer_data(SCSIRequest *req, uint32_t len)
+static void lasi_ncr710_transfer_data(SCSIRequest *req, uint32_t len)
 {
     trace_lasi_ncr710_transfer_data(len);
     ncr710_transfer_data(req, len);
 }
 
+static void lasi_ncr710_free_request(SCSIBus *bus, void *priv)
+{
+    g_free(priv);
+}
+
 static const struct SCSIBusInfo lasi_ncr710_scsi_info = {
     .tcq = true,
-    .max_target = 8,
-    .max_lun = 8,  /* full LUN support */
+    /* 8-bit bus: targets and LUNs 0-7 (scsi-bus.c maxima are inclusive). */
+    .max_target = 7,
+    .max_lun = 7,
 
     .transfer_data = lasi_ncr710_transfer_data,
     .complete = lasi_ncr710_command_complete,
     .cancel = lasi_ncr710_request_cancelled,
+    .free_request = lasi_ncr710_free_request,
 };
 
 static const MemoryRegionOps lasi_ncr710_mmio_ops = {
@@ -157,12 +157,9 @@ static const MemoryRegionOps lasi_ncr710_mmio_ops = {
 
 static const VMStateDescription vmstate_lasi_ncr710 = {
     .name = "lasi-ncr710",
-    .version_id = 1,
-    .minimum_version_id = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
     .fields = (const VMStateField[]) {
-        VMSTATE_UINT32(hw_type, LasiNCR710State),
-        VMSTATE_UINT32(sversion, LasiNCR710State),
-        VMSTATE_UINT32(hversion, LasiNCR710State),
         VMSTATE_STRUCT(ncr710, LasiNCR710State, 1, vmstate_ncr710, 
NCR710State),
         VMSTATE_END_OF_LIST()
     }
@@ -179,49 +176,36 @@ static void lasi_ncr710_realize(DeviceState *dev, Error 
**errp)
                   &lasi_ncr710_scsi_info);
     s->ncr710.as = &address_space_memory;
     s->ncr710.irq = s->lasi_irq;
+    QTAILQ_INIT(&s->ncr710.queue);
 
-    s->ncr710.reselection_retry_timer =
+    s->ncr710.scripts_timer =
         timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                     ncr710_reselection_retry_callback,
+                     ncr710_scripts_timer_callback,
                      &s->ncr710);
 
     ncr710_soft_reset(&s->ncr710);
 
     trace_lasi_ncr710_timers_initialized(
-        (uint64_t)s->ncr710.reselection_retry_timer);
+        (uint64_t)s->ncr710.scripts_timer);
 
-    /* Initialize memory region */
     memory_region_init_io(&s->mmio, OBJECT(dev), &lasi_ncr710_mmio_ops, s,
                           "lasi-ncr710", 0x200);
     sysbus_init_mmio(sbd, &s->mmio);
 }
 
-void lasi_ncr710_handle_legacy_cmdline(DeviceState *lasi_dev)
+static void lasi_ncr710_unrealize(DeviceState *dev)
 {
-    LasiNCR710State *s = LASI_NCR710(lasi_dev);
-    SCSIBus *bus = &s->ncr710.bus;
-    int found_drives = 0;
-
-    if (!bus) {
-        return;
-    }
+    LasiNCR710State *s = LASI_NCR710(dev);
 
-    for (int unit = 0; unit <= 7; unit++) {
-        DriveInfo *dinfo = drive_get(IF_SCSI, bus->busnr, unit);
-        if (dinfo) {
-            trace_lasi_ncr710_legacy_drive_found(bus->busnr, unit);
-            found_drives++;
-        }
-    }
+    timer_free(s->ncr710.scripts_timer);
+    s->ncr710.scripts_timer = NULL;
+}
 
-    trace_lasi_ncr710_handle_legacy_cmdline(bus->busnr, found_drives);
+void lasi_ncr710_handle_legacy_cmdline(DeviceState *lasi_dev)
+{
+    LasiNCR710State *s = LASI_NCR710(lasi_dev);
 
-    scsi_bus_legacy_handle_cmdline(bus);
-    BusChild *kid;
-    QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) {
-        trace_lasi_ncr710_scsi_device_created(
-            object_get_typename(OBJECT(kid->child)));
-    }
+    scsi_bus_legacy_handle_cmdline(&s->ncr710.bus);
 }
 
 DeviceState *lasi_ncr710_init(MemoryRegion *addr_space, hwaddr hpa,
@@ -248,20 +232,12 @@ static void lasi_ncr710_reset(DeviceState *dev)
     ncr710_soft_reset(&s->ncr710);
 }
 
-static void lasi_ncr710_instance_init(Object *obj)
-{
-    LasiNCR710State *s = LASI_NCR710(obj);
-
-    s->hw_type = HPHW_FIO;
-    s->sversion = LASI_710_SVERSION;
-    s->hversion = LASI_710_HVERSION;
-}
-
 static void lasi_ncr710_class_init(ObjectClass *klass, const void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = lasi_ncr710_realize;
+    dc->unrealize = lasi_ncr710_unrealize;
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->fw_name = "scsi";
     dc->desc = "HP-PARISC LASI NCR710 SCSI adapter";
@@ -274,7 +250,6 @@ static const TypeInfo lasi_ncr710_info = {
     .name          = TYPE_LASI_NCR710,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(LasiNCR710State),
-    .instance_init = lasi_ncr710_instance_init,
     .class_init    = lasi_ncr710_class_init,
 };
 
diff --git a/hw/scsi/lasi_ncr710.h b/hw/scsi/lasi_ncr710.h
index 450fb7e1c3..968604c2e7 100644
--- a/hw/scsi/lasi_ncr710.h
+++ b/hw/scsi/lasi_ncr710.h
@@ -1,12 +1,9 @@
 /*
- * LASI Wrapper for NCR710 SCSI Controller
+ * LASI wrapper for the NCR 53C710 SCSI controller
  *
  * Copyright (c) 2025 Soumyajyotii Ssarkar <[email protected]>
- * This driver was developed during the Google Summer of Code 2025 program.
- * Mentored by Helge Deller <[email protected]>
- *
- * NCR710 SCSI Controller implementation
- * Based on the NCR53C710 Technical Manual Version 3.2, December 2000
+ * Developed during Google Summer of Code 2025, mentored by
+ * Helge Deller <[email protected]>.
  *
  * SPDX-License-Identifier: GPL-2.0-or-later
  */
@@ -17,34 +14,15 @@
 #include "hw/core/sysbus.h"
 #include "exec/memattrs.h"
 #include "hw/scsi/scsi.h"
-#include "hw/scsi/ncr53c710.h"
+#include "hw/scsi/ncr53c710_v2.h"
 
 #define TYPE_LASI_NCR710 "lasi-ncr710"
 OBJECT_DECLARE_SIMPLE_TYPE(LasiNCR710State, LASI_NCR710)
 
-#define LASI_SCSI_RESET         0x000   /* SCSI Reset Register */
-#define LASI_SCSI_NCR710_BASE   0x100   /* NCR710 Base Register Offset */
-
-#define PARISC_DEVICE_ID_OFF    0x00    /* HW type, HVERSION, SVERSION */
-#define PARISC_DEVICE_CONFIG_OFF 0x04   /* Configuration data */
-
-#define PHASE_MASK              7
-#define PHASE_DO                0
-
-#define NCR710_SCNTL1_RST       0x08    /* SCSI Reset */
-#define NCR710_ISTAT_RST        0x40    /* Device Reset */
-#define NCR710_ISTAT_ABRT       0x80    /* Script Abort */
-#define NCR710_ISTAT_CON        0x08    /* ISTAT_Connected */
-#define NCR710_DSTAT_DFE        0x80    /* DMA FIFO Empty */
-#define NCR710_CTEST2_DACK      0x01    /* DMA Acknowledge */
-
 typedef struct LasiNCR710State {
     SysBusDevice parent_obj;
     MemoryRegion mmio;
     qemu_irq lasi_irq;       /* IRQ line to LASI controller */
-    uint32_t hw_type;        /* Hardware type (HPHW_*) */
-    uint32_t sversion;       /* Software version */
-    uint32_t hversion;       /* Hardware version */
     NCR710State ncr710;
 } LasiNCR710State;
 
diff --git a/hw/scsi/meson.build b/hw/scsi/meson.build
index 69fde0cf84..066d95f464 100644
--- a/hw/scsi/meson.build
+++ b/hw/scsi/meson.build
@@ -11,7 +11,7 @@ scsi_ss.add(files(
 scsi_ss.add(when: 'CONFIG_ESP', if_true: files('esp.c'))
 scsi_ss.add(when: 'CONFIG_ESP_PCI', if_true: files('esp-pci.c'))
 scsi_ss.add(when: 'CONFIG_LSI_SCSI_PCI', if_true: files('lsi53c895a.c'))
-scsi_ss.add(when: 'CONFIG_NCR710_SCSI', if_true: files('ncr53c710.c', 
'lasi_ncr710.c'))
+scsi_ss.add(when: 'CONFIG_NCR710_SCSI', if_true: files('ncr53c710_v2.c', 
'lasi_ncr710.c'))
 scsi_ss.add(when: 'CONFIG_MEGASAS_SCSI_PCI', if_true: files('megasas.c'))
 scsi_ss.add(when: 'CONFIG_MPTSAS_SCSI_PCI', if_true: files('mptsas.c', 
'mptconfig.c', 'mptendian.c'))
 scsi_ss.add(when: 'CONFIG_VMW_PVSCSI_SCSI_PCI', if_true: files('vmw_pvscsi.c'))
-- 
2.54.0


Reply via email to