Skip to contentSkip to conversation

fc transport attributes for mpt fusion driver

RFC New Michael Reed 1 participant 1 message Nov 18, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 fc transport attributes for mpt fusion driver

Hello,

I've been working on adding fc transport attributes to the mpt fusion fibre channel driver. This code is based on 2.6.15-rc1-git6 with the most recent 8 patches posted by Eric Moore. It's in working condition. (There is an error recovery panic which appears to also be present in the base code. Eric's been notified.)

I would very much appreciate comments.

Thanks,
Mike Reed
SGI

drivers/message/fusion/mptbase.c +24 -5
diff -ru em/drivers/message/fusion/mptbase.c mdr/drivers/message/fusion/mptbase.c
@@ -148,7 +148,6 @@
 static int	WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 static int	WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
 static int	GetLanConfigPages(MPT_ADAPTER *ioc);
-static int	GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
 static int	GetIoUnitPage2(MPT_ADAPTER *ioc);
 int		mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
 static int	mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
@@ -1250,6 +1249,8 @@
 	ioc->pcidev = pdev;
 	ioc->diagPending = 0;
 	spin_lock_init(&ioc->diagLock);
+	spin_lock_init(&ioc->work_lock);
+	spin_lock_init(&ioc->fc_rport_lock);
 	spin_lock_init(&ioc->initializing_hba_lock);
 
 	/* Initialize the event logging.
@@ -1273,6 +1274,10 @@
 	 */
 	INIT_LIST_HEAD(&ioc->configQ);
 
+	/* Initialize the fc rport list head.
+	 */
+	INIT_LIST_HEAD(&ioc->l.fc_rports);
+
 	/* Find lookup slot. */
 	INIT_LIST_HEAD(&ioc->list);
 	ioc->id = mpt_ids++;
@@ -1885,7 +1890,7 @@
 			 *  (FCPortPage0_t stuff)
 			 */
 			for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
-				(void) GetFcPortPage0(ioc, ii);
+				(void) mptbase_GetFcPortPage0(ioc, ii);
 			}
 
 			if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
@@ -4204,7 +4209,7 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	GetFcPortPage0 - Fetch FCPort config Page0.
+ *	mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@portnum: IOC Port number
  *
@@ -4214,8 +4219,8 @@
  *		-EAGAIN if no msg frames currently available
  *		-EFAULT for non-successful reply or no reply (timeout)
  */
-static int
-GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
+int
+mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
 {
 	ConfigPageHeader_t	 hdr;
 	CONFIGPARMS		 cfg;
@@ -4225,6 +4230,8 @@
 	int			 data_sz;
 	int			 copy_sz;
 	int			 rc;
+	int			 count=2500;
+
 
 	/* Get FCPort Page 0 header */
 	hdr.PageVersion = 0;
@@ -4248,6 +4255,8 @@
 	rc = -ENOMEM;
 	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
 	if (ppage0_alloc) {
+
+ try_again:
 		memset((u8 *)ppage0_alloc, 0, data_sz);
 		cfg.physAddr = page0_dma;
 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
@@ -4279,6 +4288,15 @@
 			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
 			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
 
+			if ((pp0dest->PortState != MPI_FCPORTPAGE0_PORTSTATE_ONLINE) ||
+					((pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK) ==
+					MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
+				if (count > 0) {
+					count --;
+					msleep_interruptible(1);
+					goto try_again;
+				}
+			}
 		}
 
 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
@@ -6361,6 +6379,7 @@
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
 EXPORT_SYMBOL(mpt_alt_ioc_wait);
+EXPORT_SYMBOL(mptbase_GetFcPortPage0);
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
drivers/message/fusion/mptbase.h +30 -0
diff -ru em/drivers/message/fusion/mptbase.h mdr/drivers/message/fusion/mptbase.h
@@ -499,6 +499,24 @@
 	int		 isRaid;		/* bit field, 1 if RAID */
 }RaidCfgData;
 
+#define MPT_RPORT_INFO_FLAGS_REGISTERED		0x01	/* rport registered */
+#define	MPT_RPORT_INFO_FLAGS_BLOCKED		0x02	/* rport blocked */
+#define	MPT_RPORT_INFO_FLAGS_MISSING		0x04	/* missing from DevPage0 scan */
+#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV	0x08	/* target mapped in vdev */
+
+/*
+ * data allocated for each fc rport device
+ */
+struct mptfc_rport_info
+{
+	struct list_head list;
+	struct fc_rport *rport;
+	VirtDevice	*vdev;
+	FCDevicePage0_t pg0;
+	u8		flags;
+	u8		debug;
+};
+
 /*
  *  Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
  */
@@ -611,7 +629,18 @@
 	int 	 		 initializing_hba_lock_flag;
 	struct list_head	 list;
 	struct net_device	*netdev;
+
+	union {
 	struct list_head	 sas_topology;
+	struct list_head	 fc_rports;	/* list of wwpn / sdev target / rport ptr */
+	} l;
+
+	spinlock_t		 fc_rport_lock;	/* for all accesses of list and ri flags */
+
+	spinlock_t		 work_lock;
+	int			 work_count;
+	struct work_struct	 work_task;	/* for use by personality, i.e., fc, sas, spi, lan */
+
 	MPT_SAS_MGMT		 sas_mgmt;
 } MPT_ADAPTER;
 
