--- /dev/null
+diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.c linux-2.4.21/drivers/scsi/megaraid.c
+--- linux-2.4.21.org/drivers/scsi/megaraid.c 2003-06-13 14:51:36.000000000 +0000
++++ linux-2.4.21/drivers/scsi/megaraid.c 2003-07-07 17:44:56.000000000 +0000
+@@ -9,7 +9,7 @@
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+- * Version : v1.18f (Dec 10, 2002)
++ * Version : v1.18j (July 7, 2003)
+ *
+ * Description: Linux device driver for LSI Logic MegaRAID controller
+ *
+@@ -512,6 +512,47 @@
+ *
+ * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers.
+ *
++ * Version 1.18g
++ * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
++ *
++ * Write the interrupt valid signature 0x10001234 as soon as reading it to
++ * flush memory caches.
++ *
++ * While sending back the inquiry information, check if the original request
++ * had an associated scatter-gather list and tranfer data from bounce buffer
++ * accordingly.
++ *
++ * Version 1.18h
++ * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
++ *
++ * Reduce the number of sectors per command to 128 from original value of
++ * 1024. Big IO sizes along with certain other operation going on in parallel,
++ * e.g., check consistency and rebuild put a heavy constraint on fW resources
++ * resulting in aborted commands.
++ *
++ * Version 1.18i
++ * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker <atulm@lsil.com>
++ *
++ * Request and reserve memory/IO regions. Otherwise a panic occurs if 2.00.x
++ * driver is loaded on top of 1.18x driver
++ *
++ * Prevent memory leak in cases when data transfer from/to application fails
++ * and ioctl is failing.
++ *
++ * Set the PCI dma_mask to default value of 0xFFFFFFFF when we get a handle to
++ * it. The previous value of 64-bit might be sticky and would cause the memory
++ * for mailbox and scatter lists to be allocated beyond 4GB. This was observed
++ * on an Itenium
++ *
++ * Version 1.18j
++ * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker <atulm@lsil.com>
++ *
++ * Disable /proc/megaraid/stat file to prevent buffer overflow error during
++ * read of this file.
++ *
++ * Add support for ioctls on AMD-64 bit platforms
++ * - Sreenivas Bagalkote <sreenib@lsil.com>
++ *
+ * BUGS:
+ * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
+ * fails to detect the controller as a pci device on the system.
+@@ -575,12 +616,27 @@
+ #include <linux/reboot.h>
+ #include <linux/init.h>
+
++#ifdef __x86_64__
++#include <asm/ioctl32.h>
++#endif
++
+ #include "sd.h"
+ #include "scsi.h"
+ #include "hosts.h"
+
+ #include "megaraid.h"
+
++#ifdef __x86_64__
++/*
++ * The IOCTL cmd received from 32 bit compiled applications
++ */
++
++extern int register_ioctl32_conversion( unsigned int cmd,
++ int(*handler)(unsigned int, unsigned int, unsigned long,
++ struct file* ));
++extern int unregister_ioctl32_conversion( unsigned int cmd );
++#endif
++
+ /*
+ *================================================================
+ * #Defines
+@@ -1141,8 +1197,14 @@
+ switch (SCpnt->cmnd[0]) {
+ case INQUIRY:
+ case READ_CAPACITY:
+- memcpy (SCpnt->request_buffer,
+- pScb->bounce_buffer, SCpnt->request_bufflen);
++ if ( SCpnt->use_sg ) {
++ sgList = (struct scatterlist *)SCpnt->request_buffer;
++ memcpy(sgList[0].address, pScb->bounce_buffer,
++ SCpnt->request_bufflen);
++ } else {
++ memcpy (SCpnt->request_buffer, pScb->bounce_buffer,
++ SCpnt->request_bufflen);
++ }
+ break;
+ }
+ #endif
+@@ -2202,30 +2264,22 @@
+ megaCfg = (mega_host_config *) devp;
+ mbox = (mega_mailbox *) tmpBox;
+
+- if (megaCfg->host->irq == irq) {
+- if (megaCfg->flag & IN_ISR) {
+- TRACE (("ISR called reentrantly!!\n"));
+- printk ("ISR called reentrantly!!\n");
+- }
+- megaCfg->flag |= IN_ISR;
+-
+- if (mega_busyWaitMbox (megaCfg)) {
+- printk (KERN_WARNING "Error: mailbox busy in isr!\n");
+- }
++ IO_LOCK;
+
+ /* Check if a valid interrupt is pending */
+ if (megaCfg->flag & BOARD_QUARTZ) {
+ dword = RDOUTDOOR (megaCfg);
+ if (dword != 0x10001234) {
+ /* Spurious interrupt */
+- megaCfg->flag &= ~IN_ISR;
++ IO_UNLOCK;
+ return;
+ }
++ WROUTDOOR (megaCfg, 0x10001234);
+ } else {
+ byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
+ if ((byte & VALID_INTR_BYTE) == 0) {
+ /* Spurious interrupt */
+- megaCfg->flag &= ~IN_ISR;
++ IO_UNLOCK;
+ return;
+ }
+ WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
+@@ -2234,58 +2288,26 @@
+ for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
+ completed[idx] = 0;
+
+- IO_LOCK;
+
+ megaCfg->nInterrupts++;
+- qCnt = 0xff;
+ while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ;
++ megaCfg->mbox->numstatus = 0xFF;
+
+- qStatus = 0xff;
+- while ((qStatus = megaCfg->mbox->status) == 0xFF) ;
++ qStatus = megaCfg->mbox->status;
+
+ /* Get list of completed requests */
+ for (idx = 0; idx < qCnt; idx++) {
+- while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
+- printk ("p");
+- }
+- completed[idx] = sIdx;
+- sIdx = 0xFF;
++ completed[idx] = megaCfg->mbox->completed[idx];
+ }
+
+ if (megaCfg->flag & BOARD_QUARTZ) {
+- WROUTDOOR (megaCfg, dword);
+ /* Acknowledge interrupt */
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+- /* In this case mbox contains physical address */
+-#if 0
+- WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2);
+-#else
+ WRINDOOR (megaCfg, 0x2);
+-#endif
+-
+-#else
+-
+-#if 0
+- WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+-#else
+- WRINDOOR (megaCfg, 0x2);
+-#endif
+-
+-#endif
+-
+-#if 0
+ while (RDINDOOR (megaCfg) & 0x02) ;
+-#endif
+ } else {
+ CLEAR_INTR (megaCfg->host->io_port);
+ }
+
+-#if DEBUG
+- if (qCnt >= MAX_FIRMWARE_STATUS) {
+- printk ("megaraid_isr: cmplt=%d ", qCnt);
+- }
+-#endif
+-
+ for (idx = 0; idx < qCnt; idx++) {
+ sIdx = completed[idx];
+ if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
+@@ -2355,26 +2377,24 @@
+ mega_runpendq (megaCfg);
+ IO_UNLOCK;
+
+- }
+-
+ }
+
+ /*==================================================*/
+ /* Wait until the controller's mailbox is available */
+ /*==================================================*/
+
+-static int mega_busyWaitMbox (mega_host_config * megaCfg)
++static inline int mega_busyWaitMbox (mega_host_config * megaCfg)
+ {
+ mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+ long counter;
+
+- for (counter = 0; counter < 10000; counter++) {
++ for (counter = 0; counter < 10; counter++) {
+ if (!mbox->busy) {
+ return 0;
+ }
+- udelay (100);
++ udelay (1);
+ }
+- return -1; /* give up after 1 second */
++ return -1; /* give up after 10 usecs */
+ }
+
+ /*=====================================================
+@@ -2420,25 +2440,8 @@
+ phys_mbox = virt_to_bus (megaCfg->mbox);
+ #endif
+
+-#if DEBUG
+- ShowMbox (pScb);
+-#endif
+-
+ /* Wait until mailbox is free */
+ if (mega_busyWaitMbox (megaCfg)) {
+- printk ("Blocked mailbox......!!\n");
+- udelay (1000);
+-
+-#if DEBUG
+- showMbox (pLastScb);
+-#endif
+-
+- /* Abort command */
+- if (pScb == NULL) {
+- TRACE (("NULL pScb in megaIssue\n"));
+- printk ("NULL pScb in megaIssue\n");
+- }
+- mega_cmd_done (megaCfg, pScb, 0x08);
+ return -1;
+ }
+
+@@ -2486,13 +2489,10 @@
+ WRINDOOR (megaCfg, phys_mbox | 0x1);
+
+ while (mbox->numstatus == 0xFF) ;
+- while (mbox->status == 0xFF) ;
+ while (mbox->mraid_poll != 0x77) ;
+ mbox->mraid_poll = 0;
+ mbox->mraid_ack = 0x77;
+-
+- /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
+- WROUTDOOR (megaCfg, cmdDone); */
++ mbox->numstatus = 0xFF;
+
+ if (pScb) {
+ mega_cmd_done (megaCfg, pScb, mbox->status);
+@@ -2523,12 +2523,6 @@
+ enable_irq (megaCfg->host->irq);
+ retval = mbox->status;
+ }
+-#if DEBUG
+- while (mega_busyWaitMbox (megaCfg)) {
+- printk(KERN_ERR "Blocked mailbox on exit......!\n");
+- udelay (1000);
+- }
+-#endif
+
+ return retval;
+ }
+@@ -2964,15 +2958,15 @@
+
+ int i, j;
+
+-#if BITS_PER_LONG==64
+- u64 megaBase;
+-#else
+- u32 megaBase;
+-#endif
++ unsigned long megaBase;
++ unsigned long tbase;
+
+ u16 pciIdx = 0;
+ u16 numFound = 0;
+ u16 subsysid, subsysvid;
++ u8 did_mem_map_f = 0;
++ u8 did_io_map_f = 0;
++ u8 did_scsi_register_f = 0;
+
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) /* 0x20100 */
+ while (!pcibios_find_device
+@@ -2991,6 +2985,17 @@
+ pciBus = pdev->bus->number;
+ pciDevFun = pdev->devfn;
+ #endif
++
++ /*
++ * Set the dma_mask to default value. It might be sticky from previous
++ * insmod-rmmod sequence
++ */
++ pdev->dma_mask = 0xFFFFFFFF;
++
++ did_mem_map_f = 0;
++ did_io_map_f = 0;
++ did_scsi_register_f = 0;
++
+ if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
+ if( (pciVendor == PCI_VENDOR_ID_PERC4_DI_YSTONE &&
+ pciDev == PCI_DEVICE_ID_PERC4_DI_YSTONE) ||
+@@ -3041,6 +3046,7 @@
+ if( (subsysvid != AMI_SUBSYS_ID) &&
+ (subsysvid != DELL_SUBSYS_ID) &&
+ (subsysvid != LSI_SUBSYS_ID) &&
++ (subsysvid != INTEL_SUBSYS_ID) &&
+ (subsysvid != HP_SUBSYS_ID) ) continue;
+
+ }
+@@ -3065,22 +3071,55 @@
+ megaIrq = pdev->irq;
+ #endif
+
++ tbase = megaBase;
++
+ pciIdx++;
+
+ if (flag & BOARD_QUARTZ) {
++
+ megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
++
++ if( ! request_mem_region(megaBase, 128,
++ "MegaRAID: LSI Logic Corporation" ) ) {
++
++ printk(KERN_WARNING "megaraid: mem region busy!\n");
++
++ continue;
++ }
++
+ megaBase = (long) ioremap (megaBase, 128);
+- if (!megaBase)
++
++ if (!megaBase) {
++
++ printk(KERN_WARNING "megaraid: could not map hba memory!\n");
++
++ release_mem_region(tbase, 128);
++
+ continue;
++ }
++ did_mem_map_f = 1;
++
+ } else {
+ megaBase &= PCI_BASE_ADDRESS_IO_MASK;
+ megaBase += 0x10;
++
++ if( ! request_region(megaBase, 16,
++ "MegaRAID: LSI Logic Corporation") ) {
++
++ printk(KERN_WARNING "megaraid: region busy.\n");
++
++ continue;
++ }
++ did_io_map_f = 1;
++
+ }
+
+ /* Initialize SCSI Host structure */
+ host = scsi_register (pHostTmpl, sizeof (mega_host_config));
+ if (!host)
+- goto err_unmap;
++ goto fail_attach;
++
++ did_scsi_register_f = 1;
+
+ /*
+ * Comment the following initialization if you know 'max_sectors' is
+@@ -3088,7 +3127,7 @@
+ * This field was introduced in Linus's kernel 2.4.7pre3 and it
+ * greatly increases the IO performance - AM
+ */
+- host->max_sectors = 1024;
++ host->max_sectors = 128;
+
+ scsi_set_pci_device(host, pdev);
+ megaCfg = (mega_host_config *) host->hostdata;
+@@ -3130,11 +3169,8 @@
+ megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
+ megaCtlrs[numCtlrs] = megaCfg;
+
+- if (!(flag & BOARD_QUARTZ)) {
+-
+- /* Request our IO Range */
+- if( !request_region(megaBase, 16, "megaraid") )
+- goto err_unregister;
++ if (flag & BOARD_QUARTZ) {
++ megaCfg->host->base = tbase;
+ }
+
+ /* Request our IRQ */
+@@ -3143,7 +3179,7 @@
+ printk (KERN_WARNING
+ "megaraid: Couldn't register IRQ %d!\n",
+ megaIrq);
+- goto err_release;
++ goto fail_attach;
+ }
+
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
+@@ -3265,8 +3301,7 @@
+ sizeof (mega_mailbox64),
+ (void *) megaCfg->mailbox64ptr,
+ megaCfg->dma_handle64);
+- scsi_unregister (host);
+- continue;
++ goto fail_attach;
+ }
+
+ /*
+@@ -3301,14 +3336,17 @@
+ #endif
+ #endif
+ continue;
+- err_release:
+- if (flag & BOARD_QUARTZ)
+- release_region (megaBase, 16);
+- err_unregister:
+- scsi_unregister (host);
+- err_unmap:
+- if (flag & BOARD_QUARTZ)
+- iounmap ((void *) megaBase);
++fail_attach:
++ if( did_mem_map_f ) {
++ iounmap((void *)megaBase);
++ release_mem_region(tbase, 128);
++ }
++ if( did_io_map_f ) {
++ release_region(megaBase, 16);
++ }
++ if( did_scsi_register_f ) {
++ scsi_unregister (host);
++ }
+ }
+ return numFound;
+ }
+@@ -3408,6 +3446,12 @@
+ }
+
+ init_MUTEX (&mimd_entry_mtx);
++#ifdef __x86_64__
++ /*
++ * Register the 32-bit ioctl conversion
++ */
++ register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl );
++#endif
+ }
+
+ return count;
+@@ -3439,6 +3483,7 @@
+ /* Free our resources */
+ if (megaCfg->flag & BOARD_QUARTZ) {
+ iounmap ((void *) megaCfg->base);
++ release_mem_region(megaCfg->host->base, 128);
+ } else {
+ release_region (megaCfg->host->io_port, 16);
+ }
+@@ -3485,6 +3530,9 @@
+
+ unregister_chrdev (major, "megadev");
+ unregister_reboot_notifier (&mega_notifier);
++#ifdef __x86_64__
++ unregister_ioctl32_conversion( MEGAIOCCMD );
++#endif
+
+ return 0;
+ }
+@@ -4244,6 +4292,11 @@
+ proc_printf (megaCfg, "Interrupts Collected = %lu\n",
+ megaCfg->nInterrupts);
+
++ proc_printf (megaCfg, "INTERFACE DISABLED\n");
++ COPY_BACK;
++ return count;
++
++#if 0 // can cause buffer overrun with 40 logical drives and IO information
+ for (i = 0; i < megaCfg->numldrv; i++) {
+ proc_printf (megaCfg, "Logical Drive %d:\n", i);
+
+@@ -4259,6 +4312,7 @@
+
+ COPY_BACK;
+ return count;
++#endif
+ }
+
+ static int proc_read_status (char *page, char **start, off_t offset,
+@@ -4896,16 +4950,16 @@
+ if( kvaddr == NULL ) {
+ printk(KERN_WARNING "megaraid:allocation failed\n");
+ ret = -ENOMEM;
+- goto out;
++ goto out_ioctl_cmd_new;
+ }
+
+ ioc.ui.fcs.buffer = kvaddr;
+
+ if (inlen) {
+ /* copyin the user data */
+- if (copy_from_user(kvaddr, (char *)uaddr, length )) {
+- ret = -EFAULT;
+- goto out;
++ if( copy_from_user(kvaddr, (char *)uaddr, length ) ) {
++ ret = -EFAULT;
++ goto out_ioctl_cmd_new;
+ }
+ }
+ }
+@@ -4923,9 +4977,10 @@
+ down(&mimd_ioctl_sem);
+
+ if( !scsicmd->result && outlen ) {
+- if (copy_to_user(uaddr, kvaddr, length))
+- ret = -EFAULT;
+- goto out;
++ if (copy_to_user(uaddr, kvaddr, length)) {
++ return -EFAULT;
++ goto out_ioctl_cmd_new;
++ }
+ }
+
+ /*
+@@ -4944,7 +4999,8 @@
+ put_user (scsicmd->result, &uioc->mbox[17]);
+ }
+
+-out:
++out_ioctl_cmd_new:
++
+ if (kvaddr) {
+ dma_free_consistent(pdevp, length, kvaddr, dma_addr);
+ }
+@@ -5045,12 +5101,8 @@
+
+ if( kvaddr == NULL ) {
+ printk (KERN_WARNING "megaraid:allocation failed\n");
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
+- kfree(scsicmd);
+-#else
+- scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
+-#endif
+- return -ENOMEM;
++ ret = -ENOMEM;
++ goto out_ioctl_cmd;
+ }
+
+ ioc.data = kvaddr;
+@@ -5058,9 +5110,15 @@
+ if (inlen) {
+ if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
+ /* copyin the user data */
+- copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen);
++ if( copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen)){
++ ret = -EFAULT;
++ goto out_ioctl_cmd;
++ }
+ } else {
+- copy_from_user (kvaddr, uaddr, inlen);
++ if( copy_from_user (kvaddr, uaddr, inlen) ) {
++ ret = -EFAULT;
++ goto out_ioctl_cmd;
++ }
+ }
+ }
+ }
+@@ -5078,11 +5136,15 @@
+
+ if (!scsicmd->result && outlen) {
+ if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
+- if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen))
++ if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) {
+ ret = -EFAULT;
++ goto out_ioctl_cmd;
++ }
+ } else {
+- if (copy_to_user (uaddr, kvaddr, outlen))
++ if (copy_to_user (uaddr, kvaddr, outlen)) {
+ ret = -EFAULT;
++ goto out_ioctl_cmd;
++ }
+ }
+ }
+
+@@ -5107,6 +5169,8 @@
+ put_user (scsicmd->result, &uioc->mbox[17]); /* status */
+ }
+
++out_ioctl_cmd:
++
+ if (kvaddr) {
+ dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
+ }
+diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.h linux-2.4.21/drivers/scsi/megaraid.h
+--- linux-2.4.21.org/drivers/scsi/megaraid.h 2003-06-13 14:51:36.000000000 +0000
++++ linux-2.4.21/drivers/scsi/megaraid.h 2003-07-07 17:43:59.000000000 +0000
+@@ -30,7 +30,8 @@
+ #define M_RD_IOCTL_CMD_NEW 0x81
+ #define M_RD_DRIVER_IOCTL_INTERFACE 0x82
+
+-#define MEGARAID_VERSION "v1.18f (Release Date: Tue Dec 10 09:54:39 EST 2002)\n"
++#define MEGARAID_VERSION "v1.18j (Release Date: Mon Jul 7 14:39:55 EDT 2003)\n"
++
+
+ #define MEGARAID_IOCTL_VERSION 114
+
+@@ -190,6 +191,7 @@
+ #define AMI_SUBSYS_ID 0x101E
+ #define DELL_SUBSYS_ID 0x1028
+ #define HP_SUBSYS_ID 0x103C
++#define INTEL_SUBSYS_ID 0x8086
+
+ #define AMI_SIGNATURE 0x3344
+ #define AMI_SIGNATURE_471 0xCCCC
+@@ -899,7 +901,9 @@
+ * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE
+ */
+ #define MEGAIOC_MAGIC 'm'
+-#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */
++
++/* Mega IOCTL command */
++#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t)
+
+ #define MEGAIOC_QNADAP 'm' /* Query # of adapters */
+ #define MEGAIOC_QDRVRVER 'e' /* Query driver version */