File: /usr/src/linux/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     
2697     	if ( megaCfg->support_ext_cdb ) {
2698     		printk(KERN_NOTICE "megaraid: supports extended CDBs.\n");
2699     	}
2700     
2701     	/*
2702     	 * I hope that I can unmap here, reason DMA transaction is not required any more
2703     	 * after this
2704     	 */
2705     
2706     	return 0;
2707     }
2708     
2709     /*-------------------------------------------------------------------------
2710      *
2711      *                      Driver interface functions
2712      *
2713      *-------------------------------------------------------------------------*/
2714     
2715     /*----------------------------------------------------------
2716      * Returns data to be displayed in /proc/scsi/megaraid/X
2717      *----------------------------------------------------------*/
2718     
2719     int megaraid_proc_info (char *buffer, char **start, off_t offset,
2720     		    int length, int host_no, int inout)
2721     {
2722     	*start = buffer;
2723     	return 0;
2724     }
2725     
2726     static int mega_findCard (Scsi_Host_Template * pHostTmpl,
2727     	       u16 pciVendor, u16 pciDev, long flag)
2728     {
2729     	mega_host_config *megaCfg = NULL;
2730     	struct Scsi_Host *host = NULL;
2731     	u_char pciBus, pciDevFun, megaIrq;
2732     
2733     	u16 magic;
2734     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2735     	u32 magic64;
2736     #endif
2737     
2738     	int i;
2739     
2740     #ifdef __LP64__
2741     	u64 megaBase;
2742     #else
2743     	u32 megaBase;
2744     #endif
2745     
2746     	u16 pciIdx = 0;
2747     	u16 numFound = 0;
2748     	u16 subsysid, subsysvid;
2749     
2750     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)	/* 0x20100 */
2751     	while (!pcibios_find_device
2752     	       (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
2753     #else
2754     
2755     #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)	/*0x20300 */
2756     	struct pci_dev *pdev = NULL;
2757     #else
2758     	struct pci_dev *pdev = pci_devices;
2759     #endif
2760     
2761     	while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
2762     		if(pci_enable_device (pdev))
2763     			continue;
2764     		pciBus = pdev->bus->number;
2765     		pciDevFun = pdev->devfn;
2766     #endif
2767     		if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
2768     			pcibios_read_config_word (pciBus, pciDevFun,
2769     						  PCI_CONF_AMISIG, &magic);
2770     			if ((magic != AMI_SIGNATURE)
2771     			    && (magic != AMI_SIGNATURE_471)) {
2772     				pciIdx++;
2773     				continue;	/* not an AMI board */
2774     			}
2775     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2776     			pcibios_read_config_dword (pciBus, pciDevFun,
2777     						   PCI_CONF_AMISIG64, &magic64);
2778     
2779     			if (magic64 == AMI_64BIT_SIGNATURE)
2780     				flag |= BOARD_64BIT;
2781     #endif
2782     		}
2783     
2784     		/* Hmmm...Should we not make this more modularized so that in future we dont add
2785     		   for each firmware */
2786     
2787     		if (flag & BOARD_QUARTZ) {
2788     			/* Check to see if this is a Dell PERC RAID controller model 466 */
2789     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)	/* 0x20100 */
2790     			pcibios_read_config_word (pciBus, pciDevFun,
2791     						  PCI_SUBSYSTEM_VENDOR_ID,
2792     						  &subsysvid);
2793     			pcibios_read_config_word (pciBus, pciDevFun,
2794     						  PCI_SUBSYSTEM_ID, &subsysid);
2795     #else
2796     			pci_read_config_word (pdev,
2797     					      PCI_SUBSYSTEM_VENDOR_ID,
2798     					      &subsysvid);
2799     			pci_read_config_word (pdev,
2800     					      PCI_SUBSYSTEM_ID, &subsysid);
2801     #endif
2802     
2803     #if 0
2804     			/*
2805     			 * This routine is called with well know values and we
2806     			 * should not be getting what we have not asked.
2807     			 * Also, the check is not right. It should have been for
2808     			 * pci_vendor_id not subsysvid - AM
2809     			 */
2810     
2811     			/* If we dont detect this valid subsystem vendor id's 
2812     			   we refuse to load the driver 
2813     			   PART of PC200X compliance
2814     			 */
2815     
2816     			if ((subsysvid != AMI_SUBSYS_ID)
2817     			    && (subsysvid != DELL_SUBSYS_ID)
2818     			    && (subsysvid != HP_SUBSYS_ID))
2819     				continue;
2820     #endif
2821     		}
2822     
2823     		printk (KERN_NOTICE
2824     			"megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
2825     			pciVendor, pciDev, pciIdx, pciBus, PCI_SLOT (pciDevFun),
2826     			PCI_FUNC (pciDevFun));
2827     		/* Read the base port and IRQ from PCI */
2828     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)	/* 0x20100 */
2829     		pcibios_read_config_dword (pciBus, pciDevFun,
2830     					   PCI_BASE_ADDRESS_0,
2831     					   (u_int *) & megaBase);
2832     		pcibios_read_config_byte (pciBus, pciDevFun,
2833     					  PCI_INTERRUPT_LINE, &megaIrq);
2834     #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)	/*0x20300 */
2835     		megaBase = pdev->base_address[0];
2836     		megaIrq = pdev->irq;
2837     #else
2838     
2839     		megaBase = pci_resource_start (pdev, 0);
2840     		megaIrq = pdev->irq;
2841     #endif
2842     
2843     		pciIdx++;
2844     
2845     		if (flag & BOARD_QUARTZ) {
2846     			megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
2847     			megaBase = (long) ioremap (megaBase, 128);
2848     			if (!megaBase)
2849     				continue;
2850     		} else {
2851     			megaBase &= PCI_BASE_ADDRESS_IO_MASK;
2852     			megaBase += 0x10;
2853     		}
2854     
2855     		/* Initialize SCSI Host structure */
2856     		host = scsi_register (pHostTmpl, sizeof (mega_host_config));
2857     		if (!host)
2858     			goto err_unmap;
2859     
2860     #if 0
2861     		/*
2862     		 * Comment the following initialization if you know 'max_sectors' is
2863     		 * not defined for this kernel.
2864     		 * This field was introduced in Linus's kernel 2.4.7pre3 and it
2865     		 * greatly increases the IO performance - AM
2866     		 */
2867     		host->max_sectors = 1024;
2868     #endif
2869     
2870     		scsi_set_pci_device(host, pdev);
2871     		megaCfg = (mega_host_config *) host->hostdata;
2872     		memset (megaCfg, 0, sizeof (mega_host_config));
2873     
2874     		printk (KERN_NOTICE "scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d"
2875     			M_RD_CRLFSTR, host->host_no, (u_int) megaBase, megaIrq);
2876     
2877     		if (flag & BOARD_64BIT)
2878     			printk (KERN_NOTICE "scsi%d : Enabling 64 bit support\n",
2879     				host->host_no);
2880     
2881     		/* Copy resource info into structure */
2882     		megaCfg->qCompletedH = NULL;
2883     		megaCfg->qCompletedT = NULL;
2884     		megaCfg->qPendingH = NULL;
2885     		megaCfg->qPendingT = NULL;
2886     		megaCfg->qFreeH = NULL;
2887     		megaCfg->qFreeT = NULL;
2888     		megaCfg->qFcnt = 0;
2889     		megaCfg->qPcnt = 0;
2890     		megaCfg->qCcnt = 0;
2891     		megaCfg->lock_free = SPIN_LOCK_UNLOCKED;
2892     		megaCfg->lock_pend = SPIN_LOCK_UNLOCKED;
2893     		megaCfg->lock_scsicmd = SPIN_LOCK_UNLOCKED;
2894     		megaCfg->flag = flag;
2895     
2896     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2897     		megaCfg->dev = pdev;
2898     #endif
2899     		megaCfg->host = host;
2900     		megaCfg->base = megaBase;
2901     		megaCfg->host->irq = megaIrq;
2902     		megaCfg->host->io_port = megaBase;
2903     		megaCfg->host->n_io_port = 16;
2904     		megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
2905     		megaCtlrs[numCtlrs] = megaCfg;
2906     
2907     		if (!(flag & BOARD_QUARTZ)) {
2908     			/* Request our IO Range */
2909     			if (check_region (megaBase, 16)) {
2910     				printk(KERN_WARNING "megaraid: Couldn't register I/O range!\n");
2911     				goto err_unregister;
2912     			}
2913     			request_region(megaBase, 16, "megaraid");
2914     		}
2915     
2916     		/* Request our IRQ */
2917     		if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
2918     				 "megaraid", megaCfg)) {
2919     			printk (KERN_WARNING
2920     				"megaraid: Couldn't register IRQ %d!\n",
2921     				megaIrq);
2922     			goto err_release;
2923     		}
2924     
2925     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2926     		/*
2927     		 * unmap while releasing the driver, Is it required to be 
2928     		 * PCI_DMA_BIDIRECTIONAL 
2929     		*/
2930     
2931     		megaCfg->mailbox64ptr
2932     		    = pci_alloc_consistent (megaCfg->dev,
2933     					    sizeof (mega_mailbox64),
2934     					    &(megaCfg->dma_handle64));
2935     
2936     		mega_register_mailbox (megaCfg,
2937     				       virt_to_bus ((void *) megaCfg->
2938     						    mailbox64ptr));
2939     #else
2940     		mega_register_mailbox (megaCfg,
2941     				       virt_to_bus ((void *) &megaCfg->
2942     						    mailbox64));
2943     #endif
2944     
2945     		mega_i_query_adapter (megaCfg);
2946     
2947     		if ((subsysid == 0x1111) && (subsysvid == 0x1111)) {
2948     
2949     			/*
2950     			 * Which firmware
2951     			 */
2952     			if( strcmp(megaCfg->fwVer, "3.00") == 0 ||
2953     					strcmp(megaCfg->fwVer, "3.01") == 0 ) {
2954     
2955     				printk( KERN_WARNING
2956     					"megaraid: Your  card is a Dell PERC 2/SC RAID controller "
2957     					"with  firmware\nmegaraid: 3.00 or 3.01.  This driver is "
2958     					"known to have corruption issues\nmegaraid: with those "
2959     					"firmware versions on this specific card.  In order\n"
2960     					"megaraid: to protect your data, please upgrade your "
2961     					"firmware to version\nmegaraid: 3.10 or later, available "
2962     					"from the Dell Technical Support web\nmegaraid: site at\n"
2963     					"http://support.dell.com/us/en/filelib/download/"
2964     					"index.asp?fileid=2940\n"
2965     				);
2966     			}
2967     		}
2968     
2969     		/*
2970     		 * If we have a HP 1M(0x60E7)/2M(0x60E8) controller with
2971     		 * firmware H.01.07 or H.01.08, disable 64 bit support,
2972     		 * since this firmware cannot handle 64 bit addressing
2973     		 */
2974     
2975     		if( (subsysvid == HP_SUBSYS_ID) &&
2976     				((subsysid == 0x60E7)||(subsysid == 0x60E8)) ) {
2977     
2978     			/*
2979     			 * which firmware
2980     			 */
2981     			if( strcmp(megaCfg->fwVer, "H01.07") == 0 ||
2982     					strcmp(megaCfg->fwVer, "H01.08") == 0 ) {
2983     				printk(KERN_WARNING
2984     						"megaraid: Firmware H.01.07 or H.01.08 on 1M/2M "
2985     						"controllers\nmegaraid: do not support 64 bit "
2986     						"addressing.\n"
2987     						"megaraid: DISABLING 64 bit support.\n");
2988     				megaCfg->flag &= ~BOARD_64BIT;
2989     			}
2990     		}
2991     
2992     		if (mega_is_bios_enabled (megaCfg)) {
2993     			mega_hbas[numCtlrs].is_bios_enabled = 1;
2994     		}
2995     
2996     		/*
2997     		 * Find out which channel is raid and which is scsi
2998     		 */
2999     		mega_enum_raid_scsi(megaCfg);
3000     		for( i = 0; i < megaCfg->host->max_channel; i++ ) {
3001     			if(IS_RAID_CH(i))
3002     				printk(KERN_NOTICE"megaraid: channel[%d] is raid.\n", i+1);
3003     			else
3004     				printk(KERN_NOTICE"megaraid: channel[%d] is scsi.\n", i+1);
3005     		}
3006     
3007     		/*
3008     		 * Find out if a logical drive is set as the boot drive. If there is
3009     		 * one, will make that as the first logical drive.
3010     		 */
3011     		mega_get_boot_ldrv(megaCfg);
3012     
3013     		mega_hbas[numCtlrs].hostdata_addr = megaCfg;
3014     
3015     		/* Initialize SCBs */
3016     		if (mega_init_scb (megaCfg)) {
3017     			pci_free_consistent (megaCfg->dev,
3018     					     sizeof (mega_mailbox64),
3019     					     (void *) megaCfg->mailbox64ptr,
3020     					     megaCfg->dma_handle64);
3021     			scsi_unregister (host);
3022     			continue;
3023     		}
3024     
3025     		/*
3026     		 * Fill in the structure which needs to be passed back to the
3027     		 * application when it does an ioctl() for controller related
3028     		 * information.
3029     		 */
3030     
3031     		i = numCtlrs;
3032     		numCtlrs++;
3033     
3034     		mcontroller[i].base = megaBase;
3035     		mcontroller[i].irq = megaIrq;
3036     		mcontroller[i].numldrv = megaCfg->numldrv;
3037     		mcontroller[i].pcibus = pciBus;
3038     		mcontroller[i].pcidev = pciDev;
3039     		mcontroller[i].pcifun = PCI_FUNC (pciDevFun);
3040     		mcontroller[i].pciid = pciIdx;
3041     		mcontroller[i].pcivendor = pciVendor;
3042     		mcontroller[i].pcislot = PCI_SLOT (pciDevFun);
3043     		mcontroller[i].uid = (pciBus << 8) | pciDevFun;
3044     
3045     		numFound++;
3046     
3047     		/* Set the Mode of addressing to 64 bit */
3048     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3049     		if ((megaCfg->flag & BOARD_64BIT) && BITS_PER_LONG == 64)
3050     #ifdef __LP64__
3051     			pdev->dma_mask = 0xffffffffffffffff;
3052     #else
3053     			pdev->dma_mask = 0xffffffff;
3054     #endif
3055     #endif
3056     		continue;
3057     	      err_release:
3058     		if (flag & BOARD_QUARTZ)
3059     			release_region (megaBase, 16);
3060     	      err_unregister:
3061     		scsi_unregister (host);
3062     	      err_unmap:
3063     		if (flag & BOARD_QUARTZ)
3064     			iounmap ((void *) megaBase);
3065     	}
3066     	return numFound;
3067     }
3068     
3069     /*---------------------------------------------------------
3070      * Detects if a megaraid controller exists in this system
3071      *---------------------------------------------------------*/
3072     
3073     int megaraid_detect (Scsi_Host_Template * pHostTmpl)
3074     {
3075     	int ctlridx = 0, count = 0;
3076     
3077     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)	/*0x20300 */
3078     	pHostTmpl->proc_dir = &proc_scsi_megaraid;
3079     #else
3080     	pHostTmpl->proc_name = "megaraid";
3081     #endif
3082     
3083     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)	/* 0x20100 */
3084     	if (!pcibios_present ()) {
3085     		printk (KERN_WARNING "megaraid: PCI bios not present."
3086     			M_RD_CRLFSTR);
3087     		return 0;
3088     	}
3089     #endif
3090     	skip_id = -1;
3091     	if (megaraid && !strncmp (megaraid, "skip", strlen ("skip"))) {
3092     		if (megaraid[4] != '\0') {
3093     			skip_id = megaraid[4] - '0';
3094     			if (megaraid[5] != '\0') {
3095     				skip_id = (skip_id * 10) + (megaraid[5] - '0');
3096     			}
3097     		}
3098     		skip_id = (skip_id > 15) ? -1 : skip_id;
3099     	}
3100     
3101     	printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION M_RD_CRLFSTR);
3102     
3103     	memset (mega_hbas, 0, sizeof (mega_hbas));
3104     
3105     	count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3106     				PCI_DEVICE_ID_AMI_MEGARAID, 0);
3107     	count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3108     				PCI_DEVICE_ID_AMI_MEGARAID2, 0);
3109     	count += mega_findCard (pHostTmpl, 0x8086,
3110     				PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
3111     	count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3112     				PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
3113     
3114     	mega_reorder_hosts ();
3115     
3116     #ifdef CONFIG_PROC_FS
3117     	if (count) {
3118     #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)	/*0x20300 */
3119     		mega_proc_dir_entry = proc_mkdir ("megaraid", &proc_root);
3120     #else
3121     		mega_proc_dir_entry = create_proc_entry ("megaraid",
3122     							 S_IFDIR | S_IRUGO |
3123     							 S_IXUGO, &proc_root);
3124     #endif
3125     		if (!mega_proc_dir_entry)
3126     			printk ("megaraid: failed to create megaraid root\n");
3127     		else
3128     			for (ctlridx = 0; ctlridx < count; ctlridx++)
3129     				mega_create_proc_entry (ctlridx,
3130     							mega_proc_dir_entry);
3131     	}
3132     #endif
3133     
3134     	/*
3135     	 * Register the driver as a character device, for applications to access
3136     	 * it for ioctls.
3137     	 * Ideally, this should go in the init_module() routine, but since it is
3138     	 * hidden in the file "scsi_module.c" ( included in the end ), we define
3139     	 * it here
3140     	 * First argument (major) to register_chrdev implies a dynamic major
3141     	 * number allocation.
3142     	 */
3143     	if (count) {
3144     		major = register_chrdev (0, "megadev", &megadev_fops);
3145     
3146     		/*
3147     		 * Register the Shutdown Notification hook in kernel
3148     		 */
3149     		if (register_reboot_notifier (&mega_notifier)) {
3150     			printk ("MegaRAID Shutdown routine not registered!!\n");
3151     		}
3152     
3153     		init_MUTEX (&mimd_entry_mtx);
3154     	}
3155     
3156     	return count;
3157     }
3158     
3159     /*---------------------------------------------------------------------
3160      * Release the controller's resources
3161      *---------------------------------------------------------------------*/
3162     int megaraid_release (struct Scsi_Host *pSHost)
3163     {
3164     	mega_host_config *megaCfg;
3165     	mega_mailbox *mbox;
3166     	u_char mboxData[16];
3167     	int i;
3168     
3169     	megaCfg = (mega_host_config *) pSHost->hostdata;
3170     	mbox = (mega_mailbox *) mboxData;
3171     
3172     	/* Flush cache to disk */
3173     	memset (mbox, 0, 16);
3174     	mboxData[0] = 0xA;
3175     
3176     	free_irq (megaCfg->host->irq, megaCfg);	/* Must be freed first, otherwise
3177     						   extra interrupt is generated */
3178     
3179     	/* Issue a blocking (interrupts disabled) command to the card */
3180     	megaIssueCmd (megaCfg, mboxData, NULL, 0);
3181     
3182     	/* Free our resources */
3183     	if (megaCfg->flag & BOARD_QUARTZ) {
3184     		iounmap ((void *) megaCfg->base);
3185     	} else {
3186     		release_region (megaCfg->host->io_port, 16);
3187     	}
3188     
3189     	mega_freeSgList (megaCfg);
3190     	pci_free_consistent (megaCfg->dev,
3191     			     sizeof (mega_mailbox64),
3192     			     (void *) megaCfg->mailbox64ptr,
3193     			     megaCfg->dma_handle64);
3194     
3195     #ifdef CONFIG_PROC_FS
3196     	if (megaCfg->controller_proc_dir_entry) {
3197     		remove_proc_entry ("stat", megaCfg->controller_proc_dir_entry);
3198     		remove_proc_entry ("status",
3199     				   megaCfg->controller_proc_dir_entry);
3200     		remove_proc_entry ("config",
3201     				   megaCfg->controller_proc_dir_entry);
3202     		remove_proc_entry ("mailbox",
3203     				   megaCfg->controller_proc_dir_entry);
3204     		for (i = 0; i < numCtlrs; i++) {
3205     			char buf[12] = { 0 };
3206     			sprintf (buf, "%d", i);
3207     			remove_proc_entry (buf, mega_proc_dir_entry);
3208     		}
3209     		remove_proc_entry ("megaraid", &proc_root);
3210     	}
3211     #endif
3212     
3213     	/*
3214     	 *	Release the controller memory. A word of warning this frees
3215     	 *	hostdata and that includes megaCfg-> so be careful what you
3216     	 *	dereference beyond this point
3217     	 */
3218     	 
3219     	scsi_unregister (pSHost);
3220     
3221     	/*
3222     	 * Unregister the character device interface to the driver. Ideally this
3223     	 * should have been done in cleanup_module routine. Since this is hidden
3224     	 * in file "scsi_module.c", we do it here.
3225     	 * major is the major number of the character device returned by call to
3226     	 * register_chrdev() routine.
3227     	 */
3228     
3229     	unregister_chrdev (major, "megadev");
3230     	unregister_reboot_notifier (&mega_notifier);
3231     
3232     	return 0;
3233     }
3234     
3235     static int mega_is_bios_enabled (mega_host_config * megacfg)
3236     {
3237     	mega_mailbox *mboxpnt;
3238     	unsigned char mbox[16];
3239     	int ret;
3240     
3241     	mboxpnt = (mega_mailbox *) mbox;
3242     
3243     	memset (mbox, 0, sizeof (mbox));
3244     	memset ((void *) megacfg->mega_buffer,
3245     		0, sizeof (megacfg->mega_buffer));
3246     
3247     	/*
3248     	 * issue command to find out if the BIOS is enabled for this controller
3249     	 */
3250     	mbox[0] = IS_BIOS_ENABLED;
3251     	mbox[2] = GET_BIOS;
3252     
3253     	mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer);
3254     
3255     	ret = megaIssueCmd (megacfg, mbox, NULL, 0);
3256     
3257     	return (*(char *) megacfg->mega_buffer);
3258     }
3259     
3260     /*
3261      * Find out what channels are RAID/SCSI
3262      */
3263     void
3264     mega_enum_raid_scsi(mega_host_config *megacfg)
3265     {
3266     	mega_mailbox *mboxp;
3267     	unsigned char mbox[16];
3268     
3269     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3270     	dma_addr_t	dma_handle;
3271     #endif
3272     
3273     	mboxp = (mega_mailbox *)mbox;
3274     
3275     	memset(mbox, 0, sizeof(mbox));
3276     	/*
3277     	 * issue command to find out what channels are raid/scsi
3278     	 */
3279     	mbox[0] = CHNL_CLASS;
3280     	mbox[2] = GET_CHNL_CLASS;
3281     
3282     	memset((void *)megacfg->mega_buffer, 0, sizeof(megacfg->mega_buffer));
3283     
3284     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3285     	dma_handle = pci_map_single(megacfg->dev, (void *)megacfg->mega_buffer,
3286     			      (2 * 1024L), PCI_DMA_FROMDEVICE);
3287     
3288     	mboxp->xferaddr = dma_handle;
3289     #else
3290     	mboxp->xferaddr = virt_to_bus((void *)megacfg->mega_buffer);
3291     #endif
3292     
3293     	/*
3294     	 * Non-ROMB firware fail this command, so all channels
3295     	 * must be shown RAID
3296     	 */
3297     	if( megaIssueCmd(megacfg, mbox, NULL, 0) == 0 ) {
3298     		mega_ch_class = *((char *)megacfg->mega_buffer);
3299     
3300     		/* logical drives channel is RAID */
3301     		mega_ch_class |= (0x01 << megacfg->host->max_channel);
3302     	}
3303     	else {
3304     		mega_ch_class = 0xFF;
3305     	}
3306     
3307     
3308     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3309     	pci_unmap_single(megacfg->dev, dma_handle,
3310     				  (2 * 1024L), PCI_DMA_FROMDEVICE);
3311     #endif
3312     
3313     }
3314     
3315     
3316     /*
3317      * get the boot logical drive number if enabled
3318      */
3319     void
3320     mega_get_boot_ldrv(mega_host_config *megacfg)
3321     {
3322     	mega_mailbox *mboxp;
3323     	unsigned char mbox[16];
3324     	struct private_bios_data *prv_bios_data;
3325     	u16		cksum = 0;
3326     	char	*cksum_p;
3327     	int		i;
3328     
3329     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3330     	dma_addr_t	dma_handle;
3331     #endif
3332     
3333     	mboxp = (mega_mailbox *)mbox;
3334     
3335     	memset(mbox, 0, sizeof(mbox));
3336     
3337     	mbox[0] = BIOS_PVT_DATA;
3338     	mbox[2] = GET_BIOS_PVT_DATA;
3339     
3340     	memset((void *)megacfg->mega_buffer, 0, sizeof(megacfg->mega_buffer));
3341     
3342     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3343     	dma_handle = pci_map_single(megacfg->dev, (void *)megacfg->mega_buffer,
3344     			      (2 * 1024L), PCI_DMA_FROMDEVICE);
3345     
3346     	mboxp->xferaddr = dma_handle;
3347     #else
3348     	mboxp->xferaddr = virt_to_bus((void *)megacfg->mega_buffer);
3349     #endif
3350     
3351     	megacfg->boot_ldrv_enabled = 0;
3352     	megacfg->boot_ldrv = 0;
3353     	if( megaIssueCmd(megacfg, mbox, NULL, 0) == 0 ) {
3354     
3355     		prv_bios_data = (struct private_bios_data *)megacfg->mega_buffer;
3356     
3357     		cksum = 0;
3358     		cksum_p = (char *)prv_bios_data;
3359     		for( i = 0; i < 14; i++ ) {
3360     			cksum += (u16)(*cksum_p++);
3361     		}
3362     
3363     		if( prv_bios_data->cksum == (u16)(0-cksum) ) {
3364     			megacfg->boot_ldrv_enabled = 1;
3365     			megacfg->boot_ldrv = prv_bios_data->boot_ldrv;
3366     		}
3367     	}
3368     
3369     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3370     	pci_unmap_single(megacfg->dev, dma_handle,
3371     				  (2 * 1024L), PCI_DMA_FROMDEVICE);
3372     #endif
3373     
3374     }
3375     
3376     
3377     static void mega_reorder_hosts (void)
3378     {
3379     	struct Scsi_Host *shpnt;
3380     	struct Scsi_Host *shone;
3381     	struct Scsi_Host *shtwo;
3382     	mega_host_config *boot_host;
3383     	int i;
3384     
3385     	/*
3386     	 * Find the (first) host which has it's BIOS enabled
3387     	 */
3388     	boot_host = NULL;
3389     	for (i = 0; i < MAX_CONTROLLERS; i++) {
3390     		if (mega_hbas[i].is_bios_enabled) {
3391     			boot_host = mega_hbas[i].hostdata_addr;
3392     			break;
3393     		}
3394     	}
3395     
3396     	if (boot_host == NULL) {
3397     		printk (KERN_WARNING "megaraid: no BIOS enabled.\n");
3398     		return;
3399     	}
3400     
3401     	/*
3402     	 * Traverse through the list of SCSI hosts for our HBA locations
3403     	 */
3404     	shone = shtwo = NULL;
3405     	for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
3406     		/* Is it one of ours? */
3407     		for (i = 0; i < MAX_CONTROLLERS; i++) {
3408     			if ((mega_host_config *) shpnt->hostdata ==
3409     			    mega_hbas[i].hostdata_addr) {
3410     				/* Does this one has BIOS enabled */
3411     				if (mega_hbas[i].hostdata_addr == boot_host) {
3412     
3413     					/* Are we first */
3414     					if (shtwo == NULL)	/* Yes! */
3415     						return;
3416     					else {	/* :-( */
3417     						shone = shpnt;
3418     					}
3419     				} else {
3420     					if (!shtwo) {
3421     						/* were we here before? xchng first */
3422     						shtwo = shpnt;
3423     					}
3424     				}
3425     				break;
3426     			}
3427     		}
3428     		/*
3429     		 * Have we got the boot host and one which does not have the bios
3430     		 * enabled.
3431     		 */
3432     		if (shone && shtwo)
3433     			break;
3434     	}
3435     	if (shone && shtwo) {
3436     		mega_swap_hosts (shone, shtwo);
3437     	}
3438     
3439     	return;
3440     }
3441     
3442     static void mega_swap_hosts (struct Scsi_Host *shone, struct Scsi_Host *shtwo)
3443     {
3444     	struct Scsi_Host *prevtoshtwo;
3445     	struct Scsi_Host *prevtoshone;
3446     	struct Scsi_Host *save = NULL;;
3447     
3448     	/* Are these two nodes adjacent */
3449     	if (shtwo->next == shone) {
3450     
3451     		if (shtwo == scsi_hostlist && shone->next == NULL) {
3452     
3453     			/* just two nodes */
3454     			scsi_hostlist = shone;
3455     			shone->next = shtwo;
3456     			shtwo->next = NULL;
3457     		} else if (shtwo == scsi_hostlist) {
3458     			/* first two nodes of the list */
3459     
3460     			scsi_hostlist = shone;
3461     			shtwo->next = shone->next;
3462     			scsi_hostlist->next = shtwo;
3463     		} else if (shone->next == NULL) {
3464     			/* last two nodes of the list */
3465     
3466     			prevtoshtwo = scsi_hostlist;
3467     
3468     			while (prevtoshtwo->next != shtwo)
3469     				prevtoshtwo = prevtoshtwo->next;
3470     
3471     			prevtoshtwo->next = shone;
3472     			shone->next = shtwo;
3473     			shtwo->next = NULL;
3474     		} else {
3475     			prevtoshtwo = scsi_hostlist;
3476     
3477     			while (prevtoshtwo->next != shtwo)
3478     				prevtoshtwo = prevtoshtwo->next;
3479     
3480     			prevtoshtwo->next = shone;
3481     			shtwo->next = shone->next;
3482     			shone->next = shtwo;
3483     		}
3484     
3485     	} else if (shtwo == scsi_hostlist && shone->next == NULL) {
3486     		/* shtwo at head, shone at tail, not adjacent */
3487     
3488     		prevtoshone = scsi_hostlist;
3489     
3490     		while (prevtoshone->next != shone)
3491     			prevtoshone = prevtoshone->next;
3492     
3493     		scsi_hostlist = shone;
3494     		shone->next = shtwo->next;
3495     		prevtoshone->next = shtwo;
3496     		shtwo->next = NULL;
3497     	} else if (shtwo == scsi_hostlist && shone->next != NULL) {
3498     		/* shtwo at head, shone is not at tail */
3499     
3500     		prevtoshone = scsi_hostlist;
3501     		while (prevtoshone->next != shone)
3502     			prevtoshone = prevtoshone->next;
3503     
3504     		scsi_hostlist = shone;
3505     		prevtoshone->next = shtwo;
3506     		save = shtwo->next;
3507     		shtwo->next = shone->next;
3508     		shone->next = save;
3509     	} else if (shone->next == NULL) {
3510     		/* shtwo not at head, shone at tail */
3511     
3512     		prevtoshtwo = scsi_hostlist;
3513     		prevtoshone = scsi_hostlist;
3514     
3515     		while (prevtoshtwo->next != shtwo)
3516     			prevtoshtwo = prevtoshtwo->next;
3517     		while (prevtoshone->next != shone)
3518     			prevtoshone = prevtoshone->next;
3519     
3520     		prevtoshtwo->next = shone;
3521     		shone->next = shtwo->next;
3522     		prevtoshone->next = shtwo;
3523     		shtwo->next = NULL;
3524     
3525     	} else {
3526     		prevtoshtwo = scsi_hostlist;
3527     		prevtoshone = scsi_hostlist;
3528     		save = NULL;;
3529     
3530     		while (prevtoshtwo->next != shtwo)
3531     			prevtoshtwo = prevtoshtwo->next;
3532     		while (prevtoshone->next != shone)
3533     			prevtoshone = prevtoshone->next;
3534     
3535     		prevtoshtwo->next = shone;
3536     		save = shone->next;
3537     		shone->next = shtwo->next;
3538     		prevtoshone->next = shtwo;
3539     		shtwo->next = save;
3540     	}
3541     	return;
3542     }
3543     
3544     static inline void mega_freeSgList (mega_host_config * megaCfg)
3545     {
3546     	int i;
3547     
3548     	for (i = 0; i < megaCfg->max_cmds; i++) {
3549     		if (megaCfg->scbList[i].sgList)
3550     			pci_free_consistent (megaCfg->dev,
3551     					     sizeof (mega_64sglist) *
3552     					     MAX_SGLIST,
3553     					     megaCfg->scbList[i].sgList,
3554     					     megaCfg->scbList[i].
3555     					     dma_sghandle64);
3556     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)	/* 0x020400 */
3557     			kfree (megaCfg->scbList[i].sgList);	/* free sgList */
3558     #endif
3559     	}
3560     }
3561     
3562     /*----------------------------------------------
3563      * Get information about the card/driver
3564      *----------------------------------------------*/
3565     const char *megaraid_info (struct Scsi_Host *pSHost)
3566     {
3567     	static char buffer[512];
3568     	mega_host_config *megaCfg;
3569     
3570     	megaCfg = (mega_host_config *) pSHost->hostdata;
3571     
3572     	sprintf (buffer,
3573     		 "AMI MegaRAID %s %d commands %d targs %d chans %d luns",
3574     		 megaCfg->fwVer, megaCfg->productInfo.MaxConcCmds,
3575     		 megaCfg->host->max_id, megaCfg->host->max_channel,
3576     		 megaCfg->host->max_lun);
3577     	return buffer;
3578     }
3579     
3580     /*-----------------------------------------------------------------
3581      * Perform a SCSI command
3582      * Mailbox area:
3583      *   00 01 command
3584      *   01 01 command id
3585      *   02 02 # of sectors
3586      *   04 04 logical bus address
3587      *   08 04 physical buffer address
3588      *   0C 01 logical drive #
3589      *   0D 01 length of scatter/gather list
3590      *   0E 01 reserved
3591      *   0F 01 mailbox busy
3592      *   10 01 numstatus byte
3593      *   11 01 status byte
3594      *-----------------------------------------------------------------*/
3595     int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
3596     {
3597     	DRIVER_LOCK_T mega_host_config * megaCfg;
3598     	mega_scb *pScb;
3599     	char *user_area = NULL;
3600     
3601     	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3602     	DRIVER_LOCK (megaCfg);
3603     
3604     	if (!(megaCfg->flag & (1L << SCpnt->channel))) {
3605     		if (SCpnt->channel < SCpnt->host->max_channel)
3606     			printk ( KERN_NOTICE
3607     				"scsi%d: scanning channel %c for devices.\n",
3608     				megaCfg->host->host_no, SCpnt->channel + '1');
3609     		else
3610     			printk ( KERN_NOTICE
3611     				"scsi%d: scanning virtual channel for logical drives.\n",
3612     				megaCfg->host->host_no);
3613     
3614     		megaCfg->flag |= (1L << SCpnt->channel);
3615     	}
3616     
3617     	SCpnt->scsi_done = pktComp;
3618     
3619     	if (mega_driver_ioctl (megaCfg, SCpnt))
3620     		return 0;
3621     
3622     	/* If driver in abort or reset.. cancel this command */
3623     	if (megaCfg->flag & IN_ABORT) {
3624     		SCpnt->result = (DID_ABORT << 16);
3625     		/* Add Scsi_Command to end of completed queue */
3626     		if (megaCfg->qCompletedH == NULL) {
3627     			megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
3628     		} else {
3629     			megaCfg->qCompletedT->host_scribble =
3630     			    (unsigned char *) SCpnt;
3631     			megaCfg->qCompletedT = SCpnt;
3632     		}
3633     		megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
3634     		megaCfg->qCcnt++;
3635     
3636     		DRIVER_UNLOCK (megaCfg);
3637     		return 0;
3638     	} else if (megaCfg->flag & IN_RESET) {
3639     		SCpnt->result = (DID_RESET << 16);
3640     		/* Add Scsi_Command to end of completed queue */
3641     		if (megaCfg->qCompletedH == NULL) {
3642     			megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
3643     		} else {
3644     			megaCfg->qCompletedT->host_scribble =
3645     			    (unsigned char *) SCpnt;
3646     			megaCfg->qCompletedT = SCpnt;
3647     		}
3648     		megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
3649     		megaCfg->qCcnt++;
3650     
3651     		DRIVER_UNLOCK (megaCfg);
3652     		return 0;
3653     	}
3654     
3655     	megaCfg->flag |= IN_QUEUE;
3656     	/* Allocate and build a SCB request */
3657     	if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
3658     		/*build SCpnt for M_RD_IOCTL_CMD_NEW cmd in mega_ioctl() */
3659     		/* Add SCB to the head of the pending queue */
3660     		/* Add SCB to the head of the pending queue */
3661     		if (megaCfg->qPendingH == NULL) {
3662     			megaCfg->qPendingH = megaCfg->qPendingT = pScb;
3663     		} else {
3664     			megaCfg->qPendingT->next = pScb;
3665     			megaCfg->qPendingT = pScb;
3666     		}
3667     		megaCfg->qPendingT->next = NULL;
3668     		megaCfg->qPcnt++;
3669     
3670     		if (mega_runpendq (megaCfg) == -1) {
3671     			DRIVER_UNLOCK (megaCfg);
3672     			return 0;
3673     		}
3674     
3675     		if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
3676     			init_MUTEX_LOCKED (&pScb->ioctl_sem);
3677     			spin_unlock_irq (&io_request_lock);
3678     			down (&pScb->ioctl_sem);
3679         		user_area = (char *)*((u32*)&pScb->SCpnt->cmnd[4]);
3680     			if (copy_to_user
3681     			    (user_area, pScb->buff_ptr, pScb->iDataSize)) {
3682     				printk
3683     				    ("megaraid: Error copying ioctl return value to user buffer.\n");
3684     				pScb->SCpnt->result = (DID_ERROR << 16);
3685     			}
3686     			spin_lock_irq (&io_request_lock);
3687     			DRIVER_LOCK (megaCfg);
3688     			kfree (pScb->buff_ptr);
3689     			pScb->buff_ptr = NULL;
3690     			mega_cmd_done (megaCfg, pScb, pScb->SCpnt->result);
3691     			mega_rundoneq (megaCfg);
3692     			mega_runpendq (megaCfg);
3693     			DRIVER_UNLOCK (megaCfg);
3694     		}
3695     
3696     		megaCfg->flag &= ~IN_QUEUE;
3697     
3698     	}
3699     
3700     	DRIVER_UNLOCK (megaCfg);
3701     	return 0;
3702     }
3703     
3704     /*----------------------------------------------------------------------
3705      * Issue a blocking command to the controller
3706      *----------------------------------------------------------------------*/
3707     volatile static int internal_done_flag = 0;
3708     volatile static int internal_done_errcode = 0;
3709     
3710     static DECLARE_WAIT_QUEUE_HEAD (internal_wait);
3711     
3712     static void internal_done (Scsi_Cmnd * SCpnt)
3713     {
3714     	internal_done_errcode = SCpnt->result;
3715     	internal_done_flag++;
3716     	wake_up (&internal_wait);
3717     }
3718     
3719     /* shouldn't be used, but included for completeness */
3720     
3721     int megaraid_command (Scsi_Cmnd * SCpnt)
3722     {
3723     	internal_done_flag = 0;
3724     
3725     	/* Queue command, and wait until it has completed */
3726     	megaraid_queue (SCpnt, internal_done);
3727     
3728     	while (!internal_done_flag) {
3729     		interruptible_sleep_on (&internal_wait);
3730     	}
3731     
3732     	return internal_done_errcode;
3733     }
3734     
3735     /*---------------------------------------------------------------------
3736      * Abort a previous SCSI request
3737      *---------------------------------------------------------------------*/
3738     int megaraid_abort (Scsi_Cmnd * SCpnt)
3739     {
3740     	mega_host_config *megaCfg;
3741     	int rc;			/*, idx; */
3742     	mega_scb *pScb;
3743     
3744     	rc = SCSI_ABORT_NOT_RUNNING;
3745     
3746     	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3747     
3748     	megaCfg->flag |= IN_ABORT;
3749     
3750     	for (pScb = megaCfg->qPendingH; pScb; pScb = pScb->next) {
3751     		if (pScb->SCpnt == SCpnt) {
3752     			/* Found an aborting command */
3753     #if DEBUG
3754     			showMbox (pScb);
3755     #endif
3756     
3757     	/*
3758     	 * If the command is queued to be issued to the firmware, abort the scsi cmd,
3759     	 * If the command is already aborted in a previous call to the _abort entry
3760     	 *  point, return SCSI_ABORT_SNOOZE, suggesting a reset.
3761     	 * If the command is issued to the firmware, which might complete after
3762     	 *  some time, we will mark the scb as aborted, and return to the mid layer,
3763     	 *  that abort could not be done.
3764     	 *  In the ISR, when this command actually completes, we will perform a normal
3765     	 *  completion.
3766     	 *
3767     	 * Oct 27, 1999
3768     	 */
3769     
3770     			switch (pScb->state) {
3771     			case SCB_ABORTED:	/* Already aborted */
3772     				rc = SCSI_ABORT_SNOOZE;
3773     				break;
3774     			case SCB_ISSUED:	/* Waiting on ISR result */
3775     				rc = SCSI_ABORT_NOT_RUNNING;
3776     				pScb->state = SCB_ABORTED;
3777     				break;
3778     			case SCB_ACTIVE:	/* still on the pending queue */
3779     				mega_freeSCB (megaCfg, pScb);
3780     				SCpnt->result = (DID_ABORT << 16);
3781     				if (megaCfg->qCompletedH == NULL) {
3782     					megaCfg->qCompletedH =
3783     					    megaCfg->qCompletedT = SCpnt;
3784     				} else {
3785     					megaCfg->qCompletedT->host_scribble =
3786     					    (unsigned char *) SCpnt;
3787     					megaCfg->qCompletedT = SCpnt;
3788     				}
3789     				megaCfg->qCompletedT->host_scribble =
3790     				    (unsigned char *) NULL;
3791     				megaCfg->qCcnt++;
3792     				rc = SCSI_ABORT_SUCCESS;
3793     				break;
3794     			default:
3795     				printk
3796     				    ("megaraid_abort: unknown command state!!\n");
3797     				rc = SCSI_ABORT_NOT_RUNNING;
3798     				break;
3799     			}
3800     			break;
3801     		}
3802     	}
3803     
3804     	megaCfg->flag &= ~IN_ABORT;
3805     
3806     #if DEBUG
3807     	if (megaCfg->flag & IN_QUEUE)
3808     		printk ("ma:flag is in queue\n");
3809     	if (megaCfg->qCompletedH == NULL)
3810     		printk ("ma:qchead == null\n");
3811     #endif
3812     
3813     	/*
3814     	 * This is required here to complete any completed requests to be communicated
3815     	 * over to the mid layer.
3816     	 * Calling just mega_rundoneq() did not work.
3817     	 */
3818     	if (megaCfg->qCompletedH) {
3819     		SCpnt = megaCfg->qCompletedH;
3820     		megaCfg->qCompletedH = (Scsi_Cmnd *) SCpnt->host_scribble;
3821     		megaCfg->qCcnt--;
3822     
3823     		SCpnt->host_scribble = (unsigned char *) NULL;
3824     		/* Callback */
3825     		callDone (SCpnt);
3826     	}
3827     	mega_rundoneq (megaCfg);
3828     
3829     	return rc;
3830     }
3831     
3832     /*---------------------------------------------------------------------
3833      * Reset a previous SCSI request
3834      *---------------------------------------------------------------------*/
3835     
3836     int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
3837     {
3838     	mega_host_config *megaCfg;
3839     	int idx;
3840     	int rc;
3841     	mega_scb *pScb;
3842     
3843     	rc = SCSI_RESET_NOT_RUNNING;
3844     	megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3845     
3846     	megaCfg->flag |= IN_RESET;
3847     
3848     	printk
3849     	    ("megaraid_RESET: %.08lx cmd=%.02x <c=%d.t=%d.l=%d>, flag = %x\n",
3850     	     SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
3851     	     SCpnt->target, SCpnt->lun, rstflags);
3852     
3853     	TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
3854     		SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
3855     		SCpnt->target, SCpnt->lun));
3856     
3857     	/*
3858     	 * Walk list of SCBs for any that are still outstanding
3859     	 */
3860     	for (idx = 0; idx < megaCfg->max_cmds; idx++) {
3861     		if (megaCfg->scbList[idx].state != SCB_FREE) {
3862     			SCpnt = megaCfg->scbList[idx].SCpnt;
3863     			pScb = &megaCfg->scbList[idx];
3864     			if (SCpnt != NULL) {
3865     				pScb->state = SCB_RESET;
3866     				break;
3867     			}
3868     		}
3869     	}
3870     
3871     	megaCfg->flag &= ~IN_RESET;
3872     
3873     	mega_rundoneq (megaCfg);
3874     	return rc;
3875     }
3876     
3877     #ifdef CONFIG_PROC_FS
3878     /* Following code handles /proc fs  */
3879     static int proc_printf (mega_host_config * megaCfg, const char *fmt, ...)
3880     {
3881     	va_list args;
3882     	int i;
3883     
3884     	if (megaCfg->procidx > PROCBUFSIZE)
3885     		return 0;
3886     
3887     	va_start (args, fmt);
3888     	i = vsprintf ((megaCfg->procbuf + megaCfg->procidx), fmt, args);
3889     	va_end (args);
3890     
3891     	megaCfg->procidx += i;
3892     	return i;
3893     }
3894     
3895     static int proc_read_config (char *page, char **start, off_t offset,
3896     		  int count, int *eof, void *data)
3897     {
3898     
3899     	mega_host_config *megaCfg = (mega_host_config *) data;
3900     
3901     	*start = page;
3902     
3903     	if (megaCfg->productInfo.ProductName[0] != 0)
3904     		proc_printf (megaCfg, "%s\n", megaCfg->productInfo.ProductName);
3905     
3906     	proc_printf (megaCfg, "Controller Type: ");
3907     
3908     	if (megaCfg->flag & BOARD_QUARTZ)
3909     		proc_printf (megaCfg, "438/466/467/471/493\n");
3910     	else
3911     		proc_printf (megaCfg, "418/428/434\n");
3912     
3913     	if (megaCfg->flag & BOARD_40LD)
3914     		proc_printf (megaCfg,
3915     			     "Controller Supports 40 Logical Drives\n");
3916     
3917     	if (megaCfg->flag & BOARD_64BIT)
3918     		proc_printf (megaCfg,
3919     			     "Controller / Driver uses 64 bit memory addressing\n");
3920     
3921     	proc_printf (megaCfg, "Base = %08x, Irq = %d, ", megaCfg->base,
3922     		     megaCfg->host->irq);
3923     
3924     	proc_printf (megaCfg, "Logical Drives = %d, Channels = %d\n",
3925     		     megaCfg->numldrv, megaCfg->productInfo.SCSIChanPresent);
3926     
3927     	proc_printf (megaCfg, "Version =%s:%s, DRAM = %dMb\n",
3928     		     megaCfg->fwVer, megaCfg->biosVer,
3929     		     megaCfg->productInfo.DramSize);
3930     
3931     	proc_printf (megaCfg,
3932     		     "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
3933     		     megaCfg->productInfo.MaxConcCmds, megaCfg->max_cmds);
3934     	COPY_BACK;
3935     	return count;
3936     }
3937     
3938     static int proc_read_stat (char *page, char **start, off_t offset,
3939     		int count, int *eof, void *data)
3940     {
3941     	int i;
3942     	mega_host_config *megaCfg = (mega_host_config *) data;
3943     
3944     	*start = page;
3945     
3946     	proc_printf (megaCfg, "Statistical Information for this controller\n");
3947     	proc_printf (megaCfg, "Interrupts Collected = %lu\n",
3948     		     megaCfg->nInterrupts);
3949     
3950     	for (i = 0; i < megaCfg->numldrv; i++) {
3951     		proc_printf (megaCfg, "Logical Drive %d:\n", i);
3952     
3953     		proc_printf (megaCfg,
3954     			     "\tReads Issued = %lu, Writes Issued = %lu\n",
3955     			     megaCfg->nReads[i], megaCfg->nWrites[i]);
3956     
3957     		proc_printf (megaCfg,
3958     			     "\tSectors Read = %lu, Sectors Written = %lu\n\n",
3959     			     megaCfg->nReadBlocks[i], megaCfg->nWriteBlocks[i]);
3960     
3961     	}
3962     
3963     	COPY_BACK;
3964     	return count;
3965     }
3966     
3967     static int proc_read_status (char *page, char **start, off_t offset,
3968     		  int count, int *eof, void *data)
3969     {
3970     	mega_host_config *megaCfg = (mega_host_config *) data;
3971     	*start = page;
3972     
3973     	proc_printf (megaCfg, "TBD\n");
3974     	COPY_BACK;
3975     	return count;
3976     }
3977     
3978     static int proc_read_mbox (char *page, char **start, off_t offset,
3979     		int count, int *eof, void *data)
3980     {
3981     
3982     	mega_host_config *megaCfg = (mega_host_config *) data;
3983     	volatile mega_mailbox *mbox = megaCfg->mbox;
3984     
3985     	*start = page;
3986     
3987     	proc_printf (megaCfg, "Contents of Mail Box Structure\n");
3988     	proc_printf (megaCfg, "  Fw Command   = 0x%02x\n", mbox->cmd);
3989     	proc_printf (megaCfg, "  Cmd Sequence = 0x%02x\n", mbox->cmdid);
3990     	proc_printf (megaCfg, "  No of Sectors= %04d\n", mbox->numsectors);
3991     	proc_printf (megaCfg, "  LBA          = 0x%02x\n", mbox->lba);
3992     	proc_printf (megaCfg, "  DTA          = 0x%08x\n", mbox->xferaddr);
3993     	proc_printf (megaCfg, "  Logical Drive= 0x%02x\n", mbox->logdrv);
3994     	proc_printf (megaCfg, "  No of SG Elmt= 0x%02x\n", mbox->numsgelements);
3995     	proc_printf (megaCfg, "  Busy         = %01x\n", mbox->busy);
3996     	proc_printf (megaCfg, "  Status       = 0x%02x\n", mbox->status);
3997     
3998     	/* proc_printf(megaCfg, "Dump of MailBox\n");
3999     	for (i = 0; i < 16; i++)
4000             	proc_printf(megaCfg, "%02x ",*(mbox + i));
4001     
4002     	proc_printf(megaCfg, "\n\nNumber of Status = %02d\n",mbox->numstatus);
4003     
4004     	for (i = 0; i < 46; i++) {
4005             	proc_printf(megaCfg,"%02d ",*(mbox + 16 + i));
4006             if (i%16)
4007                     proc_printf(megaCfg,"\n");
4008     	}
4009     
4010     	if (!mbox->numsgelements) {
4011     	        dta = phys_to_virt(mbox->xferaddr);
4012     	        for (i = 0; i < mbox->numsgelements; i++)
4013     	                if (dta) {
4014     	                        proc_printf(megaCfg,"Addr = %08x\n", (ulong)*(dta + i));                        proc_printf(megaCfg,"Length = %08x\n",
4015     	                                (ulong)*(dta + i + 4));
4016     	                }
4017     	}*/
4018     	COPY_BACK;
4019     	return count;
4020     }
4021     
4022     #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)	/*0x20300 */
4023     #define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string, \
4024                                              S_IRUSR | S_IFREG,\
4025                                              controller_proc_dir_entry,\
4026                                              fxn, megaCfg)
4027     #else
4028     #define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string,S_IRUSR | S_IFREG, controller_proc_dir_entry, fxn, megaCfg)
4029     
4030     static struct proc_dir_entry *
4031     create_proc_read_entry (const char *string,
4032     			int mode,
4033     			struct proc_dir_entry *parent,
4034     			read_proc_t * fxn, mega_host_config * megaCfg)
4035     {
4036     	struct proc_dir_entry *temp = NULL;
4037     
4038     	temp = kmalloc (sizeof (struct proc_dir_entry), GFP_KERNEL);
4039     	if (!temp)
4040     		return NULL;
4041     	memset (temp, 0, sizeof (struct proc_dir_entry));
4042     
4043     	if ((temp->name = kmalloc (strlen (string) + 1, GFP_KERNEL)) == NULL) {
4044     		kfree (temp);
4045     		return NULL;
4046     	}
4047     
4048     	strcpy ((char *) temp->name, string);
4049     	temp->namelen = strlen (string);
4050     	temp->mode = mode; /*S_IFREG | S_IRUSR */ ;
4051     	temp->data = (void *) megaCfg;
4052     	temp->read_proc = fxn;
4053     	proc_register (parent, temp);
4054     	return temp;
4055     }
4056     #endif
4057     
4058     static void mega_create_proc_entry (int index, struct proc_dir_entry *parent)
4059     {
4060     	u_char string[64] = { 0 };
4061     	mega_host_config *megaCfg = megaCtlrs[index];
4062     	struct proc_dir_entry *controller_proc_dir_entry = NULL;
4063     
4064     	sprintf (string, "%d", index);
4065     
4066     #if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)	/*0x20300 */
4067     	controller_proc_dir_entry =
4068     	    megaCfg->controller_proc_dir_entry = proc_mkdir (string, parent);
4069     #else
4070     	controller_proc_dir_entry =
4071     	    megaCfg->controller_proc_dir_entry =
4072     	    create_proc_entry (string, S_IFDIR | S_IRUGO | S_IXUGO, parent);
4073     #endif
4074     
4075     	if (!controller_proc_dir_entry)
4076     		printk ("\nmegaraid: proc_mkdir failed\n");
4077     	else {
4078     		megaCfg->proc_read =
4079     		    CREATE_READ_PROC ("config", proc_read_config);
4080     		megaCfg->proc_status =
4081     		    CREATE_READ_PROC ("status", proc_read_status);
4082     		megaCfg->proc_stat = CREATE_READ_PROC ("stat", proc_read_stat);
4083     		megaCfg->proc_mbox =
4084     		    CREATE_READ_PROC ("mailbox", proc_read_mbox);
4085     	}
4086     
4087     }
4088     #endif				/* CONFIG_PROC_FS */
4089     
4090     /*-------------------------------------------------------------
4091      * Return the disk geometry for a particular disk
4092      * Input:
4093      *   Disk *disk - Disk geometry
4094      *   kdev_t dev - Device node
4095      *   int *geom  - Returns geometry fields
4096      *     geom[0] = heads
4097      *     geom[1] = sectors
4098      *     geom[2] = cylinders
4099      *-------------------------------------------------------------*/
4100     int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
4101     {
4102     	int heads, sectors, cylinders;
4103     	mega_host_config *megaCfg;
4104     
4105     	/* Get pointer to host config structure */
4106     	megaCfg = (mega_host_config *) disk->device->host->hostdata;
4107     
4108     	if( IS_RAID_CH(disk->device->channel)) {
4109     			/* Default heads (64) & sectors (32) */
4110     			heads = 64;
4111     			sectors = 32;
4112     			cylinders = disk->capacity / (heads * sectors);
4113     
4114     			/* Handle extended translation size for logical drives > 1Gb */
4115     			if (disk->capacity >= 0x200000) {
4116     				heads = 255;
4117     				sectors = 63;
4118     				cylinders = disk->capacity / (heads * sectors);
4119     			}
4120     
4121     			/* return result */
4122     			geom[0] = heads;
4123     			geom[1] = sectors;
4124     			geom[2] = cylinders;
4125     	}
4126     	else {
4127     		if( mega_partsize(disk, dev, geom) == 0 ) return 0;
4128     
4129     		printk(KERN_WARNING
4130     				"megaraid: invalid partition on this disk on channel %d\n",
4131     				disk->device->channel);
4132     
4133     		/* Default heads (64) & sectors (32) */
4134     		heads = 64;
4135     		sectors = 32;
4136     		cylinders = disk->capacity / (heads * sectors);
4137     
4138     		/* Handle extended translation size for logical drives > 1Gb */
4139     		if (disk->capacity >= 0x200000) {
4140     			heads = 255;
4141     			sectors = 63;
4142     			cylinders = disk->capacity / (heads * sectors);
4143     		}
4144     
4145     		/* return result */
4146     		geom[0] = heads;
4147     		geom[1] = sectors;
4148     		geom[2] = cylinders;
4149     	}
4150     
4151     	return 0;
4152     }
4153     
4154     /*
4155      * Function : static int mega_partsize(Disk * disk, kdev_t dev, int *geom)
4156      *
4157      * Purpose : to determine the BIOS mapping used to create the partition
4158      *			table, storing the results (cyls, hds, and secs) in geom
4159      *
4160      * Note:	Code is picked from scsicam.h
4161      *
4162      * Returns : -1 on failure, 0 on success.
4163      */
4164     static int
4165     mega_partsize(Disk * disk, kdev_t dev, int *geom)
4166     {
4167     	struct buffer_head *bh;
4168     	struct partition *p, *largest = NULL;
4169     	int i, largest_cyl;
4170     	int heads, cyls, sectors;
4171     	int capacity = disk->capacity;
4172     
4173     	int ma = MAJOR(dev);
4174     	int mi = (MINOR(dev) & ~0xf);
4175     
4176     	int block = 1024; 
4177     
4178     	if(blksize_size[ma])
4179     		block = blksize_size[ma][mi];
4180     		
4181     	if(!(bh = bread(MKDEV(ma,mi), 0, block)))
4182     		return -1;
4183     
4184     	if( *(unsigned short *)(bh->b_data + 510) == 0xAA55 ) {
4185     		for( largest_cyl = -1, p = (struct partition *)(0x1BE + bh->b_data),
4186     				i = 0; i < 4; ++i, ++p) {
4187     
4188     			if (!p->sys_ind) continue;
4189     
4190     			cyls = p->end_cyl + ((p->end_sector & 0xc0) << 2);
4191     
4192     			if(cyls >= largest_cyl) {
4193     				largest_cyl = cyls;
4194     				largest = p;
4195     			}
4196     		}
4197     	}
4198     	if (largest) {
4199     		heads = largest->end_head + 1;
4200     		sectors = largest->end_sector & 0x3f;
4201     
4202     		if (heads == 0 || sectors == 0) {
4203     			brelse(bh);
4204     			return -1;
4205     		}
4206     
4207     		cyls = capacity/(heads * sectors);
4208     
4209     		geom[0] = heads;
4210     		geom[1] = sectors;
4211     		geom[2] = cyls;
4212     
4213     		brelse(bh);
4214     		return 0;
4215     	}
4216     
4217     	brelse(bh);
4218     	return -1;
4219     }
4220     
4221     
4222     /*
4223      * This routine will be called when the use has done a forced shutdown on the
4224      * system. Flush the Adapter cache, that's the most we can do.
4225      */
4226     static int megaraid_reboot_notify (struct notifier_block *this, unsigned long code,
4227     			void *unused)
4228     {
4229     	struct Scsi_Host *pSHost;
4230     	mega_host_config *megaCfg;
4231     	mega_mailbox *mbox;
4232     	u_char mboxData[16];
4233     	int i;
4234     
4235     	if (code == SYS_DOWN || code == SYS_HALT) {
4236     		for (i = 0; i < numCtlrs; i++) {
4237     			pSHost = megaCtlrs[i]->host;
4238     
4239     			megaCfg = (mega_host_config *) pSHost->hostdata;
4240     			mbox = (mega_mailbox *) mboxData;
4241     
4242     			/* Flush cache to disk */
4243     			memset (mbox, 0, 16);
4244     			mboxData[0] = 0xA;
4245     
4246     			/*
4247     			 * Free irq, otherwise extra interrupt is generated
4248     			 */
4249     			free_irq (megaCfg->host->irq, megaCfg);
4250     
4251     			/*
4252     			   * Issue a blocking (interrupts disabled) command to
4253     			   * the card
4254     			 */
4255     			megaIssueCmd (megaCfg, mboxData, NULL, 0);
4256     		}
4257     	}
4258     	return NOTIFY_DONE;
4259     }
4260     
4261     static int mega_init_scb (mega_host_config * megacfg)
4262     {
4263     	int idx;
4264     
4265     #if DEBUG
4266     	if (megacfg->max_cmds >= MAX_COMMANDS) {
4267     		printk ("megaraid:ctlr max cmds = %x : MAX_CMDS = %x",
4268     			megacfg->max_cmds, MAX_COMMANDS);
4269     	}
4270     #endif
4271     
4272     	for (idx = megacfg->max_cmds - 1; idx >= 0; idx--) {
4273     
4274     		megacfg->scbList[idx].idx = idx;
4275     
4276     		/*
4277     		 * ISR will make this flag zero to indicate the command has been
4278     		 * completed. This is only for user ioctl calls. Rest of the driver
4279     		 * and the mid-layer operations are not connected with this flag.
4280     		 */
4281     
4282     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4283     		megacfg->scbList[idx].sgList =
4284     		    pci_alloc_consistent (megacfg->dev,
4285     					  sizeof (mega_64sglist) * MAX_SGLIST,
4286     					  &(megacfg->scbList[idx].
4287     					    dma_sghandle64));
4288     
4289     		megacfg->scbList[idx].sg64List =
4290     		    (mega_64sglist *) megacfg->scbList[idx].sgList;
4291     #else
4292     		megacfg->scbList[idx].sgList = kmalloc (sizeof (mega_sglist) * MAX_SGLIST, GFP_ATOMIC | GFP_DMA);
4293     #endif
4294     
4295     		if (megacfg->scbList[idx].sgList == NULL) {
4296     			printk (KERN_WARNING
4297     				"Can't allocate sglist for id %d\n", idx);
4298     			mega_freeSgList (megacfg);
4299     			return -1;
4300     		}
4301     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4302     		megacfg->scbList[idx].pthru = pci_alloc_consistent (megacfg->dev,
4303     					  sizeof (mega_passthru),
4304     					  &(megacfg->scbList[idx].
4305     					    dma_passthruhandle64));
4306     
4307     		if (megacfg->scbList[idx].pthru == NULL) {
4308     			printk (KERN_WARNING
4309     				"Can't allocate passthru for id %d\n", idx);
4310     		}
4311     
4312     		megacfg->scbList[idx].epthru =
4313     			pci_alloc_consistent(
4314     				megacfg->dev, sizeof(mega_ext_passthru),
4315     				&(megacfg->scbList[idx].dma_ext_passthruhandle64)
4316     			);
4317     
4318     		if (megacfg->scbList[idx].epthru == NULL) {
4319     			printk (KERN_WARNING
4320     				"Can't allocate extended passthru for id %d\n", idx);
4321     		}
4322     		/* 
4323     		 * Allocate a 256 Byte Bounce Buffer for handling INQ/RD_CAPA 
4324     		 */
4325     		megacfg->scbList[idx].bounce_buffer = pci_alloc_consistent (megacfg->dev,
4326     					  256,
4327     					  &(megacfg->scbList[idx].
4328     					    dma_bounce_buffer));
4329     
4330     		if (!megacfg->scbList[idx].bounce_buffer)
4331     			printk
4332     			    ("megaraid: allocation for bounce buffer failed\n");
4333     
4334     		megacfg->scbList[idx].dma_type = M_RD_DMA_TYPE_NONE;
4335     #endif
4336     
4337     		if (idx < MAX_COMMANDS) {
4338     			/*
4339     			 * Link to free list
4340     			 * lock not required since we are loading the driver, so no
4341     			 * commands possible right now.
4342     			 */
4343     			enq_scb_freelist (megacfg, &megacfg->scbList[idx],
4344     					  NO_LOCK, INTR_ENB);
4345     
4346     		}
4347     	}
4348     
4349     	return 0;
4350     }
4351     
4352     /*
4353      * Enqueues a SCB
4354      */
4355     static void enq_scb_freelist (mega_host_config * megacfg, mega_scb * scb, int lock,
4356     		  int intr)
4357     {
4358     
4359     	if (lock == INTERNAL_LOCK || intr == INTR_DIS) {
4360     		if (intr == INTR_DIS)
4361     			spin_lock_irq (&megacfg->lock_free);
4362     		else
4363     			spin_lock (&megacfg->lock_free);
4364     	}
4365     
4366     	scb->state = SCB_FREE;
4367     	scb->SCpnt = NULL;
4368     
4369     	if (megacfg->qFreeH == (mega_scb *) NULL) {
4370     		megacfg->qFreeH = megacfg->qFreeT = scb;
4371     	} else {
4372     		megacfg->qFreeT->next = scb;
4373     		megacfg->qFreeT = scb;
4374     	}
4375     
4376     	megacfg->qFreeT->next = NULL;
4377     	megacfg->qFcnt++;
4378     
4379     	if (lock == INTERNAL_LOCK || intr == INTR_DIS) {
4380     		if (intr == INTR_DIS)
4381     			spin_unlock_irq (&megacfg->lock_free);
4382     		else
4383     			spin_unlock (&megacfg->lock_free);
4384     	}
4385     }
4386     
4387     /*
4388      * Routines for the character/ioctl interface to the driver
4389      */
4390     static int megadev_open (struct inode *inode, struct file *filep)
4391     {
4392     	MOD_INC_USE_COUNT;
4393     	return 0;		/* success */
4394     }
4395     
4396     static int megadev_ioctl_entry (struct inode *inode, struct file *filep,
4397     		     unsigned int cmd, unsigned long arg)
4398     {
4399     	int ret = -1;
4400     
4401     	/*
4402     	 * We do not allow parallel ioctls to the driver as of now.
4403     	 */
4404     	down (&mimd_entry_mtx);
4405     	ret = megadev_ioctl (inode, filep, cmd, arg);
4406     	up (&mimd_entry_mtx);
4407     
4408     	return ret;
4409     
4410     }
4411     
4412     static int megadev_ioctl (struct inode *inode, struct file *filep,
4413     	       unsigned int cmd, unsigned long arg)
4414     {
4415     	int adapno;
4416     	kdev_t dev;
4417     	u32 inlen;
4418     	struct uioctl_t ioc;
4419     	char *kvaddr = NULL;
4420     	int nadap = numCtlrs;
4421     	u8 opcode;
4422     	u32 outlen;
4423     	int ret;
4424     	u8 subopcode;
4425     	Scsi_Cmnd *scsicmd;
4426     	struct Scsi_Host *shpnt;
4427     	char *uaddr;
4428     	struct uioctl_t *uioc;
4429     	dma_addr_t	dma_addr;
4430     	u32		length;
4431     	mega_host_config *megacfg = NULL;
4432     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/* 0x020400 */
4433     	struct pci_dev pdev;
4434     	struct pci_dev *pdevp = &pdev;
4435     #else
4436     	char *pdevp = NULL;
4437     #endif
4438     	IO_LOCK_T;
4439     
4440     	if (!inode || !(dev = inode->i_rdev))
4441     		return -EINVAL;
4442     
4443     	if (_IOC_TYPE (cmd) != MEGAIOC_MAGIC)
4444     		return (-EINVAL);
4445     
4446     	/*
4447     	 * Get the user ioctl structure
4448     	 */
4449     	ret = verify_area (VERIFY_WRITE, (char *) arg, sizeof (struct uioctl_t));
4450     
4451     	if (ret)
4452     		return ret;
4453     
4454     	if(copy_from_user (&ioc, (char *) arg, sizeof (struct uioctl_t)))
4455     		return -EFAULT;
4456     
4457     	/*
4458     	 * The first call the applications should make is to find out the
4459     	 * number of controllers in the system. The next logical call should
4460     	 * be for getting the list of controllers in the system as detected
4461     	 * by the driver.
4462     	 */
4463     
4464     	/*
4465     	 * Get the opcode and subopcode for the commands
4466     	 */
4467     	opcode = ioc.ui.fcs.opcode;
4468     	subopcode = ioc.ui.fcs.subopcode;
4469     
4470     	switch (opcode) {
4471     	case M_RD_DRIVER_IOCTL_INTERFACE:
4472     		switch (subopcode) {
4473     		case MEGAIOC_QDRVRVER:	/* Query driver version */
4474     			put_user (driver_ver, (u32 *) ioc.data);
4475     			return 0;
4476     
4477     		case MEGAIOC_QNADAP:	/* Get # of adapters */
4478     			put_user (nadap, (int *) ioc.data);
4479     			return nadap;
4480     
4481     		case MEGAIOC_QADAPINFO:	/* Get adapter information */
4482     			/*
4483     			 * which adapter?
4484     			 */
4485     			adapno = ioc.ui.fcs.adapno;
4486     
4487     			/*
4488     			 * The adapter numbers do not start with 0, at least in
4489     			 * the user space. This is just to make sure, 0 is not the
4490     			 * default value which will refer to adapter 1. So the
4491     			 * user needs to make use of macros MKADAP() and GETADAP()
4492     			 * (See megaraid.h) while making ioctl() call.
4493     			 */
4494     			adapno = GETADAP (adapno);
4495     
4496     			if (adapno >= numCtlrs)
4497     				return (-ENODEV);
4498     
4499     			ret = verify_area (VERIFY_WRITE,
4500     					   ioc.data,
4501     					   sizeof (struct mcontroller));
4502     			if (ret)
4503     				return ret;
4504     
4505     			/*
4506     			 * Copy struct mcontroller to user area
4507     			 */
4508     			copy_to_user (ioc.data,
4509     				      mcontroller + adapno,
4510     				      sizeof (struct mcontroller));
4511     			return 0;
4512     
4513     		default:
4514     			return (-EINVAL);
4515     
4516     		}		/* inner switch */
4517     		break;
4518     
4519     	case M_RD_IOCTL_CMD_NEW:
4520     		/* which adapter?  */
4521     		adapno = ioc.ui.fcs.adapno;
4522     
4523     		/* See comment above: MEGAIOC_QADAPINFO */
4524     		adapno = GETADAP(adapno);
4525     
4526     		if (adapno >= numCtlrs)
4527     			return(-ENODEV);
4528     
4529     		length = ioc.ui.fcs.length;
4530     
4531     		/* Check for zero length buffer or very large buffers */
4532     		if( !length || length > 32*1024 )
4533     			return -EINVAL;
4534     
4535     		/* save the user address */
4536     		uaddr = ioc.ui.fcs.buffer;
4537     
4538     		/*
4539     		 * For M_RD_IOCTL_CMD_NEW commands, the fields outlen and inlen of
4540     		 * uioctl_t structure are treated as flags. If outlen is 1, the
4541     		 * data is transferred from the device and if inlen is 1, the data
4542     		 * is transferred to the device.
4543     		 */
4544     		outlen = ioc.outlen;
4545     		inlen = ioc.inlen;
4546     
4547     		if(outlen) {
4548     			ret = verify_area(VERIFY_WRITE, (char *)ioc.ui.fcs.buffer, length);
4549     			if (ret) return ret;
4550     		}
4551     		if(inlen) {
4552     			ret = verify_area(VERIFY_READ, (char *) ioc.ui.fcs.buffer, length);
4553     			if (ret) return ret;
4554     		}
4555     
4556     		/*
4557     		 * Find this host
4558     		 */
4559     		for( shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next ) {
4560     			if( shpnt->hostdata == (unsigned long *)megaCtlrs[adapno] ) {
4561     				megacfg = (mega_host_config *)shpnt->hostdata;
4562     				break;
4563     			}
4564     		}
4565     		if(shpnt == NULL)  return -ENODEV;
4566     
4567     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4568     		scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
4569     #else
4570     		scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
4571     							  GFP_ATOMIC | GFP_DMA);
4572     #endif
4573     		if(scsicmd == NULL) return -ENOMEM;
4574     
4575     		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
4576     		scsicmd->host = shpnt;
4577     
4578     		if( outlen || inlen ) {
4579     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4580     			pdevp = &pdev;
4581     			memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
4582     			pdevp->dma_mask = 0xffffffff;
4583     #else
4584     			pdevp = NULL;
4585     #endif
4586     			kvaddr = dma_alloc_consistent(pdevp, length, &dma_addr);
4587     
4588     			if( kvaddr == NULL ) {
4589     				printk(KERN_WARNING "megaraid:allocation failed\n");
4590     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
4591     				kfree(scsicmd);
4592     #else
4593     				scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4594     #endif
4595     				return -ENOMEM;
4596     			}
4597     
4598     			ioc.ui.fcs.buffer = kvaddr;
4599     
4600     			if (inlen) {
4601     				/* copyin the user data */
4602     				copy_from_user(kvaddr, (char *)uaddr, length );
4603     			}
4604     		}
4605     
4606     		scsicmd->cmnd[0] = MEGADEVIOC;
4607     		scsicmd->request_buffer = (void *)&ioc;
4608     
4609     		init_MUTEX_LOCKED(&mimd_ioctl_sem);
4610     
4611     		IO_LOCK;
4612     		megaraid_queue(scsicmd, megadev_ioctl_done);
4613     
4614     		IO_UNLOCK;
4615     
4616     		down(&mimd_ioctl_sem);
4617     
4618     		if( !scsicmd->result && outlen ) {
4619     			copy_to_user(uaddr, kvaddr, length);
4620     		}
4621     
4622     		/*
4623     		 * copyout the result
4624     		 */
4625     		uioc = (struct uioctl_t *)arg;
4626     
4627     		if( ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
4628     			put_user( scsicmd->result, &uioc->pthru.scsistatus );
4629     		} else {
4630     			put_user(1, &uioc->mbox[16]);	/* numstatus */
4631     			/* status */
4632     			put_user (scsicmd->result, &uioc->mbox[17]);
4633     		}
4634     
4635     		if (kvaddr) {
4636     			dma_free_consistent(pdevp, length, kvaddr, dma_addr);
4637     		}
4638     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
4639     		kfree (scsicmd);
4640     #else
4641     		scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4642     #endif
4643     
4644     		/* restore the user address */
4645     		ioc.ui.fcs.buffer = uaddr;
4646     
4647     		return ret;
4648     
4649     	case M_RD_IOCTL_CMD:
4650     		/* which adapter?  */
4651     		adapno = ioc.ui.fcs.adapno;
4652     
4653     		/* See comment above: MEGAIOC_QADAPINFO */
4654     		adapno = GETADAP (adapno);
4655     
4656     		if (adapno >= numCtlrs)
4657     			return (-ENODEV);
4658     
4659     		/* save the user address */
4660     		uaddr = ioc.data;
4661     		outlen = ioc.outlen;
4662     		inlen = ioc.inlen;
4663     
4664     		if ((outlen >= IOCTL_MAX_DATALEN) || (inlen >= IOCTL_MAX_DATALEN))
4665     			return (-EINVAL);
4666     
4667     		if (outlen) {
4668     			ret = verify_area (VERIFY_WRITE, ioc.data, outlen);
4669     			if (ret) return ret;
4670     		}
4671     		if (inlen) {
4672     			ret = verify_area (VERIFY_READ, ioc.data, inlen);
4673     			if (ret) return ret;
4674     		}
4675     
4676     		/*
4677     		 * Find this host
4678     		 */
4679     		for( shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next ) {
4680     			if( shpnt->hostdata == (unsigned long *)megaCtlrs[adapno] ) {
4681     				megacfg = (mega_host_config *)shpnt->hostdata;
4682     				break;
4683     			}
4684     		}
4685     		if(shpnt == NULL)  return -ENODEV;
4686     
4687     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4688     		scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
4689     #else
4690     		scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
4691     							  GFP_ATOMIC | GFP_DMA);
4692     #endif
4693     		if(scsicmd == NULL) return -ENOMEM;
4694     
4695     		memset(scsicmd, 0, sizeof(Scsi_Cmnd));
4696     		scsicmd->host = shpnt;
4697     
4698     		if (outlen || inlen) {
4699     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4700     			pdevp = &pdev;
4701     			memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
4702     			pdevp->dma_mask = 0xffffffff;
4703     #else
4704     			pdevp = NULL;
4705     #endif
4706     			/*
4707     			 * Allocate a page of kernel space.
4708     			 */
4709     			kvaddr = dma_alloc_consistent(pdevp, PAGE_SIZE, &dma_addr);
4710     
4711     			if( kvaddr == NULL ) {
4712     				printk (KERN_WARNING "megaraid:allocation failed\n");
4713     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)	/*0x20400 */
4714     				kfree(scsicmd);
4715     #else
4716     				scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4717     #endif
4718     				return -ENOMEM;
4719     			}
4720     
4721     			ioc.data = kvaddr;
4722     
4723     			if (inlen) {
4724     				if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4725     					/* copyin the user data */
4726     					copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen);
4727     				} else {
4728     					copy_from_user (kvaddr, uaddr, inlen);
4729     				}
4730     			}
4731     		}
4732     
4733     		scsicmd->cmnd[0] = MEGADEVIOC;
4734     		scsicmd->request_buffer = (void *) &ioc;
4735     
4736     		init_MUTEX_LOCKED (&mimd_ioctl_sem);
4737     
4738     		IO_LOCK;
4739     		megaraid_queue (scsicmd, megadev_ioctl_done);
4740     
4741     		IO_UNLOCK;
4742     		down (&mimd_ioctl_sem);
4743     
4744     		if (!scsicmd->result && outlen) {
4745     			if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4746     				copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen);
4747     			} else {
4748     				copy_to_user (uaddr, kvaddr, outlen);
4749     			}
4750     		}
4751     
4752     		/*
4753     		 * copyout the result
4754     		 */
4755     		uioc = (struct uioctl_t *) arg;
4756     
4757     		if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4758     			put_user (scsicmd->result, &uioc->pthru.scsistatus);
4759     		} else {
4760     			put_user (1, &uioc->mbox[16]);	/* numstatus */
4761     			/* status */
4762     			put_user (scsicmd->result, &uioc->mbox[17]);
4763     		}
4764     
4765     		if (kvaddr) {
4766     			dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
4767     		}
4768     
4769     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4770     		kfree (scsicmd);
4771     #else
4772     		scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4773     #endif
4774     
4775     		/* restore user pointer */
4776     		ioc.data = uaddr;
4777     
4778     		return ret;
4779     
4780     	default:
4781     		return (-EINVAL);
4782     
4783     	}/* Outer switch */
4784     
4785     	return 0;
4786     }
4787     
4788     static void
4789     megadev_ioctl_done(Scsi_Cmnd *sc)
4790     {
4791     	up (&mimd_ioctl_sem);
4792     }
4793     
4794     static mega_scb *
4795     megadev_doioctl (mega_host_config * megacfg, Scsi_Cmnd * sc)
4796     {
4797     	u8 cmd;
4798     	struct uioctl_t *ioc = NULL;
4799     	mega_mailbox *mbox = NULL;
4800     	mega_ioctl_mbox *mboxioc = NULL;
4801     	struct mbox_passthru *mboxpthru = NULL;
4802     	mega_scb *scb = NULL;
4803     	mega_passthru *pthru = NULL;
4804     
4805     	if ((scb = mega_allocateSCB (megacfg, sc)) == NULL) {
4806     		sc->result = (DID_ERROR << 16);
4807     		callDone (sc);
4808     		return NULL;
4809     	}
4810     
4811     	ioc = (struct uioctl_t *) sc->request_buffer;
4812     
4813     	memcpy (scb->mboxData, ioc->mbox, sizeof (scb->mboxData));
4814     
4815     	/* The generic mailbox */
4816     	mbox = (mega_mailbox *) ioc->mbox;
4817     
4818     	/*
4819     	 * Get the user command
4820     	 */
4821     	cmd = ioc->mbox[0];
4822     
4823     	switch (cmd) {
4824     	case MEGA_MBOXCMD_PASSTHRU:
4825     		/*
4826     		   * prepare the SCB with information from the user ioctl structure
4827     		 */
4828     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4829     		pthru = scb->pthru;
4830     #else
4831     		pthru = &scb->pthru;
4832     #endif
4833     		memcpy (pthru, &ioc->pthru, sizeof (mega_passthru));
4834     		mboxpthru = (struct mbox_passthru *) scb->mboxData;
4835     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4836     		if (megacfg->flag & BOARD_64BIT) {
4837     			/* This is just a sample with one element 
4838     			   * This if executes onlu on 2.4 kernels
4839     			 */
4840     			mboxpthru->dataxferaddr = scb->dma_passthruhandle64;
4841     			scb->sg64List[0].address =
4842     			    pci_map_single (megacfg->dev,
4843     					    ioc->data,
4844     					    4096, PCI_DMA_BIDIRECTIONAL);
4845     			scb->sg64List[0].length = 4096;	// TODO: Check this
4846     			pthru->dataxferaddr = scb->dma_sghandle64;
4847     			pthru->numsgelements = 1;
4848     			mboxpthru->cmd = 0xC3;
4849     		} else {
4850     			mboxpthru->dataxferaddr = scb->dma_passthruhandle64;
4851     			pthru->dataxferaddr =
4852     			    pci_map_single (megacfg->dev,
4853     					    ioc->data,
4854     					    4096, PCI_DMA_BIDIRECTIONAL);
4855     			pthru->numsgelements = 0;
4856     		}
4857     
4858     #else
4859     		{
4860     			mboxpthru->dataxferaddr = virt_to_bus (&scb->pthru);
4861     			pthru->dataxferaddr = virt_to_bus (ioc->data);
4862     			pthru->numsgelements = 0;
4863     		}
4864     #endif
4865     
4866     		pthru->reqsenselen = 14;
4867     		break;
4868     
4869     	default:		/* Normal command */
4870     		mboxioc = (mega_ioctl_mbox *) scb->mboxData;
4871     
4872     		if (ioc->ui.fcs.opcode == M_RD_IOCTL_CMD_NEW) {
4873     			scb->buff_ptr = ioc->ui.fcs.buffer;
4874     			scb->iDataSize = ioc->ui.fcs.length;
4875     		} else {
4876     			scb->buff_ptr = ioc->data;
4877     			scb->iDataSize = 4096;	// TODO:check it
4878     		}
4879     
4880     		set_mbox_xfer_addr (megacfg, scb, mboxioc, FROMTO_DEVICE);
4881     		mboxioc->numsgelements = 0;
4882     		break;
4883     	}
4884     
4885     	return scb;
4886     }
4887     
4888     static int
4889     megadev_close (struct inode *inode, struct file *filep)
4890     {
4891     #ifdef MODULE
4892     	MOD_DEC_USE_COUNT;
4893     #endif
4894     	return 0;
4895     }
4896     
4897     
4898     static int
4899     mega_support_ext_cdb(mega_host_config *this_hba)
4900     {
4901     	mega_mailbox *mboxpnt;
4902     	unsigned char mbox[16];
4903     	int ret;
4904     
4905     	mboxpnt = (mega_mailbox *) mbox;
4906     
4907     	memset(mbox, 0, sizeof (mbox));
4908     	/*
4909     	 * issue command to find out if controller supports extended CDBs.
4910     	 */
4911     	mbox[0] = 0xA4;
4912     	mbox[2] = 0x16;
4913     
4914     	ret = megaIssueCmd(this_hba, mbox, NULL, 0);
4915     
4916     	return !ret;
4917     }
4918     
4919     
4920     #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
4921     void *
4922     dma_alloc_consistent(void *dev, size_t size, dma_addr_t *dma_addr)
4923     {
4924     	void	*_tv;
4925     	int		npages;
4926     	int		order = 0;
4927     
4928     	/*
4929     	 * How many pages application needs
4930     	 */
4931     	npages = size / PAGE_SIZE;
4932     
4933     	/* Do we need one more page */
4934     	if(size % PAGE_SIZE)
4935     		npages++;
4936     
4937     	order = mega_get_order(npages);
4938     
4939     	_tv = (void *)__get_free_pages(GFP_DMA, order);
4940     
4941     	if( _tv != NULL ) {
4942     		memset(_tv, 0, size);
4943     		*(dma_addr) = virt_to_bus(_tv);
4944     	}
4945     
4946     	return _tv;
4947     }
4948     
4949     /*
4950      * int mega_get_order(int)
4951      *
4952      * returns the order to be used as 2nd argument to __get_free_pages() - which
4953      * return pages equal to pow(2, order) - AM
4954      */
4955     int
4956     mega_get_order(int n)
4957     {
4958     	int		i = 0;
4959     
4960     	while( pow_2(i++) < n )
4961     		; /* null statement */
4962     
4963     	return i-1;
4964     }
4965     
4966     /*
4967      * int pow_2(int)
4968      *
4969      * calculates pow(2, i)
4970      */
4971     int
4972     pow_2(int i)
4973     {
4974     	unsigned int	v = 1;
4975     	
4976     	while(i--)
4977     		v <<= 1;
4978     
4979     	return v;
4980     }
4981     
4982     void
4983     dma_free_consistent(void *dev, size_t size, void *vaddr, dma_addr_t dma_addr)
4984     {
4985     	int		npages;
4986     	int		order = 0;
4987     
4988     	npages = size / PAGE_SIZE;
4989     
4990     	if(size % PAGE_SIZE)
4991     		npages++;
4992     
4993     	if (npages == 1)
4994     		order = 0;
4995     	else if (npages == 2)
4996     		order = 1;
4997     	else if (npages <= 4)
4998     		order = 2;
4999     	else
5000     		order = 3;
5001     
5002     	free_pages((unsigned long)vaddr, order);
5003     
5004     }
5005     #endif
5006     
5007     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
5008     static
5009     #endif				/* LINUX VERSION 2.4.XX */
5010     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) || defined(MODULE)
5011     Scsi_Host_Template driver_template = MEGARAID;
5012     
5013     #include "scsi_module.c"
5014     #endif				/* LINUX VERSION 2.4.XX || MODULE */
5015     
5016     /* vi: set ts=4: */
5017