diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2009-05-14 18:32:59 -0400 |
---|---|---|
committer | Mike Christie <michaelc@cs.wisc.edu> | 2009-05-14 18:33:28 -0400 |
commit | 6fc020102775dd54c0f76f5107cec72a78ca68ee (patch) | |
tree | 089be297a7e09999ce37969416579ed90425b939 /kernel | |
parent | a236f029ac96c621873a25079d56e0b5bf8a959d (diff) | |
download | open-iscsi-6fc020102775dd54c0f76f5107cec72a78ca68ee.tar.gz |
kernel: update 2.6.14 - .23 support
Update 2.6.14 - .23 support.
Note: 2.6.16 and below is still broken. Please email the
open-iscsi list if you need this.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/2.6.14-23_compat.patch | 1102 | ||||
-rw-r--r-- | kernel/Makefile | 40 |
2 files changed, 1117 insertions, 25 deletions
diff --git a/kernel/2.6.14-23_compat.patch b/kernel/2.6.14-23_compat.patch new file mode 100644 index 0000000..ab233bb --- /dev/null +++ b/kernel/2.6.14-23_compat.patch @@ -0,0 +1,1102 @@ +diff --git a/iscsi_tcp.c b/iscsi_tcp.c +index caa116c..71df5b9 100644 +--- a/iscsi_tcp.c ++++ b/iscsi_tcp.c +@@ -456,11 +456,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, +- count); ++ err = iscsi_sw_tcp_send_data_prep(conn, scsi_sglist(task->sc), ++ scsi_sg_count(task->sc), ++ offset, count); + } + + if (err) { +@@ -793,7 +791,11 @@ iscsi_sw_tcp_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, + shost->max_lun = iscsi_max_lun; + shost->max_id = 0; + shost->max_channel = 0; ++#ifndef SCSI_MAX_VARLEN_CDB_SIZE ++ shost->max_cmd_len = 16; ++#else + shost->max_cmd_len = SCSI_MAX_VARLEN_CDB_SIZE; ++#endif + + if (iscsi_host_add(shost, NULL)) + goto free_host; +@@ -832,12 +834,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); +@@ -846,6 +842,9 @@ static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev) + } + + static struct scsi_host_template iscsi_sw_tcp_sht = { ++#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,24) ++ .use_sg_chaining = ENABLE_SG_CHAINING, ++#endif + .module = THIS_MODULE, + .name = "iSCSI Initiator over TCP/IP", + .queuecommand = iscsi_queuecommand, +@@ -856,9 +855,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/iscsi_tcp.h b/iscsi_tcp.h +index f9a4044..ab20530 100644 +--- a/iscsi_tcp.h ++++ b/iscsi_tcp.h +@@ -22,6 +22,8 @@ + #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/libiscsi.c b/libiscsi.c +index fe4b66e..6217f76 100644 +--- a/libiscsi.c ++++ b/libiscsi.c +@@ -24,7 +24,10 @@ + #include <linux/types.h> + #include <linux/kfifo.h> + #include <linux/delay.h> ++#include <linux/version.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) + #include <linux/log2.h> ++#endif + #include <asm/unaligned.h> + #include <net/tcp.h> + #include <scsi/scsi_cmnd.h> +@@ -60,6 +63,8 @@ MODULE_PARM_DESC(debug_libiscsi, "Turn on debugging for libiscsi module. " + __func__, ##arg); \ + } while (0); + ++#include "open_iscsi_compat.h" ++ + /* Serial Number Arithmetic, 32 bits, less than, RFC1982 */ + #define SNA32_CHECK 2147483648UL + +@@ -229,7 +234,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) " +@@ -300,7 +305,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); +@@ -346,7 +351,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; +@@ -373,7 +378,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; +@@ -510,12 +515,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); + } +@@ -706,7 +706,7 @@ invalid_datalen: + goto out; + } + +- senselen = get_unaligned_be16(data); ++ senselen = be16_to_cpu(get_unaligned((__be16 *) data)); + if (datalen < senselen) + goto invalid_datalen; + +@@ -723,8 +723,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; + } +@@ -773,8 +773,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; + } +@@ -1498,12 +1498,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; +diff --git a/libiscsi.h b/libiscsi.h +index 1798fbe..c9174ec 100644 +--- a/libiscsi.h ++++ b/libiscsi.h +@@ -32,6 +32,8 @@ + #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; +diff --git a/libiscsi_tcp.c b/libiscsi_tcp.c +index c2b535b..76ead4b 100644 +--- a/libiscsi_tcp.c ++++ b/libiscsi_tcp.c +@@ -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 +@@ -687,8 +696,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) + tcp_task->data_offset, + tcp_conn->in.datalen); + 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, +diff --git a/libiscsi_tcp.h b/libiscsi_tcp.h +index 3bacef5..5ea284d 100644 +--- a/libiscsi_tcp.h ++++ b/libiscsi_tcp.h +@@ -21,6 +21,7 @@ + #ifndef LIBISCSI_TCP_H + #define LIBISCSI_TCP_H + ++#include "open_iscsi_compat.h" + #include "libiscsi.h" + + struct iscsi_tcp_conn; +diff --git a/open_iscsi_compat.h b/open_iscsi_compat.h +new file mode 100644 +index 0000000..763d07a +--- /dev/null ++++ b/open_iscsi_compat.h +@@ -0,0 +1,321 @@ ++#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> ++ ++#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 ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,19) ++struct delayed_work { ++ struct work_struct work; ++}; ++ ++#define cancel_delayed_work(_dwork) cancel_delayed_work(&(_dwork)->work) ++ ++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) ++#define INIT_DELAYED_WORK(_work,_func) INIT_WORK(&(_work)->work, _func) ++ ++#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) ++ ++#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" ++ ++#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); ++} ++ ++int kernel_getsockname(struct socket *sock, struct sockaddr *addr, ++ int *addrlen) ++{ ++ return sock->ops->getname(sock, addr, addrlen, 0); ++} ++ ++int kernel_getpeername(struct socket *sock, struct sockaddr *addr, ++ int *addrlen) ++{ ++ return sock->ops->getname(sock, addr, addrlen, 1); ++} ++ ++#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) ++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) ++ ++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, input) ++ ++#elif LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,21) ++ ++#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 ++ ++#endif +diff --git a/scsi_transport_iscsi.c b/scsi_transport_iscsi.c +index c9e95e7..79436c4 100644 +--- a/scsi_transport_iscsi.c ++++ b/scsi_transport_iscsi.c +@@ -41,13 +41,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 */ +@@ -64,12 +64,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); + } + +@@ -79,33 +79,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, + }; + +@@ -113,6 +111,7 @@ static struct attribute_group iscsi_transport_group = { + .attrs = iscsi_transport_attrs, + }; + ++#if 0 + /* + * iSCSI endpoint attrs + */ +@@ -236,9 +235,10 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) + return ep; + } + EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); ++#endif + + 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; +@@ -545,15 +545,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 +689,8 @@ 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 +862,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); +@@ -1309,6 +1302,8 @@ static int + iscsi_if_transport_ep(struct iscsi_transport *transport, + struct iscsi_uevent *ev, int msg_type) + { ++ return -ENOSYS; ++#if 0 + struct iscsi_endpoint *ep; + int rc = 0; + +@@ -1340,6 +1335,8 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, + break; + } + return rc; ++ ++#endif + } + + static int +@@ -1421,6 +1418,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + ev->u.c_session.queue_depth); + break; + case ISCSI_UEVENT_CREATE_BOUND_SESSION: ++ err = -ENOSYS; ++ break; ++#if 0 + ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle); + if (!ep) { + err = -EINVAL; +@@ -1432,6 +1432,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + ev->u.c_bound_session.cmds_max, + ev->u.c_bound_session.queue_depth); + break; ++#endif + case ISCSI_UEVENT_DESTROY_SESSION: + session = iscsi_session_lookup(ev->u.d_session.sid); + if (session) +@@ -1516,55 +1517,70 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + } + + /* +- * Get message from skb. Each message is processed by iscsi_if_recv_msg. +- * Malformed skbs with wrong lengths or invalid creds are not processed. ++ * Get message from skb (based on rtnetlink_rcv_skb). Each message is ++ * processed by iscsi_if_recv_msg. Malformed skbs with wrong lengths or ++ * invalid creds are discarded silently. + */ + static void +-iscsi_if_rx(struct sk_buff *skb) ++iscsi_if_rx(struct sock *sk, int len) + { ++ struct sk_buff *skb; ++ + mutex_lock(&rx_queue_mutex); +- while (skb->len >= NLMSG_SPACE(0)) { +- int err; +- uint32_t rlen; +- struct nlmsghdr *nlh; +- struct iscsi_uevent *ev; +- +- nlh = nlmsg_hdr(skb); +- if (nlh->nlmsg_len < sizeof(*nlh) || +- skb->len < nlh->nlmsg_len) { +- break; ++ while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { ++ if (NETLINK_CREDS(skb)->uid) { ++ skb_pull(skb, skb->len); ++ goto free_skb; + } + +- ev = NLMSG_DATA(nlh); +- rlen = NLMSG_ALIGN(nlh->nlmsg_len); +- if (rlen > skb->len) +- rlen = skb->len; ++ while (skb->len >= NLMSG_SPACE(0)) { ++ int err; ++ uint32_t rlen; ++ struct nlmsghdr *nlh; ++ struct iscsi_uevent *ev; + +- err = iscsi_if_recv_msg(skb, nlh); +- 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) ++ nlh = nlmsg_hdr(skb); ++ if (nlh->nlmsg_len < sizeof(*nlh) || ++ skb->len < nlh->nlmsg_len) { + break; +- err = iscsi_if_send_reply( +- NETLINK_CREDS(skb)->pid, 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); ++ 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( ++ NETLINK_CREDS(skb)->pid, 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) + + /* +@@ -1572,10 +1588,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); \ + } +@@ -1599,16 +1614,17 @@ 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); \ ++ struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ + struct iscsi_transport *t = session->transport; \ + \ + if (perm && !capable(CAP_SYS_ADMIN)) \ +@@ -1642,10 +1658,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, +@@ -1653,11 +1668,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); \ + } + +@@ -1672,10 +1685,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); \ + } +@@ -1692,7 +1704,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) + +@@ -1700,7 +1712,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) +@@ -1708,7 +1720,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) +@@ -1716,7 +1728,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) +@@ -1808,15 +1820,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]; +@@ -1895,9 +1907,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); +- return NULL; ++unregister_cdev: ++ class_device_unregister(&priv->cdev); + free_priv: + kfree(priv); + return NULL; +@@ -1924,8 +1935,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; +@@ -1945,13 +1956,14 @@ static __init int iscsi_transport_init(void) + if (err) + return err; + ++#if 0 + err = class_register(&iscsi_endpoint_class); + if (err) + goto unregister_transport_class; +- ++#endif + err = transport_class_register(&iscsi_host_class); + if (err) +- goto unregister_endpoint_class; ++ goto unregister_transport_class; + + err = transport_class_register(&iscsi_connection_class); + if (err) +@@ -1982,8 +1994,10 @@ unregister_conn_class: + transport_class_unregister(&iscsi_connection_class); + unregister_host_class: + transport_class_unregister(&iscsi_host_class); ++#if 0 + unregister_endpoint_class: + class_unregister(&iscsi_endpoint_class); ++#endif + unregister_transport_class: + class_unregister(&iscsi_transport_class); + return err; +@@ -1996,7 +2010,9 @@ static void __exit iscsi_transport_exit(void) + transport_class_unregister(&iscsi_connection_class); + transport_class_unregister(&iscsi_session_class); + transport_class_unregister(&iscsi_host_class); ++#if 0 + class_unregister(&iscsi_endpoint_class); ++#endif + class_unregister(&iscsi_transport_class); + } + +diff --git a/scsi_transport_iscsi.h b/scsi_transport_iscsi.h +index 6beea23..d509d17 100644 +--- a/scsi_transport_iscsi.h ++++ b/scsi_transport_iscsi.h +@@ -28,6 +28,8 @@ + #include <linux/mutex.h> + #include "iscsi_if.h" + ++#include "open_iscsi_compat.h" ++ + struct scsi_transport_template; + struct iscsi_transport; + struct iscsi_endpoint; +-- +1.5.2.1 + diff --git a/kernel/Makefile b/kernel/Makefile index 75671bd..a97c52f 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -49,8 +49,7 @@ all: kernel_check # form. #some constants -14to19_patch=2.6.14-19_compat.patch -20to21_patch=2.6.20-21_compat.patch +14to23_patch=2.6.14-23_compat.patch 24_patch=2.6.24_compat.patch 26_patch=2.6.26_compat.patch 27_patch=2.6.27_compat.patch @@ -69,25 +68,25 @@ KSUBLEVEL = $(shell cat $(KSRC)/Makefile | awk -F= '/^SUBLEVEL =/ {print $$2}' | KERNEL_TARGET=linux_2_6_$(KSUBLEVEL) kernel_check: $(KERNEL_TARGET) -linux_2_6_14: has_14to19_patch +linux_2_6_14: has_14to23_patch -linux_2_6_15: has_14to19_patch +linux_2_6_15: has_14to23_patch -linux_2_6_16: has_14to19_patch +linux_2_6_16: has_14to23_patch -linux_2_6_17: has_14to19_patch +linux_2_6_17: has_14to23_patch -linux_2_6_18: has_14to19_patch +linux_2_6_18: has_14to23_patch -linux_2_6_19: has_14to19_patch +linux_2_6_19: has_14to23_patch -linux_2_6_20: has_20to21_patch +linux_2_6_20: has_14to23_patch -linux_2_6_21: has_20to21_patch +linux_2_6_21: has_14to23_patch -linux_2_6_22: has_20to21_patch +linux_2_6_22: has_14to23_patch -linux_2_6_23: has_20to21_patch +linux_2_6_23: has_14to23_patch linux_2_6_24: has_24_patch @@ -112,22 +111,13 @@ do_unpatch_code: # these below targets must be the same as the variable name prefixed by has_ # otherwise below compat_patch: target will not work -has_14to19_patch: $(14to19_patch) - echo "Patching source code for linux-2.6.14-19 ..." +has_14to23_patch: $(14to23_patch) + echo "Patching source code for linux-2.6.14-23 ..." if [ -e $(cur_patched) ]; then \ make -C . clean; \ fi - patch -p1 < $(14to19_patch) - cp $(14to19_patch) $@ - ln -s $@ $(cur_patched) - -has_20to21_patch: $(20to21_patch) - echo "Patching source code for linux-2.6.20-21 ..." - if [ -e $(cur_patched) ]; then \ - make -C . clean; \ - fi - patch -p1 < $(20to21_patch) - cp $(20to21_patch) $@ + patch -p1 < $(14to23_patch) + cp $(14to23_patch) $@ ln -s $@ $(cur_patched) has_24_patch: $(24_patch) |