public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] aacraid 32/64 ioctl support (update)
@ 2004-06-16 15:52 Mark Haverkamp
  2004-06-16 16:01 ` Christoph Hellwig
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Haverkamp @ 2004-06-16 15:52 UTC (permalink / raw)
  To: James Bottomley, linux-scsi; +Cc: Mark Salyzyn

Here is an updated patch from Adaptec that adds support for 32 bit apps
access to ioctl with 64 bit kernel.  Built against 2.6.7

This patch fixes a problem that existed in my previous submission.

Signed-off-by: Mark Haverkamp <markh@osdl.org>

===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited =====
--- 1.14/drivers/scsi/aacraid/aacraid.h	2004-05-10 13:02:37 -07:00
+++ edited/drivers/scsi/aacraid/aacraid.h	2004-06-04 13:44:08 -07:00
@@ -650,6 +650,7 @@
 struct aac_fib_context {
 	s16	 		type;		// used for verification of structure	
 	s16	 		size;
+	u32			unique;		// unique value representing this context
 	ulong			jiffies;	// used for cleanup - dmb changed to ulong
 	struct list_head	next;		// used to link context's into a linked list
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
@@ -1226,11 +1227,11 @@
 	u32	disknum;
 	u32	cnum;
 };
-
+ 
 struct fib_ioctl
 {
-	char	*fibctx;
-	int	wait;
+	u32	fibctx;
+	s32	wait;
 	char	*fib;
 };
 
===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited =====
--- 1.5/drivers/scsi/aacraid/commctrl.c	2004-05-10 13:22:40 -07:00
+++ edited/drivers/scsi/aacraid/commctrl.c	2004-06-15 14:59:29 -07:00
@@ -92,11 +92,12 @@
 		 */
 		kfib->header.XferState = 0;
 	} else {
-		if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
-			1, 1, NULL, NULL) != 0) 
-		{
+		int retval = fib_send(kfib->header.Command, fibptr,
+				le32_to_cpu(kfib->header.Size) , FsaNormal,
+				1, 1, NULL, NULL);
+		if (retval != 0) {
 			fib_free(fibptr);
-			return -EINVAL;
+			return retval;
 		}
 		if (fib_complete(fibptr) != 0) {
 			fib_free(fibptr);
@@ -130,14 +131,24 @@
 {
 	struct aac_fib_context * fibctx;
 	int status;
-	unsigned long flags;
 
 	fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
 	if (fibctx == NULL) {
 		status = -ENOMEM;
 	} else {
+		unsigned long flags;
+		struct list_head * entry;
+		struct aac_fib_context * context;
+
 		fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
 		fibctx->size = sizeof(struct aac_fib_context);
+ 		/*
+		 *	Yes yes, I know this could be an index, but we have a
+		 * better guarantee of uniqueness for the locked loop below.
+		 * Without the aid of a persistent history, this also helps
+		 * reduce the chance that the opaque context would be reused.
+		 */
+		fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
 		/*
 		 *	Initialize the mutex used to wait for the next AIF.
 		 */
@@ -155,9 +166,22 @@
 		 *	AdapterFibContext list.
 		 */
 		spin_lock_irqsave(&dev->fib_lock, flags);
+		/* Ensure that we have a unique identifier */
+		entry = dev->fib_list.next;
+		while(entry != &dev->fib_list) {
+			context = list_entry(entry, struct aac_fib_context, next);
+			if (context->unique == fibctx->unique) {
+				/* Not unique (32 bits) */
+				fibctx->unique++;
+				entry = dev->fib_list.next;
+			} else {
+				entry = entry->next;
+			}
+		}
 		list_add_tail(&fibctx->next, &dev->fib_list);
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(arg,  &fibctx, sizeof(struct aac_fib_context *))) {
+		if (copy_to_user(arg,  &fibctx->unique, 
+						sizeof(fibctx->unique))) {
 			status = -EFAULT;
 		} else {
 			status = 0;
@@ -178,43 +202,44 @@
 static int next_getadapter_fib(struct aac_dev * dev, void *arg)
 {
 	struct fib_ioctl f;
-	struct aac_fib_context *fibctx, *aifcp;
 	struct fib *fib;
+	struct aac_fib_context *fibctx;
 	int status;
 	struct list_head * entry;
-	int found;
 	unsigned long flags;
 	
 	if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
 		return -EFAULT;
 	/*
-	 *	Extract the AdapterFibContext from the Input parameters.
-	 */
-	fibctx = (struct aac_fib_context *) f.fibctx;
-
-	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
 	 *
 	 *	Search the list of AdapterFibContext addresses on the adapter
 	 *	to be sure this is a valid address
 	 */
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the AdapterFibContext from the Input parameters.
+		 */
+		if(fibctx->unique == f.fibctx) {   /* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
-	if (found == 0)
+	if (!fibctx) {
+		dprintk ((KERN_INFO "Fib Context not found\n"));
 		return -EINVAL;
+	}
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
-		 (fibctx->size != sizeof(struct aac_fib_context)))
+		 (fibctx->size != sizeof(struct aac_fib_context))) {
+		dprintk ((KERN_INFO "Fib Context corrupt?\n"));
 		return -EINVAL;
+	}
 	status = 0;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	/*
@@ -309,16 +334,10 @@
  
 static int close_getadapter_fib(struct aac_dev * dev, void *arg)
 {
-	struct aac_fib_context *fibctx, *aifcp;
+	struct aac_fib_context *fibctx;
 	int status;
 	unsigned long flags;
 	struct list_head * entry;
-	int found;
-
-	/*
-	 *	Extract the fibctx from the input parameters
-	 */
-	fibctx = arg;
 
 	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -327,19 +346,23 @@
 	 *	to be sure this is a valid address
 	 */
 
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the fibctx from the input parameters
+		 */
+		if(fibctx->unique == (u32)(unsigned long)arg) {   
+			/* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
 
-	if(found == 0)
+	if (!fibctx)
 		return 0; /* Already gone */
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
@@ -356,8 +379,9 @@
  *	@dev: adapter
  *	@arg: ioctl arguments
  *
- *	This routine returns the firmware version.
- *      Under Linux, there have been no version incompatibilities, so this is simple!
+ *	This routine returns the driver version.
+ *      Under Linux, there have been no version incompatibilities, so this is 
+ *      simple!
  */
 
 static int check_revision(struct aac_dev *dev, void *arg)
@@ -419,6 +443,11 @@
 		goto cleanup;
 	}
 
+	if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
+		rcode = -EINVAL;
+		goto cleanup;
+	}
+
 	if(copy_from_user(srbcmd, user_srb,fibsize)){
 		printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); 
 		rcode = -EFAULT;
@@ -438,7 +467,7 @@
 	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
 	srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
 	
-	switch(srbcmd->flags){
+	switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
 	case SRB_DataOut:
 		data_dir = DMA_TO_DEVICE;
 		break;
@@ -451,17 +480,26 @@
 	default:
 		data_dir = DMA_NONE;
 	}
-	if( dev->pae_support ==1 ) {
+	if(dev->pae_support == 1) {
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
 		byte_count = 0;
 
-		// This should also catch if user used the 32 bit sgmap
-		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
+		/*
+		 * This should also catch if user used the 32 bit sgmap
+		 */
+		actual_fibsize = sizeof (struct aac_srb) - 
+			sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * 
+			 	sizeof (struct sgentry64));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
+		if ((data_dir == DMA_NONE) && psg->count) { 
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
 
 		for (i = 0; i < psg->count; i++) {
 			dma_addr_t addr; 
@@ -503,6 +541,11 @@
 		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
+		if ((data_dir == DMA_NONE) && psg->count) {
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
===== drivers/scsi/aacraid/linit.c 1.29 vs edited =====
--- 1.29/drivers/scsi/aacraid/linit.c	2004-05-10 04:42:31 -07:00
+++ edited/drivers/scsi/aacraid/linit.c	2004-06-15 15:39:05 -07:00
@@ -42,6 +42,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <asm/semaphore.h>
+#include <linux/syscalls.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -50,6 +51,9 @@
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsicam.h>
 #include <scsi/scsi_eh.h>
+#if (defined(CONFIG_COMPAT))
+# include <linux/ioctl32.h>
+#endif
 
 #include "aacraid.h"
 
@@ -168,6 +172,30 @@
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA      ", 1 }, /* ASR-2025SA      (ZCR DIMM SATA) */
 };
 
+#if (defined(CONFIG_COMPAT))
+/* 
+ * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
+ */
+int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
+		unsigned long arg, struct file *file)
+{
+	struct fib_ioctl f;
+	mm_segment_t fs;
+	int retval;
+
+	memset (&f, 0, sizeof(f));
+	if(copy_from_user((void *)&f, (void *)arg, 
+				sizeof(struct fib_ioctl) - sizeof(u32)))
+		return -EFAULT;
+	fs = get_fs();
+	set_fs(get_ds());
+	retval = sys_ioctl(fd, cmd, (unsigned long)&f);
+	set_fs(fs);
+	return retval;
+}
+#endif
+
+
 /**
  *	aac_queuecommand	-	queue a SCSI command
  *	@cmd:		SCSI command to queue
@@ -643,12 +671,39 @@
 		printk(KERN_WARNING
 		       "aacraid: unable to register \"aac\" device.\n");
 	}
+#	if (defined(CONFIG_COMPAT))
+		register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
+		register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
+		register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
+		register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, 
+			aac_get_next_adapter_fib_ioctl);
+		register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
+		register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
+		register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
+		register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
+		register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
+		register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
+		register_ioctl32_conversion(2131, NULL);
+#	endif
 
 	return 0;
 }
 
 static void __exit aac_exit(void)
 {
+#	if (defined(CONFIG_COMPAT))
+		unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
+		unregister_ioctl32_conversion(FSACTL_SENDFIB);
+		unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
+		unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
+		unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
+		unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
+		unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
+		unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
+		unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
+		unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
+		unregister_ioctl32_conversion(2131);
+#	endif
 	unregister_chrdev(aac_cfg_major, "aac");
 	pci_unregister_driver(&aac_pci_driver);
 }


-- 
Mark Haverkamp <markh@osdl.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 15:52 [PATCH] aacraid 32/64 ioctl support (update) Mark Haverkamp
@ 2004-06-16 16:01 ` Christoph Hellwig
  2004-06-16 16:02   ` Christoph Hellwig
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2004-06-16 16:01 UTC (permalink / raw)
  To: Mark Haverkamp; +Cc: James Bottomley, linux-scsi, Mark Salyzyn

On Wed, Jun 16, 2004 at 08:52:17AM -0700, Mark Haverkamp wrote:
> +		if (retval != 0) {

the != 0 is superflous.

> -	if( dev->pae_support ==1 ) {
> +	if(dev->pae_support == 1) {

if you're fixing up the strange style in the driver please go to the right
indentation directly (space before opening brace)

> +++ edited/drivers/scsi/aacraid/linit.c	2004-06-15 15:39:05 -07:00
> @@ -42,6 +42,7 @@
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
>  #include <asm/semaphore.h>
> +#include <linux/syscalls.h>

<linux/*.h> before <asm/*.h> please

>  #include <scsi/scsi_tcq.h>
>  #include <scsi/scsicam.h>
>  #include <scsi/scsi_eh.h>
> +#if (defined(CONFIG_COMPAT))
> +# include <linux/ioctl32.h>
> +#endif

ioctl32.h should be fine to include even without CONFIG_COMPAT

>  
>  #include "aacraid.h"
>  
> @@ -168,6 +172,30 @@
>  	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA      ", 1 }, /* ASR-2025SA      (ZCR DIMM SATA) */
>  };
>  
> +#if (defined(CONFIG_COMPAT))

just ifdef instead of all those braces.

> +/* 
> + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
> + */
> +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
> +		unsigned long arg, struct file *file)
> +{
> +	struct fib_ioctl f;
> +	mm_segment_t fs;
> +	int retval;
> +
> +	memset (&f, 0, sizeof(f));
> +	if(copy_from_user((void *)&f, (void *)arg, 
> +				sizeof(struct fib_ioctl) - sizeof(u32)))
> +		return -EFAULT;
> +	fs = get_fs();
> +	set_fs(get_ds());
> +	retval = sys_ioctl(fd, cmd, (unsigned long)&f);
> +	set_fs(fs);
> +	return retval;

use compat_alloc_userspace here.

> @@ -643,12 +671,39 @@
>  		printk(KERN_WARNING
>  		       "aacraid: unable to register \"aac\" device.\n");
>  	}
> +#	if (defined(CONFIG_COMPAT))
> +		register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
> +		register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
> +		register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
> +		register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, 
> +			aac_get_next_adapter_fib_ioctl);
> +		register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
> +		register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
> +		register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
> +		register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
> +		register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
> +		register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
> +		register_ioctl32_conversion(2131, NULL);
> +#	endif

#ifdef please and no additional indentation inside the ifdef please.

>  static void __exit aac_exit(void)
>  {
> +#	if (defined(CONFIG_COMPAT))
> +		unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
> +		unregister_ioctl32_conversion(FSACTL_SENDFIB);
> +		unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
> +		unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
> +		unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
> +		unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
> +		unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
> +		unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
> +		unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
> +		unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
> +		unregister_ioctl32_conversion(2131);
> +#	endif

dito.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 16:01 ` Christoph Hellwig
@ 2004-06-16 16:02   ` Christoph Hellwig
  2004-06-16 17:12     ` Mark Haverkamp
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2004-06-16 16:02 UTC (permalink / raw)
  To: Mark Haverkamp; +Cc: James Bottomley, linux-scsi, Mark Salyzyn

On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote:
> > +		register_ioctl32_conversion(2131, NULL);
> > +#	endif
> 
> #ifdef please and no additional indentation inside the ifdef please.

btw, what's ioctl2131?  It doesn't seem to be implemented, so no need to translate it.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 16:02   ` Christoph Hellwig
@ 2004-06-16 17:12     ` Mark Haverkamp
  2004-06-16 17:19       ` Christoph Hellwig
  0 siblings, 1 reply; 9+ messages in thread
From: Mark Haverkamp @ 2004-06-16 17:12 UTC (permalink / raw)
  To: Christoph Hellwig, James Bottomley; +Cc: linux-scsi, Mark Salyzyn

On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote:
> On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote:
> > > +		register_ioctl32_conversion(2131, NULL);
> > > +#	endif
> > 
> > #ifdef please and no additional indentation inside the ifdef please.
> 
> btw, what's ioctl2131?  It doesn't seem to be implemented, so no need to translate it.

Christoph,

I think that I have addressed all of your comments in this patch.

removed != 0
fixed indentation
fixed include order
fixed ifdefs
used compat_alloc_user_space

I checked, and 2131 is implemented in aachba.c and looks like it gets
container info.

---

James,

Here is the updated patch.

===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited =====
--- 1.14/drivers/scsi/aacraid/aacraid.h	2004-05-10 13:02:37 -07:00
+++ edited/drivers/scsi/aacraid/aacraid.h	2004-06-04 13:44:08 -07:00
@@ -650,6 +650,7 @@
 struct aac_fib_context {
 	s16	 		type;		// used for verification of structure	
 	s16	 		size;
+	u32			unique;		// unique value representing this context
 	ulong			jiffies;	// used for cleanup - dmb changed to ulong
 	struct list_head	next;		// used to link context's into a linked list
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
@@ -1226,11 +1227,11 @@
 	u32	disknum;
 	u32	cnum;
 };
-
+ 
 struct fib_ioctl
 {
-	char	*fibctx;
-	int	wait;
+	u32	fibctx;
+	s32	wait;
 	char	*fib;
 };
 
===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited =====
--- 1.5/drivers/scsi/aacraid/commctrl.c	2004-05-10 13:22:40 -07:00
+++ edited/drivers/scsi/aacraid/commctrl.c	2004-06-16 10:05:11 -07:00
@@ -92,11 +92,12 @@
 		 */
 		kfib->header.XferState = 0;
 	} else {
-		if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
-			1, 1, NULL, NULL) != 0) 
-		{
+		int retval = fib_send(kfib->header.Command, fibptr,
+				le32_to_cpu(kfib->header.Size) , FsaNormal,
+				1, 1, NULL, NULL);
+		if (retval) {
 			fib_free(fibptr);
-			return -EINVAL;
+			return retval;
 		}
 		if (fib_complete(fibptr) != 0) {
 			fib_free(fibptr);
@@ -130,14 +131,24 @@
 {
 	struct aac_fib_context * fibctx;
 	int status;
-	unsigned long flags;
 
 	fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
 	if (fibctx == NULL) {
 		status = -ENOMEM;
 	} else {
+		unsigned long flags;
+		struct list_head * entry;
+		struct aac_fib_context * context;
+
 		fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
 		fibctx->size = sizeof(struct aac_fib_context);
+ 		/*
+		 *	Yes yes, I know this could be an index, but we have a
+		 * better guarantee of uniqueness for the locked loop below.
+		 * Without the aid of a persistent history, this also helps
+		 * reduce the chance that the opaque context would be reused.
+		 */
+		fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
 		/*
 		 *	Initialize the mutex used to wait for the next AIF.
 		 */
@@ -155,9 +166,22 @@
 		 *	AdapterFibContext list.
 		 */
 		spin_lock_irqsave(&dev->fib_lock, flags);
+		/* Ensure that we have a unique identifier */
+		entry = dev->fib_list.next;
+		while (entry != &dev->fib_list) {
+			context = list_entry(entry, struct aac_fib_context, next);
+			if (context->unique == fibctx->unique) {
+				/* Not unique (32 bits) */
+				fibctx->unique++;
+				entry = dev->fib_list.next;
+			} else {
+				entry = entry->next;
+			}
+		}
 		list_add_tail(&fibctx->next, &dev->fib_list);
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(arg,  &fibctx, sizeof(struct aac_fib_context *))) {
+		if (copy_to_user(arg,  &fibctx->unique, 
+						sizeof(fibctx->unique))) {
 			status = -EFAULT;
 		} else {
 			status = 0;
@@ -178,43 +202,44 @@
 static int next_getadapter_fib(struct aac_dev * dev, void *arg)
 {
 	struct fib_ioctl f;
-	struct aac_fib_context *fibctx, *aifcp;
 	struct fib *fib;
+	struct aac_fib_context *fibctx;
 	int status;
 	struct list_head * entry;
-	int found;
 	unsigned long flags;
 	
 	if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
 		return -EFAULT;
 	/*
-	 *	Extract the AdapterFibContext from the Input parameters.
-	 */
-	fibctx = (struct aac_fib_context *) f.fibctx;
-
-	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
 	 *
 	 *	Search the list of AdapterFibContext addresses on the adapter
 	 *	to be sure this is a valid address
 	 */
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
-	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+	while (entry != &dev->fib_list) {
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the AdapterFibContext from the Input parameters.
+		 */
+		if (fibctx->unique == f.fibctx) {   /* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
-	if (found == 0)
+	if (!fibctx) {
+		dprintk ((KERN_INFO "Fib Context not found\n"));
 		return -EINVAL;
+	}
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
-		 (fibctx->size != sizeof(struct aac_fib_context)))
+		 (fibctx->size != sizeof(struct aac_fib_context))) {
+		dprintk ((KERN_INFO "Fib Context corrupt?\n"));
 		return -EINVAL;
+	}
 	status = 0;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	/*
@@ -309,16 +334,10 @@
  
 static int close_getadapter_fib(struct aac_dev * dev, void *arg)
 {
-	struct aac_fib_context *fibctx, *aifcp;
+	struct aac_fib_context *fibctx;
 	int status;
 	unsigned long flags;
 	struct list_head * entry;
-	int found;
-
-	/*
-	 *	Extract the fibctx from the input parameters
-	 */
-	fibctx = arg;
 
 	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -327,19 +346,23 @@
 	 *	to be sure this is a valid address
 	 */
 
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the fibctx from the input parameters
+		 */
+		if (fibctx->unique == (u32)(unsigned long)arg) {   
+			/* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
 
-	if(found == 0)
+	if (!fibctx)
 		return 0; /* Already gone */
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
@@ -356,8 +379,9 @@
  *	@dev: adapter
  *	@arg: ioctl arguments
  *
- *	This routine returns the firmware version.
- *      Under Linux, there have been no version incompatibilities, so this is simple!
+ *	This routine returns the driver version.
+ *      Under Linux, there have been no version incompatibilities, so this is 
+ *      simple!
  */
 
 static int check_revision(struct aac_dev *dev, void *arg)
@@ -419,6 +443,11 @@
 		goto cleanup;
 	}
 
+	if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
+		rcode = -EINVAL;
+		goto cleanup;
+	}
+
 	if(copy_from_user(srbcmd, user_srb,fibsize)){
 		printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); 
 		rcode = -EFAULT;
@@ -438,7 +467,7 @@
 	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
 	srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
 	
-	switch(srbcmd->flags){
+	switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
 	case SRB_DataOut:
 		data_dir = DMA_TO_DEVICE;
 		break;
@@ -451,17 +480,26 @@
 	default:
 		data_dir = DMA_NONE;
 	}
-	if( dev->pae_support ==1 ) {
+	if (dev->pae_support == 1) {
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
 		byte_count = 0;
 
-		// This should also catch if user used the 32 bit sgmap
-		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
+		/*
+		 * This should also catch if user used the 32 bit sgmap
+		 */
+		actual_fibsize = sizeof (struct aac_srb) - 
+			sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * 
+			 	sizeof (struct sgentry64));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
+		if ((data_dir == DMA_NONE) && psg->count) { 
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
 
 		for (i = 0; i < psg->count; i++) {
 			dma_addr_t addr; 
@@ -503,6 +541,11 @@
 		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
+		if ((data_dir == DMA_NONE) && psg->count) {
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
===== drivers/scsi/aacraid/linit.c 1.29 vs edited =====
--- 1.29/drivers/scsi/aacraid/linit.c	2004-05-10 04:42:31 -07:00
+++ edited/drivers/scsi/aacraid/linit.c	2004-06-16 10:05:29 -07:00
@@ -31,6 +31,7 @@
 #define AAC_DRIVER_BUILD_DATE		__DATE__
 #define AAC_DRIVERNAME			"aacraid"
 
+#include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/init.h>
@@ -41,6 +42,8 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/syscalls.h>
+#include <linux/ioctl32.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -168,6 +171,27 @@
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA      ", 1 }, /* ASR-2025SA      (ZCR DIMM SATA) */
 };
 
+#ifdef CONFIG_COMPAT
+/* 
+ * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
+ */
+int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
+		unsigned long arg, struct file *file)
+{
+	struct fib_ioctl *f;
+	int retval;
+
+	f = compat_alloc_user_space(sizeof(*f));
+	memset (f, 0, sizeof(*f));
+	if (copy_from_user((void *)f, (void *)arg, 
+				sizeof(struct fib_ioctl) - sizeof(u32)))
+		return -EFAULT;
+	retval = sys_ioctl(fd, cmd, (unsigned long)f);
+	return retval;
+}
+#endif
+
+
 /**
  *	aac_queuecommand	-	queue a SCSI command
  *	@cmd:		SCSI command to queue
@@ -643,12 +667,39 @@
 		printk(KERN_WARNING
 		       "aacraid: unable to register \"aac\" device.\n");
 	}
+#ifdef CONFIG_COMPAT
+	register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
+	register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
+	register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
+	register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, 
+		aac_get_next_adapter_fib_ioctl);
+	register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
+	register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
+	register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
+	register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
+	register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
+	register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
+	register_ioctl32_conversion(2131, NULL);
+#endif
 
 	return 0;
 }
 
 static void __exit aac_exit(void)
 {
+#ifdef CONFIG_COMPAT
+	unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
+	unregister_ioctl32_conversion(FSACTL_SENDFIB);
+	unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
+	unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
+	unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
+	unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
+	unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
+	unregister_ioctl32_conversion(2131);
+#endif
 	unregister_chrdev(aac_cfg_major, "aac");
 	pci_unregister_driver(&aac_pci_driver);
 }



-- 
Mark Haverkamp <markh@osdl.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 17:12     ` Mark Haverkamp
@ 2004-06-16 17:19       ` Christoph Hellwig
  2004-06-16 17:51         ` Mark Haverkamp
  2004-06-16 18:23         ` Mark Haverkamp
  0 siblings, 2 replies; 9+ messages in thread
From: Christoph Hellwig @ 2004-06-16 17:19 UTC (permalink / raw)
  To: Mark Haverkamp
  Cc: Christoph Hellwig, James Bottomley, linux-scsi, Mark Salyzyn

On Wed, Jun 16, 2004 at 10:12:00AM -0700, Mark Haverkamp wrote:
> On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote:
> > On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote:
> > > > +		register_ioctl32_conversion(2131, NULL);
> > > > +#	endif
> > > 
> > > #ifdef please and no additional indentation inside the ifdef please.
> > 
> > btw, what's ioctl2131?  It doesn't seem to be implemented, so no need to translate it.
> 
> Christoph,
> 
> I think that I have addressed all of your comments in this patch.
> 
> removed != 0
> fixed indentation
> fixed include order
> fixed ifdefs
> used compat_alloc_user_space

Although the compat_alloc_user_space implementations I looked at don't fail I
think a check for NULL wouldn't hurt.

> I checked, and 2131 is implemented in aachba.c and looks like it gets
> container info.

Hmm, could we please get a symbolic name for that from adaptec?

> +#ifdef CONFIG_COMPAT
> +/* 
> + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
> + */
> +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
> +		unsigned long arg, struct file *file)

hmm, should probably be static.

> +{
> +	struct fib_ioctl *f;
> +	int retval;
> +
> +	f = compat_alloc_user_space(sizeof(*f));
> +	memset (f, 0, sizeof(*f));

superflous space before the opening brace here.

> +	if (copy_from_user((void *)f, (void *)arg, 
> +				sizeof(struct fib_ioctl) - sizeof(u32)))
> +		return -EFAULT;
> +	retval = sys_ioctl(fd, cmd, (unsigned long)f);
> +	return retval;

No need for retval here.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 17:19       ` Christoph Hellwig
@ 2004-06-16 17:51         ` Mark Haverkamp
  2004-06-16 17:53           ` Christoph Hellwig
  2004-06-16 18:23         ` Mark Haverkamp
  1 sibling, 1 reply; 9+ messages in thread
From: Mark Haverkamp @ 2004-06-16 17:51 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: James Bottomley, linux-scsi, Mark Salyzyn

On Wed, 2004-06-16 at 10:19, Christoph Hellwig wrote:
> On Wed, Jun 16, 2004 at 10:12:00AM -0700, Mark Haverkamp wrote:
> > On Wed, 2004-06-16 at 09:02, Christoph Hellwig wrote:
> > > On Wed, Jun 16, 2004 at 05:01:07PM +0100, Christoph Hellwig wrote:
> > > > > +		register_ioctl32_conversion(2131, NULL);
> > > > > +#	endif
> > > > 
> > > > #ifdef please and no additional indentation inside the ifdef please.
> > > 
> > > btw, what's ioctl2131?  It doesn't seem to be implemented, so no need to translate it.
> > 
> > Christoph,
> > 
> > I think that I have addressed all of your comments in this patch.
> > 
> > removed != 0
> > fixed indentation
> > fixed include order
> > fixed ifdefs
> > used compat_alloc_user_space
> 
> Although the compat_alloc_user_space implementations I looked at don't fail I
> think a check for NULL wouldn't hurt.

The places that I looked where they check the return value use
access_ok().  What do you think?

> 
> > I checked, and 2131 is implemented in aachba.c and looks like it gets
> > container info.
> 
> Hmm, could we please get a symbolic name for that from adaptec?

I sent a note to Mark at adaptec about this.  I'll post a revised patch
when I hear from him.

> 
> > +#ifdef CONFIG_COMPAT
> > +/* 
> > + * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
> > + */
> > +int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
> > +		unsigned long arg, struct file *file)
> 
> hmm, should probably be static.

OK

> 
> > +{
> > +	struct fib_ioctl *f;
> > +	int retval;
> > +
> > +	f = compat_alloc_user_space(sizeof(*f));

I just noticed this.  Can we use memset on a user pointer?  If not, what
would be the best way to handle this?


> > +	memset (f, 0, sizeof(*f));
> 
> superflous space before the opening brace here.

OK
> 
> > +	if (copy_from_user((void *)f, (void *)arg, 
> > +				sizeof(struct fib_ioctl) - sizeof(u32)))
> > +		return -EFAULT;
> > +	retval = sys_ioctl(fd, cmd, (unsigned long)f);
> > +	return retval;
> 
> No need for retval here.

OK
-- 
Mark Haverkamp <markh@osdl.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 17:53           ` Christoph Hellwig
@ 2004-06-16 17:52             ` David S. Miller
  0 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2004-06-16 17:52 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: markh, James.Bottomley, linux-scsi, mark_salyzyn, linux-arch,
	linux-kernel

On Wed, 16 Jun 2004 18:53:25 +0100
Christoph Hellwig <hch@infradead.org> wrote:

> > I just noticed this.  Can we use memset on a user pointer?  If not, what
> > would be the best way to handle this?
> 
> 
> Good question.  Maybe the architecture-folks know an answer?

Use clear_user()


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 17:51         ` Mark Haverkamp
@ 2004-06-16 17:53           ` Christoph Hellwig
  2004-06-16 17:52             ` David S. Miller
  0 siblings, 1 reply; 9+ messages in thread
