Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 Jan 2015 07:49:50 +0000 (UTC)
From:      Edward Tomasz Napierala <trasz@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r277963 - in head/sys: cam/ctl conf dev/iscsi modules/ctl modules/iscsi
Message-ID:  <201501310749.t0V7noWu098808@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trasz
Date: Sat Jan 31 07:49:50 2015
New Revision: 277963
URL: https://svnweb.freebsd.org/changeset/base/277963

Log:
  Add kobj interface between ICL and the rest of the iSCSI stack.
  Review note - icl.c was moved to icl_soft.c.
  
  MFC after:	1 month
  Sponsored by:	The FreeBSD Foundation

Added:
  head/sys/dev/iscsi/icl_soft.c
     - copied, changed from r277931, head/sys/dev/iscsi/icl.c
Replaced:
  head/sys/dev/iscsi/icl.c   (contents, props changed)
Modified:
  head/sys/cam/ctl/ctl_frontend_iscsi.c
  head/sys/conf/files
  head/sys/dev/iscsi/icl.h
  head/sys/dev/iscsi/iscsi.c
  head/sys/modules/ctl/Makefile
  head/sys/modules/iscsi/Makefile

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c	Sat Jan 31 07:49:50 2015	(r277963)
@@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/ctl/ctl_private.h>
 
 #include <dev/iscsi/icl.h>
+#include <dev/iscsi/icl_wrappers.h>
 #include <dev/iscsi/iscsi_proto.h>
 #include <cam/ctl/ctl_frontend_iscsi.h>
 
