Redo xfer sync/wide/tag notification again: we need to notify upper layer
that we can do tag. Start sync/wide nego at first command, but wait ADAPTER_REQ_SET_XFER_MODE to notify upper level.
This commit is contained in:
parent
99054d7a6c
commit
d032d80637
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: aic7xxx.c,v 1.70 2001/04/25 17:53:31 bouyer Exp $ */
|
||||
/* $NetBSD: aic7xxx.c,v 1.71 2001/04/26 16:56:53 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Generic driver for the aic7xxx based adaptec SCSI controllers
|
||||
|
@ -284,6 +284,7 @@ static void ahc_set_syncrate(struct ahc_softc *, struct ahc_devinfo *,
|
|||
static void ahc_set_width(struct ahc_softc *, struct ahc_devinfo *,
|
||||
u_int, u_int, int, int);
|
||||
static void ahc_set_tags(struct ahc_softc *, struct ahc_devinfo *, int);
|
||||
static void ahc_update_xfer_mode(struct ahc_softc *, struct ahc_devinfo *);
|
||||
static void ahc_construct_sdtr(struct ahc_softc *, u_int, u_int);
|
||||
|
||||
static void ahc_construct_wdtr(struct ahc_softc *, u_int);
|
||||
|
@ -1271,22 +1272,6 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
|||
ahc_update_pending_syncrates(ahc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print messages if we're verbose and at the end of a negotiation
|
||||
* cycle.
|
||||
*/
|
||||
if (done) {
|
||||
if (offset != 0) {
|
||||
printf("%s: target %d synchronous at %sMHz, "
|
||||
"offset = 0x%x\n", ahc_name(ahc),
|
||||
devinfo->target, syncrate->rate, offset);
|
||||
} else {
|
||||
printf("%s: target %d using "
|
||||
"asynchronous transfers\n",
|
||||
ahc_name(ahc), devinfo->target);
|
||||
}
|
||||
}
|
||||
|
||||
if ((type & AHC_TRANS_GOAL) != 0) {
|
||||
tinfo->goal.period = period;
|
||||
tinfo->goal.offset = offset;
|
||||
|
@ -1331,12 +1316,6 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
|||
tinfo->current.width = width;
|
||||
}
|
||||
|
||||
if (done) {
|
||||
printf("%s: target %d using %dbit transfers\n",
|
||||
ahc_name(ahc), devinfo->target,
|
||||
8 * (0x01 << width));
|
||||
}
|
||||
|
||||
if ((type & AHC_TRANS_GOAL) != 0)
|
||||
tinfo->goal.width = width;
|
||||
if ((type & AHC_TRANS_USER) != 0)
|
||||
|
@ -1363,6 +1342,34 @@ ahc_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, int enable)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ahc_update_xfer_mode(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
||||
{
|
||||
struct scsipi_xfer_mode xm;
|
||||
struct ahc_initiator_tinfo *tinfo;
|
||||
struct tmode_tstate *tstate;
|
||||
|
||||
if (ahc->inited_targets[devinfo->target] != 2)
|
||||
return;
|
||||
|
||||
tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid,
|
||||
devinfo->target, &tstate);
|
||||
|
||||
xm.xm_target = devinfo->target;
|
||||
xm.xm_mode = 0;
|
||||
xm.xm_period = tinfo->current.period;
|
||||
xm.xm_offset = tinfo->current.offset;
|
||||
if (tinfo->current.width == 1)
|
||||
xm.xm_mode |= PERIPH_CAP_WIDE16;
|
||||
if (tinfo->current.period)
|
||||
xm.xm_mode |= PERIPH_CAP_SYNC;
|
||||
if (tstate->tagenable & devinfo->target_mask)
|
||||
xm.xm_mode |= PERIPH_CAP_TQING;
|
||||
scsipi_async_event(
|
||||
devinfo->channel == 'B' ? &ahc->sc_channel_b : &ahc->sc_channel,
|
||||
ASYNC_EVENT_XFER_MODE, &xm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach all the sub-devices we can find
|
||||
*/
|
||||
|
@ -2508,7 +2515,8 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||
ahc_construct_sdtr(ahc, period, tinfo->goal.offset);
|
||||
ahc->msgout_index = 0;
|
||||
response = 1;
|
||||
}
|
||||
} else
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
} else if (ahc_sent_msg(ahc, MSG_EXT_SDTR, /*full*/FALSE)) {
|
||||
/* note asynch xfers and clear flag */
|
||||
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL, /*period*/0,
|
||||
|
@ -2520,12 +2528,14 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
|
|||
ahc_name(ahc),
|
||||
devinfo->channel, devinfo->target);
|
||||
#endif
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
} else if ((scb->hscb->control & TAG_ENB) != 0) {
|
||||
printf("%s:%c:%d: refuses tagged commands. Performing "
|
||||
"non-tagged I/O\n", ahc_name(ahc),
|
||||
devinfo->channel, devinfo->target);
|
||||
|
||||
ahc_set_tags(ahc, devinfo, FALSE);
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
|
||||
/*
|
||||
* Resend the identify for this CCB as the target
|
||||
|
@ -2943,6 +2953,7 @@ ahc_parse_msg(struct ahc_softc *ahc, struct scsipi_periph *periph,
|
|||
syncrate, period, offset,
|
||||
AHC_TRANS_ACTIVE|AHC_TRANS_GOAL,
|
||||
/*paused*/TRUE, /*done*/TRUE);
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
|
||||
/*
|
||||
* See if we initiated Sync Negotiation
|
||||
|
@ -3066,7 +3077,8 @@ ahc_parse_msg(struct ahc_softc *ahc, struct scsipi_periph *periph,
|
|||
ahc_construct_sdtr(ahc, period, offset);
|
||||
ahc->msgout_index = 0;
|
||||
response = TRUE;
|
||||
}
|
||||
} else
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
}
|
||||
done = MSGLOOP_MSGCOMPLETE;
|
||||
break;
|
||||
|
@ -3251,6 +3263,7 @@ ahc_handle_devreset(struct ahc_softc *ahc, struct ahc_devinfo *devinfo,
|
|||
ahc_set_syncrate(ahc, devinfo, /*syncrate*/NULL,
|
||||
/*period*/0, /*offset*/0, AHC_TRANS_CUR,
|
||||
/*paused*/TRUE, /*done*/FALSE);
|
||||
ahc_update_xfer_mode(ahc, devinfo);
|
||||
|
||||
if (message != NULL && (verbose_level <= 0))
|
||||
printf("%s: %s on %c:%d. %d SCBs aborted\n", ahc_name(ahc),
|
||||
|
@ -3832,7 +3845,7 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
|
|||
xs = arg;
|
||||
periph = xs->xs_periph;
|
||||
|
||||
SC_DEBUG(periph, SDEV_DB3, ("ahc_action\n"));
|
||||
SC_DEBUG(xs->xs_periph, SDEV_DB3, ("ahc_action\n"));
|
||||
|
||||
/* must protect the queue */
|
||||
s = splbio();
|
||||
|
@ -3904,7 +3917,6 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
|
|||
our_id, target_id, &tstate);
|
||||
if (ahc->inited_targets[target_id] == 0) {
|
||||
struct ahc_devinfo devinfo;
|
||||
|
||||
s = splbio();
|
||||
ahc_compile_devinfo(&devinfo, our_id, target_id,
|
||||
periph->periph_lun,
|
||||
|
@ -3915,7 +3927,6 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
|
|||
ahc->inited_targets[target_id] = 1;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
hscb->scsirate = tinfo->scsirate;
|
||||
hscb->scsioffset = tinfo->current.offset;
|
||||
if ((tstate->ultraenb & mask) != 0)
|
||||
|
@ -3951,13 +3962,13 @@ ahc_action(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg)
|
|||
&tstate);
|
||||
ahc_compile_devinfo(&devinfo, our_id, target_id,
|
||||
0, channel, ROLE_INITIATOR);
|
||||
ahc->inited_targets[target_id] = 2;
|
||||
if (xm->xm_mode & PERIPH_CAP_TQING &&
|
||||
(tstate->tagdisable & devinfo.target_mask) == 0) {
|
||||
ahc_set_tags(ahc, &devinfo, TRUE);
|
||||
printf("%s: target %d using tagged queuing\n",
|
||||
ahc_name(ahc), target_id);
|
||||
}
|
||||
splx(s);
|
||||
ahc_update_xfer_mode(ahc, &devinfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5226,6 +5237,7 @@ ahc_reset_channel(struct ahc_softc *ahc, char channel, int initiate_reset)
|
|||
/*syncrate*/NULL, /*period*/0,
|
||||
/*offset*/0, AHC_TRANS_CUR,
|
||||
/*paused*/TRUE, FALSE);
|
||||
ahc_update_xfer_mode(ahc, &devinfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue