* Make the ahc and ahd probes more alike.

* Remove some redundant code.
* ahd: Don't initiate negotiation for a discovery xs when the negotiation goal
  is set. Just looking at the auto_negotiate mask is enough, and it can
  cause an endless loop if the request gets requeued (happens with a
  of a PPR negotiation, which ends with a busfree).
This commit is contained in:
fvdl 2003-09-02 21:02:56 +00:00
parent b9fcb05e95
commit 4458cfede6
5 changed files with 111 additions and 73 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: aic79xx.c,v 1.21 2003/08/29 05:50:42 thorpej Exp $ */
/* $NetBSD: aic79xx.c,v 1.22 2003/09/02 21:02:56 fvdl Exp $ */
/*
* Core routines and tables shareable across OS platforms.
@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: aic79xx.c,v 1.21 2003/08/29 05:50:42 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: aic79xx.c,v 1.22 2003/09/02 21:02:56 fvdl Exp $");
#include <dev/ic/aic79xx_osm.h>
#include <dev/ic/aic79xx_inline.h>
@ -262,8 +262,6 @@ static void ahd_freedmamem(bus_dma_tag_t tag,
caddr_t vaddr,
bus_dma_segment_t *seg,
int nseg);
static void ahd_update_xfer_mode(struct ahd_softc *ahc,
struct ahd_devinfo *devinfo);
/******************************** Private Inlines *****************************/
static __inline void ahd_assert_atn(struct ahd_softc *ahd);
@ -3088,10 +3086,6 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
update_needed += ahd_update_neg_request(ahd, devinfo, tstate,
tinfo, AHD_NEG_TO_GOAL);
if (update_needed)
ahd_update_xfer_mode(ahd, devinfo);
ahd->sc_req = 0;
if (update_needed && active)
ahd_update_pending_scbs(ahd);
}
@ -9805,37 +9799,3 @@ ahd_freedmamem(tag, size, map, vaddr, seg, nseg)
bus_dmamem_unmap(tag, vaddr, size);
bus_dmamem_free(tag, seg, nseg);
}
static void
ahd_update_xfer_mode(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
{
struct scsipi_xfer_mode xm;
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
tinfo = ahd_fetch_transinfo(ahd, devinfo->channel, devinfo->our_scsiid,
devinfo->target, &tstate);
xm.xm_target = devinfo->target;
xm.xm_mode = 0;
xm.xm_period = tinfo->curr.period;
xm.xm_offset = tinfo->curr.offset;
if (tinfo->curr.width == 1)
xm.xm_mode |= PERIPH_CAP_WIDE16;
if (tinfo->curr.period)
xm.xm_mode |= PERIPH_CAP_SYNC;
if (tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ)
xm.xm_mode |= PERIPH_CAP_DT;
if (tstate->tagenable & devinfo->target_mask)
xm.xm_mode |= PERIPH_CAP_TQING;
tinfo->goal.width = tinfo->curr.width;
tinfo->goal.period = tinfo->curr.period;
tinfo->goal.offset = tinfo->curr.offset;
tinfo->goal.ppr_options = tinfo->curr.ppr_options;
ahd_update_neg_request(ahd, devinfo, tstate,
tinfo, AHD_NEG_TO_GOAL);
scsipi_async_event(&ahd->sc_channel, ASYNC_EVENT_XFER_MODE, &xm);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: aic79xx_osm.c,v 1.5 2003/08/29 00:10:04 thorpej Exp $ */
/* $NetBSD: aic79xx_osm.c,v 1.6 2003/09/02 21:02:57 fvdl Exp $ */
/*
* Bus independent NetBSD shim for the aic7xxx based adaptec SCSI controllers
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: aic79xx_osm.c,v 1.5 2003/08/29 00:10:04 thorpej Exp $");
__KERNEL_RCSID(0, "$NetBSD: aic79xx_osm.c,v 1.6 2003/09/02 21:02:57 fvdl Exp $");
#include <dev/ic/aic79xx_osm.h>
#include <dev/ic/aic7xxx_cam.h>
@ -310,7 +310,12 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
tinfo = ahd_fetch_transinfo(ahd, channel, our_id,
target_id, &tstate);
col_idx = AHD_NEVER_COL_IDX; /* ??? */
if (xs->xs_tag_type != 0 ||
(tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
col_idx = AHD_NEVER_COL_IDX;
else
col_idx = AHD_BUILD_COL_IDX(target_id,
periph->periph_lun);
if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
xs->error = XS_RESOURCE_SHORTAGE;
@ -357,6 +362,8 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
u_int width;
int s;
char channel;
u_int ppr_options, period, offset;
uint16_t old_autoneg;
target_id = xm->xm_target;
our_id = chan->chan_id;
@ -367,6 +374,8 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
ahd_compile_devinfo(&devinfo, our_id, target_id,
0, channel, ROLE_INITIATOR);
old_autoneg = tstate->auto_negotiate;
/*
* XXX since the period and offset are not provided here,
* fake things by forcing a renegotiation using the user
@ -375,7 +384,10 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
* values, assuming that the user set it up that way.
*/
if (ahd->inited_target[target_id] == 0) {
tinfo->goal = tinfo->user;
period = tinfo->user.period;
offset = tinfo->user.offset;
ppr_options = tinfo->user.ppr_options;
width = tinfo->user.width;
tstate->tagenable |=
(ahd->user_tagenable & devinfo.target_mask);
tstate->discenable |=
@ -393,19 +405,23 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
ahd_validate_width(ahd, NULL, &width, ROLE_UNKNOWN);
if (width > tinfo->user.width)
width = tinfo->user.width;
tinfo->goal.width = width;
ahd_set_width(ahd, &devinfo, width, AHD_TRANS_GOAL, FALSE);
if (!(xm->xm_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT))) {
tinfo->goal.period = 0;
tinfo->goal.offset = 0;
tinfo->goal.ppr_options = 0;
period = 0;
offset = 0;
ppr_options = 0;
}
if ((xm->xm_mode & PERIPH_CAP_DT) &&
(tinfo->user.ppr_options & MSG_EXT_PPR_DT_REQ))
tinfo->goal.ppr_options |= MSG_EXT_PPR_DT_REQ;
ppr_options |= MSG_EXT_PPR_DT_REQ;
else
tinfo->goal.ppr_options &= ~MSG_EXT_PPR_DT_REQ;
ppr_options &= ~MSG_EXT_PPR_DT_REQ;
if ((tstate->discenable & devinfo.target_mask) == 0 ||
(tstate->tagenable & devinfo.target_mask) == 0)
ppr_options &= ~MSG_EXT_PPR_IU_REQ;
if ((xm->xm_mode & PERIPH_CAP_TQING) &&
(ahd->user_tagenable & devinfo.target_mask))
@ -413,14 +429,43 @@ ahd_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
else
tstate->tagenable &= ~devinfo.target_mask;
ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX);
ahd_validate_offset(ahd, NULL, period, &offset,
MSG_EXT_WDTR_BUS_8_BIT, ROLE_UNKNOWN);
if (offset == 0) {
period = 0;
ppr_options = 0;
}
if (ppr_options != 0
&& tinfo->user.transport_version >= 3) {
tinfo->goal.transport_version =
tinfo->user.transport_version;
tinfo->curr.transport_version =
tinfo->user.transport_version;
}
ahd_set_syncrate(ahd, &devinfo, period, offset,
ppr_options, AHD_TRANS_GOAL, FALSE);
/*
* If this is the first request, and no negotiation is
* needed, just confirm the state to the scsipi layer,
* so that it can print a message.
*/
if (!ahd_update_neg_request(ahd, &devinfo, tstate,
tinfo, AHD_NEG_IF_NON_ASYNC) && first)
if (old_autoneg == tstate->auto_negotiate && first) {
xm->xm_mode = 0;
xm->xm_period = tinfo->curr.period;
xm->xm_offset = tinfo->curr.offset;
if (tinfo->curr.width == MSG_EXT_WDTR_BUS_16_BIT)
xm->xm_mode |= PERIPH_CAP_WIDE16;
if (tinfo->curr.period)
xm->xm_mode |= PERIPH_CAP_SYNC;
if (tstate->tagenable & devinfo.target_mask)
xm->xm_mode |= PERIPH_CAP_TQING;
if (tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ)
xm->xm_mode |= PERIPH_CAP_DT;
scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm);
}
splx(s);
}
}
@ -506,13 +551,16 @@ ahd_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
scb->hscb->control &= ~MK_MESSAGE;
}
#if 0 /* This looks like it makes sense at first, but it can loop */
if ((xs->xs_control & XS_CTL_DISCOVERY) &&
(tinfo->goal.width != 0
|| tinfo->goal.period != 0
|| tinfo->goal.ppr_options != 0)) {
scb->flags |= SCB_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE;
} else if ((tstate->auto_negotiate & mask) != 0) {
} else
#endif
if ((tstate->auto_negotiate & mask) != 0) {
scb->flags |= SCB_AUTO_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE;
}

View File

@ -1070,8 +1070,6 @@ struct ahd_softc {
bus_space_tag_t tags[2];
bus_space_handle_t bshs[2];
scsipi_adapter_req_t sc_req;
void *shutdown_hook;
struct scb_data scb_data;

View File

@ -1,4 +1,4 @@
/* $NetBSD: aic7xxx_osm.c,v 1.10 2003/07/14 15:47:10 lukem Exp $ */
/* $NetBSD: aic7xxx_osm.c,v 1.11 2003/09/02 21:02:57 fvdl Exp $ */
/*
* Bus independent FreeBSD shim for the aic7xxx based adaptec SCSI controllers
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: aic7xxx_osm.c,v 1.10 2003/07/14 15:47:10 lukem Exp $");
__KERNEL_RCSID(0, "$NetBSD: aic7xxx_osm.c,v 1.11 2003/09/02 21:02:57 fvdl Exp $");
#include <dev/ic/aic7xxx_osm.h>
#include <dev/ic/aic7xxx_inline.h>
@ -340,6 +340,9 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
int target_id, our_id, first;
u_int width;
char channel;
u_int ppr_options, period, offset;
struct ahc_syncrate *syncrate;
uint16_t old_autoneg;
target_id = xm->xm_target;
our_id = chan->chan_id;
@ -350,6 +353,8 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
ahc_compile_devinfo(&devinfo, our_id, target_id,
0, channel, ROLE_INITIATOR);
old_autoneg = tstate->auto_negotiate;
/*
* XXX since the period and offset are not provided here,
* fake things by forcing a renegotiation using the user
@ -358,7 +363,10 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
* values, assuming that the user set it up that way.
*/
if (ahc->inited_target[target_id] == 0) {
tinfo->goal = tinfo->user;
period = tinfo->user.period;
offset = tinfo->user.offset;
ppr_options = tinfo->user.ppr_options;
width = tinfo->user.width;
tstate->tagenable |=
(ahc->user_tagenable & devinfo.target_mask);
tstate->discenable |=
@ -376,19 +384,22 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
ahc_validate_width(ahc, NULL, &width, ROLE_UNKNOWN);
if (width > tinfo->user.width)
width = tinfo->user.width;
tinfo->goal.width = width;
ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
if (!(xm->xm_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT))) {
tinfo->goal.period = 0;
tinfo->goal.offset = 0;
tinfo->goal.ppr_options = 0;
period = 0;
offset = 0;
ppr_options = 0;
}
if ((xm->xm_mode & PERIPH_CAP_DT) &&
(tinfo->user.ppr_options & MSG_EXT_PPR_DT_REQ))
tinfo->goal.ppr_options |= MSG_EXT_PPR_DT_REQ;
(ppr_options & MSG_EXT_PPR_DT_REQ))
ppr_options |= MSG_EXT_PPR_DT_REQ;
else
tinfo->goal.ppr_options &= ~MSG_EXT_PPR_DT_REQ;
ppr_options &= ~MSG_EXT_PPR_DT_REQ;
if ((tstate->discenable & devinfo.target_mask) == 0 ||
(tstate->tagenable & devinfo.target_mask) == 0)
ppr_options &= ~MSG_EXT_PPR_IU_REQ;
if ((xm->xm_mode & PERIPH_CAP_TQING) &&
(ahc->user_tagenable & devinfo.target_mask))
@ -396,13 +407,33 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
else
tstate->tagenable &= ~devinfo.target_mask;
syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,
AHC_SYNCRATE_MAX);
ahc_validate_offset(ahc, NULL, syncrate, &offset,
width, ROLE_UNKNOWN);
if (offset == 0) {
period = 0;
ppr_options = 0;
}
if (ppr_options != 0
&& tinfo->user.transport_version >= 3) {
tinfo->goal.transport_version =
tinfo->user.transport_version;
tinfo->curr.transport_version =
tinfo->user.transport_version;
}
ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
ppr_options, AHC_TRANS_GOAL, FALSE);
/*
* If this is the first request, and no negotiation is
* needed, just confirm the state to the scsipi layer,
* so that it can print a message.
*/
if (!ahc_update_neg_request(ahc, &devinfo, tstate,
tinfo, AHC_NEG_IF_NON_ASYNC) && first) {
if (old_autoneg == tstate->auto_negotiate && first) {
xm->xm_mode = 0;
xm->xm_period = tinfo->curr.period;
xm->xm_offset = tinfo->curr.offset;
@ -525,12 +556,15 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments)
if (xs->xs_tag_type)
scb->hscb->control |= xs->xs_tag_type;
#if 0 /* This looks like it makes sense at first, but it can loop */
if ((xs->xs_control & XS_CTL_DISCOVERY) && (tinfo->goal.width == 0
&& tinfo->goal.offset == 0
&& tinfo->goal.ppr_options == 0)) {
scb->flags |= SCB_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE;
} else if ((tstate->auto_negotiate & mask) != 0) {
} else
#endif
if ((tstate->auto_negotiate & mask) != 0) {
scb->flags |= SCB_AUTO_NEGOTIATE;
scb->hscb->control |= MK_MESSAGE;
}

View File

@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: aic7xxxvar.h,v 1.40 2003/07/08 10:06:30 itojun Exp $
* $Id: aic7xxxvar.h,v 1.41 2003/09/02 21:02:58 fvdl Exp $
*
* $FreeBSD: /repoman/r/ncvs/src/sys/dev/aic7xxx/aic7xxx.h,v 1.44 2003/01/20 20:44:55 gibbs Exp $
*/
@ -1024,8 +1024,6 @@ struct ahc_softc {
bus_space_tag_t tag;
bus_space_handle_t bsh;
scsipi_adapter_req_t sc_req;
#ifndef __linux__
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
#endif