* 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:
parent
b9fcb05e95
commit
4458cfede6
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user