- Use MI ADAPTER_REQ_SET_XFER_MODE callback.
- Nuke some magic numbers.
This commit is contained in:
parent
1dae310858
commit
689089f7a9
126
sys/dev/ic/iha.c
126
sys/dev/ic/iha.c
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: iha.c,v 1.12 2001/11/17 21:26:12 tsutsui Exp $ */
|
/* $NetBSD: iha.c,v 1.13 2001/11/18 14:33:10 tsutsui Exp $ */
|
||||||
/*
|
/*
|
||||||
* Initio INI-9xxxU/UW SCSI Device Driver
|
* Initio INI-9xxxU/UW SCSI Device Driver
|
||||||
*
|
*
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: iha.c,v 1.12 2001/11/17 21:26:12 tsutsui Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: iha.c,v 1.13 2001/11/18 14:33:10 tsutsui Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
|
@ -74,7 +74,7 @@ __KERNEL_RCSID(0, "$NetBSD: iha.c,v 1.12 2001/11/17 21:26:12 tsutsui Exp $");
|
||||||
* SCSI Rate Table, indexed by FLAG_SCSI_RATE field of
|
* SCSI Rate Table, indexed by FLAG_SCSI_RATE field of
|
||||||
* tcs flags.
|
* tcs flags.
|
||||||
*/
|
*/
|
||||||
static const u_int8_t iha_rate_tbl[8] = {
|
static const u_int8_t iha_rate_tbl[] = {
|
||||||
/* fast 20 */
|
/* fast 20 */
|
||||||
/* nanosecond divide by 4 */
|
/* nanosecond divide by 4 */
|
||||||
12, /* 50ns, 20M */
|
12, /* 50ns, 20M */
|
||||||
|
@ -86,6 +86,7 @@ static const u_int8_t iha_rate_tbl[8] = {
|
||||||
50, /* 200ns, 5M */
|
50, /* 200ns, 5M */
|
||||||
62 /* 250ns, 4M */
|
62 /* 250ns, 4M */
|
||||||
};
|
};
|
||||||
|
#define IHA_MAX_PERIOD 62
|
||||||
|
|
||||||
#ifdef notused
|
#ifdef notused
|
||||||
static u_int16_t eeprom_default[EEPROM_SIZE] = {
|
static u_int16_t eeprom_default[EEPROM_SIZE] = {
|
||||||
|
@ -228,6 +229,7 @@ static void iha_abort_xs(struct iha_softc *, struct scsipi_xfer *, u_int8_t);
|
||||||
|
|
||||||
void iha_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t,
|
void iha_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
void iha_update_xfer_mode(struct iha_softc *, int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* iha_intr - the interrupt service routine for the iha driver
|
* iha_intr - the interrupt service routine for the iha driver
|
||||||
|
@ -352,7 +354,30 @@ iha_scsipi_request(chan, req, arg)
|
||||||
return; /* XXX */
|
return; /* XXX */
|
||||||
|
|
||||||
case ADAPTER_REQ_SET_XFER_MODE:
|
case ADAPTER_REQ_SET_XFER_MODE:
|
||||||
return; /* XXX */
|
{
|
||||||
|
struct tcs *tcs;
|
||||||
|
struct scsipi_xfer_mode *xm = arg;
|
||||||
|
|
||||||
|
tcs = &sc->sc_tcs[xm->xm_target];
|
||||||
|
|
||||||
|
if ((xm->xm_mode & PERIPH_CAP_WIDE16) != 0 &&
|
||||||
|
(tcs->flags & FLAG_NO_WIDE) == 0)
|
||||||
|
tcs->flags &= ~(FLAG_WIDE_DONE|FLAG_SYNC_DONE);
|
||||||
|
|
||||||
|
if ((xm->xm_mode & PERIPH_CAP_SYNC) != 0 &&
|
||||||
|
(tcs->flags & FLAG_NO_SYNC) == 0)
|
||||||
|
tcs->flags &= ~FLAG_SYNC_DONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we're not going to negotiate, send the
|
||||||
|
* notification now, since it won't happen later.
|
||||||
|
*/
|
||||||
|
if ((tcs->flags & (FLAG_WIDE_DONE|FLAG_SYNC_DONE)) ==
|
||||||
|
(FLAG_WIDE_DONE|FLAG_SYNC_DONE))
|
||||||
|
iha_update_xfer_mode(sc, xm->xm_target);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1997,13 +2022,16 @@ iha_msgin_extended(sc)
|
||||||
flags = sc->sc_actscb->tcs->flags;
|
flags = sc->sc_actscb->tcs->flags;
|
||||||
|
|
||||||
if ((flags & FLAG_NO_WIDE) != 0)
|
if ((flags & FLAG_NO_WIDE) != 0)
|
||||||
sc->sc_msg[2] = 0; /* Offer async xfers only */
|
/* Offer 8bit xfers only */
|
||||||
|
sc->sc_msg[2] = MSG_EXT_WDTR_BUS_8_BIT;
|
||||||
|
|
||||||
else if (sc->sc_msg[2] > 2) /* BAD MSG: 2 is max value */
|
else if (sc->sc_msg[2] > MSG_EXT_WDTR_BUS_32_BIT)
|
||||||
|
/* BAD MSG */
|
||||||
return (iha_msgout_reject(sc));
|
return (iha_msgout_reject(sc));
|
||||||
|
|
||||||
else if (sc->sc_msg[2] == 2) /* a request for 32 bit xfers*/
|
else if (sc->sc_msg[2] == MSG_EXT_WDTR_BUS_32_BIT)
|
||||||
sc->sc_msg[2] = 1; /* Offer 16 instead */
|
/* Offer 16bit instead */
|
||||||
|
sc->sc_msg[2] = MSG_EXT_WDTR_BUS_16_BIT;
|
||||||
|
|
||||||
else {
|
else {
|
||||||
iha_wide_done(sc);
|
iha_wide_done(sc);
|
||||||
|
@ -2041,29 +2069,31 @@ iha_msgin_sdtr(sc)
|
||||||
|
|
||||||
default_period = iha_rate_tbl[flags & FLAG_SCSI_RATE];
|
default_period = iha_rate_tbl[flags & FLAG_SCSI_RATE];
|
||||||
|
|
||||||
if (sc->sc_msg[3] == 0) /* target offered async only. Accept it. */
|
if (sc->sc_msg[3] == 0)
|
||||||
|
/* target offered async only. Accept it. */
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
newoffer = 0;
|
newoffer = 0;
|
||||||
|
|
||||||
if ((flags & FLAG_NO_SYNC) != 0) {
|
if ((flags & FLAG_NO_SYNC) != 0) {
|
||||||
sc->sc_msg[3] = 0;
|
sc->sc_msg[3] = 0;
|
||||||
newoffer = 1;
|
newoffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_msg[3] > IHA_MAX_OFFSET) {
|
if (sc->sc_msg[3] > IHA_MAX_OFFSET) {
|
||||||
sc->sc_msg[3] = IHA_MAX_OFFSET;
|
sc->sc_msg[3] = IHA_MAX_OFFSET;
|
||||||
newoffer = 1;
|
newoffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_msg[2] < default_period) {
|
if (sc->sc_msg[2] < default_period) {
|
||||||
sc->sc_msg[2] = default_period;
|
sc->sc_msg[2] = default_period;
|
||||||
newoffer = 1;
|
newoffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc->sc_msg[2] >= 59) { /* XXX magic */
|
if (sc->sc_msg[2] > IHA_MAX_PERIOD) {
|
||||||
|
/* Use async */
|
||||||
sc->sc_msg[3] = 0;
|
sc->sc_msg[3] = 0;
|
||||||
newoffer = 1;
|
newoffer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (newoffer);
|
return (newoffer);
|
||||||
|
@ -2156,13 +2186,13 @@ static int
|
||||||
iha_msgout_sdtr(sc)
|
iha_msgout_sdtr(sc)
|
||||||
struct iha_softc *sc;
|
struct iha_softc *sc;
|
||||||
{
|
{
|
||||||
int rateindex;
|
struct tcs *tcs = sc->sc_actscb->tcs;
|
||||||
|
|
||||||
rateindex = sc->sc_actscb->tcs->flags & FLAG_SCSI_RATE;
|
tcs->flags |= FLAG_SYNC_DONE;
|
||||||
|
|
||||||
sc->sc_msg[0] = MSG_EXT_SDTR_LEN;
|
sc->sc_msg[0] = MSG_EXT_SDTR_LEN;
|
||||||
sc->sc_msg[1] = MSG_EXT_SDTR;
|
sc->sc_msg[1] = MSG_EXT_SDTR;
|
||||||
sc->sc_msg[2] = iha_rate_tbl[rateindex];
|
sc->sc_msg[2] = iha_rate_tbl[tcs->flags & FLAG_SCSI_RATE];
|
||||||
sc->sc_msg[3] = IHA_MAX_OFFSET; /* REQ/ACK */
|
sc->sc_msg[3] = IHA_MAX_OFFSET; /* REQ/ACK */
|
||||||
|
|
||||||
return (iha_msgout_extended(sc));
|
return (iha_msgout_extended(sc));
|
||||||
|
@ -2187,6 +2217,8 @@ iha_wide_done(sc)
|
||||||
tcs->flags &= ~FLAG_SYNC_DONE;
|
tcs->flags &= ~FLAG_SYNC_DONE;
|
||||||
tcs->flags |= FLAG_WIDE_DONE;
|
tcs->flags |= FLAG_WIDE_DONE;
|
||||||
|
|
||||||
|
iha_update_xfer_mode(sc, sc->sc_actscb->target);
|
||||||
|
|
||||||
bus_space_write_1(iot, ioh, TUL_SCONFIG0, tcs->sconfig0);
|
bus_space_write_1(iot, ioh, TUL_SCONFIG0, tcs->sconfig0);
|
||||||
bus_space_write_1(iot, ioh, TUL_SYNCM, tcs->syncm);
|
bus_space_write_1(iot, ioh, TUL_SYNCM, tcs->syncm);
|
||||||
}
|
}
|
||||||
|
@ -2200,26 +2232,26 @@ iha_sync_done(sc)
|
||||||
struct tcs *tcs = sc->sc_actscb->tcs;
|
struct tcs *tcs = sc->sc_actscb->tcs;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((tcs->flags & FLAG_SYNC_DONE) == 0) {
|
tcs->period = sc->sc_msg[2];
|
||||||
tcs->period = sc->sc_msg[2];
|
tcs->offset = sc->sc_msg[3];
|
||||||
tcs->offset = sc->sc_msg[3];
|
if (tcs->offset != 0) {
|
||||||
if (tcs->offset != 0) {
|
tcs->syncm |= tcs->offset;
|
||||||
tcs->syncm |= tcs->offset;
|
|
||||||
|
|
||||||
/* pick the highest possible rate */
|
/* pick the highest possible rate */
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < sizeof(iha_rate_tbl); i++)
|
||||||
if (iha_rate_tbl[i] >= tcs->period)
|
if (iha_rate_tbl[i] >= tcs->period)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tcs->syncm |= (i << 4);
|
tcs->syncm |= (i << 4);
|
||||||
tcs->sconfig0 |= ALTPD;
|
tcs->sconfig0 |= ALTPD;
|
||||||
}
|
|
||||||
|
|
||||||
tcs->flags |= FLAG_SYNC_DONE;
|
|
||||||
|
|
||||||
bus_space_write_1(iot, ioh, TUL_SCONFIG0, tcs->sconfig0);
|
|
||||||
bus_space_write_1(iot, ioh, TUL_SYNCM, tcs->syncm);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcs->flags |= FLAG_SYNC_DONE;
|
||||||
|
|
||||||
|
iha_update_xfer_mode(sc, sc->sc_actscb->target);
|
||||||
|
|
||||||
|
bus_space_write_1(iot, ioh, TUL_SCONFIG0, tcs->sconfig0);
|
||||||
|
bus_space_write_1(iot, ioh, TUL_SYNCM, tcs->syncm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2850,3 +2882,29 @@ iha_reset_tcs(tcs, config0)
|
||||||
tcs->syncm = 0;
|
tcs->syncm = 0;
|
||||||
tcs->sconfig0 = config0;
|
tcs->sconfig0 = config0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
iha_update_xfer_mode(sc, target)
|
||||||
|
struct iha_softc *sc;
|
||||||
|
int target;
|
||||||
|
{
|
||||||
|
struct tcs *tcs = &sc->sc_tcs[target];
|
||||||
|
struct scsipi_xfer_mode xm;
|
||||||
|
|
||||||
|
xm.xm_target = target;
|
||||||
|
xm.xm_mode = 0;
|
||||||
|
xm.xm_period = 0;
|
||||||
|
xm.xm_offset = 0;
|
||||||
|
|
||||||
|
if (tcs->syncm & PERIOD_WIDE_SCSI)
|
||||||
|
xm.xm_mode |= PERIPH_CAP_WIDE16;
|
||||||
|
|
||||||
|
if (tcs->period) {
|
||||||
|
xm.xm_mode |= PERIPH_CAP_SYNC;
|
||||||
|
xm.xm_period = tcs->period;
|
||||||
|
xm.xm_offset = tcs->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
scsipi_async_event(&sc->sc_channel, ASYNC_EVENT_XFER_MODE, &xm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue