From a5589e099a73e4515b197a3e315b88a734138e06 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Mon, 26 Jan 2009 17:23:46 +0000 Subject: [PATCH] Recently (Subversion revision 633) code was added to scst_vdisk.c that performs a.o. 64-bit division. While gcc supports 64-bit divisions on 32-bit CPU's, gcc generates a function call for these 64-bit divisions (see also http://gcc.gnu.org/onlinedocs/gccint/Integer-library-routines.html for the entire list). Unfortunately there is no implementation available for these functions in the Linux kernel. Which means that loading kernel modules that contain 64-bit divisions on a 32-bit system will fail and that insmod/ modprobe will complain about undefined references to e.g. __umoddi3. AFAIK the proper approach in the Linux kernel is to use the do_div() macro for performing 64-bit divisions. This macro is defined in . The patch below converts the call to div_s64_rem() by a call to do_div(). The patch below has been verified 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.12 -k 2.6.28.1 on a 64-bit system and verified that the output of the re*/sparse* files did not contain any compilation errors. - Verified that the patched SCST source compiles fine on CentOS 5.2, 32-bit. - Verified that the scst_vdisk module loads correctly on CentOS 5.2, 32-bit. Signed-off-by: Bart Van Assche git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@640 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_vdisk.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 847a550fa..803ce5e7d 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -39,21 +39,7 @@ #include #include #include - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) -#include -#else #include -static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder) -{ - unsigned long long d = dividend; - unsigned int dd = divisor, r; - - r = do_div(d, dd); - *remainder = r; - return d; -} -#endif #define LOG_PREFIX "dev_vdisk" @@ -242,7 +228,6 @@ struct scst_vdisk_thr { static struct kmem_cache *vdisk_thr_cachep; #define DEF_NUM_THREADS 5 - static int num_threads = DEF_NUM_THREADS; module_param_named(num_threads, num_threads, int, 0); @@ -1406,9 +1391,16 @@ static int vdisk_rigid_geo_pg(unsigned char *p, int pcontrol, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x98/* 15K RPM */, 0, 0}; int32_t ncyl, n, rem; + uint64_t dividend; memcpy(p, geo_m_pg, sizeof(geo_m_pg)); - ncyl = div_s64_rem(virt_dev->nblocks, DEF_HEADS * DEF_SECTORS, &rem); + /* + * Divide virt_dev->nblocks by (DEF_HEADS * DEF_SECTORS) and store + * the quotient in ncyl and the remainder in rem. + */ + dividend = virt_dev->nblocks; + rem = do_div(dividend, DEF_HEADS * DEF_SECTORS); + ncyl = dividend; if (rem != 0) ncyl++; memcpy(&n, p + 2, sizeof(u32));