public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates
@ 2011-12-17  0:53 Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 1/8] isci: cleanup oem parameter and recipe handling Dan Williams
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi

These are priority updates, targeted for inclusion in 3.2-final, for the
driver to honor the latest definition of oem parameters and support the
latest revision of silicon.  The oem parameter format (phy configuration
settings passed along from platform firmware) has been updated to
revision 1.3, current driver only supports 1.0.  The C1 silicon update
involves updates to the per-silicon-revision hard-coded phy tuning
recipes.

This also updates the driver version from v1.0 to v1.1 to remove the
stale EXPERIMENTAL tag and reflect the C1 level of silicon support.

A performance fix and a fix for a crash that can be triggered by
enabling a dev_dbg() statement are also included.

Please apply, or pull from:

  git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git fixes

...to receive:

Dan Williams (2):
      isci: cleanup oem parameter and recipe handling
      isci: update version to 1.1

Dave Jiang (1):
      isci: oem parameter format v1.1 (ssc select)

Jeff Skirvin (3):
      isci: update afe (analog-front-end) recipe for C1
      isci: oem parameter format v1.3 (cable select)
      isci: link speeds default to gen 2

Maciej Trela (1):
      isci: remove unused 'isci_tmf->device' field

Marcin Tomczak (1):
      isci: performance-fix, shorten default "no outbound task" timeout

 drivers/scsi/Kconfig                   |    5 -
 drivers/scsi/isci/firmware/create_fw.c |   53 +++---
 drivers/scsi/isci/firmware/create_fw.h |   13 ++-
 drivers/scsi/isci/host.c               |  277 ++++++++++++++++++++++++--------
 drivers/scsi/isci/host.h               |   27 +++-
 drivers/scsi/isci/init.c               |   25 +++-
 drivers/scsi/isci/isci.h               |    1 +
 drivers/scsi/isci/phy.c                |  137 +++++++++++-----
 drivers/scsi/isci/probe_roms.c         |    2 +-
 drivers/scsi/isci/probe_roms.h         |   89 ++++++++++-
 drivers/scsi/isci/task.c               |    2 +-
 drivers/scsi/isci/task.h               |    7 +-
 firmware/isci/isci_firmware.bin.ihex   |    2 +-
 13 files changed, 477 insertions(+), 163 deletions(-)

Thanks,
Dan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 1/8] isci: cleanup oem parameter and recipe handling
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 2/8] isci: update afe (analog-front-end) recipe for C1 Dan Williams
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi

Before updating the code to support the latest platform updates and
silicon revision cleanup some of the long deref chains.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/firmware/create_fw.c |   47 ++++++--------
 drivers/scsi/isci/host.c               |  107 ++++++++++++++------------------
 drivers/scsi/isci/phy.c                |   81 ++++++++++++------------
 3 files changed, 107 insertions(+), 128 deletions(-)

