Skip to contentSkip to conversation

aic94xx: SCSI timeout fix

PATCH In review Alexis Bruemmer 1 participant 1 message Nov 9, 2006 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 1/4 aic94xx: SCSI timeout fix

The patch updates DDB0 in the aic94xx driver itself. It doesn't supply or use lldd_port_formed field. DDB0 is updated prior to posting notification to libsas layer.

---

drivers/scsi/aic94xx/aic94xx_hwi.c +18 -0
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -112,6 +112,21 @@ static int asd_init_phy(struct asd_phy *
 	return 0;
 }
 
+static void asd_init_ports(struct asd_ha_struct *asd_ha)
+{
+	int i;
+
+	spin_lock_init(&asd_ha->asd_ports_lock);
+	for (i = 0; i < ASD_MAX_PHYS; i++) {
+		struct asd_port *asd_port = &asd_ha->asd_ports[i];
+
+		memset(asd_port->sas_addr, 0, SAS_ADDR_SIZE);
+		memset(asd_port->attached_sas_addr, 0, SAS_ADDR_SIZE);
+		asd_port->phy_mask = 0;
+		asd_port->num_phys = 0;
+	}
+}
+
 static int asd_init_phys(struct asd_ha_struct *asd_ha)
 {
 	u8 i;
@@ -121,6 +136,7 @@ static int asd_init_phys(struct asd_ha_s
 		struct asd_phy *phy = &asd_ha->phys[i];
 
 		phy->phy_desc = &asd_ha->hw_prof.phy_desc[i];
+		phy->asd_port = NULL;
 
 		phy->sas_phy.enabled = 0;
 		phy->sas_phy.id = i;
@@ -657,6 +673,8 @@ int asd_init_hw(struct asd_ha_struct *as
 			    pci_name(asd_ha->pcidev));
 		goto Out;
 	}
+
+	asd_init_ports(asd_ha);
 
 	err = asd_init_scbs(asd_ha);
 	if (err) {
drivers/scsi/aic94xx/aic94xx_hwi.h +12 -0
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_hwi.h
@@ -192,6 +192,16 @@ struct asd_seq_data {
 	struct asd_ascb **escb_arr; /* array of pointers to escbs */
 };
 
+/* This is an internal port structure. These are used to get accurate
+ * phy_mask for updating DDB 0.
+ */
+struct asd_port {
+	u8  sas_addr[SAS_ADDR_SIZE];
+	u8  attached_sas_addr[SAS_ADDR_SIZE];
+	u32 phy_mask;
+	int num_phys;
+};
+
 /* This is the Host Adapter structure.  It describes the hardware
  * SAS adapter.
  */
@@ -210,6 +220,8 @@ struct asd_ha_struct {
 	struct hw_profile hw_prof;
 
 	struct asd_phy    phys[ASD_MAX_PHYS];
+	spinlock_t        asd_ports_lock;
+	struct asd_port   asd_ports[ASD_MAX_PHYS];
 	struct asd_sas_port   ports[ASD_MAX_PHYS];
 
 	struct dma_pool  *scb_pool;
drivers/scsi/aic94xx/aic94xx_init.c +0 -2
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_init.c
@@ -766,8 +766,6 @@ static void asd_remove_driver_attrs(stru
 }
 
 static struct sas_domain_function_template aic94xx_transport_functions = {
-	.lldd_port_formed	= asd_update_port_links,
-
 	.lldd_dev_found		= asd_dev_found,
 	.lldd_dev_gone		= asd_dev_gone,
 
drivers/scsi/aic94xx/aic94xx_sas.h +1 -0
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_sas.h
@@ -733,6 +733,7 @@ struct asd_phy {
 
 	struct sas_identify_frame *identify_frame;
 	struct asd_dma_tok  *id_frm_tok;
+	struct asd_port     *asd_port;
 
 	u8         frame_rcvd[ASD_EDB_SIZE];
 };
drivers/scsi/aic94xx/aic94xx_scb.c +72 -0

120 lines not on this page · raw message

drivers/scsi/aic94xx/aic94xx_seq.c +3 -4
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_seq.c
@@ -1369,10 +1369,9 @@ int asd_start_seqs(struct asd_ha_struct 
  * port_map_by_links is also used as the conn_mask byte in the
  * initiator/target port DDB.
  */
-void asd_update_port_links(struct asd_sas_phy *sas_phy)
-{
-	struct asd_ha_struct *asd_ha = sas_phy->ha->lldd_ha;
-	const u8 phy_mask = (u8) sas_phy->port->phy_mask;
+void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
+{
+	const u8 phy_mask = (u8) phy->asd_port->phy_mask;
 	u8  phy_is_up;
 	u8  mask;
 	int i, err;
drivers/scsi/aic94xx/aic94xx_seq.h +1 -1
diff -r 445d70ce1ff2 drivers/scsi/aic94xx/aic94xx_seq.h
@@ -64,7 +64,7 @@ int asd_init_seqs(struct asd_ha_struct *
 int asd_init_seqs(struct asd_ha_struct *asd_ha);
 int asd_start_seqs(struct asd_ha_struct *asd_ha);
 
-void asd_update_port_links(struct asd_sas_phy *phy);
+void asd_update_port_links(struct asd_ha_struct *asd_ha, struct asd_phy *phy);
 #endif
 
 #endif