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
This commit is contained in:
Noriaki Mitsunaga 2001-02-25 12:40:30 +00:00
parent 7a6ac3e087
commit a4539b3e56
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=73025
8 changed files with 247 additions and 443 deletions

View File

@ -59,8 +59,10 @@
#ifdef __NetBSD__
#include <sys/disklabel.h>
#endif
#if defined(__FreeBSD__) && __FreeBSD_version >= 500001
#ifdef __FreeBSD__
#if __FreeBSD_version >= 500001
#include <sys/bio.h>
#endif
#include <sys/devicestat.h>
#endif
#include <sys/buf.h>
@ -94,6 +96,7 @@
#include <cam/cam_periph.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_low.h>
@ -126,7 +129,7 @@ static struct slccb *scsi_low_establish_ccb __P((struct targ_info *, struct lun_
static int scsi_low_done __P((struct scsi_low_softc *, struct slccb *));
static void scsi_low_twiddle_wait __P((void));
static struct lun_info *scsi_low_alloc_li __P((struct targ_info *, int, int));
static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int));
static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int, int));
static void scsi_low_calcf __P((struct targ_info *, struct lun_info *));
static struct lun_info *scsi_low_establish_lun __P((struct targ_info *, int));
#ifndef CAM
@ -227,7 +230,6 @@ scsi_low_alloc_li(ti, lun, alloc)
int lun;
int alloc;
{
struct scsi_low_softc *slp = ti->ti_sc;
struct lun_info *li;
li = LIST_FIRST(&ti->ti_litab);
@ -250,11 +252,11 @@ scsi_low_alloc_li(ti, lun, alloc)
if (alloc == 0)
return li;
li = malloc(ti->ti_lunsize, M_DEVBUF, M_NOWAIT);
li = malloc(sizeof(struct lun_info), M_DEVBUF, M_NOWAIT);
if (li == NULL)
panic("no lun info mem\n");
memset(li, 0, ti->ti_lunsize);
memset(li, 0, sizeof(struct lun_info));
li->li_lun = lun;
li->li_ti = ti;
#if defined(SDEV_NOPARITY) && defined(SDEV_NODISC)
@ -264,9 +266,6 @@ scsi_low_alloc_li(ti, lun, alloc)
LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
/* host specific structure initialization per lun */
(void) ((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li));
return li;
}
@ -274,20 +273,20 @@ scsi_low_alloc_li(ti, lun, alloc)
* allocate targ_info
**************************************************************/
static struct targ_info *
scsi_low_alloc_ti(slp, targ)
scsi_low_alloc_ti(slp, targ, targ_size)
struct scsi_low_softc *slp;
int targ;
int targ, targ_size;
{
struct targ_info *ti;
if (TAILQ_FIRST(&slp->sl_titab) == NULL)
TAILQ_INIT(&slp->sl_titab);
ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT);
ti = malloc(targ_size, M_DEVBUF, M_NOWAIT);
if (ti == NULL)
panic("%s short of memory\n", slp->sl_xname);
memset(ti, 0, sizeof(struct targ_info));
memset(ti, 0, targ_size);
ti->ti_id = targ;
ti->ti_sc = slp;
@ -296,6 +295,9 @@ scsi_low_alloc_ti(slp, targ)
TAILQ_INIT(&ti->ti_discq);
LIST_INIT(&ti->ti_litab);
/* host specific structure initialization per target */
(void) ((*slp->sl_funcs->scsi_low_targ_init) (slp, ti));
return ti;
}
@ -463,9 +465,9 @@ scsi_low_rescan_bus(struct scsi_low_softc *slp)
#endif
int
scsi_low_attach(slp, openings, ntargs, nluns, lunsize)
scsi_low_attach(slp, openings, ntargs, nluns, targ_size)
struct scsi_low_softc *slp;
int openings, ntargs, nluns, lunsize;
int openings, ntargs, nluns, targ_size;
{
struct targ_info *ti;
struct lun_info *li;
@ -488,13 +490,12 @@ scsi_low_attach(slp, openings, ntargs, nluns, lunsize)
printf("change kernel options SCSI_LOW_NTARGETS");
}
if (lunsize < sizeof(struct lun_info))
lunsize = sizeof(struct lun_info);
if (targ_size < sizeof(struct targ_info))
targ_size = sizeof(struct targ_info);
for (i = 0; i < ntargs; i ++)
{
ti = scsi_low_alloc_ti(slp, i);
ti->ti_lunsize = lunsize;
ti = scsi_low_alloc_ti(slp, i, targ_size);
li = scsi_low_alloc_li(ti, 0, 1);
}
@ -641,11 +642,12 @@ scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb)
struct slccb *cb;
#if 0
printf("scsi_low_scsi_action() func code %d Target: %d, LUN: %d\n",
printf("scsi_low_scsi_action() func code 0x%x Target: %d, LUN: %d\n",
ccb->ccb_h.func_code, target, ccb->ccb_h.target_lun);
#endif
switch (ccb->ccb_h.func_code) {
case XPT_SCSI_IO: /* Execute the requested I/O operation */
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
if (((cb = scsi_low_get_ccb()) == NULL)) {
ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
xpt_done(ccb);
@ -670,7 +672,6 @@ scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb)
splx(s);
break;
case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
case XPT_EN_LUN: /* Enable LUN as a target */
case XPT_TARGET_IO: /* Execute target I/O request */
case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
@ -693,12 +694,12 @@ scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb)
cts = &ccb->cts;
ti = slp->sl_ti[ccb->ccb_h.target_id];
s = splcam();
li = LIST_FIRST(&ti->ti_litab);
if (li != NULL && li->li_lun != lun)
while ((li = LIST_NEXT(li, lun_chain)) != NULL)
if (li->li_lun == lun)
break;
s = splcam();
if (li != NULL && (cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
if (li->li_cfgflags & SCSI_LOW_DISC)
cts->flags = CCB_TRANS_DISC_ENB;
@ -707,7 +708,9 @@ scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb)
if (li->li_cfgflags & SCSI_LOW_QTAG)
cts->flags |= CCB_TRANS_TAG_ENB;
cts->bus_width = 0;/*HN2*/
cts->sync_period = ti->ti_maxsynch.period;
cts->sync_offset = ti->ti_maxsynch.offset;
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
cts->valid = CCB_TRANS_SYNC_RATE_VALID
| CCB_TRANS_SYNC_OFFSET_VALID
@ -979,12 +982,10 @@ scsi_low_start(slp)
if ((cb->ccb_flags & CCB_SENSE) != 0)
{
memset(&cb->ccb_sense, 0, sizeof(cb->ccb_sense));
#ifdef CAM
#else
memset(&cb->ccb_sense_cmd, 0, sizeof(cb->ccb_sense_cmd));
cb->ccb_sense_cmd.opcode = REQUEST_SENSE;
cb->ccb_sense_cmd.byte2 = (li->li_lun << 5);
cb->ccb_sense_cmd.length = sizeof(cb->ccb_sense);
#endif
cb->ccb_scp.scp_cmd = (u_int8_t *) &cb->ccb_sense_cmd;
cb->ccb_scp.scp_cmdlen = sizeof(cb->ccb_sense_cmd);
cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
@ -1030,7 +1031,7 @@ scsi_low_start(slp)
break;
case UNIT_SYNCH:
if (li->li_maxsynch.offset > 0)
if (ti->ti_maxsynch.offset > 0)
{
scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
scsi_low_unit_ready_cmd(cb);
@ -1040,7 +1041,7 @@ scsi_low_start(slp)
case UNIT_WIDE:
#ifdef SCSI_LOW_SUPPORT_WIDE
if (li->li_width > 0)
if (ti->ti_width > 0)
{
scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
scsi_low_unit_ready_cmd(cb);
@ -1128,10 +1129,11 @@ scsi_low_done(slp, cb)
{
cb->ccb_flags &= ~CCB_SENSE;
#ifdef CAM
ccb->csio.sense_data = cb->ccb_sense;
/* ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; */
ccb->ccb_h.status = CAM_REQ_CMP;
/* ccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR; */
memcpy(&ccb->csio.sense_data,
&cb->ccb_sense,
sizeof(ccb->csio.sense_data));
ccb->ccb_h.status = CAM_AUTOSNS_VALID
| CAM_REQ_CMP_ERR;
#else
xs->sense.scsi_sense = cb->ccb_sense;
xs->error = XS_SENSE;
@ -1153,7 +1155,7 @@ scsi_low_done(slp, cb)
#define SCSIPI_SCSI_CD_COMPLETELY_BUGGY "YES"
#ifdef SCSIPI_SCSI_CD_COMPLETELY_BUGGY
#ifdef CAM
if (/* cb->bp == NULL && */
if (cb->bp == NULL &&
slp->sl_scp.scp_datalen < cb->ccb_scp.scp_datalen)
#else
if (xs->bp == NULL &&
@ -1171,7 +1173,7 @@ scsi_low_done(slp, cb)
cb->ccb_error |= PDMAERR;
#ifdef CAM
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
#else
xs->error = XS_DRIVER_STUFFUP;
#endif
@ -1179,18 +1181,23 @@ scsi_low_done(slp, cb)
case ST_CHKCOND:
case ST_MET:
cb->ccb_flags |= CCB_SENSE;
#ifdef CAM
ccb->ccb_h.status = CAM_AUTOSENSE_FAIL;
if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
cb->ccb_flags |= CCB_SENSE;
goto retry;
}
ccb->ccb_h.status = CAM_AUTOSENSE_FAIL | CAM_REQ_CMP_ERR;
break;
#else
cb->ccb_flags |= CCB_SENSE;
xs->error = XS_SENSE;
#endif
goto retry;
#endif
case ST_BUSY:
cb->ccb_error |= BUSYERR;
#ifdef CAM
ccb->ccb_h.status = CAM_BUSY; /* SCSI_STATUS_ERROR; */
ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
#else
xs->error = XS_BUSY;
#endif
@ -1199,7 +1206,7 @@ scsi_low_done(slp, cb)
default:
cb->ccb_error |= FATALIO;
#ifdef CAM
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
#else
xs->error = XS_DRIVER_STUFFUP;
#endif
@ -1223,7 +1230,7 @@ scsi_low_done(slp, cb)
else
{
#ifdef CAM
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
ccb->ccb_h.status = CAM_UNREC_HBA_ERROR;
#else
xs->error = XS_DRIVER_STUFFUP;
#endif
@ -1257,11 +1264,9 @@ scsi_low_done(slp, cb)
}
else
{
#if 0
if (ccb->ccb_h.status != CAM_AUTOSENSE_FAIL &&
if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID == 0) &&
cb->ccb_rcnt < slp->sl_max_retry)
goto retry;
#endif
#else
if (xs->error == XS_NOERROR)
{
@ -1274,19 +1279,23 @@ scsi_low_done(slp, cb)
goto retry;
#endif
#ifndef CAM
#ifdef SCSI_LOW_WARNINGS
#ifdef CAM
if (cb->bp != NULL)
#else
if (xs->bp != NULL)
#endif
{
scsi_low_print(slp, ti);
printf("%s: WARNING: File system IO abort\n",
slp->sl_xname);
}
#endif /* SCSI_LOW_WARNINGS */
#endif
}
#ifdef CAM
if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
ccb->csio.scsi_status = ti->ti_status;
xpt_done(ccb);
#else
@ -1363,7 +1372,7 @@ scsi_low_reset_nexus(slp, fdone)
{
li->li_state = UNIT_SLEEP;
li->li_disc = 0;
((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li));
((*slp->sl_funcs->scsi_low_targ_init) (slp, ti));
scsi_low_calcf(ti, li);
}
@ -1650,7 +1659,7 @@ scsi_low_data(slp, ti, bp, direction)
}
#ifdef CAM
*bp = NULL; /* (cb->ccb == NULL) ? NULL : cb->bp; */
*bp = (cb == NULL) ? NULL : cb->bp;
#else
*bp = (cb->xs == NULL) ? NULL : cb->xs->bp;
#endif
@ -1796,8 +1805,8 @@ scsi_low_msgfunc_synch(ti)
ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND;
ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
ti->ti_msgoutstr[ptr + 3] = li->li_maxsynch.period;
ti->ti_msgoutstr[ptr + 4] = li->li_maxsynch.offset;
ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
return MSG_EXTEND_SYNCHLEN + 2;
}
@ -1817,7 +1826,7 @@ scsi_low_msgfunc_wide(ti)
ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND;
ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
ti->ti_msgoutstr[ptr + 3] = li->li_width;
ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
return MSG_EXTEND_WIDELEN + 2;
}
@ -1911,9 +1920,7 @@ scsi_low_errfunc_wide(ti, msgflags)
struct targ_info *ti;
u_int msgflags;
{
struct lun_info *li = ti->ti_li;
li->li_width = 0;
ti->ti_width = 0;
return 0;
}
@ -2085,8 +2092,8 @@ scsi_low_synch(ti)
u_char *s;
int error;
if (MSGIN_PERIOD(ti) >= li->li_maxsynch.period &&
MSGIN_OFFSET(ti) <= li->li_maxsynch.offset)
if (MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset)
{
if ((offset = MSGIN_OFFSET(ti)) != 0)
period = MSGIN_PERIOD(ti);
@ -2098,15 +2105,15 @@ scsi_low_synch(ti)
* Target seems to be brain damaged.
* Force async transfer.
*/
li->li_maxsynch.period = 0;
li->li_maxsynch.offset = 0;
ti->ti_maxsynch.period = 0;
ti->ti_maxsynch.offset = 0;
printf("%s: target brain damaged. async transfer\n",
slp->sl_xname);
return EINVAL;
}
li->li_maxsynch.period = period;
li->li_maxsynch.offset = offset;
ti->ti_maxsynch.period = period;
ti->ti_maxsynch.offset = offset;
error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
if (error != 0)
@ -2420,8 +2427,8 @@ scsi_low_calcf(ti, li)
(slp->sl_cfgflags & CFG_ASYNC) == 0)
{
offset = SCSI_LOW_OFFSET(li->li_cfgflags);
if (offset > li->li_maxsynch.offset)
offset = li->li_maxsynch.offset;
if (offset > ti->ti_maxsynch.offset)
offset = ti->ti_maxsynch.offset;
li->li_flags |= SCSI_LOW_SYNC;
}
else
@ -2434,14 +2441,14 @@ scsi_low_calcf(ti, li)
period = SCSI_LOW_MAX_SYNCH_SPEED;
if (period != 0)
period = 1000 * 10 / (period * 4);
if (period < li->li_maxsynch.period)
period = li->li_maxsynch.period;
if (period < ti->ti_maxsynch.period)
period = ti->ti_maxsynch.period;
}
else
period = 0;
li->li_maxsynch.offset = offset;
li->li_maxsynch.period = period;
ti->ti_maxsynch.offset = offset;
ti->ti_maxsynch.period = period;
}
#ifdef SCSI_LOW_TARGET_OPEN
@ -2471,8 +2478,8 @@ scsi_low_target_open(link, cf)
printf("%s(%d:%d): max period(%dns) max offset(%d) flags 0x%b\n",
slp->sl_xname, target, lun,
li->li_maxsynch.period * 4,
li->li_maxsynch.offset,
ti->ti_maxsynch.period * 4,
ti->ti_maxsynch.offset,
li->li_flags, SCSI_LOW_BITS);
return 0;
}

View File

@ -223,16 +223,6 @@ struct lun_info {
u_int li_flags; /* real control flags */
u_int li_cfgflags; /* given target cfgflags */
u_int li_quirks; /* given target quirk */
/*
* lun synch and wide data
*/
struct synch {
u_int8_t offset;
u_int8_t period;
} li_maxsynch; /* synch data */
u_int li_width;
};
struct targ_info {
@ -319,9 +309,14 @@ struct targ_info {
u_int ti_msgoutlen; /* msgout strlen */
/*
* lun info size.
* synch and wide data
*/
int ti_lunsize;
struct synch {
u_int8_t offset;
u_int8_t period;
} ti_maxsynch; /* synch data */
u_int ti_width;
};
/*************************************************
@ -335,7 +330,7 @@ typedef struct scsi_low_softc *sc_low_t;
#define SC_LOW_INIT_T (int (*) __P((sc_low_t, int)))
#define SC_LOW_BUSRST_T (void (*) __P((sc_low_t)))
#define SC_LOW_LUN_INIT_T (int (*) __P((sc_low_t, struct targ_info *, struct lun_info *)))
#define SC_LOW_TARG_INIT_T (int (*) __P((sc_low_t, struct targ_info *)))
#define SC_LOW_SELECT_T (int (*) __P((sc_low_t, struct slccb *)))
#define SC_LOW_ATTEN_T (void (*) __P((sc_low_t)))
#define SC_LOW_NEXUS_T (int (*) __P((sc_low_t, struct targ_info *)))
@ -346,7 +341,7 @@ typedef struct scsi_low_softc *sc_low_t;
struct scsi_low_funcs {
int (*scsi_low_init) __P((sc_low_t, int));
void (*scsi_low_bus_reset) __P((sc_low_t));
int (*scsi_low_lun_init) __P((sc_low_t, struct targ_info *, struct lun_info *));
int (*scsi_low_targ_init) __P((sc_low_t, struct targ_info *));
int (*scsi_low_start_bus) __P((sc_low_t, struct slccb *));
int (*scsi_low_establish_nexus) __P((sc_low_t, struct targ_info *));

View File

@ -128,6 +128,10 @@ extern struct cfdriver ncv_cd;
/**************************************************************
* DECLARE
**************************************************************/
#ifdef __NetBSD__
extern int delaycount;
#endif
/* static */
static void ncv_pio_read __P((struct ncv_softc *, u_int8_t *, u_int));
static void ncv_pio_write __P((struct ncv_softc *, u_int8_t *, u_int));
@ -153,13 +157,12 @@ static int ncv_nexus __P((struct ncv_softc *, struct targ_info *));
#ifdef NCV_POWER_CONTROL
static int ncvhw_power __P((struct ncv_softc *, u_int));
#endif
static int ncv_lun_init __P((struct ncv_softc *, struct targ_info *, struct lun_info *));
static void settimeout __P((void *));
static int ncv_targ_init __P((struct ncv_softc *, struct targ_info *));
struct scsi_low_funcs ncv_funcs = {
SC_LOW_INIT_T ncv_world_start,
SC_LOW_BUSRST_T ncvhw_bus_reset,
SC_LOW_LUN_INIT_T ncv_lun_init,
SC_LOW_TARG_INIT_T ncv_targ_init,
SC_LOW_SELECT_T ncvhw_start_selection,
SC_LOW_NEXUS_T ncv_nexus,
@ -434,18 +437,24 @@ ncv_world_start(sc, fdone)
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
u_int8_t stat;
#ifdef __FreeBSD__
intrmask_t s;
#endif
ncvhw_reset(iot, ioh, &sc->sc_hw);
ncvhw_init(iot, ioh, &sc->sc_hw);
#ifdef __FreeBSD__
s = splcam();
#endif
scsi_low_bus_reset(slp);
ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_stat);
stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat);
#ifdef __FreeBSD__
splx(s);
#endif
delay(1000);
if (((stat & INTR_SBR) == 0) ||
@ -462,41 +471,39 @@ ncv_msg(sc, ti, msg)
struct targ_info *ti;
u_int msg;
{
struct lun_info *li = ti->ti_li;
struct ncv_lun_info *nli = (void *) li;
struct ncv_targ_info *nti = (void *) ti;
u_int hwcycle, period;
if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
return 0;
period = li->li_maxsynch.period;
period = ti->ti_maxsynch.period;
hwcycle = 1000 / ((sc->sc_hw.clk == 0) ? 40 : (5 * sc->sc_hw.clk));
if (period < 200 / 4 && period >= 100 / 4)
nli->nli_reg_cfg3 |= C3_FSCSI;
nti->nti_reg_cfg3 |= C3_FSCSI;
else
nli->nli_reg_cfg3 &= ~C3_FSCSI;
nti->nti_reg_cfg3 &= ~C3_FSCSI;
period = ((period * 40 / hwcycle) + 5) / 10;
nli->nli_reg_period = period & 0x1f;
nli->nli_reg_offset = li->li_maxsynch.offset;
nti->nti_reg_period = period & 0x1f;
nti->nti_reg_offset = ti->ti_maxsynch.offset;
return 0;
}
static int
ncv_lun_init(sc, ti, li)
ncv_targ_init(sc, ti)
struct ncv_softc *sc;
struct targ_info *ti;
struct lun_info *li;
{
struct ncv_lun_info *nli = (void *) li;
struct ncv_targ_info *nti = (void *) ti;
li->li_maxsynch.period = sc->sc_hw.mperiod;
li->li_maxsynch.offset = sc->sc_hw.moffset;
ti->ti_maxsynch.period = sc->sc_hw.mperiod;
ti->ti_maxsynch.offset = sc->sc_hw.moffset;
nli->nli_reg_cfg3 = sc->sc_hw.cfg3;
nli->nli_reg_period = 0;
nli->nli_reg_offset = 0;
nti->nti_reg_cfg3 = sc->sc_hw.cfg3;
nti->nti_reg_period = 0;
nti->nti_reg_offset = 0;
return 0;
}
@ -590,9 +597,14 @@ ncvattachsubr(sc)
printf("\n");
sc->sc_hw = ncv_template;
ncv_setup_img(&sc->sc_hw, slp->sl_cfgflags, slp->sl_hostid);
#ifdef __FreeBSD__
sc->sc_wc = 0x2000 * 2000; /* XXX need calibration */
#else /* NetBSD */
sc->sc_wc = delaycount * 2000; /* 2 sec */
#endif
slp->sl_funcs = &ncv_funcs;
(void) scsi_low_attach(slp, 2, NCV_NTARGETS, NCV_NLUNS,
sizeof(struct ncv_lun_info));
sizeof(struct ncv_targ_info));
}
/**************************************************************
@ -678,12 +690,8 @@ ncv_pio_read(sc, buf, reqlen)
struct scsi_low_softc *slp = &sc->sc_sclow;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
int s;
int tout = 0;
int tout = sc->sc_wc;
register u_int8_t fstat;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
bus_space_write_1(iot, ioh, cr1_pflag, 0);
@ -696,12 +704,7 @@ ncv_pio_read(sc, buf, reqlen)
bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN);
slp->sl_flags |= HW_PDMASTART;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, 2 * hz);
#else
timeout(settimeout, &tout, 2 * hz);
#endif
while (reqlen >= FIFO_F_SZ && tout == 0)
while (reqlen >= FIFO_F_SZ && tout > 0)
{
fstat = bus_space_read_1(iot, ioh, cr1_fstat);
if (fstat & FIFO_F)
@ -721,6 +724,7 @@ ncv_pio_read(sc, buf, reqlen)
else if (fstat & FIFO_BRK)
break;
tout --;
}
if (reqlen >= FIFO_2_SZ)
@ -740,7 +744,7 @@ ncv_pio_read(sc, buf, reqlen)
}
}
while (reqlen > 0 && tout == 0)
while (reqlen > 0 && tout > 0)
{
fstat = bus_space_read_1(iot, ioh, cr1_fstat);
if ((fstat & FIFO_E) == 0)
@ -752,23 +756,14 @@ ncv_pio_read(sc, buf, reqlen)
else if (fstat & FIFO_BRK)
break;
tout --;
}
ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
sc->sc_tdatalen = reqlen;
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);
}
}
static void
@ -780,12 +775,8 @@ ncv_pio_write(sc, buf, reqlen)
struct scsi_low_softc *slp = &sc->sc_sclow;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
int s;
int tout = 0;
int tout = sc->sc_wc;
register u_int8_t fstat;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
ncvhw_select_register_1(iot, ioh, &sc->sc_hw);
bus_space_write_1(iot, ioh, cr1_pflag, 0);
@ -798,12 +789,7 @@ ncv_pio_write(sc, buf, reqlen)
bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN);
slp->sl_flags |= HW_PDMASTART;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, 2 * hz);
#else
timeout(settimeout, &tout, 2 * hz);
#endif
while (reqlen >= FIFO_F_SZ && tout == 0)
while (reqlen >= FIFO_F_SZ && tout > 0)
{
fstat = bus_space_read_1(iot, ioh, cr1_fstat);
if (fstat & FIFO_BRK)
@ -821,9 +807,11 @@ ncv_pio_write(sc, buf, reqlen)
buf += FIFO_F_SZ;
reqlen -= FIFO_F_SZ;
}
else
tout --;
}
while (reqlen > 0 && tout == 0)
while (reqlen > 0 && tout > 0)
{
fstat = bus_space_read_1(iot, ioh, cr1_fstat);
if (fstat & FIFO_BRK)
@ -834,32 +822,15 @@ ncv_pio_write(sc, buf, reqlen)
bus_space_write_1(iot, ioh, cr1_fdata, *buf++);
reqlen --;
}
else
tout --;
}
done:
ncvhw_select_register_0(iot, ioh, &sc->sc_hw);
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 void
settimeout(arg)
void *arg;
{
int *tout = arg;
*tout = 1;
}
/**************************************************************
@ -928,15 +899,15 @@ ncv_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 ncv_lun_info *nli = (void *) li;
struct ncv_targ_info *nti = (void *) ti;
if (li->li_flags & SCSI_LOW_NOPARITY)
bus_space_write_1(iot, ioh, cr0_cfg1, sc->sc_hw.cfg1);
else
bus_space_write_1(iot, ioh, cr0_cfg1, sc->sc_hw.cfg1 | C1_PARENB);
bus_space_write_1(iot, ioh, cr0_period, nli->nli_reg_period);
bus_space_write_1(iot, ioh, cr0_offs, nli->nli_reg_offset);
bus_space_write_1(iot, ioh, cr0_cfg3, nli->nli_reg_cfg3);
bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period);
bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset);
bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3);
return 0;
}

View File

@ -47,6 +47,7 @@ struct ncv_softc {
bus_space_handle_t sc_ioh;
void *sc_ih;
int sc_wc; /* weight counter */
int sc_selstop; /* sel atn stop asserted */
int sc_compseq; /* completion seq cmd asserted */
int sc_tdatalen; /* temp xfer data len */
@ -64,14 +65,14 @@ struct ncv_softc {
};
/*****************************************************************
* Lun information
* Target information
*****************************************************************/
struct ncv_lun_info {
struct lun_info nli_li;
struct ncv_targ_info {
struct targ_info nti_ti;
u_int8_t nli_reg_cfg3; /* cfg3 images per lun */
u_int8_t nli_reg_offset; /* synch offset register per lun */
u_int8_t nli_reg_period; /* synch period register per lun */
u_int8_t nti_reg_cfg3; /* cfg3 images per target */
u_int8_t nti_reg_offset; /* synch offset register per target */
u_int8_t nti_reg_period; /* synch period register per target */
};
/*****************************************************************

View File

@ -138,6 +138,10 @@ extern struct cfdriver nsp_cd;
/**************************************************************
* DECLARE
**************************************************************/
#ifdef __NetBSD__
extern int delaycount;
#endif
/* static */
static void nsp_pio_read __P((struct nsp_softc *, struct targ_info *));
static void nsp_pio_write __P((struct nsp_softc *, struct targ_info *));
@ -158,13 +162,12 @@ static int nsp_expect_signal __P((struct nsp_softc *, u_int8_t, u_int8_t));
static __inline void nsp_start_timer __P((struct nsp_softc *, int));
static int nsp_dataphase_bypass __P((struct nsp_softc *, struct targ_info *));
static void nsp_setup_fifo __P((struct nsp_softc *, int));
static int nsp_lun_init __P((struct nsp_softc *, struct targ_info *, struct lun_info *));
static void settimeout __P((void *));
static int nsp_targ_init __P((struct nsp_softc *, struct targ_info *));
struct scsi_low_funcs nspfuncs = {
SC_LOW_INIT_T nsp_world_start,
SC_LOW_BUSRST_T nsphw_bus_reset,
SC_LOW_LUN_INIT_T nsp_lun_init,
SC_LOW_TARG_INIT_T nsp_targ_init,
SC_LOW_SELECT_T nsphw_start_selection,
SC_LOW_NEXUS_T nsp_nexus,
@ -214,19 +217,10 @@ nsp_expect_signal(sc, curphase, 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 rv = -1;
int s;
int tout = 0;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
int wc = (sc->sc_wc >> 2);
u_int8_t ph, isrc;
int rv = -1;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, hz/2);
#else
timeout(settimeout, &tout, hz/2);
#endif
do
{
ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON);
@ -244,18 +238,9 @@ nsp_expect_signal(sc, curphase, 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: nsp_expect_signal timeout\n", slp->sl_xname);
rv = -1;
}
@ -363,11 +348,7 @@ nsphw_start_selection(sc, cb)
bus_space_handle_t bsh = sc->sc_ioh;
struct targ_info *ti = cb->ti;
register u_int8_t arbs, ph;
int s;
int tout = 0;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
int s, wc = sc->sc_wc;
/* check bus free */
if (slp->sl_disc > 0)
@ -385,28 +366,13 @@ nsphw_start_selection(sc, cb)
/* start arbitration */
SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART);
nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_EXEC);
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, 2 * hz);
#else
timeout(settimeout, &tout, 2 * hz);
#endif
do
{
/* XXX: what a stupid chip! */
arbs = nsp_cr_read_1(bst, bsh, NSPR_ARBITS);
delay(1);
}
while ((arbs & (ARBITS_WIN | ARBITS_FAIL)) == 0 && tout == 0);
s = splhigh();
if (tout == 0) {
#ifdef __FreeBSD__
untimeout(settimeout, &tout, ch);
#else
untimeout(settimeout, &tout);
#endif
}
splx(s);
while ((arbs & (ARBITS_WIN | ARBITS_FAIL)) == 0 && wc -- > 0);
if ((arbs & ARBITS_WIN) == 0)
{
@ -443,9 +409,11 @@ nsp_world_start(sc, fdone)
int fdone;
{
struct scsi_low_softc *slp = &sc->sc_sclow;
#ifdef __FreeBSD__
intrmask_t s;
s = splcam();
#endif
sc->sc_cnt = 0;
sc->sc_seltout = 0;
if ((slp->sl_cfgflags & CFG_NOATTEN) == 0)
@ -456,7 +424,9 @@ nsp_world_start(sc, fdone)
nsphw_init(sc);
scsi_low_bus_reset(slp);
#ifdef __FreeBSD__
splx(s);
#endif
SOFT_INTR_REQUIRED(slp);
return 0;
@ -491,16 +461,15 @@ nsp_msg(sc, ti, msg)
u_int msg;
{
struct ncp_synch_data *sdp;
struct lun_info *li = ti->ti_li;
struct nsp_lun_info *nli = (void *) li;
struct nsp_targ_info *nti = (void *) ti;
u_int period, offset;
int i;
if ((msg & SCSI_LOW_MSG_SYNCH) == 0)
return 0;
period = li->li_maxsynch.period;
offset = li->li_maxsynch.offset;
period = ti->ti_maxsynch.period;
offset = ti->ti_maxsynch.offset;
if (sc->sc_iclkdiv == CLKDIVR_20M)
sdp = &ncp_sync_data_20M[0];
else
@ -518,31 +487,30 @@ nsp_msg(sc, ti, msg)
* NO proper period/offset found,
* Retry neg with the target.
*/
li->li_maxsynch.period = 0;
li->li_maxsynch.offset = 0;
nli->nli_reg_syncr = 0;
nli->nli_reg_ackwidth = 0;
ti->ti_maxsynch.period = 0;
ti->ti_maxsynch.offset = 0;
nti->nti_reg_syncr = 0;
nti->nti_reg_ackwidth = 0;
return EINVAL;
}
nli->nli_reg_syncr = (sdp->chip_period << SYNCR_PERS) |
nti->nti_reg_syncr = (sdp->chip_period << SYNCR_PERS) |
(offset & SYNCR_OFFM);
nli->nli_reg_ackwidth = sdp->ack_width;
nti->nti_reg_ackwidth = sdp->ack_width;
return 0;
}
static int
nsp_lun_init(sc, ti, li)
nsp_targ_init(sc, ti)
struct nsp_softc *sc;
struct targ_info *ti;
struct lun_info *li;
{
struct nsp_lun_info *nli = (void *) li;
struct nsp_targ_info *nti = (void *) ti;
li->li_maxsynch.period = 200 / 4;
li->li_maxsynch.offset = 15;
nli->nli_reg_syncr = 0;
nli->nli_reg_ackwidth = 0;
ti->ti_maxsynch.period = 200 / 4;
ti->ti_maxsynch.offset = 15;
nti->nti_reg_syncr = 0;
nti->nti_reg_ackwidth = 0;
return 0;
}
@ -582,6 +550,11 @@ nspattachsubr(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 = &nspfuncs;
if (sc->sc_memh != NULL)
@ -590,7 +563,7 @@ nspattachsubr(sc)
sc->sc_xmode = NSP_PIO;
(void) scsi_low_attach(slp, 2, NSP_NTARGETS, NSP_NLUNS,
sizeof(struct nsp_lun_info));
sizeof(struct nsp_targ_info));
}
/**************************************************************
@ -706,23 +679,14 @@ nsp_pio_read(sc, ti)
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 s;
int tout = 0;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
int tout = sc->sc_wc;
u_int res, ocount, mask = sc->sc_mask;
u_int8_t stat, fstat;
slp->sl_flags |= HW_PDMASTART;
ocount = sc->sc_cnt;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, 2 * hz);
#else
timeout(settimeout, &tout, 2 * hz);
#endif
while (slp->sl_scp.scp_datalen > 0 && tout == 0)
while (slp->sl_scp.scp_datalen > 0 && tout -- > 0)
{
stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON);
stat &= SCBUSMON_PHMASK;
@ -772,18 +736,8 @@ nsp_pio_read(sc, ti)
}
sc->sc_cnt = ocount;
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);
}
}
static void
@ -795,21 +749,12 @@ nsp_pio_write(sc, ti)
bus_space_tag_t bst = sc->sc_iot;
bus_space_handle_t bsh = sc->sc_ioh;
u_int res, ocount, mask = sc->sc_mask;
int s;
int tout = 0;
int tout = sc->sc_wc;
register u_int8_t stat;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
ocount = sc->sc_cnt;
slp->sl_flags |= HW_PDMASTART;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, 2 * hz);
#else
timeout(settimeout, &tout, 2 * hz);
#endif
while (slp->sl_scp.scp_datalen > 0 && tout == 0)
while (slp->sl_scp.scp_datalen > 0 && tout -- > 0)
{
stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON);
stat &= SCBUSMON_PHMASK;
@ -847,27 +792,8 @@ nsp_pio_write(sc, ti)
}
sc->sc_cnt = ocount;
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 void
settimeout(arg)
void *arg;
{
int *tout = arg;
*tout = 1;
}
static int
@ -879,38 +805,19 @@ nsp_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 tout = 0;
int ss;
#ifdef __FreeBSD__
struct callout_handle ch;
#endif
int wc = (sc->sc_wc >> 2);
u_int8_t regv;
#ifdef __FreeBSD__
ch = timeout(settimeout, &tout, hz/2);
#else
timeout(settimeout, &tout, hz/2);
#endif
do
{
regv = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON);
if (regv == 0xff)
break;
}
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 singla off timeout \n", slp->sl_xname, s);
}
return 0;
}
@ -1063,11 +970,11 @@ nsp_nexus(sc, ti)
{
bus_space_tag_t bst = sc->sc_iot;
bus_space_handle_t bsh = sc->sc_ioh;
struct nsp_lun_info *nli = (void *) ti->ti_li;
struct nsp_targ_info *nti = (void *) ti;
/* setup synch transfer registers */
nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nli->nli_reg_syncr);
nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nli->nli_reg_ackwidth);
nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nti->nti_reg_syncr);
nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nti->nti_reg_ackwidth);
/* setup pdma fifo */
nsp_setup_fifo(sc, 1);

View File

@ -46,6 +46,7 @@ struct nsp_softc {
bus_space_handle_t sc_memh;
void *sc_ih;
int sc_wc;
int sc_seltout; /* selection timeout counter */
int sc_timer; /* timer start */
@ -77,13 +78,13 @@ struct nsp_softc {
};
/*****************************************************************
* Lun information
* Target information
*****************************************************************/
struct nsp_lun_info {
struct lun_info nli_li; /* generic lun info */
struct nsp_targ_info {
struct targ_info nti_ti; /* generic target info */
u_int8_t nli_reg_syncr; /* sync registers per devices */
u_int8_t nli_reg_ackwidth; /* ackwidth per devices */
u_int8_t nti_reg_syncr; /* sync registers per devices */
u_int8_t nti_reg_ackwidth; /* ackwidth per devices */
};
/*****************************************************************

View File

@ -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;
}

View File

@ -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 */
};
/*****************************************************************