diff --git a/drivers/scsi/isci/firmware/create_fw.c b/drivers/scsi/isci/firmware/create_fw.c
index c7a2887..36eabef 100644
--- a/drivers/scsi/isci/firmware/create_fw.c
+++ b/drivers/scsi/isci/firmware/create_fw.c
@@ -40,7 +40,7 @@ int write_blob(struct isci_orom *isci_orom)
 
 void set_binary_values(struct isci_orom *isci_orom)
 {
-	int ctrl_idx, phy_idx, port_idx;
+	int c, phy_idx, port_idx;
 
 	/* setting OROM signature */
 	strncpy(isci_orom->hdr.signature, sig, strlen(sig));
@@ -49,31 +49,26 @@ void set_binary_values(struct isci_orom *isci_orom)
 	isci_orom->hdr.hdr_length = sizeof(struct sci_bios_oem_param_block_hdr);
 	isci_orom->hdr.num_elements = num_elements;
 
-	for (ctrl_idx = 0; ctrl_idx < 2; ctrl_idx++) {
-		isci_orom->ctrl[ctrl_idx].controller.mode_type = mode_type;
-		isci_orom->ctrl[ctrl_idx].controller.max_concurrent_dev_spin_up =
-			max_num_concurrent_dev_spin_up;
-		isci_orom->ctrl[ctrl_idx].controller.do_enable_ssc =
-			enable_ssc;
-
-		for (port_idx = 0; port_idx < 4; port_idx++)
-			isci_orom->ctrl[ctrl_idx].ports[port_idx].phy_mask =
-				phy_mask[ctrl_idx][port_idx];
-
-		for (phy_idx = 0; phy_idx < 4; phy_idx++) {
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.high =
-				(__u32)(sas_addr[ctrl_idx][phy_idx] >> 32);
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.low =
-				(__u32)(sas_addr[ctrl_idx][phy_idx]);
-
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control0 =
-				afe_tx_amp_control0;
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control1 =
-				afe_tx_amp_control1;
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control2 =
-				afe_tx_amp_control2;
-			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control3 =
-				afe_tx_amp_control3;
+	for (c = 0; c < 2; c++) {
+		struct sci_oem_params *ctrl = &isci_orom->ctrl[c];
+
+		ctrl->controller.mode_type = mode_type;
+		ctrl->controller.max_concurr_spin_up = max_num_concurrent_dev_spin_up;
+		ctrl->controller.do_enable_ssc = enable_ssc;
+
+		for (port_idx = 0; port_idx < SCI_MAX_PORTS; port_idx++)
+			ctrl->ports[port_idx].phy_mask = phy_mask[c][port_idx];
+
+		for (phy_idx = 0; phy_idx < SCI_MAX_PHYS; phy_idx++) {
+			struct sci_phy_oem_params *phy = &ctrl->phys[phy_idx];
+
+			phy->sas_address.high = sas_addr[c][phy_idx] >> 32;
+			phy->sas_address.low = sas_addr[c][phy_idx];
+
+			phy->afe_tx_amp_control0 = afe_tx_amp_control0;
+			phy->afe_tx_amp_control1 = afe_tx_amp_control1;
+			phy->afe_tx_amp_control2 = afe_tx_amp_control2;
+			phy->afe_tx_amp_control3 = afe_tx_amp_control3;
 		}
 	}
 }
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index e7fe9c4..8e7de19 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1910,160 +1910,147 @@ void sci_controller_power_control_queue_remove(struct isci_host *ihost,
 
 #define AFE_REGISTER_WRITE_DELAY 10
 
-/* Initialize the AFE for this phy index. We need to read the AFE setup from
- * the OEM parameters
- */
 static void sci_controller_afe_initialization(struct isci_host *ihost)
 {
+	struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
 	const struct sci_oem_params *oem = &ihost->oem_parameters;
 	struct pci_dev *pdev = ihost->pdev;
 	u32 afe_status;
 	u32 phy_id;
 
 	/* Clear DFX Status registers */
-	writel(0x0081000f, &ihost->scu_registers->afe.afe_dfx_master_control0);
+	writel(0x0081000f, &afe->afe_dfx_master_control0);
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
 	if (is_b0(pdev)) {
 		/* PM Rx Equalization Save, PM SPhy Rx Acknowledgement
-		 * Timer, PM Stagger Timer */
-		writel(0x0007BFFF, &ihost->scu_registers->afe.afe_pmsn_master_control2);
+		 * Timer, PM Stagger Timer
+		 */
+		writel(0x0007BFFF, &afe->afe_pmsn_master_control2);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 	}
 
 	/* Configure bias currents to normal */
 	if (is_a2(pdev))
-		writel(0x00005A00, &ihost->scu_registers->afe.afe_bias_control);
+		writel(0x00005A00, &afe->afe_bias_control);
 	else if (is_b0(pdev) || is_c0(pdev))
-		writel(0x00005F00, &ihost->scu_registers->afe.afe_bias_control);
+		writel(0x00005F00, &afe->afe_bias_control);
 
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
 	/* Enable PLL */
 	if (is_b0(pdev) || is_c0(pdev))
-		writel(0x80040A08, &ihost->scu_registers->afe.afe_pll_control0);
+		writel(0x80040A08, &afe->afe_pll_control0);
 	else
-		writel(0x80040908, &ihost->scu_registers->afe.afe_pll_control0);
+		writel(0x80040908, &afe->afe_pll_control0);
 
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
 	/* Wait for the PLL to lock */
 	do {
-		afe_status = readl(&ihost->scu_registers->afe.afe_common_block_status);
+		afe_status = readl(&afe->afe_common_block_status);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 	} while ((afe_status & 0x00001000) == 0);
 
 	if (is_a2(pdev)) {
-		/* Shorten SAS SNW lock time (RxLock timer value from 76 us to 50 us) */
-		writel(0x7bcc96ad, &ihost->scu_registers->afe.afe_pmsn_master_control0);
+		/* Shorten SAS SNW lock time (RxLock timer value from 76
+		 * us to 50 us)
+		 */
+		writel(0x7bcc96ad, &afe->afe_pmsn_master_control0);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 	}
 
 	for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
+		struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id];
 		const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
 
 		if (is_b0(pdev)) {
 			 /* Configure transmitter SSC parameters */
-			writel(0x00030000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
+			writel(0x00030000, &xcvr->afe_tx_ssc_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		} else if (is_c0(pdev)) {
 			 /* Configure transmitter SSC parameters */
-			writel(0x0003000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
+			writel(0x0003000, &xcvr->afe_tx_ssc_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
-			/*
-			 * All defaults, except the Receive Word Alignament/Comma Detect
-			 * Enable....(0xe800) */
-			writel(0x00004500, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+			/* All defaults, except the Receive Word
+			 * Alignament/Comma Detect Enable....(0xe800)
+			 */
+			writel(0x00004500, &xcvr->afe_xcvr_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		} else {
-			/*
-			 * All defaults, except the Receive Word Alignament/Comma Detect
-			 * Enable....(0xe800) */
-			writel(0x00004512, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+			/* All defaults, except the Receive Word
+			 * Alignament/Comma Detect Enable....(0xe800)
+			 */
+			writel(0x00004512, &xcvr->afe_xcvr_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
-			writel(0x0050100F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control1);
+			writel(0x0050100F, &xcvr->afe_xcvr_control1);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		}
 
-		/*
-		 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
-		 * & increase TX int & ext bias 20%....(0xe85c) */
+		/* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
+		 * & increase TX int & ext bias 20%....(0xe85c)
+		 */
 		if (is_a2(pdev))
-			writel(0x000003F0, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			writel(0x000003F0, &xcvr->afe_channel_control);
 		else if (is_b0(pdev)) {
 			 /* Power down TX and RX (PWRDNTX and PWRDNRX) */
-			writel(0x000003D7, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			writel(0x000003D7, &xcvr->afe_channel_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
-
-			/*
-			 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
-			 * & increase TX int & ext bias 20%....(0xe85c) */
-			writel(0x000003D4, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			writel(0x000003D4, &xcvr->afe_channel_control);
 		} else {
-			writel(0x000001E7, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			writel(0x000001E7, &xcvr->afe_channel_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
-
-			/*
-			 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
-			 * & increase TX int & ext bias 20%....(0xe85c) */
-			writel(0x000001E4, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			writel(0x000001E4, &xcvr->afe_channel_control);
 		}
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
 		if (is_a2(pdev)) {
 			/* Enable TX equalization (0xe824) */
-			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+			writel(0x00040000, &xcvr->afe_tx_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		}
 
-		/*
-		 * RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0, TPD=0x0(TX Power On),
-		 * RDD=0x0(RX Detect Enabled) ....(0xe800) */
-		writel(0x00004100, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+		writel(0x00004100, &xcvr->afe_xcvr_control0);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
 		/* Leave DFE/FFE on */
 		if (is_a2(pdev))
-			writel(0x3F11103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+			writel(0x3F11103F, &xcvr->afe_rx_ssc_control0);
 		else if (is_b0(pdev)) {
-			writel(0x3F11103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+			writel(0x3F11103F, &xcvr->afe_rx_ssc_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 			/* Enable TX equalization (0xe824) */
-			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+			writel(0x00040000, &xcvr->afe_tx_control);
 		} else {
-			writel(0x0140DF0F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control1);
+			writel(0x0140DF0F, &xcvr->afe_rx_ssc_control1);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
-			writel(0x3F6F103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+			writel(0x3F6F103F, &xcvr->afe_rx_ssc_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
 			/* Enable TX equalization (0xe824) */
-			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+			writel(0x00040000, &xcvr->afe_tx_control);
 		}
 
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
-		writel(oem_phy->afe_tx_amp_control0,
-			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control0);
+		writel(oem_phy->afe_tx_amp_control0, &xcvr->afe_tx_amp_control0);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
-		writel(oem_phy->afe_tx_amp_control1,
-			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control1);
+		writel(oem_phy->afe_tx_amp_control1, &xcvr->afe_tx_amp_control1);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
-		writel(oem_phy->afe_tx_amp_control2,
-			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control2);
+		writel(oem_phy->afe_tx_amp_control2, &xcvr->afe_tx_amp_control2);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
-		writel(oem_phy->afe_tx_amp_control3,
-			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control3);
+		writel(oem_phy->afe_tx_amp_control3, &xcvr->afe_tx_amp_control3);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 	}
 
 	/* Transfer control to the PEs */
-	writel(0x00010f00, &ihost->scu_registers->afe.afe_dfx_master_control0);
+	writel(0x00010f00, &afe->afe_dfx_master_control0);
 	udelay(AFE_REGISTER_WRITE_DELAY);
 }
 
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 35f50c2..0ae0990 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -91,22 +91,23 @@ sci_phy_transport_layer_initialization(struct isci_phy *iphy,
 
 static enum sci_status
 sci_phy_link_layer_initialization(struct isci_phy *iphy,
-				  struct scu_link_layer_registers __iomem *reg)
+				  struct scu_link_layer_registers __iomem *llr)
 {
 	struct isci_host *ihost = iphy->owning_port->owning_controller;
+	struct sci_phy_user_params *phy_user;
+	struct sci_phy_oem_params *phy_oem;
 	int phy_idx = iphy->phy_index;
-	struct sci_phy_user_params *phy_user = &ihost->user_parameters.phys[phy_idx];
-	struct sci_phy_oem_params *phy_oem =
-		&ihost->oem_parameters.phys[phy_idx];
-	u32 phy_configuration;
 	struct sci_phy_cap phy_cap;
+	u32 phy_configuration;
 	u32 parity_check = 0;
 	u32 parity_count = 0;
 	u32 llctl, link_rate;
 	u32 clksm_value = 0;
 	u32 sp_timeouts = 0;
 
-	iphy->link_layer_registers = reg;
+	phy_user = &ihost->user_parameters.phys[phy_idx];
+	phy_oem = &ihost->oem_parameters.phys[phy_idx];
+	iphy->link_layer_registers = llr;
 
 	/* Set our IDENTIFY frame data */
 	#define SCI_END_DEVICE 0x01
@@ -116,32 +117,26 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 	       SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
 	       SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
 	       SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
-	       &iphy->link_layer_registers->transmit_identification);
+	       &llr->transmit_identification);
 
 	/* Write the device SAS Address */
-	writel(0xFEDCBA98,
-	       &iphy->link_layer_registers->sas_device_name_high);
-	writel(phy_idx, &iphy->link_layer_registers->sas_device_name_low);
+	writel(0xFEDCBA98, &llr->sas_device_name_high);
+	writel(phy_idx, &llr->sas_device_name_low);
 
 	/* Write the source SAS Address */
-	writel(phy_oem->sas_address.high,
-		&iphy->link_layer_registers->source_sas_address_high);
-	writel(phy_oem->sas_address.low,
-		&iphy->link_layer_registers->source_sas_address_low);
+	writel(phy_oem->sas_address.high, &llr->source_sas_address_high);
+	writel(phy_oem->sas_address.low, &llr->source_sas_address_low);
 
 	/* Clear and Set the PHY Identifier */
-	writel(0, &iphy->link_layer_registers->identify_frame_phy_id);
-	writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
-		&iphy->link_layer_registers->identify_frame_phy_id);
+	writel(0, &llr->identify_frame_phy_id);
+	writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx), &llr->identify_frame_phy_id);
 
 	/* Change the initial state of the phy configuration register */
-	phy_configuration =
-		readl(&iphy->link_layer_registers->phy_configuration);
+	phy_configuration = readl(&llr->phy_configuration);
 
 	/* Hold OOB state machine in reset */
 	phy_configuration |=  SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
-	writel(phy_configuration,
-		&iphy->link_layer_registers->phy_configuration);
+	writel(phy_configuration, &llr->phy_configuration);
 
 	/* Configure the SNW capabilities */
 	phy_cap.all = 0;
@@ -155,9 +150,9 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 		phy_cap.gen1_ssc = 1;
 	}
 
-	/*
-	 * The SAS specification indicates that the phy_capabilities that
-	 * are transmitted shall have an even parity.  Calculate the parity. */
+	/* The SAS specification indicates that the phy_capabilities that
+	 * are transmitted shall have an even parity.  Calculate the parity.
+	 */
 	parity_check = phy_cap.all;
 	while (parity_check != 0) {
 		if (parity_check & 0x1)
@@ -165,20 +160,20 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 		parity_check >>= 1;
 	}
 
-	/*
-	 * If parity indicates there are an odd number of bits set, then
-	 * set the parity bit to 1 in the phy capabilities. */
+	/* If parity indicates there are an odd number of bits set, then
+	 * set the parity bit to 1 in the phy capabilities.
+	 */
 	if ((parity_count % 2) != 0)
 		phy_cap.parity = 1;
 
-	writel(phy_cap.all, &iphy->link_layer_registers->phy_capabilities);
+	writel(phy_cap.all, &llr->phy_capabilities);
 
 	/* Set the enable spinup period but disable the ability to send
 	 * notify enable spinup
 	 */
 	writel(SCU_ENSPINUP_GEN_VAL(COUNT,
 			phy_user->notify_enable_spin_up_insertion_frequency),
-		&iphy->link_layer_registers->notify_enable_spinup_control);
+		&llr->notify_enable_spinup_control);
 
 	/* Write the ALIGN Insertion Ferequency for connected phy and
 	 * inpendent of connected state
@@ -189,11 +184,10 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 	clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
 			phy_user->align_insertion_frequency);
 
-	writel(clksm_value, &iphy->link_layer_registers->clock_skew_management);
+	writel(clksm_value, &llr->clock_skew_management);
 
 	/* @todo Provide a way to write this register correctly */
-	writel(0x02108421,
-		&iphy->link_layer_registers->afe_lookup_table_control);
+	writel(0x02108421, &llr->afe_lookup_table_control);
 
 	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
 		(u8)ihost->user_parameters.no_outbound_task_timeout);
@@ -210,9 +204,9 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 		break;
 	}
 	llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
-	writel(llctl, &iphy->link_layer_registers->link_layer_control);
+	writel(llctl, &llr->link_layer_control);
 
-	sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
+	sp_timeouts = readl(&llr->sas_phy_timeouts);
 
 	/* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
 	sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
@@ -222,20 +216,23 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 	 */
 	sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
 
-	writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
+	writel(sp_timeouts, &llr->sas_phy_timeouts);
 
 	if (is_a2(ihost->pdev)) {
-		/* Program the max ARB time for the PHY to 700us so we inter-operate with
-		 * the PMC expander which shuts down PHYs if the expander PHY generates too
-		 * many breaks.  This time value will guarantee that the initiator PHY will
-		 * generate the break.
+		/* Program the max ARB time for the PHY to 700us so we
+		 * inter-operate with the PMC expander which shuts down
+		 * PHYs if the expander PHY generates too many breaks.
+		 * This time value will guarantee that the initiator PHY
+		 * will generate the break.
 		 */
 		writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
-			&iphy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
+		       &llr->maximum_arbitration_wait_timer_timeout);
 	}
 
-	/* Disable link layer hang detection, rely on the OS timeout for I/O timeouts. */
-	writel(0, &iphy->link_layer_registers->link_layer_hang_detection_timeout);
+	/* Disable link layer hang detection, rely on the OS timeout for
+	 * I/O timeouts.
+	 */
+	writel(0, &llr->link_layer_hang_detection_timeout);
 
 	/* We can exit the initial state to the stopped state */
 	sci_change_state(&iphy->sm, SCI_PHY_STOPPED);


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 2/8] isci: update afe (analog-front-end) recipe for C1
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 1/8] isci: cleanup oem parameter and recipe handling Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 3/8] isci: oem parameter format v1.1 (ssc select) Dan Williams
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Jeff Skirvin, Marcin Tomczak, Jiangbi Liu

From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>

C1 silicon requires updates to the phy tuning recipe and also support
for user provided cable selects (per-phy) for short, medium, and long
cables.  Default to 'short' awaiting support for selecting the cable via
oem parameters.

Reviewed-by: Jiangbi Liu <jiangbi.liu@intel.com>
Signed-off-by: Marcin Tomczak <marcin.tomczak@intel.com>
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/host.c       |  107 +++++++++++++++++++++++++++++++++-------
 drivers/scsi/isci/host.h       |    9 +++
 drivers/scsi/isci/phy.c        |    7 ++-
 drivers/scsi/isci/probe_roms.c |    2 -
 4 files changed, 101 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 8e7de19..e1d844d 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1908,12 +1908,23 @@ void sci_controller_power_control_queue_remove(struct isci_host *ihost,
 	ihost->power_control.requesters[iphy->phy_index] = NULL;
 }
 
+static int is_long_cable(int phy, unsigned char selection_byte)
+{
+	return 0;
+}
+
+static int is_medium_cable(int phy, unsigned char selection_byte)
+{
+	return 0;
+}
+
 #define AFE_REGISTER_WRITE_DELAY 10
 
 static void sci_controller_afe_initialization(struct isci_host *ihost)
 {
 	struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
 	const struct sci_oem_params *oem = &ihost->oem_parameters;
+	unsigned char cable_selection_mask = 0;
 	struct pci_dev *pdev = ihost->pdev;
 	u32 afe_status;
 	u32 phy_id;
@@ -1922,11 +1933,11 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 	writel(0x0081000f, &afe->afe_dfx_master_control0);
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
-	if (is_b0(pdev)) {
+	if (is_b0(pdev) || is_c0(pdev) || is_c1(pdev)) {
 		/* PM Rx Equalization Save, PM SPhy Rx Acknowledgement
 		 * Timer, PM Stagger Timer
 		 */
-		writel(0x0007BFFF, &afe->afe_pmsn_master_control2);
+		writel(0x0007FFFF, &afe->afe_pmsn_master_control2);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 	}
 
@@ -1935,14 +1946,23 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 		writel(0x00005A00, &afe->afe_bias_control);
 	else if (is_b0(pdev) || is_c0(pdev))
 		writel(0x00005F00, &afe->afe_bias_control);
+	else if (is_c1(pdev))
+		writel(0x00005500, &afe->afe_bias_control);
 
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
 	/* Enable PLL */
-	if (is_b0(pdev) || is_c0(pdev))
-		writel(0x80040A08, &afe->afe_pll_control0);
-	else
+	if (is_a2(pdev))
 		writel(0x80040908, &afe->afe_pll_control0);
+	else if (is_b0(pdev) || is_c0(pdev))
+		writel(0x80040A08, &afe->afe_pll_control0);
+	else if (is_c1(pdev)) {
+		writel(0x80000B08, &afe->afe_pll_control0);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+		writel(0x00000B08, &afe->afe_pll_control0);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+		writel(0x80000B08, &afe->afe_pll_control0);
+	}
 
 	udelay(AFE_REGISTER_WRITE_DELAY);
 
@@ -1963,46 +1983,68 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 	for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
 		struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id];
 		const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
+		int cable_length_long =
+			is_long_cable(phy_id, cable_selection_mask);
+		int cable_length_medium =
+			is_medium_cable(phy_id, cable_selection_mask);
+
+		if (is_a2(pdev)) {
+			/* All defaults, except the Receive Word
+			 * Alignament/Comma Detect Enable....(0xe800)
+			 */
+			writel(0x00004512, &xcvr->afe_xcvr_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
 
-		if (is_b0(pdev)) {
+			writel(0x0050100F, &xcvr->afe_xcvr_control1);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+		} else if (is_b0(pdev)) {
 			 /* Configure transmitter SSC parameters */
 			writel(0x00030000, &xcvr->afe_tx_ssc_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		} else if (is_c0(pdev)) {
 			 /* Configure transmitter SSC parameters */
-			writel(0x0003000, &xcvr->afe_tx_ssc_control);
+			writel(0x00010202, &xcvr->afe_tx_ssc_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
 			/* All defaults, except the Receive Word
 			 * Alignament/Comma Detect Enable....(0xe800)
 			 */
-			writel(0x00004500, &xcvr->afe_xcvr_control0);
+			writel(0x00014500, &xcvr->afe_xcvr_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
-		} else {
+		} else if (is_c1(pdev)) {
+			/* Configure transmitter SSC parameters */
+			writel(0x00010202, &xcvr->afe_tx_ssc_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
 			/* All defaults, except the Receive Word
 			 * Alignament/Comma Detect Enable....(0xe800)
 			 */
-			writel(0x00004512, &xcvr->afe_xcvr_control0);
-			udelay(AFE_REGISTER_WRITE_DELAY);
-
-			writel(0x0050100F, &xcvr->afe_xcvr_control1);
+			writel(0x0001C500, &xcvr->afe_xcvr_control0);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		}
 
-		/* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
-		 * & increase TX int & ext bias 20%....(0xe85c)
+		/* Power up TX and RX out from power down (PWRDNTX and
+		 * PWRDNRX) & increase TX int & ext bias 20%....(0xe85c)
 		 */
 		if (is_a2(pdev))
 			writel(0x000003F0, &xcvr->afe_channel_control);
 		else if (is_b0(pdev)) {
-			 /* Power down TX and RX (PWRDNTX and PWRDNRX) */
 			writel(0x000003D7, &xcvr->afe_channel_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
+
 			writel(0x000003D4, &xcvr->afe_channel_control);
-		} else {
+		} else if (is_c0(pdev)) {
 			writel(0x000001E7, &xcvr->afe_channel_control);
 			udelay(AFE_REGISTER_WRITE_DELAY);
+
 			writel(0x000001E4, &xcvr->afe_channel_control);
+		} else if (is_c1(pdev)) {
+			writel(cable_length_long ? 0x000002F7 : 0x000001F7,
+			       &xcvr->afe_channel_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			writel(cable_length_long ? 0x000002F4 : 0x000001F4,
+			       &xcvr->afe_channel_control);
 		}
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
@@ -2012,7 +2054,16 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 			udelay(AFE_REGISTER_WRITE_DELAY);
 		}
 
-		writel(0x00004100, &xcvr->afe_xcvr_control0);
+		if (is_a2(pdev) || is_b0(pdev))
+			/* RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0,
+			 * TPD=0x0(TX Power On), RDD=0x0(RX Detect
+			 * Enabled) ....(0xe800)
+			 */
+			writel(0x00004100, &xcvr->afe_xcvr_control0);
+		else if (is_c0(pdev))
+			writel(0x00014100, &xcvr->afe_xcvr_control0);
+		else if (is_c1(pdev))
+			writel(0x0001C100, &xcvr->afe_xcvr_control0);
 		udelay(AFE_REGISTER_WRITE_DELAY);
 
 		/* Leave DFE/FFE on */
@@ -2023,8 +2074,8 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 			udelay(AFE_REGISTER_WRITE_DELAY);
 			/* Enable TX equalization (0xe824) */
 			writel(0x00040000, &xcvr->afe_tx_control);
-		} else {
-			writel(0x0140DF0F, &xcvr->afe_rx_ssc_control1);
+		} else if (is_c0(pdev)) {
+			writel(0x01400C0F, &xcvr->afe_rx_ssc_control1);
 			udelay(AFE_REGISTER_WRITE_DELAY);
 
 			writel(0x3F6F103F, &xcvr->afe_rx_ssc_control0);
@@ -2032,6 +2083,22 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 
 			/* Enable TX equalization (0xe824) */
 			writel(0x00040000, &xcvr->afe_tx_control);
+		} else if (is_c1(pdev)) {
+			writel(cable_length_long ? 0x01500C0C :
+			       cable_length_medium ? 0x01400C0D : 0x02400C0D,
+			       &xcvr->afe_xcvr_control1);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			writel(0x000003E0, &xcvr->afe_dfx_rx_control1);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			writel(cable_length_long ? 0x33091C1F :
+			       cable_length_medium ? 0x3315181F : 0x2B17161F,
+			       &xcvr->afe_rx_ssc_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			/* Enable TX equalization (0xe824) */
+			writel(0x00040000, &xcvr->afe_tx_control);
 		}
 
 		udelay(AFE_REGISTER_WRITE_DELAY);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 646051a..4573075 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -435,7 +435,14 @@ static inline bool is_b0(struct pci_dev *pdev)
 
 static inline bool is_c0(struct pci_dev *pdev)
 {
-	if (pdev->revision >= 5)
+	if (pdev->revision == 5)
+		return true;
+	return false;
+}
+
+static inline bool is_c1(struct pci_dev *pdev)
+{
+	if (pdev->revision >= 6)
 		return true;
 	return false;
 }
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 0ae0990..c650d30 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -186,8 +186,11 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 
 	writel(clksm_value, &llr->clock_skew_management);
 
-	/* @todo Provide a way to write this register correctly */
-	writel(0x02108421, &llr->afe_lookup_table_control);
+	if (is_c0(ihost->pdev) || is_c1(ihost->pdev)) {
+		writel(0x04210400, &llr->afe_lookup_table_control);
+		writel(0x020A7C05, &llr->sas_primitive_timeout);
+	} else
+		writel(0x02108421, &llr->afe_lookup_table_control);
 
 	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
 		(u8)ihost->user_parameters.no_outbound_task_timeout);
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index b5f4341..9b8117b 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -147,7 +147,7 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw
 
 	memcpy(orom, fw->data, fw->size);
 
-	if (is_c0(pdev))
+	if (is_c0(pdev) || is_c1(pdev))
 		goto out;
 
 	/*


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 3/8] isci: oem parameter format v1.1 (ssc select)
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 1/8] isci: cleanup oem parameter and recipe handling Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 2/8] isci: update afe (analog-front-end) recipe for C1 Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 4/8] isci: oem parameter format v1.3 (cable select) Dan Williams
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Dave Jiang

From: Dave Jiang <dave.jiang@intel.com>

v1.1 allows finer grained tuning of the SSC (spread-spectrum-clocking)
settings for SAS and SATA.  See notes in probe_roms.h

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/firmware/create_fw.h |   11 +++++--
 drivers/scsi/isci/host.c               |   47 +++++++++++++++++++++++++++-
 drivers/scsi/isci/init.c               |    3 +-
 drivers/scsi/isci/phy.c                |   51 ++++++++++++++++++++++++++++++-
 drivers/scsi/isci/probe_roms.h         |   53 +++++++++++++++++++++++++++++++-
 firmware/isci/isci_firmware.bin.ihex   |    2 +
 6 files changed, 158 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/isci/firmware/create_fw.h b/drivers/scsi/isci/firmware/create_fw.h
index 5f29882..e12dbd7 100644
--- a/drivers/scsi/isci/firmware/create_fw.h
+++ b/drivers/scsi/isci/firmware/create_fw.h
@@ -62,7 +62,14 @@ static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFF00000001ULL,
 static const int max_num_concurrent_dev_spin_up = 1;
 
 /* enable of ssc operation */
-static const int enable_ssc;
+/*
+ * NOTE: also see probe_roms.h. This value can be set for ssc values.
+ * Values can be set for:
+ * ssc_sata_tx_spread_level
+ * ssc_sas_tx_spread_level
+ * ssc_sas_tx_type
+ */
+static const __u8 enable_ssc;
 
 /* AFE_TX_AMP_CONTROL */
 static const unsigned int afe_tx_amp_control0 = 0x000bdd08;
@@ -72,6 +79,6 @@ static const unsigned int afe_tx_amp_control3 = 0x000afc6e;
 
 static const char blob_name[] = "isci_firmware.bin";
 static const char sig[] = "ISCUOEMB";
-static const unsigned char version = 0x10;
+static const unsigned char version = ISCI_ROM_VER_LATEST;
 
 #endif
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index e1d844d..2521cee 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1759,7 +1759,7 @@ static enum sci_status sci_controller_construct(struct isci_host *ihost,
 	return sci_controller_reset(ihost);
 }
 
-int sci_oem_parameters_validate(struct sci_oem_params *oem)
+int sci_oem_parameters_validate(struct sci_oem_params *oem, u8 version)
 {
 	int i;
 
@@ -1791,18 +1791,61 @@ int sci_oem_parameters_validate(struct sci_oem_params *oem)
 	    oem->controller.max_concurr_spin_up < 1)
 		return -EINVAL;
 
+	if (oem->controller.do_enable_ssc) {
+		if (version < ISCI_ROM_VER_1_1 && oem->controller.do_enable_ssc != 1)
+			return -EINVAL;
+
+		if (version >= ISCI_ROM_VER_1_1) {
+			u8 test = oem->controller.ssc_sata_tx_spread_level;
+
+			switch (test) {
+			case 0:
+			case 2:
+			case 3:
+			case 6:
+			case 7:
+				break;
+			default:
+				return -EINVAL;
+			}
+
+			test = oem->controller.ssc_sas_tx_spread_level;
+			if (oem->controller.ssc_sas_tx_type == 0) {
+				switch (test) {
+				case 0:
+				case 2:
+				case 3:
+					break;
+				default:
+					return -EINVAL;
+				}
+			} else if (oem->controller.ssc_sas_tx_type == 1) {
+				switch (test) {
+				case 0:
+				case 3:
+				case 6:
+					break;
+				default:
+					return -EINVAL;
+				}
+			}
+		}
+	}
+
 	return 0;
 }
 
 static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
 {
 	u32 state = ihost->sm.current_state_id;
+	struct isci_pci_info *pci_info = to_pci_info(ihost->pdev);
 
 	if (state == SCIC_RESET ||
 	    state == SCIC_INITIALIZING ||
 	    state == SCIC_INITIALIZED) {
 
-		if (sci_oem_parameters_validate(&ihost->oem_parameters))
+		if (sci_oem_parameters_validate(&ihost->oem_parameters,
+						pci_info->orom->hdr.version))
 			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
 
 		return SCI_SUCCESS;
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index a97edab..8a34fd9 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -466,7 +466,8 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
 		orom = isci_request_oprom(pdev);
 
 	for (i = 0; orom && i < ARRAY_SIZE(orom->ctrl); i++) {
-		if (sci_oem_parameters_validate(&orom->ctrl[i])) {
+		if (sci_oem_parameters_validate(&orom->ctrl[i],
+						orom->hdr.version)) {
 			dev_warn(&pdev->dev,
 				 "[%d]: invalid oem parameters detected, falling back to firmware\n", i);
 			devm_kfree(&pdev->dev, orom);
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index c650d30..61000cd 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -144,10 +144,59 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
 	phy_cap.gen3_no_ssc = 1;
 	phy_cap.gen2_no_ssc = 1;
 	phy_cap.gen1_no_ssc = 1;
-	if (ihost->oem_parameters.controller.do_enable_ssc == true) {
+	if (ihost->oem_parameters.controller.do_enable_ssc) {
+		struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
+		struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_idx];
+		struct isci_pci_info *pci_info = to_pci_info(ihost->pdev);
+		bool en_sas = false;
+		bool en_sata = false;
+		u32 sas_type = 0;
+		u32 sata_spread = 0x2;
+		u32 sas_spread = 0x2;
+
 		phy_cap.gen3_ssc = 1;
 		phy_cap.gen2_ssc = 1;
 		phy_cap.gen1_ssc = 1;
+
+		if (pci_info->orom->hdr.version < ISCI_ROM_VER_1_1)
+			en_sas = en_sata = true;
+		else {
+			sata_spread = ihost->oem_parameters.controller.ssc_sata_tx_spread_level;
+			sas_spread = ihost->oem_parameters.controller.ssc_sas_tx_spread_level;
+
+			if (sata_spread)
+				en_sata = true;
+
+			if (sas_spread) {
+				en_sas = true;
+				sas_type = ihost->oem_parameters.controller.ssc_sas_tx_type;
+			}
+
+		}
+
+		if (en_sas) {
+			u32 reg;
+
+			reg = readl(&xcvr->afe_xcvr_control0);
+			reg |= (0x00100000 | (sas_type << 19));
+			writel(reg, &xcvr->afe_xcvr_control0);
+
+			reg = readl(&xcvr->afe_tx_ssc_control);
+			reg |= sas_spread << 8;
+			writel(reg, &xcvr->afe_tx_ssc_control);
+		}
+
+		if (en_sata) {
+			u32 reg;
+
+			reg = readl(&xcvr->afe_tx_ssc_control);
+			reg |= sata_spread;
+			writel(reg, &xcvr->afe_tx_ssc_control);
+
+			reg = readl(&llr->stp_control);
+			reg |= 1 << 12;
+			writel(reg, &llr->stp_control);
+		}
 	}
 
 	/* The SAS specification indicates that the phy_capabilities that
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h
index 2c75248..42dd054 100644
--- a/drivers/scsi/isci/probe_roms.h
+++ b/drivers/scsi/isci/probe_roms.h
@@ -152,7 +152,7 @@ struct sci_user_parameters {
 #define MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT 4
 
 struct sci_oem_params;
-int sci_oem_parameters_validate(struct sci_oem_params *oem);
+int sci_oem_parameters_validate(struct sci_oem_params *oem, u8 version);
 
 struct isci_orom;
 struct isci_orom *isci_request_oprom(struct pci_dev *pdev);
@@ -191,6 +191,10 @@ struct isci_oem_hdr {
 			0x1a, 0x04, 0xc6)
 #define ISCI_EFI_VAR_NAME	"RstScuO"
 
+#define ISCI_ROM_VER_1_0	0x10
+#define ISCI_ROM_VER_1_1	0x11
+#define ISCI_ROM_VER_LATEST	ISCI_ROM_VER_1_1
+
 /* Allowed PORT configuration modes APC Automatic PORT configuration mode is
  * defined by the OEM configuration parameters providing no PHY_MASK parameters
  * for any PORT. i.e. There are no phys assigned to any of the ports at start.
@@ -220,7 +224,52 @@ struct sci_oem_params {
 	struct {
 		uint8_t mode_type;
 		uint8_t max_concurr_spin_up;
-		uint8_t do_enable_ssc;
+		/*
+		 * This bitfield indicates the OEM's desired default Tx
+		 * Spread Spectrum Clocking (SSC) settings for SATA and SAS.
+		 * NOTE: Default SSC Modulation Frequency is 31.5KHz.
+		 */
+		union {
+			struct {
+			/*
+			 * NOTE: Max spread for SATA is +0 / -5000 PPM.
+			 * Down-spreading SSC (only method allowed for SATA):
+			 *  SATA SSC Tx Disabled                    = 0x0
+			 *  SATA SSC Tx at +0 / -1419 PPM Spread    = 0x2
+			 *  SATA SSC Tx at +0 / -2129 PPM Spread    = 0x3
+			 *  SATA SSC Tx at +0 / -4257 PPM Spread    = 0x6
+			 *  SATA SSC Tx at +0 / -4967 PPM Spread    = 0x7
+			 */
+				uint8_t ssc_sata_tx_spread_level:4;
+			/*
+			 * SAS SSC Tx Disabled                     = 0x0
+			 *
+			 * NOTE: Max spread for SAS down-spreading +0 /
+			 *	 -2300 PPM
+			 * Down-spreading SSC:
+			 *  SAS SSC Tx at +0 / -1419 PPM Spread     = 0x2
+			 *  SAS SSC Tx at +0 / -2129 PPM Spread     = 0x3
+			 *
+			 * NOTE: Max spread for SAS center-spreading +2300 /
+			 *	 -2300 PPM
+			 * Center-spreading SSC:
+			 *  SAS SSC Tx at +1064 / -1064 PPM Spread  = 0x3
+			 *  SAS SSC Tx at +2129 / -2129 PPM Spread  = 0x6
+			 */
+				uint8_t ssc_sas_tx_spread_level:3;
+			/*
+			 * NOTE: Refer to the SSC section of the SAS 2.x
+			 * Specification for proper setting of this field.
+			 * For standard SAS Initiator SAS PHY operation it
+			 * should be 0 for Down-spreading.
+			 * SAS SSC Tx spread type:
+			 *  Down-spreading SSC      = 0
+			 *  Center-spreading SSC    = 1
+			 */
+				uint8_t ssc_sas_tx_type:1;
+			};
+			uint8_t do_enable_ssc;
+		};
 		uint8_t reserved;
 	} controller;
 
diff --git a/firmware/isci/isci_firmware.bin.ihex b/firmware/isci/isci_firmware.bin.ihex
index 2e66195..daab5ba 100644
--- a/firmware/isci/isci_firmware.bin.ihex
+++ b/firmware/isci/isci_firmware.bin.ihex
@@ -1,4 +1,4 @@
-:10000000495343554F454D42E80018100002000087
+:10000000495343554F454D42E80018110002000086
 :1000100000000000000000000101000000000000DE
 :10002000FFFFCF5F0100000008DD0B0000FC0F00A8
 :10003000097C0B006EFC0A00FFFFCF5F010000008F


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 4/8] isci: oem parameter format v1.3 (cable select)
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (2 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 3/8] isci: oem parameter format v1.1 (ssc select) Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 5/8] isci: performance-fix, shorten default "no outbound task" timeout Dan Williams
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Jeff Skirvin, Jiangbi Liu

From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>

v1.3 allows the attenuation of the attached cables to be specified to
the driver in terms of 'short', 'medium', and 'long' (see probe_roms.h).
These settings (per phy) are retrieved from the platform oem-parameters
(BIOS rom) or via a module parameter override.

Reviewed-by: Jiangbi Liu <jiangbi.liu@intel.com>
Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/firmware/create_fw.c |    6 ++++
 drivers/scsi/isci/firmware/create_fw.h |    2 +
 drivers/scsi/isci/host.c               |   43 ++++++++++++++++++++++++++++++--
 drivers/scsi/isci/host.h               |   18 +++++++++++++
 drivers/scsi/isci/init.c               |   16 ++++++++++++
 drivers/scsi/isci/isci.h               |    1 +
 drivers/scsi/isci/probe_roms.h         |   38 +++++++++++++++++++++++++++-
 7 files changed, 119 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/isci/firmware/create_fw.c b/drivers/scsi/isci/firmware/create_fw.c
index 36eabef..fd0674b 100644
--- a/drivers/scsi/isci/firmware/create_fw.c
+++ b/drivers/scsi/isci/firmware/create_fw.c
@@ -51,6 +51,7 @@ void set_binary_values(struct isci_orom *isci_orom)
 
 	for (c = 0; c < 2; c++) {
 		struct sci_oem_params *ctrl = &isci_orom->ctrl[c];
+		__u8 cable_selection_mask = 0;
 
 		ctrl->controller.mode_type = mode_type;
 		ctrl->controller.max_concurr_spin_up = max_num_concurrent_dev_spin_up;
@@ -61,6 +62,7 @@ void set_binary_values(struct isci_orom *isci_orom)
 
 		for (phy_idx = 0; phy_idx < SCI_MAX_PHYS; phy_idx++) {
 			struct sci_phy_oem_params *phy = &ctrl->phys[phy_idx];
+			__u8 cable_phy = cable_selection[c][phy_idx];
 
 			phy->sas_address.high = sas_addr[c][phy_idx] >> 32;
 			phy->sas_address.low = sas_addr[c][phy_idx];
@@ -69,7 +71,11 @@ void set_binary_values(struct isci_orom *isci_orom)
 			phy->afe_tx_amp_control1 = afe_tx_amp_control1;
 			phy->afe_tx_amp_control2 = afe_tx_amp_control2;
 			phy->afe_tx_amp_control3 = afe_tx_amp_control3;
+
+			cable_selection_mask |= (cable_phy & 1) << phy_idx;
+			cable_selection_mask |= (cable_phy & 2) << (phy_idx + 3);
 		}
+		ctrl->controller.cable_selection_mask = cable_selection_mask;
 	}
 }
 
diff --git a/drivers/scsi/isci/firmware/create_fw.h b/drivers/scsi/isci/firmware/create_fw.h
index e12dbd7..0602813 100644
--- a/drivers/scsi/isci/firmware/create_fw.h
+++ b/drivers/scsi/isci/firmware/create_fw.h
@@ -58,6 +58,8 @@ static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFF00000001ULL,
 						     0x5FCFFFFF00000002ULL } };
 #endif
 
+static const int cable_selection[2][4];
+
 /* Maximum number of concurrent device spin up */
 static const int max_num_concurrent_dev_spin_up = 1;
 
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 2521cee..3374f1b 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1666,6 +1666,9 @@ static void sci_controller_set_default_config_parameters(struct isci_host *ihost
 	/* Default to no SSC operation. */
 	ihost->oem_parameters.controller.do_enable_ssc = false;
 
+	/* Default to short cables on all phys. */
+	ihost->oem_parameters.controller.cable_selection_mask = 0;
+
 	/* Initialize all of the port parameter information to narrow ports. */
 	for (index = 0; index < SCI_MAX_PORTS; index++) {
 		ihost->oem_parameters.ports[index].phy_mask = 0;
@@ -1953,12 +1956,46 @@ void sci_controller_power_control_queue_remove(struct isci_host *ihost,
 
 static int is_long_cable(int phy, unsigned char selection_byte)
 {
-	return 0;
+	return !!(selection_byte & (1 << phy));
 }
 
 static int is_medium_cable(int phy, unsigned char selection_byte)
 {
-	return 0;
+	return !!(selection_byte & (1 << (phy + 4)));
+}
+
+static enum cable_selections decode_selection_byte(
+	int phy,
+	unsigned char selection_byte)
+{
+	return ((selection_byte & (1 << phy)) ? 1 : 0)
+		+ (selection_byte & (1 << (phy + 4)) ? 2 : 0);
+}
+
+unsigned char *cable_selection_byte_ptr(struct isci_host *ihost)
+{
+	if (is_cable_select_overridden())
+		return ((unsigned char *)&cable_selection_override)
+			+ ihost->id;
+	else
+		return &ihost->oem_parameters.controller.cable_selection_mask;
+}
+
+enum cable_selections decode_cable_selection(struct isci_host *ihost, int phy)
+{
+	return decode_selection_byte(phy, *cable_selection_byte_ptr(ihost));
+}
+
+char *lookup_cable_names(enum cable_selections selection)
+{
+	static char *cable_names[] = {
+		[short_cable]     = "short",
+		[long_cable]      = "long",
+		[medium_cable]    = "medium",
+		[undefined_cable] = "<undefined, assumed long>" /* bit 0==1 */
+	};
+	return (selection <= undefined_cable) ? cable_names[selection]
+					      : cable_names[undefined_cable];
 }
 
 #define AFE_REGISTER_WRITE_DELAY 10
@@ -1967,10 +2004,10 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
 {
 	struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
 	const struct sci_oem_params *oem = &ihost->oem_parameters;
-	unsigned char cable_selection_mask = 0;
 	struct pci_dev *pdev = ihost->pdev;
 	u32 afe_status;
 	u32 phy_id;
+	unsigned char cable_selection_mask = *cable_selection_byte_ptr(ihost);
 
 	/* Clear DFX Status registers */
 	writel(0x0081000f, &afe->afe_dfx_master_control0);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 4573075..5477f0f 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -447,6 +447,24 @@ static inline bool is_c1(struct pci_dev *pdev)
 	return false;
 }
 
+enum cable_selections {
+	short_cable     = 0,
+	long_cable      = 1,
+	medium_cable    = 2,
+	undefined_cable = 3
+};
+
+#define CABLE_OVERRIDE_DISABLED (0x10000)
+
+static inline int is_cable_select_overridden(void)
+{
+	return cable_selection_override < CABLE_OVERRIDE_DISABLED;
+}
+
+enum cable_selections decode_cable_selection(struct isci_host *ihost, int phy);
+void validate_cable_selections(struct isci_host *ihost);
+char *lookup_cable_names(enum cable_selections);
+
 /* set hw control for 'activity', even though active enclosures seem to drive
  * the activity led on their own.  Skip setting FSENG control on 'status' due
  * to unexpected operation and 'error' due to not being a supported automatic
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 8a34fd9..1047108 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -122,6 +122,14 @@ unsigned char max_concurr_spinup;
 module_param(max_concurr_spinup, byte, 0);
 MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
 
+uint cable_selection_override = CABLE_OVERRIDE_DISABLED;
+module_param(cable_selection_override, uint, 0);
+
+MODULE_PARM_DESC(cable_selection_override,
+		 "This field indicates length of the SAS/SATA cable between "
+		 "host and device. If any bits > 15 are set (default) "
+		 "indicates \"use platform defaults\"");
+
 static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
 {
 	struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
@@ -412,6 +420,14 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
 		return NULL;
 	isci_host->shost = shost;
 
+	dev_info(&pdev->dev, "%sSCU controller %d: phy 3-0 cables: "
+		 "{%s, %s, %s, %s}\n",
+		 (is_cable_select_overridden() ? "* " : ""), isci_host->id,
+		 lookup_cable_names(decode_cable_selection(isci_host, 3)),
+		 lookup_cable_names(decode_cable_selection(isci_host, 2)),
+		 lookup_cable_names(decode_cable_selection(isci_host, 1)),
+		 lookup_cable_names(decode_cable_selection(isci_host, 0)));
+
 	err = isci_host_init(isci_host);
 	if (err)
 		goto err_shost;
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h
index 8efeb6b..234ab46 100644
--- a/drivers/scsi/isci/isci.h
+++ b/drivers/scsi/isci/isci.h
@@ -480,6 +480,7 @@ extern u16 ssp_inactive_to;
 extern u16 stp_inactive_to;
 extern unsigned char phy_gen;
 extern unsigned char max_concurr_spinup;
+extern uint cable_selection_override;
 
 irqreturn_t isci_msix_isr(int vec, void *data);
 irqreturn_t isci_intx_isr(int vec, void *data);
diff --git a/drivers/scsi/isci/probe_roms.h b/drivers/scsi/isci/probe_roms.h
index 42dd054..bb0e9d4 100644
--- a/drivers/scsi/isci/probe_roms.h
+++ b/drivers/scsi/isci/probe_roms.h
@@ -193,7 +193,8 @@ struct isci_oem_hdr {
 
 #define ISCI_ROM_VER_1_0	0x10
 #define ISCI_ROM_VER_1_1	0x11
-#define ISCI_ROM_VER_LATEST	ISCI_ROM_VER_1_1
+#define ISCI_ROM_VER_1_3	0x13
+#define ISCI_ROM_VER_LATEST	ISCI_ROM_VER_1_3
 
 /* Allowed PORT configuration modes APC Automatic PORT configuration mode is
  * defined by the OEM configuration parameters providing no PHY_MASK parameters
@@ -270,7 +271,40 @@ struct sci_oem_params {
 			};
 			uint8_t do_enable_ssc;
 		};
-		uint8_t reserved;
+		/*
+		 * This field indicates length of the SAS/SATA cable between
+		 * host and device.
+		 * This field is used make relationship between analog
+		 * parameters of the phy in the silicon and length of the cable.
+		 * Supported cable attenuation levels:
+		 * "short"- up to 3m, "medium"-3m to 6m, and "long"- more than
+		 * 6m.
+		 *
+		 * This is bit mask field:
+		 *
+		 * BIT:      (MSB) 7     6     5     4
+		 * ASSIGNMENT:   <phy3><phy2><phy1><phy0>  - Medium cable
+		 *                                           length assignment
+		 * BIT:            3     2     1     0  (LSB)
+		 * ASSIGNMENT:   <phy3><phy2><phy1><phy0>  - Long cable length
+		 *                                           assignment
+		 *
+		 * BITS 7-4 are set when the cable length is assigned to medium
+		 * BITS 3-0 are set when the cable length is assigned to long
+		 *
+		 * The BIT positions are clear when the cable length is
+		 * assigned to short.
+		 *
+		 * Setting the bits for both long and medium cable length is
+		 * undefined.
+		 *
+		 * A value of 0x84 would assign
+		 *    phy3 - medium
+		 *    phy2 - long
+		 *    phy1 - short
+		 *    phy0 - short
+		 */
+		uint8_t cable_selection_mask;
 	} controller;
 
 	struct {


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 5/8] isci: performance-fix, shorten default "no outbound task" timeout
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (3 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 4/8] isci: oem parameter format v1.3 (cable select) Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 6/8] isci: link speeds default to gen 2 Dan Williams
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Marcin Tomczak

From: Marcin Tomczak <marcin.tomczak@intel.com>

>From Richard Boyd:
"No task timeout timer reduced from 20 to 2 This timer controls how
long the SCU hardware will hold open the TX side of the connection
before sending a DONE.  The timer allows the hardware to attempt to
optimize the DONE/CLOSE behavior to allow for new COMMAND IU to be
posted.  In practice closing the connection quicker is better."

Signed-off-by: Marcin Tomczak <marcin.tomczak@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/host.c |    2 +-
 drivers/scsi/isci/init.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 3374f1b..ecaa7bb 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1697,7 +1697,7 @@ static void sci_controller_set_default_config_parameters(struct isci_host *ihost
 	ihost->user_parameters.ssp_inactivity_timeout = 5;
 	ihost->user_parameters.stp_max_occupancy_timeout = 5;
 	ihost->user_parameters.ssp_max_occupancy_timeout = 20;
-	ihost->user_parameters.no_outbound_task_timeout = 20;
+	ihost->user_parameters.no_outbound_task_timeout = 2;
 }
 
 static void controller_timeout(unsigned long data)
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 1047108..3c4ddad 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -94,7 +94,7 @@ MODULE_DEVICE_TABLE(pci, isci_id_table);
 
 /* linux isci specific settings */
 
-unsigned char no_outbound_task_to = 20;
+unsigned char no_outbound_task_to = 2;
 module_param(no_outbound_task_to, byte, 0);
 MODULE_PARM_DESC(no_outbound_task_to, "No Outbound Task Timeout (1us incr)");
 


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 6/8] isci: link speeds default to gen 2
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (4 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 5/8] isci: performance-fix, shorten default "no outbound task" timeout Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 7/8] isci: remove unused 'isci_tmf->device' field Dan Williams
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Jeff Skirvin

From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>

Gen-3 operation is marginal, default to gen-2 for now.

Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/host.c |    5 +++--
 drivers/scsi/isci/init.c |    2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index ecaa7bb..b09c36b 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1676,8 +1676,9 @@ static void sci_controller_set_default_config_parameters(struct isci_host *ihost
 
 	/* Initialize all of the phy parameter information. */
 	for (index = 0; index < SCI_MAX_PHYS; index++) {
-		/* Default to 6G (i.e. Gen 3) for now. */
-		ihost->user_parameters.phys[index].max_speed_generation = 3;
+		/* Default to 3G (i.e. Gen 2). */
+		ihost->user_parameters.phys[index].max_speed_generation =
+			SCIC_SDS_PARM_GEN2_SPEED;
 
 		/* the frequencies cannot be 0 */
 		ihost->user_parameters.phys[index].align_insertion_frequency = 0x7f;
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 3c4ddad..2bcfb40 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -114,7 +114,7 @@ u16 stp_inactive_to = 5;
 module_param(stp_inactive_to, ushort, 0);
 MODULE_PARM_DESC(stp_inactive_to, "STP inactivity timeout (100us incr)");
 
-unsigned char phy_gen = 3;
+unsigned char phy_gen = SCIC_SDS_PARM_GEN2_SPEED;
 module_param(phy_gen, byte, 0);
 MODULE_PARM_DESC(phy_gen, "PHY generation (1: 1.5Gbps 2: 3.0Gbps 3: 6.0Gbps)");
 


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 7/8] isci: remove unused 'isci_tmf->device' field
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (5 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 6/8] isci: link speeds default to gen 2 Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-17  0:53 ` [3.2-rc PATCH 8/8] isci: update version to 1.1 Dan Williams
  2011-12-18 13:49 ` [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates James Bottomley
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi; +Cc: Maciej Trela

From: Maciej Trela <maciej.trela@intel.com>

As the field was never set, isci_print_tmf() using 'isci_tmf->device'
sometimes causes a kernel crash if the dev_dbg() statement is enabled.
Remove the unused field both from isci_tmf struct definition and from
isci_print_tmf()

Signed-off-by: Maciej Trela <maciej.trela@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/isci/task.c |    2 +-
 drivers/scsi/isci/task.h |    7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 66ad3dc..f5a3f7d 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -496,7 +496,7 @@ static int isci_task_execute_tmf(struct isci_host *ihost,
 		}
 	}
 
-	isci_print_tmf(tmf);
+	isci_print_tmf(ihost, tmf);
 
 	if (tmf->status == SCI_SUCCESS)
 		ret =  TMF_RESP_FUNC_COMPLETE;
diff --git a/drivers/scsi/isci/task.h b/drivers/scsi/isci/task.h
index bc78c0a..1b27b37 100644
--- a/drivers/scsi/isci/task.h
+++ b/drivers/scsi/isci/task.h
@@ -106,7 +106,6 @@ struct isci_tmf {
 	} resp;
 	unsigned char lun[8];
 	u16 io_tag;
-	struct isci_remote_device *device;
 	enum isci_tmf_function_codes tmf_code;
 	int status;
 
@@ -120,10 +119,10 @@ struct isci_tmf {
 
 };
 
-static inline void isci_print_tmf(struct isci_tmf *tmf)
+static inline void isci_print_tmf(struct isci_host *ihost, struct isci_tmf *tmf)
 {
 	if (SAS_PROTOCOL_SATA == tmf->proto)
-		dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
+		dev_dbg(&ihost->pdev->dev,
 			"%s: status = %x\n"
 			"tmf->resp.d2h_fis.status = %x\n"
 			"tmf->resp.d2h_fis.error = %x\n",
@@ -132,7 +131,7 @@ static inline void isci_print_tmf(struct isci_tmf *tmf)
 			tmf->resp.d2h_fis.status,
 			tmf->resp.d2h_fis.error);
 	else
-		dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
+		dev_dbg(&ihost->pdev->dev,
 			"%s: status = %x\n"
 			"tmf->resp.resp_iu.data_present = %x\n"
 			"tmf->resp.resp_iu.status = %x\n"


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [3.2-rc PATCH 8/8] isci: update version to 1.1
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (6 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 7/8] isci: remove unused 'isci_tmf->device' field Dan Williams
@ 2011-12-17  0:53 ` Dan Williams
  2011-12-18 13:49 ` [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates James Bottomley
  8 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-17  0:53 UTC (permalink / raw)
  To: linux-scsi

Bump the version now that the driver has atapi support and the initial
round of hotplug fixes.  The EXPERIMENTAL tag should have been removed a
while back.  While we're here also kill the "select SCSI_SAS_HOST_SMP"
as the build error was separately fixed by commit d962480e "[SCSI]
libsas: fix try_test_sas_gpio_gp_bit() build error".

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/scsi/Kconfig     |    5 -----
 drivers/scsi/isci/init.c |    2 +-
 2 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 06ea3bc..16570aa 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -830,16 +830,11 @@ config SCSI_ISCI
 	tristate "Intel(R) C600 Series Chipset SAS Controller"
 	depends on PCI && SCSI
 	depends on X86
-	# (temporary): known alpha quality driver
-	depends on EXPERIMENTAL
 	select SCSI_SAS_LIBSAS
-	select SCSI_SAS_HOST_SMP
 	---help---
 	  This driver supports the 6Gb/s SAS capabilities of the storage
 	  control unit found in the Intel(R) C600 series chipset.
 
-	  The experimental tag will be removed after the driver exits alpha
-
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
 	depends on ISA && SCSI
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 2bcfb40..17c4c2c 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -65,7 +65,7 @@
 #include "probe_roms.h"
 
 #define MAJ 1
-#define MIN 0
+#define MIN 1
 #define BUILD 0
 #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
 	__stringify(BUILD)


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates
  2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
                   ` (7 preceding siblings ...)
  2011-12-17  0:53 ` [3.2-rc PATCH 8/8] isci: update version to 1.1 Dan Williams
@ 2011-12-18 13:49 ` James Bottomley
  2011-12-18 18:46   ` Williams, Dan J
  8 siblings, 1 reply; 13+ messages in thread
From: James Bottomley @ 2011-12-18 13:49 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-scsi

On Fri, 2011-12-16 at 16:53 -0800, Dan Williams wrote:
> These are priority updates, targeted for inclusion in 3.2-final, for the
> driver to honor the latest definition of oem parameters and support the
> latest revision of silicon.  The oem parameter format (phy configuration
> settings passed along from platform firmware) has been updated to
> revision 1.3, current driver only supports 1.0.  The C1 silicon update
> involves updates to the per-silicon-revision hard-coded phy tuning
> recipes.

The -rc tree is for bug fixes only, not whatever you choose to call
"priority updates".  We have long established the position that a driver
update, even to support new hardware, isn't a bug fix ... the
distributions apply it through their enhancement processes. See below
for the individual comments

> This also updates the driver version from v1.0 to v1.1 to remove the
> stale EXPERIMENTAL tag and reflect the C1 level of silicon support.
> 
> A performance fix and a fix for a crash that can be triggered by
> enabling a dev_dbg() statement are also included.
> 
> Please apply, or pull from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git fixes
> 
> ...to receive:
> 
> Dan Williams (2):
>       isci: cleanup oem parameter and recipe handling

This isn't a bug fix

>       isci: update version to 1.1
> 
> Dave Jiang (1):
>       isci: oem parameter format v1.1 (ssc select)
> Jeff Skirvin (3):
>       isci: update afe (analog-front-end) recipe for C1
>       isci: oem parameter format v1.3 (cable select)

New silicon support is an enhancement not a bug fix (last three patches)

>       isci: link speeds default to gen 2

This might be viewed as a but fix ... with a better description.

> Maciej Trela (1):
>       isci: remove unused 'isci_tmf->device' field

This isn't a bug fix.

> Marcin Tomczak (1):
>       isci: performance-fix, shorten default "no outbound task" timeout

I don't quite see from the description how this is a performance
enhancement?  It does nothing in the single initiator case, right?

James




^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates
  2011-12-18 13:49 ` [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates James Bottomley
@ 2011-12-18 18:46   ` Williams, Dan J
  2011-12-21 21:05     ` James Bottomley
  0 siblings, 1 reply; 13+ messages in thread
From: Williams, Dan J @ 2011-12-18 18:46 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi

On Sun, Dec 18, 2011 at 5:49 AM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> On Fri, 2011-12-16 at 16:53 -0800, Dan Williams wrote:
>> These are priority updates, targeted for inclusion in 3.2-final, for the
>> driver to honor the latest definition of oem parameters and support the
>> latest revision of silicon.  The oem parameter format (phy configuration
>> settings passed along from platform firmware) has been updated to
>> revision 1.3, current driver only supports 1.0.  The C1 silicon update
>> involves updates to the per-silicon-revision hard-coded phy tuning
>> recipes.
>
> The -rc tree is for bug fixes only, not whatever you choose to call
> "priority updates".  We have long established the position that a driver
> update, even to support new hardware, isn't a bug fix ...

These updates are aiming to get ahead of the bug reports that will be
filed as these platform changes get distributed.  Public bugzillas
seem to be the difference compared to some of the platform revision
specific updates that went into -rc6 via the drm tree.

> the
> distributions apply it through their enhancement processes. See below
> for the individual comments
>
>> This also updates the driver version from v1.0 to v1.1 to remove the
>> stale EXPERIMENTAL tag and reflect the C1 level of silicon support.
>>
>> A performance fix and a fix for a crash that can be triggered by
>> enabling a dev_dbg() statement are also included.
>>
>> Please apply, or pull from:
>>
>>   git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git fixes
>>
>> ...to receive:
>>
>> Dan Williams (2):
>>       isci: cleanup oem parameter and recipe handling
>
> This isn't a bug fix

Certainly not, but I wanted git blame on the subsequent settings to
point to the commit where the value actually changed before adding
more line wrapped register writes.

>>       isci: update version to 1.1

Mainline currently has v1.0+, and this reverts d962480e "[SCSI]
libsas: fix try_test_sas_gpio_gp_bit() build error", because it was
the wrong fix.

>>
>> Dave Jiang (1):
>>       isci: oem parameter format v1.1 (ssc select)
>> Jeff Skirvin (3):
>>       isci: update afe (analog-front-end) recipe for C1
>>       isci: oem parameter format v1.3 (cable select)
>
> New silicon support is an enhancement not a bug fix (last three patches)

I hate being put between a platform definition revision and a -rc window.

3.2 has an opportunity to ship with support for these settings that
affect link stability and meet signal integrity targets so I felt it
was worth calling these patches out separately from the wider updates
targeted for 3.3.

>> Maciej Trela (1):
>>       isci: remove unused 'isci_tmf->device' field
>
> This isn't a bug fix.

Yeah, "kernel crash" made me throw it in the 'fixes' pile, but since
it is hidden behind enabling a dev_dbg() statement it can certainly be
deferred.

>> Marcin Tomczak (1):
>>       isci: performance-fix, shorten default "no outbound task" timeout
>
> I don't quite see from the description how this is a performance
> enhancement?  It does nothing in the single initiator case, right?

This rate limits the link arbitration for how often the hardware
switches to a different remote-node-context.  At higher queue depths
we would see IOPs performance drop off rather than saturate, adjusting
this timeout corrected that condition.

--
Dan
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates
  2011-12-18 18:46   ` Williams, Dan J
@ 2011-12-21 21:05     ` James Bottomley
  2011-12-21 22:17       ` Dan Williams
  0 siblings, 1 reply; 13+ messages in thread
From: James Bottomley @ 2011-12-21 21:05 UTC (permalink / raw)
  To: Williams, Dan J; +Cc: linux-scsi

On Sun, 2011-12-18 at 10:46 -0800, Williams, Dan J wrote: 
> On Sun, Dec 18, 2011 at 5:49 AM, James Bottomley
> <James.Bottomley@hansenpartnership.com> wrote:
> > On Fri, 2011-12-16 at 16:53 -0800, Dan Williams wrote:
> >> These are priority updates, targeted for inclusion in 3.2-final, for the
> >> driver to honor the latest definition of oem parameters and support the
> >> latest revision of silicon.  The oem parameter format (phy configuration
> >> settings passed along from platform firmware) has been updated to
> >> revision 1.3, current driver only supports 1.0.  The C1 silicon update
> >> involves updates to the per-silicon-revision hard-coded phy tuning
> >> recipes.
> >
> > The -rc tree is for bug fixes only, not whatever you choose to call
> > "priority updates".  We have long established the position that a driver
> > update, even to support new hardware, isn't a bug fix ...
> 
> These updates are aiming to get ahead of the bug reports that will be
> filed as these platform changes get distributed.  Public bugzillas
> seem to be the difference compared to some of the platform revision
> specific updates that went into -rc6 via the drm tree.
> 
> > the
> > distributions apply it through their enhancement processes. See below
> > for the individual comments
> >
> >> This also updates the driver version from v1.0 to v1.1 to remove the
> >> stale EXPERIMENTAL tag and reflect the C1 level of silicon support.
> >>
> >> A performance fix and a fix for a crash that can be triggered by
> >> enabling a dev_dbg() statement are also included.
> >>
> >> Please apply, or pull from:
> >>
> >>   git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git fixes
> >>
> >> ...to receive:
> >>
> >> Dan Williams (2):
> >>       isci: cleanup oem parameter and recipe handling
> >
> > This isn't a bug fix
> 
> Certainly not, but I wanted git blame on the subsequent settings to
> point to the commit where the value actually changed before adding
> more line wrapped register writes.

Anyone who uses git blame knows how to cope with that.  If we adopted
that principle; we'd have tons of whitespace and code motion type
changes in the stable trees, which isn't a good precedent.

> >>       isci: update version to 1.1
> 
> Mainline currently has v1.0+, and this reverts d962480e "[SCSI]
> libsas: fix try_test_sas_gpio_gp_bit() build error", because it was
> the wrong fix.
> 
> >>
> >> Dave Jiang (1):
> >>       isci: oem parameter format v1.1 (ssc select)
> >> Jeff Skirvin (3):
> >>       isci: update afe (analog-front-end) recipe for C1
> >>       isci: oem parameter format v1.3 (cable select)
> >
> > New silicon support is an enhancement not a bug fix (last three patches)
> 
> I hate being put between a platform definition revision and a -rc window.
> 
> 3.2 has an opportunity to ship with support for these settings that
> affect link stability and meet signal integrity targets so I felt it
> was worth calling these patches out separately from the wider updates
> targeted for 3.3.

The process for updates is that they go into the next merge window (i.e.
for the 3.3 kernel).  If there's a case for adding this to 3.2 or
earlier kernels, then the distros will do it.

> >> Maciej Trela (1):
> >>       isci: remove unused 'isci_tmf->device' field
> >
> > This isn't a bug fix.
> 
> Yeah, "kernel crash" made me throw it in the 'fixes' pile, but since
> it is hidden behind enabling a dev_dbg() statement it can certainly be
> deferred.

What kernel crash?  The changelog doesn't mention anything about it.

> >> Marcin Tomczak (1):
> >>       isci: performance-fix, shorten default "no outbound task" timeout
> >
> > I don't quite see from the description how this is a performance
> > enhancement?  It does nothing in the single initiator case, right?
> 
> This rate limits the link arbitration for how often the hardware
> switches to a different remote-node-context.  At higher queue depths
> we would see IOPs performance drop off rather than saturate, adjusting
> this timeout corrected that condition.

I think I still don't understand what this is.  All outbound links have
to switch context rapidly in a multi-target environment with switches on
the order of microseconds ... where exactly is this 10s timeout you
reduce to 2s triggered?

James



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates
  2011-12-21 21:05     ` James Bottomley
@ 2011-12-21 22:17       ` Dan Williams
  0 siblings, 0 replies; 13+ messages in thread
From: Dan Williams @ 2011-12-21 22:17 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi

On Wed, Dec 21, 2011 at 1:05 PM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
>> >> Dan Williams (2):
>> >>       isci: cleanup oem parameter and recipe handling
>> >
>> > This isn't a bug fix
>>
>> Certainly not, but I wanted git blame on the subsequent settings to
>> point to the commit where the value actually changed before adding
>> more line wrapped register writes.
>
> Anyone who uses git blame knows how to cope with that.  If we adopted
> that principle; we'd have tons of whitespace and code motion type
> changes in the stable trees, which isn't a good precedent.

Ok, I would not have submitted a cleanup like this to -stable... and
that's the litmus test I should use for queuing (or not as it were)
late -rc changes.

>> >> Dave Jiang (1):
>> >>       isci: oem parameter format v1.1 (ssc select)
>> >> Jeff Skirvin (3):
>> >>       isci: update afe (analog-front-end) recipe for C1
>> >>       isci: oem parameter format v1.3 (cable select)
>> >
>> > New silicon support is an enhancement not a bug fix (last three patches)
>>
>> I hate being put between a platform definition revision and a -rc window.
>>
>> 3.2 has an opportunity to ship with support for these settings that
>> affect link stability and meet signal integrity targets so I felt it
>> was worth calling these patches out separately from the wider updates
>> targeted for 3.3.
>
> The process for updates is that they go into the next merge window (i.e.
> for the 3.3 kernel).  If there's a case for adding this to 3.2 or
> earlier kernels, then the distros will do it.

3.3 material it is.

>> >> Maciej Trela (1):
>> >>       isci: remove unused 'isci_tmf->device' field
>> >
>> > This isn't a bug fix.
>>
>> Yeah, "kernel crash" made me throw it in the 'fixes' pile, but since
>> it is hidden behind enabling a dev_dbg() statement it can certainly be
>> deferred.
>
> What kernel crash?  The changelog doesn't mention anything about it.

NULL de-reference of ->device.

"As the field was never set, isci_print_tmf() using 'isci_tmf->device'
sometimes causes a kernel crash if the dev_dbg() statement is
enabled."

>> >> Marcin Tomczak (1):
>> >>       isci: performance-fix, shorten default "no outbound task" timeout
>> >
>> > I don't quite see from the description how this is a performance
>> > enhancement?  It does nothing in the single initiator case, right?
>>
>> This rate limits the link arbitration for how often the hardware
>> switches to a different remote-node-context.  At higher queue depths
>> we would see IOPs performance drop off rather than saturate, adjusting
>> this timeout corrected that condition.
>
> I think I still don't understand what this is.  All outbound links have
> to switch context rapidly in a multi-target environment with switches on
> the order of microseconds ... where exactly is this 10s timeout you
> reduce to 2s triggered?

Not sure what gave the 1s unit impression, but now that I look the
units of the module parameter are wrong.  This value is in 256ns
increments (not 1us) so we are changing the target context switch rate
from 5us to 512ns.  This value is put to the phy's link layer control
register in sci_phy_link_layer_initialization().

--
Dan
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-12-21 22:17 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-17  0:53 [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 1/8] isci: cleanup oem parameter and recipe handling Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 2/8] isci: update afe (analog-front-end) recipe for C1 Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 3/8] isci: oem parameter format v1.1 (ssc select) Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 4/8] isci: oem parameter format v1.3 (cable select) Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 5/8] isci: performance-fix, shorten default "no outbound task" timeout Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 6/8] isci: link speeds default to gen 2 Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 7/8] isci: remove unused 'isci_tmf->device' field Dan Williams
2011-12-17  0:53 ` [3.2-rc PATCH 8/8] isci: update version to 1.1 Dan Williams
2011-12-18 13:49 ` [GIT 3.2-rc PATCH 0/8] isci: platform and hardware enabling updates James Bottomley
2011-12-18 18:46   ` Williams, Dan J
2011-12-21 21:05     ` James Bottomley
2011-12-21 22:17       ` Dan Williams

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox