Esempio n. 1
0
File: ct.c Progetto: 2asoft/freebsd
/**************************************************
 * ### SCSI PHASE SEQUENCER ###
 **************************************************/
static int
ct_reselected(struct ct_softc *ct, u_int8_t scsi_status)
{
	struct scsi_low_softc *slp = &ct->sc_sclow;
	struct ct_bus_access_handle *chp = &ct->sc_ch;
	struct targ_info *ti;
	u_int sid;
	u_int8_t regv;

	ct->sc_atten = 0;
	ct->sc_satgo &= ~CT_SAT_GOING;
	regv = ct_cr_read_1(chp, wd3s_sid);
	if ((regv & SIDR_VALID) == 0)
		return EJUSTRETURN;

	sid = regv & SIDR_IDM;
	if ((ti = scsi_low_reselected(slp, sid)) == NULL)
		return EJUSTRETURN;

	ct_target_nexus_establish(ct, 0, SCSI_LOW_READ);
	if (scsi_status != BSR_AFM_RESEL)
		return EJUSTRETURN;

	SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN);
	regv = ct_cr_read_1(chp, wd3s_data);
	if (scsi_low_msgin(slp, ti, (u_int) regv) == 0)
	{
		if (scsi_low_is_msgout_continue(ti, 0) != 0)
		{
			/* XXX: scsi_low_attetion */
			scsi_low_attention(slp);
		}
	}

	if (ct->sc_atten != 0)
	{
		ct_attention(ct);
	}

	ct_cr_write_1(chp, wd3s_cmd, WD3S_NEGATE_ACK);
	return EJUSTRETURN;
}
Esempio n. 2
0
/**************************************************************
 * disconnect & reselect (HW low)
 **************************************************************/
static int
stg_reselected(struct stg_softc *sc)
{
	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 tout;
	u_int sid;
	u_int8_t regv;

	if (slp->sl_selid != NULL)
	{
		/* XXX:
		 * Selection vs Reselection conflicts.
		 */
		bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
		stghw_bcr_write_1(sc, BCTL_BUSFREE);
	}
	else if (slp->sl_Tnexus != NULL)
	{
		kprintf("%s: unexpected termination\n", slp->sl_xname);
		stg_disconnected(sc, slp->sl_Tnexus);
	}

	/* XXX:
	 * We should ack the reselection as soon as possible,
	 * because the target would abort the current reselection seq 
  	 * due to reselection timeout.
	 */
	tout = STG_DELAY_SELECT_POLLING_MAX;
	while (tout -- > 0)
	{
		regv = bus_space_read_1(iot, ioh, tmc_bstat);
		if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == 
			    (BSTAT_IO | BSTAT_SEL))
		{
			SCSI_LOW_DELAY(1);
			regv = bus_space_read_1(iot, ioh, tmc_bstat);
			if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == 
				    (BSTAT_IO | BSTAT_SEL))
				goto reselect_start;
		}
		SCSI_LOW_DELAY(1);
	}
	kprintf("%s: reselction timeout I\n", slp->sl_xname);
	return EJUSTRETURN;
	
reselect_start:
	sid = (u_int) bus_space_read_1(iot, ioh, tmc_scsiid);
	if ((sid & sc->sc_idbit) == 0)
	{
		/* not us */
		return EJUSTRETURN;
	}

	bus_space_write_1(iot, ioh, tmc_fctl, 
			    sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT);
	bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit);
	stghw_bcr_write_1(sc, sc->sc_busc | BCTL_BSY);

	while (tout -- > 0)
	{
		regv = bus_space_read_1(iot, ioh, tmc_bstat);
		if ((regv & (BSTAT_SEL | BSTAT_BSY)) == BSTAT_BSY)
			goto reselected;
		SCSI_LOW_DELAY(1);
	}
	kprintf("%s: reselction timeout II\n", slp->sl_xname);
	return EJUSTRETURN;

reselected:
	sid &= ~sc->sc_idbit;
	sid = ffs(sid) - 1;
	if (scsi_low_reselected(slp, sid) == NULL)
		return EJUSTRETURN;

#ifdef	STG_STATICS
	stg_statics.reselect ++;
#endif	/* STG_STATICS */
	return EJUSTRETURN;
}