Source-Changes-HG archive

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

[src/trunk]: src/sys/dev Add support for tagged queuing to esiop (256 tags pe...



details:   https://anonhg.NetBSD.org/src/rev/f5d48e9ec301
branches:  trunk
changeset: 525962:f5d48e9ec301
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Mon Apr 22 15:53:39 2002 +0000

description:
Add support for tagged queuing to esiop (256 tags per device).
For this add another indirecton: the DSA in the LUN table points to
a table of DSA indexed by the tag number when tagged command is in use.
For non tagged command, the LUN DSA still points to the tables describing the
xfer directly.

diffstat:

 sys/dev/ic/esiop.c              |  376 +++++++++++++++++++++++++--------------
 sys/dev/ic/esiopvar.h           |   47 ++++-
 sys/dev/microcode/siop/esiop.ss |   41 +++-
 3 files changed, 316 insertions(+), 148 deletions(-)

diffs (truncated from 784 to 300 lines):

diff -r cc112542c5a9 -r f5d48e9ec301 sys/dev/ic/esiop.c
--- a/sys/dev/ic/esiop.c        Mon Apr 22 15:48:55 2002 +0000
+++ b/sys/dev/ic/esiop.c        Mon Apr 22 15:53:39 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: esiop.c,v 1.1 2002/04/21 22:52:05 bouyer Exp $ */
+/*     $NetBSD: esiop.c,v 1.2 2002/04/22 15:53:39 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.1 2002/04/21 22:52:05 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: esiop.c,v 1.2 2002/04/22 15:53:39 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -84,6 +84,7 @@
 void   esiop_handle_reset __P((struct esiop_softc *));
 void   esiop_scsicmd_end __P((struct esiop_cmd *));
 void   esiop_unqueue __P((struct esiop_softc *, int, int));
+int    esiop_handle_qtag_reject __P((struct esiop_cmd *));
 static void    esiop_start __P((struct esiop_softc *, struct esiop_cmd *));
 void   esiop_timeout __P((void *));
 int    esiop_scsicmd __P((struct scsipi_xfer *));
@@ -91,6 +92,7 @@
                        scsipi_adapter_req_t, void *));
 void   esiop_dump_script __P((struct esiop_softc *));
 void   esiop_morecbd __P((struct esiop_softc *));
+void   esiop_moretagtbl __P((struct esiop_softc *));
 void   siop_add_reselsw __P((struct esiop_softc *, int));
 void   esiop_update_scntl3 __P((struct esiop_softc *,
                        struct siop_common_target *));
@@ -201,6 +203,8 @@
        }
        TAILQ_INIT(&sc->free_list);
        TAILQ_INIT(&sc->cmds);
+       TAILQ_INIT(&sc->free_tagtbl);
+       TAILQ_INIT(&sc->tag_tblblk);
        sc->sc_currschedslot = 0;
 #ifdef SIOP_DEBUG
        printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p\n",
@@ -491,10 +495,11 @@
                            target, lun);
                        goto none;
                }
-               esiop_cmd = esiop_lun->active;
+               esiop_cmd =
+                   (tag >= 0) ? esiop_lun->tactive[tag] : esiop_lun->active;
                if (esiop_cmd == NULL) {
-                       printf("esiop_cmd (target %d lun %d) not valid\n",
-                           target, lun);
+                       printf("esiop_cmd (target %d lun %d tag %d) not valid\n",
+                           target, lun, tag);
                        goto none;
                }
                xs = esiop_cmd->cmd_c.xs;
@@ -677,10 +682,7 @@
                                esiop_target = (struct esiop_target *)
                                    esiop_cmd->cmd_c.siop_target;
                                lun = xs->xs_periph->periph_lun;
-#if 0 /* XXX TAG */
                                tag = esiop_cmd->cmd_c.tag;
-#endif
-                               tag = -1;
                                esiop_lun = esiop_target->esiop_lun[lun];
                                esiop_cmd->cmd_c.status = CMDST_DONE;
                                xs->error = XS_SELTIMEOUT;
@@ -854,18 +856,15 @@
                                        /* no table to flush here */
                                        CALL_SCRIPT(Ent_msgin_ack);
                                        return 1;
-                               }
-#if 0 /* XXX TAG */
-                               else if (msg == MSG_SIMPLE_Q_TAG || 
+                               } else if (msg == MSG_SIMPLE_Q_TAG || 
                                    msg == MSG_HEAD_OF_Q_TAG ||
                                    msg == MSG_ORDERED_Q_TAG) {
-                                       if (siop_handle_qtag_reject(
+                                       if (esiop_handle_qtag_reject(
                                            esiop_cmd) == -1)
                                                goto reset;
                                        CALL_SCRIPT(Ent_msgin_ack);
                                        return 1;
                                }
-#endif /* XXX TAG */
                                if (xs)
                                        scsipi_printaddr(xs->xs_periph);
                                else
@@ -1047,10 +1046,10 @@
                CALL_SCRIPT(Ent_script_sched);
        else
                restart = 1;
-#if 0 /* XXX TAG */
-       esiop_lun->esiop_tag[tag].active = NULL;
-#endif
-       esiop_lun->active = NULL;
+       if (tag >= 0)
+               esiop_lun->tactive[tag] = NULL;
+       else
+               esiop_lun->active = NULL;
        esiop_scsicmd_end(esiop_cmd);
        if (freetarget && esiop_target->target_c.status == TARST_PROBING)
                esiop_del_dev(sc, target, lun);
@@ -1131,7 +1130,7 @@
 esiop_checkdone(sc)
        struct esiop_softc *sc;
 {
-       int target, lun;
+       int target, lun, tag;
        struct esiop_target *esiop_target;
        struct esiop_lun *esiop_lun;
        struct esiop_cmd *esiop_cmd;
@@ -1146,15 +1145,27 @@
                        if (esiop_lun == NULL)
                                continue;
                        esiop_cmd = esiop_lun->active;
-                       if (esiop_cmd == NULL)
-                               continue;
-                       status = le32toh(esiop_cmd->cmd_tables->status);
-                       if (status != SCSI_OK)
-                               continue;
-                       /* Ok, this command has been handled */
-                       esiop_cmd->cmd_c.xs->status = status;
-                       esiop_lun->active = NULL;
-                       esiop_scsicmd_end(esiop_cmd);
+                       if (esiop_cmd) {
+                               status = le32toh(esiop_cmd->cmd_tables->status);
+                               if (status == SCSI_OK) {
+                                       /* Ok, this command has been handled */
+                                       esiop_cmd->cmd_c.xs->status = status;
+                                       esiop_lun->active = NULL;
+                                       esiop_scsicmd_end(esiop_cmd);
+                               }
+                       }
+                       for (tag = 0; tag < ESIOP_NTAG; tag++) {
+                               esiop_cmd = esiop_lun->tactive[tag];
+                               if (esiop_cmd == NULL)
+                                       continue;
+                               status = le32toh(esiop_cmd->cmd_tables->status);
+                               if (status == SCSI_OK) {
+                                       /* Ok, this command has been handled */
+                                       esiop_cmd->cmd_c.xs->status = status;
+                                       esiop_lun->tactive[tag] = NULL;
+                                       esiop_scsicmd_end(esiop_cmd);
+                               }
+                       }
                }
        }
 }
@@ -1165,8 +1176,8 @@
        int target;
        int lun;
 {
-#if 0 /* XXX TAG */
        int slot, tag;
+       u_int32_t slotdsa;
        struct esiop_cmd *esiop_cmd;
        struct esiop_lun *esiop_lun =
            ((struct esiop_target *)sc->sc_c.targets[target])->esiop_lun[lun];
@@ -1174,41 +1185,30 @@
        /* first make sure to read valid data */
        esiop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
-       for (tag = 1; tag < ESIOP_NTAG; tag++) {
+       for (tag = 0; tag < ESIOP_NTAG; tag++) {
                /* look for commands in the scheduler, not yet started */
-               if (siop_lun->siop_tag[tag].active == NULL) 
+               if (esiop_lun->tactive[tag] == NULL) 
                        continue;
-               esiop_cmd = siop_lun->siop_tag[tag].active;
-               for (slot = 0; slot <= sc->sc_currschedslot; slot++) {
-                       if (esiop_script_read(sc,
-                           (Ent_script_sched_slot0 / 4) + slot * 2 + 1) ==
-                           esiop_cmd->cmd_c.dsa +
-                           sizeof(struct siop_common_xfer) +
-                           Ent_ldsa_select)
+               esiop_cmd = esiop_lun->tactive[tag];
+               for (slot = 0; slot <= A_ncmd_slots; slot++) {
+                       slotdsa = esiop_script_read(sc,
+                           sc->sc_shedoffset + slot * 2);
+                       if (slotdsa & A_f_cmd_free)
+                               continue;
+                       if ((slotdsa & ~A_f_cmd_free) == esiop_cmd->cmd_c.dsa)
                                break;
                }
-               if (slot >  sc->sc_currschedslot)
+               if (slot >  ESIOP_NTAG)
                        continue; /* didn't find it */
-               if (esiop_script_read(sc,
-                   (Ent_script_sched_slot0 / 4) + slot * 2) == 0x80000000)
-                       continue; /* already started */
-               /* clear the slot */
-               esiop_script_write(sc, (Ent_script_sched_slot0 / 4) + slot * 2,
-                   0x80000000);
+               /* Mark this slot as ignore */
+               esiop_script_write(sc, sc->sc_shedoffset + slot * 2,
+                   esiop_cmd->cmd_c.dsa | A_f_cmd_ignore);
                /* ask to requeue */
                esiop_cmd->cmd_c.xs->error = XS_REQUEUE;
                esiop_cmd->cmd_c.xs->status = SCSI_SIOP_NOCHECK;
-               siop_lun->siop_tag[tag].active = NULL;
-               siop_scsicmd_end(esiop_cmd);
+               esiop_lun->tactive[tag] = NULL;
+               esiop_scsicmd_end(esiop_cmd);
        }
-       /* update sc_currschedslot */
-       sc->sc_currschedslot = 0;
-       for (slot = SIOP_NSLOTS - 1; slot >= 0; slot--) {
-               if (esiop_script_read(sc,
-                   (Ent_script_sched_slot0 / 4) + slot * 2) != 0x80000000)
-                       sc->sc_currschedslot = slot;
-       }
-#endif /* XXX TAG */
 }
 
 /*
@@ -1216,17 +1216,18 @@
  * has to adjust the reselect script.
  */
 
-#if 0 /* XXX TAG */
+
 int
 esiop_handle_qtag_reject(esiop_cmd)
        struct esiop_cmd *esiop_cmd;
 {
-       struct siop_softc *sc = (struct esiop_softc *)esiop_cmd->cmd_c.siop_sc;
+       struct esiop_softc *sc = (struct esiop_softc *)esiop_cmd->cmd_c.siop_sc;
        int target = esiop_cmd->cmd_c.xs->xs_periph->periph_target;
        int lun = esiop_cmd->cmd_c.xs->xs_periph->periph_lun;
        int tag = esiop_cmd->cmd_tables->msg_out[2];
-       struct esiop_lun *esiop_lun =
-           ((struct esiop_target*)sc->sc_c.targets[target])->esiop_lun[lun];
+       struct esiop_target *esiop_target =
+           (struct esiop_target*)sc->sc_c.targets[target];
+       struct esiop_lun *esiop_lun = esiop_target->esiop_lun[lun];
 
 #ifdef SIOP_DEBUG
        printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n",
@@ -1234,30 +1235,26 @@
            esiop_cmd->cmd_c.status);
 #endif
 
-       if (esiop_lun->siop_tag[0].active != NULL) {
+       if (esiop_lun->active != NULL) {
                printf("%s: untagged command already running for target %d "
                    "lun %d (status %d)\n", sc->sc_c.sc_dev.dv_xname,
-                   target, lun, esiop_lun->siop_tag[0].active->cmd_c.status);
+                   target, lun, esiop_lun->active->cmd_c.status);
                return -1;
        }
        /* clear tag slot */
-       esiop_lun->siop_tag[tag].active = NULL;
+       esiop_lun->tactive[tag] = NULL;
        /* add command to non-tagged slot */
-       esiop_lun->siop_tag[0].active = esiop_cmd;
-       esiop_cmd->cmd_c.tag = 0;
-       /* adjust reselect script if there is one */
-       if (esiop_lun->siop_tag[0].reseloff > 0) {
-               esiop_script_write(sc,
-                   esiop_lun->siop_tag[0].reseloff + 1,
-                   esiop_cmd->cmd_c.dsa + sizeof(struct siop_common_xfer) +
-                   Ent_ldsa_reload_dsa);
-               esiop_table_sync(esiop_cmd, BUS_DMASYNC_PREWRITE);
-       }
+       esiop_lun->active = esiop_cmd;
+       esiop_cmd->cmd_c.flags &= ~CMDFL_TAG;
+       esiop_cmd->cmd_c.tag = -1;
+       /* update DSA table */
+       esiop_script_write(sc, esiop_target->lun_table_offset + lun + 2,
+           esiop_cmd->cmd_c.dsa);
+       esiop_lun->lun_flags &= ~LUNF_TAGTABLE;
+       esiop_script_sync(sc, BUS_DMASYNC_PREREAD |  BUS_DMASYNC_PREWRITE);
        return 0;
 }
 
-#endif /* XXX TAG */
-
 /*
  * handle a bus reset: reset chip, unqueue all active commands, free all
  * target struct and report loosage to upper layer.
@@ -1298,17 +1295,14 @@
                        esiop_lun = esiop_target->esiop_lun[lun];
                        if (esiop_lun == NULL)
                                continue;
-#if 0 /* XXX TAG */
-                       for (tag = 0; tag <
+                       for (tag = -1; tag <
                            ((sc->sc_c.targets[target]->flags & TARF_TAG) ?
-                           ESIOP_NTAG : 1);
+                           ESIOP_NTAG : 0);
                            tag++) {
-                               esiop_cmd = esiop_lun->siop_tag[tag].active;
-#else
-                       {
-                               tag = -1;
-                               esiop_cmd = esiop_lun->active;
-#endif /* XXX TAG */



Home | Main Index | Thread Index | Old Index