From: Christoph Hellwig @ 2004-06-16 17:53 UTC (permalink / raw)
  To: Mark Haverkamp
  Cc: James Bottomley, linux-scsi, Mark Salyzyn, linux-arch,
	linux-kernel

> > Although the compat_alloc_user_space implementations I looked at don't fail I
> > think a check for NULL wouldn't hurt.
> 
> The places that I looked where they check the return value use
> access_ok().  What do you think?

 
> > > +	f = compat_alloc_user_space(sizeof(*f));
> 
> I just noticed this.  Can we use memset on a user pointer?  If not, what
> would be the best way to handle this?


Good question.  Maybe the architecture-folks know an answer?
 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] aacraid 32/64 ioctl support (update)
  2004-06-16 17:19       ` Christoph Hellwig
  2004-06-16 17:51         ` Mark Haverkamp
@ 2004-06-16 18:23         ` Mark Haverkamp
  1 sibling, 0 replies; 9+ messages in thread
From: Mark Haverkamp @ 2004-06-16 18:23 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: James Bottomley, linux-scsi, Mark Salyzyn

Christoph, James,

Fixed comment items:

check return value of compat_alloc_user_space with access_ok
Got a name for 2131
aac_get_next... is static
replaced memset with clear_user
hopefully got all the '(' stuff this time
removed retval

===== drivers/scsi/aacraid/aachba.c 1.22 vs edited =====
--- 1.22/drivers/scsi/aacraid/aachba.c	2004-01-10 16:21:26 -08:00
+++ edited/drivers/scsi/aacraid/aachba.c	2004-06-16 10:54:24 -07:00
@@ -1197,7 +1197,7 @@
 		return delete_disk(dev, arg);
 	case FSACTL_FORCE_DELETE_DISK:
 		return force_delete_disk(dev, arg);
-	case 2131:
+	case FSACTL_GET_CONTAINERS:
 		return aac_get_containers(dev);
 	default:
 		return -ENOTTY;
===== drivers/scsi/aacraid/aacraid.h 1.14 vs edited =====
--- 1.14/drivers/scsi/aacraid/aacraid.h	2004-05-10 13:02:37 -07:00
+++ edited/drivers/scsi/aacraid/aacraid.h	2004-06-16 10:55:44 -07:00
@@ -650,6 +650,7 @@
 struct aac_fib_context {
 	s16	 		type;		// used for verification of structure	
 	s16	 		size;
+	u32			unique;		// unique value representing this context
 	ulong			jiffies;	// used for cleanup - dmb changed to ulong
 	struct list_head	next;		// used to link context's into a linked list
 	struct semaphore 	wait_sem;	// this is used to wait for the next fib to arrive.
@@ -1226,11 +1227,11 @@
 	u32	disknum;
 	u32	cnum;
 };
-
+ 
 struct fib_ioctl
 {
-	char	*fibctx;
-	int	wait;
+	u32	fibctx;
+	s32	wait;
 	char	*fib;
 };
 
@@ -1271,6 +1272,7 @@
 #define FSACTL_MINIPORT_REV_CHECK               CTL_CODE(2107, METHOD_BUFFERED)
 #define FSACTL_GET_PCI_INFO               	CTL_CODE(2119, METHOD_BUFFERED)
 #define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
+#define FSACTL_GET_CONTAINERS			2131
 
 
 struct aac_common
===== drivers/scsi/aacraid/commctrl.c 1.5 vs edited =====
--- 1.5/drivers/scsi/aacraid/commctrl.c	2004-05-10 13:22:40 -07:00
+++ edited/drivers/scsi/aacraid/commctrl.c	2004-06-16 11:18:30 -07:00
@@ -92,11 +92,12 @@
 		 */
 		kfib->header.XferState = 0;
 	} else {
-		if (fib_send(kfib->header.Command, fibptr, le32_to_cpu(kfib->header.Size) , FsaNormal,
-			1, 1, NULL, NULL) != 0) 
-		{
+		int retval = fib_send(kfib->header.Command, fibptr,
+				le32_to_cpu(kfib->header.Size) , FsaNormal,
+				1, 1, NULL, NULL);
+		if (retval) {
 			fib_free(fibptr);
-			return -EINVAL;
+			return retval;
 		}
 		if (fib_complete(fibptr) != 0) {
 			fib_free(fibptr);
@@ -130,14 +131,24 @@
 {
 	struct aac_fib_context * fibctx;
 	int status;
-	unsigned long flags;
 
 	fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL);
 	if (fibctx == NULL) {
 		status = -ENOMEM;
 	} else {
+		unsigned long flags;
+		struct list_head * entry;
+		struct aac_fib_context * context;
+
 		fibctx->type = FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT;
 		fibctx->size = sizeof(struct aac_fib_context);
+ 		/*
+		 *	Yes yes, I know this could be an index, but we have a
+		 * better guarantee of uniqueness for the locked loop below.
+		 * Without the aid of a persistent history, this also helps
+		 * reduce the chance that the opaque context would be reused.
+		 */
+		fibctx->unique = (u32)((ulong)fibctx & 0xFFFFFFFF);
 		/*
 		 *	Initialize the mutex used to wait for the next AIF.
 		 */
@@ -155,9 +166,22 @@
 		 *	AdapterFibContext list.
 		 */
 		spin_lock_irqsave(&dev->fib_lock, flags);
+		/* Ensure that we have a unique identifier */
+		entry = dev->fib_list.next;
+		while (entry != &dev->fib_list) {
+			context = list_entry(entry, struct aac_fib_context, next);
+			if (context->unique == fibctx->unique) {
+				/* Not unique (32 bits) */
+				fibctx->unique++;
+				entry = dev->fib_list.next;
+			} else {
+				entry = entry->next;
+			}
+		}
 		list_add_tail(&fibctx->next, &dev->fib_list);
 		spin_unlock_irqrestore(&dev->fib_lock, flags);
-		if (copy_to_user(arg,  &fibctx, sizeof(struct aac_fib_context *))) {
+		if (copy_to_user(arg,  &fibctx->unique, 
+						sizeof(fibctx->unique))) {
 			status = -EFAULT;
 		} else {
 			status = 0;
@@ -178,43 +202,44 @@
 static int next_getadapter_fib(struct aac_dev * dev, void *arg)
 {
 	struct fib_ioctl f;
-	struct aac_fib_context *fibctx, *aifcp;
 	struct fib *fib;
+	struct aac_fib_context *fibctx;
 	int status;
 	struct list_head * entry;
-	int found;
 	unsigned long flags;
 	
 	if(copy_from_user((void *)&f, arg, sizeof(struct fib_ioctl)))
 		return -EFAULT;
 	/*
-	 *	Extract the AdapterFibContext from the Input parameters.
-	 */
-	fibctx = (struct aac_fib_context *) f.fibctx;
-
-	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
 	 *
 	 *	Search the list of AdapterFibContext addresses on the adapter
 	 *	to be sure this is a valid address
 	 */
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
-	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+	while (entry != &dev->fib_list) {
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the AdapterFibContext from the Input parameters.
+		 */
+		if (fibctx->unique == f.fibctx) {   /* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
-	if (found == 0)
+	if (!fibctx) {
+		dprintk ((KERN_INFO "Fib Context not found\n"));
 		return -EINVAL;
+	}
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
-		 (fibctx->size != sizeof(struct aac_fib_context)))
+		 (fibctx->size != sizeof(struct aac_fib_context))) {
+		dprintk ((KERN_INFO "Fib Context corrupt?\n"));
 		return -EINVAL;
+	}
 	status = 0;
 	spin_lock_irqsave(&dev->fib_lock, flags);
 	/*
@@ -309,16 +334,10 @@
  
 static int close_getadapter_fib(struct aac_dev * dev, void *arg)
 {
-	struct aac_fib_context *fibctx, *aifcp;
+	struct aac_fib_context *fibctx;
 	int status;
 	unsigned long flags;
 	struct list_head * entry;
-	int found;
-
-	/*
-	 *	Extract the fibctx from the input parameters
-	 */
-	fibctx = arg;
 
 	/*
 	 *	Verify that the HANDLE passed in was a valid AdapterFibContext
@@ -327,19 +346,23 @@
 	 *	to be sure this is a valid address
 	 */
 
-	found = 0;
 	entry = dev->fib_list.next;
+	fibctx = NULL;
 
 	while(entry != &dev->fib_list) {
-		aifcp = list_entry(entry, struct aac_fib_context, next);
-		if(fibctx == aifcp) {   /* We found a winner */
-			found = 1;
+		fibctx = list_entry(entry, struct aac_fib_context, next);
+		/*
+		 *	Extract the fibctx from the input parameters
+		 */
+		if (fibctx->unique == (u32)(unsigned long)arg) {   
+			/* We found a winner */
 			break;
 		}
 		entry = entry->next;
+		fibctx = NULL;
 	}
 
-	if(found == 0)
+	if (!fibctx)
 		return 0; /* Already gone */
 
 	if((fibctx->type != FSAFS_NTC_GET_ADAPTER_FIB_CONTEXT) ||
@@ -356,8 +379,9 @@
  *	@dev: adapter
  *	@arg: ioctl arguments
  *
- *	This routine returns the firmware version.
- *      Under Linux, there have been no version incompatibilities, so this is simple!
+ *	This routine returns the driver version.
+ *      Under Linux, there have been no version incompatibilities, so this is 
+ *      simple!
  */
 
 static int check_revision(struct aac_dev *dev, void *arg)
@@ -419,6 +443,11 @@
 		goto cleanup;
 	}
 
+	if (fibsize > FIB_DATA_SIZE_IN_BYTES) {
+		rcode = -EINVAL;
+		goto cleanup;
+	}
+
 	if(copy_from_user(srbcmd, user_srb,fibsize)){
 		printk(KERN_DEBUG"aacraid: Could not copy srb from user\n"); 
 		rcode = -EFAULT;
@@ -438,7 +467,7 @@
 	srbcmd->retry_limit =cpu_to_le32(0); // Obsolete parameter
 	srbcmd->cdb_size = cpu_to_le32(srbcmd->cdb_size);
 	
-	switch(srbcmd->flags){
+	switch (srbcmd->flags & (SRB_DataIn | SRB_DataOut)) {
 	case SRB_DataOut:
 		data_dir = DMA_TO_DEVICE;
 		break;
@@ -451,17 +480,26 @@
 	default:
 		data_dir = DMA_NONE;
 	}
-	if( dev->pae_support ==1 ) {
+	if (dev->pae_support == 1) {
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
 		byte_count = 0;
 
-		// This should also catch if user used the 32 bit sgmap
-		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry64));
+		/*
+		 * This should also catch if user used the 32 bit sgmap
+		 */
+		actual_fibsize = sizeof(struct aac_srb) - 
+			sizeof(struct sgentry) + ((srbcmd->sg.count & 0xff) * 
+			 	sizeof(struct sgentry64));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
+		if ((data_dir == DMA_NONE) && psg->count) { 
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
 
 		for (i = 0; i < psg->count; i++) {
 			dma_addr_t addr; 
@@ -503,6 +541,11 @@
 		actual_fibsize = sizeof (struct aac_srb) + (((srbcmd->sg.count & 0xff) - 1) * sizeof (struct sgentry));
 		if(actual_fibsize != fibsize){ // User made a mistake - should not continue
 			printk(KERN_DEBUG"aacraid: Bad Size specified in Raw SRB command\n");
+			rcode = -EINVAL;
+			goto cleanup;
+		}
+		if ((data_dir == DMA_NONE) && psg->count) {
+			printk(KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n");
 			rcode = -EINVAL;
 			goto cleanup;
 		}
===== drivers/scsi/aacraid/linit.c 1.29 vs edited =====
--- 1.29/drivers/scsi/aacraid/linit.c	2004-05-10 04:42:31 -07:00
+++ edited/drivers/scsi/aacraid/linit.c	2004-06-16 11:02:38 -07:00
@@ -31,6 +31,7 @@
 #define AAC_DRIVER_BUILD_DATE		__DATE__
 #define AAC_DRIVERNAME			"aacraid"
 
+#include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/completion.h>
 #include <linux/init.h>
@@ -41,6 +42,8 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/syscalls.h>
+#include <linux/ioctl32.h>
 #include <asm/semaphore.h>
 
 #include <scsi/scsi.h>
@@ -168,6 +171,29 @@
 	{ aac_rx_init, "aacraid",  "ADAPTEC ", "ASR-2025SA      ", 1 }, /* ASR-2025SA      (ZCR DIMM SATA) */
 };
 
+#ifdef CONFIG_COMPAT
+/* 
+ * Promote 32 bit apps that call get_next_adapter_fib_ioctl to 64 bit version 
+ */
+static int aac_get_next_adapter_fib_ioctl(unsigned int fd, unsigned int cmd, 
+		unsigned long arg, struct file *file)
+{
+	struct fib_ioctl *f;
+
+	f = compat_alloc_user_space(sizeof(*f));
+	if (!access_ok(VERIFY_WRITE, f, sizeof(*f)))
+		return -EFAULT;
+
+	clear_user(f, sizeof(*f));
+	if (copy_from_user((void *)f, (void *)arg, 
+				sizeof(struct fib_ioctl) - sizeof(u32)))
+		return -EFAULT;
+
+	return sys_ioctl(fd, cmd, (unsigned long)f);
+}
+#endif
+
+
 /**
  *	aac_queuecommand	-	queue a SCSI command
  *	@cmd:		SCSI command to queue
@@ -643,12 +669,39 @@
 		printk(KERN_WARNING
 		       "aacraid: unable to register \"aac\" device.\n");
 	}
+#ifdef CONFIG_COMPAT
+	register_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK, NULL);
+	register_ioctl32_conversion(FSACTL_SENDFIB, NULL);
+	register_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB, NULL);
+	register_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB, 
+		aac_get_next_adapter_fib_ioctl);
+	register_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB, NULL);
+	register_ioctl32_conversion(FSACTL_SEND_RAW_SRB, NULL);
+	register_ioctl32_conversion(FSACTL_GET_PCI_INFO, NULL);
+	register_ioctl32_conversion(FSACTL_QUERY_DISK, NULL);
+	register_ioctl32_conversion(FSACTL_DELETE_DISK, NULL);
+	register_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK, NULL);
+	register_ioctl32_conversion(FSACTL_GET_CONTAINERS, NULL);
+#endif
 
 	return 0;
 }
 
 static void __exit aac_exit(void)
 {
+#ifdef CONFIG_COMPAT
+	unregister_ioctl32_conversion(FSACTL_MINIPORT_REV_CHECK);
+	unregister_ioctl32_conversion(FSACTL_SENDFIB);
+	unregister_ioctl32_conversion(FSACTL_OPEN_GET_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_GET_NEXT_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_CLOSE_GET_ADAPTER_FIB);
+	unregister_ioctl32_conversion(FSACTL_SEND_RAW_SRB);
+	unregister_ioctl32_conversion(FSACTL_GET_PCI_INFO);
+	unregister_ioctl32_conversion(FSACTL_QUERY_DISK);
+	unregister_ioctl32_conversion(FSACTL_DELETE_DISK);
+	unregister_ioctl32_conversion(FSACTL_FORCE_DELETE_DISK);
+	unregister_ioctl32_conversion(FSACTL_GET_CONTAINERS);
+#endif
 	unregister_chrdev(aac_cfg_major, "aac");
 	pci_unregister_driver(&aac_pci_driver);
 }


-- 
Mark Haverkamp <markh@osdl.org>


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-06-16 18:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-16 15:52 [PATCH] aacraid 32/64 ioctl support (update) Mark Haverkamp
2004-06-16 16:01 ` Christoph Hellwig
2004-06-16 16:02   ` Christoph Hellwig
2004-06-16 17:12     ` Mark Haverkamp
2004-06-16 17:19       ` Christoph Hellwig
2004-06-16 17:51         ` Mark Haverkamp
2004-06-16 17:53           ` Christoph Hellwig
2004-06-16 17:52             ` David S. Miller
2004-06-16 18:23         ` Mark Haverkamp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox