Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Use a u_int32_t in script RAM instead of the SEM bit...



details:   https://anonhg.NetBSD.org/src/rev/eb5d54efdd27
branches:  trunk
changeset: 526201:eb5d54efdd27
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Apr 27 18:46:49 2002 +0000

description:
Use a u_int32_t in script RAM instead of the SEM bit in ISTAT to pass flags
between script and driver. This allows more than one flag, and is easier to
manage (we almost can't read/write istat outside of the irq handler).

diffstat:

 sys/dev/ic/esiop.c              |  79 ++++++++++++++++++++++++++++++----------
 sys/dev/ic/esiopvar.h           |   4 +-
 sys/dev/microcode/siop/esiop.ss |  18 +++++++-
 3 files changed, 76 insertions(+), 25 deletions(-)

diffs (235 lines):

diff -r c61842879e46 -r eb5d54efdd27 sys/dev/ic/esiop.c
--- a/sys/dev/ic/esiop.c        Sat Apr 27 17:40:19 2002 +0000
+++ b/sys/dev/ic/esiop.c        Sat Apr 27 18:46:49 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: esiop.c,v 1.11 2002/04/27 17:39:51 bouyer Exp $        */
+/*     $NetBSD: esiop.c,v 1.12 2002/04/27 18:46:49 bouyer Exp $        */
 
 /*
  * Copyright (c) 2002 Manuel Bouyer.
@@ -33,7 +33,7 @@
 /* SYM53c7/8xx PCI-SCSI I/O Processors driver */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: esiop.c,v 1.11 2002/04/27 17:39:51 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: esiop.c,v 1.12 2002/04/27 18:46:49 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -219,18 +219,22 @@
 {
        int i, j;
        u_int32_t addr;
-       u_int32_t msgin_addr;
+       u_int32_t msgin_addr, sem_addr;
 
        siop_common_reset(&sc->sc_c);
 
        /*
-        * we copy the script at the beggining of RAM. Then there is 8 bytes
-        * for messages in.
+        * we copy the script at the beggining of RAM. Then there is 4 bytes
+        * for messages in, and 4 bytes for semaphore
         */
        sc->sc_free_offset = sizeof(esiop_script) / sizeof(esiop_script[0]);
        msgin_addr =
            sc->sc_free_offset * sizeof(u_int32_t) + sc->sc_c.sc_scriptaddr;
-       sc->sc_free_offset += 2;
+       sc->sc_free_offset += 1;
+       sc->sc_semoffset = sc->sc_free_offset;
+       sem_addr =
+           sc->sc_semoffset * sizeof(u_int32_t) + sc->sc_c.sc_scriptaddr;
+       sc->sc_free_offset += 1;
        /* then we have the scheduler ring */
        sc->sc_shedoffset = sc->sc_free_offset;
        sc->sc_free_offset += A_ncmd_slots * CMD_SLOTSIZE;
@@ -255,6 +259,12 @@
                        bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
                            E_abs_msgin2_Used[j] * 4, msgin_addr);
                }
