1 diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.c linux-2.4.21/drivers/scsi/megaraid.c
2 --- linux-2.4.21.org/drivers/scsi/megaraid.c 2003-06-13 14:51:36.000000000 +0000
3 +++ linux-2.4.21/drivers/scsi/megaraid.c 2003-07-07 17:44:56.000000000 +0000
5 * as published by the Free Software Foundation; either version
6 * 2 of the License, or (at your option) any later version.
8 - * Version : v1.18f (Dec 10, 2002)
9 + * Version : v1.18j (July 7, 2003)
11 * Description: Linux device driver for LSI Logic MegaRAID controller
15 * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers.
18 + * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
20 + * Write the interrupt valid signature 0x10001234 as soon as reading it to
21 + * flush memory caches.
23 + * While sending back the inquiry information, check if the original request
24 + * had an associated scatter-gather list and tranfer data from bounce buffer
28 + * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
30 + * Reduce the number of sectors per command to 128 from original value of
31 + * 1024. Big IO sizes along with certain other operation going on in parallel,
32 + * e.g., check consistency and rebuild put a heavy constraint on fW resources
33 + * resulting in aborted commands.
36 + * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker <atulm@lsil.com>
38 + * Request and reserve memory/IO regions. Otherwise a panic occurs if 2.00.x
39 + * driver is loaded on top of 1.18x driver
41 + * Prevent memory leak in cases when data transfer from/to application fails
42 + * and ioctl is failing.
44 + * Set the PCI dma_mask to default value of 0xFFFFFFFF when we get a handle to
45 + * it. The previous value of 64-bit might be sticky and would cause the memory
46 + * for mailbox and scatter lists to be allocated beyond 4GB. This was observed
50 + * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker <atulm@lsil.com>
52 + * Disable /proc/megaraid/stat file to prevent buffer overflow error during
53 + * read of this file.
55 + * Add support for ioctls on AMD-64 bit platforms
56 + * - Sreenivas Bagalkote <sreenib@lsil.com>
59 * Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
60 * fails to detect the controller as a pci device on the system.
62 #include <linux/reboot.h>
63 #include <linux/init.h>
66 +#include <asm/ioctl32.h>
77 + * The IOCTL cmd received from 32 bit compiled applications
80 +extern int register_ioctl32_conversion( unsigned int cmd,
81 + int(*handler)(unsigned int, unsigned int, unsigned long,
83 +extern int unregister_ioctl32_conversion( unsigned int cmd );
87 *================================================================
89 @@ -1141,8 +1197,14 @@
90 switch (SCpnt->cmnd[0]) {
93 - memcpy (SCpnt->request_buffer,
94 - pScb->bounce_buffer, SCpnt->request_bufflen);
95 + if ( SCpnt->use_sg ) {
96 + sgList = (struct scatterlist *)SCpnt->request_buffer;
97 + memcpy(sgList[0].address, pScb->bounce_buffer,
98 + SCpnt->request_bufflen);
100 + memcpy (SCpnt->request_buffer, pScb->bounce_buffer,
101 + SCpnt->request_bufflen);
106 @@ -2202,30 +2264,22 @@
107 megaCfg = (mega_host_config *) devp;
108 mbox = (mega_mailbox *) tmpBox;
110 - if (megaCfg->host->irq == irq) {
111 - if (megaCfg->flag & IN_ISR) {
112 - TRACE (("ISR called reentrantly!!\n"));
113 - printk ("ISR called reentrantly!!\n");
115 - megaCfg->flag |= IN_ISR;
117 - if (mega_busyWaitMbox (megaCfg)) {
118 - printk (KERN_WARNING "Error: mailbox busy in isr!\n");
122 /* Check if a valid interrupt is pending */
123 if (megaCfg->flag & BOARD_QUARTZ) {
124 dword = RDOUTDOOR (megaCfg);
125 if (dword != 0x10001234) {
126 /* Spurious interrupt */
127 - megaCfg->flag &= ~IN_ISR;
131 + WROUTDOOR (megaCfg, 0x10001234);
133 byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
134 if ((byte & VALID_INTR_BYTE) == 0) {
135 /* Spurious interrupt */
136 - megaCfg->flag &= ~IN_ISR;
140 WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
141 @@ -2234,58 +2288,26 @@
142 for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
147 megaCfg->nInterrupts++;
149 while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ;
150 + megaCfg->mbox->numstatus = 0xFF;
153 - while ((qStatus = megaCfg->mbox->status) == 0xFF) ;
154 + qStatus = megaCfg->mbox->status;
156 /* Get list of completed requests */
157 for (idx = 0; idx < qCnt; idx++) {
158 - while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
161 - completed[idx] = sIdx;
163 + completed[idx] = megaCfg->mbox->completed[idx];
166 if (megaCfg->flag & BOARD_QUARTZ) {
167 - WROUTDOOR (megaCfg, dword);
168 /* Acknowledge interrupt */
169 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
170 - /* In this case mbox contains physical address */
172 - WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2);
174 WRINDOOR (megaCfg, 0x2);
180 - WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
182 - WRINDOOR (megaCfg, 0x2);
188 while (RDINDOOR (megaCfg) & 0x02) ;
191 CLEAR_INTR (megaCfg->host->io_port);
195 - if (qCnt >= MAX_FIRMWARE_STATUS) {
196 - printk ("megaraid_isr: cmplt=%d ", qCnt);
200 for (idx = 0; idx < qCnt; idx++) {
201 sIdx = completed[idx];
202 if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
203 @@ -2355,26 +2377,24 @@
204 mega_runpendq (megaCfg);
211 /*==================================================*/
212 /* Wait until the controller's mailbox is available */
213 /*==================================================*/
215 -static int mega_busyWaitMbox (mega_host_config * megaCfg)
216 +static inline int mega_busyWaitMbox (mega_host_config * megaCfg)
218 mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
221 - for (counter = 0; counter < 10000; counter++) {
222 + for (counter = 0; counter < 10; counter++) {
229 - return -1; /* give up after 1 second */
230 + return -1; /* give up after 10 usecs */
233 /*=====================================================
234 @@ -2420,25 +2440,8 @@
235 phys_mbox = virt_to_bus (megaCfg->mbox);
242 /* Wait until mailbox is free */
243 if (mega_busyWaitMbox (megaCfg)) {
244 - printk ("Blocked mailbox......!!\n");
248 - showMbox (pLastScb);
251 - /* Abort command */
252 - if (pScb == NULL) {
253 - TRACE (("NULL pScb in megaIssue\n"));
254 - printk ("NULL pScb in megaIssue\n");
256 - mega_cmd_done (megaCfg, pScb, 0x08);
260 @@ -2486,13 +2489,10 @@
261 WRINDOOR (megaCfg, phys_mbox | 0x1);
263 while (mbox->numstatus == 0xFF) ;
264 - while (mbox->status == 0xFF) ;
265 while (mbox->mraid_poll != 0x77) ;
266 mbox->mraid_poll = 0;
267 mbox->mraid_ack = 0x77;
269 - /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
270 - WROUTDOOR (megaCfg, cmdDone); */
271 + mbox->numstatus = 0xFF;
274 mega_cmd_done (megaCfg, pScb, mbox->status);
275 @@ -2523,12 +2523,6 @@
276 enable_irq (megaCfg->host->irq);
277 retval = mbox->status;
280 - while (mega_busyWaitMbox (megaCfg)) {
281 - printk(KERN_ERR "Blocked mailbox on exit......!\n");
288 @@ -2964,15 +2958,15 @@
292 -#if BITS_PER_LONG==64
297 + unsigned long megaBase;
298 + unsigned long tbase;
302 u16 subsysid, subsysvid;
303 + u8 did_mem_map_f = 0;
304 + u8 did_io_map_f = 0;
305 + u8 did_scsi_register_f = 0;
307 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) /* 0x20100 */
308 while (!pcibios_find_device
309 @@ -2991,6 +2985,17 @@
310 pciBus = pdev->bus->number;
311 pciDevFun = pdev->devfn;
315 + * Set the dma_mask to default value. It might be sticky from previous
316 + * insmod-rmmod sequence
318 + pdev->dma_mask = 0xFFFFFFFF;
322 + did_scsi_register_f = 0;
324 if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
325 if( (pciVendor == PCI_VENDOR_ID_PERC4_DI_YSTONE &&
326 pciDev == PCI_DEVICE_ID_PERC4_DI_YSTONE) ||
327 @@ -3041,6 +3046,7 @@
328 if( (subsysvid != AMI_SUBSYS_ID) &&
329 (subsysvid != DELL_SUBSYS_ID) &&
330 (subsysvid != LSI_SUBSYS_ID) &&
331 + (subsysvid != INTEL_SUBSYS_ID) &&
332 (subsysvid != HP_SUBSYS_ID) ) continue;
335 @@ -3065,22 +3071,55 @@
343 if (flag & BOARD_QUARTZ) {
345 megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
347 + if( ! request_mem_region(megaBase, 128,
348 + "MegaRAID: LSI Logic Corporation" ) ) {
350 + printk(KERN_WARNING "megaraid: mem region busy!\n");
355 megaBase = (long) ioremap (megaBase, 128);
360 + printk(KERN_WARNING "megaraid: could not map hba memory!\n");
362 + release_mem_region(tbase, 128);
369 megaBase &= PCI_BASE_ADDRESS_IO_MASK;
372 + if( ! request_region(megaBase, 16,
373 + "MegaRAID: LSI Logic Corporation") ) {
375 + printk(KERN_WARNING "megaraid: region busy.\n");
383 /* Initialize SCSI Host structure */
384 host = scsi_register (pHostTmpl, sizeof (mega_host_config));
389 + did_scsi_register_f = 1;
392 * Comment the following initialization if you know 'max_sectors' is
393 @@ -3088,7 +3127,7 @@
394 * This field was introduced in Linus's kernel 2.4.7pre3 and it
395 * greatly increases the IO performance - AM
397 - host->max_sectors = 1024;
398 + host->max_sectors = 128;
400 scsi_set_pci_device(host, pdev);
401 megaCfg = (mega_host_config *) host->hostdata;
402 @@ -3130,11 +3169,8 @@
403 megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
404 megaCtlrs[numCtlrs] = megaCfg;
406 - if (!(flag & BOARD_QUARTZ)) {
408 - /* Request our IO Range */
409 - if( !request_region(megaBase, 16, "megaraid") )
410 - goto err_unregister;
411 + if (flag & BOARD_QUARTZ) {
412 + megaCfg->host->base = tbase;
415 /* Request our IRQ */
416 @@ -3143,7 +3179,7 @@
418 "megaraid: Couldn't register IRQ %d!\n",
424 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
425 @@ -3265,8 +3301,7 @@
426 sizeof (mega_mailbox64),
427 (void *) megaCfg->mailbox64ptr,
428 megaCfg->dma_handle64);
429 - scsi_unregister (host);
435 @@ -3301,14 +3336,17 @@
440 - if (flag & BOARD_QUARTZ)
441 - release_region (megaBase, 16);
443 - scsi_unregister (host);
445 - if (flag & BOARD_QUARTZ)
446 - iounmap ((void *) megaBase);
448 + if( did_mem_map_f ) {
449 + iounmap((void *)megaBase);
450 + release_mem_region(tbase, 128);
452 + if( did_io_map_f ) {
453 + release_region(megaBase, 16);
455 + if( did_scsi_register_f ) {
456 + scsi_unregister (host);
461 @@ -3408,6 +3446,12 @@
464 init_MUTEX (&mimd_entry_mtx);
467 + * Register the 32-bit ioctl conversion
469 + register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl );
474 @@ -3439,6 +3483,7 @@
475 /* Free our resources */
476 if (megaCfg->flag & BOARD_QUARTZ) {
477 iounmap ((void *) megaCfg->base);
478 + release_mem_region(megaCfg->host->base, 128);
480 release_region (megaCfg->host->io_port, 16);
482 @@ -3485,6 +3530,9 @@
484 unregister_chrdev (major, "megadev");
485 unregister_reboot_notifier (&mega_notifier);
487 + unregister_ioctl32_conversion( MEGAIOCCMD );
492 @@ -4244,6 +4292,11 @@
493 proc_printf (megaCfg, "Interrupts Collected = %lu\n",
494 megaCfg->nInterrupts);
496 + proc_printf (megaCfg, "INTERFACE DISABLED\n");
500 +#if 0 // can cause buffer overrun with 40 logical drives and IO information
501 for (i = 0; i < megaCfg->numldrv; i++) {
502 proc_printf (megaCfg, "Logical Drive %d:\n", i);
504 @@ -4259,6 +4312,7 @@
511 static int proc_read_status (char *page, char **start, off_t offset,
512 @@ -4896,16 +4950,16 @@
513 if( kvaddr == NULL ) {
514 printk(KERN_WARNING "megaraid:allocation failed\n");
517 + goto out_ioctl_cmd_new;
520 ioc.ui.fcs.buffer = kvaddr;
523 /* copyin the user data */
524 - if (copy_from_user(kvaddr, (char *)uaddr, length )) {
527 + if( copy_from_user(kvaddr, (char *)uaddr, length ) ) {
529 + goto out_ioctl_cmd_new;
533 @@ -4923,7 +4977,7 @@
534 if( !scsicmd->result && outlen ) {
535 if (copy_to_user(uaddr, kvaddr, length)) {
538 + goto out_ioctl_cmd_new;
542 @@ -4944,7 +4999,8 @@
543 put_user (scsicmd->result, &uioc->mbox[17]);
550 dma_free_consistent(pdevp, length, kvaddr, dma_addr);
552 @@ -5045,12 +5101,8 @@
554 if( kvaddr == NULL ) {
555 printk (KERN_WARNING "megaraid:allocation failed\n");
556 -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
559 - scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
563 + goto out_ioctl_cmd;
567 @@ -5058,9 +5110,15 @@
569 if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
570 /* copyin the user data */
571 - copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen);
572 + if( copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen)){
574 + goto out_ioctl_cmd;
577 - copy_from_user (kvaddr, uaddr, inlen);
578 + if( copy_from_user (kvaddr, uaddr, inlen) ) {
580 + goto out_ioctl_cmd;
585 @@ -5078,11 +5136,15 @@
587 if (!scsicmd->result && outlen) {
588 if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
589 - if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen))
590 + if (copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen)) {
592 + goto out_ioctl_cmd;
595 - if (copy_to_user (uaddr, kvaddr, outlen))
596 + if (copy_to_user (uaddr, kvaddr, outlen)) {
598 + goto out_ioctl_cmd;
603 @@ -5107,6 +5169,8 @@
604 put_user (scsicmd->result, &uioc->mbox[17]); /* status */
610 dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
612 diff -Nur linux-2.4.21.org/drivers/scsi/megaraid.h linux-2.4.21/drivers/scsi/megaraid.h
613 --- linux-2.4.21.org/drivers/scsi/megaraid.h 2003-06-13 14:51:36.000000000 +0000
614 +++ linux-2.4.21/drivers/scsi/megaraid.h 2003-07-07 17:43:59.000000000 +0000
616 #define M_RD_IOCTL_CMD_NEW 0x81
617 #define M_RD_DRIVER_IOCTL_INTERFACE 0x82
619 -#define MEGARAID_VERSION "v1.18f (Release Date: Tue Dec 10 09:54:39 EST 2002)\n"
620 +#define MEGARAID_VERSION "v1.18j (Release Date: Mon Jul 7 14:39:55 EDT 2003)\n"
623 #define MEGARAID_IOCTL_VERSION 114
626 #define AMI_SUBSYS_ID 0x101E
627 #define DELL_SUBSYS_ID 0x1028
628 #define HP_SUBSYS_ID 0x103C
629 +#define INTEL_SUBSYS_ID 0x8086
631 #define AMI_SIGNATURE 0x3344
632 #define AMI_SIGNATURE_471 0xCCCC
634 * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE
636 #define MEGAIOC_MAGIC 'm'
637 -#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */
639 +/* Mega IOCTL command */
640 +#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t)
642 #define MEGAIOC_QNADAP 'm' /* Query # of adapters */
643 #define MEGAIOC_QDRVRVER 'e' /* Query driver version */