Mike Christie wrote: > On 09/01/2009 09:53 AM, Mike Christie wrote: >> On 09/01/2009 03:58 AM, Or Gerlitz wrote: >>> Mike Christie wrote: >>>> Or, I am ccing you because some time ago Erez was working on support >>>> for older RHEL and SLES kernels for OFED. It looks like the patch >>>> below would not be useful to you because iser is supported in those >>>> kernels, but did you guys all need RHEL 4 and maybe SLES 9 support too? >>> Hi Mike, I'm used to work with patches which have a change log and are >>> signed, where this patch lacks both, so I can't really understand what >>> it is about, sorry. >>> >> >> A signature is not going to help you understand that patch will it? :) >> >> I do not think a changelog will help either since it is the first >> version of a RFC patch. >> >> From the subject of the mail and the body it looks like Rakesh is >> trying to port libiscsi to older distro kernels (RHEL 5 and SLES 10 >> based) so he can support cxgb3i on them. >> >> I am just asking you guys if you also need RHEL 4 and SLES 9 support. >> > > You guys meaning, do you need iser and does Rakesh need cxgb3i?
Hi Mike, Yes we do want to support cxgb3i on RHEL4/SLES9. I am sending the modified patch against current james tree's libiscsi part. This patch can replace existing 2.6.14-23_compat.patch. Regards Rakesh Ranjan --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "open-iscsi" group. To post to this group, send email to open-iscsi@googlegroups.com To unsubscribe from this group, send email to open-iscsi+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/open-iscsi -~----------~----~----~----~------~----~------~--~---
>From 3e33dcf314395c77dbe02c32602a8c9212136b46 Mon Sep 17 00:00:00 2001 From: Rakesh Ranjan <rran...@chelsio.com> Date: Thu, 3 Sep 2009 17:23:10 +0530 Subject: [RFC] libiscsi port to support cxgb3i on older RHEL/SLES Signed-off-by: Rakesh Ranjan <rran...@chelsio.com> --- kernel/iscsi_tcp.c | 18 +-- kernel/iscsi_tcp.h | 1 + kernel/libiscsi.c | 92 ++++++++--- kernel/libiscsi.h | 6 +- kernel/libiscsi_tcp.c | 29 +++- kernel/open_iscsi_compat.h | 360 +++++++++++++++++++++++++++++++++++++++++ kernel/scsi_transport_iscsi.c | 272 +++++++++++++++---------------- kernel/scsi_transport_iscsi.h | 7 +- 8 files changed, 600 insertions(+), 185 deletions(-) create mode 100644 kernel/open_iscsi_compat.h diff --git a/kernel/iscsi_tcp.c b/kernel/iscsi_tcp.c index 61e5018..b05801f 100644 --- a/kernel/iscsi_tcp.c +++ b/kernel/iscsi_tcp.c @@ -459,10 +459,9 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task, if (!task->sc) iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count); else { - struct scsi_data_buffer *sdb = scsi_out(task->sc); - err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl, - sdb->table.nents, offset, + err = iscsi_sw_tcp_send_data_prep(conn, scsi_sglist(task->sc), + scsi_sg_count(task->sc), offset, count); } @@ -608,14 +607,14 @@ static int iscsi_sw_tcp_get_addr(struct iscsi_conn *conn, struct socket *sock, case AF_INET: sin = (struct sockaddr_in *)addr; spin_lock_bh(&conn->session->lock); - sprintf(buf, "%pI4", &sin->sin_addr.s_addr); + sprintf(buf, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr)); *port = be16_to_cpu(sin->sin_port); spin_unlock_bh(&conn->session->lock); break; case AF_INET6: sin6 = (struct sockaddr_in6 *)addr; spin_lock_bh(&conn->session->lock); - sprintf(buf, "%pI6", &sin6->sin6_addr); + sprintf(buf, NIP6_FMT, NIP6(sin6->sin6_addr)); *port = be16_to_cpu(sin6->sin6_port); spin_unlock_bh(&conn->session->lock); break; @@ -827,12 +826,6 @@ static void iscsi_sw_tcp_session_destroy(struct iscsi_cls_session *cls_session) iscsi_host_free(shost); } -static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev) -{ - set_bit(QUEUE_FLAG_BIDI, &sdev->request_queue->queue_flags); - return 0; -} - static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) { blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_ANY); @@ -851,9 +844,8 @@ static struct scsi_host_template iscsi_sw_tcp_sht = { .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_device_reset_handler= iscsi_eh_device_reset, - .eh_target_reset_handler= iscsi_eh_target_reset, + .eh_host_reset_handler = iscsi_eh_target_reset, .use_clustering = DISABLE_CLUSTERING, - .slave_alloc = iscsi_sw_tcp_slave_alloc, .slave_configure = iscsi_sw_tcp_slave_configure, .target_alloc = iscsi_target_alloc, .proc_name = "iscsi_tcp", diff --git a/kernel/iscsi_tcp.h b/kernel/iscsi_tcp.h index f9a4044..5327cfa 100644 --- a/kernel/iscsi_tcp.h +++ b/kernel/iscsi_tcp.h @@ -22,6 +22,7 @@ #ifndef ISCSI_SW_TCP_H #define ISCSI_SW_TCP_H +#include "open_iscsi_compat.h" #include "libiscsi.h" #include "libiscsi_tcp.h" diff --git a/kernel/libiscsi.c b/kernel/libiscsi.c index 8808779..e2e80ad 100644 --- a/kernel/libiscsi.c +++ b/kernel/libiscsi.c @@ -34,6 +34,7 @@ #include <scsi/scsi_host.h> #include <scsi/scsi.h> #include <scsi/scsi_transport.h> +#include "open_iscsi_compat.h" #include "iscsi_proto.h" #include "scsi_transport_iscsi.h" #include "libiscsi.h" @@ -252,7 +253,7 @@ static int iscsi_prep_bidi_ahs(struct iscsi_task *task) sizeof(rlen_ahdr->reserved)); rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH; rlen_ahdr->reserved = 0; - rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length); + rlen_ahdr->read_length = cpu_to_be32(scsi_bufflen(sc)); ISCSI_DBG_SESSION(task->conn->session, "bidi-in rlen_ahdr->read_length(%d) " @@ -323,7 +324,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) return rc; } if (sc->sc_data_direction == DMA_TO_DEVICE) { - unsigned out_len = scsi_out(sc)->length; + unsigned out_len = scsi_bufflen(sc); struct iscsi_r2t_info *r2t = &task->unsol_r2t; hdr->data_length = cpu_to_be32(out_len); @@ -369,7 +370,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) } else { hdr->flags |= ISCSI_FLAG_CMD_FINAL; zero_data(hdr->dlength); - hdr->data_length = cpu_to_be32(scsi_in(sc)->length); + hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); if (sc->sc_data_direction == DMA_FROM_DEVICE) hdr->flags |= ISCSI_FLAG_CMD_READ; @@ -396,7 +397,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", conn->id, sc, sc->cmnd[0], task->itt, scsi_bufflen(sc), - scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, + scsi_bidi_cmnd(sc) ? scsi_bufflen(sc) : 0, session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); return 0; @@ -533,12 +534,7 @@ static void fail_scsi_task(struct iscsi_task *task, int err) state = ISCSI_TASK_ABRT_TMF; sc->result = err << 16; - if (!scsi_bidi_cmnd(sc)) - scsi_set_resid(sc, scsi_bufflen(sc)); - else { - scsi_out(sc)->resid = scsi_out(sc)->length; - scsi_in(sc)->resid = scsi_in(sc)->length; - } + scsi_set_resid(sc, scsi_bufflen(sc)); iscsi_complete_task(task, state); } @@ -729,7 +725,7 @@ invalid_datalen: goto out; } - senselen = get_unaligned_be16(data); + senselen = be16_to_cpu(get_unaligned((__be16 *) data)); if (datalen < senselen) goto invalid_datalen; @@ -746,8 +742,8 @@ invalid_datalen: if (scsi_bidi_cmnd(sc) && res_count > 0 && (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW || - res_count <= scsi_in(sc)->length)) - scsi_in(sc)->resid = res_count; + res_count <= scsi_bufflen(sc))) + scsi_set_resid(sc, res_count); else sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; } @@ -796,8 +792,8 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (res_count > 0 && (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || - res_count <= scsi_in(sc)->length)) - scsi_in(sc)->resid = res_count; + res_count <= scsi_bufflen(sc))) + scsi_set_resid(sc, res_count); else sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; } @@ -977,7 +973,9 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, task = iscsi_itt_to_ctask(conn, hdr->itt); if (!task) return ISCSI_ERR_BAD_ITT; +#if !(defined RHELC1) && !(defined SLEC1) task->last_xfer = jiffies; +#endif break; case ISCSI_OP_R2T: /* @@ -1216,12 +1214,21 @@ static int iscsi_xmit_task(struct iscsi_conn *conn) spin_unlock_bh(&conn->session->lock); rc = conn->session->tt->xmit_task(task); spin_lock_bh(&conn->session->lock); +#if ((defined RHELC1) || (defined SLEC1)) + __iscsi_put_task(task); + if (!rc) { + /* done with this task */ + conn->task = NULL; + } +#else if (!rc) { /* done with this task */ task->last_xfer = jiffies; conn->task = NULL; } + __iscsi_put_task(task); +#endif return rc; } @@ -1387,9 +1394,11 @@ static inline struct iscsi_task *iscsi_alloc_task(struct iscsi_conn *conn, task->state = ISCSI_TASK_PENDING; task->conn = conn; task->sc = sc; +#if !((defined RHELC1) && !(defined SLEC1)) task->have_checked_conn = false; task->last_timeout = jiffies; task->last_xfer = jiffies; +#endif INIT_LIST_HEAD(&task->running); return task; } @@ -1518,7 +1527,11 @@ reject: ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); spin_lock(host->host_lock); +#if ((defined RHELC1) || (defined SLEC1)) + return SCSI_MLQUEUE_DEVICE_BUSY; +#else return SCSI_MLQUEUE_TARGET_BUSY; +#endif prepd_fault: sc->scsi_done = NULL; @@ -1527,12 +1540,7 @@ fault: spin_unlock(&session->lock); ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); - if (!scsi_bidi_cmnd(sc)) - scsi_set_resid(sc, scsi_bufflen(sc)); - else { - scsi_out(sc)->resid = scsi_out(sc)->length; - scsi_in(sc)->resid = scsi_in(sc)->length; - } + scsi_set_resid(sc, scsi_bufflen(sc)); done(sc); spin_lock(host->host_lock); return 0; @@ -1551,7 +1559,9 @@ int iscsi_target_alloc(struct scsi_target *starget) struct iscsi_cls_session *cls_session = starget_to_session(starget); struct iscsi_session *session = cls_session->dd_data; +#if 0 starget->can_queue = session->scsi_cmds_max; +#endif return 0; } EXPORT_SYMBOL_GPL(iscsi_target_alloc); @@ -1570,13 +1580,11 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) } EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); -int iscsi_eh_target_reset(struct scsi_cmnd *sc) +int iscsi_target_reset(struct iscsi_cls_session *cls_session) { - struct iscsi_cls_session *cls_session; struct iscsi_session *session; struct iscsi_conn *conn; - cls_session = starget_to_session(scsi_target(sc->device)); session = cls_session->dd_data; conn = session->leadconn; @@ -1620,6 +1628,15 @@ failed: mutex_unlock(&session->eh_mutex); return SUCCESS; } +EXPORT_SYMBOL_GPL(iscsi_target_reset); + +int iscsi_eh_target_reset(struct scsi_cmnd *sc) +{ + struct iscsi_cls_session *cls_session; + + cls_session = starget_to_session(scsi_target(sc->device)); + return iscsi_target_reset(cls_session); +} EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); static void iscsi_tmf_timedout(unsigned long data) @@ -1748,7 +1765,10 @@ static int iscsi_has_ping_timed_out(struct iscsi_conn *conn) static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) { enum blk_eh_timer_return rc = BLK_EH_NOT_HANDLED; + +#if !(defined RHELC1) && !(defined SLEC1) struct iscsi_task *task = NULL; +#endif struct iscsi_cls_session *cls_session; struct iscsi_session *session; struct iscsi_conn *conn; @@ -1775,6 +1795,7 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) goto done; } +#if !(defined RHELC1) && !(defined SLEC1) task = (struct iscsi_task *)sc->SCp.ptr; if (!task) goto done; @@ -1794,6 +1815,7 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) rc = BLK_EH_RESET_TIMER; goto done; } +#endif if (!conn->recv_timeout && !conn->ping_timeout) goto done; @@ -1806,6 +1828,7 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) goto done; } +#if !(defined RHELC1) && !(defined SLEC1) /* Assumes nop timeout is shorter than scsi cmd timeout */ if (task->have_checked_conn) goto done; @@ -1819,15 +1842,34 @@ static enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc) rc = BLK_EH_RESET_TIMER; goto done; } +#else + /* + * if we are about to check the transport then give the command + * more time + */ + if (time_before_eq(conn->last_recv + (conn->recv_timeout * HZ), + jiffies)) { + rc = BLK_EH_RESET_TIMER; + goto done; + } +#endif + +#if !(defined RHELC1) && !(defined SLEC1) /* Make sure there is a transport check done */ iscsi_send_nopout(conn, NULL); task->have_checked_conn = true; rc = BLK_EH_RESET_TIMER; - +#else + /* if in the middle of checking the transport then give us more time */ + if (conn->ping_task) + rc = BLK_EH_RESET_TIMER; +#endif done: +#if !(defined RHELC1) && !(defined SLEC1) if (task) task->last_timeout = jiffies; +#endif spin_unlock(&session->lock); ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ? "timer reset" : "nh"); diff --git a/kernel/libiscsi.h b/kernel/libiscsi.h index b6dd8a7..93b0fca 100644 --- a/kernel/libiscsi.h +++ b/kernel/libiscsi.h @@ -31,12 +31,13 @@ #include "iscsi_proto.h" #include "iscsi_if.h" #include "scsi_transport_iscsi.h" +#include "open_iscsi_compat.h" struct scsi_transport_template; struct scsi_host_template; struct scsi_device; struct Scsi_Host; -struct scsi_target; +//struct scsi_target; struct scsi_cmnd; struct socket; struct iscsi_transport; @@ -125,10 +126,12 @@ struct iscsi_task { struct scsi_cmnd *sc; /* associated SCSI cmd*/ struct iscsi_conn *conn; /* used connection */ +#if !defined RHELC1 && !defined SLEC1 /* data processing tracking */ unsigned long last_xfer; unsigned long last_timeout; bool have_checked_conn; +#endif /* state set/tested under session->lock */ int state; atomic_t refcount; @@ -335,6 +338,7 @@ struct iscsi_host { extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth); extern int iscsi_eh_abort(struct scsi_cmnd *sc); extern int iscsi_eh_target_reset(struct scsi_cmnd *sc); +extern int iscsi_target_reset(struct iscsi_cls_session *cls_session); extern int iscsi_eh_device_reset(struct scsi_cmnd *sc); extern int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)); diff --git a/kernel/libiscsi_tcp.c b/kernel/libiscsi_tcp.c index 4051e62..cf1a961 100644 --- a/kernel/libiscsi_tcp.c +++ b/kernel/libiscsi_tcp.c @@ -40,9 +40,9 @@ #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi.h> +#include "open_iscsi_compat.h" #include "scsi_transport_iscsi.h" - -#include "iscsi_tcp.h" +#include "libiscsi_tcp.h" MODULE_AUTHOR("Mike Christie <micha...@cs.wisc.edu>, " "Dmitry Yusupov <dmitry_...@yahoo.com>, " @@ -360,6 +360,16 @@ iscsi_segment_seek_sg(struct iscsi_segment *segment, struct scatterlist *sg; unsigned int i; + /* + * older kernels could send use_sg=0 for commands like sgio + * or scsi-ml commands. + */ + if (!sg_count) { + iscsi_segment_init_linear(segment, (void *)sg_list + offset, + size, done, hash); + return 0; + } + __iscsi_segment_init(segment, size, done, hash); for_each_sg(sg_list, sg, sg_count, i) { if (offset < sg->length) { @@ -471,7 +481,7 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task) struct iscsi_tcp_task *tcp_task = task->dd_data; struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr; int datasn = be32_to_cpu(rhdr->datasn); - unsigned total_in_length = scsi_in(task->sc)->length; + unsigned total_in_length = scsi_bufflen(task->sc); /* * lib iscsi will update this in the completion handling if there @@ -565,11 +575,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task) r2t->data_length, session->max_burst); r2t->data_offset = be32_to_cpu(rhdr->data_offset); - if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) { + if (r2t->data_offset + r2t->data_length > scsi_bufflen(task->sc)) { iscsi_conn_printk(KERN_ERR, conn, "invalid R2T with data len %u at offset %u " "and total length %d\n", r2t->data_length, - r2t->data_offset, scsi_out(task->sc)->length); + r2t->data_offset, scsi_bufflen(task->sc)); __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t, sizeof(void*)); return ISCSI_ERR_DATALEN; @@ -668,7 +678,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) if (tcp_conn->in.datalen) { struct iscsi_tcp_task *tcp_task = task->dd_data; struct hash_desc *rx_hash = NULL; - struct scsi_data_buffer *sdb = scsi_in(task->sc); /* * Setup copy of Data-In into the Scsi_Cmnd @@ -686,10 +695,12 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) "offset=%d, datalen=%d)\n", tcp_task->data_offset, tcp_conn->in.datalen); +#if !(defined RHELC1) && !(defined SLEC1) task->last_xfer = jiffies; +#endif rc = iscsi_segment_seek_sg(&tcp_conn->in.segment, - sdb->table.sgl, - sdb->table.nents, + scsi_sglist(task->sc), + scsi_sg_count(task->sc), tcp_task->data_offset, tcp_conn->in.datalen, iscsi_tcp_process_data_in, @@ -715,7 +726,9 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) else if (ahslen) rc = ISCSI_ERR_AHSLEN; else if (task->sc->sc_data_direction == DMA_TO_DEVICE) { +#if !(defined RHELC1) && !(defined SLEC1) task->last_xfer = jiffies; +#endif rc = iscsi_tcp_r2t_rsp(conn, task); } else rc = ISCSI_ERR_PROTO; diff --git a/kernel/open_iscsi_compat.h b/kernel/open_iscsi_compat.h new file mode 100644 index 0000000..ff5e88f --- /dev/null +++ b/kernel/open_iscsi_compat.h @@ -0,0 +1,360 @@ +#ifndef OPEN_ISCSI_COMPAT +#define OPEN_ISCSI_COMPAT + +#include <linux/version.h> +#include <linux/kernel.h> +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_host.h> + +#ifndef SCAN_WILD_CARD +#define SCAN_WILD_CARD ~0 +#endif + +#ifndef NIPQUAD_FMT +#define NIPQUAD_FMT "%u.%u.%u.%u" +#endif + +#ifndef NIP6_FMT +#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" +#endif + +#ifndef DEFINE_MUTEX + +/* mutex changes from 2.6.16-rc1 and up */ +#define DEFINE_MUTEX DECLARE_MUTEX +#define mutex_lock down +#define mutex_unlock up +#define mutex semaphore +#define mutex_init init_MUTEX +#endif + +#ifdef RHEL_RELEASE_CODE +#if (RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5, 4)) +#define RHELC1 1 +#endif +#endif + +#ifdef SLE_VERSION_CODE +#if (SLE_VERSION_CODE < SLE_VERSION(11, 0, 0)) +#define SLEC1 1 +#endif +#endif + + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,19) +#if !(defined RHELC1) && !(defined SLEC1) +struct delayed_work { + struct work_struct work; +}; + +#define cancel_delayed_work(_dwork) cancel_delayed_work(&(_dwork)->work) +#define INIT_DELAYED_WORK(_work,_func) INIT_WORK(&(_work)->work, _func) +#endif + +static inline void INIT_WORK_compat(struct work_struct *work, void *func) +{ + INIT_WORK(work, func, work); +} + +#undef INIT_WORK +#define INIT_WORK(_work, _func) INIT_WORK_compat(_work, _func) +#if !(defined INIT_DELAYED_WORK) +#define INIT_DELAYED_WORK(_work,_func) INIT_WORK_compat(_work, _func) +#endif +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) + +void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun) +{ + int i; + + memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun)); + + for (i = 0; i < sizeof(lun); i += 2) { + scsilun->scsi_lun[i] = (lun >> 8) & 0xFF; + scsilun->scsi_lun[i+1] = lun & 0xFF; + lun = lun >> 16; + } +} + +#define __nlmsg_put(skb, daemon_pid, seq, type, len, flags) \ + __nlmsg_put(skb, daemon_pid, 0, 0, len) + +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) && \ + RHEL_RELEASE_CODE != RHEL_RELEASE_VERSION(4,8) + +#define gfp_t unsigned + +void *kzalloc(size_t size, gfp_t flags) +{ + void *ret = kmalloc(size, flags); + if (ret) + memset(ret, 0, size); +} + +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) + +#include "linux/crypto.h" + +#if !defined SLEC1 +#define CRYPTO_ALG_ASYNC 0x00000080 +struct hash_desc +{ + struct crypto_tfm *tfm; + u32 flags; +}; + +static inline int crypto_hash_init(struct hash_desc *desc) +{ + crypto_digest_init(desc->tfm); + return 0; +} + +static inline int crypto_hash_digest(struct hash_desc *desc, + struct scatterlist *sg, + unsigned int nbytes, u8 *out) +{ + crypto_digest_digest(desc->tfm, sg, 1, out); + return nbytes; +} + +static inline int crypto_hash_update(struct hash_desc *desc, + struct scatterlist *sg, + unsigned int nbytes) +{ + crypto_digest_update(desc->tfm, sg, 1); + return nbytes; +} + +static inline int crypto_hash_final(struct hash_desc *desc, u8 *out) +{ + crypto_digest_final(desc->tfm, out); + return 0; +} + +static inline struct crypto_tfm *crypto_alloc_hash(const char *alg_name, + u32 type, u32 mask) +{ + struct crypto_tfm *ret = crypto_alloc_tfm(alg_name ,type); + return ret ? ret : ERR_PTR(-ENOMEM); +} + +static inline void crypto_free_hash(struct crypto_tfm *tfm) +{ + crypto_free_tfm(tfm); +} +#endif +#ifdef RHEL_RELEASE_VERSION +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,1) +static inline int kernel_getsockname(struct socket *sock, struct sockaddr *addr, + int *addrlen) +{ + return sock->ops->getname(sock, addr, addrlen, 0); +} + +static inline int kernel_getpeername(struct socket *sock, struct sockaddr *addr, + int *addrlen) +{ + return sock->ops->getname(sock, addr, addrlen, 1); +} +#endif +#endif +#endif + +#ifndef bool +#define bool int +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20) +#ifdef RHEL_RELEASE_VERSION +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2) && \ + RHEL_RELEASE_CODE != RHEL_RELEASE_VERSION(4,8) +static inline int is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} +#endif +#else +/* not a redhat kernel */ +static inline int is_power_of_2(unsigned long n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} +#endif +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21) + +static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb) +{ + return (struct nlmsghdr *)skb->data; +} + +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) +#ifdef RHEL_RELEASE_VERSION +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2) +static inline void *shost_priv(struct Scsi_Host *shost) +{ + return (void *)shost->hostdata; +} +#endif +#else +/* not a redhat kernel */ +static inline void *shost_priv(struct Scsi_Host *shost) +{ + return (void *)shost->hostdata; +} +#endif + +/* + * Note: We do not support bidi for the compat modules if the kernel + * does not have support. + */ +#define scsi_sg_count(cmd) ((cmd)->use_sg) +#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer) +#define scsi_bufflen(cmd) ((cmd)->request_bufflen) + +#ifdef RHEL_RELEASE_VERSION +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2) +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->resid = resid; +} + +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->resid; +} +#endif +#else +/* not a redhat kernel */ +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->resid = resid; +} + +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->resid; +} +#endif + +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) + +#ifdef SLE_VERSION_CODE +#if SLE_VERSION_CODE == SLE_VERSION(10,2,0) + +static inline unsigned fls_long(unsigned long l) +{ + if (sizeof(l) == 4) + return fls(l); + return fls64(l); +} + +#endif +#endif + +static inline unsigned long rounddown_pow_of_two(unsigned long n) +{ + return 1UL << (fls_long(n) - 1); +} + + +static inline struct scatterlist *sg_next(struct scatterlist *sg) +{ + if (!sg) { + BUG(); + return NULL; + } + return sg + 1; +} + +#define for_each_sg(sglist, sg, nr, __i) \ + for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg)) + +#define sg_page(_sg) _sg->page + +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg->page = page; + sg->offset = offset; + sg->length = len; +} + +static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents) +{ + memset(sgl, 0, sizeof(*sgl) * nents); +} +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24) + +static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd) +{ + return 0; +} + +#define netlink_kernel_release(_nls) \ + sock_release(_nls->sk_socket) + +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13) + +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \ + netlink_kernel_create(uint, groups, input, cb_mutex, mod) + +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,19) + +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \ + netlink_kernel_create(uint, groups, input, mod) + +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) + +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \ + netlink_kernel_create(uint, groups, input, cb_mutex, mod) + +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) + +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \ + netlink_kernel_create(uint, groups, input, cb_mutex, mod) + +#endif + +#ifndef DID_TRANSPORT_DISRUPTED +#define DID_TRANSPORT_DISRUPTED DID_BUS_BUSY +#endif + +#ifndef DID_TRANSPORT_FAILFAST +#define DID_TRANSPORT_FAILFAST DID_NO_CONNECT +#endif + +#ifndef SCSI_MLQUEUE_TARGET_BUSY +#define SCSI_MLQUEUE_TARGET_BUSY SCSI_MLQUEUE_HOST_BUSY +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) + +#define BLK_EH_NOT_HANDLED EH_NOT_HANDLED +#define BLK_EH_RESET_TIMER EH_RESET_TIMER + +#define blk_eh_timer_return scsi_eh_timer_return + +#endif + +#ifndef SCSI_MAX_VARLEN_CDB_SIZE +#define SCSI_MAX_VARLEN_CDB_SIZE 16 +#endif + +#endif diff --git a/kernel/scsi_transport_iscsi.c b/kernel/scsi_transport_iscsi.c index 6cbeefa..8ef6d45 100644 --- a/kernel/scsi_transport_iscsi.c +++ b/kernel/scsi_transport_iscsi.c @@ -40,13 +40,13 @@ struct iscsi_internal { struct scsi_transport_template t; struct iscsi_transport *iscsi_transport; struct list_head list; - struct device dev; + struct class_device cdev; - struct device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; + struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; struct transport_container conn_cont; - struct device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; + struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; struct transport_container session_cont; - struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; + struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; }; static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ @@ -63,12 +63,12 @@ static DEFINE_SPINLOCK(iscsi_transport_lock); #define to_iscsi_internal(tmpl) \ container_of(tmpl, struct iscsi_internal, t) -#define dev_to_iscsi_internal(_dev) \ - container_of(_dev, struct iscsi_internal, dev) +#define cdev_to_iscsi_internal(_cdev) \ + container_of(_cdev, struct iscsi_internal, cdev) -static void iscsi_transport_release(struct device *dev) +static void iscsi_transport_release(struct class_device *cdev) { - struct iscsi_internal *priv = dev_to_iscsi_internal(dev); + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); kfree(priv); } @@ -78,33 +78,31 @@ static void iscsi_transport_release(struct device *dev) */ static struct class iscsi_transport_class = { .name = "iscsi_transport", - .dev_release = iscsi_transport_release, + .release = iscsi_transport_release, }; static ssize_t -show_transport_handle(struct device *dev, struct device_attribute *attr, - char *buf) +show_transport_handle(struct class_device *cdev, char *buf) { - struct iscsi_internal *priv = dev_to_iscsi_internal(dev); + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport)); } -static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); +static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); #define show_transport_attr(name, format) \ static ssize_t \ -show_transport_##name(struct device *dev, \ - struct device_attribute *attr,char *buf) \ +show_transport_##name(struct class_device *cdev, char *buf) \ { \ - struct iscsi_internal *priv = dev_to_iscsi_internal(dev); \ + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \ return sprintf(buf, format"\n", priv->iscsi_transport->name); \ } \ -static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); show_transport_attr(caps, "0x%x"); static struct attribute *iscsi_transport_attrs[] = { - &dev_attr_handle.attr, - &dev_attr_caps.attr, + &class_device_attr_handle.attr, + &class_device_attr_caps.attr, NULL, }; @@ -122,27 +120,30 @@ static struct attribute_group iscsi_transport_group = { struct device_attribute dev_attr_##_prefix##_##_name = \ __ATTR(_name,_mode,_show,_store) -static void iscsi_endpoint_release(struct device *dev) +static void iscsi_endpoint_release(struct class_device *cdev) { - struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); + struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(cdev); kfree(ep); } static struct class iscsi_endpoint_class = { .name = "iscsi_endpoint", - .dev_release = iscsi_endpoint_release, + .release = iscsi_endpoint_release, }; static ssize_t -show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) +show_ep_handle(struct class_device *cdev, char *buf) { - struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); + struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(cdev); return sprintf(buf, "%llu\n", (unsigned long long) ep->id); } -static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); + +static struct class_device_attribute class_device_attr_ep_handle = + __ATTR(handle, S_IRUGO, show_ep_handle, NULL); + static struct attribute *iscsi_endpoint_attrs[] = { - &dev_attr_ep_handle.attr, + &class_device_attr_ep_handle.attr, NULL, }; @@ -152,26 +153,15 @@ static struct attribute_group iscsi_endpoint_group = { #define ISCSI_MAX_EPID -1 -static int iscsi_match_epid(struct device *dev, void *data) -{ - struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); - uint64_t *epid = (uint64_t *) data; - - return *epid == ep->id; -} - struct iscsi_endpoint * iscsi_create_endpoint(int dd_size) { - struct device *dev; struct iscsi_endpoint *ep; uint64_t id; int err; for (id = 1; id < ISCSI_MAX_EPID; id++) { - dev = class_find_device(&iscsi_endpoint_class, NULL, &id, - iscsi_match_epid); - if (!dev) + if (!iscsi_lookup_endpoint(id)) break; } if (id == ISCSI_MAX_EPID) { @@ -186,8 +176,9 @@ iscsi_create_endpoint(int dd_size) ep->id = id; ep->dev.class = &iscsi_endpoint_class; - dev_set_name(&ep->dev, "ep-%llu", (unsigned long long) id); - err = device_register(&ep->dev); + snprintf(ep->dev.class_id, BUS_ID_SIZE, "ep-%llu", + (unsigned long long) id); + err = class_device_register(&ep->dev); if (err) goto free_ep; @@ -200,7 +191,7 @@ iscsi_create_endpoint(int dd_size) return ep; unregister_dev: - device_unregister(&ep->dev); + class_device_unregister(&ep->dev); return NULL; free_ep: @@ -212,32 +203,29 @@ EXPORT_SYMBOL_GPL(iscsi_create_endpoint); void iscsi_destroy_endpoint(struct iscsi_endpoint *ep) { sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group); - device_unregister(&ep->dev); + class_device_unregister(&ep->dev); } EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint); struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) { - struct iscsi_endpoint *ep; - struct device *dev; - - dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, - iscsi_match_epid); - if (!dev) - return NULL; + struct iscsi_endpoint *ep = NULL; + struct class_device *cdev; - ep = iscsi_dev_to_endpoint(dev); - /* - * we can drop this now because the interface will prevent - * removals and lookups from racing. - */ - put_device(dev); + down_read(&iscsi_endpoint_class.subsys.rwsem); + list_for_each_entry(cdev, &iscsi_endpoint_class.children, node) { + ep = iscsi_dev_to_endpoint(cdev); + if (ep->id == handle) + break; + ep = NULL; + } + up_read(&iscsi_endpoint_class.subsys.rwsem); return ep; } EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); static int iscsi_setup_host(struct transport_container *tc, struct device *dev, - struct device *cdev) + struct class_device *cdev) { struct Scsi_Host *shost = dev_to_shost(dev); struct iscsi_cls_host *ihost = shost->shost_data; @@ -499,7 +487,7 @@ static void session_recovery_timedout(struct work_struct *work) { struct iscsi_cls_session *session = container_of(work, struct iscsi_cls_session, - recovery_work.work); + recovery_work); unsigned long flags; iscsi_cls_session_printk(KERN_INFO, session, @@ -530,8 +518,6 @@ static void __iscsi_unblock_session(struct work_struct *work) struct iscsi_cls_session *session = container_of(work, struct iscsi_cls_session, unblock_work); - struct Scsi_Host *shost = iscsi_session_to_shost(session); - struct iscsi_cls_host *ihost = shost->shost_data; unsigned long flags; /* @@ -544,15 +530,6 @@ static void __iscsi_unblock_session(struct work_struct *work) spin_unlock_irqrestore(&session->lock, flags); /* start IO */ scsi_target_unblock(&session->dev); - /* - * Only do kernel scanning if the driver is properly hooked into - * the async scanning code (drivers like iscsi_tcp do login and - * scanning from userspace). - */ - if (shost->hostt->scan_finished) { - if (scsi_queue_work(shost, &session->scan_work)) - atomic_inc(&ihost->nr_scans); - } } /** @@ -698,7 +675,7 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) } session->target_id = id; - dev_set_name(&session->dev, "session%u", session->sid); + snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", session->sid); err = device_add(&session->dev); if (err) { iscsi_cls_session_printk(KERN_ERR, session, @@ -870,7 +847,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid) if (!get_device(&session->dev)) goto free_conn; - dev_set_name(&conn->dev, "connection%d:%u", session->sid, cid); + snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", + session->sid, cid); conn->dev.parent = &session->dev; conn->dev.release = iscsi_conn_release; err = device_register(&conn->dev); @@ -940,7 +918,15 @@ iscsi_if_transport_lookup(struct iscsi_transport *tt) static int iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp) { - return nlmsg_multicast(nls, skb, 0, group, gfp); + int err; + + NETLINK_CB(skb).dst_group = group; + + err = netlink_broadcast(nls, skb, 0, group, gfp); + if (err > 0) + err = 0; + + return err; } int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, @@ -1572,51 +1558,65 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) * Malformed skbs with wrong lengths or invalid creds are not processed. */ static void -iscsi_if_rx(struct sk_buff *skb) +iscsi_if_rx(struct sock *sk, int len) { - mutex_lock(&rx_queue_mutex); - while (skb->len >= NLMSG_SPACE(0)) { - int err; - uint32_t rlen; - struct nlmsghdr *nlh; - struct iscsi_uevent *ev; - uint32_t group; - - nlh = nlmsg_hdr(skb); - if (nlh->nlmsg_len < sizeof(*nlh) || - skb->len < nlh->nlmsg_len) { - break; - } - - ev = NLMSG_DATA(nlh); - rlen = NLMSG_ALIGN(nlh->nlmsg_len); - if (rlen > skb->len) - rlen = skb->len; + struct sk_buff *skb; - err = iscsi_if_recv_msg(skb, nlh, &group); - if (err) { - ev->type = ISCSI_KEVENT_IF_ERROR; - ev->iferror = err; + mutex_lock(&rx_queue_mutex); + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { + if (NETLINK_CREDS(skb)->uid) { + skb_pull(skb, skb->len); + goto free_skb; } - do { - /* - * special case for GET_STATS: - * on success - sending reply and stats from - * inside of if_recv_msg(), - * on error - fall through. - */ - if (ev->type == ISCSI_UEVENT_GET_STATS && !err) + + while (skb->len >= NLMSG_SPACE(0)) { + int err; + uint32_t rlen; + struct nlmsghdr *nlh; + struct iscsi_uevent *ev; + uint32_t group; + + nlh = nlmsg_hdr(skb); + if (nlh->nlmsg_len < sizeof(*nlh) || + skb->len < nlh->nlmsg_len) { break; - err = iscsi_if_send_reply(group, nlh->nlmsg_seq, - nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); - } while (err < 0 && err != -ECONNREFUSED); - skb_pull(skb, rlen); + } + + ev = NLMSG_DATA(nlh); + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + + err = iscsi_if_recv_msg(skb, nlh, &group); + if (err) { + ev->type = ISCSI_KEVENT_IF_ERROR; + ev->iferror = err; + } + do { + /* + * special case for GET_STATS: + * on success - sending reply and stats from + * inside of if_recv_msg(), + * on error - fall through. + */ + if (ev->type == ISCSI_UEVENT_GET_STATS && !err) + break; + err = iscsi_if_send_reply(group, nlh->nlmsg_seq, + nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); + } while (err < 0 && err != -ECONNREFUSED); + skb_pull(skb, rlen); + } +free_skb: + kfree_skb(skb); } mutex_unlock(&rx_queue_mutex); } +#define iscsi_cdev_to_conn(_cdev) \ + iscsi_dev_to_conn(_cdev->dev) + #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \ -struct device_attribute dev_attr_##_prefix##_##_name = \ +struct class_device_attribute class_device_attr_##_prefix##_##_name = \ __ATTR(_name,_mode,_show,_store) /* @@ -1624,10 +1624,9 @@ struct device_attribute dev_attr_##_prefix##_##_name = \ */ #define iscsi_conn_attr_show(param) \ static ssize_t \ -show_conn_param_##param(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +show_conn_param_##param(struct class_device *cdev, char *buf) \ { \ - struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \ + struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ struct iscsi_transport *t = conn->transport; \ return t->get_conn_param(conn, param, buf); \ } @@ -1651,16 +1650,18 @@ iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO); iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO); +#define iscsi_cdev_to_session(_cdev) \ + iscsi_dev_to_session(_cdev->dev) + /* * iSCSI session attrs */ #define iscsi_session_attr_show(param, perm) \ static ssize_t \ -show_session_param_##param(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +show_session_param_##param(struct class_device *cdev, char *buf) \ { \ struct iscsi_cls_session *session = \ - iscsi_dev_to_session(dev->parent); \ + iscsi_cdev_to_session(cdev); \ struct iscsi_transport *t = session->transport; \ \ if (perm && !capable(CAP_SYS_ADMIN)) \ @@ -1694,10 +1695,9 @@ iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0); iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0) static ssize_t -show_priv_session_state(struct device *dev, struct device_attribute *attr, - char *buf) +show_priv_session_state(struct class_device *cdev, char *buf) { - struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); + struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); return sprintf(buf, "%s\n", iscsi_session_state_name(session->state)); } static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state, @@ -1705,11 +1705,9 @@ static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state, #define iscsi_priv_session_attr_show(field, format) \ static ssize_t \ -show_priv_session_##field(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +show_priv_session_##field(struct class_device *cdev, char *buf) \ { \ - struct iscsi_cls_session *session = \ - iscsi_dev_to_session(dev->parent); \ + struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\ return sprintf(buf, format"\n", session->field); \ } @@ -1724,10 +1722,9 @@ iscsi_priv_session_attr(recovery_tmo, "%d"); */ #define iscsi_host_attr_show(param) \ static ssize_t \ -show_host_param_##param(struct device *dev, \ - struct device_attribute *attr, char *buf) \ +show_host_param_##param(struct class_device *cdev, char *buf) \ { \ - struct Scsi_Host *shost = transport_class_to_shost(dev); \ + struct Scsi_Host *shost = transport_class_to_shost(cdev); \ struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \ return priv->iscsi_transport->get_host_param(shost, param, buf); \ } @@ -1744,7 +1741,7 @@ iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME); #define SETUP_PRIV_SESSION_RD_ATTR(field) \ do { \ - priv->session_attrs[count] = &dev_attr_priv_sess_##field; \ + priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ count++; \ } while (0) @@ -1752,7 +1749,7 @@ do { \ #define SETUP_SESSION_RD_ATTR(field, param_flag) \ do { \ if (tt->param_mask & param_flag) { \ - priv->session_attrs[count] = &dev_attr_sess_##field; \ + priv->session_attrs[count] = &class_device_attr_sess_##field; \ count++; \ } \ } while (0) @@ -1760,7 +1757,7 @@ do { \ #define SETUP_CONN_RD_ATTR(field, param_flag) \ do { \ if (tt->param_mask & param_flag) { \ - priv->conn_attrs[count] = &dev_attr_conn_##field; \ + priv->conn_attrs[count] = &class_device_attr_conn_##field; \ count++; \ } \ } while (0) @@ -1768,7 +1765,7 @@ do { \ #define SETUP_HOST_RD_ATTR(field, param_flag) \ do { \ if (tt->host_param_mask & param_flag) { \ - priv->host_attrs[count] = &dev_attr_host_##field; \ + priv->host_attrs[count] = &class_device_attr_host_##field; \ count++; \ } \ } while (0) @@ -1859,15 +1856,15 @@ iscsi_register_transport(struct iscsi_transport *tt) priv->t.user_scan = iscsi_user_scan; priv->t.create_work_queue = 1; - priv->dev.class = &iscsi_transport_class; - dev_set_name(&priv->dev, "%s", tt->name); - err = device_register(&priv->dev); + priv->cdev.class = &iscsi_transport_class; + snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name); + err = class_device_register(&priv->cdev); if (err) goto free_priv; - err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group); + err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group); if (err) - goto unregister_dev; + goto unregister_cdev; /* host parameters */ priv->t.host_attrs.ac.attrs = &priv->host_attrs[0]; @@ -1946,8 +1943,8 @@ iscsi_register_transport(struct iscsi_transport *tt) printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name); return &priv->t; -unregister_dev: - device_unregister(&priv->dev); +unregister_cdev: + class_device_unregister(&priv->cdev); return NULL; free_priv: kfree(priv); @@ -1975,8 +1972,8 @@ int iscsi_unregister_transport(struct iscsi_transport *tt) transport_container_unregister(&priv->session_cont); transport_container_unregister(&priv->t.host_attrs); - sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group); - device_unregister(&priv->dev); + sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group); + class_device_unregister(&priv->cdev); mutex_unlock(&rx_queue_mutex); return 0; @@ -1999,7 +1996,6 @@ static __init int iscsi_transport_init(void) err = class_register(&iscsi_endpoint_class); if (err) goto unregister_transport_class; - err = transport_class_register(&iscsi_host_class); if (err) goto unregister_endpoint_class; @@ -2033,8 +2029,10 @@ unregister_conn_class: transport_class_unregister(&iscsi_connection_class); unregister_host_class: transport_class_unregister(&iscsi_host_class); + unregister_endpoint_class: class_unregister(&iscsi_endpoint_class); + unregister_transport_class: class_unregister(&iscsi_transport_class); return err; diff --git a/kernel/scsi_transport_iscsi.h b/kernel/scsi_transport_iscsi.h index ef4b697..4efa993 100644 --- a/kernel/scsi_transport_iscsi.h +++ b/kernel/scsi_transport_iscsi.h @@ -26,6 +26,7 @@ #include <linux/device.h> #include <linux/list.h> #include <linux/mutex.h> +#include "open_iscsi_compat.h" #include "iscsi_if.h" struct scsi_transport_template; @@ -190,7 +191,11 @@ struct iscsi_cls_session { /* recovery fields */ int recovery_tmo; +#if !(defined RHELC1) && !(defined SLEC1) struct delayed_work recovery_work; +#else + struct work_struct recovery_work; +#endif unsigned int target_id; @@ -219,7 +224,7 @@ extern void iscsi_host_for_each_session(struct Scsi_Host *shost, struct iscsi_endpoint { void *dd_data; /* LLD private data */ - struct device dev; + struct class_device dev; uint64_t id; }; -- 1.6.0.6