@@ -1241,7 +1242,7 @@ cfiscsi_session_new(struct cfiscsi_softc
 	cv_init(&cs->cs_login_cv, "cfiscsi_login");
 #endif
 
-	cs->cs_conn = icl_conn_new("cfiscsi", &cs->cs_lock);
+	cs->cs_conn = icl_new_conn(NULL, "cfiscsi", &cs->cs_lock);
 	cs->cs_conn->ic_receive = cfiscsi_receive_callback;
 	cs->cs_conn->ic_error = cfiscsi_error_callback;
 	cs->cs_conn->ic_prv0 = cs;
@@ -2013,6 +2014,7 @@ cfiscsi_ioctl_port_create(struct ctl_req
 		return;
 	}
 	port = &ct->ct_port;
+	// WAT
 	if (ct->ct_state == CFISCSI_TARGET_STATE_DYING)
 		goto done;
 

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/conf/files	Sat Jan 31 07:49:50 2015	(r277963)
@@ -1521,6 +1521,7 @@ ipw_monitor.fw			optional ipwmonitorfw |
 	clean		"ipw_monitor.fw"
 dev/iscsi/icl.c			optional iscsi | ctl 
 dev/iscsi/icl_proxy.c		optional iscsi | ctl
+dev/iscsi/icl_soft.c		optional iscsi | ctl 
 dev/iscsi/iscsi.c		optional iscsi scbus
 dev/iscsi_initiator/iscsi.c	optional iscsi_initiator scbus
 dev/iscsi_initiator/iscsi_subr.c	optional iscsi_initiator scbus

Added: head/sys/dev/iscsi/icl.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/iscsi/icl.c	Sat Jan 31 07:49:50 2015	(r277963)
@@ -0,0 +1,247 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Edward Tomasz Napierala under sponsorship
+ * from the FreeBSD Foundation.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ */
+
+/*
+ * iSCSI Common Layer.  It's used by both the initiator and target to send
+ * and receive iSCSI PDUs.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/condvar.h>
+#include <sys/conf.h>
+#include <sys/lock.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+#include <sys/sx.h>
+
+#include <dev/iscsi/icl.h>
+#include <icl_conn_if.h>
+
+struct icl_module {
+	TAILQ_ENTRY(icl_module)		im_next;
+	char				*im_name;
+	int				im_priority;
+	int				(*im_limits)(size_t *limitp);
+	struct icl_conn			*(*im_new_conn)(const char *name,
+					    struct mtx *lock);
+};
+
+struct icl_softc {
+	struct sx			sc_lock;
+	TAILQ_HEAD(, icl_module)	sc_modules;
+};
+
+SYSCTL_NODE(_kern, OID_AUTO, icl, CTLFLAG_RD, 0, "iSCSI Common Layer");
+int icl_debug = 1;
+SYSCTL_INT(_kern_icl, OID_AUTO, debug, CTLFLAG_RWTUN,
+    &icl_debug, 0, "Enable debug messages");
+
+static MALLOC_DEFINE(M_ICL, "icl", "iSCSI Common Layer");
+static struct icl_softc	*sc;
+
+static struct icl_module *
+icl_find(const char *name)
+{
+	struct icl_module *im, *im_max;
+
+	sx_assert(&sc->sc_lock, SA_LOCKED);
+
+	/*
+	 * If the name was not specified, pick a module with highest
+	 * priority.
+	 */
+	if (name == NULL || name[0] == '\0') {
+		im_max = TAILQ_FIRST(&sc->sc_modules);
+		TAILQ_FOREACH(im, &sc->sc_modules, im_next) {
+			if (im->im_priority > im_max->im_priority)
+				im_max = im;
+		}
+
+		return (im_max);
+	}
+
+	TAILQ_FOREACH(im, &sc->sc_modules, im_next) {
+		if (strcmp(im->im_name, name) == 0)
+			return (im);
+	}
+
+	return (NULL);
+}
+
+struct icl_conn *
+icl_new_conn(const char *offload, const char *name, struct mtx *lock)
+{
+	struct icl_module *im;
+	struct icl_conn *ic;
+
+	sx_slock(&sc->sc_lock);
+	im = icl_find(offload);
+
+	if (im == NULL) {
+		ICL_WARN("offload \"%s\" not found", offload);
+		sx_sunlock(&sc->sc_lock);
+		return (NULL);
+	}
+
+	ic = im->im_new_conn(name, lock);
+	sx_sunlock(&sc->sc_lock);
+
+	return (ic);
+}
+
+int
+icl_limits(const char *offload, size_t *limitp)
+{
+	struct icl_module *im;
+	int error;
+
+	sx_slock(&sc->sc_lock);
+	im = icl_find(offload);
+
+	if (im == NULL) {
+		ICL_WARN("offload \"%s\" not found", offload);
+		sx_sunlock(&sc->sc_lock);
+		return (ENXIO);
+	}
+
+	error = im->im_limits(limitp);
+	sx_sunlock(&sc->sc_lock);
+
+	return (error);
+}
+
+
+int
+icl_register(const char *offload, int priority, int (*limits)(size_t *),
+    struct icl_conn *(*new_conn)(const char *, struct mtx *))
+{
+	struct icl_module *im;
+
+	sx_xlock(&sc->sc_lock);
+	im = icl_find(offload);
+
+	if (im != NULL) {
+		ICL_WARN("offload \"%s\" already registered", offload);
+		sx_xunlock(&sc->sc_lock);
+		return (EBUSY);
+	}
+
+	im = malloc(sizeof(*im), M_ICL, M_ZERO | M_WAITOK);
+	im->im_name = strdup(offload, M_ICL);
+	im->im_priority = priority;
+	im->im_limits = limits;
+	im->im_new_conn = new_conn;
+
+	TAILQ_INSERT_HEAD(&sc->sc_modules, im, im_next);
+	sx_xunlock(&sc->sc_lock);
+
+	ICL_DEBUG("offload \"%s\" registered", offload);
+	return (0);
+}
+
+int
+icl_unregister(const char *offload)
+{
+	struct icl_module *im;
+
+	sx_xlock(&sc->sc_lock);
+	im = icl_find(offload);
+
+	if (im == NULL) {
+		ICL_WARN("offload \"%s\" not registered", offload);
+		sx_xunlock(&sc->sc_lock);
+		return (ENXIO);
+	}
+
+	TAILQ_REMOVE(&sc->sc_modules, im, im_next);
+	sx_xunlock(&sc->sc_lock);
+
+	free(im->im_name, M_ICL);
+	free(im, M_ICL);
+
+	ICL_DEBUG("offload \"%s\" unregistered", offload);
+	return (0);
+}
+
+static int
+icl_load(void)
+{
+
+	sc = malloc(sizeof(*sc), M_ICL, M_ZERO | M_WAITOK);
+	sx_init(&sc->sc_lock, "icl");
+	TAILQ_INIT(&sc->sc_modules);
+
+	return (0);
+}
+
+static int
+icl_unload(void)
+{
+
+	sx_slock(&sc->sc_lock);
+	KASSERT(TAILQ_EMPTY(&sc->sc_modules), ("still have modules"));
+	sx_sunlock(&sc->sc_lock);
+
+	sx_destroy(&sc->sc_lock);
+	free(sc, M_ICL);
+
+	return (0);
+}
+
+static int
+icl_modevent(module_t mod, int what, void *arg)
+{
+
+	switch (what) {
+	case MOD_LOAD:
+		return (icl_load());
+	case MOD_UNLOAD:
+		return (icl_unload());
+	default:
+		return (EINVAL);
+	}
+}
+
+moduledata_t icl_data = {
+	"icl",
+	icl_modevent,
+	0
+};
+
+DECLARE_MODULE(icl, icl_data, SI_SUB_DRIVERS, SI_ORDER_FIRST);
+MODULE_VERSION(icl, 1);

