1 diff --git a/iscsi_tcp.c b/iscsi_tcp.c
2 index 8ef3f41..14c6706 100644
5 @@ -445,11 +445,9 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
7 iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count);
9 - struct scsi_data_buffer *sdb = scsi_out(task->sc);
11 - err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl,
12 - sdb->table.nents, offset,
14 + err = iscsi_sw_tcp_send_data_prep(conn, scsi_sglist(task->sc),
15 + scsi_sg_count(task->sc),
20 @@ -782,7 +780,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max,
21 shost->max_lun = iscsi_max_lun;
23 shost->max_channel = 0;
24 +#ifndef SCSI_MAX_VARLEN_CDB_SIZE
25 + shost->max_cmd_len = 16;
27 shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE;
30 if (iscsi_host_add(shost, NULL))
32 @@ -830,6 +832,9 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
35 static struct scsi_host_template iscsi_sw_tcp_sht = {
36 +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,24)
37 + .use_sg_chaining = ENABLE_SG_CHAINING,
39 .module = THIS_MODULE,
40 .name = "iSCSI Initiator over TCP/IP",
41 .queuecommand = iscsi_queuecommand,
42 @@ -840,7 +845,7 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
43 .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
44 .eh_abort_handler = iscsi_eh_abort,
45 .eh_device_reset_handler= iscsi_eh_device_reset,
46 - .eh_target_reset_handler= iscsi_eh_target_reset,
47 + .eh_host_reset_handler = iscsi_eh_target_reset,
48 .use_clustering = DISABLE_CLUSTERING,
49 .slave_configure = iscsi_sw_tcp_slave_configure,
50 .proc_name = "iscsi_tcp",
51 diff --git a/iscsi_tcp.h b/iscsi_tcp.h
52 index f9a4044..ab20530 100644
56 #ifndef ISCSI_SW_TCP_H
57 #define ISCSI_SW_TCP_H
59 +#include "open_iscsi_compat.h"
62 #include "libiscsi_tcp.h"
64 diff --git a/libiscsi.c b/libiscsi.c
65 index 457ecfe..756b171 100644
69 #include <linux/types.h>
70 #include <linux/kfifo.h>
71 #include <linux/delay.h>
72 +#include <linux/version.h>
73 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
74 #include <linux/log2.h>
76 #include <asm/unaligned.h>
78 #include <scsi/scsi_cmnd.h>
80 #include "scsi_transport_iscsi.h"
83 +#include "open_iscsi_compat.h"
85 /* Serial Number Arithmetic, 32 bits, less than, RFC1982 */
86 #define SNA32_CHECK 2147483648UL
88 @@ -199,7 +204,7 @@ static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
89 sizeof(rlen_ahdr->reserved));
90 rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
91 rlen_ahdr->reserved = 0;
92 - rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
93 + rlen_ahdr->read_length = cpu_to_be32(scsi_bufflen(sc));
95 debug_scsi("bidi-in rlen_ahdr->read_length(%d) "
96 "rlen_ahdr->ahslength(%d)\n",
97 @@ -267,7 +272,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
100 if (sc->sc_data_direction == DMA_TO_DEVICE) {
101 - unsigned out_len = scsi_out(sc)->length;
102 + unsigned out_len = scsi_bufflen(sc);
103 struct iscsi_r2t_info *r2t = &task->unsol_r2t;
105 hdr->data_length = cpu_to_be32(out_len);
106 @@ -313,7 +318,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
108 hdr->flags |= ISCSI_FLAG_CMD_FINAL;
109 zero_data(hdr->dlength);
110 - hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
111 + hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
113 if (sc->sc_data_direction == DMA_FROM_DEVICE)
114 hdr->flags |= ISCSI_FLAG_CMD_READ;
115 @@ -340,7 +345,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
116 "bidirectional" : sc->sc_data_direction == DMA_TO_DEVICE ?
117 "write" : "read", conn->id, sc, sc->cmnd[0], task->itt,
119 - scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
120 + scsi_bidi_cmnd(sc) ? scsi_bufflen(sc) : 0,
121 session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
124 @@ -432,12 +437,7 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task,
125 conn->session->queued_cmdsn--;
128 - if (!scsi_bidi_cmnd(sc))
129 - scsi_set_resid(sc, scsi_bufflen(sc));
131 - scsi_out(sc)->resid = scsi_out(sc)->length;
132 - scsi_in(sc)->resid = scsi_in(sc)->length;
134 + scsi_set_resid(sc, scsi_bufflen(sc));
136 if (conn->task == task)
138 @@ -631,7 +631,7 @@ invalid_datalen:
142 - senselen = get_unaligned_be16(data);
143 + senselen = be16_to_cpu(get_unaligned((__be16 *) data));
144 if (datalen < senselen)
145 goto invalid_datalen;
147 @@ -647,8 +647,8 @@ invalid_datalen:
149 if (scsi_bidi_cmnd(sc) && res_count > 0 &&
150 (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
151 - res_count <= scsi_in(sc)->length))
152 - scsi_in(sc)->resid = res_count;
153 + res_count <= scsi_bufflen(sc)))
154 + scsi_set_resid(sc, res_count);
156 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
158 @@ -697,8 +697,8 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
161 (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
162 - res_count <= scsi_in(sc)->length))
163 - scsi_in(sc)->resid = res_count;
164 + res_count <= scsi_bufflen(sc)))
165 + scsi_set_resid(sc, res_count);
167 sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
169 @@ -1244,10 +1244,9 @@ again:
173 -static void iscsi_xmitworker(struct work_struct *work)
174 +static void iscsi_xmitworker(void *data)
176 - struct iscsi_conn *conn =
177 - container_of(work, struct iscsi_conn, xmitwork);
178 + struct iscsi_conn *conn = data;
181 * serialize Xmit worker on a per-connection basis.
182 @@ -1408,12 +1407,7 @@ prepd_fault:
184 spin_unlock(&session->lock);
185 debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
186 - if (!scsi_bidi_cmnd(sc))
187 - scsi_set_resid(sc, scsi_bufflen(sc));
189 - scsi_out(sc)->resid = scsi_out(sc)->length;
190 - scsi_in(sc)->resid = scsi_in(sc)->length;
192 + scsi_set_resid(sc, scsi_bufflen(sc));
194 spin_lock(host->host_lock);
196 @@ -1998,8 +1992,10 @@ int iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
197 if (!shost->can_queue)
198 shost->can_queue = ISCSI_DEF_XMIT_CMDS_MAX;
200 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
201 if (!shost->transportt->eh_timed_out)
202 shost->transportt->eh_timed_out = iscsi_eh_cmd_timed_out;
204 return scsi_add_host(shost, pdev);
206 EXPORT_SYMBOL_GPL(iscsi_host_add);
207 @@ -2295,7 +2291,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size,
208 INIT_LIST_HEAD(&conn->mgmtqueue);
209 INIT_LIST_HEAD(&conn->xmitqueue);
210 INIT_LIST_HEAD(&conn->requeue);
211 - INIT_WORK(&conn->xmitwork, iscsi_xmitworker);
212 + INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn);
214 /* allocate login_task used for the login/text sequences */
215 spin_lock_bh(&session->lock);
216 diff --git a/libiscsi.h b/libiscsi.h
217 index a261e2c..1274bc9 100644
222 #include <linux/types.h>
223 #include <linux/wait.h>
224 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
225 #include <linux/mutex.h>
226 -#include <linux/timer.h>
227 -#include <linux/workqueue.h>
230 #include "iscsi_proto.h"
231 #include "iscsi_if.h"
232 #include "scsi_transport_iscsi.h"
234 +#include "open_iscsi_compat.h"
236 struct scsi_transport_template;
237 struct scsi_host_template;
239 diff --git a/libiscsi_tcp.c b/libiscsi_tcp.c
240 index 92cb13d..ea7dd8d 100644
243 @@ -357,6 +357,17 @@ iscsi_segment_seek_sg(struct iscsi_segment *segment,
245 debug_scsi("iscsi_segment_seek_sg offset %u size %llu\n",
249 + * older kernels could send use_sg=0 for commands like sgio
250 + * or scsi-ml commands.
253 + iscsi_segment_init_linear(segment, (void *)sg_list + offset,
258 __iscsi_segment_init(segment, size, done, hash);
259 for_each_sg(sg_list, sg, sg_count, i) {
260 debug_scsi("sg %d, len %u offset %u\n", i, sg->length,
261 @@ -469,7 +480,7 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
262 struct iscsi_tcp_task *tcp_task = task->dd_data;
263 struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
264 int datasn = be32_to_cpu(rhdr->datasn);
265 - unsigned total_in_length = scsi_in(task->sc)->length;
266 + unsigned total_in_length = scsi_bufflen(task->sc);
268 iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr);
269 if (tcp_conn->in.datalen == 0)
270 @@ -557,11 +568,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
271 r2t->data_length, session->max_burst);
273 r2t->data_offset = be32_to_cpu(rhdr->data_offset);
274 - if (r2t->data_offset + r2t->data_length > scsi_out(task->sc)->length) {
275 + if (r2t->data_offset + r2t->data_length > scsi_bufflen(task->sc)) {
276 iscsi_conn_printk(KERN_ERR, conn,
277 "invalid R2T with data len %u at offset %u "
278 "and total length %d\n", r2t->data_length,
279 - r2t->data_offset, scsi_out(task->sc)->length);
280 + r2t->data_offset, scsi_bufflen(task->sc));
281 __kfifo_put(tcp_task->r2tpool.queue, (void*)&r2t,
283 return ISCSI_ERR_DATALEN;
284 @@ -660,7 +671,6 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
285 if (tcp_conn->in.datalen) {
286 struct iscsi_tcp_task *tcp_task = task->dd_data;
287 struct hash_desc *rx_hash = NULL;
288 - struct scsi_data_buffer *sdb = scsi_in(task->sc);
291 * Setup copy of Data-In into the Scsi_Cmnd
292 @@ -679,8 +689,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
293 tcp_task->data_offset,
294 tcp_conn->in.datalen);
295 rc = iscsi_segment_seek_sg(&tcp_conn->in.segment,
298 + scsi_sglist(task->sc),
299 + scsi_sg_count(task->sc),
300 tcp_task->data_offset,
301 tcp_conn->in.datalen,
302 iscsi_tcp_process_data_in,
303 diff --git a/libiscsi_tcp.h b/libiscsi_tcp.h
304 index 3bacef5..5ea284d 100644
308 #ifndef LIBISCSI_TCP_H
309 #define LIBISCSI_TCP_H
311 +#include "open_iscsi_compat.h"
312 #include "libiscsi.h"
314 struct iscsi_tcp_conn;
315 diff --git a/open_iscsi_compat.h b/open_iscsi_compat.h
317 index 0000000..2dbe4ce
319 +++ b/open_iscsi_compat.h
321 +#ifndef OPEN_ISCSI_COMPAT
322 +#define OPEN_ISCSI_COMPAT
324 +#include <linux/version.h>
325 +#include <linux/kernel.h>
326 +#include <scsi/scsi.h>
327 +#include <scsi/scsi_cmnd.h>
329 +#ifndef SCAN_WILD_CARD
330 +#define SCAN_WILD_CARD ~0
334 +#define NIPQUAD_FMT "%u.%u.%u.%u"
338 +#define NIP6_FMT "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x"
341 +#ifndef DEFINE_MUTEX
343 +/* mutex changes from 2.6.16-rc1 and up */
344 +#define DEFINE_MUTEX DECLARE_MUTEX
345 +#define mutex_lock down
346 +#define mutex_unlock up
347 +#define mutex semaphore
348 +#define mutex_init init_MUTEX
351 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
353 +void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun)
357 + memset(scsilun->scsi_lun, 0, sizeof(scsilun->scsi_lun));
359 + for (i = 0; i < sizeof(lun); i += 2) {
360 + scsilun->scsi_lun[i] = (lun >> 8) & 0xFF;
361 + scsilun->scsi_lun[i+1] = lun & 0xFF;
366 +#define __nlmsg_put(skb, daemon_pid, seq, type, len, flags) \
367 + __nlmsg_put(skb, daemon_pid, 0, 0, len)
371 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
373 +#define gfp_t unsigned
375 +void *kzalloc(size_t size, gfp_t flags)
377 + void *ret = kmalloc(size, flags);
379 + memset(ret, 0, size);
384 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
386 +#include "linux/crypto.h"
388 +#define CRYPTO_ALG_ASYNC 0x00000080
391 + struct crypto_tfm *tfm;
395 +static inline int crypto_hash_init(struct hash_desc *desc)
397 + crypto_digest_init(desc->tfm);
401 +static inline int crypto_hash_digest(struct hash_desc *desc,
402 + struct scatterlist *sg,
403 + unsigned int nbytes, u8 *out)
405 + crypto_digest_digest(desc->tfm, sg, 1, out);
409 +static inline int crypto_hash_update(struct hash_desc *desc,
410 + struct scatterlist *sg,
411 + unsigned int nbytes)
413 + crypto_digest_update(desc->tfm, sg, 1);
417 +static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
419 + crypto_digest_final(desc->tfm, out);
423 +static inline struct crypto_tfm *crypto_alloc_hash(const char *alg_name,
424 + u32 type, u32 mask)
426 + struct crypto_tfm *ret = crypto_alloc_tfm(alg_name ,type);
427 + return ret ? ret : ERR_PTR(-ENOMEM);
430 +static inline void crypto_free_hash(struct crypto_tfm *tfm)
432 + crypto_free_tfm(tfm);
435 +int kernel_getsockname(struct socket *sock, struct sockaddr *addr,
438 + return sock->ops->getname(sock, addr, addrlen, 0);
441 +int kernel_getpeername(struct socket *sock, struct sockaddr *addr,
444 + return sock->ops->getname(sock, addr, addrlen, 1);
453 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,20)
454 +#ifdef RHEL_RELEASE_VERSION
455 +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2)
456 +static inline int is_power_of_2(unsigned long n)
458 + return (n != 0 && ((n & (n - 1)) == 0));
462 +/* not a redhat kernel */
463 +static inline int is_power_of_2(unsigned long n)
465 + return (n != 0 && ((n & (n - 1)) == 0));
470 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21)
472 +static inline struct nlmsghdr *nlmsg_hdr(const struct sk_buff *skb)
474 + return (struct nlmsghdr *)skb->data;
479 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)
480 +#ifdef RHEL_RELEASE_VERSION
481 +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2)
482 +static inline void *shost_priv(struct Scsi_Host *shost)
484 + return (void *)shost->hostdata;
488 +/* not a redhat kernel */
489 +static inline void *shost_priv(struct Scsi_Host *shost)
491 + return (void *)shost->hostdata;
496 + * Note: We do not support bidi for the compat modules if the kernel
497 + * does not have support.
499 +#define scsi_sg_count(cmd) ((cmd)->use_sg)
500 +#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer)
501 +#define scsi_bufflen(cmd) ((cmd)->request_bufflen)
503 +#ifdef RHEL_RELEASE_VERSION
504 +#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,2)
505 +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
507 + cmd->resid = resid;
510 +static inline int scsi_get_resid(struct scsi_cmnd *cmd)
516 +/* not a redhat kernel */
517 +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid)
519 + cmd->resid = resid;
522 +static inline int scsi_get_resid(struct scsi_cmnd *cmd)
530 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
532 +static inline unsigned long rounddown_pow_of_two(unsigned long n)
534 + return 1UL << (fls_long(n) - 1);
538 +static inline struct scatterlist *sg_next(struct scatterlist *sg)
547 +#define for_each_sg(sglist, sg, nr, __i) \
548 + for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
550 +#define sg_page(_sg) _sg->page
552 +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
553 + unsigned int len, unsigned int offset)
556 + sg->offset = offset;
560 +static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
562 + memset(sgl, 0, sizeof(*sgl) * nents);
566 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24)
568 +static inline int scsi_bidi_cmnd(struct scsi_cmnd *cmd)
573 +#define netlink_kernel_release(_nls) \
574 + sock_release(_nls->sk_socket)
580 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13)
582 +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \
583 + netlink_kernel_create(uint, input)
585 +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21)
587 +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \
588 + netlink_kernel_create(uint, groups, input, mod)
590 +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22)
592 +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \
593 + netlink_kernel_create(uint, groups, input, cb_mutex, mod)
595 +#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)
597 +#define netlink_kernel_create(net, uint, groups, input, cb_mutex, mod) \
598 + netlink_kernel_create(uint, groups, input, cb_mutex, mod)
602 +#ifndef DID_TRANSPORT_DISRUPTED
603 +#define DID_TRANSPORT_DISRUPTED DID_BUS_BUSY
606 +#ifndef DID_TRANSPORT_FAILFAST
607 +#define DID_TRANSPORT_FAILFAST DID_NO_CONNECT
610 +#ifndef SCSI_MLQUEUE_TARGET_BUSY
611 +#define SCSI_MLQUEUE_TARGET_BUSY SCSI_MLQUEUE_HOST_BUSY
614 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27)
616 +#define BLK_EH_NOT_HANDLED EH_NOT_HANDLED
617 +#define BLK_EH_RESET_TIMER EH_RESET_TIMER
619 +#define blk_eh_timer_return scsi_eh_timer_return
624 diff --git a/scsi_transport_iscsi.c b/scsi_transport_iscsi.c
625 index 4781d81..98d1351 100644
626 --- a/scsi_transport_iscsi.c
627 +++ b/scsi_transport_iscsi.c
629 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
631 #include <linux/module.h>
632 +#include <linux/version.h>
633 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
634 #include <linux/mutex.h>
637 #include <scsi/scsi.h>
638 #include <scsi/scsi_host.h>
639 @@ -41,13 +44,13 @@ struct iscsi_internal {
640 struct scsi_transport_template t;
641 struct iscsi_transport *iscsi_transport;
642 struct list_head list;
644 + struct class_device cdev;
646 - struct device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
647 + struct class_device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1];
648 struct transport_container conn_cont;
649 - struct device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
650 + struct class_device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1];
651 struct transport_container session_cont;
652 - struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
653 + struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
656 static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
657 @@ -64,12 +67,12 @@ static DEFINE_SPINLOCK(iscsi_transport_lock);
658 #define to_iscsi_internal(tmpl) \
659 container_of(tmpl, struct iscsi_internal, t)
661 -#define dev_to_iscsi_internal(_dev) \
662 - container_of(_dev, struct iscsi_internal, dev)
663 +#define cdev_to_iscsi_internal(_cdev) \
664 + container_of(_cdev, struct iscsi_internal, cdev)
666 -static void iscsi_transport_release(struct device *dev)
667 +static void iscsi_transport_release(struct class_device *cdev)
669 - struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
670 + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
674 @@ -79,33 +82,31 @@ static void iscsi_transport_release(struct device *dev)
676 static struct class iscsi_transport_class = {
677 .name = "iscsi_transport",
678 - .dev_release = iscsi_transport_release,
679 + .release = iscsi_transport_release,
683 -show_transport_handle(struct device *dev, struct device_attribute *attr,
685 +show_transport_handle(struct class_device *cdev, char *buf)
687 - struct iscsi_internal *priv = dev_to_iscsi_internal(dev);
688 + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev);
689 return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport));
691 -static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
692 +static CLASS_DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL);
694 #define show_transport_attr(name, format) \
696 -show_transport_##name(struct device *dev, \
697 - struct device_attribute *attr,char *buf) \
698 +show_transport_##name(struct class_device *cdev, char *buf) \
700 - struct iscsi_internal *priv = dev_to_iscsi_internal(dev); \
701 + struct iscsi_internal *priv = cdev_to_iscsi_internal(cdev); \
702 return sprintf(buf, format"\n", priv->iscsi_transport->name); \
704 -static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
705 +static CLASS_DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL);
707 show_transport_attr(caps, "0x%x");
709 static struct attribute *iscsi_transport_attrs[] = {
710 - &dev_attr_handle.attr,
711 - &dev_attr_caps.attr,
712 + &class_device_attr_handle.attr,
713 + &class_device_attr_caps.attr,
717 @@ -113,6 +114,7 @@ static struct attribute_group iscsi_transport_group = {
718 .attrs = iscsi_transport_attrs,
723 * iSCSI endpoint attrs
725 @@ -236,9 +238,10 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
728 EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint);
731 static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
732 - struct device *cdev)
733 + struct class_device *cdev)
735 struct Scsi_Host *shost = dev_to_shost(dev);
736 struct iscsi_cls_host *ihost = shost->shost_data;
737 @@ -257,7 +260,7 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
740 static int iscsi_remove_host(struct transport_container *tc, struct device *dev,
741 - struct device *cdev)
742 + struct class_device *cdev)
744 struct Scsi_Host *shost = dev_to_shost(dev);
745 struct iscsi_cls_host *ihost = shost->shost_data;
746 @@ -497,10 +500,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
747 iscsi_user_scan_session);
750 -static void iscsi_scan_session(struct work_struct *work)
751 +static void iscsi_scan_session(void *data)
753 - struct iscsi_cls_session *session =
754 - container_of(work, struct iscsi_cls_session, scan_work);
755 + struct iscsi_cls_session *session = data;
756 struct Scsi_Host *shost = iscsi_session_to_shost(session);
757 struct iscsi_cls_host *ihost = shost->shost_data;
758 struct iscsi_scan_data scan_data;
759 @@ -513,11 +515,9 @@ static void iscsi_scan_session(struct work_struct *work)
760 atomic_dec(&ihost->nr_scans);
763 -static void session_recovery_timedout(struct work_struct *work)
764 +static void session_recovery_timedout(void *data)
766 - struct iscsi_cls_session *session =
767 - container_of(work, struct iscsi_cls_session,
768 - recovery_work.work);
769 + struct iscsi_cls_session *session = data;
772 iscsi_cls_session_printk(KERN_INFO, session,
773 @@ -543,11 +543,9 @@ static void session_recovery_timedout(struct work_struct *work)
774 scsi_target_unblock(&session->dev);
777 -static void __iscsi_unblock_session(struct work_struct *work)
778 +static void __iscsi_unblock_session(void *data)
780 - struct iscsi_cls_session *session =
781 - container_of(work, struct iscsi_cls_session,
783 + struct iscsi_cls_session *session = data;
784 struct Scsi_Host *shost = iscsi_session_to_shost(session);
785 struct iscsi_cls_host *ihost = shost->shost_data;
787 @@ -567,10 +565,12 @@ static void __iscsi_unblock_session(struct work_struct *work)
788 * the async scanning code (drivers like iscsi_tcp do login and
789 * scanning from userspace).
791 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
792 if (shost->hostt->scan_finished) {
793 if (queue_work(ihost->scan_workq, &session->scan_work))
794 atomic_inc(&ihost->nr_scans);
800 @@ -590,11 +590,9 @@ void iscsi_unblock_session(struct iscsi_cls_session *session)
802 EXPORT_SYMBOL_GPL(iscsi_unblock_session);
804 -static void __iscsi_block_session(struct work_struct *work)
805 +static void __iscsi_block_session(void *data)
807 - struct iscsi_cls_session *session =
808 - container_of(work, struct iscsi_cls_session,
810 + struct iscsi_cls_session *session = data;
813 spin_lock_irqsave(&session->lock, flags);
814 @@ -611,11 +609,9 @@ void iscsi_block_session(struct iscsi_cls_session *session)
816 EXPORT_SYMBOL_GPL(iscsi_block_session);
818 -static void __iscsi_unbind_session(struct work_struct *work)
819 +static void __iscsi_unbind_session(void *data)
821 - struct iscsi_cls_session *session =
822 - container_of(work, struct iscsi_cls_session,
824 + struct iscsi_cls_session *session = data;
825 struct Scsi_Host *shost = iscsi_session_to_shost(session);
826 struct iscsi_cls_host *ihost = shost->shost_data;
828 @@ -658,12 +654,12 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
829 session->transport = transport;
830 session->recovery_tmo = 120;
831 session->state = ISCSI_SESSION_FREE;
832 - INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
833 + INIT_WORK(&session->recovery_work, session_recovery_timedout, session);
834 INIT_LIST_HEAD(&session->sess_list);
835 - INIT_WORK(&session->unblock_work, __iscsi_unblock_session);
836 - INIT_WORK(&session->block_work, __iscsi_block_session);
837 - INIT_WORK(&session->unbind_work, __iscsi_unbind_session);
838 - INIT_WORK(&session->scan_work, iscsi_scan_session);
839 + INIT_WORK(&session->unblock_work, __iscsi_unblock_session, session);
840 + INIT_WORK(&session->block_work, __iscsi_block_session, session);
841 + INIT_WORK(&session->unbind_work, __iscsi_unbind_session, session);
842 + INIT_WORK(&session->scan_work, iscsi_scan_session, session);
843 spin_lock_init(&session->lock);
845 /* this is released in the dev's release function */
846 @@ -723,7 +719,8 @@ int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
848 session->target_id = id;
850 - dev_set_name(&session->dev, "session%u", session->sid);
851 + snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
853 err = device_add(&session->dev);
855 iscsi_cls_session_printk(KERN_ERR, session,
856 @@ -822,7 +819,7 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
857 scsi_target_unblock(&session->dev);
858 /* flush running scans then delete devices */
859 flush_workqueue(ihost->scan_workq);
860 - __iscsi_unbind_session(&session->unbind_work);
861 + __iscsi_unbind_session(session);
863 /* hw iscsi may not have removed all connections from session */
864 err = device_for_each_child(&session->dev, NULL,
865 @@ -896,7 +893,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
866 if (!get_device(&session->dev))
869 - dev_set_name(&conn->dev, "connection%d:%u", session->sid, cid);
870 + snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u",
871 + session->sid, cid);
872 conn->dev.parent = &session->dev;
873 conn->dev.release = iscsi_conn_release;
874 err = device_register(&conn->dev);
875 @@ -1305,6 +1303,8 @@ static int
876 iscsi_if_transport_ep(struct iscsi_transport *transport,
877 struct iscsi_uevent *ev, int msg_type)
881 struct iscsi_endpoint *ep;
882 struct sockaddr *dst_addr;
884 @@ -1345,6 +1345,8 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
893 @@ -1426,6 +1428,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
894 ev->u.c_session.queue_depth);
896 case ISCSI_UEVENT_CREATE_BOUND_SESSION:
900 ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle);
903 @@ -1437,6 +1442,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
904 ev->u.c_bound_session.cmds_max,
905 ev->u.c_bound_session.queue_depth);
908 case ISCSI_UEVENT_DESTROY_SESSION:
909 session = iscsi_session_lookup(ev->u.d_session.sid);
911 @@ -1519,55 +1525,70 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
915 - * Get message from skb. Each message is processed by iscsi_if_recv_msg.
916 - * Malformed skbs with wrong lengths or invalid creds are not processed.
917 + * Get message from skb (based on rtnetlink_rcv_skb). Each message is
918 + * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or
919 + * invalid creds are discarded silently.
922 -iscsi_if_rx(struct sk_buff *skb)
923 +iscsi_if_rx(struct sock *sk, int len)
925 + struct sk_buff *skb;
927 mutex_lock(&rx_queue_mutex);
928 - while (skb->len >= NLMSG_SPACE(0)) {
931 - struct nlmsghdr *nlh;
932 - struct iscsi_uevent *ev;
934 - nlh = nlmsg_hdr(skb);
935 - if (nlh->nlmsg_len < sizeof(*nlh) ||
936 - skb->len < nlh->nlmsg_len) {
938 + while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
939 + if (NETLINK_CREDS(skb)->uid) {
940 + skb_pull(skb, skb->len);
944 - ev = NLMSG_DATA(nlh);
945 - rlen = NLMSG_ALIGN(nlh->nlmsg_len);
946 - if (rlen > skb->len)
948 + while (skb->len >= NLMSG_SPACE(0)) {
951 + struct nlmsghdr *nlh;
952 + struct iscsi_uevent *ev;
954 - err = iscsi_if_recv_msg(skb, nlh);
956 - ev->type = ISCSI_KEVENT_IF_ERROR;
961 - * special case for GET_STATS:
962 - * on success - sending reply and stats from
963 - * inside of if_recv_msg(),
964 - * on error - fall through.
966 - if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
967 + nlh = nlmsg_hdr(skb);
968 + if (nlh->nlmsg_len < sizeof(*nlh) ||
969 + skb->len < nlh->nlmsg_len) {
971 - err = iscsi_if_send_reply(
972 - NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
973 - nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
974 - } while (err < 0 && err != -ECONNREFUSED);
975 - skb_pull(skb, rlen);
978 + ev = NLMSG_DATA(nlh);
979 + rlen = NLMSG_ALIGN(nlh->nlmsg_len);
980 + if (rlen > skb->len)
983 + err = iscsi_if_recv_msg(skb, nlh);
985 + ev->type = ISCSI_KEVENT_IF_ERROR;
990 + * special case for GET_STATS:
991 + * on success - sending reply and stats from
992 + * inside of if_recv_msg(),
993 + * on error - fall through.
995 + if (ev->type == ISCSI_UEVENT_GET_STATS && !err)
997 + err = iscsi_if_send_reply(
998 + NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq,
999 + nlh->nlmsg_type, 0, 0, ev, sizeof(*ev));
1000 + } while (err < 0 && err != -ECONNREFUSED);
1001 + skb_pull(skb, rlen);
1006 mutex_unlock(&rx_queue_mutex);
1009 +#define iscsi_cdev_to_conn(_cdev) \
1010 + iscsi_dev_to_conn(_cdev->dev)
1012 #define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \
1013 -struct device_attribute dev_attr_##_prefix##_##_name = \
1014 +struct class_device_attribute class_device_attr_##_prefix##_##_name = \
1015 __ATTR(_name,_mode,_show,_store)
1018 @@ -1575,10 +1596,9 @@ struct device_attribute dev_attr_##_prefix##_##_name = \
1020 #define iscsi_conn_attr_show(param) \
1022 -show_conn_param_##param(struct device *dev, \
1023 - struct device_attribute *attr, char *buf) \
1024 +show_conn_param_##param(struct class_device *cdev, char *buf) \
1026 - struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \
1027 + struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
1028 struct iscsi_transport *t = conn->transport; \
1029 return t->get_conn_param(conn, param, buf); \
1031 @@ -1602,16 +1622,17 @@ iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1032 iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
1033 iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
1035 +#define iscsi_cdev_to_session(_cdev) \
1036 + iscsi_dev_to_session(_cdev->dev)
1039 * iSCSI session attrs
1041 #define iscsi_session_attr_show(param, perm) \
1043 -show_session_param_##param(struct device *dev, \
1044 - struct device_attribute *attr, char *buf) \
1045 +show_session_param_##param(struct class_device *cdev, char *buf) \
1047 - struct iscsi_cls_session *session = \
1048 - iscsi_dev_to_session(dev->parent); \
1049 + struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1050 struct iscsi_transport *t = session->transport; \
1052 if (perm && !capable(CAP_SYS_ADMIN)) \
1053 @@ -1645,10 +1666,9 @@ iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0);
1054 iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0)
1057 -show_priv_session_state(struct device *dev, struct device_attribute *attr,
1059 +show_priv_session_state(struct class_device *cdev, char *buf)
1061 - struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent);
1062 + struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);
1063 return sprintf(buf, "%s\n", iscsi_session_state_name(session->state));
1065 static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
1066 @@ -1656,11 +1676,9 @@ static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state,
1068 #define iscsi_priv_session_attr_show(field, format) \
1070 -show_priv_session_##field(struct device *dev, \
1071 - struct device_attribute *attr, char *buf) \
1072 +show_priv_session_##field(struct class_device *cdev, char *buf) \
1074 - struct iscsi_cls_session *session = \
1075 - iscsi_dev_to_session(dev->parent); \
1076 + struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\
1077 return sprintf(buf, format"\n", session->field); \
1080 @@ -1675,10 +1693,9 @@ iscsi_priv_session_attr(recovery_tmo, "%d");
1082 #define iscsi_host_attr_show(param) \
1084 -show_host_param_##param(struct device *dev, \
1085 - struct device_attribute *attr, char *buf) \
1086 +show_host_param_##param(struct class_device *cdev, char *buf) \
1088 - struct Scsi_Host *shost = transport_class_to_shost(dev); \
1089 + struct Scsi_Host *shost = transport_class_to_shost(cdev); \
1090 struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
1091 return priv->iscsi_transport->get_host_param(shost, param, buf); \
1093 @@ -1695,7 +1712,7 @@ iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
1095 #define SETUP_PRIV_SESSION_RD_ATTR(field) \
1097 - priv->session_attrs[count] = &dev_attr_priv_sess_##field; \
1098 + priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
1102 @@ -1703,7 +1720,7 @@ do { \
1103 #define SETUP_SESSION_RD_ATTR(field, param_flag) \
1105 if (tt->param_mask & param_flag) { \
1106 - priv->session_attrs[count] = &dev_attr_sess_##field; \
1107 + priv->session_attrs[count] = &class_device_attr_sess_##field; \
1111 @@ -1711,7 +1728,7 @@ do { \
1112 #define SETUP_CONN_RD_ATTR(field, param_flag) \
1114 if (tt->param_mask & param_flag) { \
1115 - priv->conn_attrs[count] = &dev_attr_conn_##field; \
1116 + priv->conn_attrs[count] = &class_device_attr_conn_##field; \
1120 @@ -1719,7 +1736,7 @@ do { \
1121 #define SETUP_HOST_RD_ATTR(field, param_flag) \
1123 if (tt->host_param_mask & param_flag) { \
1124 - priv->host_attrs[count] = &dev_attr_host_##field; \
1125 + priv->host_attrs[count] = &class_device_attr_host_##field; \
1129 @@ -1808,19 +1825,21 @@ iscsi_register_transport(struct iscsi_transport *tt)
1130 INIT_LIST_HEAD(&priv->list);
1131 priv->daemon_pid = -1;
1132 priv->iscsi_transport = tt;
1133 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
1134 priv->t.user_scan = iscsi_user_scan;
1136 if (!(tt->caps & CAP_DATA_PATH_OFFLOAD))
1137 priv->t.create_work_queue = 1;
1139 - priv->dev.class = &iscsi_transport_class;
1140 - dev_set_name(&priv->dev, "%s", tt->name);
1141 - err = device_register(&priv->dev);
1142 + priv->cdev.class = &iscsi_transport_class;
1143 + snprintf(priv->cdev.class_id, BUS_ID_SIZE, "%s", tt->name);
1144 + err = class_device_register(&priv->cdev);
1148 - err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group);
1149 + err = sysfs_create_group(&priv->cdev.kobj, &iscsi_transport_group);
1151 - goto unregister_dev;
1152 + goto unregister_cdev;
1154 /* host parameters */
1155 priv->t.host_attrs.ac.attrs = &priv->host_attrs[0];
1156 @@ -1899,9 +1918,8 @@ iscsi_register_transport(struct iscsi_transport *tt)
1157 printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name);
1161 - device_unregister(&priv->dev);
1164 + class_device_unregister(&priv->cdev);
1168 @@ -1928,8 +1946,8 @@ int iscsi_unregister_transport(struct iscsi_transport *tt)
1169 transport_container_unregister(&priv->session_cont);
1170 transport_container_unregister(&priv->t.host_attrs);
1172 - sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group);
1173 - device_unregister(&priv->dev);
1174 + sysfs_remove_group(&priv->cdev.kobj, &iscsi_transport_group);
1175 + class_device_unregister(&priv->cdev);
1176 mutex_unlock(&rx_queue_mutex);
1179 @@ -1949,13 +1967,14 @@ static __init int iscsi_transport_init(void)
1184 err = class_register(&iscsi_endpoint_class);
1186 goto unregister_transport_class;
1189 err = transport_class_register(&iscsi_host_class);
1191 - goto unregister_endpoint_class;
1192 + goto unregister_transport_class;
1194 err = transport_class_register(&iscsi_connection_class);
1196 @@ -1986,8 +2005,10 @@ unregister_conn_class:
1197 transport_class_unregister(&iscsi_connection_class);
1198 unregister_host_class:
1199 transport_class_unregister(&iscsi_host_class);
1201 unregister_endpoint_class:
1202 class_unregister(&iscsi_endpoint_class);
1204 unregister_transport_class:
1205 class_unregister(&iscsi_transport_class);
1207 @@ -2000,7 +2021,9 @@ static void __exit iscsi_transport_exit(void)
1208 transport_class_unregister(&iscsi_connection_class);
1209 transport_class_unregister(&iscsi_session_class);
1210 transport_class_unregister(&iscsi_host_class);
1212 class_unregister(&iscsi_endpoint_class);
1214 class_unregister(&iscsi_transport_class);
1217 diff --git a/scsi_transport_iscsi.h b/scsi_transport_iscsi.h
1218 index 27d067a..6fa17f6 100644
1219 --- a/scsi_transport_iscsi.h
1220 +++ b/scsi_transport_iscsi.h
1223 #include <linux/device.h>
1224 #include <linux/list.h>
1225 +#include <linux/version.h>
1226 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
1227 #include <linux/mutex.h>
1229 #include "iscsi_if.h"
1231 +#include "open_iscsi_compat.h"
1233 struct scsi_transport_template;
1234 struct iscsi_transport;
1235 struct iscsi_endpoint;
1236 @@ -184,7 +189,7 @@ struct iscsi_cls_session {
1238 /* recovery fields */
1240 - struct delayed_work recovery_work;
1241 + struct work_struct recovery_work;
1243 unsigned int target_id;