Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4b53a11 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by James Bottomley
Browse files

[SCSI] aic79xx: DV parameter settings



This patch updates various scsi_transport_spi parameters with the actual
parameters used by the driver internally.
Domain Validation for all devices should now work properly.

Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 73a25462
Loading
Loading
Loading
Loading
+218 −13
Original line number Diff line number Diff line
@@ -1636,9 +1636,9 @@ ahd_send_async(struct ahd_softc *ahd, char channel,
		spi_period(starget) = tinfo->curr.period;
		spi_width(starget) = tinfo->curr.width;
		spi_offset(starget) = tinfo->curr.offset;
		spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ;
		spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ;
		spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ;
		spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
		spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
		spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
		spi_display_xfer_agreement(starget);
		break;
	}
@@ -2318,6 +2318,18 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)

static void ahd_linux_exit(void);

static void ahd_linux_set_xferflags(struct scsi_target *starget, unsigned int ppr_options, unsigned int period)
{
	spi_qas(starget) = (ppr_options & MSG_EXT_PPR_QAS_REQ)? 1 : 0;
	spi_dt(starget) = (ppr_options & MSG_EXT_PPR_DT_REQ)? 1 : 0;
	spi_iu(starget) = (ppr_options & MSG_EXT_PPR_IU_REQ) ? 1 : 0;
	spi_rd_strm(starget) = (ppr_options & MSG_EXT_PPR_RD_STRM) ? 1 : 0;
	spi_wr_flow(starget) = (ppr_options & MSG_EXT_PPR_WR_FLOW) ? 1 : 0;
	spi_pcomp_en(starget) = (ppr_options & MSG_EXT_PPR_PCOMP_EN) ? 1 : 0;
	spi_rti(starget) = (ppr_options & MSG_EXT_PPR_RTI) ? 1 : 0;
	spi_period(starget) = period;
}

static void ahd_linux_set_width(struct scsi_target *starget, int width)
{
	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
@@ -2343,9 +2355,14 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
				      shost->this_id, starget->id, &tstate);
	struct ahd_devinfo devinfo;
	unsigned int ppr_options = tinfo->goal.ppr_options;
	unsigned int dt;
	unsigned long flags;
	unsigned long offset = tinfo->goal.offset;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: set period to %d\n", ahd_name(ahd), period);
#endif
	if (offset == 0)
		offset = MAX_OFFSET;

@@ -2357,6 +2374,8 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
			ppr_options |= MSG_EXT_PPR_IU_REQ;
	}

	dt = ppr_options & MSG_EXT_PPR_DT_REQ;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);

@@ -2366,7 +2385,11 @@ static void ahd_linux_set_period(struct scsi_target *starget, int period)
			ppr_options &= MSG_EXT_PPR_QAS_REQ;
	}

	ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	ahd_linux_set_xferflags(starget, ppr_options, period);

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
@@ -2385,15 +2408,24 @@ static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
	struct ahd_devinfo devinfo;
	unsigned int ppr_options = 0;
	unsigned int period = 0;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned long flags;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: set offset to %d\n", ahd_name(ahd), offset);
#endif

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	if (offset != 0) {
		period = tinfo->goal.period;
		ppr_options = tinfo->goal.ppr_options;
		ahd_find_syncrate(ahd, &period, &ppr_options, AHD_SYNCRATE_MAX);
		ahd_find_syncrate(ahd, &period, &ppr_options, 
				  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
	}
	ahd_linux_set_xferflags(starget, ppr_options, period);

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, offset, ppr_options,
			 AHD_TRANS_GOAL, FALSE);
@@ -2415,17 +2447,28 @@ static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
	unsigned int period = tinfo->goal.period;
	unsigned long flags;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s DT\n", ahd_name(ahd), 
		       dt ? "enabling" : "disabling");
#endif
	if (dt) {
		ppr_options |= MSG_EXT_PPR_DT_REQ;
		if (period > 9)
			period = 9; /* at least 12.5ns for DT */
	} else if (period <= 9)
	} else {
		if (period <= 9)
			period = 10; /* If resetting DT, period must be >= 25ns */

		/* IU is invalid without DT set */
		ppr_options &= ~MSG_EXT_PPR_IU_REQ;
	}
	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	ahd_linux_set_xferflags(starget, ppr_options, period);

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
@@ -2445,16 +2488,28 @@ static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
	unsigned int ppr_options = tinfo->goal.ppr_options
		& ~MSG_EXT_PPR_QAS_REQ;
	unsigned int period = tinfo->goal.period;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned int dt;
	unsigned long flags;

	if (qas)
#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s QAS\n", ahd_name(ahd), 
		       qas ? "enabling" : "disabling");
#endif

	if (qas) {
		ppr_options |= MSG_EXT_PPR_QAS_REQ; 
	}

	dt = ppr_options & MSG_EXT_PPR_DT_REQ;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	spi_qas(starget) = (ppr_options & MSG_EXT_PPR_QAS_REQ)? 1 : 0;

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
@@ -2474,16 +2529,29 @@ static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
	unsigned int ppr_options = tinfo->goal.ppr_options
		& ~MSG_EXT_PPR_IU_REQ;
	unsigned int period = tinfo->goal.period;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned int dt;
	unsigned long flags;

	if (iu)
#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s IU\n", ahd_name(ahd),
		       iu ? "enabling" : "disabling");
#endif

	if (iu) {
		ppr_options |= MSG_EXT_PPR_IU_REQ;
		ppr_options |= MSG_EXT_PPR_DT_REQ; /* IU requires DT */
	}

	dt = ppr_options & MSG_EXT_PPR_DT_REQ;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	ahd_linux_set_xferflags(starget, ppr_options, period);

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
@@ -2506,6 +2574,12 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned long flags;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s Read Streaming\n", ahd_name(ahd), 
		       rdstrm  ? "enabling" : "disabling");
#endif

	if (rdstrm)
		ppr_options |= MSG_EXT_PPR_RD_STRM;

@@ -2513,6 +2587,131 @@ static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	spi_rd_strm(starget) = (ppr_options & MSG_EXT_PPR_RD_STRM) ? 1 : 0;

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
	ahd_unlock(ahd, &flags);
}

static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
{
	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
	struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
	struct ahd_tmode_tstate *tstate;
	struct ahd_initiator_tinfo *tinfo 
		= ahd_fetch_transinfo(ahd,
				      starget->channel + 'A',
				      shost->this_id, starget->id, &tstate);
	struct ahd_devinfo devinfo;
	unsigned int ppr_options = tinfo->goal.ppr_options
		& ~MSG_EXT_PPR_WR_FLOW;
	unsigned int period = tinfo->goal.period;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned long flags;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s Write Flow Control\n", ahd_name(ahd),
		       wrflow ? "enabling" : "disabling");
#endif

	if (wrflow)
		ppr_options |= MSG_EXT_PPR_WR_FLOW;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	spi_wr_flow(starget) = (ppr_options & MSG_EXT_PPR_WR_FLOW) ? 1 : 0;

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
	ahd_unlock(ahd, &flags);
}

static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
{
	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
	struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
	struct ahd_tmode_tstate *tstate;
	struct ahd_initiator_tinfo *tinfo 
		= ahd_fetch_transinfo(ahd,
				      starget->channel + 'A',
				      shost->this_id, starget->id, &tstate);
	struct ahd_devinfo devinfo;
	unsigned int ppr_options = tinfo->goal.ppr_options
		& ~MSG_EXT_PPR_RTI;
	unsigned int period = tinfo->goal.period;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned long flags;

	if ((ahd->features & AHD_RTI) == 0) {
#ifdef AHD_DEBUG
		if ((ahd_debug & AHD_SHOW_DV) != 0)
			printf("%s: RTI not available\n", ahd_name(ahd));
#endif
		return;
	}

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s RTI\n", ahd_name(ahd),
		       rti ? "enabling" : "disabling");
#endif

	if (rti)
		ppr_options |= MSG_EXT_PPR_RTI;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	spi_rti(starget) = (ppr_options & MSG_EXT_PPR_RTI) ? 1 : 0;

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
	ahd_unlock(ahd, &flags);
}

static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
{
	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
	struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
	struct ahd_tmode_tstate *tstate;
	struct ahd_initiator_tinfo *tinfo 
		= ahd_fetch_transinfo(ahd,
				      starget->channel + 'A',
				      shost->this_id, starget->id, &tstate);
	struct ahd_devinfo devinfo;
	unsigned int ppr_options = tinfo->goal.ppr_options
		& ~MSG_EXT_PPR_PCOMP_EN;
	unsigned int period = tinfo->goal.period;
	unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
	unsigned long flags;

#ifdef AHD_DEBUG
	if ((ahd_debug & AHD_SHOW_DV) != 0)
		printf("%s: %s Precompensation\n", ahd_name(ahd), 
		       pcomp ? "Enable" : "Disable");
#endif

	if (pcomp)
		ppr_options |= MSG_EXT_PPR_PCOMP_EN;

	ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
			    starget->channel + 'A', ROLE_INITIATOR);
	ahd_find_syncrate(ahd, &period, &ppr_options,
			  dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);

	spi_pcomp_en(starget) = (ppr_options & MSG_EXT_PPR_PCOMP_EN) ? 1 : 0;

	ahd_lock(ahd, &flags);
	ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
			 ppr_options, AHD_TRANS_GOAL, FALSE);
@@ -2534,6 +2733,12 @@ static struct spi_function_template ahd_linux_transport_functions = {
	.show_qas	= 1,
	.set_rd_strm	= ahd_linux_set_rd_strm,
	.show_rd_strm	= 1,
	.set_wr_flow	= ahd_linux_set_wr_flow,
	.show_wr_flow	= 1,
	.set_rti	= ahd_linux_set_rti,
	.show_rti	= 1,
	.set_pcomp_en	= ahd_linux_set_pcomp_en,
	.show_pcomp_en	= 1,
};