mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-19 05:36:22 +00:00
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 <asm/div64.h>. 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 <bart.vanassche@gmail.com> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@640 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -39,21 +39,7 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
|
||||
#include <linux/math64.h>
|
||||
#else
|
||||
#include <asm/div64.h>
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user