From bc96b052d5bbd7f4bd2bf3f2b92c927bfbb796f2 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Wed, 25 Mar 2009 12:55:27 +0000 Subject: [PATCH] The patch below adds support for the 2.6.29 kernel and also fixes the checkpatch issues reported by the checkpatch script included with the 2.6.29 kernel and that were not yet reported by the 2.6.28 checkpatch script (trailing statements should be on the next line / struct should normally be const). The patch below has been tested as follows: - Reran scripts/run-regression-tests -k 2.6.24.7 -k 2.6.25.20 -k 2.6.26.8 -k 2.6.27.21 -k 2.6.28.9 -k 2.6.29 and verified the output. - Rebuilt, installed and loaded scst, iscsi-scst and srpt as follows: make -s clean && make -s -C scst install && make -s -C iscsi-scst install && make -s -C srpt install && cd scstadmin && make -s && make -s install && modprobe scst_vdisk && modprobe iscsi-scst && dmesg Signed-off-by: Bart Van Assche with minor cleanups and corrections in put_page_callback-2.6.29.patch git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@717 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- iscsi-scst/kernel/config.c | 4 +- iscsi-scst/kernel/conn.c | 7 +- iscsi-scst/kernel/iscsi.c | 2 +- iscsi-scst/kernel/iscsi.h | 6 +- .../patches/put_page_callback-2.6.29.patch | 360 ++++++++++++++++++ iscsi-scst/kernel/session.c | 2 +- iscsi-scst/kernel/target.c | 2 +- scst/include/scst.h | 2 +- .../Kconfig.drivers.Linux-2.6.18.patch | 12 + .../Kconfig.drivers.Linux-2.6.29.patch | 12 + .../Makefile.drivers.Linux-2.6.18.patch | 11 + .../Makefile.drivers.Linux-2.6.29.patch | 11 + scst/kernel/io_context-2.6.29.patch | 61 +++ scst/kernel/scst_exec_req_fifo-2.6.29.patch | 112 ++++++ scst/src/dev_handlers/scst_cdrom.c | 6 +- scst/src/dev_handlers/scst_disk.c | 6 +- scst/src/dev_handlers/scst_modisk.c | 6 +- scst/src/dev_handlers/scst_user.c | 2 +- scst/src/dev_handlers/scst_vdisk.c | 2 +- scst/src/scst_lib.c | 16 +- 20 files changed, 623 insertions(+), 19 deletions(-) create mode 100644 iscsi-scst/kernel/patches/put_page_callback-2.6.29.patch create mode 100644 scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.18.patch create mode 100644 scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.29.patch create mode 100644 scst/kernel/in-tree/Makefile.drivers.Linux-2.6.18.patch create mode 100644 scst/kernel/in-tree/Makefile.drivers.Linux-2.6.29.patch create mode 100644 scst/kernel/io_context-2.6.29.patch create mode 100644 scst/kernel/scst_exec_req_fifo-2.6.29.patch diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index c53b592c5..b4294c2fc 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -168,7 +168,7 @@ static void iscsi_proc_log_entry_clean(struct scst_tgt_template *templ) struct proc_entries { const char *name; - struct file_operations *fops; + const struct file_operations *const fops; }; static struct proc_entries iscsi_proc_entries[] = @@ -475,7 +475,7 @@ static int release(struct inode *inode, struct file *filp) return 0; } -struct file_operations ctr_fops = { +const struct file_operations ctr_fops = { .owner = THIS_MODULE, .unlocked_ioctl = ioctl, .compat_ioctl = ioctl, diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 238464fbc..1f6e0a112 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -89,9 +89,14 @@ void conn_info_show(struct seq_file *seq, struct iscsi_session *session) "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr)); break; case AF_INET6: +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) snprintf(buf, sizeof(buf), "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", NIP6(inet6_sk(sk)->daddr)); +#else + snprintf(buf, sizeof(buf), "[%p6]", + &inet6_sk(sk)->daddr); +#endif break; default: break; @@ -500,7 +505,7 @@ out_err: /* target_mutex supposed to be locked */ int conn_add(struct iscsi_session *session, struct iscsi_kern_conn_info *info) { - struct iscsi_conn *conn, *new_conn; + struct iscsi_conn *conn, *new_conn = NULL; int err; bool reinstatement = false; diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index 3ff334c49..b7f88171c 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -3156,7 +3156,7 @@ static int __init iscsi_init(void) if (err < 0) goto out_reg_tmpl; - num = max(num_online_cpus(), 2); + num = max((int)num_online_cpus(), 2); err = iscsi_run_threads(num, "iscsird", istrd); if (err != 0) diff --git a/iscsi-scst/kernel/iscsi.h b/iscsi-scst/kernel/iscsi.h index ed6c113dd..c0e0d7764 100644 --- a/iscsi-scst/kernel/iscsi.h +++ b/iscsi-scst/kernel/iscsi.h @@ -387,7 +387,7 @@ struct iscsi_cmnd { extern struct mutex target_mgmt_mutex; -extern struct file_operations ctr_fops; +extern const struct file_operations ctr_fops; extern spinlock_t iscsi_rd_lock; extern struct list_head iscsi_rd_list; @@ -443,14 +443,14 @@ extern void target_del_session(struct iscsi_target *target, extern void target_del_all_sess(struct iscsi_target *target, int flags); extern void target_del_all(void); -extern struct seq_operations iscsi_seq_op; +extern const struct seq_operations iscsi_seq_op; /* config.c */ extern int iscsi_procfs_init(void); extern void iscsi_procfs_exit(void); /* session.c */ -extern struct file_operations session_seq_fops; +extern const struct file_operations session_seq_fops; extern struct iscsi_session *session_lookup(struct iscsi_target *, u64); extern void sess_enable_reinstated_sess(struct iscsi_session *); extern int session_add(struct iscsi_target *, struct iscsi_kern_session_info *); diff --git a/iscsi-scst/kernel/patches/put_page_callback-2.6.29.patch b/iscsi-scst/kernel/patches/put_page_callback-2.6.29.patch new file mode 100644 index 000000000..628a6d815 --- /dev/null +++ b/iscsi-scst/kernel/patches/put_page_callback-2.6.29.patch @@ -0,0 +1,360 @@ +diff -upkr linux-2.6.29/include/linux/mm_types.h linux-2.6.29/include/linux/mm_types.h +--- linux-2.6.29/include/linux/mm_types.h 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/include/linux/mm_types.h 2009-03-25 12:13:18.000000000 +0300 +@@ -94,6 +94,18 @@ struct page { + void *virtual; /* Kernel virtual address (NULL if + not kmapped, ie. highmem) */ + #endif /* WANT_PAGE_VIRTUAL */ ++ ++#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) ++ /* ++ * Used to implement support for notification on zero-copy TCP transfer ++ * completion. It might look as not good to have this field here and ++ * it's better to have it in struct sk_buff, but it would make the code ++ * much more complicated and fragile, since all skb then would have to ++ * contain only pages with the same value in this field. ++ */ ++ void *net_priv; ++#endif ++ + }; + + /* +diff -upkr linux-2.6.29/include/linux/net.h linux-2.6.29/include/linux/net.h +--- linux-2.6.29/include/linux/net.h 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/include/linux/net.h 2009-03-25 12:13:18.000000000 +0300 +@@ -57,6 +57,7 @@ typedef enum { + #include + #include + #include /* For O_CLOEXEC and O_NONBLOCK */ ++#include + + struct poll_table_struct; + struct pipe_inode_info; +@@ -352,5 +353,44 @@ static const struct proto_ops name##_ops + extern struct ratelimit_state net_ratelimit_state; + #endif + ++#if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) ++/* Support for notification on zero-copy TCP transfer completion */ ++typedef void (*net_get_page_callback_t)(struct page *page); ++typedef void (*net_put_page_callback_t)(struct page *page); ++ ++extern net_get_page_callback_t net_get_page_callback; ++extern net_put_page_callback_t net_put_page_callback; ++ ++extern int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback); ++ ++/* ++ * See comment for net_set_get_put_page_callbacks() why those functions ++ * don't need any protection. ++ */ ++static inline void net_get_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_get_page_callback(page); ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ if (page->net_priv != 0) ++ net_put_page_callback(page); ++ put_page(page); ++} ++#else ++static inline void net_get_page(struct page *page) ++{ ++ get_page(page); ++} ++static inline void net_put_page(struct page *page) ++{ ++ put_page(page); ++} ++#endif /* CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION */ ++ + #endif /* __KERNEL__ */ + #endif /* _LINUX_NET_H */ +diff -upkr linux-2.6.29/net/core/skbuff.c linux-2.6.29/net/core/skbuff.c +--- linux-2.6.29/net/core/skbuff.c 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/core/skbuff.c 2009-03-25 13:57:33.000000000 +0300 +@@ -73,13 +73,13 @@ static struct kmem_cache *skbuff_fclone_ + static void sock_pipe_buf_release(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) + { +- put_page(buf->page); ++ net_put_page(buf->page); + } + + static void sock_pipe_buf_get(struct pipe_inode_info *pipe, + struct pipe_buffer *buf) + { +- get_page(buf->page); ++ net_get_page(buf->page); + } + + static int sock_pipe_buf_steal(struct pipe_inode_info *pipe, +@@ -327,7 +327,7 @@ static void skb_release_data(struct sk_b + if (skb_shinfo(skb)->nr_frags) { + int i; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + } + + if (skb_shinfo(skb)->frag_list) +@@ -716,7 +716,7 @@ struct sk_buff *pskb_copy(struct sk_buff + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i]; +- get_page(skb_shinfo(n)->frags[i].page); ++ net_get_page(skb_shinfo(n)->frags[i].page); + } + skb_shinfo(n)->nr_frags = i; + } +@@ -781,7 +781,7 @@ int pskb_expand_head(struct sk_buff *skb + sizeof(struct skb_shared_info)); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_clone_fraglist(skb); +@@ -1050,7 +1050,7 @@ drop_pages: + skb_shinfo(skb)->nr_frags = i; + + for (; i < nfrags; i++) +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + + if (skb_shinfo(skb)->frag_list) + skb_drop_fraglist(skb); +@@ -1219,7 +1219,7 @@ pull_pages: + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +@@ -1322,7 +1322,7 @@ fault: + */ + static void sock_spd_release(struct splice_pipe_desc *spd, unsigned int i) + { +- put_page(spd->pages[i]); ++ net_put_page(spd->pages[i]); + } + + static inline struct page *linear_to_page(struct page *page, unsigned int len, +@@ -1352,7 +1352,7 @@ static inline int spd_fill_page(struct s + if (!page) + return 1; + } else +- get_page(page); ++ net_get_page(page); + + spd->pages[spd->nr_pages] = page; + spd->partial[spd->nr_pages].len = len; +@@ -1977,7 +1977,7 @@ static inline void skb_split_no_header(s + * where splitting is expensive. + * 2. Split is accurately. We make this. + */ +- get_page(skb_shinfo(skb)->frags[i].page); ++ net_get_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb1)->frags[0].page_offset += len - pos; + skb_shinfo(skb1)->frags[0].size -= len - pos; + skb_shinfo(skb)->frags[i].size = len - pos; +@@ -2098,7 +2098,7 @@ int skb_shift(struct sk_buff *tgt, struc + to++; + + } else { +- get_page(fragfrom->page); ++ net_get_page(fragfrom->page); + fragto->page = fragfrom->page; + fragto->page_offset = fragfrom->page_offset; + fragto->size = todo; +@@ -2120,7 +2120,7 @@ int skb_shift(struct sk_buff *tgt, struc + fragto = &skb_shinfo(tgt)->frags[merge]; + + fragto->size += fragfrom->size; +- put_page(fragfrom->page); ++ net_put_page(fragfrom->page); + } + + /* Reposition in the original skb */ +@@ -2514,7 +2514,7 @@ struct sk_buff *skb_segment(struct sk_bu + + while (pos < offset + len && i < nfrags) { + *frag = skb_shinfo(skb)->frags[i]; +- get_page(frag->page); ++ net_get_page(frag->page); + size = frag->size; + + if (pos < offset) { +diff -upkr linux-2.6.29/net/ipv4/ip_output.c linux-2.6.29/net/ipv4/ip_output.c +--- linux-2.6.29/net/ipv4/ip_output.c 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/ipv4/ip_output.c 2009-03-25 12:13:18.000000000 +0300 +@@ -1013,7 +1013,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +@@ -1171,7 +1171,7 @@ ssize_t ip_append_page(struct sock *sk, + if (skb_can_coalesce(skb, i, page, offset)) { + skb_shinfo(skb)->frags[i-1].size += len; + } else if (i < MAX_SKB_FRAGS) { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, len); + } else { + err = -EMSGSIZE; +diff -upkr linux-2.6.29/net/ipv4/Makefile linux-2.6.29/net/ipv4/Makefile +--- linux-2.6.29/net/ipv4/Makefile 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/ipv4/Makefile 2009-03-25 12:13:18.000000000 +0300 +@@ -49,6 +49,7 @@ obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o + obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o + obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o + obj-$(CONFIG_NETLABEL) += cipso_ipv4.o ++obj-$(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) += tcp_zero_copy.o + + obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \ + xfrm4_output.o +diff -upkr linux-2.6.29/net/ipv4/tcp.c linux-2.6.29/net/ipv4/tcp.c +--- linux-2.6.29/net/ipv4/tcp.c 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/ipv4/tcp.c 2009-03-25 12:13:18.000000000 +0300 +@@ -720,7 +720,7 @@ new_segment: + if (can_coalesce) { + skb_shinfo(skb)->frags[i - 1].size += copy; + } else { +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, offset, copy); + } + +@@ -925,7 +925,7 @@ new_segment: + goto new_segment; + } else if (page) { + if (off == PAGE_SIZE) { +- put_page(page); ++ net_put_page(page); + TCP_PAGE(sk) = page = NULL; + off = 0; + } +@@ -966,9 +966,9 @@ new_segment: + } else { + skb_fill_page_desc(skb, i, page, off, copy); + if (TCP_PAGE(sk)) { +- get_page(page); ++ net_get_page(page); + } else if (off + copy < PAGE_SIZE) { +- get_page(page); ++ net_get_page(page); + TCP_PAGE(sk) = page; + } + } +diff -upkr linux-2.6.29/net/ipv4/tcp_output.c linux-2.6.29/net/ipv4/tcp_output.c +--- linux-2.6.29/net/ipv4/tcp_output.c 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/ipv4/tcp_output.c 2009-03-25 12:13:18.000000000 +0300 +@@ -871,7 +871,7 @@ static void __pskb_trim_head(struct sk_b + k = 0; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + if (skb_shinfo(skb)->frags[i].size <= eat) { +- put_page(skb_shinfo(skb)->frags[i].page); ++ net_put_page(skb_shinfo(skb)->frags[i].page); + eat -= skb_shinfo(skb)->frags[i].size; + } else { + skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i]; +diff -upkr linux-2.6.29/net/ipv4/tcp_zero_copy.c linux-2.6.29/net/ipv4/tcp_zero_copy.c +--- linux-2.6.29/net/ipv4/tcp_zero_copy.c 2009-03-25 14:03:29.000000000 +0300 ++++ linux-2.6.29/net/ipv4/tcp_zero_copy.c 2009-03-25 12:13:18.000000000 +0300 +@@ -0,0 +1,49 @@ ++/* ++ * Support routines for TCP zero copy transmit ++ * ++ * Created by Vladislav Bolkhovitin ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ */ ++ ++#include ++ ++net_get_page_callback_t net_get_page_callback __read_mostly; ++EXPORT_SYMBOL(net_get_page_callback); ++ ++net_put_page_callback_t net_put_page_callback __read_mostly; ++EXPORT_SYMBOL(net_put_page_callback); ++ ++/* ++ * Caller of this function must ensure that at the moment when it's called ++ * there are no pages in the system with net_priv field set to non-zero ++ * value. Hence, this function, as well as net_get_page() and net_put_page(), ++ * don't need any protection. ++ */ ++int net_set_get_put_page_callbacks( ++ net_get_page_callback_t get_callback, ++ net_put_page_callback_t put_callback) ++{ ++ int res = 0; ++ ++ if ((net_get_page_callback != NULL) && (get_callback != NULL) && ++ (net_get_page_callback != get_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ if ((net_put_page_callback != NULL) && (put_callback != NULL) && ++ (net_put_page_callback != put_callback)) { ++ res = -EBUSY; ++ goto out; ++ } ++ ++ net_get_page_callback = get_callback; ++ net_put_page_callback = put_callback; ++ ++out: ++ return res; ++} ++EXPORT_SYMBOL(net_set_get_put_page_callbacks); +diff -upkr linux-2.6.29/net/ipv6/ip6_output.c linux-2.6.29/net/ipv6/ip6_output.c +--- linux-2.6.29/net/ipv6/ip6_output.c 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/ipv6/ip6_output.c 2009-03-25 12:13:18.000000000 +0300 +@@ -1394,7 +1394,7 @@ alloc_new_skb: + err = -EMSGSIZE; + goto error; + } +- get_page(page); ++ net_get_page(page); + skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0); + frag = &skb_shinfo(skb)->frags[i]; + } +diff -upkr linux-2.6.29/net/Kconfig linux-2.6.29/net/Kconfig +--- linux-2.6.29/net/Kconfig 2009-03-24 02:12:14.000000000 +0300 ++++ linux-2.6.29/net/Kconfig 2009-03-25 12:13:18.000000000 +0300 +@@ -54,6 +54,18 @@ config INET + + Short answer: say Y. + ++config TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION ++ bool "TCP/IP zero-copy transfer completion notification" ++ depends on INET ++ default SCST_ISCSI ++ ---help--- ++ Adds support for sending a notification upon completion of a ++ zero-copy TCP/IP transfer. This can speed up certain TCP/IP ++ software. Currently this is only used by the iSCSI target driver ++ iSCSI-SCST. ++ ++ If unsure, say N. ++ + if INET + source "net/ipv4/Kconfig" + source "net/ipv6/Kconfig" diff --git a/iscsi-scst/kernel/session.c b/iscsi-scst/kernel/session.c index 39fba5f0d..39e05c618 100644 --- a/iscsi-scst/kernel/session.c +++ b/iscsi-scst/kernel/session.c @@ -286,7 +286,7 @@ static int iscsi_session_seq_open(struct inode *inode, struct file *file) return res; } -struct file_operations session_seq_fops = { +const struct file_operations session_seq_fops = { .owner = THIS_MODULE, .open = iscsi_session_seq_open, .read = seq_read, diff --git a/iscsi-scst/kernel/target.c b/iscsi-scst/kernel/target.c index a6d8dd362..eaa9e426f 100644 --- a/iscsi-scst/kernel/target.c +++ b/iscsi-scst/kernel/target.c @@ -330,7 +330,7 @@ static int iscsi_seq_show(struct seq_file *m, void *p) return 0; } -struct seq_operations iscsi_seq_op = { +const struct seq_operations iscsi_seq_op = { .start = iscsi_seq_start, .next = iscsi_seq_next, .stop = iscsi_seq_stop, diff --git a/scst/include/scst.h b/scst/include/scst.h index f5c7386de..5af7f4555 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -2755,7 +2755,7 @@ int scst_proc_log_entry_write(struct file *file, const char __user *buf, * helper data structure and function to create proc entry. */ struct scst_proc_data { - struct file_operations seq_op; + const struct file_operations seq_op; int (*show)(struct seq_file *, void *); void *data; }; diff --git a/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.18.patch b/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.18.patch new file mode 100644 index 000000000..f6ed08886 --- /dev/null +++ b/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.18.patch @@ -0,0 +1,12 @@ +diff -uprN ../orig/linux-2.6.24/drivers/Kconfig linux-2.6.24/drivers/Kconfig +--- ../orig/linux-2.6.24/drivers/Kconfig 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/Kconfig 2008-05-13 13:05:55.000000000 +0200 +@@ -18,6 +18,8 @@ + + source "drivers/scsi/Kconfig" + ++source "drivers/scst/Kconfig" ++ + source "drivers/cdrom/Kconfig" + + source "drivers/md/Kconfig" diff --git a/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.29.patch b/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.29.patch new file mode 100644 index 000000000..81fc97ea1 --- /dev/null +++ b/scst/kernel/in-tree/Kconfig.drivers.Linux-2.6.29.patch @@ -0,0 +1,12 @@ +diff -upkr -X linux-2.6.29/Documentation/dontdiff linux-2.6.29/drivers/Kconfig linux-2.6.29/drivers/Kconfig +--- linux-2.6.29/drivers/Kconfig 2008-07-14 01:51:29.000000000 +0400 ++++ linux-2.6.29/drivers/Kconfig 2008-07-24 14:14:46.000000000 +0400 +@@ -24,6 +24,8 @@ source "drivers/ide/Kconfig" + + source "drivers/scsi/Kconfig" + ++source "drivers/scst/Kconfig" ++ + source "drivers/ata/Kconfig" + + source "drivers/md/Kconfig" diff --git a/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.18.patch b/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.18.patch new file mode 100644 index 000000000..12015a9de --- /dev/null +++ b/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.18.patch @@ -0,0 +1,11 @@ +diff -uprN ../orig/linux-2.6.24/drivers/Makefile linux-2.6.24/drivers/Makefile +--- ../orig/linux-2.6.24/drivers/Makefile 2008-01-24 23:58:37.000000000 +0100 ++++ linux-2.6.24/drivers/Makefile 2008-05-13 13:06:34.000000000 +0200 +@@ -34,6 +34,7 @@ + obj-$(CONFIG_IDE) += ide/ + obj-$(CONFIG_FC4) += fc4/ + obj-$(CONFIG_SCSI) += scsi/ ++obj-$(CONFIG_SCST) += scst/ + obj-$(CONFIG_FUSION) += message/ + obj-$(CONFIG_IEEE1394) += ieee1394/ + obj-y += cdrom/ diff --git a/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.29.patch b/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.29.patch new file mode 100644 index 000000000..eb2defed4 --- /dev/null +++ b/scst/kernel/in-tree/Makefile.drivers.Linux-2.6.29.patch @@ -0,0 +1,11 @@ +diff -upkr -X linux-2.6.29/Documentation/dontdiff linux-2.6.29/drivers/Makefile linux-2.6.29/drivers/Makefile +--- linux-2.6.29/drivers/Makefile 2008-07-14 01:51:29.000000000 +0400 ++++ linux-2.6.29/drivers/Makefile 2008-07-24 14:15:29.000000000 +0400 +@@ -42,6 +42,7 @@ obj-$(CONFIG_ATM) += atm/ + obj-y += macintosh/ + obj-$(CONFIG_IDE) += ide/ + obj-$(CONFIG_SCSI) += scsi/ ++obj-$(CONFIG_SCST) += scst/ + obj-$(CONFIG_ATA) += ata/ + obj-$(CONFIG_FUSION) += message/ + obj-$(CONFIG_FIREWIRE) += firewire/ diff --git a/scst/kernel/io_context-2.6.29.patch b/scst/kernel/io_context-2.6.29.patch new file mode 100644 index 000000000..830b7fba4 --- /dev/null +++ b/scst/kernel/io_context-2.6.29.patch @@ -0,0 +1,61 @@ +diff -upkr linux-2.6.29/block/blk-ioc.c linux-2.6.29/block/blk-ioc.c +--- linux-2.6.29/block/blk-ioc.c 2008-12-25 02:26:37.000000000 +0300 ++++ linux-2.6.29/block/blk-ioc.c 2009-03-23 14:28:48.000000000 +0300 +@@ -65,6 +65,21 @@ static void cfq_exit(struct io_context * + rcu_read_unlock(); + } + ++void __exit_io_context(struct io_context *ioc) ++{ ++ if (ioc == NULL) ++ return; ++ ++ if (atomic_dec_and_test(&ioc->nr_tasks)) { ++ if (ioc->aic && ioc->aic->exit) ++ ioc->aic->exit(ioc->aic); ++ cfq_exit(ioc); ++ ++ put_io_context(ioc); ++ } ++} ++EXPORT_SYMBOL(__exit_io_context); ++ + /* Called by the exitting task */ + void exit_io_context(void) + { +@@ -75,13 +90,7 @@ void exit_io_context(void) + current->io_context = NULL; + task_unlock(current); + +- if (atomic_dec_and_test(&ioc->nr_tasks)) { +- if (ioc->aic && ioc->aic->exit) +- ioc->aic->exit(ioc->aic); +- cfq_exit(ioc); +- +- put_io_context(ioc); +- } ++ __exit_io_context(ioc); + } + + struct io_context *alloc_io_context(gfp_t gfp_flags, int node) +@@ -105,6 +114,7 @@ struct io_context *alloc_io_context(gfp_ + + return ret; + } ++EXPORT_SYMBOL(alloc_io_context); + + /* + * If the current task has no IO context then create one and initialise it. +diff -upkr linux-2.6.29/include/linux/iocontext.h linux-2.6.29/include/linux/iocontext.h +--- linux-2.6.29/include/linux/iocontext.h 2008-12-25 02:26:37.000000000 +0300 ++++ linux-2.6.29/include/linux/iocontext.h 2009-03-23 14:05:01.000000000 +0300 +@@ -103,7 +103,9 @@ static inline struct io_context *ioc_tas + int put_io_context(struct io_context *ioc); + void exit_io_context(void); + struct io_context *get_io_context(gfp_t gfp_flags, int node); ++#define SCST_IO_CONTEXT + struct io_context *alloc_io_context(gfp_t gfp_flags, int node); ++void __exit_io_context(struct io_context *ioc); + void copy_io_context(struct io_context **pdst, struct io_context **psrc); + #else + static inline void exit_io_context(void) diff --git a/scst/kernel/scst_exec_req_fifo-2.6.29.patch b/scst/kernel/scst_exec_req_fifo-2.6.29.patch new file mode 100644 index 000000000..ceb771e22 --- /dev/null +++ b/scst/kernel/scst_exec_req_fifo-2.6.29.patch @@ -0,0 +1,112 @@ +diff -upr linux-2.6.29/drivers/scsi/scsi_lib.c linux-2.6.29/drivers/scsi/scsi_lib.c +--- linux-2.6.29/drivers/scsi/scsi_lib.c 2008-07-14 01:51:29.000000000 +0400 ++++ linux-2.6.29/drivers/scsi/scsi_lib.c 2008-07-31 21:20:00.000000000 +0400 +@@ -402,7 +402,7 @@ free_bios: + } + + /** +- * scsi_execute_async - insert request ++ * __scsi_execute_async - insert request + * @sdev: scsi device + * @cmd: scsi command + * @cmd_len: length of scsi cdb +@@ -415,11 +415,14 @@ free_bios: + * @privdata: data passed to done() + * @done: callback function when done + * @gfp: memory allocation flags ++ * @at_head: insert request at head or tail of queue + */ +-int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++static inline int __scsi_execute_async(struct scsi_device *sdev, ++ const unsigned char *cmd, + int cmd_len, int data_direction, void *buffer, unsigned bufflen, + int use_sg, int timeout, int retries, void *privdata, +- void (*done)(void *, char *, int, int), gfp_t gfp) ++ void (*done)(void *, char *, int, int), gfp_t gfp, ++ int at_head) + { + struct request *req; + struct scsi_io_context *sioc; +@@ -456,7 +461,7 @@ int scsi_execute_async(struct scsi_devic + sioc->data = privdata; + sioc->done = done; + +- blk_execute_rq_nowait(req->q, NULL, req, 1, scsi_end_async); ++ blk_execute_rq_nowait(req->q, NULL, req, at_head, scsi_end_async); + return 0; + + free_req: +@@ -465,8 +468,55 @@ free_sense: + kmem_cache_free(scsi_io_context_cache, sioc); + return DRIVER_ERROR << 24; + } ++ ++/** ++ * scsi_execute_async - insert request ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, ++ unsigned bufflen, int use_sg, int timeout, ++ int retries, void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 1); ++} + EXPORT_SYMBOL_GPL(scsi_execute_async); + ++/** ++ * scsi_execute_async_fifo - insert request at tail, in FIFO order ++ * @sdev: scsi device ++ * @cmd: scsi command ++ * @cmd_len: length of scsi cdb ++ * @data_direction: data direction ++ * @buffer: data buffer (this can be a kernel buffer or scatterlist) ++ * @bufflen: len of buffer ++ * @use_sg: if buffer is a scatterlist this is the number of elements ++ * @timeout: request timeout in seconds ++ * @retries: number of times to retry request ++ * @flags: or into request flags ++ **/ ++int scsi_execute_async_fifo(struct scsi_device *sdev, const unsigned char *cmd, ++ int cmd_len, int data_direction, void *buffer, ++ unsigned bufflen, int use_sg, int timeout, int retries, ++ void *privdata, ++ void (*done)(void *, char *, int, int), gfp_t gfp) ++{ ++ return __scsi_execute_async(sdev, cmd, cmd_len, data_direction, buffer, ++ bufflen, use_sg, timeout, retries, privdata, done, gfp, 0); ++} ++EXPORT_SYMBOL_GPL(scsi_execute_async_fifo); ++ + /* + * Function: scsi_init_cmd_errh() + * +diff -upr linux-2.6.29/include/scsi/scsi_device.h linux-2.6.29/include/scsi/scsi_device.h +--- linux-2.6.29/include/scsi/scsi_device.h 2008-07-14 01:51:29.000000000 +0400 ++++ linux-2.6.29/include/scsi/scsi_device.h 2008-07-31 21:20:39.000000000 +0400 +@@ -376,6 +376,14 @@ extern int scsi_execute_async(struct scs + int timeout, int retries, void *privdata, + void (*done)(void *, char *, int, int), + gfp_t gfp); ++#define SCSI_EXEC_REQ_FIFO_DEFINED ++extern int scsi_execute_async_fifo(struct scsi_device *sdev, ++ const unsigned char *cmd, int cmd_len, ++ int data_direction, void *buffer, ++ unsigned bufflen, int use_sg, ++ int timeout, int retries, void *privdata, ++ void (*done)(void *, char *, int, int), ++ gfp_t gfp); + + static inline int __must_check scsi_device_reprobe(struct scsi_device *sdev) + { diff --git a/scst/src/dev_handlers/scst_cdrom.c b/scst/src/dev_handlers/scst_cdrom.c index cc5e2a58a..460ee9ce5 100644 --- a/scst/src/dev_handlers/scst_cdrom.c +++ b/scst/src/dev_handlers/scst_cdrom.c @@ -109,7 +109,11 @@ static int cdrom_attach(struct scst_device *dev) TRACE_DBG("%s", "Doing READ_CAPACITY"); res = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, - SCST_GENERIC_CDROM_REG_TIMEOUT, 3, 0); + SCST_GENERIC_CDROM_REG_TIMEOUT, 3, 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + , NULL +#endif + ); TRACE_DBG("READ_CAPACITY done: %x", res); diff --git a/scst/src/dev_handlers/scst_disk.c b/scst/src/dev_handlers/scst_disk.c index 2257bf673..ddb850c06 100644 --- a/scst/src/dev_handlers/scst_disk.c +++ b/scst/src/dev_handlers/scst_disk.c @@ -185,7 +185,11 @@ static int disk_attach(struct scst_device *dev) TRACE_DBG("%s", "Doing READ_CAPACITY"); res = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, - SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0); + SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + , NULL +#endif + ); TRACE_DBG("READ_CAPACITY done: %x", res); diff --git a/scst/src/dev_handlers/scst_modisk.c b/scst/src/dev_handlers/scst_modisk.c index 793743b91..1a45eba02 100644 --- a/scst/src/dev_handlers/scst_modisk.c +++ b/scst/src/dev_handlers/scst_modisk.c @@ -199,7 +199,11 @@ static int modisk_attach(struct scst_device *dev) TRACE_DBG("%s", "Doing READ_CAPACITY"); res = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer, buffer_size, sense_buffer, - SCST_GENERIC_MODISK_REG_TIMEOUT, 3, 0); + SCST_GENERIC_MODISK_REG_TIMEOUT, 3, 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + , NULL +#endif + ); TRACE_DBG("READ_CAPACITY done: %x", res); diff --git a/scst/src/dev_handlers/scst_user.c b/scst/src/dev_handlers/scst_user.c index 842c14ccf..601f363e9 100644 --- a/scst/src/dev_handlers/scst_user.c +++ b/scst/src/dev_handlers/scst_user.c @@ -205,7 +205,7 @@ static struct kmem_cache *user_get_cmd_cachep; static DEFINE_MUTEX(dev_priv_mutex); -static struct file_operations dev_user_fops = { +static const struct file_operations dev_user_fops = { .poll = dev_user_poll, .unlocked_ioctl = dev_user_ioctl, #ifdef CONFIG_COMPAT diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 6cd562ff6..b99aaa9ff 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -3267,7 +3267,7 @@ static int vcdrom_change(char *p, char *name) { loff_t err; struct scst_vdisk_dev *virt_dev, *vv; - char *file_name, *fn, *old_fn; + char *file_name, *fn = NULL, *old_fn; int len; int res = 0; diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 51c405344..6d8a1c1bb 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1664,7 +1664,11 @@ static void scst_send_release(struct scst_device *dev) TRACE(TRACE_DEBUG | TRACE_SCSI, "%s", "Sending RELEASE req to " "SCSI mid-level"); rc = scsi_execute(scsi_dev, cdb, SCST_DATA_NONE, NULL, 0, - sense, 15, 0, 0); + sense, 15, 0, 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + , NULL +#endif + ); TRACE_DBG("MODE_SENSE done: %x", rc); if (scsi_status_is_good(rc)) { @@ -3093,7 +3097,11 @@ int scst_obtain_device_parameters(struct scst_device *dev) TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE"); res = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer, - sizeof(buffer), sense_buffer, 15, 0, 0); + sizeof(buffer), sense_buffer, 15, 0, 0 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29) + , NULL +#endif + ); TRACE_DBG("MODE_SENSE done: %x", res); @@ -3139,14 +3147,14 @@ int scst_obtain_device_parameters(struct scst_device *dev) } else { #if 0 if ((status_byte(res) == CHECK_CONDITION) && + SCST_SENSE_VALID(sense_buffer)) { #else /* * 3ware controller is buggy and returns CONDITION_GOOD * instead of CHECK_CONDITION */ - if ( + if (SCST_SENSE_VALID(sense_buffer)) { #endif - SCST_SENSE_VALID(sense_buffer)) { if (scst_analyze_sense(sense_buffer, sizeof(sense_buffer), SCST_SENSE_KEY_VALID,