svn commit: r331766 - in head: share/man/man4 sys/amd64/conf sys/conf sys/dev/ocs_fc sys/modules sys/modules/ocs_fc

Kenneth D. Merry ken at FreeBSD.org
Fri Mar 30 15:28:26 UTC 2018


Author: ken
Date: Fri Mar 30 15:28:25 2018
New Revision: 331766
URL: https://svnweb.freebsd.org/changeset/base/331766

Log:
  Bring in the Broadcom/Emulex Fibre Channel driver, ocs_fc(4).
  
  The ocs_fc(4) driver supports the following hardware:
  
  Emulex 16/8G FC GEN 5 HBAS
  	LPe15004 FC Host Bus Adapters
  	LPe160XX FC Host Bus Adapters
  
  Emulex 32/16G FC GEN 6 HBAS
  	LPe3100X FC Host Bus Adapters
  	LPe3200X FC Host Bus Adapters
  
  The driver supports target and initiator mode, and also supports FC-Tape.
  
  Note that the driver only currently works on little endian platforms.  It
  is only included in the module build for amd64 and i386, and in GENERIC
  on amd64 only.
  
  Submitted by:	Ram Kishore Vegesna <ram.vegesna at broadcom.com>
  Reviewed by:	mav
  MFC after:	5 days
  Relnotes:	yes
  Sponsored by:	Broadcom
  Differential Revision:	https://reviews.freebsd.org/D11423

Added:
  head/share/man/man4/ocs_fc.4   (contents, props changed)
  head/sys/dev/ocs_fc/
  head/sys/dev/ocs_fc/ocs.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_cam.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_cam.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_common.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_ddump.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_ddump.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_device.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_device.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_domain.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_domain.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_drv_fc.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_els.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_els.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_fabric.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_fabric.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_fcp.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_hw.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_hw.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_hw_queues.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_hw_queues.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_io.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_io.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_ioctl.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_ioctl.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_list.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_mgmt.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_mgmt.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_node.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_node.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_os.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_os.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_pci.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_scsi.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_scsi.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_sm.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_sm.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_sport.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_sport.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_stats.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_unsol.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_unsol.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_utils.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_utils.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_vpd.h   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_xport.c   (contents, props changed)
  head/sys/dev/ocs_fc/ocs_xport.h   (contents, props changed)
  head/sys/dev/ocs_fc/sli4.c   (contents, props changed)
  head/sys/dev/ocs_fc/sli4.h   (contents, props changed)
  head/sys/dev/ocs_fc/version.h   (contents, props changed)
  head/sys/modules/ocs_fc/
  head/sys/modules/ocs_fc/Makefile   (contents, props changed)
Modified:
  head/share/man/man4/Makefile
  head/sys/amd64/conf/GENERIC
  head/sys/conf/files
  head/sys/modules/Makefile

Modified: head/share/man/man4/Makefile
==============================================================================
--- head/share/man/man4/Makefile	Fri Mar 30 14:41:16 2018	(r331765)
+++ head/share/man/man4/Makefile	Fri Mar 30 15:28:25 2018	(r331766)
@@ -402,6 +402,7 @@ MAN=	aac.4 \
 	${_nvram2env.4} \
 	${_nxge.4} \
 	oce.4 \
+	ocs_fc.4\
 	ohci.4 \
 	orm.4 \
 	ow.4 \

Added: head/share/man/man4/ocs_fc.4
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/share/man/man4/ocs_fc.4	Fri Mar 30 15:28:25 2018	(r331766)
@@ -0,0 +1,194 @@
+.\" Copyright (c) 2017 Broadcom. All rights reserved.
+.\" The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright notice,
+.\"    this list of conditions and the following disclaimer.
+.\"
+.\" 2. Redistributions in binary form must reproduce the above copyright notice,
+.\"    this list of conditions and the following disclaimer in the documentation
+.\"    and/or other materials provided with the distribution.
+.\"
+.\" 3. Neither the name of the copyright holder nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 30, 2018
+.Dt OCS_FC 4
+.Os
+.Sh NAME
+.Nm ocs_fc
+.Nd "Device driver for Emulex Fibre Channel Host Adapters"
+.Sh SYNOPSIS
+To compile this driver into the kernel, add this line to the
+kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device ocs_fc"
+.Ed
+.Pp
+To load the driver as a module at boot, add this line to
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+ocs_fc_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides access to Fibre Channel SCSI devices.
+.Pp
+The
+.Nm
+driver supports initiator and target modes.
+Support is available for Arbitrated loops, Point-to-Point,
+and Fabric connections.
+FC-Tape is highly recommended for connections to tape drives that support
+it.
+FC-Tape includes four elements from the T-10 FCP-4 specification:
+.Bl -bullet -offset indent
+.It
+Precise Delivery of Commands
+.It
+Confirmed Completion of FCP I/O Operations
+.It
+Retransmission of Unsuccessfully Transmitted IUs
+.It
+Task Retry Identification
+.El
+.Pp
+Together these features allow for link level error recovery with tape
+devices.
+Without link level error recovery, an initiator cannot, for instance, tell whether a tape write
+command that has timed out resulted in all, part, or none of the data going to
+the tape drive.
+FC-Tape is automatically enabled when both the controller and target support it.
+
+.Sh HARDWARE
+The
+.Nm
+driver supports these Fibre Channel adapters:
+.Bl -tag -width xxxxxx -offset indent
+.It Emulex 16/8G FC GEN 5 HBAS
+.Bd -literal -offset indent
+LPe15004 FC Host Bus Adapters
+LPe160XX FC Host Bus Adapters
+.Ed
+.It Emulex 32/16G FC GEN 6 HBAS
+.Bd -literal -offset indent
+LPe3100X FC Host Bus Adapters
+LPe3200X FC Host Bus Adapters
+.Ed
+.El
+.Sh UPDATING FIRMWARE
+Adapter firmware updates are persistent.
+.Pp
+Firmware can be updated by following these steps:
+.Bl -enum
+.It
+Copy this code to a
+.Pa Makefile :
+.Bd -literal -offset indent
+KMOD=ocsflash
+FIRMWS=imagename.grp:ocsflash
+\&.include <bsd.kmod.mk>
+.Ed
+.It
+Replace
+.Pa imagename
+with the name of the GRP file.
+.It
+Copy the
+.Pa Makefile
+and GRP file to a local directory
+.It
+Execute
+.Cm make
+and copy the generated
+.Pa ocsflash.ko
+file to
+.Pa /lib/modules
+.It
+.Cm sysctl dev.ocs_fc.<N>.fw_upgrade=ocsflash
+.It
+Check kernel messages regarding status of the operation
+.It
+Reboot the machine
+.El
+.Pp
+.Sh BOOT OPTIONS
+Options are controlled by setting values in
+.Pa /boot/device.hints .
+.Pp
+They are:
+.Bl -tag -width indent
+.It Va hint.ocs_fc.N.initiator
+Enable initiator functionality.
+Default 1 (enabled), 0 to disable.
+.It Va hint.ocs_fc.N.target
+Enable target functionality.
+Default 1 (enabled), 0 to disable.
+.It Va hint.ocs_fc.N.topology
+Topology: 0 for Auto, 1 for NPort only, 2 for Loop only.
+.It Va hint.ocs_fc.N.speed
+Link speed in megabits per second.
+Possible values include:
+0 Auto-speed negotiation (default), 4000 (4GFC), 8000 (8GFC), 16000 (16GFC).
+.El
+.Sh SYSCTL OPTIONS
+.Bl -tag -width indent
+.It Va dev.ocs_fc.N.port_state
+Port state (read/write).
+Valid values are
+.Li online
+and
+.Li offline .
+.It Va dev.ocs_fc.N.wwpn
+World Wide Port Name (read/write).
+.It Va dev.ocs_fc.N.wwnn
+World Wide Node Name (read/write).
+.It Va dev.ocs_fc.N.fwrev
+Firmware revision (read-only).
+.It Va dev.ocs_fc.N.sn
+Adapter serial number (read-only).
+.It Va dev.ocs_fc.N.configured_speed
+Configured Port Speed (read/write).
+Valid values are:
+0 Auto-speed negotiation (default), 4000 (4GFC), 8000 (8GFC), 16000 (16GFC).
+.It Va dev.ocs_fc.N.configured_topology
+Configured Port Topology (read/write).
+Valid values are:
+0-Auto; 1-NPort; 2-Loop.
+.It Va dev.ocs_fc.N.current_speed
+Current Port Speed (read-only).
+.It Va dev.ocs_fc.N.current_topology
+Current Port Topology (read-only).
+.El
+.Sh SUPPORT
+For general information and support,
+go to the Broadcom website at:
+.Pa http://www.broadcom.com/
+or E-Mail at
+.Pa ocs-driver-team.pdl at broadcom.com.
+.Sh SEE ALSO
+.Xr ifconfig 8
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Broadcom.

Modified: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Fri Mar 30 14:41:16 2018	(r331765)
+++ head/sys/amd64/conf/GENERIC	Fri Mar 30 15:28:25 2018	(r331766)
@@ -141,6 +141,7 @@ device		adw			# Advansys wide SCSI adapters
 device		aic			# Adaptec 15[012]x SCSI adapters, AIC-6[23]60.
 device		bt			# Buslogic/Mylex MultiMaster SCSI adapters
 device		isci			# Intel C600 SAS controller
+device		ocs_fc			# Emulex FC adapters
 
 # ATA/SCSI peripherals
 device		scbus			# SCSI bus (required for ATA/SCSI)

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Fri Mar 30 14:41:16 2018	(r331765)
+++ head/sys/conf/files	Fri Mar 30 15:28:25 2018	(r331766)
@@ -2578,6 +2578,27 @@ dev/oce/oce_mbox.c		optional oce pci
 dev/oce/oce_queue.c		optional oce pci
 dev/oce/oce_sysctl.c		optional oce pci
 dev/oce/oce_util.c		optional oce pci
+dev/ocs_fc/ocs_pci.c		optional ocs_fc pci
+dev/ocs_fc/ocs_ioctl.c		optional ocs_fc pci
+dev/ocs_fc/ocs_os.c		optional ocs_fc pci
+dev/ocs_fc/ocs_utils.c		optional ocs_fc pci
+dev/ocs_fc/ocs_hw.c		optional ocs_fc pci
+dev/ocs_fc/ocs_hw_queues.c	optional ocs_fc pci
+dev/ocs_fc/sli4.c		optional ocs_fc pci
+dev/ocs_fc/ocs_sm.c		optional ocs_fc pci
+dev/ocs_fc/ocs_device.c		optional ocs_fc pci
+dev/ocs_fc/ocs_xport.c		optional ocs_fc pci
+dev/ocs_fc/ocs_domain.c		optional ocs_fc pci
+dev/ocs_fc/ocs_sport.c		optional ocs_fc pci
+dev/ocs_fc/ocs_els.c		optional ocs_fc pci
+dev/ocs_fc/ocs_fabric.c		optional ocs_fc pci
+dev/ocs_fc/ocs_io.c		optional ocs_fc pci
+dev/ocs_fc/ocs_node.c		optional ocs_fc pci
+dev/ocs_fc/ocs_scsi.c		optional ocs_fc pci
+dev/ocs_fc/ocs_unsol.c		optional ocs_fc pci
+dev/ocs_fc/ocs_ddump.c		optional ocs_fc pci
+dev/ocs_fc/ocs_mgmt.c		optional ocs_fc pci
+dev/ocs_fc/ocs_cam.c		optional ocs_fc pci
 dev/ofw/ofw_bus_if.m		optional fdt
 dev/ofw/ofw_bus_subr.c		optional fdt
 dev/ofw/ofw_cpu.c		optional fdt

Added: head/sys/dev/ocs_fc/ocs.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ocs_fc/ocs.h	Fri Mar 30 15:28:25 2018	(r331766)
@@ -0,0 +1,261 @@
+/*-
+ * Copyright (c) 2017 Broadcom. All rights reserved.
+ * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/**
+ * @file
+ * OCS bsd driver common include file
+ */
+
+
+#if !defined(__OCS_H__)
+#define __OCS_H__
+
+#include "ocs_os.h"
+#include "ocs_utils.h"
+
+#include "ocs_hw.h"
+#include "ocs_scsi.h"
+#include "ocs_io.h"
+
+#include "version.h"
+
+#define DRV_NAME			"ocs_fc"
+#define DRV_VERSION 							\
+	STR_BE_MAJOR "." STR_BE_MINOR "." STR_BE_BUILD "." STR_BE_BRANCH
+
+/**
+ * @brief Interrupt context
+ */
+typedef struct ocs_intr_ctx_s {
+	uint32_t	vec;		/** Zero based interrupt vector */
+	void		*softc;		/** software context for interrupt */
+	char		name[64];	/** label for this context */
+} ocs_intr_ctx_t;
+
+typedef struct ocs_fcport_s {
+	struct cam_sim          *sim;
+	struct cam_path         *path;
+	uint32_t                role;
+
+	ocs_tgt_resource_t      targ_rsrc_wildcard;
+	ocs_tgt_resource_t      targ_rsrc[OCS_MAX_LUN];
+	ocs_vport_spec_t	*vport;
+} ocs_fcport;
+
+#define FCPORT(ocs, chan)	(&((ocs_fcport *)(ocs)->fcports)[(chan)])
+
+/**
+ * @brief Driver's context
+ */
+
+struct ocs_softc {
+
+	device_t		dev;
+	struct cdev		*cdev;
+
+	ocs_pci_reg_t		reg[PCI_MAX_BAR];
+
+	uint32_t		instance_index;
+	const char		*desc;
+
+	uint32_t		irqid;
+	struct resource		*irq;
+	void			*tag;
+
+	ocs_intr_ctx_t		intr_ctx;
+	uint32_t		n_vec;
+
+	bus_dma_tag_t		dmat;	/** Parent DMA tag */
+	bus_dma_tag_t		buf_dmat;/** IO buffer DMA tag */
+	char display_name[OCS_DISPLAY_NAME_LENGTH];
+	uint16_t		pci_vendor;
+	uint16_t		pci_device;
+	uint16_t		pci_subsystem_vendor;
+	uint16_t		pci_subsystem_device;
+	char			businfo[16];
+	const char		*driver_version;
+	const char		*fw_version;
+	const char		*model;
+
+	ocs_hw_t hw;
+
+	ocs_rlock_t lock;	/**< device wide lock */
+
+	ocs_xport_e		ocs_xport;
+	ocs_xport_t *xport;	/**< pointer to transport object */
+	ocs_domain_t *domain;
+	ocs_list_t domain_list;
+	uint32_t domain_instance_count;
+	void (*domain_list_empty_cb)(ocs_t *ocs, void *arg);		
+	void *domain_list_empty_cb_arg;
+
+	uint8_t enable_ini;
+	uint8_t enable_tgt;
+	uint8_t fc_type;
+	int ctrlmask;
+	uint8_t explicit_buffer_list;
+	uint8_t external_loopback;
+	uint8_t skip_hw_teardown;
+	int speed;
+	int topology;
+	int ethernet_license;
+	int num_scsi_ios;
+	uint8_t enable_hlm;
+	uint32_t hlm_group_size;
+	uint32_t max_isr_time_msec;	/*>> Maximum ISR time */
+	uint32_t auto_xfer_rdy_size; /*>> Max sized write to use auto xfer rdy*/
+	uint8_t esoc;
+	int logmask;
+	char *hw_war_version;
+	uint32_t num_vports;
+	uint32_t target_io_timer_sec;
+	uint32_t hw_bounce;
+	uint8_t rq_threads;
+	uint8_t rq_selection_policy;
+	uint8_t rr_quanta;
+	char *filter_def;
+	uint32_t max_remote_nodes;
+
+	/*
+	 * tgt_rscn_delay - delay in kicking off RSCN processing 
+	 * (nameserver queries) after receiving an RSCN on the target. 
+	 * This prevents thrashing of nameserver requests due to a huge burst of
+	 * RSCNs received in a short period of time.
+	 * Note: this is only valid when target RSCN handling is enabled -- see 
+	 * ctrlmask.
+	 */
+	time_t tgt_rscn_delay_msec;	/*>> minimum target RSCN delay */
+
+	/*
+	 * tgt_rscn_period - determines maximum frequency when processing 
+	 * back-to-back RSCNs; e.g. if this value is 30, there will never be 
+	 * any more than 1 RSCN handling per 30s window. This prevents 
+	 * initiators on a faulty link generating many RSCN from causing the 
+	 * target to continually query the nameserver. 
+	 * Note: This is only valid when target RSCN handling is enabled
+	 */
+	time_t tgt_rscn_period_msec;	/*>> minimum target RSCN period */
+
+	uint32_t		enable_task_set_full;		
+	uint32_t		io_in_use;		
+	uint32_t		io_high_watermark; /**< used to send task set full */
+	struct mtx              sim_lock;
+	uint32_t		config_tgt:1,	/**< Configured to support target mode */
+				config_ini:1;	/**< Configured to support initiator mode */
+
+
+	uint32_t nodedb_mask;			/**< Node debugging mask */
+
+	char			modeldesc[64];
+	char			serialnum[64];
+	char			fwrev[64];
+	char			sli_intf[9];
+
+	ocs_ramlog_t		*ramlog;
+	ocs_textbuf_t		ddump_saved;
+
+	ocs_mgmt_functions_t	*mgmt_functions;
+	ocs_mgmt_functions_t	*tgt_mgmt_functions;
+	ocs_mgmt_functions_t	*ini_mgmt_functions;
+
+	ocs_err_injection_e err_injection;
+	uint32_t cmd_err_inject;
+	time_t delay_value_msec;
+
+	bool			attached;
+	struct mtx		dbg_lock;
+	
+	struct cam_devq		*devq;
+	ocs_fcport		*fcports;
+
+	void*			tgt_ocs;
+};
+
+static inline void
+ocs_device_lock_init(ocs_t *ocs)
+{
+	ocs_rlock_init(ocs, &ocs->lock, "ocsdevicelock");
+}
+
+static inline int32_t
+ocs_device_lock_try(ocs_t *ocs)
+{
+	return ocs_rlock_try(&ocs->lock);
+}
+
+static inline void
+ocs_device_lock(ocs_t *ocs)
+{
+	ocs_rlock_acquire(&ocs->lock);
+}
+
+static inline void
+ocs_device_unlock(ocs_t *ocs)
+{
+	ocs_rlock_release(&ocs->lock);
+}
+
+static inline void
+ocs_device_lock_free(ocs_t *ocs)
+{
+	ocs_rlock_free(&ocs->lock);
+}
+
+extern int32_t ocs_device_detach(ocs_t *ocs);
+
+extern int32_t ocs_device_attach(ocs_t *ocs);
+
+#define ocs_is_initiator_enabled()	(ocs->enable_ini)
+#define ocs_is_target_enabled()	(ocs->enable_tgt)
+
+#include "ocs_xport.h"
+#include "ocs_domain.h"
+#include "ocs_sport.h"
+#include "ocs_node.h"
+#include "ocs_unsol.h"
+#include "ocs_scsi.h"
+#include "ocs_ioctl.h"
+
+static inline ocs_io_t *
+ocs_io_alloc(ocs_t *ocs)
+{
+	return ocs_io_pool_io_alloc(ocs->xport->io_pool);
+}
+
+static inline void
+ocs_io_free(ocs_t *ocs, ocs_io_t *io)
+{
+	ocs_io_pool_io_free(ocs->xport->io_pool, io);
+}
+
+#endif /* __OCS_H__ */

Added: head/sys/dev/ocs_fc/ocs_cam.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/ocs_fc/ocs_cam.c	Fri Mar 30 15:28:25 2018	(r331766)
@@ -0,0 +1,2640 @@
+/*-
+ * Copyright (c) 2017 Broadcom. All rights reserved.
+ * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/**
+ * @defgroup scsi_api_target SCSI Target API
+ * @defgroup scsi_api_initiator SCSI Initiator API
+ * @defgroup cam_api Common Access Method (CAM) API
+ * @defgroup cam_io CAM IO
+ */
+
+/**
+ * @file
+ * Provides CAM functionality.
+ */
+
+#include "ocs.h"
+#include "ocs_scsi.h"
+#include "ocs_device.h"
+
+/* Default IO timeout value for initiators is 30 seconds */
+#define OCS_CAM_IO_TIMEOUT	30
+
+typedef struct {
+	ocs_scsi_sgl_t *sgl;
+	uint32_t sgl_max;
+	uint32_t sgl_count;
+	int32_t rc;
+} ocs_dmamap_load_arg_t;
+
+static void ocs_action(struct cam_sim *, union ccb *);
+static void ocs_poll(struct cam_sim *);
+
+static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *,
+					struct ccb_hdr *, uint32_t *);
+static int32_t ocs_tgt_resource_abort(struct ocs_softc *, ocs_tgt_resource_t *);
+static uint32_t ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb);
+static void ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb);
+static void ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb);
+static int32_t ocs_target_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
+static int32_t ocs_io_abort_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *);
+static int32_t ocs_task_set_full_or_busy(ocs_io_t *io);
+static int32_t ocs_initiator_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e,
+		ocs_scsi_cmd_resp_t *, uint32_t, void *);
+static uint32_t
+ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role);
+
+static inline ocs_io_t *ocs_scsi_find_io(struct ocs_softc *ocs, uint32_t tag)
+{
+
+	return ocs_io_get_instance(ocs, tag);
+}
+
+static inline void ocs_target_io_free(ocs_io_t *io)
+{
+	io->tgt_io.state = OCS_CAM_IO_FREE;
+	io->tgt_io.flags = 0;
+	io->tgt_io.app = NULL;
+	ocs_scsi_io_complete(io);
+	if(io->ocs->io_in_use != 0)
+		atomic_subtract_acq_32(&io->ocs->io_in_use, 1);
+}
+
+static int32_t
+ocs_attach_port(ocs_t *ocs, int chan)
+{
+
+	struct cam_sim	*sim = NULL;
+	struct cam_path	*path = NULL;
+	uint32_t	max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
+	ocs_fcport *fcp = FCPORT(ocs, chan);
+
+	if (NULL == (sim = cam_sim_alloc(ocs_action, ocs_poll, 
+				device_get_name(ocs->dev), ocs, 
+				device_get_unit(ocs->dev), &ocs->sim_lock,
+				max_io, max_io, ocs->devq))) {
+		device_printf(ocs->dev, "Can't allocate SIM\n");
+		return 1;
+	}
+
+	mtx_lock(&ocs->sim_lock);
+	if (CAM_SUCCESS != xpt_bus_register(sim, ocs->dev, chan)) {
+		device_printf(ocs->dev, "Can't register bus %d\n", 0);
+		mtx_unlock(&ocs->sim_lock);
+		cam_sim_free(sim, FALSE);
+		return 1;
+	}
+	mtx_unlock(&ocs->sim_lock);
+
+	if (CAM_REQ_CMP != xpt_create_path(&path, NULL, cam_sim_path(sim),
+				CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)) {
+		device_printf(ocs->dev, "Can't create path\n");
+		xpt_bus_deregister(cam_sim_path(sim));
+		mtx_unlock(&ocs->sim_lock);
+		cam_sim_free(sim, FALSE);
+		return 1;
+	}
+
+	fcp->sim  = sim;
+	fcp->path = path;
+
+	return 0;
+
+}
+
+static int32_t
+ocs_detach_port(ocs_t *ocs, int32_t chan)
+{
+	ocs_fcport *fcp = NULL;
+	struct cam_sim	*sim = NULL;
+	struct cam_path	*path = NULL;
+	fcp = FCPORT(ocs, chan);
+
+	sim = fcp->sim;
+	path = fcp->path;
+
+	if (fcp->sim) {
+		mtx_lock(&ocs->sim_lock);
+			ocs_tgt_resource_abort(ocs, &fcp->targ_rsrc_wildcard);
+			if (path) {
+				xpt_async(AC_LOST_DEVICE, path, NULL);
+				xpt_free_path(path);
+				fcp->path = NULL;
+			}
+			xpt_bus_deregister(cam_sim_path(sim));
+
+			cam_sim_free(sim, FALSE);
+			fcp->sim = NULL;
+		mtx_unlock(&ocs->sim_lock);
+	}
+	
+	return 0;
+}
+
+int32_t
+ocs_cam_attach(ocs_t *ocs)
+{
+	struct cam_devq	*devq = NULL;
+	int	i = 0;
+	uint32_t	max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS);
+
+	if (NULL == (devq = cam_simq_alloc(max_io))) {
+		device_printf(ocs->dev, "Can't allocate SIMQ\n");
+		return -1;
+	}
+
+	ocs->devq = devq;
+
+	if (mtx_initialized(&ocs->sim_lock) == 0) {
+		mtx_init(&ocs->sim_lock, "ocs_sim_lock", NULL, MTX_DEF);
+	}
+
+	for (i = 0; i < (ocs->num_vports + 1); i++) {
+		if (ocs_attach_port(ocs, i)) {
+			ocs_log_err(ocs, "Attach port failed for chan: %d\n", i);
+			goto detach_port;
+		}
+	}
+	
+	ocs->io_high_watermark = max_io;
+	ocs->io_in_use = 0;
+	return 0;
+
+detach_port:
+	while (--i >= 0) {
+		ocs_detach_port(ocs, i);
+	}
+
+	cam_simq_free(ocs->devq);
+
+	if (mtx_initialized(&ocs->sim_lock))
+		mtx_destroy(&ocs->sim_lock);
+
+	return 1;	
+}
+
+int32_t
+ocs_cam_detach(ocs_t *ocs)
+{
+	int i = 0;
+
+	for (i = (ocs->num_vports); i >= 0; i--) {
+		ocs_detach_port(ocs, i);
+	}
+
+	cam_simq_free(ocs->devq);
+
+	if (mtx_initialized(&ocs->sim_lock))
+		mtx_destroy(&ocs->sim_lock);
+
+	return 0;
+}
+
+/***************************************************************************
+ * Functions required by SCSI base driver API
+ */
+
+/**
+ * @ingroup scsi_api_target
+ * @brief Attach driver to the BSD SCSI layer (a.k.a CAM)
+ *
+ * Allocates + initializes CAM related resources and attaches to the CAM
+ *
+ * @param ocs the driver instance's software context
+ *
+ * @return 0 on success, non-zero otherwise
+ */
+int32_t
+ocs_scsi_tgt_new_device(ocs_t *ocs)
+{
+	ocs->enable_task_set_full = ocs_scsi_get_property(ocs, 
+					OCS_SCSI_ENABLE_TASK_SET_FULL);
+	ocs_log_debug(ocs, "task set full processing is %s\n",
+		ocs->enable_task_set_full ? "enabled" : "disabled");
+
+	return 0;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief Tears down target members of ocs structure.
+ *
+ * Called by OS code when device is removed.
+ *
+ * @param ocs pointer to ocs
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ */
+int32_t
+ocs_scsi_tgt_del_device(ocs_t *ocs)
+{
+
+	return 0;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief accept new domain notification
+ *
+ * Called by base drive when new domain is discovered.  A target-server
+ * will use this call to prepare for new remote node notifications
+ * arising from ocs_scsi_new_initiator().
+ *
+ * The domain context has an element <b>ocs_scsi_tgt_domain_t tgt_domain</b> 
+ * which is declared by the target-server code and is used for target-server 
+ * private data.
+ *
+ * This function will only be called if the base-driver has been enabled for 
+ * target capability.
+ *
+ * Note that this call is made to target-server backends, 
+ * the ocs_scsi_ini_new_domain() function is called to initiator-client backends.
+ *
+ * @param domain pointer to domain
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ */
+int32_t
+ocs_scsi_tgt_new_domain(ocs_domain_t *domain)
+{
+	return 0;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief accept domain lost notification
+ *
+ * Called by base-driver when a domain goes away.  A target-server will
+ * use this call to clean up all domain scoped resources.
+ *
+ * Note that this call is made to target-server backends,
+ * the ocs_scsi_ini_del_domain() function is called to initiator-client backends.
+ *
+ * @param domain pointer to domain
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ */
+void
+ocs_scsi_tgt_del_domain(ocs_domain_t *domain)
+{
+}
+
+
+/**
+ * @ingroup scsi_api_target
+ * @brief accept new sli port (sport) notification
+ *
+ * Called by base drive when new sport is discovered.  A target-server
+ * will use this call to prepare for new remote node notifications
+ * arising from ocs_scsi_new_initiator().
+ *
+ * The domain context has an element <b>ocs_scsi_tgt_sport_t tgt_sport</b> 
+ * which is declared by the target-server code and is used for
+ * target-server private data.
+ *
+ * This function will only be called if the base-driver has been enabled for 
+ * target capability.
+ *
+ * Note that this call is made to target-server backends,
+ * the ocs_scsi_tgt_new_domain() is called to initiator-client backends.
+ *
+ * @param sport pointer to SLI port
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ */
+int32_t
+ocs_scsi_tgt_new_sport(ocs_sport_t *sport)
+{
+	ocs_t *ocs = sport->ocs;
+
+	if(!sport->is_vport) {
+		sport->tgt_data = FCPORT(ocs, 0);
+	}
+
+	return 0;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief accept SLI port gone notification
+ *
+ * Called by base-driver when a sport goes away.  A target-server will
+ * use this call to clean up all sport scoped resources.
+ *
+ * Note that this call is made to target-server backends,
+ * the ocs_scsi_ini_del_sport() is called to initiator-client backends.
+ *
+ * @param sport pointer to SLI port
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ */
+void
+ocs_scsi_tgt_del_sport(ocs_sport_t *sport)
+{
+	return;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief receive notification of a new SCSI initiator node
+ *
+ * Sent by base driver to notify a target-server of the presense of a new
+ * remote initiator.   The target-server may use this call to prepare for
+ * inbound IO from this node.
+ *
+ * The ocs_node_t structure has and elment of type ocs_scsi_tgt_node_t named
+ * tgt_node that is declared and used by a target-server for private
+ * information.
+ *
+ * This function is only called if the target capability is enabled in driver.
+ *
+ * @param node pointer to new remote initiator node
+ *
+ * @return returns 0 for success, a negative error code value for failure.
+ *
+ * @note
+ */
+int32_t
+ocs_scsi_new_initiator(ocs_node_t *node)
+{
+	ocs_t	*ocs = node->ocs;
+	struct ac_contract ac;
+	struct ac_device_changed *adc;
+
+	ocs_fcport	*fcp = NULL;
+
+	fcp = node->sport->tgt_data;
+	if (fcp == NULL) {
+		ocs_log_err(ocs, "FCP is NULL \n");
+		return 1;
+	}	
+
+	/*
+	 * Update the IO watermark by decrementing it by the
+	 * number of IOs reserved for each initiator.
+	 */
+	atomic_subtract_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO);
+
+	ac.contract_number = AC_CONTRACT_DEV_CHG;
+	adc = (struct ac_device_changed *) ac.contract_data;
+	adc->wwpn = ocs_node_get_wwpn(node);
+	adc->port = node->rnode.fc_id;
+	adc->target = node->instance_index;
+	adc->arrived = 1;
+	xpt_async(AC_CONTRACT, fcp->path, &ac);
+
+	return 0;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief validate new initiator
+ *
+ * Sent by base driver to validate a remote initiatiator.   The target-server
+ * returns TRUE if this initiator should be accepted.
+ *
+ * This function is only called if the target capability is enabled in driver.
+ *
+ * @param node pointer to remote initiator node to validate
+ *
+ * @return TRUE if initiator should be accepted, FALSE if it should be rejected
+ *
+ * @note
+ */
+
+int32_t
+ocs_scsi_validate_initiator(ocs_node_t *node)
+{
+	return 1;
+}
+
+/**
+ * @ingroup scsi_api_target
+ * @brief Delete a SCSI initiator node
+ *
+ * Sent by base driver to notify a target-server that a remote initiator
+ * is now gone. The base driver will have terminated all outstanding IOs 
+ * and the target-server will receive appropriate completions.
+ *
+ * This function is only called if the base driver is enabled for
+ * target capability.
+ *
+ * @param node pointer node being deleted
+ * @param reason Reason why initiator is gone.
+ *
+ * @return OCS_SCSI_CALL_COMPLETE to indicate that all work was completed
+ *
+ * @note
+ */
+int32_t
+ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason)
+{
+	ocs_t	*ocs = node->ocs;
+
+	struct ac_contract ac;
+	struct ac_device_changed *adc;
+	ocs_fcport	*fcp = NULL;
+
+	fcp = node->sport->tgt_data;
+	if (fcp == NULL) {
+		ocs_log_err(ocs, "FCP is NULL \n");
+		return 1;
+	}
+
+	ac.contract_number = AC_CONTRACT_DEV_CHG;
+	adc = (struct ac_device_changed *) ac.contract_data;
+	adc->wwpn = ocs_node_get_wwpn(node);
+	adc->port = node->rnode.fc_id;
+	adc->target = node->instance_index;
+	adc->arrived = 0;
+	xpt_async(AC_CONTRACT, fcp->path, &ac);
+
+
+	if (reason == OCS_SCSI_INITIATOR_MISSING) {
+		return OCS_SCSI_CALL_COMPLETE;
+	}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list