]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-megaraid.patch
- ported from linux-2.4.25-atmdd.patch
[packages/kernel.git] / kernel-megaraid.patch
CommitLineData
f365dffd 1diff -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
4@@ -9,7 +9,7 @@
5 * as published by the Free Software Foundation; either version
6 * 2 of the License, or (at your option) any later version.
7 *
8- * Version : v1.18f (Dec 10, 2002)
9+ * Version : v1.18j (July 7, 2003)
10 *
11 * Description: Linux device driver for LSI Logic MegaRAID controller
12 *
13@@ -512,6 +512,47 @@
14 *
15 * remove GFP_DMA flag for ioctl. This was causing overrun of DMA buffers.
16 *
17+ * Version 1.18g
18+ * Fri Jan 31 18:29:25 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
19+ *
20+ * Write the interrupt valid signature 0x10001234 as soon as reading it to
21+ * flush memory caches.
22+ *
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
25+ * accordingly.
26+ *
27+ * Version 1.18h
28+ * Thu Feb 6 17:18:48 EST 2003 - Atul Mukker <atul.mukker@lsil.com>
29+ *
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.
34+ *
35+ * Version 1.18i
36+ * Fri Jun 20 07:39:05 EDT 2003 - Atul Mukker <atulm@lsil.com>
37+ *
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
40+ *
41+ * Prevent memory leak in cases when data transfer from/to application fails
42+ * and ioctl is failing.
43+ *
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
47+ * on an Itenium
48+ *
49+ * Version 1.18j
50+ * Mon Jul 7 14:39:55 EDT 2003 - Atul Mukker <atulm@lsil.com>
51+ *
52+ * Disable /proc/megaraid/stat file to prevent buffer overflow error during
53+ * read of this file.
54+ *
55+ * Add support for ioctls on AMD-64 bit platforms
56+ * - Sreenivas Bagalkote <sreenib@lsil.com>
57+ *
58 * BUGS:
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.
61@@ -575,12 +616,27 @@
62 #include <linux/reboot.h>
63 #include <linux/init.h>
64
65+#ifdef __x86_64__
66+#include <asm/ioctl32.h>
67+#endif
68+
69 #include "sd.h"
70 #include "scsi.h"
71 #include "hosts.h"
72
73 #include "megaraid.h"
74
75+#ifdef __x86_64__
76+/*
77+ * The IOCTL cmd received from 32 bit compiled applications
78+ */
79+
80+extern int register_ioctl32_conversion( unsigned int cmd,
81+ int(*handler)(unsigned int, unsigned int, unsigned long,
82+ struct file* ));
83+extern int unregister_ioctl32_conversion( unsigned int cmd );
84+#endif
85+
86 /*
87 *================================================================
88 * #Defines
89@@ -1141,8 +1197,14 @@
90 switch (SCpnt->cmnd[0]) {
91 case INQUIRY:
92 case READ_CAPACITY:
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);
99+ } else {
100+ memcpy (SCpnt->request_buffer, pScb->bounce_buffer,
101+ SCpnt->request_bufflen);
102+ }
103 break;
104 }
105 #endif
106@@ -2202,30 +2264,22 @@
107 megaCfg = (mega_host_config *) devp;
108 mbox = (mega_mailbox *) tmpBox;
109
110- if (megaCfg->host->irq == irq) {
111- if (megaCfg->flag & IN_ISR) {
112- TRACE (("ISR called reentrantly!!\n"));
113- printk ("ISR called reentrantly!!\n");
114- }
115- megaCfg->flag |= IN_ISR;
116-
117- if (mega_busyWaitMbox (megaCfg)) {
118- printk (KERN_WARNING "Error: mailbox busy in isr!\n");
119- }
120+ IO_LOCK;
121
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;
128+ IO_UNLOCK;
129 return;
130 }
131+ WROUTDOOR (megaCfg, 0x10001234);
132 } else {
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;
137+ IO_UNLOCK;
138 return;
139 }
140 WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
141@@ -2234,58 +2288,26 @@
142 for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
143 completed[idx] = 0;
144
145- IO_LOCK;
146
147 megaCfg->nInterrupts++;
148- qCnt = 0xff;
149 while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ;
150+ megaCfg->mbox->numstatus = 0xFF;
151
152- qStatus = 0xff;
153- while ((qStatus = megaCfg->mbox->status) == 0xFF) ;
154+ qStatus = megaCfg->mbox->status;
155
156 /* Get list of completed requests */
157 for (idx = 0; idx < qCnt; idx++) {
158- while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
159- printk ("p");
160- }
161- completed[idx] = sIdx;
162- sIdx = 0xFF;
163+ completed[idx] = megaCfg->mbox->completed[idx];
164 }
165
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 */
171-#if 0
172- WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2);
173-#else
174 WRINDOOR (megaCfg, 0x2);
175-#endif
176-
177-#else
178-
179-#if 0
180- WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
181-#else
182- WRINDOOR (megaCfg, 0x2);
183-#endif
184-
185-#endif
186-
187-#if 0
188 while (RDINDOOR (megaCfg) & 0x02) ;
189-#endif
190 } else {
191 CLEAR_INTR (megaCfg->host->io_port);
192 }
193
194-#if DEBUG
195- if (qCnt >= MAX_FIRMWARE_STATUS) {
196- printk ("megaraid_isr: cmplt=%d ", qCnt);
197- }
198-#endif
199-
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);
205 IO_UNLOCK;
206
207- }
208-
209 }
210
211 /*==================================================*/
212 /* Wait until the controller's mailbox is available */
213 /*==================================================*/
214
215-static int mega_busyWaitMbox (mega_host_config * megaCfg)
216+static inline int mega_busyWaitMbox (mega_host_config * megaCfg)
217 {
218 mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
219 long counter;
220
221- for (counter = 0; counter < 10000; counter++) {
222+ for (counter = 0; counter < 10; counter++) {
223 if (!mbox->busy) {
224 return 0;
225 }
226- udelay (100);
227+ udelay (1);
228 }
229- return -1; /* give up after 1 second */
230+ return -1; /* give up after 10 usecs */
231 }
232
233 /*=====================================================
234@@ -2420,25 +2440,8 @@
235 phys_mbox = virt_to_bus (megaCfg->mbox);
236 #endif
237
238-#if DEBUG
239- ShowMbox (pScb);
240-#endif
241-
242 /* Wait until mailbox is free */
243 if (mega_busyWaitMbox (megaCfg)) {
244- printk ("Blocked mailbox......!!\n");
245- udelay (1000);
246-
247-#if DEBUG
248- showMbox (pLastScb);
249-#endif
250-
251- /* Abort command */
252- if (pScb == NULL) {
253- TRACE (("NULL pScb in megaIssue\n"));
254- printk ("NULL pScb in megaIssue\n");
255- }
256- mega_cmd_done (megaCfg, pScb, 0x08);
257 return -1;
258 }
259
260@@ -2486,13 +2489,10 @@
261 WRINDOOR (megaCfg, phys_mbox | 0x1);
262
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;
268-
269- /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
270- WROUTDOOR (megaCfg, cmdDone); */
271+ mbox->numstatus = 0xFF;
272
273 if (pScb) {
274 mega_cmd_done (megaCfg, pScb, mbox->status);
275@@ -2523,12 +2523,6 @@
276 enable_irq (megaCfg->host->irq);
277 retval = mbox->status;
278 }
279-#if DEBUG
280- while (mega_busyWaitMbox (megaCfg)) {
281- printk(KERN_ERR "Blocked mailbox on exit......!\n");
282- udelay (1000);
283- }
284-#endif
285
286 return retval;
287 }
288@@ -2964,15 +2958,15 @@
289
290 int i, j;
291
292-#if BITS_PER_LONG==64
293- u64 megaBase;
294-#else
295- u32 megaBase;
296-#endif
297+ unsigned long megaBase;
298+ unsigned long tbase;
299
300 u16 pciIdx = 0;
301 u16 numFound = 0;
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;
306
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;
312 #endif
313+
314+ /*
315+ * Set the dma_mask to default value. It might be sticky from previous
316+ * insmod-rmmod sequence
317+ */
318+ pdev->dma_mask = 0xFFFFFFFF;
319+
320+ did_mem_map_f = 0;
321+ did_io_map_f = 0;
322+ did_scsi_register_f = 0;
323+
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;
333
334 }
335@@ -3065,22 +3071,55 @@
336 megaIrq = pdev->irq;
337 #endif
338
339+ tbase = megaBase;
340+
341 pciIdx++;
342
343 if (flag & BOARD_QUARTZ) {
344+
345 megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
346+
347+ if( ! request_mem_region(megaBase, 128,
348+ "MegaRAID: LSI Logic Corporation" ) ) {
349+
350+ printk(KERN_WARNING "megaraid: mem region busy!\n");
351+
352+ continue;
353+ }
354+
355 megaBase = (long) ioremap (megaBase, 128);
356- if (!megaBase)
357+
358+ if (!megaBase) {
359+
360+ printk(KERN_WARNING "megaraid: could not map hba memory!\n");
361+
362+ release_mem_region(tbase, 128);
363+
364 continue;
365+ }
366+ did_mem_map_f = 1;
367+
368 } else {
369 megaBase &= PCI_BASE_ADDRESS_IO_MASK;
370 megaBase += 0x10;
371+
372+ if( ! request_region(megaBase, 16,
373+ "MegaRAID: LSI Logic Corporation") ) {
374+
375+ printk(KERN_WARNING "megaraid: region busy.\n");
376+
377+ continue;
378+ }
379+ did_io_map_f = 1;
380+
381 }
382
383 /* Initialize SCSI Host structure */
384 host = scsi_register (pHostTmpl, sizeof (mega_host_config));
385 if (!host)
386- goto err_unmap;
387+ goto fail_attach;
388+
389+ did_scsi_register_f = 1;
390
391 /*
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
396 */
397- host->max_sectors = 1024;
398+ host->max_sectors = 128;
399
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;
405
406- if (!(flag & BOARD_QUARTZ)) {
407-
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;
413 }
414
415 /* Request our IRQ */
416@@ -3143,7 +3179,7 @@
417 printk (KERN_WARNING
418 "megaraid: Couldn't register IRQ %d!\n",
419 megaIrq);
420- goto err_release;
421+ goto fail_attach;
422 }
423
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);
430- continue;
431+ goto fail_attach;
432 }
433
434 /*
435@@ -3301,14 +3336,17 @@
436 #endif
437 #endif
438 continue;
439- err_release:
440- if (flag & BOARD_QUARTZ)
441- release_region (megaBase, 16);
442- err_unregister:
443- scsi_unregister (host);
444- err_unmap:
445- if (flag & BOARD_QUARTZ)
446- iounmap ((void *) megaBase);
447+fail_attach:
448+ if( did_mem_map_f ) {
449+ iounmap((void *)megaBase);
450+ release_mem_region(tbase, 128);
451+ }
452+ if( did_io_map_f ) {
453+ release_region(megaBase, 16);
454+ }
455+ if( did_scsi_register_f ) {
456+ scsi_unregister (host);
457+ }
458 }
459 return numFound;
460 }
461@@ -3408,6 +3446,12 @@
462 }
463
464 init_MUTEX (&mimd_entry_mtx);
465+#ifdef __x86_64__
466+ /*
467+ * Register the 32-bit ioctl conversion
468+ */
469+ register_ioctl32_conversion( MEGAIOCCMD, sys_ioctl );
470+#endif
471 }
472
473 return count;
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);
479 } else {
480 release_region (megaCfg->host->io_port, 16);
481 }
482@@ -3485,6 +3530,9 @@
483
484 unregister_chrdev (major, "megadev");
485 unregister_reboot_notifier (&mega_notifier);
486+#ifdef __x86_64__
487+ unregister_ioctl32_conversion( MEGAIOCCMD );
488+#endif
489
490 return 0;
491 }
492@@ -4244,6 +4292,11 @@
493 proc_printf (megaCfg, "Interrupts Collected = %lu\n",
494 megaCfg->nInterrupts);
495
496+ proc_printf (megaCfg, "INTERFACE DISABLED\n");
497+ COPY_BACK;
498+ return count;
499+
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);
503
504@@ -4259,6 +4312,7 @@
505
506 COPY_BACK;
507 return count;
508+#endif
509 }
510
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");
515 ret = -ENOMEM;
516- goto out;
517+ goto out_ioctl_cmd_new;
518 }
519
520 ioc.ui.fcs.buffer = kvaddr;
521
522 if (inlen) {
523 /* copyin the user data */
524- if (copy_from_user(kvaddr, (char *)uaddr, length )) {
525- ret = -EFAULT;
526- goto out;
527+ if( copy_from_user(kvaddr, (char *)uaddr, length ) ) {
528+ ret = -EFAULT;
529+ goto out_ioctl_cmd_new;
530 }
531 }
532 }
a3854b07 533@@ -4923,7 +4977,7 @@
f365dffd 534 if( !scsicmd->result && outlen ) {
a3854b07
JR
535 if (copy_to_user(uaddr, kvaddr, length)) {
536 ret = -EFAULT;
f365dffd 537- goto out;
f365dffd 538+ goto out_ioctl_cmd_new;
a3854b07 539 }
f365dffd 540 }
541
f365dffd 542@@ -4944,7 +4999,8 @@
543 put_user (scsicmd->result, &uioc->mbox[17]);
544 }
545
546-out:
547+out_ioctl_cmd_new:
548+
549 if (kvaddr) {
550 dma_free_consistent(pdevp, length, kvaddr, dma_addr);
551 }
552@@ -5045,12 +5101,8 @@
553
554 if( kvaddr == NULL ) {
555 printk (KERN_WARNING "megaraid:allocation failed\n");
556-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
557- kfree(scsicmd);
558-#else
559- scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
560-#endif
561- return -ENOMEM;
562+ ret = -ENOMEM;
563+ goto out_ioctl_cmd;
564 }
565
566 ioc.data = kvaddr;
567@@ -5058,9 +5110,15 @@
568 if (inlen) {
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)){
573+ ret = -EFAULT;
574+ goto out_ioctl_cmd;
575+ }
576 } else {
577- copy_from_user (kvaddr, uaddr, inlen);
578+ if( copy_from_user (kvaddr, uaddr, inlen) ) {
579+ ret = -EFAULT;
580+ goto out_ioctl_cmd;
581+ }
582 }
583 }
584 }
585@@ -5078,11 +5136,15 @@
586
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)) {
591 ret = -EFAULT;
592+ goto out_ioctl_cmd;
593+ }
594 } else {
595- if (copy_to_user (uaddr, kvaddr, outlen))
596+ if (copy_to_user (uaddr, kvaddr, outlen)) {
597 ret = -EFAULT;
598+ goto out_ioctl_cmd;
599+ }
600 }
601 }
602
603@@ -5107,6 +5169,8 @@
604 put_user (scsicmd->result, &uioc->mbox[17]); /* status */
605 }
606
607+out_ioctl_cmd:
608+
609 if (kvaddr) {
610 dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
611 }
612diff -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
615@@ -30,7 +30,8 @@
616 #define M_RD_IOCTL_CMD_NEW 0x81
617 #define M_RD_DRIVER_IOCTL_INTERFACE 0x82
618
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"
621+
622
623 #define MEGARAID_IOCTL_VERSION 114
624
625@@ -190,6 +191,7 @@
626 #define AMI_SUBSYS_ID 0x101E
627 #define DELL_SUBSYS_ID 0x1028
628 #define HP_SUBSYS_ID 0x103C
629+#define INTEL_SUBSYS_ID 0x8086
630
631 #define AMI_SIGNATURE 0x3344
632 #define AMI_SIGNATURE_471 0xCCCC
633@@ -899,7 +901,9 @@
634 * Defines for Driver IOCTL interface, Op-code:M_RD_DRIVER_IOCTL_INTERFACE
635 */
636 #define MEGAIOC_MAGIC 'm'
637-#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0) /* Mega IOCTL command */
638+
639+/* Mega IOCTL command */
640+#define MEGAIOCCMD _IOWR(MEGAIOC_MAGIC, 0, struct uioctl_t)
641
642 #define MEGAIOC_QNADAP 'm' /* Query # of adapters */
643 #define MEGAIOC_QDRVRVER 'e' /* Query driver version */
This page took 0.168498 seconds and 4 git commands to generate.