Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/dev/ic Pull up revisions 1.7-1.11 (requested by bou...



details:   https://anonhg.NetBSD.org/src/rev/cd9ce57c4db9
branches:  netbsd-1-5
changeset: 490409:cd9ce57c4db9
user:      he <he%NetBSD.org@localhost>
date:      Sat Dec 16 01:59:46 2000 +0000

description:
Pull up revisions 1.7-1.11 (requested by bouyer):
  Speed improvements to the siop driver, and add tagged queueing
  support.  As a side effect, better handling of some not so common
  phase or message sequences.

diffstat:

 sys/dev/ic/siop_common.c |  225 +++++++++++++++++++++++++++++++---------------
 1 files changed, 151 insertions(+), 74 deletions(-)

diffs (truncated from 392 to 300 lines):

diff -r 578e5b359ccb -r cd9ce57c4db9 sys/dev/ic/siop_common.c
--- a/sys/dev/ic/siop_common.c  Fri Dec 15 06:20:25 2000 +0000
+++ b/sys/dev/ic/siop_common.c  Sat Dec 16 01:59:46 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: siop_common.c,v 1.3.2.1 2000/07/24 16:51:38 bouyer Exp $       */
+/*     $NetBSD: siop_common.c,v 1.3.2.2 2000/12/16 01:59:46 he Exp $   */
 
 /*
  * Copyright (c) 2000 Manuel Bouyer.
@@ -76,7 +76,7 @@
            SCNTL0_ARB_MASK | SCNTL0_EPC | SCNTL0_AAP);
        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL1, 0);
        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3, sc->clock_div);
-       bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCXFER, 0);
+       bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SXFER, 0);
        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DIEN, 0xff);
        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SIEN0,
            0xff & ~(SIEN0_CMP | SIEN0_SEL | SIEN0_RSL));
@@ -124,28 +124,78 @@
        sc->sc_reset(sc);
 }
 
+/* prepare tables before sending a cmd */
+void
+siop_setuptables(siop_cmd)
+       struct siop_cmd *siop_cmd;
+{
+       int i;
+       struct siop_softc *sc = siop_cmd->siop_sc;
+       struct scsipi_xfer *xs = siop_cmd->xs;
+       int target = xs->sc_link->scsipi_scsi.target;
+       int lun = xs->sc_link->scsipi_scsi.lun;
+
+       siop_cmd->siop_tables.id = htole32(sc->targets[target]->id);
+       memset(siop_cmd->siop_tables.msg_out, 0, 8);
+       siop_cmd->siop_tables.msg_out[0] = MSG_IDENTIFY(lun, 1);
+       siop_cmd->siop_tables.t_msgout.count= htole32(1);
+       if (sc->targets[target]->status == TARST_ASYNC) {
+               if (sc->targets[target]->flags & TARF_WIDE) {
+                       sc->targets[target]->status = TARST_WIDE_NEG;
+                       siop_wdtr_msg(siop_cmd, 1, MSG_EXT_WDTR_BUS_16_BIT);
+               } else if (sc->targets[target]->flags & TARF_SYNC) {
+                       sc->targets[target]->status = TARST_SYNC_NEG;
+                       siop_sdtr_msg(siop_cmd, 1, sc->minsync, sc->maxoff);
+               } else {
+                       sc->targets[target]->status = TARST_OK;
+               }
+       } else if (sc->targets[target]->status == TARST_OK &&
+           (sc->targets[target]->flags & TARF_TAG) &&
+           siop_cmd->status != CMDST_SENSE) {
+               siop_cmd->flags |= CMDFL_TAG;
+       }
+       siop_cmd->siop_tables.status =
+           htole32(SCSI_SIOP_NOSTATUS); /* set invalid status */
+
+       siop_cmd->siop_tables.cmd.count =
+           htole32(siop_cmd->dmamap_cmd->dm_segs[0].ds_len);
+       siop_cmd->siop_tables.cmd.addr =
+           htole32(siop_cmd->dmamap_cmd->dm_segs[0].ds_addr);
+       if ((xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) ||
+           siop_cmd->status == CMDST_SENSE) {
+               for (i = 0; i < siop_cmd->dmamap_data->dm_nsegs; i++) {
+                       siop_cmd->siop_tables.data[i].count =
+                           htole32(siop_cmd->dmamap_data->dm_segs[i].ds_len);
+                       siop_cmd->siop_tables.data[i].addr =
+                           htole32(siop_cmd->dmamap_data->dm_segs[i].ds_addr);
+               }
+       }
+       siop_table_sync(siop_cmd, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+}
+
 int
 siop_wdtr_neg(siop_cmd)
        struct siop_cmd *siop_cmd;
 {
-       struct siop_softc *sc = siop_cmd->siop_target->siop_sc;
+       struct siop_softc *sc = siop_cmd->siop_sc;
        struct siop_target *siop_target = siop_cmd->siop_target;
        int target = siop_cmd->xs->sc_link->scsipi_scsi.target;
+       struct siop_xfer_common *tables = &siop_cmd->siop_xfer->tables;
 
        if (siop_target->status == TARST_WIDE_NEG) {
                /* we initiated wide negotiation */
-               switch (siop_cmd->siop_table->msg_in[3]) {
+               switch (tables->msg_in[3]) {
                case MSG_EXT_WDTR_BUS_8_BIT:
                        printf("%s: target %d using 8bit transfers\n",
                            sc->sc_dev.dv_xname, target);
-                       siop_target->flags &= ~SF_BUS_WIDE;
+                       siop_target->flags &= ~TARF_ISWIDE;
                        sc->targets[target]->id &= ~(SCNTL3_EWS << 24);
                        break;
                case MSG_EXT_WDTR_BUS_16_BIT:
-                       if (sc->features & SF_BUS_WIDE) {
+                       if (siop_target->flags & TARF_WIDE) {
                                printf("%s: target %d using 16bit transfers\n",
                                    sc->sc_dev.dv_xname, target);
-                               siop_target->flags |= TARF_WIDE;
+                               siop_target->flags |= TARF_ISWIDE;
                                sc->targets[target]->id |= (SCNTL3_EWS << 24);
                                break;
                        }
@@ -155,34 +205,23 @@
                         * hum, we got more than what we can handle, shoudn't
                         * happen. Reject, and stay async
                         */
-                       siop_target->flags &= ~TARF_WIDE;
+                       siop_target->flags &= ~TARF_ISWIDE;
                        siop_target->status = TARST_OK;
                        printf("%s: rejecting invalid wide negotiation from "
                            "target %d (%d)\n", sc->sc_dev.dv_xname, target,
-                           siop_cmd->siop_table->msg_in[3]);
-                       siop_cmd->siop_table->t_msgout.count= htole32(1);
-                       siop_cmd->siop_table->t_msgout.addr =
-                           htole32(siop_cmd->dsa);
-                       siop_cmd->siop_table->msg_out[0] = MSG_MESSAGE_REJECT;
+                           tables->msg_in[3]);
+                       tables->t_msgout.count= htole32(1);
+                       tables->msg_out[0] = MSG_MESSAGE_REJECT;
                        return SIOP_NEG_MSGOUT;
                }
-               siop_cmd->siop_table->id =
-                   htole32(sc->targets[target]->id);
+               tables->id = htole32(sc->targets[target]->id);
                bus_space_write_1(sc->sc_rt, sc->sc_rh,
                    SIOP_SCNTL3,
                    (sc->targets[target]->id >> 24) & 0xff);
                /* we now need to do sync */
-               if ((siop_cmd->xs->sc_link->quirks & SDEV_NOSYNC) == 0) {
+               if (siop_target->flags & TARF_SYNC) {
                        siop_target->status = TARST_SYNC_NEG;
-                       siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED;
-                       siop_cmd->siop_table->msg_out[1] = MSG_EXT_SDTR_LEN;
-                       siop_cmd->siop_table->msg_out[2] = MSG_EXT_SDTR;
-                       siop_cmd->siop_table->msg_out[3] = sc->minsync;
-                       siop_cmd->siop_table->msg_out[4] = sc->maxoff;
-                       siop_cmd->siop_table->t_msgout.count =
-                           htole32(MSG_EXT_SDTR_LEN + 2);
-                       siop_cmd->siop_table->t_msgout.addr =
-                           htole32(siop_cmd->dsa);
+                       siop_sdtr_msg(siop_cmd, 0, sc->minsync, sc->maxoff);
                        return SIOP_NEG_MSGOUT;
                } else {
                        siop_target->status = TARST_OK;
@@ -190,37 +229,28 @@
                }
        } else {
                /* target initiated wide negotiation */
-               if (siop_cmd->siop_table->msg_in[3] >= MSG_EXT_WDTR_BUS_16_BIT
-                   && (sc->features & SF_BUS_WIDE)) {
+               if (tables->msg_in[3] >= MSG_EXT_WDTR_BUS_16_BIT
+                   && (siop_target->flags & TARF_WIDE)) {
                        printf("%s: target %d using 16bit transfers\n",
                            sc->sc_dev.dv_xname, target);
-                       siop_target->flags |= TARF_WIDE;
+                       siop_target->flags |= TARF_ISWIDE;
                        sc->targets[target]->id |= SCNTL3_EWS << 24;
-                       siop_cmd->siop_table->msg_out[3] =
-                           MSG_EXT_WDTR_BUS_16_BIT;
                } else {
                        printf("%s: target %d using 8bit transfers\n",
                            sc->sc_dev.dv_xname, target);
-                       siop_target->flags &= ~SF_BUS_WIDE;
+                       siop_target->flags &= ~TARF_ISWIDE;
                        sc->targets[target]->id &= ~(SCNTL3_EWS << 24);
-                       siop_cmd->siop_table->msg_out[3] =
-                           MSG_EXT_WDTR_BUS_8_BIT;
                }
-               siop_cmd->siop_table->id =
-                   htole32(sc->targets[target]->id);
+               tables->id = htole32(sc->targets[target]->id);
                bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3,
                    (sc->targets[target]->id >> 24) & 0xff);
                /*
                 * we did reset wide parameters, so fall back to async,
-                * but don't shedule a sync neg, target should initiate it
+                * but don't schedule a sync neg, target should initiate it
                 */
                siop_target->status = TARST_OK;
-               siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED;
-               siop_cmd->siop_table->msg_out[1] = MSG_EXT_WDTR_LEN;
-               siop_cmd->siop_table->msg_out[2] = MSG_EXT_WDTR;
-               siop_cmd->siop_table->t_msgout.count=
-                   htole32(MSG_EXT_WDTR_LEN + 2);
-               siop_cmd->siop_table->t_msgout.addr = htole32(siop_cmd->dsa);
+               siop_wdtr_msg(siop_cmd, 0, (siop_target->flags & TARF_ISWIDE) ?
+                   MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT);
                return SIOP_NEG_MSGOUT;
        }
 }
@@ -229,14 +259,15 @@
 siop_sdtr_neg(siop_cmd)
        struct siop_cmd *siop_cmd;
 {
-       struct siop_softc *sc = siop_cmd->siop_target->siop_sc;
+       struct siop_softc *sc = siop_cmd->siop_sc;
        struct siop_target *siop_target = siop_cmd->siop_target;
        int target = siop_cmd->xs->sc_link->scsipi_scsi.target;
        int sync, offset, i;
        int send_msgout = 0;
+       struct siop_xfer_common *tables = &siop_cmd->siop_xfer->tables;
 
-       sync = siop_cmd->siop_table->msg_in[3];
-       offset = siop_cmd->siop_table->msg_in[4];
+       sync = tables->msg_in[3];
+       offset = tables->msg_in[4];
 
        if (siop_target->status == TARST_SYNC_NEG) {
                /* we initiated sync negotiation */
@@ -267,9 +298,9 @@
                                        sc->targets[target]->id &=
                                            ~(SCNTL3_ULTRA << 24);
                                sc->targets[target]->id &=
-                                   ~(SCXFER_MO_MASK << 8);
+                                   ~(SXFER_MO_MASK << 8);
                                sc->targets[target]->id |=
-                                   (offset & SCXFER_MO_MASK) << 8;
+                                   (offset & SXFER_MO_MASK) << 8;
                                goto end;
                        }
                }
@@ -279,13 +310,13 @@
                 */
 reject:
                send_msgout = 1;
-               siop_cmd->siop_table->t_msgout.count= htole32(1);
-               siop_cmd->siop_table->msg_out[0] = MSG_MESSAGE_REJECT;
+               tables->t_msgout.count= htole32(1);
+               tables->msg_out[0] = MSG_MESSAGE_REJECT;
                printf("%s: target %d asynchronous\n", sc->sc_dev.dv_xname,
                    target);
                sc->targets[target]->id &= ~(SCNTL3_SCF_MASK << 24);
                sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24);
-               sc->targets[target]->id &= ~(SCXFER_MO_MASK << 8);
+               sc->targets[target]->id &= ~(SXFER_MO_MASK << 8);
        } else { /* target initiated sync neg */
 #ifdef DEBUG
                printf("sdtr (target): sync %d offset %d\n", sync, offset);
@@ -318,17 +349,10 @@
                                        sc->targets[target]->id &=
                                            ~(SCNTL3_ULTRA << 24);
                                sc->targets[target]->id &=
-                                   ~(SCXFER_MO_MASK << 8);
+                                   ~(SXFER_MO_MASK << 8);
                                sc->targets[target]->id |=
-                                   (offset & SCXFER_MO_MASK) << 8;
-                               siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED;
-                               siop_cmd->siop_table->msg_out[1] =
-                                   MSG_EXT_SDTR_LEN;
-                               siop_cmd->siop_table->msg_out[2] = MSG_EXT_SDTR;
-                               siop_cmd->siop_table->msg_out[3] = sync;
-                               siop_cmd->siop_table->msg_out[4] = offset;
-                               siop_cmd->siop_table->t_msgout.count=
-                                   htole32(MSG_EXT_SDTR_LEN + 2);
+                                   (offset & SXFER_MO_MASK) << 8;
+                               siop_sdtr_msg(siop_cmd, 0, sync, offset);
                                send_msgout = 1;
                                goto end;
                        }
@@ -338,27 +362,20 @@
                    sc->sc_dev.dv_xname, target);
                sc->targets[target]->id &= ~(SCNTL3_SCF_MASK << 24);
                sc->targets[target]->id &= ~(SCNTL3_ULTRA << 24);
-               sc->targets[target]->id &= ~(SCXFER_MO_MASK << 8);
-               siop_cmd->siop_table->msg_out[0] = MSG_EXTENDED;
-               siop_cmd->siop_table->msg_out[1] = MSG_EXT_SDTR_LEN;
-               siop_cmd->siop_table->msg_out[2] = MSG_EXT_SDTR;
-               siop_cmd->siop_table->msg_out[3] = 0;
-               siop_cmd->siop_table->msg_out[4] = 0;
-               siop_cmd->siop_table->t_msgout.count=
-                   htole32(MSG_EXT_SDTR_LEN + 2);
+               sc->targets[target]->id &= ~(SXFER_MO_MASK << 8);
+               siop_sdtr_msg(siop_cmd, 0, 0, 0);
                send_msgout = 1;
        }
 end:
 #ifdef DEBUG
        printf("id now 0x%x\n", sc->targets[target]->id);
 #endif
-       siop_cmd->siop_table->id = htole32(sc->targets[target]->id);
+       tables->id = htole32(sc->targets[target]->id);
        bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCNTL3,
            (sc->targets[target]->id >> 24) & 0xff);
-       bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SCXFER,
+       bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_SXFER,
            (sc->targets[target]->id >> 8) & 0xff);
        if (send_msgout) {
-               siop_cmd->siop_table->t_msgout.addr = htole32(siop_cmd->dsa);
                return SIOP_NEG_MSGOUT;
        } else {
                return SIOP_NEG_ACK;
@@ -366,6 +383,34 @@
 }
 
 void
+siop_sdtr_msg(siop_cmd, offset, ssync, soff)
+       struct siop_cmd *siop_cmd;
+       int offset;
+       int ssync, soff;
+{



Home | Main Index | Thread Index | Old Index