#!/bin/bash ############################################################################ # # Script for converting the SCST source tree as it exists in the Subversion # repository to a Linux kernel patch. # # Copyright (C) 2008-2009 Bart Van Assche # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation, version 2 # of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ############################################################################ ######################## # Function definitions # ######################## source $(dirname $0)/kernel-functions function usage { echo "Usage: $0 [-d] [-h] [-m] [-n] [-p ] [-s] [-u] " echo "where: " echo " -d - enable patch specialization debugging" echo " -h - show this text" echo " -m - add mpt target driver" echo " -n - do not delete code disabled via preprocessor statements" echo " -p - generate multiple patches instead of one big patch into"\ "the specified directory." echo " -s - disable patch specialization." echo " -u - enables #define GENERATING_UPSTREAM_PATCH." } # Convert an existing patch. # $1: path of patch to be added. # $2: path in kernel tree of file to be patched. function add_patch { if [ ! -e "$1" ]; then echo "Error: could not find $1." >&2 exit 1 fi sed -e "s:^--- [^ ]*:--- orig/linux-${kver}/$2:" \ -e "s:^+++ [^ ]*:+++ linux-${kver}/$2:" \ < "$1" } # Generate a patch for a file to be added to the kernel source tree, and strip # trailing whitespace from C source files while converting the file to patch # format. # $1: path of file to be added. # $2: path in kernel tree where file should be added. function add_file { local a b if [ ! -e "$1" ]; then echo "Error: could not find $1." >&2 exit 1 fi # Only include files that were not generated by the build process # -- skip *.mod.c. if [ "$1" = "${1%.mod.c}" -a "$1" ]; then cat <"${tmppatch}" touch "${tmppatch}" { if [ -e /usr/bin/diffstat ]; then awk 'BEGIN{h=1}/^diff/{h=0}/^---/{h=0}h!=0{print}' < "${tmppatch}" echo "---" diffstat "${tmppatch}" echo "" awk 'BEGIN{h=1}/^diff/{h=0}/^---/{h=0}h==0{print}' < "${tmppatch}" fi } \ > "${patchdir}/$(basename $1)" rm -f "${tmppatch}" else # echo "Discarded $(wc -l) lines." true fi else specialize_patch fi } # Returns 0 (true) if SCST core file "$1" should be added in a separate patch, # and 1 (false) if not. function in_separate_patch { echo "${source_files_in_separate_patch}" | grep -qE "^$1 | $1 | $1\$|^$1\$" } ######################### # Argument verification # ######################### debug_specialize="false" enable_specialize="true" generating_upstream_patch="false" mpt_scst="false" multiple_patches="false" patchdir="" qla2x00t="true" replace_sbug_by_bug="true" specialize_patch_options="-v delete_disabled_code=1" srpt="true" if [ ! -e scst -o ! -e iscsi-scst -o ! -e srpt -o ! -e scst_local ]; then echo "Please run this script from inside the SCST subversion source tree." exit 1 fi set -- $(/usr/bin/getopt dhlmnp:su "$@") while [ "$1" != "${1#-}" ] do case "$1" in '-d') debug_specialize="true"; shift;; '-h') usage; exit 1;; '-l') shift;; '-m') mpt_scst="true"; shift;; '-n') specialize_patch_options="-v blank_deleted_code=1" shift ;; '-p') multiple_patches="true"; patchdir="$2"; shift; shift;; '-s') enable_specialize="false"; shift;; '-u') generating_upstream_patch="true"; shift;; '--') shift;; *) usage; exit 1;; esac done if [ $# != 1 ]; then usage exit 1 fi # Strip patch level from the kernel version number. kver="$(kernel_version "$1")" # kver3: first three components of the version number. if [ "${1#2.}" != "$1" ]; then kver3="$kver" else kver3="$1" fi # Include fcst in the patch for kernel versions 2.6.33 and later. if [ "${kver}" ">" "2.6.32" ]; then include_fcst="true" else include_fcst="false" fi # Make sure that for kernel 2.6.26 and later the line # "#define CONFIG_SCST_PROC" is removed from scst/include/scst.h. if grep -qw scst_sysfs scst/kernel/in-tree/Makefile.scst-${kver} \ || [ "${generating_upstream_patch}" = "true" ]; then specialize_patch_options="${specialize_patch_options} -v config_scst_proc_undefined=1" else include_proc_impl="true" fi if [ "${debug_specialize}" = "true" ]; then specialize_patch_options="${specialize_patch_options} -v debug=1" fi if [ "${generating_upstream_patch}" = "true" ]; then specialize_patch_options="${specialize_patch_options} -v generating_upstream_patch_defined=1 -v config_tcp_zero_copy_transfer_completion_notification_undefined=1" fi if [ "${multiple_patches}" = "true" ]; then if [ -e "${patchdir}" ]; then echo "Patch output directory ${patchdir} already exists." fi mkdir -p "${patchdir}" if [ ! -d "${patchdir}" ]; then echo "Error: ${patchdir} is not a directory." fi fi #################### # Patch Generation # #################### for f in fcst/linux-patches/series-${kver}* do if [ -e "$f" ]; then fcst_patch_series="$f" fi done # General kernel patches. scsi_exec_req_fifo_defined=0 scst_io_context=0 for p in scst/kernel/*-${kver}.patch \ $(if [ "${1#3.2.}" != "$1" ] && [ "${1#3.2.}" -ge 57 ]; then echo iscsi-scst/kernel/patches/*-3.2.57.patch; elif [ "${1#3.7.}" != "$1" ] && [ "${1#3.7.}" -ge 10 ]; then echo iscsi-scst/kernel/patches/*-3.7.10.patch; elif [ "${1#3.10.}" != "$1" ] && [ "${1#3.10.}" -ge 30 ]; then echo iscsi-scst/kernel/patches/*-3.10.30.patch; elif [ "${1#3.12.}" != "$1" ] && [ "${1#3.12.}" -ge 11 ]; then echo iscsi-scst/kernel/patches/*-3.12.11.patch; elif [ "${1#3.13.}" != "$1" ] && [ "${1#3.13.}" -ge 3 ]; then echo iscsi-scst/kernel/patches/*-3.13.3.patch; else echo iscsi-scst/kernel/patches/*-${kver}.patch; fi) do # Exclude the put_page_callback patch when command-line option -u has been # specified since the current approach is not considered acceptable for # upstream kernel inclusion. See also http://lkml.org/lkml/2008/12/11/213. if [ "${generating_upstream_patch}" = "false" \ -o "${p#iscsi-scst/kernel/patches/put_page_callback}" = "$p" ] then if grep -q '^\+#define SCSI_EXEC_REQ_FIFO_DEFINED$' "${p}"; then scsi_exec_req_fifo_defined=1 fi if grep -q '^\+#define SCST_IO_CONTEXT$' "${p}"; then scst_io_context=1 fi diffname="${p#scst/kernel/}" diffname="${p%-${kver}.patch}.diff" process_patch < "$p" "${diffname}" fi done scst_03_public_headers="scst/include/scst.h scst/include/scst_const.h" scst_04_main="scst/src/scst_main.c scst/src/scst_module.c scst/src/scst_priv.h" scst_05_targ="scst/src/scst_targ.c" scst_06_lib="scst/src/scst_lib.c" scst_07_pres="scst/src/scst_pres.h scst/src/scst_pres.c" scst_08_sysfs="scst/src/scst_sysfs.c" scst_09_debug="scst/include/scst_debug.h scst/src/scst_debug.c" scst_proc="scst/src/scst_proc.c" scst_10_sgv="scst/include/scst_sgv.h scst/src/scst_mem.h scst/src/scst_mem.c doc/sgv_cache.sgml" scst_user="scst/include/scst_user.h scst/src/dev_handlers/scst_user.c" scst_13_vdisk="scst/src/dev_handlers/scst_vdisk.c" scst_14_tg="scst/src/scst_tg.c" separate_patches="scst_03_public_headers scst_04_main scst_05_targ scst_06_lib scst_07_pres scst_08_sysfs scst_09_debug scst_10_sgv scst_user scst_13_vdisk scst_14_tg" if [ "$include_proc_impl" = "true" ]; then separate_patches+=" scst_proc" fi source_files_in_separate_patch="" for s in ${separate_patches} do source_files_in_separate_patch+=" $(set | \ sed -n -e "s/^$s='\(.*\)'$/\1/p" -e "s/^$s=\(.*\)$/\1/p")" done # Directory drivers/ ( add_patch "scst/kernel/in-tree/Kconfig.drivers.Linux-${kver}.patch" \ "drivers/Kconfig" add_patch "scst/kernel/in-tree/Makefile.drivers.Linux-${kver}.patch"\ "drivers/Makefile" ) \ | process_patch "scst_01_drivers_kbuild.diff" # Directory drivers/scst/ ( tmpdir="/tmp/scst-$$" mkdir -p "${tmpdir}" tmp_Kconfig="${tmpdir}/Kconfig.scst-${kver}" cat "scst/kernel/in-tree/Kconfig.scst" | \ if [ "${include_fcst}" ]; then cat else grep -v '^source "drivers/scst/fcst/Kconfig"$' fi >"${tmp_Kconfig}" add_file "${tmp_Kconfig}" "drivers/scst/Kconfig" tmp_Makefile="${tmpdir}/Makefile.scst-${kver}" cat "scst/kernel/in-tree/Makefile.scst-${kver}" | \ if [ "$include_proc_impl" != "true" ]; then grep -v 'scst_proc' else cat fi | \ if [ "${include_fcst}" -a "${kver}" != "2.6.37" -a "${kver}" != "2.6.38" ]; then cat else sed -e 's: fcst/* : :' fi >"$tmp_Makefile" add_file "$tmp_Makefile" "drivers/scst/Makefile" rm -rf "${tmpdir}" ) \ | process_patch "scst_02_scst_kbuild.diff" for s in ${separate_patches} do { fileset=$s for f in $(set | grep "^$s=" | sed -e "s/^$s='\(.*\)'\$/\1/" -e "s/^$s=\(.*\)\$/\1/") do if [ "${f#scst/include}" != "${f}" ]; then add_file "${f}" "include/scst/${f#scst/include/}" elif [ "${f#doc}" != "${f}" ]; then add_file "${f}" "Documentation/scst/${f#doc/}" else add_file "${f}" "drivers/scst/${f#scst/src/}" fi done if [ "$s" = "scst_03_public_headers" ]; then tmp_itf_ver="$(mktemp /tmp/scst-itf-ver.h.XXXXXXXXXX)" cat <<"EOF" >$tmp_itf_ver /* Autogenerated, don't edit */ #define SCST_INTF_VER "SCST_INTF_VER" #define SCST_CONST_INTF_VER "SCST_CONST_INTF_VER" #define DEV_USER_INTF_VER "DEV_USER_INTF_VER" EOF add_file "$tmp_itf_ver" "include/scst/scst_itf_ver.h" rm -f "$tmp_itf_ver" fi } | process_patch "${s}.diff" done { add_file "scst/README_in-tree" "Documentation/scst/README.scst" add_file "scst/SysfsRules" "Documentation/scst/SysfsRules" } | process_patch "scst_11_core_doc.diff" # Directory drivers/scst/dev_handlers/ add_file "scst/kernel/in-tree/Makefile.dev_handlers-${kver}" \ "drivers/scst/dev_handlers/Makefile" \ | process_patch "scst_11_dev_handlers_makefile.diff" for f in $(ls scst/src/dev_handlers/*.[ch] 2>/dev/null) do if ! in_separate_patch "${f}"; then add_file "${f}" "drivers/scst/dev_handlers/${f#scst/src/dev_handlers/}" fi done \ | process_patch "scst_14_passthrough.diff" # Directory drivers/scst/fcst/ { if [ -e "${fcst_patch_series}" ]; then for f in $(grep -v '^#' "${fcst_patch_series}") do cat "fcst/linux-patches/${f}" done fi add_file "fcst/Makefile_in-tree" \ "drivers/scst/fcst/Makefile" add_file "fcst/Kconfig" "drivers/scst/fcst/Kconfig" for f in $(ls fcst/*.[ch] 2>/dev/null) do add_file "${f}" "drivers/scst/fcst/${f#fcst/}" done } \ | process_patch "fcst.diff" add_file "fcst/README" "Documentation/scst/README.fcst" \ | process_patch "fcst-doc.diff" # Directory drivers/scst/iscsi-scst/ # Make sure the file iscsi-scst/iscsi_scst_itf_ver.h is up to date. make -s -C iscsi-scst include/iscsi_scst_itf_ver.h ( for f in $(ls iscsi-scst/include/*h 2>/dev/null) do if [ "${f}" != "iscsi-scst/include/iscsi_scst_itf_ver.h" ]; then add_file "${f}" "include/scst/${f#iscsi-scst/include/}" fi done add_file "iscsi-scst/include/iscsi_scst_itf_ver.h" "include/scst/iscsi_scst_itf_ver.h" add_file "iscsi-scst/kernel/Makefile.in-kernel" \ "drivers/scst/iscsi-scst/Makefile" add_file "iscsi-scst/kernel/Kconfig" "drivers/scst/iscsi-scst/Kconfig" for f in $(ls iscsi-scst/kernel/*.[ch] 2>/dev/null) do add_file "${f}" "drivers/scst/iscsi-scst/${f#iscsi-scst/kernel/}" done ) \ | process_patch "iscsi-scst.diff" add_file "iscsi-scst/README_in-tree" "Documentation/scst/README.iscsi" \ | process_patch "iscsi-scst-doc.diff" # Directory drivers/scst/qla2x00-target/ if [ "${qla2x00t}" = "true" ]; then ( cd qla2x00t && ./generate-in-tree-patches "$1" ) for f in $(ls qla2x00t/in-tree-patches/"$1"/*.patch 2>/dev/null) do g="${f#qla2x00t/in-tree-patches/$1/}" g="${g%.patch}" add_patch "${f}" "drivers/scsi/qla2xxx/${g}" done add_file "qla2x00t/qla2x_tgt.h" \ "drivers/scsi/qla2xxx/qla2x_tgt.h" add_file "qla2x00t/qla2x_tgt_def.h" \ "drivers/scsi/qla2xxx/qla2x_tgt_def.h" add_file "qla2x00t/qla2x00-target/Makefile_in-tree-${kver}" \ "drivers/scst/qla2xxx-target/Makefile" add_file "qla2x00t/qla2x00-target/Kconfig" \ "drivers/scst/qla2xxx-target/Kconfig" for f in $(ls qla2x00t/qla2x00-target/*.[ch] 2>/dev/null) do add_file "${f}" "drivers/scst/qla2xxx-target/${f#qla2x00t/qla2x00-target/}" done add_file "qla2x00t/qla2x00-target/README" \ "Documentation/scst/README.qla2x00t" \ | process_patch "qla2x00t-doc.diff" else add_empty_file "drivers/scst/qla2xxx-target/Makefile" add_empty_file "drivers/scst/qla2xxx-target/Kconfig" fi \ | process_patch "qla2x00t.diff" # Directory drivers/scst/srpt { cat < Cc: Vu Pham Cc: Roland Dreier Cc: David Dillow EOF if [ "$srpt" = "true" ]; then add_file "srpt/README_in-tree" "Documentation/scst/README.srpt" add_file "srpt/src/Kconfig" "drivers/scst/srpt/Kconfig" add_file "srpt/src/Makefile.in_kernel" "drivers/scst/srpt/Makefile" for f in $(ls srpt/src/*.[ch] 2>/dev/null) do add_file "${f}" "drivers/scst/srpt/${f#srpt/src/}" done else add_empty_file "drivers/scst/srpt/Kconfig" add_empty_file "drivers/scst/srpt/Makefile" fi \ } | process_patch "scst_17_srpt.diff" # Directory drivers/message/fusion/mpt_scst if [ "$mpt_scst" = "true" ]; then ( add_patch "mpt/in-tree/Kconfig-2.6.24.diff" "drivers/message/fusion/Kconfig" add_patch "mpt/in-tree/Makefile.diff" "drivers/message/fusion/Makefile" add_file "mpt/in-tree/Makefile" "drivers/message/fusion/mpt_scst/Makefile" add_file "mpt/in-tree/Kconfig" "drivers/message/fusion/mpt_scst/Kconfig" for f in $(ls mpt/*.[ch] 2>/dev/null) do add_file "${f}" "drivers/message/fusion/mpt_scst/${f#mpt/}" done ) \ | process_patch "mpt_scst.diff" fi # Directory drivers/scst/scst_local ( add_file "scst_local/README" "Documentation/scst/README.scst_local" add_file "scst_local/in-tree/Kconfig" "drivers/scst/scst_local/Kconfig" add_file "scst_local/in-tree/Makefile-${kver}" "drivers/scst/scst_local/Makefile" add_file "scst_local/scst_local.c" "drivers/scst/scst_local/scst_local.c" ) \ | process_patch "scst_16_local.diff" # Directory drivers/scsi/ibmvstgt { ( cd ibmvstgt && ./generate-in-tree-patches "${kver}" ) if [ -e "ibmvstgt/in-tree-patches/${kver}" ]; then if [ "${multiple_patches}" = "true" ]; then cat < Cc: Fujita Tomonori Cc: Brian King Cc: Robert Jennings EOF fi for f in \ drivers/scsi/ibmvscsi/ibmvstgt.c \ drivers/scsi/libsrp.c \ include/scsi/libsrp.h \ include/scsi/srp.h do patch="ibmvstgt/in-tree-patches/${kver}/$(basename $f).patch" if [ -e "${patch}" ]; then add_patch "${patch}" $f fi done add_file "ibmvstgt/README.sysfs" "Documentation/powerpc/ibmvstgt.txt" fi } \ | process_patch "scst_18_ibmvstgt.diff" { ( cd ibmvstgt && ./generate-in-tree-patches "${kver}" ) if [ -e "ibmvstgt/in-tree-patches/${kver}" ]; then if [ "${multiple_patches}" = "true" ]; then cat < EOF fi for f in \ arch/arm/configs/at572d940hfek_defconfig \ arch/arm/configs/cam60_defconfig \ arch/arm/configs/s3c2410_defconfig \ arch/m68k/configs/amiga_defconfig \ arch/m68k/configs/apollo_defconfig \ arch/m68k/configs/atari_defconfig \ arch/m68k/configs/bvme6000_defconfig \ arch/m68k/configs/hp300_defconfig \ arch/m68k/configs/mac_defconfig \ arch/m68k/configs/multi_defconfig \ arch/m68k/configs/mvme147_defconfig \ arch/m68k/configs/mvme16x_defconfig \ arch/m68k/configs/q40_defconfig \ arch/m68k/configs/sun3_defconfig \ arch/m68k/configs/sun3x_defconfig \ arch/mips/configs/bcm47xx_defconfig \ arch/mips/configs/decstation_defconfig \ arch/mips/configs/ip22_defconfig \ arch/mips/configs/ip27_defconfig \ arch/mips/configs/ip32_defconfig \ arch/mips/configs/jazz_defconfig \ arch/mips/configs/malta_defconfig \ arch/mips/configs/markeins_defconfig \ arch/mips/configs/pnx8550-jbs_defconfig \ arch/mips/configs/pnx8550-stb810_defconfig \ arch/mips/configs/rm200_defconfig \ arch/mips/configs/tb0226_defconfig \ arch/mips/configs/tb0287_defconfig \ arch/powerpc/configs/52xx/motionpro_defconfig \ arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig \ arch/powerpc/configs/mpc5200_defconfig \ drivers/scsi/Kconfig \ drivers/scsi/Makefile \ drivers/scsi/hosts.c \ drivers/scsi/scsi_sysfs.c \ drivers/scsi/scsi_tgt_if.c \ drivers/scsi/scsi_tgt_lib.c \ drivers/scsi/scsi_tgt_priv.h \ drivers/scsi/scsi_transport_fc.c \ drivers/scsi/scsi_transport_fc_internal.h \ drivers/scsi/scsi_transport_srp.c \ drivers/scsi/scsi_transport_srp_internal.h \ include/scsi/scsi_host.h \ include/scsi/scsi_tgt.h \ include/scsi/scsi_tgt_if.h do add_patch "ibmvstgt/in-tree-patches/${kver}/$(basename $f).patch" $f done fi } \ | process_patch "scst_19_scsi_tgt.diff"