From: Don Dugger <n0ano@n0ano.com>
To: linux-ia64@vger.kernel.org
Subject: Re: [Linux-ia64] platform detection at run-time
Date: Thu, 26 Sep 2002 04:32:15 +0000 [thread overview]
Message-ID: <marc-linux-ia64-105590701906069@msgid-missing> (raw)
In-Reply-To: <marc-linux-ia64-105590701906051@msgid-missing>
[-- Attachment #1: Type: text/plain, Size: 4122 bytes --]
Nitin-
Attached is a kernel patch that should fix the SG_IO ioctl call for
IA32 programs. If you could test it out and let me know how it works
that would be a big help. I don't have a test program so I haven't
tested it myself but I think it should be correct, I just lifted
code from the sparc64 port that does the same thing.
The patch is against an ia64-020821.diff patched 2.4.19 kernel.
On Wed, Sep 25, 2002 at 05:25:35PM -0400, Sane_Purushottam@emc.com wrote:
> SG_IO. The application is sending SCSI commands to the devices.
>
> Nitin Sane
> sane_purushottam@emc.com
> (508) 382-7319
>
>
> -----Original Message-----
> From: Don Dugger [mailto:n0ano@n0ano.com]
> Sent: Wednesday, September 25, 2002 5:08 PM
> To: Sane_Purushottam@emc.com
> Cc: kevin.vanmaren@unisys.com; linux-ia64@linuxia64.org
> Subject: Re: [Linux-ia64] platform detection at run-time
>
>
> Nitin-
>
> Can you tell me exactly which ioctl calls you're using that aren't
> working? We have code in the kernel to deal with just this situation.
> I didn't transform EVERY ioctl in existence so let me know which ones
> you're using and I'll fix them.
>
> On Wed, Sep 25, 2002 at 03:33:12PM -0400, Sane_Purushottam@emc.com wrote:
> > The reason, I have to detect the architecture at run time has to do with
> the
> > interface with (sg) driver. Since the driver is natively compiled for
> > 64-bit, it expects the data structure handed over to it, to be 64-bit
> wide.
> > Thus my 32-bit application cannot issue ioctl calls successfully.
> >
> > So, in my application, based on the platform, I fill the appropriate
> > structure before ioctl call.
> >
> > Nitin Sane
> > sane_purushottam@emc.com
> > (508) 382-7319
> >
> >
> > -----Original Message-----
> > From: Van Maren, Kevin [mailto:kevin.vanmaren@unisys.com]
> > Sent: Wednesday, September 25, 2002 3:28 PM
> > To: 'Sane_Purushottam@emc.com '; 'linux-ia64@linuxia64.org '
> > Subject: RE: [Linux-ia64] platform detection at run-time
> >
> >
> > Nitin,
> >
> > Have you decided what you want to do about AMD's x86-64?
> > That is another 64-bit platform that will run your 32-bit binary.
> >
> > Ideally all three platforms would be enough alike you don't
> > have to worry about it: is there a problem with Linux that is
> > causing you to perform this check?
> >
> > Kevin
> >
> > -----Original Message-----
> > From: Sane_Purushottam@emc.com
> > To: linux-ia64@linuxia64.org
> > Cc: Sane_Purushottam@emc.com
> > Sent: 9/25/02 2:18 PM
> > Subject: [Linux-ia64] platform detection at run-time
> >
> > I have a linux application running on 32-bit machines. Due to some
> > third-party limitations, we cannot build this application on 64-bit
> > machines
> > natively. Thus we'll be using the '32-bit compatibility mode'.
> >
> > For some application specific reasons, I need to be able to determine at
> > run-time whether the application is running on a 32-bit or a 64-bit
> > platform.
> >
> > What I have found is that there's no reliable way for the application to
> > determine whether it's running on a 64-bit machine. I use info obtained
> > from
> > /proc/cpuinfo (more specifically family field) to determine the
> > platform.
> > However this is not standard. On Redhat 7.1 (lk 2.4.3-12) family value
> > is
> > set to IA-64 while on Redhat 7.2 (lk 2.4.9-34) this field is set to
> > 'Itanium'.
> >
> > What is the preferred method to determine the platform at run time ??
> > Are
> > these values likely to change (after I change my code to handle this)
> > ????
> >
> > Nitin Sane
> > sane_purushottam@emc.com
> > (508) 382-7319
> >
> >
> > _______________________________________________
> > Linux-IA64 mailing list
> > Linux-IA64@linuxia64.org
> > http://lists.linuxia64.org/lists/listinfo/linux-ia64
> >
> > _______________________________________________
> > Linux-IA64 mailing list
> > Linux-IA64@linuxia64.org
> > http://lists.linuxia64.org/lists/listinfo/linux-ia64
>
> --
> Don Dugger
> "Censeo Toto nos in Kansa esse decisse." - D. Gale
> n0ano@n0ano.com
--
Don Dugger
"Censeo Toto nos in Kansa esse decisse." - D. Gale
n0ano@n0ano.com
[-- Attachment #2: patch_0925.l --]
[-- Type: text/plain, Size: 7486 bytes --]
diff -Naur linux-2.4.19/arch/ia64/ia32/ia32_ioctl.c linux-2.4.19-ddd/arch/ia64/ia32/ia32_ioctl.c
--- linux-2.4.19/arch/ia64/ia32/ia32_ioctl.c Fri Aug 2 18:39:42 2002
+++ linux-2.4.19-ddd/arch/ia64/ia32/ia32_ioctl.c Wed Sep 25 21:27:11 2002
@@ -24,6 +24,12 @@
#include <linux/if_ppp.h>
#include <linux/ixjuser.h>
#include <linux/i2o-dev.h>
+#include <scsi/scsi.h>
+/* Ugly hack. */
+#undef __KERNEL__
+#include <scsi/scsi_ioctl.h>
+#define __KERNEL__
+#include <scsi/sg.h>
#include <asm/ia32.h>
@@ -56,6 +62,235 @@
|| put_user(d->d_reclen, &d32->d_reclen)
|| copy_to_user(d32->d_name, d->d_name, namelen + 1));
}
+/*
+ * The transform code for the SG_IO ioctl was brazenly lifted from
+ * the Sparc64 port in the file `arch/sparc64/kernel/ioctl32.c'.
+ * Thanks to Jakub Jelinek & Eddie C. Dost.
+ */
+typedef struct sg_io_hdr32 {
+ int interface_id; /* [i] 'S' for SCSI generic (required) */
+ int dxfer_direction; /* [i] data transfer direction */
+ char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ char mx_sb_len; /* [i] max length to write to sbp */
+ short iovec_count; /* [i] 0 implies no scatter gather */
+ int dxfer_len; /* [i] byte count of data transfer */
+ int dxferp; /* [i], [*io] points to data transfer memory
+ or scatter gather list */
+ int cmdp; /* [i], [*i] points to command to perform */
+ int sbp; /* [i], [*o] points to sense_buffer memory */
+ int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
+ int flags; /* [i] 0 -> default, see SG_FLAG... */
+ int pack_id; /* [i->o] unused internally (normally) */
+ int usr_ptr; /* [i->o] unused internally */
+ char status; /* [o] scsi status */
+ char masked_status; /* [o] shifted, masked scsi status */
+ char msg_status; /* [o] messaging level data (optional) */
+ char sb_len_wr; /* [o] byte count actually written to sbp */
+ short host_status; /* [o] errors from host adapter */
+ short driver_status; /* [o] errors from software driver */
+ int resid; /* [o] dxfer_len - actual_transferred */
+ int duration; /* [o] time taken by cmd (unit: millisec) */
+ int info; /* [o] auxiliary information */
+} sg_io_hdr32_t; /* 64 bytes long (on IA32) */
+
+struct iovec32 { unsigned int iov_base; int iov_len; };
+
+static int alloc_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
+{
+ struct iovec32 *uiov = (struct iovec32 *) P(uptr32);
+ sg_iovec_t *kiov;
+ int i;
+
+ sgp->dxferp = kmalloc(sgp->iovec_count *
+ sizeof(sg_iovec_t), GFP_KERNEL);
+ if (!sgp->dxferp)
+ return -ENOMEM;
+ memset(sgp->dxferp, 0,
+ sgp->iovec_count * sizeof(sg_iovec_t));
+
+ kiov = (sg_iovec_t *) sgp->dxferp;
+ for (i = 0; i < sgp->iovec_count; i++) {
+ int iov_base32;
+ if (__get_user(iov_base32, &uiov->iov_base) ||
+ __get_user(kiov->iov_len, &uiov->iov_len))
+ return -EFAULT;
+
+ kiov->iov_base = kmalloc(kiov->iov_len, GFP_KERNEL);
+ if (!kiov->iov_base)
+ return -ENOMEM;
+ if (copy_from_user(kiov->iov_base,
+ (void *) P(iov_base32),
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }
+
+ return 0;
+}
+
+static int copy_back_sg_iovec(sg_io_hdr_t *sgp, int uptr32)
+{
+ struct iovec32 *uiov = (struct iovec32 *) P(uptr32);
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ int iov_base32;
+
+ if (__get_user(iov_base32, &uiov->iov_base))
+ return -EFAULT;
+
+ if (copy_to_user((void *) P(iov_base32),
+ kiov->iov_base,
+ kiov->iov_len))
+ return -EFAULT;
+
+ uiov++;
+ kiov++;
+ }
+
+ return 0;
+}
+
+static void free_sg_iovec(sg_io_hdr_t *sgp)
+{
+ sg_iovec_t *kiov = (sg_iovec_t *) sgp->dxferp;
+ int i;
+
+ for (i = 0; i < sgp->iovec_count; i++) {
+ if (kiov->iov_base) {
+ kfree(kiov->iov_base);
+ kiov->iov_base = NULL;
+ }
+ kiov++;
+ }
+ kfree(sgp->dxferp);
+ sgp->dxferp = NULL;
+}
+
+static int sg_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ sg_io_hdr32_t *sg_io32;
+ sg_io_hdr_t sg_io64;
+ int dxferp32, cmdp32, sbp32;
+ mm_segment_t old_fs;
+ int err = 0;
+
+ sg_io32 = (sg_io_hdr32_t *)arg;
+ err = __get_user(sg_io64.interface_id, &sg_io32->interface_id);
+ err |= __get_user(sg_io64.dxfer_direction, &sg_io32->dxfer_direction);
+ err |= __get_user(sg_io64.cmd_len, &sg_io32->cmd_len);
+ err |= __get_user(sg_io64.mx_sb_len, &sg_io32->mx_sb_len);
+ err |= __get_user(sg_io64.iovec_count, &sg_io32->iovec_count);
+ err |= __get_user(sg_io64.dxfer_len, &sg_io32->dxfer_len);
+ err |= __get_user(sg_io64.timeout, &sg_io32->timeout);
+ err |= __get_user(sg_io64.flags, &sg_io32->flags);
+ err |= __get_user(sg_io64.pack_id, &sg_io32->pack_id);
+
+ sg_io64.dxferp = NULL;
+ sg_io64.cmdp = NULL;
+ sg_io64.sbp = NULL;
+
+ err |= __get_user(cmdp32, &sg_io32->cmdp);
+ sg_io64.cmdp = kmalloc(sg_io64.cmd_len, GFP_KERNEL);
+ if (!sg_io64.cmdp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.cmdp,
+ (void *) P(cmdp32),
+ sg_io64.cmd_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err |= __get_user(sbp32, &sg_io32->sbp);
+ sg_io64.sbp = kmalloc(sg_io64.mx_sb_len, GFP_KERNEL);
+ if (!sg_io64.sbp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.sbp,
+ (void *) P(sbp32),
+ sg_io64.mx_sb_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ err |= __get_user(dxferp32, &sg_io32->dxferp);
+ if (sg_io64.iovec_count) {
+ int ret;
+
+ if ((ret = alloc_sg_iovec(&sg_io64, dxferp32))) {
+ err = ret;
+ goto out;
+ }
+ } else {
+ sg_io64.dxferp = kmalloc(sg_io64.dxfer_len, GFP_KERNEL);
+ if (!sg_io64.dxferp) {
+ err = -ENOMEM;
+ goto out;
+ }
+ if (copy_from_user(sg_io64.dxferp,
+ (void *) P(dxferp32),
+ sg_io64.dxfer_len)) {
+ err = -EFAULT;
+ goto out;
+ }
+ }
+
+ /* Unused internally, do not even bother to copy it over. */
+ sg_io64.usr_ptr = NULL;
+
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ err = sys_ioctl (fd, cmd, (unsigned long) &sg_io64);
+ set_fs (old_fs);
+
+ if (err < 0)
+ goto out;
+
+ err = __put_user(sg_io64.pack_id, &sg_io32->pack_id);
+ err |= __put_user(sg_io64.status, &sg_io32->status);
+ err |= __put_user(sg_io64.masked_status, &sg_io32->masked_status);
+ err |= __put_user(sg_io64.msg_status, &sg_io32->msg_status);
+ err |= __put_user(sg_io64.sb_len_wr, &sg_io32->sb_len_wr);
+ err |= __put_user(sg_io64.host_status, &sg_io32->host_status);
+ err |= __put_user(sg_io64.driver_status, &sg_io32->driver_status);
+ err |= __put_user(sg_io64.resid, &sg_io32->resid);
+ err |= __put_user(sg_io64.duration, &sg_io32->duration);
+ err |= __put_user(sg_io64.info, &sg_io32->info);
+ err |= copy_to_user((void *)P(sbp32), sg_io64.sbp, sg_io64.mx_sb_len);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count)
+ err |= copy_back_sg_iovec(&sg_io64, dxferp32);
+ else
+ err |= copy_to_user((void *)P(dxferp32),
+ sg_io64.dxferp,
+ sg_io64.dxfer_len);
+ }
+ if (err)
+ err = -EFAULT;
+
+out:
+ if (sg_io64.cmdp)
+ kfree(sg_io64.cmdp);
+ if (sg_io64.sbp)
+ kfree(sg_io64.sbp);
+ if (sg_io64.dxferp) {
+ if (sg_io64.iovec_count) {
+ free_sg_iovec(&sg_io64);
+ } else {
+ kfree(sg_io64.dxferp);
+ }
+ }
+ return err;
+}
asmlinkage long
sys32_ioctl (unsigned int fd, unsigned int cmd, unsigned int arg)
@@ -266,6 +501,9 @@
break;
default:
return sys_ioctl(fd, cmd, (unsigned long)arg);
+
+ case IOCTL_NR(SG_IO):
+ return(sg_ioctl_trans(fd, cmd, arg));
}
printk("%x:unimplemented IA32 ioctl system call\n", cmd);
prev parent reply other threads:[~2002-09-26 4:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-25 18:18 [Linux-ia64] platform detection at run-time Sane_Purushottam
2002-09-25 18:22 ` Don Dugger
2002-09-25 18:35 ` Nathan Straz
2002-09-25 18:46 ` David Mosberger
2002-09-25 18:48 ` David Mosberger
2002-09-25 18:57 ` Nathan Straz
2002-09-25 19:00 ` Joe Griffin
2002-09-25 19:05 ` David Mosberger
2002-09-25 19:28 ` Van Maren, Kevin
2002-09-25 19:33 ` Sane_Purushottam
2002-09-25 19:40 ` Wichmann, Mats D
2002-09-25 19:48 ` David Mosberger
2002-09-25 20:45 ` Grant Grundler
2002-09-25 21:07 ` Don Dugger
2002-09-25 21:25 ` Sane_Purushottam
2002-09-25 23:29 ` David Mosberger
2002-09-26 4:32 ` Don Dugger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=marc-linux-ia64-105590701906069@msgid-missing \
--to=n0ano@n0ano.com \
--cc=linux-ia64@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.