diff --git a/iscsi-scst/include/iscsit_transport.h b/iscsi-scst/include/iscsit_transport.h new file mode 100644 index 000000000..e4e5ff870 --- /dev/null +++ b/iscsi-scst/include/iscsit_transport.h @@ -0,0 +1,65 @@ + +#ifndef __ISCSI_TRANSPORT_H__ +#define __ISCSI_TRANSPORT_H__ + +#include +#include + +#ifdef INSIDE_KERNEL_TREE +#include +#else +#include +#endif + +/* forward declarations */ +struct iscsi_session; +struct iscsi_kern_conn_info; +struct iscsi_conn; + +enum iscsit_transport_type { + ISCSI_TCP, + ISCSI_RDMA, +}; + +struct iscsit_transport { + struct iscsi_cmnd* (*iscsit_alloc_cmd)(struct iscsi_conn *conn, + struct iscsi_cmnd *parent); + void (*iscsit_free_cmd)(struct iscsi_cmnd *cmnd); + void (*iscsit_preprocessing_done)(struct iscsi_cmnd *cmnd); + void (*iscsit_send_data_rsp)(struct iscsi_cmnd *req, u8 *sense, + int sense_len, u8 status, + int send_status); + void (*iscsit_make_conn_wr_active)(struct iscsi_conn *conn); + int (*iscsit_conn_alloc)(struct iscsi_session *session, + struct iscsi_kern_conn_info *info, + struct iscsi_conn **new_conn, + struct iscsit_transport *transport); + int (*iscsit_conn_activate)(struct iscsi_conn *conn); + void (*iscsit_conn_free)(struct iscsi_conn *conn); + void (*iscsit_conn_close)(struct iscsi_conn *conn, int flags); + void (*iscsit_mark_conn_closed)(struct iscsi_conn *conn, int flags); + ssize_t (*iscsit_get_initiator_ip)(struct iscsi_conn *conn, char *buf, + int size); + int (*iscsit_send_locally)(struct iscsi_cmnd *cmnd, + unsigned int cmd_count); + void (*iscsit_set_sense_data)(struct iscsi_cmnd *rsp, + const u8 *sense_buf, int sense_len); + void (*iscsit_set_req_data)(struct iscsi_cmnd *req, + struct iscsi_cmnd *rsp); + int (*iscsit_receive_cmnd_data)(struct iscsi_cmnd *cmnd); + void (*iscsit_close_all_portals)(void); + + unsigned int need_alloc_write_buf:1; + + struct module *owner; + const char name[SCST_MAX_NAME]; + enum iscsit_transport_type transport_type; + struct list_head list; +}; + +extern int iscsit_register_transport(struct iscsit_transport *t); +extern void iscsit_unregister_transport(struct iscsit_transport *t); +extern struct iscsit_transport *iscsit_get_transport(enum iscsit_transport_type type); + +#endif /* __ISCSI_TRANSPORT_H__ */ + diff --git a/iscsi-scst/kernel/Makefile b/iscsi-scst/kernel/Makefile index 9d59402c9..d90babd0d 100644 --- a/iscsi-scst/kernel/Makefile +++ b/iscsi-scst/kernel/Makefile @@ -38,5 +38,6 @@ EXTRA_CFLAGS += -DCONFIG_SCST_DEBUG -g -fno-inline -fno-inline-functions obj-m += iscsi-scst.o iscsi-scst-objs := iscsi.o nthread.o config.o digest.o \ - conn.o session.o target.o event.o param.o + conn.o session.o target.o event.o param.o \ + iscsit_transport.o diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index 7b7b05f07..38f975a14 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -33,6 +33,7 @@ #endif #include "iscsi_hdr.h" #include "iscsi_dbg.h" +#include "iscsit_transport.h" #define iscsi_sense_crc_error ABORTED_COMMAND, 0x47, 0x05 #define iscsi_sense_unexpected_unsolicited_data ABORTED_COMMAND, 0x0C, 0x0C @@ -191,6 +192,8 @@ struct iscsi_session { #define ISCSI_CONN_WR_STATE_PROCESSING 3 struct iscsi_conn { + struct iscsit_transport *transport; + struct iscsi_session *session; /* owning session */ /* Both protected by session->sn_lock */ diff --git a/iscsi-scst/kernel/iscsit_transport.c b/iscsi-scst/kernel/iscsit_transport.c new file mode 100644 index 000000000..debf87edb --- /dev/null +++ b/iscsi-scst/kernel/iscsit_transport.c @@ -0,0 +1,64 @@ + +#include +#include "iscsit_transport.h" +#include "iscsi.h" + +static LIST_HEAD(transport_list); +static DEFINE_MUTEX(transport_mutex); + +static struct iscsit_transport *__iscsit_get_transport(enum iscsit_transport_type type) +{ + struct iscsit_transport *t; + + list_for_each_entry(t, &transport_list, list) { + if (t->transport_type == type) + return t; + } + + return NULL; +} + +struct iscsit_transport *iscsit_get_transport(enum iscsit_transport_type type) +{ + struct iscsit_transport *t; + + mutex_lock(&transport_mutex); + t = __iscsit_get_transport(type); + mutex_unlock(&transport_mutex); + + return t; +} + +int iscsit_register_transport(struct iscsit_transport *t) +{ + struct iscsit_transport *tmp; + int ret = 0; + + INIT_LIST_HEAD(&t->list); + + mutex_lock(&transport_mutex); + tmp = __iscsit_get_transport(t->transport_type); + if (tmp) { + PRINT_ERROR("Unable to register transport type %d - Already registered\n", + t->transport_type); + ret = -EEXIST; + } else { + list_add_tail(&t->list, &transport_list); + PRINT_INFO("Registered iSCSI transport: %s\n", t->name); + } + mutex_unlock(&transport_mutex); + + return ret; +} +EXPORT_SYMBOL(iscsit_register_transport); + +void iscsit_unregister_transport(struct iscsit_transport *t) +{ + mutex_lock(&transport_mutex); + list_del(&t->list); + mutex_unlock(&transport_mutex); + + PRINT_INFO("Unregistered iSCSI transport: %s\n", t->name); +} +EXPORT_SYMBOL(iscsit_unregister_transport); +