summaryrefslogtreecommitdiffstats
path: root/sys/dev/stg
diff options
context:
space:
mode:
authornon <non@FreeBSD.org>2001-02-25 12:40:30 +0000
committernon <non@FreeBSD.org>2001-02-25 12:40:30 +0000
commit292085c2c12f53507fafb6423983ac0153495991 (patch)
treecf8aa02bf1dfdf3f0c69596059bacd58a5560793 /sys/dev/stg
parent4f21d5f03f0b6bd39903d4ef8d34cab68c6a0db3 (diff)
downloadFreeBSD-src-292085c2c12f53507fafb6423983ac0153495991.zip
FreeBSD-src-292085c2c12f53507fafb6423983ac0153495991.tar.gz
o Support AUTO SENSE correctly.
o Offset and period in synch messages and width negotiation should be done for per target not per lun. Move these from *lun_info to *targ_info. o Change in handling XPT_RESET_DEV and XPT_GET_TRAN_SETTINGS . o Change CAM_* xpt_done return values. o Busy loop did not timeout. Change this to timeout as original NetBSD/pc98. Reviewed by: bsd-nomads ML
Diffstat (limited to 'sys/dev/stg')
-rw-r--r--sys/dev/stg/tmc18c30.c176
-rw-r--r--sys/dev/stg/tmc18c30var.h10
2 files changed, 54 insertions, 132 deletions
diff --git a/sys/dev/stg/tmc18c30.c b/sys/dev/stg/tmc18c30.c
index 6d5ea0b..b331dd3 100644
--- a/sys/dev/stg/tmc18c30.c
+++ b/sys/dev/stg/tmc18c30.c
@@ -150,6 +150,10 @@ extern struct cfdriver stg_cd;
/**************************************************************
* DECLARE
**************************************************************/
+#ifdef __NetBSD__
+extern int delaycount;
+#endif
+
/* static */
static void stg_pio_read __P((struct stg_softc *, struct targ_info *));
static void stg_pio_write __P((struct stg_softc *, struct targ_info *));
@@ -168,14 +172,13 @@ static int stghw_start_selection __P((struct stg_softc *sc, struct slccb *));
static void stghw_bus_reset __P((struct stg_softc *));
static void stghw_attention __P((struct stg_softc *));
static int stg_nexus __P((struct stg_softc *, struct targ_info *));
-static int stg_lun_init __P((struct stg_softc *, struct targ_info *, struct lun_info *));
+static int stg_targ_init __P((struct stg_softc *, struct targ_info *));
static __inline void stghw_bcr_write_1 __P((struct stg_softc *, u_int8_t));
-static void settimeout __P((void *));
struct scsi_low_funcs stgfuncs = {
SC_LOW_INIT_T stg_world_start,
SC_LOW_BUSRST_T stghw_bus_reset,
- SC_LOW_LUN_INIT_T stg_lun_init,
+ SC_LOW_TARG_INIT_T stg_targ_init,
SC_LOW_SELECT_T stghw_start_selection,
SC_LOW_NEXUS_T stg_nexus,
@@ -271,16 +274,22 @@ stg_world_start(sc, fdone)
{
struct scsi_low_softc *slp = &sc->sc_sclow;
int error;
+#ifdef __FreeBSD__
intrmask_t s;
+#endif
if ((error = stghw_check(sc)) != 0)
return error;
+#ifdef __FreeBSD__
s = splcam();
+#endif
stghw_init(sc);
scsi_low_bus_reset(slp);
stghw_init(sc);
+#ifdef __FreeBSD__
splx(s);
+#endif
SOFT_INTR_REQUIRED(slp);
return 0;
@@ -292,29 +301,28 @@ stg_msg(sc, ti, msg)
struct targ_info *ti;
u_int msg;
{
- struct lun_info *li = ti->ti_li;
- struct stg_lun_info *sli = (void *) li;
+ struct stg_targ_info *sti = (void *) ti;
u_int period, offset;
if (msg != SCSI_LOW_MSG_SYNCH)
return EINVAL;
- period = li->li_maxsynch.period;
- offset = li->li_maxsynch.offset;
+ period = ti->ti_maxsynch.period;
+ offset = ti->ti_maxsynch.offset;
period = period << 2;
if (period >= 200)
{
- sli->sli_reg_synch = (period - 200) / 50;
+ sti->sti_reg_synch = (period - 200) / 50;
if (period % 50)
- sli->sli_reg_synch ++;
- sli->sli_reg_synch |= SSCTL_SYNCHEN;
+ sti->sti_reg_synch ++;
+ sti->sti_reg_synch |= SSCTL_SYNCHEN;
}
else if (period >= 100)
{
- sli->sli_reg_synch = (period - 100) / 50;
+ sti->sti_reg_synch = (period - 100) / 50;
if (period % 50)
- sli->sli_reg_synch ++;
- sli->sli_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN;
+ sti->sti_reg_synch ++;
+ sti->sti_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN;
}
return 0;
}
@@ -391,16 +399,15 @@ stghw_init(sc)
}
static int
-stg_lun_init(sc, ti, li)
+stg_targ_init(sc, ti)
struct stg_softc *sc;
struct targ_info *ti;
- struct lun_info *li;
{
- struct stg_lun_info *sli = (void *) li;
+ struct stg_targ_info *sti = (void *) ti;
- li->li_maxsynch.period = 0;
- li->li_maxsynch.offset = 8;
- sli->sli_reg_synch = 0;
+ ti->ti_maxsynch.period = 0;
+ ti->ti_maxsynch.offset = 8;
+ sti->sti_reg_synch = 0;
return 0;
}
@@ -449,6 +456,11 @@ stgattachsubr(sc)
printf("\n");
+#ifdef __FreeBSD__
+ sc->sc_wc = 0x2000 * 2000; /* XXX need calibration */
+#else
+ sc->sc_wc = delaycount * 2000; /* 2 sec */
+#endif
sc->sc_idbit = (1 << slp->sl_hostid);
slp->sl_funcs = &stgfuncs;
@@ -461,7 +473,7 @@ stgattachsubr(sc)
}
(void) scsi_low_attach(slp, 2, STG_NTARGETS, STG_NLUNS,
- sizeof(struct stg_lun_info));
+ sizeof(struct stg_targ_info));
}
/**************************************************************
@@ -531,23 +543,14 @@ stg_pio_read(sc, ti)
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
struct sc_p *sp = &slp->sl_scp;
- int s;
- int tout = 0;
-#ifdef __FreeBSD__
- struct callout_handle ch;
-#endif
+ int tout = sc->sc_wc;
u_int res;
u_int8_t stat;
bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_FIFOEN);
slp->sl_flags |= HW_PDMASTART;
-#ifdef __FreeBSD__
- ch = timeout(settimeout, &tout, 2 * hz);
-#else
- timeout(settimeout, &tout, 2 * hz);
-#endif
- while (sp->scp_datalen > 0 && tout == 0)
+ while (sp->scp_datalen > 0 && tout -- > 0)
{
res = bus_space_read_2(iot, ioh, tmc_fdcnt);
if (res == 0)
@@ -578,18 +581,8 @@ stg_pio_read(sc, ti)
sp->scp_data += res;
}
- s = splhigh();
- if (tout == 0) {
-#ifdef __FreeBSD__
- untimeout(settimeout, &tout, ch);
-#else
- untimeout(settimeout, &tout);
-#endif
- splx(s);
- } else {
- splx(s);
+ if (tout <= 0)
printf("%s pio read timeout\n", slp->sl_xname);
- }
}
#define WFIFO_CRIT 0x100
@@ -604,24 +597,15 @@ stg_pio_write(sc, ti)
bus_space_handle_t ioh = sc->sc_ioh;
struct sc_p *sp = &slp->sl_scp;
u_int res;
- int s;
- int tout = 0;
+ int tout = sc->sc_wc;
register u_int8_t stat;
-#ifdef __FreeBSD__
- struct callout_handle ch;
-#endif
stat = sc->sc_fcWinit | FCTL_FIFOEN | FCTL_FIFOW;
bus_space_write_1(iot, ioh, tmc_fctl, stat | FCTL_CLRFIFO);
bus_space_write_1(iot, ioh, tmc_fctl, stat);
slp->sl_flags |= HW_PDMASTART;
-#ifdef __FreeBSD__
- ch = timeout(settimeout, &tout, 2 * hz);
-#else
- timeout(settimeout, &tout, 2 * hz);
-#endif
- while (sp->scp_datalen > 0 && tout == 0)
+ while (sp->scp_datalen > 0 && tout -- > 0)
{
stat = bus_space_read_1(iot, ioh, tmc_bstat);
if ((stat & BSTAT_PHMASK) != 0)
@@ -645,18 +629,8 @@ stg_pio_write(sc, ti)
sp->scp_data += res;
}
- s = splhigh();
- if (tout == 0) {
-#ifdef __FreeBSD__
- untimeout(settimeout, &tout, ch);
-#else
- untimeout(settimeout, &tout);
-#endif
- splx(s);
- } else {
- splx(s);
+ if (tout <= 0)
printf("%s pio write timeout\n", slp->sl_xname);
- }
}
static int
@@ -668,61 +642,25 @@ stg_negate_signal(sc, mask, s)
struct scsi_low_softc *slp = &sc->sc_sclow;
bus_space_tag_t bst = sc->sc_iot;
bus_space_handle_t bsh = sc->sc_ioh;
- int ss;
- int tout = 0;
-#ifdef __FreeBSD__
- struct callout_handle ch;
-#endif
+ int wc = (sc->sc_wc >> 2);
u_int8_t regv;
-#ifdef __FreeBSD__
- ch = timeout(settimeout, &tout, 2 * hz);
-#else
- timeout(settimeout, &tout, 2 * hz);
-#endif
do
{
regv = bus_space_read_1(bst, bsh, tmc_bstat);
- if (regv == 0xff) {
- ss = splhigh();
- if (tout == 0) {
-#ifdef __FreeBSD__
- untimeout(settimeout, &tout, ch);
-#else
- untimeout(settimeout, &tout);
-#endif
- }
- splx(ss);
+ if (regv == 0xff)
return EIO;
- }
}
- while ((regv & mask) != 0 && tout == 0);
+ while ((regv & mask) != 0 && (-- wc) > 0);
- ss = splhigh();
- if (tout == 0) {
-#ifdef __FreeBSD__
- untimeout(settimeout, &tout, ch);
-#else
- untimeout(settimeout, &tout);
-#endif
- splx(ss);
- } else {
- splx(ss);
+ if (wc <= 0)
+ {
printf("%s: %s singal off timeout \n", slp->sl_xname, s);
return EIO;
}
return 0;
}
-static void
-settimeout(arg)
- void *arg;
-{
- int *tout = arg;
-
- *tout = 1;
-}
-
static int
stg_expect_signal(sc, phase, mask)
struct stg_softc *sc;
@@ -731,20 +669,11 @@ stg_expect_signal(sc, phase, mask)
struct scsi_low_softc *slp = &sc->sc_sclow;
bus_space_tag_t bst = sc->sc_iot;
bus_space_handle_t bsh = sc->sc_ioh;
+ int wc = (sc->sc_wc >> 2);
int rv = -1;
- int s;
- int tout = 0;
-#ifdef __FreeBSD__
- struct callout_handle ch;
-#endif
u_int8_t ph;
phase &= BSTAT_PHMASK;
-#ifdef __FreeBSD__
- ch = timeout(settimeout, &tout, hz/2);
-#else
- timeout(settimeout, &tout, hz/2);
-#endif
do
{
ph = bus_space_read_1(bst, bsh, tmc_bstat);
@@ -761,18 +690,9 @@ stg_expect_signal(sc, phase, mask)
break;
}
}
- while (tout == 0);
+ while (wc -- > 0);
- s = splhigh();
- if (tout == 0) {
-#ifdef __FreeBSD__
- untimeout(settimeout, &tout, ch);
-#else
- untimeout(settimeout, &tout);
-#endif
- splx(s);
- } else {
- splx(s);
+ if (wc <= 0) {
printf("%s: stg_expect_signal timeout\n", slp->sl_xname);
rv = -1;
}
@@ -907,14 +827,14 @@ stg_nexus(sc, ti)
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
struct lun_info *li = ti->ti_li;
- struct stg_lun_info *sli = (void *) ti->ti_li;
+ struct stg_targ_info *sti = (void *) ti;
if (li->li_flags & SCSI_LOW_NOPARITY)
sc->sc_fcRinit &= ~FCTL_PARENB;
else
sc->sc_fcRinit |= FCTL_PARENB;
- bus_space_write_1(iot, ioh, tmc_ssctl, sli->sli_reg_synch);
+ bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch);
return 0;
}
diff --git a/sys/dev/stg/tmc18c30var.h b/sys/dev/stg/tmc18c30var.h
index 46cc986..0940fc7 100644
--- a/sys/dev/stg/tmc18c30var.h
+++ b/sys/dev/stg/tmc18c30var.h
@@ -50,6 +50,8 @@ struct stg_softc {
void *sc_ih;
+ int sc_wc; /* weight counter */
+
u_int sc_chip; /* chip type */
u_int sc_fsz; /* fifo size */
u_int sc_idbit; /* host id bit */
@@ -75,12 +77,12 @@ struct stg_softc {
};
/*****************************************************************
- * Lun information
+ * Target information
*****************************************************************/
-struct stg_lun_info {
- struct lun_info sli_li; /* generic data */
+struct stg_targ_info {
+ struct targ_info sti_ti; /* generic data */
- u_int8_t sli_reg_synch; /* synch register per lun */
+ u_int8_t sti_reg_synch; /* synch register per target */
};
/*****************************************************************
OpenPOWER on IntegriCloud