[SCSI] 2.6 aacraid: Variable FIB size (updated patch)

New code from the Adaptec driver.  Performance enhancement for newer
adapters.  I hope that this isn't too big for a single patch.  I believe
that other than the few small cleanups mentioned, that the changes are
all related.

- Added Variable FIB size negotiation for new adapters.
- Added support to maximize scatter gather tables and thus permit
  requests larger than 64KB/each.
- Limit Scatter Gather to 34 elements for ROMB platforms.
- aac_printf is only enabled with AAC_QUIRK_34SG
- Large FIB ioctl support
- some minor cleanup

Passes sparse check.
I have tested it on x86 and ppc64 machines.

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 9946e30..f02c996 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -53,10 +53,6 @@
 #define	INQD_PDT_DMASK	0x1F	/* Peripheral Device Type Mask */
 #define	INQD_PDT_QMASK	0xE0	/* Peripheral Device Qualifer Mask */
 
-#define MAX_FIB_DATA (sizeof(struct hw_fib) - sizeof(FIB_HEADER))
-
-#define MAX_DRIVER_SG_SEGMENT_COUNT 17
-
 /*
  *	Sense codes
  */
@@ -158,6 +154,13 @@
 module_param(commit, int, 0);
 MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
 
+int numacb = -1;
+module_param(numacb, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware.");
+
+int acbsize = -1;
+module_param(acbsize, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware.");
 /**
  *	aac_get_config_status	-	check the adapter configuration
  *	@common: adapter to query
@@ -462,7 +465,7 @@
 			    1, 1,
 			    NULL, NULL);
 	if (status < 0) {
-		printk(KERN_WARNING "aacraid: probe_containers query failed.\n");
+		printk(KERN_WARNING "aacraid: probe_container query failed.\n");
 		goto error;
 	}
 
@@ -605,35 +608,63 @@
 int aac_get_adapter_info(struct aac_dev* dev)
 {
 	struct fib* fibptr;
-	struct aac_adapter_info* info;
 	int rcode;
 	u32 tmp;
+	struct aac_adapter_info * info;
+
 	if (!(fibptr = fib_alloc(dev)))
 		return -ENOMEM;
 
 	fib_init(fibptr);
-	info = (struct aac_adapter_info*) fib_data(fibptr);
-
-	memset(info,0,sizeof(struct aac_adapter_info));
+	info = (struct aac_adapter_info *) fib_data(fibptr);
+	memset(info,0,sizeof(*info));
 
 	rcode = fib_send(RequestAdapterInfo,
-			fibptr, 
-			sizeof(struct aac_adapter_info),
-			FsaNormal, 
-			1, 1, 
-			NULL, 
-			NULL);
+			 fibptr, 
+			 sizeof(*info),
+			 FsaNormal, 
+			 1, 1, 
+			 NULL, 
+			 NULL);
 
-	memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info));
+	if (rcode < 0) {
+		fib_complete(fibptr);
+		fib_free(fibptr);
+		return rcode;
+	}
+	memcpy(&dev->adapter_info, info, sizeof(*info));
+
+	if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
+		struct aac_supplement_adapter_info * info;
+
+		fib_init(fibptr);
+
+		info = (struct aac_supplement_adapter_info *) fib_data(fibptr);
+
+		memset(info,0,sizeof(*info));
+
+		rcode = fib_send(RequestSupplementAdapterInfo,
+				 fibptr,
+				 sizeof(*info),
+				 FsaNormal,
+				 1, 1,
+				 NULL,
+				 NULL);
+
+		if (rcode >= 0)
+			memcpy(&dev->supplement_adapter_info, info, sizeof(*info));
+	}
 
 	tmp = le32_to_cpu(dev->adapter_info.kernelrev);
-	printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d]\n", 
+	printk(KERN_INFO "%s%d: kernel %d.%d-%d[%d] %.*s\n", 
 			dev->name, 
 			dev->id,
 			tmp>>24,
 			(tmp>>16)&0xff,
 			tmp&0xff,
-			le32_to_cpu(dev->adapter_info.kernelbuild));
+			le32_to_cpu(dev->adapter_info.kernelbuild),
+			(int)sizeof(dev->supplement_adapter_info.BuildDate),
+			dev->supplement_adapter_info.BuildDate);
 	tmp = le32_to_cpu(dev->adapter_info.monitorrev);
 	printk(KERN_INFO "%s%d: monitor %d.%d-%d[%d]\n", 
 			dev->name, dev->id,
@@ -707,6 +738,38 @@
 			rcode = -ENOMEM;
 		}
 	}
+	/* 
+	 * 57 scatter gather elements 
+	 */
+	dev->scsi_host_ptr->sg_tablesize = (dev->max_fib_size -
+		sizeof(struct aac_fibhdr) -
+		sizeof(struct aac_write) + sizeof(struct sgmap)) /
+			sizeof(struct sgmap);
+	if (dev->dac_support) {
+		/* 
+		 * 38 scatter gather elements 
+		 */
+		dev->scsi_host_ptr->sg_tablesize =
+			(dev->max_fib_size -
+			sizeof(struct aac_fibhdr) -
+			sizeof(struct aac_write64) +
+			sizeof(struct sgmap64)) /
+				sizeof(struct sgmap64);
+	}
+	dev->scsi_host_ptr->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
+	if(!(dev->adapter_info.options & AAC_OPT_NEW_COMM)) {
+		/*
+		 * Worst case size that could cause sg overflow when
+		 * we break up SG elements that are larger than 64KB.
+		 * Would be nice if we could tell the SCSI layer what
+		 * the maximum SG element size can be. Worst case is
+		 * (sg_tablesize-1) 4KB elements with one 64KB
+		 * element.
+		 *	32bit -> 468 or 238KB	64bit -> 424 or 212KB
+		 */
+		dev->scsi_host_ptr->max_sectors =
+		  (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
+	}
 
 	fib_complete(fibptr);
 	fib_free(fibptr);
@@ -747,8 +810,10 @@
 	if (le32_to_cpu(readreply->status) == ST_OK)
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 	else {
-		printk(KERN_WARNING "read_callback: read failed, status = %d\n",
-				le32_to_cpu(readreply->status));
+#ifdef AAC_DETAILED_STATUS_INFO
+		printk(KERN_WARNING "read_callback: io failed, status = %d\n",
+		  le32_to_cpu(readreply->status));
+#endif
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
 		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
 				    HARDWARE_ERROR,
@@ -842,7 +907,8 @@
 		lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5];
 		count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8];
 	}
-	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies));
+	dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n",
+	  smp_processor_id(), (unsigned long long)lba, jiffies));
 	/*
 	 *	Alocate and initialize a Fib
 	 */
@@ -852,7 +918,7 @@
 
 	fib_init(cmd_fibcontext);
 
-	if(dev->dac_support == 1) {
+	if (dev->dac_support == 1) {
 		struct aac_read64 *readcmd;
 		readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext);
 		readcmd->command = cpu_to_le32(VM_CtHostRead64);
@@ -886,14 +952,11 @@
 		readcmd->block = cpu_to_le32(lba);
 		readcmd->count = cpu_to_le32(count * 512);
 
-		if (count * 512 > (64 * 1024))
-			BUG();
-
 		aac_build_sg(scsicmd, &readcmd->sg);
 		fibsize = sizeof(struct aac_read) + 
 			((le32_to_cpu(readcmd->sg.count) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -976,7 +1039,7 @@
 		fibsize = sizeof(struct aac_write64) + 
 			((le32_to_cpu(writecmd->sg.count) - 1) * 
 			 sizeof (struct sgentry64));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -998,15 +1061,11 @@
 		writecmd->sg.count = cpu_to_le32(1);
 		/* ->stable is not used - it did mean which type of write */
 
-		if (count * 512 > (64 * 1024)) {
-			BUG();
-		}
-
 		aac_build_sg(scsicmd, &writecmd->sg);
 		fibsize = sizeof(struct aac_write) + 
 			((le32_to_cpu(writecmd->sg.count) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 		/*
 		 *	Now send the Fib to the adapter
@@ -1025,7 +1084,6 @@
 	 */
 	if (status == -EINPROGRESS)
 	{
-		dprintk("write queued.\n");
 		return 0;
 	}
 
@@ -1111,7 +1169,7 @@
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 
 	/*
-	 *	Alocate and initialize a Fib
+	 *	Allocate and initialize a Fib
 	 */
 	if (!(cmd_fibcontext = 
 	    fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 
@@ -1403,7 +1461,7 @@
 			/*
 			 *	Unhandled commands
 			 */
-			printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]);
+			dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));
 			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
 			set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
 				ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
@@ -1818,7 +1876,7 @@
 		fibsize = sizeof (struct aac_srb) - sizeof (struct sgentry) +
 			((le32_to_cpu(srbcmd->sg.count) & 0xff) * 
 			 sizeof (struct sgentry64));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 
 		/*
@@ -1840,7 +1898,7 @@
 		fibsize = sizeof (struct aac_srb) + 
 			(((le32_to_cpu(srbcmd->sg.count) & 0xff) - 1) * 
 			 sizeof (struct sgentry));
-		BUG_ON (fibsize > (sizeof(struct hw_fib) - 
+		BUG_ON (fibsize > (dev->max_fib_size -
 					sizeof(struct aac_fibhdr)));
 
 		/*