Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42e9a92f authored by Robert Love's avatar Robert Love Committed by James Bottomley
Browse files

[SCSI] libfc: A modular Fibre Channel library



libFC is composed of 4 blocks supported by an exchange manager
and a framing library. The upper 4 layers are fc_lport, fc_disc,
fc_rport and fc_fcp. A LLD that uses libfc could choose to
either use libfc's block, or using the transport template
defined in libfc.h, override one or more blocks with its own
implementation.

The EM (Exchange Manager) manages exhcanges/sequences for all
commands- ELS, CT and FCP.

The framing library frames ELS and CT commands.

The fc_lport block manages the library's representation of the
host's FC enabled ports.

The fc_disc block manages discovery of targets as well as
handling changes that occur in the FC fabric (via. RSCN events).

The fc_rport block manages the library's representation of other
entities in the FC fabric. Currently the library uses this block
for targets, its peer when in point-to-point mode and the
directory server, but can be extended for other entities if
needed.

The fc_fcp block interacts with the scsi-ml and handles all
I/O.

Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
[jejb: added include of delay.h to fix ppc64 compile prob spotted by sfr]
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent f032c2f7
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -603,6 +603,12 @@ config SCSI_FLASHPOINT
	  substantial, so users of MultiMaster Host Adapters may not
	  wish to include it.

config LIBFC
	tristate "LibFC module"
	depends on SCSI && SCSI_FC_ATTRS
	---help---
	  Fibre Channel library module

config SCSI_DMX3191D
	tristate "DMX3191D SCSI support"
	depends on PCI && SCSI
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/
obj-$(CONFIG_SCSI_SRP_ATTRS)	+= scsi_transport_srp.o
obj-$(CONFIG_SCSI_DH)		+= device_handler/

obj-$(CONFIG_LIBFC)		+= libfc/
obj-$(CONFIG_ISCSI_TCP) 	+= libiscsi.o	libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) 	+= libiscsi.o
obj-$(CONFIG_SCSI_A4000T)	+= 53c700.o	a4000t.o
+12 −0
Original line number Diff line number Diff line
# $Id: Makefile

obj-$(CONFIG_LIBFC) += libfc.o

libfc-objs := \
	fc_disc.o \
	fc_exch.o \
	fc_elsct.o \
	fc_frame.o \
	fc_lport.o \
	fc_rport.o \
	fc_fcp.o
+845 −0

File added.

Preview size limit exceeded, changes collapsed.

+71 −0
Original line number Diff line number Diff line
/*
 * Copyright(c) 2008 Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Maintained at www.Open-FCoE.org
 */

/*
 * Provide interface to send ELS/CT FC frames
 */

#include <asm/unaligned.h>
#include <scsi/fc/fc_gs.h>
#include <scsi/fc/fc_ns.h>
#include <scsi/fc/fc_els.h>
#include <scsi/libfc.h>
#include <scsi/fc_encode.h>

/*
 * fc_elsct_send - sends ELS/CT frame
 */
static struct fc_seq *fc_elsct_send(struct fc_lport *lport,
				    struct fc_rport *rport,
				    struct fc_frame *fp,
				    unsigned int op,
				    void (*resp)(struct fc_seq *,
						 struct fc_frame *fp,
						 void *arg),
				    void *arg, u32 timer_msec)
{
	enum fc_rctl r_ctl;
	u32 did;
	enum fc_fh_type fh_type;
	int rc;

	/* ELS requests */
	if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS))
		rc = fc_els_fill(lport, rport, fp, op, &r_ctl, &did, &fh_type);
	else
		/* CT requests */
		rc = fc_ct_fill(lport, fp, op, &r_ctl, &did, &fh_type);

	if (rc)
		return NULL;

	fc_fill_fc_hdr(fp, r_ctl, did, fc_host_port_id(lport->host), fh_type,
		       FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);

	return lport->tt.exch_seq_send(lport, fp, resp, NULL, arg, timer_msec);
}

int fc_elsct_init(struct fc_lport *lport)
{
	if (!lport->tt.elsct_send)
		lport->tt.elsct_send = fc_elsct_send;

	return 0;
}
EXPORT_SYMBOL(fc_elsct_init);
Loading