Modified: head/sys/dev/iscsi/icl.h
==============================================================================
--- head/sys/dev/iscsi/icl.h	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/dev/iscsi/icl.h	Sat Jan 31 07:49:50 2015	(r277963)
@@ -37,7 +37,32 @@
  * and receive iSCSI PDUs.
  */
 
+#include <sys/types.h>
+#include <sys/kobj.h>
+#include <sys/condvar.h>
+#include <sys/sysctl.h>
+
+SYSCTL_DECL(_kern_icl);
+
+extern int icl_debug;
+
+#define	ICL_DEBUG(X, ...)						\
+	do {								\
+		if (icl_debug > 1)					\
+			printf("%s: " X "\n", __func__, ## __VA_ARGS__);\
+	} while (0)
+
+#define	ICL_WARN(X, ...)						\
+	do {								\
+		if (icl_debug > 0) {					\
+			printf("WARNING: %s: " X "\n",			\
+			    __func__, ## __VA_ARGS__);			\
+		}							\
+	} while (0)
+
 struct icl_conn;
+struct ccb_scsiio;
+union ctl_io;
 
 struct icl_pdu {
 	STAILQ_ENTRY(icl_pdu)	ip_next;
@@ -57,13 +82,6 @@ struct icl_pdu {
 	uint32_t		ip_prv2;
 };
 
-struct icl_pdu		*icl_pdu_new(struct icl_conn *ic, int flags);
-size_t			icl_pdu_data_segment_length(const struct icl_pdu *ip);
-int			icl_pdu_append_data(struct icl_pdu *ip, const void *addr, size_t len, int flags);
-void			icl_pdu_get_data(struct icl_pdu *ip, size_t off, void *addr, size_t len);
-void			icl_pdu_queue(struct icl_pdu *ip);
-void			icl_pdu_free(struct icl_pdu *ip);
-
 #define ICL_CONN_STATE_INVALID		0
 #define ICL_CONN_STATE_BHS		1
 #define ICL_CONN_STATE_AHS		2
@@ -74,6 +92,7 @@ void			icl_pdu_free(struct icl_pdu *ip);
 #define	ICL_MAX_DATA_SEGMENT_LENGTH	(128 * 1024)
 
 struct icl_conn {
+	KOBJ_FIELDS;
 	struct mtx		*ic_lock;
 	struct socket		*ic_socket;
 #ifdef DIAGNOSTIC
@@ -104,11 +123,14 @@ struct icl_conn {
 	void			*ic_prv0;
 };
 
-struct icl_conn		*icl_conn_new(const char *name, struct mtx *lock);
-void			icl_conn_free(struct icl_conn *ic);
-int			icl_conn_handoff(struct icl_conn *ic, int fd);
-void			icl_conn_close(struct icl_conn *ic);
-bool			icl_conn_connected(struct icl_conn *ic);
+struct icl_conn	*icl_new_conn(const char *offload, const char *name,
+		    struct mtx *lock);
+int		icl_limits(const char *offload, size_t *limitp);
+
+int		icl_register(const char *offload, int priority,
+		    int (*limits)(size_t *),
+		    struct icl_conn *(*new_conn)(const char *, struct mtx *));
+int		icl_unregister(const char *offload);
 
 #ifdef ICL_KERNEL_PROXY
 

Copied and modified: head/sys/dev/iscsi/icl_soft.c (from r277931, head/sys/dev/iscsi/icl.c)
==============================================================================
--- head/sys/dev/iscsi/icl.c	Fri Jan 30 14:22:15 2015	(r277931, copy source)
+++ head/sys/dev/iscsi/icl_soft.c	Sat Jan 31 07:49:50 2015	(r277963)
@@ -60,11 +60,8 @@ __FBSDID("$FreeBSD$");
 
 #include <dev/iscsi/icl.h>
 #include <dev/iscsi/iscsi_proto.h>
+#include <icl_conn_if.h>
 
-SYSCTL_NODE(_kern, OID_AUTO, icl, CTLFLAG_RD, 0, "iSCSI Common Layer");
-static int debug = 1;
-SYSCTL_INT(_kern_icl, OID_AUTO, debug, CTLFLAG_RWTUN,
-    &debug, 0, "Enable debug messages");
 static int coalesce = 1;
 SYSCTL_INT(_kern_icl, OID_AUTO, coalesce, CTLFLAG_RWTUN,
     &coalesce, 0, "Try to coalesce PDUs before sending");
@@ -79,25 +76,11 @@ static int recvspace = 1048576;
 SYSCTL_INT(_kern_icl, OID_AUTO, recvspace, CTLFLAG_RWTUN,
     &recvspace, 0, "Default receive socket buffer size");
 
-static uma_zone_t icl_conn_zone;
+static MALLOC_DEFINE(M_ICL_SOFT, "icl_soft", "iSCSI software backend");
 static uma_zone_t icl_pdu_zone;
 
 static volatile u_int	icl_ncons;
 
-#define	ICL_DEBUG(X, ...)						\
-	do {								\
-		if (debug > 1)						\
-			printf("%s: " X "\n", __func__, ## __VA_ARGS__);\
-	} while (0)
-
-#define	ICL_WARN(X, ...)						\
-	do {								\
-		if (debug > 0) {					\
-			printf("WARNING: %s: " X "\n",			\
-			    __func__, ## __VA_ARGS__);			\
-		}							\
-	} while (0)
-
 #define ICL_CONN_LOCK(X)		mtx_lock(X->ic_lock)
 #define ICL_CONN_UNLOCK(X)		mtx_unlock(X->ic_lock)
 #define ICL_CONN_LOCK_ASSERT(X)		mtx_assert(X->ic_lock, MA_OWNED)
@@ -105,6 +88,37 @@ static volatile u_int	icl_ncons;
 
 STAILQ_HEAD(icl_pdu_stailq, icl_pdu);
 
+static icl_conn_new_pdu_t	icl_soft_conn_new_pdu;
+static icl_conn_pdu_free_t	icl_soft_conn_pdu_free;
+static icl_conn_pdu_data_segment_length_t
+				    icl_soft_conn_pdu_data_segment_length;
+static icl_conn_pdu_append_data_t	icl_soft_conn_pdu_append_data;
+static icl_conn_pdu_get_data_t	icl_soft_conn_pdu_get_data;
+static icl_conn_pdu_queue_t	icl_soft_conn_pdu_queue;
+static icl_conn_handoff_t	icl_soft_conn_handoff;
+static icl_conn_free_t		icl_soft_conn_free;
+static icl_conn_close_t		icl_soft_conn_close;
+static icl_conn_connected_t	icl_soft_conn_connected;
+
+static kobj_method_t icl_soft_methods[] = {
+	KOBJMETHOD(icl_conn_new_pdu, icl_soft_conn_new_pdu),
+	KOBJMETHOD(icl_conn_pdu_free, icl_soft_conn_pdu_free),
+	KOBJMETHOD(icl_conn_pdu_data_segment_length,
+	    icl_soft_conn_pdu_data_segment_length),
+	KOBJMETHOD(icl_conn_pdu_append_data, icl_soft_conn_pdu_append_data),
+	KOBJMETHOD(icl_conn_pdu_get_data, icl_soft_conn_pdu_get_data),
+	KOBJMETHOD(icl_conn_pdu_queue, icl_soft_conn_pdu_queue),
+	KOBJMETHOD(icl_conn_handoff, icl_soft_conn_handoff),
+	KOBJMETHOD(icl_conn_free, icl_soft_conn_free),
+	KOBJMETHOD(icl_conn_close, icl_soft_conn_close),
+	KOBJMETHOD(icl_conn_connected, icl_soft_conn_connected),
+	{ 0, 0 }
+};
+
+DEFINE_CLASS(icl_soft, icl_soft_methods, sizeof(struct icl_conn));
+
+static void	icl_conn_close(struct icl_conn *ic);
+
 static void
 icl_conn_fail(struct icl_conn *ic)
 {
@@ -168,7 +182,7 @@ icl_pdu_new_empty(struct icl_conn *ic, i
 	return (ip);
 }
 
-void
+static void
 icl_pdu_free(struct icl_pdu *ip)
 {
 	struct icl_conn *ic;
@@ -184,11 +198,17 @@ icl_pdu_free(struct icl_pdu *ip)
 #endif
 }
 
+void
+icl_soft_conn_pdu_free(struct icl_conn *ic, struct icl_pdu *ip)
+{
+	icl_pdu_free(ip);
+}
+
 /*
  * Allocate icl_pdu with empty BHS to fill up by the caller.
  */
 struct icl_pdu *
-icl_pdu_new(struct icl_conn *ic, int flags)
+icl_soft_conn_new_pdu(struct icl_conn *ic, int flags)
 {
 	struct icl_pdu *ip;
 
@@ -217,7 +237,7 @@ icl_pdu_ahs_length(const struct icl_pdu 
 	return (request->ip_bhs->bhs_total_ahs_len * 4);
 }
 
-size_t
+static size_t
 icl_pdu_data_segment_length(const struct icl_pdu *request)
 {
 	uint32_t len = 0;
@@ -231,6 +251,14 @@ icl_pdu_data_segment_length(const struct
 	return (len);
 }
 
+size_t
+icl_soft_conn_pdu_data_segment_length(struct icl_conn *ic,
+    const struct icl_pdu *request)
+{
+
+	return (icl_pdu_data_segment_length(request));
+}
+
 static void
 icl_pdu_set_data_segment_length(struct icl_pdu *response, uint32_t len)
 {
@@ -1046,7 +1074,7 @@ icl_soupcall_send(struct socket *so, voi
 	return (SU_OK);
 }
 
-int
+static int
 icl_pdu_append_data(struct icl_pdu *request, const void *addr, size_t len,
     int flags)
 {
@@ -1080,7 +1108,15 @@ icl_pdu_append_data(struct icl_pdu *requ
 	return (0);
 }
 
-void
+int
+icl_soft_conn_pdu_append_data(struct icl_conn *ic, struct icl_pdu *request,
+    const void *addr, size_t len, int flags)
+{
+
+	return (icl_pdu_append_data(request, addr, len, flags));
+}
+
+static void
 icl_pdu_get_data(struct icl_pdu *ip, size_t off, void *addr, size_t len)
 {
 
@@ -1088,6 +1124,14 @@ icl_pdu_get_data(struct icl_pdu *ip, siz
 }
 
 void
+icl_soft_conn_pdu_get_data(struct icl_conn *ic, struct icl_pdu *ip,
+    size_t off, void *addr, size_t len)
+{
+
+	return (icl_pdu_get_data(ip, off, addr, len));
+}
+
+static void
 icl_pdu_queue(struct icl_pdu *ip)
 {
 	struct icl_conn *ic;
@@ -1116,14 +1160,21 @@ icl_pdu_queue(struct icl_pdu *ip)
 	cv_signal(&ic->ic_send_cv);
 }
 
-struct icl_conn *
-icl_conn_new(const char *name, struct mtx *lock)
+void
+icl_soft_conn_pdu_queue(struct icl_conn *ic, struct icl_pdu *ip)
+{
+
+	icl_pdu_queue(ip);
+}
+
+static struct icl_conn *
+icl_soft_new_conn(const char *name, struct mtx *lock)
 {
 	struct icl_conn *ic;
 
 	refcount_acquire(&icl_ncons);
 
-	ic = uma_zalloc(icl_conn_zone, M_WAITOK | M_ZERO);
+	ic = (struct icl_conn *)kobj_create(&icl_soft_class, M_ICL_SOFT, M_WAITOK | M_ZERO);
 
 	STAILQ_INIT(&ic->ic_to_send);
 	ic->ic_lock = lock;
@@ -1139,12 +1190,12 @@ icl_conn_new(const char *name, struct mt
 }
 
 void
-icl_conn_free(struct icl_conn *ic)
+icl_soft_conn_free(struct icl_conn *ic)
 {
 
 	cv_destroy(&ic->ic_send_cv);
 	cv_destroy(&ic->ic_receive_cv);
-	uma_zfree(icl_conn_zone, ic);
+	kobj_delete((struct kobj *)ic, M_ICL_SOFT);
 	refcount_release(&icl_ncons);
 }
 
@@ -1252,7 +1303,7 @@ icl_conn_start(struct icl_conn *ic)
 }
 
 int
-icl_conn_handoff(struct icl_conn *ic, int fd)
+icl_soft_conn_handoff(struct icl_conn *ic, int fd)
 {
 	struct file *fp;
 	struct socket *so;
@@ -1367,8 +1418,15 @@ icl_conn_close(struct icl_conn *ic)
 	ICL_CONN_UNLOCK(ic);
 }
 
+void
+icl_soft_conn_close(struct icl_conn *ic)
+{
+
+	icl_conn_close(ic);
+}
+
 bool
-icl_conn_connected(struct icl_conn *ic)
+icl_soft_conn_connected(struct icl_conn *ic)
 {
 	ICL_CONN_LOCK_ASSERT_NOT(ic);
 
@@ -1385,6 +1443,15 @@ icl_conn_connected(struct icl_conn *ic)
 	return (true);
 }
 
+static int
+icl_soft_limits(size_t *limitp)
+{
+
+	*limitp = 128 * 1024;
+
+	return (0);
+}
+
 #ifdef ICL_KERNEL_PROXY
 int
 icl_conn_handoff_sock(struct icl_conn *ic, struct socket *so)
@@ -1411,52 +1478,60 @@ icl_conn_handoff_sock(struct icl_conn *i
 #endif /* ICL_KERNEL_PROXY */
 
 static int
-icl_unload(void)
+icl_soft_load(void)
 {
+	int error;
 
-	if (icl_ncons != 0)
-		return (EBUSY);
+	icl_pdu_zone = uma_zcreate("icl_pdu",
+	    sizeof(struct icl_pdu), NULL, NULL, NULL, NULL,
+	    UMA_ALIGN_PTR, 0);
+	refcount_init(&icl_ncons, 0);
 
-	uma_zdestroy(icl_conn_zone);
-	uma_zdestroy(icl_pdu_zone);
+	/*
+	 * The reason we call this "none" is that to the user,
+	 * it's known as "offload driver"; "offload driver: soft"
+	 * doesn't make much sense.
+	 */
+	error = icl_register("none", 0, icl_soft_limits, icl_soft_new_conn);
+	KASSERT(error == 0, ("failed to register"));
 
-	return (0);
+	return (error);
 }
 
-static void
-icl_load(void)
+static int
+icl_soft_unload(void)
 {
 
-	icl_conn_zone = uma_zcreate("icl_conn",
-	    sizeof(struct icl_conn), NULL, NULL, NULL, NULL,
-	    UMA_ALIGN_PTR, 0);
-	icl_pdu_zone = uma_zcreate("icl_pdu",
-	    sizeof(struct icl_pdu), NULL, NULL, NULL, NULL,
-	    UMA_ALIGN_PTR, 0);
+	if (icl_ncons != 0)
+		return (EBUSY);
 
-	refcount_init(&icl_ncons, 0);
+	icl_unregister("none");
+
+	uma_zdestroy(icl_pdu_zone);
+
+	return (0);
 }
 
 static int
-icl_modevent(module_t mod, int what, void *arg)
+icl_soft_modevent(module_t mod, int what, void *arg)
 {
 
 	switch (what) {
 	case MOD_LOAD:
-		icl_load();
-		return (0);
+		return (icl_soft_load());
 	case MOD_UNLOAD:
-		return (icl_unload());
+		return (icl_soft_unload());
 	default:
 		return (EINVAL);
 	}
 }
 
-moduledata_t icl_data = {
-	"icl",
-	icl_modevent,
+moduledata_t icl_soft_data = {
+	"icl_soft",
+	icl_soft_modevent,
 	0
 };
 
-DECLARE_MODULE(icl, icl_data, SI_SUB_DRIVERS, SI_ORDER_FIRST);
+DECLARE_MODULE(icl_soft, icl_soft_data, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
+MODULE_DEPEND(icl_soft, icl, 1, 1, 1);
 MODULE_VERSION(icl, 1);

Modified: head/sys/dev/iscsi/iscsi.c
==============================================================================
--- head/sys/dev/iscsi/iscsi.c	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/dev/iscsi/iscsi.c	Sat Jan 31 07:49:50 2015	(r277963)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include <cam/scsi/scsi_message.h>
 
 #include <dev/iscsi/icl.h>
+#include <dev/iscsi/icl_wrappers.h>
 #include <dev/iscsi/iscsi_ioctl.h>
 #include <dev/iscsi/iscsi_proto.h>
 #include <dev/iscsi/iscsi.h>
@@ -1730,7 +1731,7 @@ iscsi_ioctl_session_add(struct iscsi_sof
 		return (EBUSY);
 	}
 
-	is->is_conn = icl_conn_new("iscsi", &is->is_lock);
+	is->is_conn = icl_new_conn(NULL, "iscsi", &is->is_lock);
 	is->is_conn->ic_receive = iscsi_receive_callback;
 	is->is_conn->ic_error = iscsi_error_callback;
 	is->is_conn->ic_prv0 = is;

Modified: head/sys/modules/ctl/Makefile
==============================================================================
--- head/sys/modules/ctl/Makefile	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/modules/ctl/Makefile	Sat Jan 31 07:49:50 2015	(r277963)
@@ -22,8 +22,11 @@ SRCS+=	scsi_ctl.c
 SRCS+=	bus_if.h
 SRCS+=	device_if.h
 SRCS+=	vnode_if.h
+SRCS+=	icl_conn_if.h
 SRCS+=	opt_cam.h
 
 #CFLAGS+=-DICL_KERNEL_PROXY
 
+MFILES=	kern/bus_if.m kern/device_if.m dev/iscsi/icl_conn_if.m
+
 .include <bsd.kmod.mk>

Modified: head/sys/modules/iscsi/Makefile
==============================================================================
--- head/sys/modules/iscsi/Makefile	Sat Jan 31 07:22:29 2015	(r277962)
+++ head/sys/modules/iscsi/Makefile	Sat Jan 31 07:49:50 2015	(r277963)
@@ -6,10 +6,15 @@ KMOD=	iscsi
 SRCS=	iscsi.c
 SRCS+=	icl.c
 SRCS+=	icl_proxy.c
+SRCS+=	icl_soft.c
 SRCS+=	opt_cam.h
 SRCS+=	bus_if.h
 SRCS+=	device_if.h
+SRCS+=	icl_conn_if.c
+SRCS+=	icl_conn_if.h
 
 #CFLAGS+=-DICL_KERNEL_PROXY
 
+MFILES=	kern/bus_if.m kern/device_if.m dev/iscsi/icl_conn_if.m
+
 .include <bsd.kmod.mk>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201501310749.t0V7noWu098808>