@@ -999,6 +1028,7 @@
 extern int	 mpt_findImVolumes(MPT_ADAPTER *ioc);
 extern int	 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 extern int	 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
+extern int	 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
 extern int	 mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
 
 /*
drivers/message/fusion/mptfc.c +469 -15

583 lines not on this page · raw message

drivers/message/fusion/mptsas.c +5 -5
diff -ru em/drivers/message/fusion/mptsas.c mdr/drivers/message/fusion/mptsas.c
@@ -994,7 +994,7 @@
 	if (error)
 		goto out_free_port_info;
 
-	list_add_tail(&port_info->list, &ioc->sas_topology);
+	list_add_tail(&port_info->list, &ioc->l.sas_topology);
 	for (i = 0; i < port_info->num_phys; i++) {
 		mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i],
 			(MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER <<
@@ -1047,7 +1047,7 @@
 
 	*handle = port_info->handle;
 
-	list_add_tail(&port_info->list, &ioc->sas_topology);
+	list_add_tail(&port_info->list, &ioc->l.sas_topology);
 	for (i = 0; i < port_info->num_phys; i++) {
 		struct device *parent;
 
@@ -1079,7 +1079,7 @@
 		 * HBA phys.
 		 */
 		parent = &ioc->sh->shost_gendev;
-		list_for_each_entry(p, &ioc->sas_topology, list) {
+		list_for_each_entry(p, &ioc->l.sas_topology, list) {
 			for (j = 0; j < p->num_phys; j++) {
 				if (port_info->phy_info[i].identify.handle ==
 						p->phy_info[j].attached.handle)
@@ -1202,7 +1202,7 @@
 	 */
 	sh->unique_id = ioc->id;
 
-	INIT_LIST_HEAD(&ioc->sas_topology);
+	INIT_LIST_HEAD(&ioc->l.sas_topology);
 	init_MUTEX(&ioc->sas_mgmt.mutex);
 	init_completion(&ioc->sas_mgmt.done);
 
@@ -1339,7 +1339,7 @@
 
 	sas_remove_host(ioc->sh);
 
-	list_for_each_entry_safe(p, n, &ioc->sas_topology, list) {
+	list_for_each_entry_safe(p, n, &ioc->l.sas_topology, list) {
 		list_del(&p->list);
 		kfree(p);
 	}
drivers/message/fusion/mptscsih.c +24 -3
diff -ru em/drivers/message/fusion/mptscsih.c mdr/drivers/message/fusion/mptscsih.c
@@ -58,6 +58,7 @@
 #include <linux/workqueue.h>
 
 #include <scsi/scsi.h>
+#include <scsi/scsi_transport_fc.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
@@ -893,6 +894,7 @@
  *		when a lun is disable by mid-layer.
  *		Do NOT access the referenced scsi_cmnd structure or
  *		members. Will cause either a paging or NULL ptr error.
+ * (BUT, BUT, BUT, the code does reference it!)
  *      @hd: Pointer to a SCSI HOST structure
  *	@vdevice: per device private data
  *
@@ -2566,6 +2568,18 @@
 			ddvtprintk(("Set reload IOC Pg3 Flag\n"));
 		}
 
+		/* 7. FC: Rescan for blocked rports which might have returned.
+		 */
+		else if (ioc->bus_type == FC) {
+			int work_count;
+			unsigned long flags;
+
+			spin_lock_irqsave(&ioc->work_lock,flags);
+			work_count = ++ioc->work_count;
+			spin_unlock_irqrestore(&ioc->work_lock,flags);
+			if (work_count == 1)
+				schedule_work(&ioc->work_task);
+		}
 		dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
 
 	}
@@ -2589,6 +2603,8 @@
 {
 	MPT_SCSI_HOST *hd;
 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
+	int work_count;
+	unsigned long flags;
 
 	devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
 			ioc->name, event));
@@ -2610,11 +2626,18 @@
 		/* FIXME! */
 		break;
 
+	case MPI_EVENT_RESCAN:				/* 06 */
+		spin_lock_irqsave(&ioc->work_lock,flags);
+		work_count = ++ioc->work_count;
+		spin_unlock_irqrestore(&ioc->work_lock,flags);
+		if (work_count == 1)
+			schedule_work(&ioc->work_task);
+		break;
+
 		/*
 		 *  CHECKME! Don't think we need to do
 		 *  anything for these, but...
 		 */
-	case MPI_EVENT_RESCAN:				/* 06 */
 	case MPI_EVENT_LINK_STATUS_CHANGE:		/* 07 */
 	case MPI_EVENT_LOOP_STATE_CHANGE:		/* 08 */
 		/*
@@ -3954,8 +3977,6 @@
 
 /* Search IOC page 3 to determine if this is hidden physical disk
  */
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
 static int
 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
 {