v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / drivers / scsi / megaraid.c
1 /*===================================================================
2  *
3  *                    Linux MegaRAID device driver
4  *
5  * Copyright 2001  American Megatrends Inc.
6  *
7  *              This program is free software; you can redistribute it and/or
8  *              modify it under the terms of the GNU General Public License
9  *              as published by the Free Software Foundation; either version
10  *              2 of the License, or (at your option) any later version.
11  *
12  * Version : v1.17a (July 13, 2001)
13  *
14  * Description: Linux device driver for AMI MegaRAID controller
15  *
16  * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490
17  *                                      493.
18  * History:
19  *
20  * Version 0.90:
21  *     Original source contributed by Dell; integrated it into the kernel and
22  *     cleaned up some things.  Added support for 438/466 controllers.
23  * Version 0.91:
24  *     Aligned mailbox area on 16-byte boundary.
25  *     Added schedule() at the end to properly clean up.
26  *     Made improvements for conformity to linux driver standards.
27  *
28  * Version 0.92:
29  *     Added support for 2.1 kernels.
30  *         Reads from pci_dev struct, so it's not dependent on pcibios.
31  *         Added some missing virt_to_bus() translations.
32  *     Added support for SMP.
33  *         Changed global cli()'s to spinlocks for 2.1, and simulated
34  *          spinlocks for 2.0.
35  *     Removed setting of SA_INTERRUPT flag when requesting Irq.
36  *
37  * Version 0.92ac:
38  *     Small changes to the comments/formatting. Plus a couple of
39  *      added notes. Returned to the authors. No actual code changes
40  *      save printk levels.
41  *     8 Oct 98        Alan Cox <alan.cox@linux.org>
42  *
43  *     Merged with 2.1.131 source tree.
44  *     12 Dec 98       K. Baranowski <kgb@knm.org.pl>
45  *
46  * Version 0.93:
47  *     Added support for vendor specific ioctl commands (M_RD_IOCTL_CMD+xxh)
48  *     Changed some fields in MEGARAID struct to better values.
49  *     Added signature check for Rp controllers under 2.0 kernels
50  *     Changed busy-wait loop to be time-based
51  *     Fixed SMP race condition in isr
52  *     Added kfree (sgList) on release
53  *     Added #include linux/version.h to megaraid.h for hosts.h
54  *     Changed max_id to represent max logical drives instead of targets.
55  *
56  * Version 0.94:
57  *     Got rid of some excess locking/unlocking
58  *     Fixed slight memory corruption problem while memcpy'ing into mailbox
59  *     Changed logical drives to be reported as luns rather than targets
60  *     Changed max_id to 16 since it is now max targets/chan again.
61  *     Improved ioctl interface for upcoming megamgr
62  *
63  * Version 0.95:
64  *     Fixed problem of queueing multiple commands to adapter;
65  *       still has some strange problems on some setups, so still
66  *       defaults to single.  To enable parallel commands change
67  *       #define MULTI_IO in megaraid.h
68  *     Changed kmalloc allocation to be done in beginning.
69  *     Got rid of C++ style comments
70  *
71  * Version 0.96:
72  *     762 fully supported.
73  *
74  * Version 0.97:
75  *     Changed megaraid_command to use wait_queue.
76  *
77  * Version 1.00:
78  *     Checks to see if an irq occurred while in isr, and runs through
79  *       routine again.
80  *     Copies mailbox to temp area before processing in isr
81  *     Added barrier() in busy wait to fix volatility bug
82  *     Uses separate list for freed Scbs, keeps track of cmd state
83  *     Put spinlocks around entire queue function for now...
84  *     Full multi-io commands working stablely without previous problems
85  *     Added skipXX LILO option for Madrona motherboard support
86  *
87  * Version 1.01:
88  *     Fixed bug in mega_cmd_done() for megamgr control commands,
89  *       the host_byte in the result code from the scsi request to
90  *       scsi midlayer is set to DID_BAD_TARGET when adapter's
91  *       returned codes are 0xF0 and 0xF4.
92  *
93  * Version 1.02:
94  *     Fixed the tape drive bug by extending the adapter timeout value
95  *       for passthrough command to 60 seconds in mega_build_cmd().
96  *
97  * Version 1.03:
98  *    Fixed Madrona support.
99  *    Changed the adapter timeout value from 60 sec in 1.02 to 10 min
100  *      for bigger and slower tape drive.
101  *    Added driver version printout at driver loadup time
102  *
103  * Version 1.04
104  *    Added code for 40 ld FW support.
105  *    Added new ioctl command 0x81 to support NEW_READ/WRITE_CONFIG with
106  *      data area greater than 4 KB, which is the upper bound for data
107  *      tranfer through scsi_ioctl interface.
108  *    The additional 32 bit field for 64bit address in the newly defined
109  *      mailbox64 structure is set to 0 at this point.
110  *
111  * Version 1.05
112  *    Changed the queing implementation for handling SCBs and completed
113  *      commands.
114  *    Added spinlocks in the interrupt service routine to enable the driver
115  *      function in the SMP environment.
116  *    Fixed the problem of unnecessary aborts in the abort entry point, which
117  *      also enables the driver to handle large amount of I/O requests for
118  *      long duration of time.
119  * Version 1.06
120  *              Intel Release
121  * Version 1.07
122  *    Removed the usage of uaccess.h file for kernel versions less than
123  *    2.0.36, as this file is not present in those versions.
124  *
125  * Version 108
126  *    Modified mega_ioctl so that 40LD megamanager would run
127  *    Made some changes for 2.3.XX compilation , esp wait structures
128  *    Code merge between 1.05 and 1.06 .
129  *    Bug fixed problem with ioctl interface for concurrency between
130  *    8ld and 40ld firwmare
131  *    Removed the flawed semaphore logic for handling new config command
132  *    Added support for building own scatter / gather list for big user
133  *    mode buffers
134  *    Added /proc file system support ,so that information is available in
135  *    human readable format
136  *
137  * Version 1a08
138  *    Changes for IA64 kernels. Checked for CONFIG_PROC_FS flag
139  *
140  * Version 1b08
141  *    Include file changes.
142  * Version 1b08b
143  *    Change PCI ID value for the 471 card, use #defines when searching
144  *    for megaraid cards.
145  *
146  * Version 1.10
147  *
148  *      I) Changes made to make following ioctl commands work in 0x81 interface
149  *              a)DCMD_DELETE_LOGDRV
150  *              b)DCMD_GET_DISK_CONFIG
151  *              c)DCMD_DELETE_DRIVEGROUP
152  *              d)NC_SUBOP_ENQUIRY3
153  *              e)DCMD_CHANGE_LDNO
154  *              f)DCMD_CHANGE_LOOPID
155  *              g)DCMD_FC_READ_NVRAM_CONFIG
156  *      h)DCMD_WRITE_CONFIG
157  *      II) Added mega_build_kernel_sg function
158  *  III)Firmware flashing option added
159  *
160  * Version 1.10a
161  *
162  *      I)Dell updates included in the source code.
163  *              Note:   This change is not tested due to the unavailability of IA64 kernel
164  *      and it is in the #ifdef DELL_MODIFICATION macro which is not defined
165  *
166  * Version 1.10b
167  *
168  *      I)In M_RD_IOCTL_CMD_NEW command the wrong way of copying the data
169  *    to the user address corrected
170  *
171  * Version 1.10c
172  *
173  *      I) DCMD_GET_DISK_CONFIG opcode updated for the firmware changes.
174  *
175  * Version 1.11
176  *      I)  Version number changed from 1.10c to 1.11
177  *  II) DCMD_WRITE_CONFIG(0x0D) command in the driver changed from
178  *      scatter/gather list mode to direct pointer mode..
179  *     Fixed bug of undesirably detecting HP onboard controllers which
180  *       are disabled.
181  *
182  *      Version 1.12 (Sep 21, 2000)
183  *
184  *     I. Changes have been made for Dynamic DMA mapping in IA64 platform.
185  *                To enable all these changes define M_RD_DYNAMIC_DMA_SUPPORT in megaraid.h
186  *        II. Got rid of windows mode comments
187  *       III. Removed unwanted code segments
188  *    IV. Fixed bug of HP onboard controller information (commented with
189  *                 MEGA_HP_FIX)
190  *
191  *      Version 1a12
192  *      I.      reboot notifier and new ioctl changes ported from 1c09
193  *
194  *      Version 1b12
195  *      I.      Changes in new ioctl interface routines ( Nov 06, 2000 )
196  *
197  *      Version 1c12
198  *      I.      Changes in new ioctl interface routines ( Nov 07, 2000 )
199  *
200  *      Version 1d12
201  *      I.      Compilation error under kernel 2.4.0 for 32-bit machine in mega_ioctl
202  *
203  *      Version 1e12, 1f12
204  *      1.  Fixes for pci_map_single, pci_alloc_consistent along with mailbox
205  *          alignment
206  *
207  *      Version 1.13beta
208  *      Added Support for Full 64bit address space support. If firmware
209  *      supports 64bit, it goes to 64 bit mode even on x86 32bit 
210  *      systems. Data Corruption Issues while running on test9 kernel
211  *      on IA64 systems. This issue not seen on test11 on x86 system
212  *
213  *      Version 1.13c
214  *      1. Resolved Memory Leak when using M_RD_IOCTL_CMD interface
215  *      2. Resolved Queuing problem when MailBox Blocks
216  *      3. Added unregister_reboot_notifier support
217  * 
218  *      Version 1.13d
219  *      Experimental changes in interfacing with the controller in ISR
220  *
221  *      Version 1.13e
222  *      Fixed Broken 2.2.XX compilation changes + misc changes
223  *
224  *      Version 1.13f to 1.13i
225  *      misc changes + code clean up
226  *      Cleaned up the ioctl code and added set_mbox_xfer_addr()
227  *      Support for START_DEV (6)
228  *      
229  *      Version 1.13j
230  *      Moved some code to megaraid.h file, replaced some hard coded values 
231  *      with respective macros. Changed some functions to static
232  *
233  *      Version 1.13k
234  *      Only some idendation correction to 1.13j 
235  *
236  *      Version 1.13l , 1.13m, 1.13n, 1.13o
237  *      Minor Identation changes + misc changes
238  *
239  *      Version 1.13q
240  *      Paded the new uioctl_t MIMD structure for maintaining alignment 
241  *      and size across 32 / 64 bit platforms
242  *      Changed the way MIMD IOCTL interface used virt_to_bus() to use pci
243  *      memory location
244  *
245  *      Version 1.13r
246  *      2.4.xx SCSI Changes.
247  *
248  *      Version 1.13s
249  *      Stats counter fixes
250  *      Temporary fix for some 64 bit firmwares in 2.4.XX kernels
251  *
252  *      Version 1.13t
253  *      Support for 64bit version of READ/WRITE/VIEW DISK CONFIG
254  *
255  *      Version 1.14
256  *      Did away with MEGADEV_IOCTL flag. It is now standard part of driver
257  *      without need for a special #define flag
258  *      Disabled old scsi ioctl path for kernel versions > 2.3.xx. This is due
259  *      to the nature in which the new scsi code queues a new scsi command to 
260  *      controller during SCSI IO Completion
261  *      Driver now checks for sub-system vendor id before taking ownership of
262  *      the controller
263  *
264  *      Version 1.14a
265  *      Added Host re-ordering
266  *
267  *      Version 1.14b
268  *      Corrected some issue which caused the older cards not to work
269  *      
270  *      Version 1.14c
271  *      IOCTL changes for not handling the non-64bit firmwares under 2.4.XX
272  *      kernel
273  *
274  *      Version 1.14d
275  *      Fixed Various MIMD Synchronization Issues
276  *      
277  *      Version 1.14e
278  *      Fixed the error handling during card initialization
279  *
280  *      Version 1.14f
281  *      Multiple invocations of mimd phase I ioctl stalls the cpu. Replaced
282  *      spinlock with semaphore(mutex)
283  *
284  *      Version 1.14g
285  *      Fixed running out of scbs issues while running MIMD apps under heavy IO
286  *
287  *      Version 1.14g-ac - 02/03/01
288  *      Reformatted to Linux format so I could compare to old one and cross
289  *      check bug fixes
290  *      Re fixed the assorted missing 'static' cases
291  *      Removed some unneeded version checks
292  *      Cleaned up some of the VERSION checks in the code
293  *      Left 2.0 support but removed 2.1.x support.
294  *      Collected much of the compat glue into one spot
295  *
296  *      Version 1.14g-ac2 - 22/03/01
297  *      Fixed a non obvious dereference after free in the driver unload path
298  *
299  *      Version 1.14i
300  *      changes for making 32bit application run on IA64
301  *
302  *      Version 1.14j
303  *      Tue Mar 13 14:27:54 EST 2001 - AM
304  *      Changes made in the driver to be able to run applications if the
305  *      system has memory >4GB.
306  *
307  *
308  *      Version 1.14k
309  *      Thu Mar 15 18:38:11 EST 2001 - AM
310  *
311  *      Firmware version check removed if subsysid==0x1111 and
312  *      subsysvid==0x1111, since its not yet initialized.
313  *
314  *      changes made to correctly calculate the base in mega_findCard.
315  *
316  *      Driver informational messages now appear on the console as well as
317  *      with dmesg
318  *
319  *      Older ioctl interface is returned failure on newer(2.4.xx) kernels.
320  *
321  *      Inclusion of "modversions.h" is still a debatable question. It is
322  *      included anyway with this release.
323  *
324  *      Version 1.14l
325  *      Mon Mar 19 17:39:46 EST 2001 - AM
326  *
327  *      Assorted changes to remove compilation error in 1.14k when compiled
328  *      with kernel < 2.4.0
329  *
330  *      Version 1.14m
331  *      Tue Mar 27 12:09:22 EST 2001 - AM
332  *
333  *      Added support for extended CDBs ( > 10 bytes ) and OBDR ( One Button
334  *      Disaster Recovery ) feature.
335  *
336  *
337  *      Version 1.14n
338  *      Tue Apr 10 14:28:13 EDT 2001 - AM
339  *
340  *      "modeversions.h" is no longer included in the code.
341  *      2.4.xx style mutex initialization used for older kernels also
342  *
343  *      Version 1.14o
344  *      Wed Apr 18 17:47:26 EDT 2001 - PJ
345  *
346  *      Before returning status for 'inquiry', we first check if request buffer
347  *      is SG list, and then return appropriate status
348  *
349  *      Version 1.14p
350  *      Wed Apr 25 13:44:48 EDT 2001 - PJ
351  *
352  *      SCSI result made appropriate in case of check conditions for extended
353  *      passthru commands
354  *
355  *      Do not support lun >7 for physically accessed devices 
356  *
357  *      
358  *      Version 1.15
359  *      Thu Apr 19 09:38:38 EDT 2001 - AM
360  *
361  *      1.14l rollover to 1.15 - merged with main trunk after 1.15d
362  *
363  *      Version 1.15b
364  *  Wed May 16 20:10:01 EDT 2001 - AM
365  *
366  *      "modeversions.h" is no longer included in the code.
367  *      2.4.xx style mutex initialization used for older kernels also
368  *      Brought in-sync with Alan's changes in 2.4.4
369  *      Note: 1.15a is on OBDR branch(main trunk), and is not merged with yet.
370  *
371  * Version 1.15c
372  * Mon May 21 23:10:42 EDT 2001 - AM
373  *
374  * ioctl interface uses 2.4.x conforming pci dma calls
375  * similar calls used for older kernels
376  *
377  * Version 1.15d
378  * Wed May 30 17:30:41 EDT 2001 - AM
379  *
380  * NULL is not a valid first argument for pci_alloc_consistent() on
381  * IA64(2.4.3-2.10.1). Code shuffling done in ioctl interface to get
382  * "pci_dev" before making calls to pci interface routines.
383  *
384  * Version 1.16pre
385  * Fri Jun  1 19:40:48 EDT 2001 - AM
386  *
387  * 1.14p and 1.15d merged
388  * ROMB support added
389  *
390  * Version 1.16-pre1
391  * Mon Jun  4 15:01:01 EDT 2001 - AM
392  *
393  * Non-ROMB firmware do no DMA support 0xA9 command. Value 0xFF
394  * (all channels are raid ) is chosen for those firmware.
395  *
396  * Version 1.16-pre2
397  * Mon Jun 11 18:15:31 EDT 2001 - AM
398  *
399  * Changes for boot from any logical drive
400  *
401  * Version 1.16
402  * Tue Jun 26 18:07:02 EDT 2001 - AM
403  *
404  * branched at 1.14p
405  *
406  * Check added for HP 1M/2M controllers if having firmware H.01.07 or
407  * H.01.08. If found, disable 64 bit support since these firmware have
408  * limitations for 64 bit addressing
409  *
410  *
411  * Version 1.17
412  * Thu Jul 12 11:14:09 EDT 2001 - AM
413  *
414  * 1.16pre2 and 1.16 merged.
415  *
416  * init_MUTEX and init_MUTEX_LOCKED are defined in 2.2.19. Pre-processor
417  * statements are added for them
418  *
419  * Linus's 2.4.7pre3 kernel introduces a new field 'max_sectors' in Scsi_Host
420  * structure, to improve IO performance.
421  *
422  *
423  * Version 1.17a
424  * Fri Jul 13 18:44:01 EDT 2001 - AM
425  *
426  * Starting from kernel 2.4.x, LUN is not < 8 - following SCSI-III. So to have
427  * our current formula working to calculate logical drive number, return
428  * failure for LUN > 7
429  *
430  * Version 1.17a-ac
431  * Mon Aug 6 14:59:29 BST 2001 - "Michael Johnson" <johnsom@home.com>
432  *
433  * Make the HP print formatting and check for buggy firmware runtime not
434  * ifdef dependant.
435  *
436  * BUGS:
437  *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
438  *     fails to detect the controller as a pci device on the system.
439  *
440  *     Timeout period for upper scsi layer, i.e. SD_TIMEOUT in
441  *     /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT
442  *     value must be increased to (30 * HZ) otherwise false timeouts
443  *     will occur in the upper layer.
444  *
445  *     Never set skip_id. The existing PCI code the megaraid uses fails
446  *     to properly check the vendor subid in some cases. Setting this then
447  *     makes it steal other i960's and crashes some boxes
448  *
449  *     Far too many ifdefs for versions.
450  *
451  *===================================================================*/
452
453 #include <linux/config.h>
454 #include <linux/version.h>
455 #include <linux/module.h>
456 #include <linux/types.h>
457 #include <linux/errno.h>
458 #include <linux/string.h>
459 #include <linux/kernel.h>
460 #include <linux/ioport.h>
461 #include <linux/fcntl.h>
462 #include <linux/delay.h>
463 #include <linux/pci.h>
464 #include <linux/proc_fs.h>
465 #include <linux/blk.h>
466 #include <linux/wait.h>
467 #include <linux/tqueue.h>
468 #include <linux/interrupt.h>
469 #include <linux/mm.h>
470 #include <asm/pgtable.h>
471
472 #include <linux/sched.h>
473 #include <linux/stat.h>
474 #include <linux/slab.h> /* for kmalloc() */
475 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
476 #include <linux/bios32.h>
477 #else
478 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  /* 0x20300 */
479 #include <asm/spinlock.h>
480 #else
481 #include <linux/spinlock.h>
482 #endif
483 #endif
484
485 #include <asm/io.h>
486 #include <asm/irq.h>
487
488 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,0,24) /* 0x020024 */
489 #include <asm/uaccess.h>
490 #endif
491
492 /*
493  * These header files are required for Shutdown Notification routines
494  */
495 #include <linux/notifier.h>
496 #include <linux/reboot.h>
497 #include <linux/init.h>
498
499 #include "sd.h"
500 #include "scsi.h"
501 #include "hosts.h"
502
503 #include "megaraid.h"
504
505 /*
506  *================================================================
507  *  #Defines
508  *================================================================
509  */
510
511 #define MAX_SERBUF 160
512 #define COM_BASE 0x2f8
513
514 static ulong RDINDOOR (mega_host_config * megaCfg)
515 {
516         return readl (megaCfg->base + 0x20);
517 }
518
519 static void WRINDOOR (mega_host_config * megaCfg, ulong value)
520 {
521         writel (value, megaCfg->base + 0x20);
522 }
523
524 static ulong RDOUTDOOR (mega_host_config * megaCfg)
525 {
526         return readl (megaCfg->base + 0x2C);
527 }
528
529 static void WROUTDOOR (mega_host_config * megaCfg, ulong value)
530 {
531         writel (value, megaCfg->base + 0x2C);
532 }
533
534 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) /* 0x020200 */
535 #include <linux/smp.h>
536 #define cpuid smp_processor_id()
537 #endif
538
539 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
540 #define scsi_set_pci_device(x,y)
541 #endif
542
543 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* 0x020400 */
544
545 /*
546  *      Linux 2.4 and higher
547  *
548  *      No driver private lock
549  *      Use the io_request_lock not cli/sti
550  *      queue task is a simple api without irq forms
551  */
552
553 MODULE_AUTHOR ("American Megatrends Inc.");
554 MODULE_DESCRIPTION ("AMI MegaRAID driver");
555
556 #define DRIVER_LOCK_T
557 #define DRIVER_LOCK_INIT(p)
558 #define DRIVER_LOCK(p)
559 #define DRIVER_UNLOCK(p)
560 #define IO_LOCK_T unsigned long io_flags = 0;
561 #define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
562 #define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
563
564 #define queue_task_irq(a,b)     queue_task(a,b)
565 #define queue_task_irq_off(a,b) queue_task(a,b)
566
567 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)       /* 0x020200 */
568
569 /*
570  *      Linux 2.2 and higher
571  *
572  *      No driver private lock
573  *      Use the io_request_lock not cli/sti
574  *      No pci region api
575  *      queue_task is now a single simple API
576  */
577
578 static char kernel_version[] = UTS_RELEASE;
579 MODULE_AUTHOR ("American Megatrends Inc.");
580 MODULE_DESCRIPTION ("AMI MegaRAID driver");
581
582 #define DRIVER_LOCK_T
583 #define DRIVER_LOCK_INIT(p)
584 #define DRIVER_LOCK(p)
585 #define DRIVER_UNLOCK(p)
586 #define IO_LOCK_T unsigned long io_flags = 0;
587 #define IO_LOCK spin_lock_irqsave(&io_request_lock,io_flags);
588 #define IO_UNLOCK spin_unlock_irqrestore(&io_request_lock,io_flags);
589
590 #define pci_free_consistent(a,b,c,d)
591 #define pci_unmap_single(a,b,c,d)
592 #define pci_enable_device(x) (0)
593 #define queue_task_irq(a,b)     queue_task(a,b)
594 #define queue_task_irq_off(a,b) queue_task(a,b)
595
596 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19) /* 0x020219 */
597 #define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
598 #define init_MUTEX(x)           (*(x)=MUTEX)
599 #define DECLARE_WAIT_QUEUE_HEAD(x)      struct wait_queue *x = NULL
600 #endif
601
602
603 #else
604
605 /*
606  *      Linux 2.0 macros. Here we have to provide some of our own
607  *      functionality. We also only work little endian 32bit.
608  *      Again no pci_alloc/free api
609  *      IO_LOCK/IO_LOCK_T were never used in 2.0 so now are empty 
610  */
611  
612 #define cpuid 0
613 #define DRIVER_LOCK_T long cpu_flags;
614 #define DRIVER_LOCK_INIT(p)
615 #define DRIVER_LOCK(p) \
616                 save_flags(cpu_flags); \
617                 cli();
618 #define DRIVER_UNLOCK(p) \
619                 restore_flags(cpu_flags);
620 #define IO_LOCK_T
621 #define IO_LOCK(p)
622 #define IO_UNLOCK(p)
623 #define le32_to_cpu(x) (x)
624 #define cpu_to_le32(x) (x)
625
626 #define pci_free_consistent(a,b,c,d)
627 #define pci_unmap_single(a,b,c,d)
628
629 #define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
630 #define init_MUTEX(x)           (*(x)=MUTEX)
631
632 #define pci_enable_device(x) (0)
633
634 /*
635  *      2.0 lacks spinlocks, iounmap/ioremap
636  */
637
638 #define ioremap vremap
639 #define iounmap vfree
640
641  /* simulate spin locks */
642 typedef struct {
643         volatile char lock;
644 } spinlock_t;
645
646 #define spin_lock_init(x) { (x)->lock = 0;}
647 #define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
648                                         (x)->lock=1; save_flags(flags);\
649                                         cli();}
650 #define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);}
651
652 #define DECLARE_WAIT_QUEUE_HEAD(x)      struct wait_queue *x = NULL
653
654 #endif
655
656
657 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* 0x020400 */
658 #define dma_alloc_consistent pci_alloc_consistent
659 #define dma_free_consistent pci_free_consistent
660 #else
661 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19) /* 0x020219 */
662 typedef unsigned long dma_addr_t;
663 #endif
664 void *dma_alloc_consistent(void *, size_t, dma_addr_t *);
665 void dma_free_consistent(void *, size_t, void *, dma_addr_t);
666 int mega_get_order(int);
667 int pow_2(int);
668 #endif
669
670 /* set SERDEBUG to 1 to enable serial debugging */
671 #define SERDEBUG 0
672 #if SERDEBUG
673 static void ser_init (void);
674 static void ser_puts (char *str);
675 static void ser_putc (char c);
676 static int ser_printk (const char *fmt, ...);
677 #endif
678
679 #ifdef CONFIG_PROC_FS
680 #define COPY_BACK if (offset > megaCfg->procidx) { \
681                 *eof = TRUE; \
682         megaCfg->procidx = 0; \
683         megaCfg->procbuf[0] = 0; \
684         return 0;} \
685  if ((count + offset) > megaCfg->procidx) { \
686       count = megaCfg->procidx - offset; \
687       *eof = TRUE; } \
688       memcpy(page, &megaCfg->procbuf[offset], count); \
689       megaCfg->procidx = 0; \
690       megaCfg->procbuf[0] = 0;
691 #endif
692
693 /*
694  * ================================================================
695  *                    Global variables
696  *================================================================
697  */
698
699 /*  Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
700     XX scsi id on each channel.  Used for Madrona motherboard, where SAF_TE
701     processor id cannot be scanned */
702
703 static char *megaraid;
704 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)  /* 0x20100 */
705 #ifdef MODULE
706 MODULE_PARM (megaraid, "s");
707 #endif
708 #endif
709 static int skip_id = -1;
710 static int numCtlrs = 0;
711 static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = { 0 };
712 static struct proc_dir_entry *mega_proc_dir_entry;
713
714 #if DEBUG
715 static u32 maxCmdTime = 0;
716 #endif
717
718 static mega_scb *pLastScb = NULL;
719 static struct notifier_block mega_notifier = {
720         megaraid_reboot_notify,
721         NULL,
722         0
723 };
724
725 /* For controller re-ordering */
726 struct mega_hbas mega_hbas[MAX_CONTROLLERS];
727
728 /*
729  * The File Operations structure for the serial/ioctl interface of the driver
730  */
731 /* For controller re-ordering */ 
732
733 static struct file_operations megadev_fops = {
734         ioctl:megadev_ioctl_entry,
735         open:megadev_open,
736         release:megadev_close,
737 };
738
739 /*
740  * Array to structures for storing the information about the controllers. This
741  * information is sent to the user level applications, when they do an ioctl
742  * for this information.
743  */
744 static struct mcontroller mcontroller[MAX_CONTROLLERS];
745
746 /* The current driver version */
747 static u32 driver_ver = 117;
748
749 /* major number used by the device for character interface */
750 static int major;
751
752 static struct semaphore mimd_ioctl_sem;
753 static struct semaphore mimd_entry_mtx;
754
755 #if SERDEBUG
756 volatile static spinlock_t serial_lock;
757 #endif
758
759 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)  /* 0x20300 */
760 static struct proc_dir_entry proc_scsi_megaraid = {
761         PROC_SCSI_MEGARAID, 8, "megaraid",
762         S_IFDIR | S_IRUGO | S_IXUGO, 2
763 };
764 #endif
765
766 #ifdef CONFIG_PROC_FS
767 extern struct proc_dir_entry proc_root;
768 #endif
769
770 static char mega_ch_class;      /* channels are raid or scsi */
771 #define IS_RAID_CH(ch)  ( (mega_ch_class >> (ch)) & 0x01 )
772
773 #if SERDEBUG
774 static char strbuf[MAX_SERBUF + 1];
775
776 static void ser_init (void)
777 {
778         unsigned port = COM_BASE;
779
780         outb (0x80, port + 3);
781         outb (0, port + 1);
782         /* 9600 Baud, if 19200: outb(6,port) */
783         outb (12, port);
784         outb (3, port + 3);
785         outb (0, port + 1);
786 }
787
788 static void ser_puts (char *str)
789 {
790         char *ptr;
791
792         ser_init ();
793         for (ptr = str; *ptr; ++ptr)
794                 ser_putc (*ptr);
795 }
796
797 static void ser_putc (char c)
798 {
799         unsigned port = COM_BASE;
800
801         while ((inb (port + 5) & 0x20) == 0) ;
802         outb (c, port);
803         if (c == 0x0a) {
804                 while ((inb (port + 5) & 0x20) == 0) ;
805                 outb (0x0d, port);
806         }
807 }
808
809 static int ser_printk (const char *fmt, ...)
810 {
811         va_list args;
812         int i;
813         long flags;
814
815         spin_lock_irqsave (&serial_lock, flags);
816         va_start (args, fmt);
817         i = vsprintf (strbuf, fmt, args);
818         ser_puts (strbuf);
819         va_end (args);
820         spin_unlock_irqrestore (&serial_lock, flags);
821
822         return i;
823 }
824
825 #define TRACE(a)    { ser_printk a;}
826
827 #else
828 #define TRACE(A)
829 #endif
830
831 #define TRACE1(a)
832
833 static void callDone (Scsi_Cmnd * SCpnt)
834 {
835         if (SCpnt->result) {
836                 TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n",
837                         SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
838                         SCpnt->target, SCpnt->lun, SCpnt->result));
839         }
840         SCpnt->scsi_done (SCpnt);
841 }
842
843 /*-------------------------------------------------------------------------
844  *
845  *                      Local functions
846  *
847  *-------------------------------------------------------------------------*/
848
849 /*=======================
850  * Free a SCB structure
851  *=======================
852  */
853 static void mega_freeSCB (mega_host_config * megaCfg, mega_scb * pScb)
854 {
855
856         mega_scb *pScbtmp;
857
858         if ((pScb == NULL) || (pScb->idx >= 0xFE)) {
859                 return;
860         }
861 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
862         switch (pScb->dma_type) {
863         case M_RD_DMA_TYPE_NONE:
864                 break;
865         case M_RD_PTHRU_WITH_BULK_DATA:
866                 pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,
867                                   pScb->pthru->dataxferlen,
868                                   pScb->dma_direction);
869                 break;
870         case M_RD_EPTHRU_WITH_BULK_DATA:
871                 pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,
872                                   pScb->epthru->dataxferlen,
873                                   pScb->dma_direction);
874                 break;
875         case M_RD_PTHRU_WITH_SGLIST:
876         {
877                 int count;
878                 for (count = 0; count < pScb->sglist_count; count++) {
879                         pci_unmap_single (megaCfg->dev,
880                                           pScb->dma_h_sglist[count],
881                                           pScb->sgList[count].length,
882                                           pScb->dma_direction);
883
884                 }
885                 break;
886         }
887         case M_RD_BULK_DATA_ONLY:
888                 pci_unmap_single (megaCfg->dev,
889                                   pScb->dma_h_bulkdata,
890                                   pScb->iDataSize, pScb->dma_direction);
891
892                 break;
893         case M_RD_SGLIST_ONLY:
894                 pci_unmap_sg (megaCfg->dev,
895                               pScb->SCpnt->request_buffer,
896                               pScb->SCpnt->use_sg, pScb->dma_direction);
897                 break;
898         default:
899                 break;
900         }
901 #endif
902
903         /* Unlink from pending queue */
904         if (pScb == megaCfg->qPendingH) {
905
906                 if (megaCfg->qPendingH == megaCfg->qPendingT)
907                         megaCfg->qPendingH = megaCfg->qPendingT = NULL;
908                 else
909                         megaCfg->qPendingH = megaCfg->qPendingH->next;
910
911                 megaCfg->qPcnt--;
912
913         } else {
914                 for (pScbtmp = megaCfg->qPendingH; pScbtmp;
915                      pScbtmp = pScbtmp->next) {
916
917                         if (pScbtmp->next == pScb) {
918
919                                 pScbtmp->next = pScb->next;
920
921                                 if (pScb == megaCfg->qPendingT) {
922                                         megaCfg->qPendingT = pScbtmp;
923                                 }
924
925                                 megaCfg->qPcnt--;
926                                 break;
927                         }
928                 }
929         }
930
931         /* Link back into free list */
932         pScb->state = SCB_FREE;
933         pScb->SCpnt = NULL;
934
935         if (megaCfg->qFreeH == (mega_scb *) NULL) {
936                 megaCfg->qFreeH = megaCfg->qFreeT = pScb;
937         } else {
938                 megaCfg->qFreeT->next = pScb;
939                 megaCfg->qFreeT = pScb;
940         }
941
942         megaCfg->qFreeT->next = NULL;
943         megaCfg->qFcnt++;
944
945 }
946
947 /*===========================
948  * Allocate a SCB structure
949  *===========================
950  */
951 static mega_scb *mega_allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
952 {
953         mega_scb *pScb;
954
955         /* Unlink command from Free List */
956         if ((pScb = megaCfg->qFreeH) != NULL) {
957                 megaCfg->qFreeH = pScb->next;
958                 megaCfg->qFcnt--;
959
960                 pScb->isrcount = jiffies;
961                 pScb->next = NULL;
962                 pScb->state = SCB_ACTIVE;
963                 pScb->SCpnt = SCpnt;
964
965 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
966                 pScb->dma_type = M_RD_DMA_TYPE_NONE;
967 #endif
968
969                 return pScb;
970         }
971
972         printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
973
974         return NULL;
975 }
976
977 /* Run through the list of completed requests  and finish it */
978 static void mega_rundoneq (mega_host_config * megaCfg)
979 {
980         Scsi_Cmnd *SCpnt;
981
982         while ((SCpnt = megaCfg->qCompletedH) != NULL) {
983                 megaCfg->qCompletedH = (Scsi_Cmnd *) SCpnt->host_scribble;
984                 megaCfg->qCcnt--;
985
986                 SCpnt->host_scribble = (unsigned char *) NULL;  /* XC : sep 14 */
987                 /* Callback */
988                 callDone (SCpnt);
989         }
990
991         megaCfg->qCompletedH = megaCfg->qCompletedT = NULL;
992 }
993
994 /*
995  * Runs through the list of pending requests
996  * Assumes that mega_lock spin_lock has been acquired.
997  */
998 static int mega_runpendq (mega_host_config * megaCfg)
999 {
1000         mega_scb *pScb;
1001         int rc;
1002
1003         /* Issue any pending commands to the card */
1004         for (pScb = megaCfg->qPendingH; pScb; pScb = pScb->next) {
1005                 if (pScb->state == SCB_ACTIVE) {
1006                         if ((rc =
1007                              megaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) == -1)
1008                                 return rc;
1009                 }
1010         }
1011         return 0;
1012 }
1013
1014 /* Add command to the list of completed requests */
1015
1016 static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status)
1017 {
1018         int islogical;
1019         Scsi_Cmnd *SCpnt;
1020         mega_passthru *pthru;
1021         mega_ext_passthru *epthru;
1022         mega_mailbox *mbox;
1023         struct scatterlist *sgList;
1024         u8      c;
1025
1026         if (pScb == NULL) {
1027                 TRACE (("NULL pScb in mega_cmd_done!"));
1028                 printk(KERN_CRIT "NULL pScb in mega_cmd_done!");
1029         }
1030
1031         SCpnt = pScb->SCpnt;
1032
1033 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1034         pthru = pScb->pthru;
1035         epthru = pScb->epthru;
1036 #else
1037         pthru = &pScb->pthru;
1038         epthru = &pScb->epthru;
1039 #endif
1040
1041         mbox = (mega_mailbox *) & pScb->mboxData;
1042
1043         if (SCpnt == NULL) {
1044                 TRACE (("NULL SCpnt in mega_cmd_done!"));
1045                 TRACE (("pScb->idx = ", pScb->idx));
1046                 TRACE (("pScb->state = ", pScb->state));
1047                 TRACE (("pScb->state = ", pScb->state));
1048                 panic(KERN_ERR "megaraid:Problem...!\n");
1049         }
1050
1051         islogical = (SCpnt->channel == megaCfg->host->max_channel);
1052
1053 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1054         /* Special Case to handle PassThrough->XferAddrress > 4GB */
1055         switch (SCpnt->cmnd[0]) {
1056         case INQUIRY:
1057         case READ_CAPACITY:
1058                 memcpy (SCpnt->request_buffer,
1059                         pScb->bounce_buffer, SCpnt->request_bufflen);
1060                 break;
1061         }
1062 #endif
1063
1064         mega_freeSCB (megaCfg, pScb);
1065
1066         /*
1067          * Do not return the presence of hard disk on the channel so, inquiry
1068          * sent, and returned data==hard disk or removable hard disk and not
1069          * logical, request should return failure! - PJ
1070          */
1071 #if 0
1072         if (SCpnt->cmnd[0] == INQUIRY && ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && !islogical) {
1073                 status = 0xF0;
1074         }
1075 #endif
1076         if (SCpnt->cmnd[0] == INQUIRY && !islogical) {
1077                 if ( SCpnt->use_sg ) {
1078                         sgList = (struct scatterlist *)SCpnt->request_buffer;
1079                         memcpy(&c, sgList[0].address, 0x1);
1080                 } else {
1081                         memcpy(&c, SCpnt->request_buffer, 0x1);
1082                 }
1083 #if 0
1084                 if( (c & 0x1F ) == TYPE_DISK ) {
1085                         status = 0xF0;
1086                 }
1087 #endif
1088                 if( IS_RAID_CH(SCpnt->channel) && ((c & 0x1F ) == TYPE_DISK) ) {
1089                         status = 0xF0;
1090                 }
1091         }
1092
1093
1094         /* clear result; otherwise, success returns corrupt value */
1095         SCpnt->result = 0;
1096
1097         if ((SCpnt->cmnd[0] & M_RD_IOCTL_CMD)) {        /* i.e. ioctl cmd such as M_RD_IOCTL_CMD, M_RD_IOCTL_CMD_NEW of megamgr */
1098                 switch (status) {
1099                 case 2:
1100                 case 0xF0:
1101                 case 0xF4:
1102                         SCpnt->result = (DID_BAD_TARGET << 16) | status;
1103                         break;
1104                 default:
1105                         SCpnt->result |= status;
1106                 }               /*end of switch */
1107         } else {
1108                 /* Convert MegaRAID status to Linux error code */
1109                 switch (status) {
1110                 case 0x00:      /* SUCCESS , i.e. SCSI_STATUS_GOOD */
1111                         SCpnt->result |= (DID_OK << 16);
1112                         break;
1113
1114                 case 0x02:      /* ERROR_ABORTED, i.e. SCSI_STATUS_CHECK_CONDITION */
1115
1116                         /*set sense_buffer and result fields */
1117                         if (mbox->cmd == MEGA_MBOXCMD_PASSTHRU) {
1118                                 memcpy (SCpnt->sense_buffer, pthru->reqsensearea, 14);
1119                         } else if (mbox->cmd == MEGA_MBOXCMD_EXTPASSTHRU) {
1120                                 SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION < 1);
1121                                 memcpy(
1122                                         SCpnt->sense_buffer,
1123                                         epthru->reqsensearea, 14
1124                                 );
1125                                 SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION < 1);
1126                                 /*SCpnt->result =
1127                                         (DRIVER_SENSE << 24) |
1128                                         (DID_ERROR << 16) | status;*/
1129                         } else {
1130                                 SCpnt->sense_buffer[0] = 0x70;
1131                                 SCpnt->sense_buffer[2] = ABORTED_COMMAND;
1132                                 SCpnt->result |= (CHECK_CONDITION << 1);
1133                         }
1134                         break;
1135
1136                 case 0x08:      /* ERR_DEST_DRIVE_FAILED, i.e. SCSI_STATUS_BUSY */
1137                         SCpnt->result |= (DID_BUS_BUSY << 16) | status;
1138                         break;
1139
1140                 default:
1141                         SCpnt->result |= (DID_BAD_TARGET << 16) | status;
1142                         break;
1143                 }
1144         }
1145
1146         /* Add Scsi_Command to end of completed queue */
1147         if (megaCfg->qCompletedH == NULL) {
1148                 megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1149         } else {
1150                 megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1151                 megaCfg->qCompletedT = SCpnt;
1152         }
1153
1154         megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1155         megaCfg->qCcnt++;
1156 }
1157
1158 /*-------------------------------------------------------------------
1159  *
1160  *                 Build a SCB from a Scsi_Cmnd
1161  *
1162  * Returns a SCB pointer, or NULL
1163  * If NULL is returned, the scsi_done function MUST have been called
1164  *
1165  *-------------------------------------------------------------------*/
1166
1167 static mega_scb *mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1168 {
1169         mega_scb *pScb;
1170         mega_mailbox *mbox;
1171         mega_passthru *pthru;
1172         mega_ext_passthru *epthru;
1173         long seg;
1174         char islogical;
1175         char lun = SCpnt->lun;
1176
1177         if ((SCpnt->cmnd[0] == MEGADEVIOC))
1178                 return megadev_doioctl (megaCfg, SCpnt);
1179
1180         if ((SCpnt->cmnd[0] == M_RD_IOCTL_CMD)
1181                     || (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW))
1182 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  
1183                 return mega_ioctl (megaCfg, SCpnt);     /* Handle IOCTL command */
1184 #else
1185         {
1186                 printk(KERN_WARNING "megaraid ioctl: older interface - "
1187                                 "not supported.\n");
1188                 return NULL;
1189         }
1190 #endif
1191
1192         islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */
1193                                                 (SCpnt->channel == megaCfg->host->max_channel));
1194
1195         if ( ! megaCfg->support_ext_cdb ) {
1196                 if (!islogical && lun != 0) {
1197                         SCpnt->result = (DID_BAD_TARGET << 16);
1198                         callDone (SCpnt);
1199                         return NULL;
1200                 }
1201         }
1202
1203         if (!islogical && SCpnt->target == skip_id) {
1204                 SCpnt->result = (DID_BAD_TARGET << 16);
1205                 callDone (SCpnt);
1206                 return NULL;
1207         }
1208
1209         /*
1210          * Return error for LUN > 7. The way we calculate logical drive number
1211          * requires it to be so.
1212          */
1213         if( lun > 7 ) {
1214                 SCpnt->result = (DID_BAD_TARGET << 16);
1215                 callDone (SCpnt);
1216                 return NULL;
1217         }
1218
1219         if (islogical) {
1220
1221                 lun = (SCpnt->target * 8) + lun;
1222
1223                 if(lun >= megaCfg->numldrv ) {
1224                         SCpnt->result = (DID_BAD_TARGET << 16);
1225                         callDone (SCpnt);
1226                         return NULL;
1227                 }
1228
1229                 /*
1230                  * If we have a logical drive with boot enabled, project it first
1231                  */
1232                 if( megaCfg->boot_ldrv_enabled ) {
1233                         if( lun == 0 ) {
1234                                 lun = megaCfg->boot_ldrv;
1235                         }
1236                         else {
1237                                 if( lun <= megaCfg->boot_ldrv ) {
1238                                         lun--;
1239                                 }
1240                         }
1241                 }
1242         }
1243         /*-----------------------------------------------------
1244          *
1245          *               Logical drive commands
1246          *
1247          *-----------------------------------------------------*/
1248         if (islogical) {
1249                 switch (SCpnt->cmnd[0]) {
1250                 case TEST_UNIT_READY:
1251                         memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
1252                         SCpnt->result = (DID_OK << 16);
1253                         callDone (SCpnt);
1254                         return NULL;
1255
1256                 case MODE_SENSE:
1257                         memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
1258                         SCpnt->result = (DID_OK << 16);
1259                         callDone (SCpnt);
1260                         return NULL;
1261
1262                 case READ_CAPACITY:
1263                 case INQUIRY:
1264                         /* Allocate a SCB and initialize passthru */
1265                         if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1266                                 SCpnt->result = (DID_ERROR << 16);
1267                                 callDone (SCpnt);
1268                                 return NULL;
1269                         }
1270 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1271                         pthru = pScb->pthru;
1272 #else
1273                         pthru = &pScb->pthru;
1274 #endif
1275
1276                         mbox = (mega_mailbox *) & pScb->mboxData;
1277                         memset (mbox, 0, sizeof (pScb->mboxData));
1278                         memset (pthru, 0, sizeof (mega_passthru));
1279                         pthru->timeout = 0;
1280                         pthru->ars = 1;
1281                         pthru->reqsenselen = 14;
1282                         pthru->islogical = 1;
1283                         pthru->logdrv = lun;
1284                         pthru->cdblen = SCpnt->cmd_len;
1285
1286 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1287                         /*Not sure about the direction */
1288                         pScb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1289                         pScb->dma_type = M_RD_PTHRU_WITH_BULK_DATA;
1290
1291 #if 0
1292 /* Normal Code w/o the need for bounce buffer */
1293                         pScb->dma_h_bulkdata
1294                             = pci_map_single (megaCfg->dev,
1295                                               SCpnt->request_buffer,
1296                                               SCpnt->request_bufflen,
1297                                               pScb->dma_direction);
1298
1299                         pthru->dataxferaddr = pScb->dma_h_bulkdata;
1300 #else
1301 /* Special Code to use bounce buffer for READ_CAPA/INQ */
1302                         pthru->dataxferaddr = pScb->dma_bounce_buffer;
1303                         pScb->dma_type = M_RD_DMA_TYPE_NONE;
1304 #endif
1305
1306 #else
1307                         pthru->dataxferaddr =
1308                             virt_to_bus (SCpnt->request_buffer);
1309 #endif
1310
1311                         pthru->dataxferlen = SCpnt->request_bufflen;
1312                         memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
1313
1314                         /* Initialize mailbox area */
1315                         mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1316
1317 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1318                         mbox->xferaddr = pScb->dma_passthruhandle64;
1319                         TRACE1 (("M_RD_PTHRU_WITH_BULK_DATA Enabled \n"));
1320 #else
1321                         mbox->xferaddr = virt_to_bus (pthru);
1322 #endif
1323                         return pScb;
1324
1325                 case READ_6:
1326                 case WRITE_6:
1327                 case READ_10:
1328                 case WRITE_10:
1329                         /* Allocate a SCB and initialize mailbox */
1330                         if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1331                                 SCpnt->result = (DID_ERROR << 16);
1332                                 callDone (SCpnt);
1333                                 return NULL;
1334                         }
1335                         mbox = (mega_mailbox *) & pScb->mboxData;
1336
1337                         memset (mbox, 0, sizeof (pScb->mboxData));
1338                         mbox->logdrv = lun;
1339
1340                         if (megaCfg->flag & BOARD_64BIT) {
1341                                 mbox->cmd = (*SCpnt->cmnd == READ_6
1342                                              || *SCpnt->cmnd ==
1343                                              READ_10) ? MEGA_MBOXCMD_LREAD64 :
1344                                     MEGA_MBOXCMD_LWRITE64;
1345                         } else {
1346                                 mbox->cmd = (*SCpnt->cmnd == READ_6
1347                                              || *SCpnt->cmnd ==
1348                                              READ_10) ? MEGA_MBOXCMD_LREAD :
1349                                     MEGA_MBOXCMD_LWRITE;
1350                         }
1351
1352                         /* 6-byte */
1353                         if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
1354                                 mbox->numsectors = (u32) SCpnt->cmnd[4];
1355                                 mbox->lba =
1356                                     ((u32) SCpnt->cmnd[1] << 16) |
1357                                     ((u32) SCpnt->cmnd[2] << 8) |
1358                                     (u32) SCpnt->cmnd[3];
1359                                 mbox->lba &= 0x1FFFFF;
1360
1361                                 if (*SCpnt->cmnd == READ_6) {
1362                                         megaCfg->nReads[(int) lun]++;
1363                                         megaCfg->nReadBlocks[(int) lun] +=
1364                                             mbox->numsectors;
1365                                 } else {
1366                                         megaCfg->nWrites[(int) lun]++;
1367                                         megaCfg->nWriteBlocks[(int) lun] +=
1368                                             mbox->numsectors;
1369                                 }
1370                         }
1371
1372                         /* 10-byte */
1373                         if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
1374                                 mbox->numsectors =
1375                                     (u32) SCpnt->cmnd[8] |
1376                                     ((u32) SCpnt->cmnd[7] << 8);
1377                                 mbox->lba =
1378                                     ((u32) SCpnt->cmnd[2] << 24) |
1379                                     ((u32) SCpnt->cmnd[3] << 16) |
1380                                     ((u32) SCpnt->cmnd[4] << 8) |
1381                                     (u32) SCpnt->cmnd[5];
1382
1383                                 if (*SCpnt->cmnd == READ_10) {
1384                                         megaCfg->nReads[(int) lun]++;
1385                                         megaCfg->nReadBlocks[(int) lun] +=
1386                                             mbox->numsectors;
1387                                 } else {
1388                                         megaCfg->nWrites[(int) lun]++;
1389                                         megaCfg->nWriteBlocks[(int) lun] +=
1390                                             mbox->numsectors;
1391                                 }
1392                         }
1393
1394                         /* 12-byte */
1395                         if (*SCpnt->cmnd == READ_12 || *SCpnt->cmnd == WRITE_12) {
1396                                 mbox->lba =
1397                                     ((u32) SCpnt->cmnd[2] << 24) |
1398                                     ((u32) SCpnt->cmnd[3] << 16) |
1399                                     ((u32) SCpnt->cmnd[4] << 8) |
1400                                     (u32) SCpnt->cmnd[5];
1401
1402                                 mbox->numsectors =
1403                                     ((u32) SCpnt->cmnd[6] << 24) |
1404                                     ((u32) SCpnt->cmnd[7] << 16) |
1405                                     ((u32) SCpnt->cmnd[8] << 8) |
1406                                     (u32) SCpnt->cmnd[9];
1407
1408                                 if (*SCpnt->cmnd == READ_12) {
1409                                         megaCfg->nReads[(int) lun]++;
1410                                         megaCfg->nReadBlocks[(int) lun] +=
1411                                             mbox->numsectors;
1412                                 } else {
1413                                         megaCfg->nWrites[(int) lun]++;
1414                                         megaCfg->nWriteBlocks[(int) lun] +=
1415                                             mbox->numsectors;
1416                                 }
1417                         }
1418
1419 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1420                         if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10
1421                                         || *SCpnt->cmnd == READ_12) {
1422                                 pScb->dma_direction = PCI_DMA_FROMDEVICE;
1423                         } else {        /*WRITE_6 or WRITE_10 */
1424                                 pScb->dma_direction = PCI_DMA_TODEVICE;
1425                         }
1426 #endif
1427
1428                         /* Calculate Scatter-Gather info */
1429                         mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
1430                                                                  (u32 *)&mbox->xferaddr, (u32 *)&seg);
1431
1432 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1433                         pScb->iDataSize = seg;
1434
1435                         if (mbox->numsgelements) {
1436                                 pScb->dma_type = M_RD_SGLIST_ONLY;
1437                                 TRACE1 (("M_RD_SGLIST_ONLY Enabled \n"));
1438                         } else {
1439                                 pScb->dma_type = M_RD_BULK_DATA_ONLY;
1440                                 TRACE1 (("M_RD_BULK_DATA_ONLY Enabled \n"));
1441                         }
1442 #endif
1443
1444                         return pScb;
1445                 default:
1446                         SCpnt->result = (DID_BAD_TARGET << 16);
1447                         callDone (SCpnt);
1448                         return NULL;
1449                 }
1450         }
1451         /*-----------------------------------------------------
1452          *
1453          *               Passthru drive commands
1454          *
1455          *-----------------------------------------------------*/
1456         else {
1457                 /* Allocate a SCB and initialize passthru */
1458                 if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1459                         SCpnt->result = (DID_ERROR << 16);
1460                         callDone (SCpnt);
1461                         return NULL;
1462                 }
1463
1464                 mbox = (mega_mailbox *) pScb->mboxData;
1465                 memset (mbox, 0, sizeof (pScb->mboxData));
1466
1467                 if ( megaCfg->support_ext_cdb && SCpnt->cmd_len > 10 ) {
1468                         epthru = mega_prepare_extpassthru(megaCfg, pScb, SCpnt);
1469                         mbox->cmd = MEGA_MBOXCMD_EXTPASSTHRU;
1470 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1471                         mbox->xferaddr = pScb->dma_ext_passthruhandle64;
1472
1473                         if(epthru->numsgelements) {
1474                                 pScb->dma_type = M_RD_PTHRU_WITH_SGLIST;
1475                         } else {
1476                                 pScb->dma_type = M_RD_EPTHRU_WITH_BULK_DATA;
1477                         }
1478 #else
1479                         mbox->xferaddr = virt_to_bus(epthru);
1480 #endif
1481                 }
1482                 else {
1483                         pthru = mega_prepare_passthru(megaCfg, pScb, SCpnt);
1484
1485                         /* Initialize mailbox */
1486                         mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1487 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1488                         mbox->xferaddr = pScb->dma_passthruhandle64;
1489
1490                         if (pthru->numsgelements) {
1491                                 pScb->dma_type = M_RD_PTHRU_WITH_SGLIST;
1492                         } else {
1493                                 pScb->dma_type = M_RD_PTHRU_WITH_BULK_DATA;
1494                         }
1495 #else
1496                         mbox->xferaddr = virt_to_bus(pthru);
1497 #endif
1498                 }
1499                 return pScb;
1500         }
1501         return NULL;
1502 }
1503
1504 static mega_passthru *
1505 mega_prepare_passthru(mega_host_config *megacfg, mega_scb *scb, Scsi_Cmnd *sc)
1506 {
1507         mega_passthru *pthru;
1508
1509 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1510         pthru = scb->pthru;
1511 #else
1512         pthru = &scb->pthru;
1513 #endif
1514         memset (pthru, 0, sizeof (mega_passthru));
1515
1516         /* set adapter timeout value to 10 min. for tape drive  */
1517         /* 0=6sec/1=60sec/2=10min/3=3hrs                        */
1518         pthru->timeout = 2;
1519         pthru->ars = 1;
1520         pthru->reqsenselen = 14;
1521         pthru->islogical = 0;
1522         pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
1523         pthru->target = (megacfg->flag & BOARD_40LD) ?
1524             (sc->channel << 4) | sc->target : sc->target;
1525         pthru->cdblen = sc->cmd_len;
1526         pthru->logdrv = sc->lun;
1527
1528         memcpy (pthru->cdb, sc->cmnd, sc->cmd_len);
1529
1530 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1531         /* Not sure about the direction */
1532         scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1533
1534         /* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
1535         switch (sc->cmnd[0]) {
1536         case INQUIRY:
1537         case READ_CAPACITY:
1538                 pthru->numsgelements = 0;
1539                 pthru->dataxferaddr = scb->dma_bounce_buffer;
1540                 pthru->dataxferlen = sc->request_bufflen;
1541                 break;
1542         default:
1543                 pthru->numsgelements =
1544                         mega_build_sglist(
1545                                 megacfg, scb, (u32 *)&pthru->dataxferaddr,
1546                                 (u32 *)&pthru->dataxferlen
1547                         );
1548                 break;
1549         }
1550 #else
1551         pthru->numsgelements =
1552                 mega_build_sglist(
1553                         megacfg, scb, (u32 *)&pthru->dataxferaddr,
1554                         (u32 *)&pthru->dataxferlen
1555                 );
1556 #endif
1557         return pthru;
1558 }
1559
1560 static mega_ext_passthru *
1561 mega_prepare_extpassthru(mega_host_config *megacfg, mega_scb *scb, Scsi_Cmnd *sc)
1562 {
1563         mega_ext_passthru *epthru;
1564
1565 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1566         epthru = scb->epthru;
1567 #else
1568         epthru = &scb->epthru;
1569 #endif
1570         memset(epthru, 0, sizeof(mega_ext_passthru));
1571
1572         /* set adapter timeout value to 10 min. for tape drive  */
1573         /* 0=6sec/1=60sec/2=10min/3=3hrs                        */
1574         epthru->timeout = 2;
1575         epthru->ars = 1;
1576         epthru->reqsenselen = 14;
1577         epthru->islogical = 0;
1578         epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
1579         epthru->target = (megacfg->flag & BOARD_40LD) ?
1580             (sc->channel << 4) | sc->target : sc->target;
1581         epthru->cdblen = sc->cmd_len;
1582         epthru->logdrv = sc->lun;
1583
1584         memcpy(epthru->cdb, sc->cmnd, sc->cmd_len);
1585
1586 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1587         /* Not sure about the direction */
1588         scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1589
1590         /* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
1591         switch (sc->cmnd[0]) {
1592         case INQUIRY:
1593         case READ_CAPACITY:
1594                 epthru->numsgelements = 0;
1595                 epthru->dataxferaddr = scb->dma_bounce_buffer;
1596                 epthru->dataxferlen = sc->request_bufflen;
1597                 break;
1598         default:
1599                 epthru->numsgelements =
1600                         mega_build_sglist(
1601                                 megacfg, scb, (u32 *)&epthru->dataxferaddr,
1602                                 (u32 *)&epthru->dataxferlen
1603                         );
1604                 break;
1605         }
1606 #else
1607         epthru->numsgelements =
1608                 mega_build_sglist(
1609                         megacfg, scb, (u32 *)&epthru->dataxferaddr,
1610                         (u32 *)&epthru->dataxferlen
1611                 );
1612 #endif
1613         return epthru;
1614 }
1615
1616 /* Handle Driver Level IOCTLs
1617  * Return value of 0 indicates this function could not handle , so continue
1618  * processing
1619 */
1620
1621 static int mega_driver_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1622 {
1623         unsigned char *data = (unsigned char *) SCpnt->request_buffer;
1624         mega_driver_info driver_info;
1625
1626         /* If this is not our command dont do anything */
1627         if (SCpnt->cmnd[0] != M_RD_DRIVER_IOCTL_INTERFACE)
1628                 return 0;
1629
1630         switch (SCpnt->cmnd[1]) {
1631         case GET_DRIVER_INFO:
1632                 if (SCpnt->request_bufflen < sizeof (driver_info)) {
1633                         SCpnt->result = DID_BAD_TARGET << 16;
1634                         callDone (SCpnt);
1635                         return 1;
1636                 }
1637
1638                 driver_info.size = sizeof (driver_info) - sizeof (int);
1639                 driver_info.version = MEGARAID_IOCTL_VERSION;
1640                 memcpy (data, &driver_info, sizeof (driver_info));
1641                 break;
1642         default:
1643                 SCpnt->result = DID_BAD_TARGET << 16;
1644         }
1645
1646         callDone (SCpnt);
1647         return 1;
1648 }
1649
1650 static void inline set_mbox_xfer_addr (mega_host_config * megaCfg, mega_scb * pScb,
1651                     mega_ioctl_mbox * mbox, u32 direction)
1652 {
1653
1654 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1655         switch (direction) {
1656         case TO_DEVICE:
1657                 pScb->dma_direction = PCI_DMA_TODEVICE;
1658                 break;
1659         case FROM_DEVICE:
1660                 pScb->dma_direction = PCI_DMA_FROMDEVICE;
1661                 break;
1662         case FROMTO_DEVICE:
1663                 pScb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1664                 break;
1665         }
1666
1667         pScb->dma_h_bulkdata
1668             = pci_map_single (megaCfg->dev,
1669                               pScb->buff_ptr,
1670                               pScb->iDataSize, pScb->dma_direction);
1671         mbox->xferaddr = pScb->dma_h_bulkdata;
1672         pScb->dma_type = M_RD_BULK_DATA_ONLY;
1673         TRACE1 (("M_RD_BULK_DATA_ONLY Enabled \n"));
1674 #else
1675         mbox->xferaddr = virt_to_bus (pScb->buff_ptr);
1676 #endif
1677 }
1678
1679 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
1680
1681 /*--------------------------------------------------------------------
1682  * build RAID commands for controller, passed down through ioctl()
1683  *--------------------------------------------------------------------*/
1684 static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1685 {
1686         mega_scb *pScb;
1687         mega_ioctl_mbox *mbox;
1688         mega_mailbox *mailbox;
1689         mega_passthru *pthru;
1690         u8 *mboxdata;
1691         long seg, i = 0;
1692         unsigned char *data = (unsigned char *) SCpnt->request_buffer;
1693
1694         if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1695                 SCpnt->result = (DID_ERROR << 16);
1696                 callDone (SCpnt);
1697                 return NULL;
1698         }
1699         pthru = &pScb->pthru;
1700
1701         mboxdata = (u8 *) & pScb->mboxData;
1702         mbox = (mega_ioctl_mbox *) & pScb->mboxData;
1703         mailbox = (mega_mailbox *) & pScb->mboxData;
1704         memset (mailbox, 0, sizeof (pScb->mboxData));
1705
1706         if (data[0] == 0x03) {  /* passthrough command */
1707                 unsigned char cdblen = data[2];
1708                 memset (pthru, 0, sizeof (mega_passthru));
1709                 pthru->islogical = (data[cdblen + 3] & 0x80) ? 1 : 0;
1710                 pthru->timeout = data[cdblen + 3] & 0x07;
1711                 pthru->reqsenselen = 14;
1712                 pthru->ars = (data[cdblen + 3] & 0x08) ? 1 : 0;
1713                 pthru->logdrv = data[cdblen + 4];
1714                 pthru->channel = data[cdblen + 5];
1715                 pthru->target = data[cdblen + 6];
1716                 pthru->cdblen = cdblen;
1717                 memcpy (pthru->cdb, &data[3], cdblen);
1718
1719                 mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1720
1721
1722                 pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
1723                                                           (u32 *) & pthru->
1724                                                           dataxferaddr,
1725                                                           (u32 *) & pthru->
1726                                                           dataxferlen);
1727
1728                 mailbox->xferaddr = virt_to_bus (pthru);
1729
1730                 for (i = 0; i < (SCpnt->request_bufflen - cdblen - 7); i++) {
1731                         data[i] = data[i + cdblen + 7];
1732                 }
1733                 return pScb;
1734         }
1735         /* else normal (nonpassthru) command */
1736
1737 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,0,24) /*0x020024 */
1738         /*
1739          *usage of the function copy from user is used in case of data more than
1740          *4KB.This is used only with adapters which supports more than 8 logical
1741          * drives.This feature is disabled on kernels earlier or same as 2.0.36
1742          * as the uaccess.h file is not available with those kernels.
1743          */
1744
1745         if (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
1746                 /* use external data area for large xfers  */
1747                 /* If cmnd[0] is set to M_RD_IOCTL_CMD_NEW then *
1748                  *   cmnd[4..7] = external user buffer     *
1749                  *   cmnd[8..11] = length of buffer        *
1750                  *                                         */
1751         char *user_area = (char *)*((u32*)&SCpnt->cmnd[4]);
1752                 u32 xfer_size = *((u32 *) & SCpnt->cmnd[8]);
1753                 switch (data[0]) {
1754                 case FW_FIRE_WRITE:
1755                 case FW_FIRE_FLASH:
1756                         if ((ulong) user_area & (PAGE_SIZE - 1)) {
1757                                 printk
1758                                     ("megaraid:user address not aligned on 4K boundary.Error.\n");
1759                                 SCpnt->result = (DID_ERROR << 16);
1760                                 callDone (SCpnt);
1761                                 return NULL;
1762                         }
1763                         break;
1764                 default:
1765                         break;
1766                 }
1767
1768                 if (!(pScb->buff_ptr = kmalloc (xfer_size, GFP_KERNEL))) {
1769                         printk
1770                             ("megaraid: Insufficient mem for M_RD_IOCTL_CMD_NEW.\n");
1771                         SCpnt->result = (DID_ERROR << 16);
1772                         callDone (SCpnt);
1773                         return NULL;
1774                 }
1775
1776                 copy_from_user (pScb->buff_ptr, user_area, xfer_size);
1777                 pScb->iDataSize = xfer_size;
1778
1779                 switch (data[0]) {
1780                 case DCMD_FC_CMD:
1781                         switch (data[1]) {
1782                         case DCMD_FC_READ_NVRAM_CONFIG:
1783                         case DCMD_GET_DISK_CONFIG:
1784                                 {
1785                                         if ((ulong) pScb->
1786                                             buff_ptr & (PAGE_SIZE - 1)) {
1787                                                 printk
1788                                                     ("megaraid:user address not sufficient Error.\n");
1789                                                 SCpnt->result =
1790                                                     (DID_ERROR << 16);
1791                                                 callDone (SCpnt);
1792                                                 return NULL;
1793                                         }
1794
1795                                         /*building SG list */
1796                                         mega_build_kernel_sg (pScb->buff_ptr,
1797                                                               xfer_size,
1798                                                               pScb, mbox);
1799                                         break;
1800                                 }
1801                         default:
1802                                 break;
1803                         }       /*switch (data[1]) */
1804                         break;
1805                 }
1806
1807         }
1808 #endif
1809
1810         mbox->cmd = data[0];
1811         mbox->channel = data[1];
1812         mbox->param = data[2];
1813         mbox->pad[0] = data[3];
1814         mbox->logdrv = data[4];
1815
1816         if (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
1817                 switch (data[0]) {
1818                 case FW_FIRE_WRITE:
1819                         mbox->cmd = FW_FIRE_WRITE;
1820                         mbox->channel = data[1];        /* Current Block Number */
1821                         set_mbox_xfer_addr (megaCfg, pScb, mbox, TO_DEVICE);
1822                         mbox->numsgelements = 0;
1823                         break;
1824                 case FW_FIRE_FLASH:
1825                         mbox->cmd = FW_FIRE_FLASH;
1826                         mbox->channel = data[1] | 0x80; /* Origin */
1827                         set_mbox_xfer_addr (megaCfg, pScb, mbox, TO_DEVICE);
1828                         mbox->numsgelements = 0;
1829                         break;
1830                 case DCMD_FC_CMD:
1831                         *(mboxdata + 0) = data[0];      /*mailbox byte 0: DCMD_FC_CMD */
1832                         *(mboxdata + 2) = data[1];      /*sub command */
1833                         switch (data[1]) {
1834                         case DCMD_FC_READ_NVRAM_CONFIG:
1835                         case DCMD_FC_READ_NVRAM_CONFIG_64:
1836                                 /* number of elements in SG list */
1837                                 *(mboxdata + 3) = mbox->numsgelements;
1838                                 if (megaCfg->flag & BOARD_64BIT)
1839                                         *(mboxdata + 2) =
1840                                             DCMD_FC_READ_NVRAM_CONFIG_64;
1841                                 break;
1842                         case DCMD_WRITE_CONFIG:
1843                         case DCMD_WRITE_CONFIG_64:
1844                                 if (megaCfg->flag & BOARD_64BIT)
1845                                         *(mboxdata + 2) = DCMD_WRITE_CONFIG_64;
1846                                 set_mbox_xfer_addr (megaCfg, pScb, mbox,
1847                                                     TO_DEVICE);
1848                                 mbox->numsgelements = 0;
1849                                 break;
1850                         case DCMD_GET_DISK_CONFIG:
1851                         case DCMD_GET_DISK_CONFIG_64:
1852                                 if (megaCfg->flag & BOARD_64BIT)
1853                                         *(mboxdata + 2) =
1854                                             DCMD_GET_DISK_CONFIG_64;
1855                                 *(mboxdata + 3) = data[2];      /*number of elements in SG list */
1856                                 /*nr of elements in SG list */
1857                                 *(mboxdata + 4) = mbox->numsgelements;
1858                                 break;
1859                         case DCMD_DELETE_LOGDRV:
1860                         case DCMD_DELETE_DRIVEGROUP:
1861                         case NC_SUBOP_ENQUIRY3:
1862                                 *(mboxdata + 3) = data[2];
1863                                 set_mbox_xfer_addr (megaCfg, pScb, mbox,
1864                                                     FROMTO_DEVICE);
1865                                 mbox->numsgelements = 0;
1866                                 break;
1867                         case DCMD_CHANGE_LDNO:
1868                         case DCMD_CHANGE_LOOPID:
1869                                 *(mboxdata + 3) = data[2];
1870                                 *(mboxdata + 4) = data[3];
1871                                 set_mbox_xfer_addr (megaCfg, pScb, mbox,
1872                                                     TO_DEVICE);
1873                                 mbox->numsgelements = 0;
1874                                 break;
1875                         default:
1876                                 set_mbox_xfer_addr (megaCfg, pScb, mbox,
1877                                                     FROMTO_DEVICE);
1878                                 mbox->numsgelements = 0;
1879                                 break;
1880                         }       /*switch */
1881                         break;
1882                 default:
1883                         set_mbox_xfer_addr (megaCfg, pScb, mbox, FROMTO_DEVICE);
1884                         mbox->numsgelements = 0;
1885                         break;
1886                 }
1887         } else {
1888
1889                 mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
1890                                                          (u32 *) & mbox->
1891                                                          xferaddr,
1892                                                          (u32 *) & seg);
1893
1894                 /* Handling some of the fw special commands */
1895                 switch (data[0]) {
1896                 case 6: /* START_DEV */
1897                         mbox->xferaddr = *((u32 *) & data[i + 6]);
1898                         break;
1899                 default:
1900                         break;
1901                 }
1902
1903                 for (i = 0; i < (SCpnt->request_bufflen - 6); i++) {
1904                         data[i] = data[i + 6];
1905                 }
1906         }
1907
1908         return (pScb);
1909 }
1910
1911
1912 static void mega_build_kernel_sg (char *barea, ulong xfersize, mega_scb * pScb, mega_ioctl_mbox * mbox)
1913 {
1914         ulong i, buffer_area, len, end, end_page, x, idx = 0;
1915
1916         buffer_area = (ulong) barea;
1917         i = buffer_area;
1918         end = buffer_area + xfersize;
1919         end_page = (end) & ~(PAGE_SIZE - 1);
1920
1921         do {
1922                 len = PAGE_SIZE - (i % PAGE_SIZE);
1923                 x = pScb->sgList[idx].address =
1924                     virt_to_bus ((volatile void *) i);
1925                 pScb->sgList[idx].length = len;
1926                 i += len;
1927                 idx++;
1928         } while (i < end_page);
1929
1930         if ((end - i) < 0) {
1931                 printk ("megaraid:Error in user address\n");
1932         }
1933
1934         if (end - i) {
1935                 pScb->sgList[idx].address = virt_to_bus ((volatile void *) i);
1936                 pScb->sgList[idx].length = end - i;
1937                 idx++;
1938         }
1939         mbox->xferaddr = virt_to_bus (pScb->sgList);
1940         mbox->numsgelements = idx;
1941 }
1942 #endif
1943
1944
1945 #if DEBUG
1946 static unsigned int cum_time = 0;
1947 static unsigned int cum_time_cnt = 0;
1948
1949 static void showMbox (mega_scb * pScb)
1950 {
1951         mega_mailbox *mbox;
1952
1953         if (pScb == NULL)
1954                 return;
1955
1956         mbox = (mega_mailbox *) pScb->mboxData;
1957         printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
1958                 pScb->SCpnt->pid,
1959                 mbox->cmd, mbox->cmdid, mbox->numsectors,
1960                 mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements);
1961 }
1962
1963 #endif
1964
1965 /*--------------------------------------------------------------------
1966  * Interrupt service routine
1967  *--------------------------------------------------------------------*/
1968 static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
1969 {
1970         IO_LOCK_T
1971         mega_host_config * megaCfg;
1972         u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
1973         u32 dword = 0;
1974         mega_mailbox *mbox;
1975         mega_scb *pScb;
1976         u_char qCnt, qStatus;
1977         u_char completed[MAX_FIRMWARE_STATUS];
1978         Scsi_Cmnd *SCpnt;
1979
1980         megaCfg = (mega_host_config *) devp;
1981         mbox = (mega_mailbox *) tmpBox;
1982
1983         if (megaCfg->host->irq == irq) {
1984                 if (megaCfg->flag & IN_ISR) {
1985                         TRACE (("ISR called reentrantly!!\n"));
1986                         printk ("ISR called reentrantly!!\n");
1987                 }
1988                 megaCfg->flag |= IN_ISR;
1989
1990                 if (mega_busyWaitMbox (megaCfg)) {
1991                         printk (KERN_WARNING "Error: mailbox busy in isr!\n");
1992                 }
1993
1994                 /* Check if a valid interrupt is pending */
1995                 if (megaCfg->flag & BOARD_QUARTZ) {
1996                         dword = RDOUTDOOR (megaCfg);
1997                         if (dword != 0x10001234) {
1998                                 /* Spurious interrupt */
1999                                 megaCfg->flag &= ~IN_ISR;
2000                                 return;
2001                         }
2002                 } else {
2003                         byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
2004                         if ((byte & VALID_INTR_BYTE) == 0) {
2005                                 /* Spurious interrupt */
2006                                 megaCfg->flag &= ~IN_ISR;
2007                                 return;
2008                         }
2009                         WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
2010                 }
2011
2012                 for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
2013                         completed[idx] = 0;
2014
2015                 IO_LOCK;
2016
2017                 megaCfg->nInterrupts++;
2018                 qCnt = 0xff;
2019                 while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ;
2020
2021                 qStatus = 0xff;
2022                 while ((qStatus = megaCfg->mbox->status) == 0xFF) ;
2023
2024                 /* Get list of completed requests */
2025                 for (idx = 0; idx < qCnt; idx++) {
2026                         while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
2027                                 printk ("p");
2028                         }
2029                         completed[idx] = sIdx;
2030                         sIdx = 0xFF;
2031                 }
2032
2033                 if (megaCfg->flag & BOARD_QUARTZ) {
2034                         WROUTDOOR (megaCfg, dword);
2035                         /* Acknowledge interrupt */
2036 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2037                         /* In this case mbox contains physical address */
2038 #if 0
2039                         WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2);
2040 #else
2041                         WRINDOOR (megaCfg, 0x2);
2042 #endif
2043
2044 #else
2045
2046 #if 0
2047                         WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
2048 #else
2049                         WRINDOOR (megaCfg, 0x2);
2050 #endif
2051
2052 #endif
2053
2054 #if 0
2055                         while (RDINDOOR (megaCfg) & 0x02) ;
2056 #endif
2057                 } else {
2058                         CLEAR_INTR (megaCfg->host->io_port);
2059                 }
2060
2061 #if DEBUG
2062                 if (qCnt >= MAX_FIRMWARE_STATUS) {
2063                         printk ("megaraid_isr: cmplt=%d ", qCnt);
2064                 }
2065 #endif
2066
2067                 for (idx = 0; idx < qCnt; idx++) {
2068                         sIdx = completed[idx];
2069                         if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
2070                                 pScb = &megaCfg->scbList[sIdx - 1];
2071
2072                                 /* ASSERT(pScb->state == SCB_ISSUED); */
2073
2074 #if DEBUG
2075                                 if (((jiffies) - pScb->isrcount) > maxCmdTime) {
2076                                         maxCmdTime = (jiffies) - pScb->isrcount;
2077                                         printk
2078                                             ("megaraid_isr : cmd time = %u\n",
2079                                              maxCmdTime);
2080                                 }
2081 #endif
2082                                 /*
2083                                  * Assuming that the scsi command, for which 
2084                                  * an abort request was received earlier, has 
2085                                  * completed.
2086                                  */
2087                                 if (pScb->state == SCB_ABORTED) {
2088                                         SCpnt = pScb->SCpnt;
2089                                 }
2090                                 if (pScb->state == SCB_RESET) {
2091                                         SCpnt = pScb->SCpnt;
2092                                         mega_freeSCB (megaCfg, pScb);
2093                                         SCpnt->result = (DID_RESET << 16);
2094                                         if (megaCfg->qCompletedH == NULL) {
2095                                                 megaCfg->qCompletedH =
2096                                                     megaCfg->qCompletedT =
2097                                                     SCpnt;
2098                                         } else {
2099                                                 megaCfg->qCompletedT->
2100                                                     host_scribble =
2101                                                     (unsigned char *) SCpnt;
2102                                                 megaCfg->qCompletedT = SCpnt;
2103                                         }
2104                                         megaCfg->qCompletedT->host_scribble =
2105                                             (unsigned char *) NULL;
2106                                         megaCfg->qCcnt++;
2107                                         continue;
2108                                 }
2109
2110                                 /* We don't want the ISR routine to touch M_RD_IOCTL_CMD_NEW commands, so
2111                                  * don't mark them as complete, instead we pop their semaphore so
2112                                  * that the queue routine can finish them off
2113                                  */
2114                                 if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
2115                                         /* save the status byte for the queue routine to use */
2116                                         pScb->SCpnt->result = qStatus;
2117                                         up (&pScb->ioctl_sem);
2118                                 } else {
2119                                         /* Mark command as completed */
2120                                         mega_cmd_done (megaCfg, pScb, qStatus);
2121                                 }
2122                         } else {
2123                                 printk
2124                                     ("megaraid: wrong cmd id completed from firmware:id=%x\n",
2125                                      sIdx);
2126                         }
2127                 }
2128
2129                 mega_rundoneq (megaCfg);
2130
2131                 megaCfg->flag &= ~IN_ISR;
2132                 /* Loop through any pending requests */
2133                 mega_runpendq (megaCfg);
2134                 IO_UNLOCK;
2135
2136         }
2137
2138 }
2139
2140 /*==================================================*/
2141 /* Wait until the controller's mailbox is available */
2142 /*==================================================*/
2143
2144 static int mega_busyWaitMbox (mega_host_config * megaCfg)
2145 {
2146         mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
2147         long counter;
2148
2149         for (counter = 0; counter < 10000; counter++) {
2150                 if (!mbox->busy) {
2151                         return 0;
2152                 }
2153                 udelay (100);
2154                 barrier ();
2155         }
2156         return -1;              /* give up after 1 second */
2157 }
2158
2159 /*=====================================================
2160  * Post a command to the card
2161  *
2162  * Arguments:
2163  *   mega_host_config *megaCfg - Controller structure
2164  *   u_char *mboxData - Mailbox area, 16 bytes
2165  *   mega_scb *pScb   - SCB posting (or NULL if N/A)
2166  *   int intr         - if 1, interrupt, 0 is blocking
2167  * Return Value: (added on 7/26 for 40ld/64bit)
2168  *   -1: the command was not actually issued out
2169  *   other cases:
2170  *     intr==0, return ScsiStatus, i.e. mbox->status
2171  *     intr==1, return 0
2172  *=====================================================
2173  */
2174 static int megaIssueCmd (mega_host_config * megaCfg, u_char * mboxData, 
2175                 mega_scb * pScb, int intr)
2176 {
2177         volatile mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
2178
2179 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2180         volatile mega_mailbox64 *mbox64 = (mega_mailbox64 *) megaCfg->mbox64;
2181 #endif
2182
2183         u_char byte;
2184
2185 #ifdef __LP64__
2186         u64 phys_mbox;
2187 #else
2188         u32 phys_mbox;
2189 #endif
2190         u8 retval = -1;
2191
2192         mboxData[0x1] = (pScb ? pScb->idx + 1 : 0xFE);  /* Set cmdid */
2193         mboxData[0xF] = 1;      /* Set busy */
2194
2195 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2196         /* In this case mbox contains physical address */
2197         phys_mbox = megaCfg->adjdmahandle64;
2198 #else
2199         phys_mbox = virt_to_bus (megaCfg->mbox);
2200 #endif
2201
2202 #if DEBUG
2203         ShowMbox (pScb);
2204 #endif
2205
2206         /* Wait until mailbox is free */
2207         if (mega_busyWaitMbox (megaCfg)) {
2208                 printk ("Blocked mailbox......!!\n");
2209                 udelay (1000);
2210
2211 #if DEBUG
2212                 showMbox (pLastScb);
2213 #endif
2214
2215                 /* Abort command */
2216                 if (pScb == NULL) {
2217                         TRACE (("NULL pScb in megaIssue\n"));
2218                         printk ("NULL pScb in megaIssue\n");
2219                 }
2220                 mega_cmd_done (megaCfg, pScb, 0x08);
2221                 return -1;
2222         }
2223
2224         pLastScb = pScb;
2225
2226         /* Copy mailbox data into host structure */
2227         megaCfg->mbox64->xferSegment_lo = 0;
2228         megaCfg->mbox64->xferSegment_hi = 0;
2229
2230         memcpy ((char *) mbox, mboxData, 16);
2231
2232 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2233         switch (mboxData[0]) {
2234         case MEGA_MBOXCMD_LREAD64:
2235         case MEGA_MBOXCMD_LWRITE64:
2236                 mbox64->xferSegment_lo = mbox->xferaddr;
2237                 mbox64->xferSegment_hi = 0;
2238                 mbox->xferaddr = 0xFFFFFFFF;
2239                 break;
2240         }
2241 #endif
2242
2243         /* Kick IO */
2244         if (intr) {
2245                 /* Issue interrupt (non-blocking) command */
2246                 if (megaCfg->flag & BOARD_QUARTZ) {
2247                         mbox->mraid_poll = 0;
2248                         mbox->mraid_ack = 0;
2249
2250                         WRINDOOR (megaCfg, phys_mbox | 0x1);
2251                 } else {
2252                         ENABLE_INTR (megaCfg->host->io_port);
2253                         ISSUE_COMMAND (megaCfg->host->io_port);
2254                 }
2255                 pScb->state = SCB_ISSUED;
2256
2257                 retval = 0;
2258         } else {                /* Issue non-ISR (blocking) command */
2259                 disable_irq (megaCfg->host->irq);
2260                 if (megaCfg->flag & BOARD_QUARTZ) {
2261                         mbox->mraid_poll = 0;
2262                         mbox->mraid_ack = 0;
2263                         mbox->numstatus = 0xFF;
2264                         mbox->status = 0xFF;
2265                         WRINDOOR (megaCfg, phys_mbox | 0x1);
2266
2267                         while (mbox->numstatus == 0xFF) ;
2268                         while (mbox->status == 0xFF) ;
2269                         while (mbox->mraid_poll != 0x77) ;
2270                         mbox->mraid_poll = 0;
2271                         mbox->mraid_ack = 0x77;
2272
2273                         /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
2274                            WROUTDOOR (megaCfg, cmdDone); */
2275
2276                         if (pScb) {
2277                                 mega_cmd_done (megaCfg, pScb, mbox->status);
2278                         }
2279
2280                         WRINDOOR (megaCfg, phys_mbox | 0x2);
2281                         while (RDINDOOR (megaCfg) & 0x2) ;
2282
2283                 } else {
2284                         DISABLE_INTR (megaCfg->host->io_port);
2285                         ISSUE_COMMAND (megaCfg->host->io_port);
2286
2287                         while (!
2288                                ((byte =
2289                                  READ_PORT (megaCfg->host->io_port,
2290                                             INTR_PORT)) & INTR_VALID)) ;
2291                         WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
2292
2293                         ENABLE_INTR (megaCfg->host->io_port);
2294                         CLEAR_INTR (megaCfg->host->io_port);
2295
2296                         if (pScb) {
2297                                 mega_cmd_done (megaCfg, pScb, mbox->status);
2298                         } else {
2299                                 TRACE (("Error: NULL pScb!\n"));
2300                         }
2301                 }
2302                 enable_irq (megaCfg->host->irq);
2303                 retval = mbox->status;
2304         }
2305 #if DEBUG
2306         while (mega_busyWaitMbox (megaCfg)) {
2307                 printk(KERN_ERR "Blocked mailbox on exit......!\n");
2308                 udelay (1000);
2309         }
2310 #endif
2311
2312         return retval;
2313 }
2314
2315 /*-------------------------------------------------------------------
2316  * Copies data to SGLIST
2317  *-------------------------------------------------------------------*/
2318 /* Note:
2319         For 64 bit cards, we need a minimum of one SG element for read/write
2320 */
2321
2322 static int
2323 mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
2324                    u32 * buffer, u32 * length)
2325 {
2326         struct scatterlist *sgList;
2327         int idx;
2328
2329 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2330         int sgcnt;
2331 #endif
2332
2333         mega_mailbox *mbox = NULL;
2334
2335         mbox = (mega_mailbox *) scb->mboxData;
2336         /* Scatter-gather not used */
2337         if (scb->SCpnt->use_sg == 0) {
2338
2339 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2340                 scb->dma_h_bulkdata = pci_map_single (megaCfg->dev,
2341                                       scb->SCpnt->request_buffer,
2342                                       scb->SCpnt->request_bufflen,
2343                                       scb->dma_direction);
2344                 /* We need to handle special commands like READ64, WRITE64
2345                    as they need a minimum of 1 SG irrespective of actually SG
2346                  */
2347                 if ((megaCfg->flag & BOARD_64BIT) &&
2348                     ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2349                      (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2350                         scb->sg64List[0].address = scb->dma_h_bulkdata;
2351                         scb->sg64List[0].length = scb->SCpnt->request_bufflen;
2352                         *buffer = scb->dma_sghandle64;
2353                         *length = 0;
2354                         scb->sglist_count = 1;
2355                         return 1;
2356                 } else {
2357                         *buffer = scb->dma_h_bulkdata;
2358                         *length = (u32) scb->SCpnt->request_bufflen;
2359                 }
2360 #else
2361                 *buffer = virt_to_bus (scb->SCpnt->request_buffer);
2362                 *length = (u32) scb->SCpnt->request_bufflen;
2363 #endif
2364                 return 0;
2365         }
2366
2367         sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
2368
2369         if (scb->SCpnt->use_sg == 1) {
2370
2371 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2372                 scb->dma_h_bulkdata = pci_map_single (megaCfg->dev,
2373                                       sgList[0].address,
2374                                       sgList[0].length, scb->dma_direction);
2375
2376                 if ((megaCfg->flag & BOARD_64BIT) &&
2377                     ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2378                      (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2379                         scb->sg64List[0].address = scb->dma_h_bulkdata;
2380                         scb->sg64List[0].length = scb->SCpnt->request_bufflen;
2381                         *buffer = scb->dma_sghandle64;
2382                         *length = 0;
2383                         scb->sglist_count = 1;
2384                         return 1;
2385                 } else {
2386                         *buffer = scb->dma_h_bulkdata;
2387                         *length = (u32) sgList[0].length;
2388                 }
2389 #else
2390                 *buffer = virt_to_bus (sgList[0].address);
2391                 *length = (u32) sgList[0].length;
2392 #endif
2393
2394                 return 0;
2395         }
2396
2397         /* Copy Scatter-Gather list info into controller structure */
2398 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2399         sgcnt = pci_map_sg (megaCfg->dev,
2400                             sgList, scb->SCpnt->use_sg, scb->dma_direction);
2401
2402         /* Determine the validity of the new count  */
2403         if (sgcnt == 0)
2404                 printk ("pci_map_sg returned zero!!! ");
2405
2406         for (idx = 0; idx < sgcnt; idx++, sgList++) {
2407
2408                 if ((megaCfg->flag & BOARD_64BIT) &&
2409                     ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2410                      (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2411                         scb->sg64List[idx].address = sg_dma_address (sgList);
2412                         scb->sg64List[idx].length = sg_dma_len (sgList);
2413                 } else {
2414                         scb->sgList[idx].address = sg_dma_address (sgList);
2415                         scb->sgList[idx].length = sg_dma_len (sgList);
2416                 }
2417
2418         }
2419
2420 #else
2421         for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
2422                 scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
2423                 scb->sgList[idx].length = (u32) sgList[idx].length;
2424         }
2425 #endif
2426
2427         /* Reset pointer and length fields */
2428 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2429         *buffer = scb->dma_sghandle64;
2430         scb->sglist_count = scb->SCpnt->use_sg;
2431 #else
2432         *buffer = virt_to_bus (scb->sgList);
2433 #endif
2434         *length = 0;
2435
2436 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2437         /* Return count of SG requests */
2438         return sgcnt;
2439 #else
2440         /* Return count of SG requests */
2441         return scb->SCpnt->use_sg;
2442 #endif
2443 }
2444
2445 /*--------------------------------------------------------------------
2446  * Initializes the address of the controller's mailbox register
2447  *  The mailbox register is used to issue commands to the card.
2448  *  Format of the mailbox area:
2449  *   00 01 command
2450  *   01 01 command id
2451  *   02 02 # of sectors
2452  *   04 04 logical bus address
2453  *   08 04 physical buffer address
2454  *   0C 01 logical drive #
2455  *   0D 01 length of scatter/gather list
2456  *   0E 01 reserved
2457  *   0F 01 mailbox busy
2458  *   10 01 numstatus byte
2459  *   11 01 status byte
2460  *--------------------------------------------------------------------*/
2461 static int
2462 mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
2463 {
2464         /* align on 16-byte boundary */
2465 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2466         megaCfg->mbox = &megaCfg->mailbox64ptr->mailbox;
2467 #else
2468         megaCfg->mbox = &megaCfg->mailbox64.mailbox;
2469 #endif
2470
2471 #ifdef __LP64__
2472         megaCfg->mbox = (mega_mailbox *) ((((u64) megaCfg->mbox) + 16) & ((u64) (-1) ^ 0x0F));
2473         megaCfg->adjdmahandle64 = (megaCfg->dma_handle64 + 16) & ((u64) (-1) ^ 0x0F);
2474         megaCfg->mbox64 = (mega_mailbox64 *) ((u_char *) megaCfg->mbox - sizeof (u64));
2475         paddr = (paddr + 4 + 16) & ((u64) (-1) ^ 0x0F);
2476 #else
2477         megaCfg->mbox
2478             = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xFFFFFFF0);
2479
2480 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2481         megaCfg->adjdmahandle64 = ((megaCfg->dma_handle64 + 16) & 0xFFFFFFF0);
2482 #endif
2483
2484         megaCfg->mbox64 = (mega_mailbox64 *) ((u_char *) megaCfg->mbox - 8);
2485         paddr = (paddr + 4 + 16) & 0xFFFFFFF0;
2486 #endif
2487
2488         /* Register mailbox area with the firmware */
2489         if (!(megaCfg->flag & BOARD_QUARTZ)) {
2490                 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
2491                 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1,
2492                             (paddr >> 8) & 0xFF);
2493                 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2,
2494                             (paddr >> 16) & 0xFF);
2495                 WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3,
2496                             (paddr >> 24) & 0xFF);
2497                 WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION,
2498                             ENABLE_MBOX_BYTE);
2499
2500                 CLEAR_INTR (megaCfg->host->io_port);
2501                 ENABLE_INTR (megaCfg->host->io_port);
2502         }
2503         return 0;
2504 }
2505
2506 /*---------------------------------------------------------------------------
2507  * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and
2508  * puts it into ProductInfo and Enquiry3 structures for later use
2509  *---------------------------------------------------------------------------*/
2510 static void mega_Convert8ldTo40ld (mega_RAIDINQ * inquiry,
2511                        mega_Enquiry3 * enquiry3,
2512                        megaRaidProductInfo * productInfo)
2513 {
2514         int i;
2515
2516         productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds;
2517         enquiry3->rbldRate = inquiry->AdpInfo.RbldRate;
2518         productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent;
2519
2520         for (i = 0; i < 4; i++) {
2521                 productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i];
2522                 productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i];
2523         }
2524         enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval;
2525         productInfo->DramSize = inquiry->AdpInfo.DramSize;
2526
2527         enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv;
2528
2529         for (i = 0; i < MAX_LOGICAL_DRIVES; i++) {
2530                 enquiry3->lDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i];
2531                 enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i];
2532                 enquiry3->lDrvState[i]
2533                     = inquiry->LogdrvInfo.LDrvState[i];
2534         }
2535
2536         for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++) {
2537                 enquiry3->pDrvState[i]
2538                     = inquiry->PhysdrvInfo.PDrvState[i];
2539         }
2540 }
2541
2542 /*-------------------------------------------------------------------
2543  * Issue an adapter info query to the controller
2544  *-------------------------------------------------------------------*/
2545 static int mega_i_query_adapter (mega_host_config * megaCfg)
2546 {
2547         mega_Enquiry3 *enquiry3Pnt;
2548         mega_mailbox *mbox;
2549         u_char mboxData[16];
2550
2551 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2552         dma_addr_t raid_inq_dma_handle = 0, prod_info_dma_handle = 0, enquiry3_dma_handle = 0;
2553 #endif
2554         u8 retval;
2555
2556         /* Initialize adapter inquiry mailbox */
2557
2558         mbox = (mega_mailbox *) mboxData;
2559
2560         memset ((void *) megaCfg->mega_buffer, 0,
2561                 sizeof (megaCfg->mega_buffer));
2562         memset (mbox, 0, 16);
2563
2564 /*
2565  * Try to issue Enquiry3 command
2566  * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
2567  * update enquiry3 structure
2568  */
2569 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2570         enquiry3_dma_handle = pci_map_single (megaCfg->dev,
2571                               (void *) megaCfg->mega_buffer,
2572                               (2 * 1024L), PCI_DMA_FROMDEVICE);
2573
2574         mbox->xferaddr = enquiry3_dma_handle;
2575 #else
2576         /*Taken care */
2577         mbox->xferaddr = virt_to_bus ((void *) megaCfg->mega_buffer);
2578 #endif
2579
2580         /* Initialize mailbox databuffer addr */
2581         enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer;
2582         /* point mega_Enguiry3 to the data buf */
2583
2584         mboxData[0] = FC_NEW_CONFIG;    /* i.e. mbox->cmd=0xA1 */
2585         mboxData[2] = NC_SUBOP_ENQUIRY3;        /* i.e. 0x0F */
2586         mboxData[3] = ENQ3_GET_SOLICITED_FULL;  /* i.e. 0x02 */
2587
2588         /* Issue a blocking command to the card */
2589         if ((retval = megaIssueCmd (megaCfg, mboxData, NULL, 0)) != 0) {        /* the adapter does not support 40ld */
2590                 mega_RAIDINQ adapterInquiryData;
2591                 mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData;
2592
2593 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2594                 raid_inq_dma_handle = pci_map_single (megaCfg->dev,
2595                                       (void *) adapterInquiryPnt,
2596                                       sizeof (mega_RAIDINQ),
2597                                       PCI_DMA_FROMDEVICE);
2598                 mbox->xferaddr = raid_inq_dma_handle;
2599 #else
2600                 /*taken care */
2601                 mbox->xferaddr = virt_to_bus ((void *) adapterInquiryPnt);
2602 #endif
2603
2604                 mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;    /*issue old 0x05 command to adapter */
2605                 /* Issue a blocking command to the card */ ;
2606                 retval = megaIssueCmd (megaCfg, mboxData, NULL, 0);
2607
2608                 pci_unmap_single (megaCfg->dev,
2609                                   raid_inq_dma_handle,
2610                                   sizeof (mega_RAIDINQ), PCI_DMA_FROMDEVICE);
2611
2612                 /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/
2613                 mega_Convert8ldTo40ld (adapterInquiryPnt,
2614                                        enquiry3Pnt,
2615                                        (megaRaidProductInfo *) & megaCfg->
2616                                        productInfo);
2617
2618         } else {                /* adapter supports 40ld */
2619                 megaCfg->flag |= BOARD_40LD;
2620
2621                 pci_unmap_single (megaCfg->dev,
2622                                   enquiry3_dma_handle,
2623                                   (2 * 1024L), PCI_DMA_FROMDEVICE);
2624 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2625 /*get productInfo, which is static information and will be unchanged*/
2626                 prod_info_dma_handle
2627                     = pci_map_single (megaCfg->dev,
2628                                       (void *) &megaCfg->productInfo,
2629                                       sizeof (megaRaidProductInfo),
2630                                       PCI_DMA_FROMDEVICE);
2631                 mbox->xferaddr = prod_info_dma_handle;
2632 #else
2633                 /*taken care */
2634                 mbox->xferaddr = virt_to_bus ((void *) &megaCfg->productInfo);
2635 #endif
2636
2637                 mboxData[0] = FC_NEW_CONFIG;    /* i.e. mbox->cmd=0xA1 */
2638                 mboxData[2] = NC_SUBOP_PRODUCT_INFO;    /* i.e. 0x0E */
2639
2640                 if ((retval = megaIssueCmd (megaCfg, mboxData, NULL, 0)) != 0)
2641                         printk ("ami:Product_info cmd failed with error: %d\n",
2642                                 retval);
2643
2644                 pci_unmap_single (megaCfg->dev,
2645                                   prod_info_dma_handle,
2646                                   sizeof (megaRaidProductInfo),
2647                                   PCI_DMA_FROMDEVICE);
2648         }
2649
2650         megaCfg->host->max_channel = megaCfg->productInfo.SCSIChanPresent;
2651         megaCfg->host->max_id = 16;     /* max targets per channel */
2652         /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1; */
2653         megaCfg->host->max_lun =        /* max lun */
2654             (megaCfg->
2655              flag & BOARD_40LD) ? FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
2656         megaCfg->host->cmd_per_lun = MAX_CMD_PER_LUN;
2657
2658         megaCfg->numldrv = enquiry3Pnt->numLDrv;
2659         megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
2660         if (megaCfg->max_cmds > MAX_COMMANDS)
2661                 megaCfg->max_cmds = MAX_COMMANDS - 1;
2662
2663         megaCfg->host->can_queue = megaCfg->max_cmds - 1;
2664
2665 #if 0
2666         if (megaCfg->host->can_queue >= MAX_COMMANDS) {
2667                 megaCfg->host->can_queue = MAX_COMMANDS - 16;
2668         }
2669 #endif
2670
2671  /* use HP firmware and bios version encoding */
2672 if (megaCfg->productInfo.subSystemVendorID == HP_SUBSYS_ID) {
2673         sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
2674                  megaCfg->productInfo.FwVer[2],
2675                  megaCfg->productInfo.FwVer[1] >> 8,
2676                  megaCfg->productInfo.FwVer[1] & 0x0f,
2677                  megaCfg->productInfo.FwVer[2] >> 8,
2678                  megaCfg->productInfo.FwVer[2] & 0x0f);
2679         sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
2680                  megaCfg->productInfo.BiosVer[2],
2681                  megaCfg->productInfo.BiosVer[1] >> 8,
2682                  megaCfg->productInfo.BiosVer[1] & 0x0f,
2683                  megaCfg->productInfo.BiosVer[2] >> 8,
2684                  megaCfg->productInfo.BiosVer[2] & 0x0f);
2685 } else {
2686         memcpy (megaCfg->fwVer, (char *) megaCfg->productInfo.FwVer, 4);
2687         megaCfg->fwVer[4] = 0;
2688
2689         memcpy (megaCfg->biosVer, (char *) megaCfg->productInfo.BiosVer, 4);
2690         megaCfg->biosVer[4] = 0;
2691 }
2692         megaCfg->support_ext_cdb = mega_support_ext_cdb(megaCfg);
2693
2694         printk (KERN_NOTICE "megaraid: [%s:%s] detected %d logical drives" M_RD_CRLFSTR,
2695                 megaCfg->fwVer, megaCfg->biosVer, megaCfg->numldrv);
2696