[patch 6/8] mptfusion: fc transport

Moore, Eric Dean
2004-11-19T16:11:22Z

[-- Attachment #1: Type: text/plain, Size: 133 bytes --]

This provides fc_transport support, exporting
port_id, port_name, node_name.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>

[-- Attachment #2: mptfusion-6.patch --]
[-- Type: application/octet-stream, Size: 7252 bytes --]

diff -uarN b/drivers/message/fusion/Kconfig a/drivers/message/fusion/Kconfig
--- b/drivers/message/fusion/Kconfig 2004-11-17 16:24:38.000000000 -0700
+++ a/drivers/message/fusion/Kconfig 2004-11-18 12:28:57.000000000 -0700
@@ -4,6 +4,7 @@
config FUSION
tristate "Fusion MPT (base + ScsiHost) drivers"
depends on PCI && SCSI
+ select SCSI_FC_ATTRS
---help---
LSI Logic Fusion(TM) Message Passing Technology (MPT) device support
provides high performance SCSI host initiator, and LAN [1] interface
diff -uarN b/drivers/message/fusion/Makefile a/drivers/message/fusion/Makefile
--- b/drivers/message/fusion/Makefile 2004-11-18 12:18:18.000000000 -0700
+++ a/drivers/message/fusion/Makefile 2004-11-18 12:24:53.000000000 -0700
@@ -33,6 +33,7 @@
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
#CFLAGS_mptscsih.o += -DMPT_DEBUG_RESET
#CFLAGS_mptscsih.o += -DMPT_DEBUG_NEH
+CFLAGS_mptscsih.o += -DMPTSCSIH_ENABLE_FC_TRANSPORT
#
# For mptctl:
#CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL
diff -uarN b/drivers/message/fusion/mptscsih.c a/drivers/message/fusion/mptscsih.c
--- b/drivers/message/fusion/mptscsih.c 2004-11-18 14:54:27.000000000 -0700
+++ a/drivers/message/fusion/mptscsih.c 2004-11-18 14:54:45.000000000 -0700
@@ -83,6 +83,8 @@
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>

#include "mptbase.h"
#include "mptscsih.h"
@@ -259,6 +261,10 @@
static struct mptscsih_driver_setup driver_setup;
static struct scsi_host_template driver_template;

+#if defined(MPTSCSIH_ENABLE_FC_TRANSPORT)
+static struct scsi_transport_template *mptscsih_transport_template = NULL;
+#endif
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_add_sge - Place a simple SGE at address pAddr.
@@ -1129,7 +1135,13 @@
sh->max_lun = MPT_LAST_LUN + 1;
sh->max_channel = 0;
sh->this_id = ioc->pfacts[0].PortSCSIID;
-
+
+#if defined(MPTSCSIH_ENABLE_FC_TRANSPORT)
+ if (ioc->bus_type == FC) {
+ BUG_ON(mptscsih_transport_template == NULL);
+ sh->transportt = mptscsih_transport_template;
+ }
+#endif
/* Required entry.
*/
sh->unique_id = ioc->id;
@@ -1301,6 +1313,145 @@

}

+#if defined(MPTSCSIH_ENABLE_FC_TRANSPORT)
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * GetFcDevicePage0 - returns FC Device Page 0 data
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @bus: bus id
+ * @targetId: target id
+ * @fcDevicePage: FC Device Page 0 data
+ *
+ * Returns count of number bytes copied into @fcDevicePage
+ *
+ */
+
+static int
+GetFcDevicePage0(MPT_ADAPTER *ioc, u8 bus, u8 targetId, pFCDevicePage0_t fcDevicePage)
+{
+ ConfigPageHeader_t hdr;
+ CONFIGPARMS cfg;
+ pFCDevicePage0_t ppage0_alloc;
+ dma_addr_t page0_dma;
+ int data_sz;
+ int copy_sz=0;
+ int rc;
+
+ /* Get FCPort Page 0 header */
+ hdr.PageVersion = 0;
+ hdr.PageLength = 0;
+ hdr.PageNumber = 0;
+ hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
+ cfg.hdr = &hdr;
+ cfg.physAddr = -1;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
+ cfg.dir = 0;
+
+ cfg.pageAddr = (bus << 8) + targetId + MPI_FC_DEVICE_PGAD_FORM_BUS_TID;
+ cfg.timeout = 0;
+
+ if ((rc = mpt_config(ioc, &cfg)) != 0)
+ return 0;
+
+ if (hdr.PageLength == 0)
+ return 0;
+
+ data_sz = hdr.PageLength * 4;
+ rc = -ENOMEM;
+ ppage0_alloc = (pFCDevicePage0_t ) pci_alloc_consistent(ioc->pcidev,
+ data_sz, &page0_dma);
+ if (ppage0_alloc) {
+ memset((u8 *)ppage0_alloc, 0, data_sz);
+ cfg.physAddr = page0_dma;
+ cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
+
+ if ((rc = mpt_config(ioc, &cfg)) == 0) {
+ /* save the data */
+ copy_sz = min_t(int, sizeof(FCDevicePage0_t), data_sz);
+ memcpy(fcDevicePage, ppage0_alloc, copy_sz);
+ }
+
+ pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc,
+ page0_dma);
+ }
+
+ return copy_sz;
+}
+
+static void
+mptscsih_get_port_id(struct scsi_target *starget)
+{
+ struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ FCDevicePage0_t fcDevicePage;
+ int rc;
+
+ fc_starget_port_id(starget) = -1;
+ hd = (MPT_SCSI_HOST *)host->hostdata;
+ if (hd==NULL)
+ return;
+ ioc = hd->ioc;
+ rc = GetFcDevicePage0(ioc, starget->channel, starget->id, &fcDevicePage);
+ if (rc > offsetof(FCDevicePage0_t,Protocol))
+ fc_starget_port_id(starget) = le64_to_cpu(fcDevicePage.PortIdentifier);
+}
+
+static void
+mptscsih_get_port_name(struct scsi_target *starget)
+{
+ struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ FCDevicePage0_t fcDevicePage;
+ int rc;
+
+ fc_starget_port_name(starget) = -1;
+ hd = (MPT_SCSI_HOST *)host->hostdata;
+ if (hd==NULL)
+ return;
+ ioc = hd->ioc;
+ rc = GetFcDevicePage0(ioc, starget->channel, starget->id, &fcDevicePage);
+ if (rc > offsetof(FCDevicePage0_t,PortIdentifier)) {
+ memcpy(&fc_starget_port_name(starget),&fcDevicePage.WWPN,
+ sizeof(fcDevicePage.WWPN));
+ le64_to_cpus(&fc_starget_port_name(starget));
+ }
+}
+
+static void
+mptscsih_get_node_name(struct scsi_target *starget)
+{
+ struct Scsi_Host *host = dev_to_shost(starget->dev.parent);
+ MPT_SCSI_HOST *hd;
+ MPT_ADAPTER *ioc;
+ FCDevicePage0_t fcDevicePage;
+ int rc;
+
+ fc_starget_node_name(starget) = -1;
+ hd = (MPT_SCSI_HOST *)host->hostdata;
+ if (hd==NULL)
+ return;
+ ioc = hd->ioc;
+ rc = GetFcDevicePage0(ioc, starget->channel, starget->id, &fcDevicePage);
+ if (rc > offsetof(FCDevicePage0_t,WWPN)) {
+ memcpy(&fc_starget_node_name(starget),&fcDevicePage.WWNN,
+ sizeof(fcDevicePage.WWNN));
+ le64_to_cpus(&fc_starget_node_name(starget));
+ }
+}
+
+static struct fc_function_template mptscsih_transport_functions = {
+ .get_starget_port_id = mptscsih_get_port_id,
+ .show_starget_port_id = 1,
+ .get_starget_port_name = mptscsih_get_port_name,
+ .show_starget_port_name = 1,
+ .get_starget_node_name = mptscsih_get_node_name,
+ .show_starget_node_name = 1,
+};
+#endif
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mptscsih_remove - Removed scsi devices
@@ -1481,6 +1632,13 @@

show_mptmod_ver(my_NAME, my_VERSION);

+#if defined(MPTSCSIH_ENABLE_FC_TRANSPORT)
+ mptscsih_transport_template =
+ fc_attach_transport(&mptscsih_transport_functions);
+ if (!mptscsih_transport_template)
+ return -ENODEV;
+#endif
+
ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
@@ -1528,6 +1686,9 @@
{
mpt_device_driver_deregister(MPTSCSIH_DRIVER);

+#if defined(MPTSCSIH_ENABLE_FC_TRANSPORT)
+ fc_release_transport(mptscsih_transport_template);
+#endif
mpt_reset_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM
": Deregistered for IOC reset notifications\n"));