+               for (j = 0; j <
+                   (sizeof(E_abs_sem_Used) / sizeof(E_abs_sem_Used[0]));
+                   j++) {
+                       bus_space_write_4(sc->sc_c.sc_ramt, sc->sc_c.sc_ramh,
+                           E_abs_sem_Used[j] * 4, sem_addr);
+               }
 
                if (sc->sc_c.features & SF_CHIP_LED0) {
                        bus_space_write_region_4(sc->sc_c.sc_ramt,
@@ -287,6 +297,12 @@
                        sc->sc_c.sc_script[E_abs_msgin2_Used[j]] =
                            htole32(msgin_addr);
                }
+               for (j = 0; j <
+                   (sizeof(E_abs_sem_Used) / sizeof(E_abs_sem_Used[0]));
+                   j++) {
+                       sc->sc_c.sc_script[E_abs_sem_Used[j]] =
+                           htole32(sem_addr);
+               }
 
                if (sc->sc_c.features & SF_CHIP_LED0) {
                        for (j = 0; j < (sizeof(esiop_led_on) /
@@ -423,18 +439,10 @@
        }
        retval = 1;
        INCSTAT(esiop_stat_intr);
+       esiop_checkdone(sc);
        if (istat & ISTAT_INTF) {
                bus_space_write_1(sc->sc_c.sc_rt, sc->sc_c.sc_rh,
                    SIOP_ISTAT, ISTAT_INTF);
-               esiop_checkdone(sc);
-               if (sc->sc_flags & SCF_CHAN_NOSLOT) {
-                       /*
-                        * at last one command terminated,
-                        * so we should have free slots now
-                        */
-                       sc->sc_flags &= ~SCF_CHAN_NOSLOT;
-                       scsipi_channel_thaw(&sc->sc_c.sc_chan, 1);
-               }
                goto again;
        }
 
@@ -1091,12 +1099,6 @@
        if (freetarget && esiop_target->target_c.status == TARST_PROBING)
                esiop_del_dev(sc, target, lun);
        CALL_SCRIPT(Ent_script_sched);
-       if (sc->sc_flags & SCF_CHAN_NOSLOT) {
-               /* a command terminated, so we have free slots now */
-               sc->sc_flags &= ~SCF_CHAN_NOSLOT;
-               scsipi_channel_thaw(&sc->sc_c.sc_chan, 1);
-       }
-
        return 1;
 }
 
@@ -1173,6 +1175,25 @@
        u_int32_t slot;
        int needsync = 0;
        int status;
+       u_int32_t sem;
+
+       esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+       sem = esiop_script_read(sc, sc->sc_semoffset);
+       esiop_script_write(sc, sc->sc_semoffset, sem & ~A_sem_done);
+       if ((sc->sc_flags & SCF_CHAN_NOSLOT) && (sem & A_sem_start)) {
+               /*
+                * at last one command have been started,
+                * so we should have free slots now
+                */
+               sc->sc_flags &= ~SCF_CHAN_NOSLOT;
+               scsipi_channel_thaw(&sc->sc_c.sc_chan, 1);
+       }
+       esiop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+       if ((sem & A_sem_done) == 0) {
+               /* no pending done command */
+               return;
+       }
 
        bus_dmamap_sync(sc->sc_c.sc_dmat, sc->sc_done_map,
            sc->sc_done_offset, A_ndone_slots * sizeof(u_int32_t),
@@ -1422,6 +1443,16 @@
                lun = periph->periph_lun;
 
                s = splbio();
+               /*
+                * first check if there are pending complete commands.
+                * this can free us some resources (in the rings for example).
+                * we have to lock it to avoid recursion.
+                */
+               if ((sc->sc_flags & SCF_CHAN_ADAPTREQ) == 0) {
+                       sc->sc_flags |= SCF_CHAN_ADAPTREQ;
+                       esiop_checkdone(sc);
+                       sc->sc_flags &= ~SCF_CHAN_ADAPTREQ;
+               }
 #ifdef SIOP_DEBUG_SCHED
                printf("starting cmd for %d:%d tag %d(%d)\n", target, lun,
                    xs->xs_tag_type, xs->xs_tag_id);
@@ -1626,6 +1657,12 @@
                 */
                scsipi_channel_freeze(&sc->sc_c.sc_chan, 1);
                sc->sc_flags |= SCF_CHAN_NOSLOT;
+               esiop_script_sync(sc,
+                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+               esiop_script_write(sc, sc->sc_semoffset,
+                   esiop_script_read(sc, sc->sc_semoffset) & ~A_sem_start);
+               esiop_script_sync(sc,
+                   BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
                esiop_cmd->cmd_c.xs->error = XS_REQUEUE;
                esiop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
                esiop_scsicmd_end(esiop_cmd);
diff -r c61842879e46 -r eb5d54efdd27 sys/dev/ic/esiopvar.h
--- a/sys/dev/ic/esiopvar.h     Sat Apr 27 17:40:19 2002 +0000
+++ b/sys/dev/ic/esiopvar.h     Sat Apr 27 18:46:49 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: esiopvar.h,v 1.6 2002/04/27 17:39:52 bouyer Exp $      */
+/*     $NetBSD: esiopvar.h,v 1.7 2002/04/27 18:46:49 bouyer Exp $      */
 
 /*
  * Copyright (c) 2002 Manuel Bouyer.
@@ -138,6 +138,7 @@
 /* Driver internal state */
 struct esiop_softc {
        struct siop_common_softc sc_c;
+       u_int32_t sc_semoffset;         /* semaphore */
        u_int32_t sc_shedoffset;        /* base of scheduler ring */
        int sc_currschedslot;           /* current scheduler slot */
        struct cbd_list cmds;           /* list of command block descriptors */
@@ -155,6 +156,7 @@
 
 /* defs for sc_flags */
 #define SCF_CHAN_NOSLOT        0x0001          /* channel out of sheduler slot */
+#define SCF_CHAN_ADAPTREQ 0x0002       /* esiop_scsipi_request() is running */
 
 void    esiop_attach __P((struct esiop_softc *));
 int    esiop_intr __P((void *));
diff -r c61842879e46 -r eb5d54efdd27 sys/dev/microcode/siop/esiop.ss
--- a/sys/dev/microcode/siop/esiop.ss   Sat Apr 27 17:40:19 2002 +0000
+++ b/sys/dev/microcode/siop/esiop.ss   Sat Apr 27 18:46:49 2002 +0000
@@ -1,4 +1,4 @@
-;      $NetBSD: esiop.ss,v 1.11 2002/04/27 17:39:52 bouyer Exp $
+;      $NetBSD: esiop.ss,v 1.12 2002/04/27 18:46:50 bouyer Exp $
 
 ;
 ; Copyright (c) 2002 Manuel Bouyer.
@@ -115,11 +115,18 @@
 EXTERN tlq_offset;
 EXTERN abs_msgin2;
 
+EXTERN abs_sem; a 32bits word used a semaphore between script and driver
+ABSOLUTE sem_done = 0x01; there are pending done commands
+ABSOLUTE sem_start = 0x02; a CMD slot was freed
+
 PROC  esiop_script:
 
 no_cmd:
-       MOVE ISTAT & 0x10 TO SFBR;  pending done command ?
+       LOAD SCRATCHB0, 4, abs_sem; pending done command ?
+       MOVE SCRATCHB0 & sem_done TO SFBR;
        INTFLY 0, IF NOT 0x00; 
+       MOVE SCRATCHB0 | sem_start TO SCRATCHB0; we are there because the 
+       STORE NOFLUSH SCRATCHB0, 4, abs_sem;     cmd ring is empty
 reselect:
        MOVE 0x00 TO SCRATCHA1;
        MOVE 0x00 TO SCRATCHC0;
@@ -256,6 +263,9 @@
        JUMP REL(script_sched), IF NOT 0x00; next command if ignore
        MOVE SCRATCHB0 & 0xfc to SCRATCHB0; clear f_cmd_*
        CALL REL(restoredsa); and move SCRATCHB to DSA
+       LOAD SCRATCHB0, 4, abs_sem;
+       MOVE SCRATCHB0 | sem_start TO SCRATCHB0;
+       STORE NOFLUSH SCRATCHB0, 4, abs_sem;
 
 ; a NOP by default; patched with MOVE GPREG & 0xfe to GPREG on compile-time
 ; option "SIOP_SYMLED"
@@ -405,7 +415,9 @@
        MOVE 0xff to SCRATCHF3;
        MOVE 0  to SCRATCHE2;
 is_done:
-       MOVE ISTAT | 0x10 TO ISTAT; signal that cmd is done in ISTAT
+       LOAD SCRATCHB0, 4, abs_sem; signal that a command is done
+       MOVE SCRATCHB0 | sem_done TO SCRATCHB0;
+       STORE NOFLUSH SCRATCHB0, 4, abs_sem;
        JUMP REL(script_sched); and attempt next command
 
 handle_extin:



Home | Main Index | Thread Index | Old Index