linux-bk/drivers/scsi/megaraid.c
<<
>>
Prefs
   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.18 (Oct 11, 2001)
  13 *
  14 * Description: Linux device driver for LSI Logic 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 *
 431 * Version 1.17b
 432 * Mon Jul 30 19:24:02 EDT 2001 - AM
 433 *
 434 * Added support for random deletion of logical drives
 435 *
 436 * Version 1.17c
 437 * Tue Sep 25 09:37:49 EDT 2001 - Atul Mukker <atulm@lsil.com>
 438 *
 439 * With single and dual channel controllers, some virtaul channels are
 440 * displayed negative.
 441 *
 442 * Version 1.17a-ac
 443 * Mon Aug 6 14:59:29 BST 2001 - "Michael Johnson" <johnsom@home.com>
 444 *
 445 * Make the HP print formatting and check for buggy firmware runtime not
 446 * ifdef dependant.
 447 *
 448 *
 449 * Version 1.17d
 450 * Thu Oct 11 10:48:45 EDT 2001 - Atul Mukker <atulm@lsil.com>
 451 *
 452 * Driver 1.17c oops when loaded without controller.
 453 *
 454 * Special case for "use_sg == 1" removed while building the scatter gather
 455 * list.
 456 *
 457 * Version 1.18
 458 * Thu Oct 11 15:02:53 EDT 2001 - Atul Mukker <atulm@lsil.com>
 459 *
 460 * References to AMI have been changed to LSI Logic.
 461 *
 462 *
 463 * BUGS:
 464 *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
 465 *     fails to detect the controller as a pci device on the system.
 466 *
 467 *     Timeout period for upper scsi layer, i.e. SD_TIMEOUT in
 468 *     /drivers/scsi/sd.c, is too short for this controller. SD_TIMEOUT
 469 *     value must be increased to (30 * HZ) otherwise false timeouts
 470 *     will occur in the upper layer.
 471 *
 472 *     Never set skip_id. The existing PCI code the megaraid uses fails
 473 *     to properly check the vendor subid in some cases. Setting this then
 474 *     makes it steal other i960's and crashes some boxes
 475 *
 476 *     Far too many ifdefs for versions.
 477 *
 478 *===================================================================*/
 479
 480#include <linux/config.h>
 481#include <linux/version.h>
 482#include <linux/module.h>
 483#include <linux/types.h>
 484#include <linux/errno.h>
 485#include <linux/string.h>
 486#include <linux/kernel.h>
 487#include <linux/ioport.h>
 488#include <linux/fcntl.h>
 489#include <linux/delay.h>
 490#include <linux/pci.h>
 491#include <linux/proc_fs.h>
 492#include <linux/blk.h>
 493#include <linux/wait.h>
 494#include <linux/workqueue.h>
 495#include <linux/interrupt.h>
 496#include <linux/mm.h>
 497#include <linux/string.h>
 498#include <asm/pgtable.h>
 499
 500#include <linux/sched.h>
 501#include <linux/stat.h>
 502#include <linux/slab.h> /* for kmalloc() */
 503#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
 504#include <linux/bios32.h>
 505#else
 506#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  /* 0x20300 */
 507#include <asm/spinlock.h>
 508#else
 509#include <linux/spinlock.h>
 510#endif
 511#endif
 512
 513#include <asm/io.h>
 514#include <asm/irq.h>
 515
 516#if LINUX_VERSION_CODE > KERNEL_VERSION(2,0,24) /* 0x020024 */
 517#include <asm/uaccess.h>
 518#endif
 519
 520/*
 521 * These header files are required for Shutdown Notification routines
 522 */
 523#include <linux/notifier.h>
 524#include <linux/reboot.h>
 525#include <linux/init.h>
 526#include "scsi.h"
 527#include "hosts.h"
 528#include <scsi/scsicam.h>
 529
 530#include "megaraid.h"
 531
 532/*
 533 *================================================================
 534 *  #Defines
 535 *================================================================
 536 */
 537
 538#define MAX_SERBUF 160
 539#define COM_BASE 0x2f8
 540
 541static ulong RDINDOOR (mega_host_config * megaCfg)
 542{
 543        return readl (megaCfg->base + 0x20);
 544}
 545
 546static void WRINDOOR (mega_host_config * megaCfg, ulong value)
 547{
 548        writel (value, megaCfg->base + 0x20);
 549}
 550
 551static ulong RDOUTDOOR (mega_host_config * megaCfg)
 552{
 553        return readl (megaCfg->base + 0x2C);
 554}
 555
 556static void WROUTDOOR (mega_host_config * megaCfg, ulong value)
 557{
 558        writel (value, megaCfg->base + 0x2C);
 559}
 560
 561#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) /* 0x020200 */
 562#include <linux/smp.h>
 563#define cpuid smp_processor_id()
 564#endif
 565
 566#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)
 567#define scsi_set_pci_device(x,y)
 568#endif
 569
 570#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* 0x020400 */
 571
 572/*
 573 *      Linux 2.4 and higher
 574 *
 575 *      No driver private lock
 576 *      Use the io_request_lock not cli/sti
 577 *      queue task is a simple api without irq forms
 578 */
 579
 580MODULE_AUTHOR ("LSI Logic Corporation");
 581MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
 582MODULE_LICENSE ("GPL");
 583
 584#define DRIVER_LOCK_T
 585#define DRIVER_LOCK_INIT(p)
 586#define DRIVER_LOCK(p)
 587#define DRIVER_UNLOCK(p)
 588#define IO_LOCK_T unsigned long io_flags = 0
 589#define IO_LOCK(host) spin_lock_irqsave(host->host_lock,io_flags)
 590#define IO_UNLOCK(host) spin_unlock_irqrestore(host->host_lock,io_flags)
 591#define IO_LOCK_IRQ(host) spin_lock_irq(host->host_lock)
 592#define IO_UNLOCK_IRQ(host) spin_unlock_irq(host->host_lock)
 593
 594#define queue_task_irq(a,b)     queue_task(a,b)
 595#define queue_task_irq_off(a,b) queue_task(a,b)
 596
 597#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)       /* 0x020200 */
 598
 599/*
 600 *      Linux 2.2 and higher
 601 *
 602 *      No driver private lock
 603 *      Use the io_request_lock not cli/sti
 604 *      No pci region api
 605 *      queue_task is now a single simple API
 606 */
 607
 608static char kernel_version[] = UTS_RELEASE;
 609MODULE_AUTHOR ("LSI Logic Corporation");
 610MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
 611
 612#define DRIVER_LOCK_T
 613#define DRIVER_LOCK_INIT(p)
 614#define DRIVER_LOCK(p)
 615#define DRIVER_UNLOCK(p)
 616#define IO_LOCK_T unsigned long io_flags = 0
 617#define IO_LOCK(host) spin_lock_irqsave(host->host_lock,io_flags);
 618#define IO_UNLOCK(host) spin_unlock_irqrestore(host->host_lock,io_flags);
 619
 620#define pci_free_consistent(a,b,c,d)
 621#define pci_unmap_single(a,b,c,d)
 622#define pci_enable_device(x) (0)
 623#define queue_task_irq(a,b)     queue_task(a,b)
 624#define queue_task_irq_off(a,b) queue_task(a,b)
 625
 626#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19) /* 0x020219 */
 627#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
 628#define init_MUTEX(x)           (*(x)=MUTEX)
 629#define DECLARE_WAIT_QUEUE_HEAD(x)      struct wait_queue *x = NULL
 630#endif
 631
 632
 633#else
 634
 635/*
 636 *      Linux 2.0 macros. Here we have to provide some of our own
 637 *      functionality. We also only work little endian 32bit.
 638 *      Again no pci_alloc/free api
 639 *      IO_LOCK/IO_LOCK_T were never used in 2.0 so now are empty 
 640 */
 641 
 642#define cpuid 0
 643#define DRIVER_LOCK_T long cpu_flags;
 644#define DRIVER_LOCK_INIT(p)
 645#define DRIVER_LOCK(p) \
 646                save_flags(cpu_flags); \
 647                cli();
 648#define DRIVER_UNLOCK(p) \
 649                restore_flags(cpu_flags);
 650#define IO_LOCK_T
 651#define IO_LOCK(p)
 652#define IO_UNLOCK(p)
 653#define le32_to_cpu(x) (x)
 654#define cpu_to_le32(x) (x)
 655
 656#define pci_free_consistent(a,b,c,d)
 657#define pci_unmap_single(a,b,c,d)
 658
 659#define init_MUTEX_LOCKED(x)    (*(x)=MUTEX_LOCKED)
 660#define init_MUTEX(x)           (*(x)=MUTEX)
 661
 662#define pci_enable_device(x) (0)
 663
 664/*
 665 *      2.0 lacks spinlocks, iounmap/ioremap
 666 */
 667
 668#define ioremap vremap
 669#define iounmap vfree
 670
 671 /* simulate spin locks */
 672typedef struct {
 673        volatile char lock;
 674} spinlock_t;
 675
 676#define spin_lock_init(x) { (x)->lock = 0;}
 677#define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
 678                                        (x)->lock=1; save_flags(flags);\
 679                                        cli();}
 680#define spin_unlock_irqrestore(x,flags) { (x)->lock=0; restore_flags(flags);}
 681
 682#define DECLARE_WAIT_QUEUE_HEAD(x)      struct wait_queue *x = NULL
 683
 684#endif
 685
 686
 687#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* 0x020400 */
 688#define dma_alloc_consistent pci_alloc_consistent
 689#define dma_free_consistent pci_free_consistent
 690#else
 691#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,19) /* 0x020219 */
 692typedef unsigned long dma_addr_t;
 693#endif
 694void *dma_alloc_consistent(void *, size_t, dma_addr_t *);
 695void dma_free_consistent(void *, size_t, void *, dma_addr_t);
 696int mega_get_order(int);
 697int pow_2(int);
 698#endif
 699
 700/* set SERDEBUG to 1 to enable serial debugging */
 701#define SERDEBUG 0
 702#if SERDEBUG
 703static void ser_init (void);
 704static void ser_puts (char *str);
 705static void ser_putc (char c);
 706static int ser_printk (const char *fmt, ...);
 707#endif
 708
 709#ifdef CONFIG_PROC_FS
 710#define COPY_BACK if (offset > megaCfg->procidx) { \
 711                *eof = TRUE; \
 712        megaCfg->procidx = 0; \
 713        megaCfg->procbuf[0] = 0; \
 714        return 0;} \
 715 if ((count + offset) > megaCfg->procidx) { \
 716      count = megaCfg->procidx - offset; \
 717      *eof = TRUE; } \
 718      memcpy(page, &megaCfg->procbuf[offset], count); \
 719      megaCfg->procidx = 0; \
 720      megaCfg->procbuf[0] = 0;
 721#endif
 722
 723/*
 724 * ================================================================
 725 *                    Global variables
 726 *================================================================
 727 */
 728
 729/*  Use "megaraid=skipXX" as LILO option to prohibit driver from scanning
 730    XX scsi id on each channel.  Used for Madrona motherboard, where SAF_TE
 731    processor id cannot be scanned */
 732
 733static char *megaraid;
 734#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)  /* 0x20100 */
 735#ifdef MODULE
 736MODULE_PARM (megaraid, "s");
 737#endif
 738#endif
 739static int skip_id = -1;
 740static int numCtlrs = 0;
 741static mega_host_config *megaCtlrs[FC_MAX_CHANNELS] = { 0 };
 742static struct proc_dir_entry *mega_proc_dir_entry;
 743
 744#if DEBUG
 745static u32 maxCmdTime = 0;
 746#endif
 747
 748static mega_scb *pLastScb = NULL;
 749static struct notifier_block mega_notifier = {
 750        megaraid_reboot_notify,
 751        NULL,
 752        0
 753};
 754
 755/* For controller re-ordering */
 756struct mega_hbas mega_hbas[MAX_CONTROLLERS];
 757
 758/*
 759 * The File Operations structure for the serial/ioctl interface of the driver
 760 */
 761/* For controller re-ordering */ 
 762
 763static struct file_operations megadev_fops = {
 764        .owner                  = THIS_MODULE,
 765        .ioctl                  = megadev_ioctl_entry,
 766};
 767
 768/*
 769 * Array to structures for storing the information about the controllers. This
 770 * information is sent to the user level applications, when they do an ioctl
 771 * for this information.
 772 */
 773static struct mcontroller mcontroller[MAX_CONTROLLERS];
 774
 775/* The current driver version */
 776static u32 driver_ver = 114;
 777
 778/* major number used by the device for character interface */
 779static int major;
 780
 781static struct semaphore mimd_ioctl_sem;
 782static struct semaphore mimd_entry_mtx;
 783
 784#if SERDEBUG
 785volatile static spinlock_t serial_lock;
 786#endif
 787
 788#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)  /* 0x20300 */
 789static struct proc_dir_entry proc_scsi_megaraid = {
 790        PROC_SCSI_MEGARAID, 8, "megaraid",
 791        S_IFDIR | S_IRUGO | S_IXUGO, 2
 792};
 793#endif
 794
 795#ifdef CONFIG_PROC_FS
 796extern struct proc_dir_entry proc_root;
 797#endif
 798
 799static char mega_ch_class;      /* channels are raid or scsi */
 800#define IS_RAID_CH(ch)  ( (mega_ch_class >> (ch)) & 0x01 )
 801
 802#if SERDEBUG
 803static char strbuf[MAX_SERBUF + 1];
 804
 805static void ser_init (void)
 806{
 807        unsigned port = COM_BASE;
 808
 809        outb (0x80, port + 3);
 810        outb (0, port + 1);
 811        /* 9600 Baud, if 19200: outb(6,port) */
 812        outb (12, port);
 813        outb (3, port + 3);
 814        outb (0, port + 1);
 815}
 816
 817static void ser_puts (char *str)
 818{
 819        char *ptr;
 820
 821        ser_init ();
 822        for (ptr = str; *ptr; ++ptr)
 823                ser_putc (*ptr);
 824}
 825
 826static void ser_putc (char c)
 827{
 828        unsigned port = COM_BASE;
 829
 830        while ((inb (port + 5) & 0x20) == 0) ;
 831        outb (c, port);
 832        if (c == 0x0a) {
 833                while ((inb (port + 5) & 0x20) == 0) ;
 834                outb (0x0d, port);
 835        }
 836}
 837
 838static int ser_printk (const char *fmt, ...)
 839{
 840        va_list args;
 841        int i;
 842        long flags;
 843
 844        spin_lock_irqsave (&serial_lock, flags);
 845        va_start (args, fmt);
 846        i = vsprintf (strbuf, fmt, args);
 847        ser_puts (strbuf);
 848        va_end (args);
 849        spin_unlock_irqrestore (&serial_lock, flags);
 850
 851        return i;
 852}
 853
 854#define TRACE(a)    { ser_printk a;}
 855
 856#else
 857#define TRACE(A)
 858#endif
 859
 860#define TRACE1(a)
 861
 862static void callDone (Scsi_Cmnd * SCpnt)
 863{
 864        if (SCpnt->result) {
 865                TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n",
 866                        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
 867                        SCpnt->target, SCpnt->lun, SCpnt->result));
 868        }
 869        SCpnt->scsi_done (SCpnt);
 870}
 871
 872/*-------------------------------------------------------------------------
 873 *
 874 *                      Local functions
 875 *
 876 *-------------------------------------------------------------------------*/
 877
 878/*=======================
 879 * Free a SCB structure
 880 *=======================
 881 */
 882static void mega_freeSCB (mega_host_config * megaCfg, mega_scb * pScb)
 883{
 884
 885        mega_scb *pScbtmp;
 886
 887        if ((pScb == NULL) || (pScb->idx >= 0xFE)) {
 888                return;
 889        }
 890#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 891        switch (pScb->dma_type) {
 892        case M_RD_DMA_TYPE_NONE:
 893                break;
 894        case M_RD_PTHRU_WITH_BULK_DATA:
 895                pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,
 896                                  pScb->pthru->dataxferlen,
 897                                  pScb->dma_direction);
 898                break;
 899        case M_RD_EPTHRU_WITH_BULK_DATA:
 900                pci_unmap_single (megaCfg->dev, pScb->dma_h_bulkdata,
 901                                  pScb->epthru->dataxferlen,
 902                                  pScb->dma_direction);
 903                break;
 904        case M_RD_PTHRU_WITH_SGLIST:
 905        {
 906                int count;
 907                for (count = 0; count < pScb->sglist_count; count++) {
 908                        pci_unmap_single (megaCfg->dev,
 909                                          pScb->dma_h_sglist[count],
 910                                          pScb->sgList[count].length,
 911                                          pScb->dma_direction);
 912
 913                }
 914                break;
 915        }
 916        case M_RD_BULK_DATA_ONLY:
 917                pci_unmap_single (megaCfg->dev,
 918                                  pScb->dma_h_bulkdata,
 919                                  pScb->iDataSize, pScb->dma_direction);
 920
 921                break;
 922        case M_RD_SGLIST_ONLY:
 923                pci_unmap_sg (megaCfg->dev,
 924                              pScb->SCpnt->request_buffer,
 925                              pScb->SCpnt->use_sg, pScb->dma_direction);
 926                break;
 927        default:
 928                break;
 929        }
 930#endif
 931
 932        /* Unlink from pending queue */
 933        if (pScb == megaCfg->qPendingH) {
 934
 935                if (megaCfg->qPendingH == megaCfg->qPendingT)
 936                        megaCfg->qPendingH = megaCfg->qPendingT = NULL;
 937                else
 938                        megaCfg->qPendingH = megaCfg->qPendingH->next;
 939
 940                megaCfg->qPcnt--;
 941
 942        } else {
 943                for (pScbtmp = megaCfg->qPendingH; pScbtmp;
 944                     pScbtmp = pScbtmp->next) {
 945
 946                        if (pScbtmp->next == pScb) {
 947
 948                                pScbtmp->next = pScb->next;
 949
 950                                if (pScb == megaCfg->qPendingT) {
 951                                        megaCfg->qPendingT = pScbtmp;
 952                                }
 953
 954                                megaCfg->qPcnt--;
 955                                break;
 956                        }
 957                }
 958        }
 959
 960        /* Link back into free list */
 961        pScb->state = SCB_FREE;
 962        pScb->SCpnt = NULL;
 963
 964        if (megaCfg->qFreeH == (mega_scb *) NULL) {
 965                megaCfg->qFreeH = megaCfg->qFreeT = pScb;
 966        } else {
 967                megaCfg->qFreeT->next = pScb;
 968                megaCfg->qFreeT = pScb;
 969        }
 970
 971        megaCfg->qFreeT->next = NULL;
 972        megaCfg->qFcnt++;
 973
 974}
 975
 976/*===========================
 977 * Allocate a SCB structure
 978 *===========================
 979 */
 980static mega_scb *mega_allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 981{
 982        mega_scb *pScb;
 983
 984        /* Unlink command from Free List */
 985        if ((pScb = megaCfg->qFreeH) != NULL) {
 986                megaCfg->qFreeH = pScb->next;
 987                megaCfg->qFcnt--;
 988
 989                pScb->isrcount = jiffies;
 990                pScb->next = NULL;
 991                pScb->state = SCB_ACTIVE;
 992                pScb->SCpnt = SCpnt;
 993
 994#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 995                pScb->dma_type = M_RD_DMA_TYPE_NONE;
 996#endif
 997
 998                return pScb;
 999        }
1000
1001        printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
1002
1003        return NULL;
1004}
1005
1006/* Run through the list of completed requests  and finish it */
1007static void mega_rundoneq (mega_host_config * megaCfg)
1008{
1009        Scsi_Cmnd *SCpnt;
1010
1011        while ((SCpnt = megaCfg->qCompletedH) != NULL) {
1012                megaCfg->qCompletedH = (Scsi_Cmnd *) SCpnt->host_scribble;
1013                megaCfg->qCcnt--;
1014
1015                SCpnt->host_scribble = (unsigned char *) NULL;  /* XC : sep 14 */
1016                /* Callback */
1017                callDone (SCpnt);
1018        }
1019
1020        megaCfg->qCompletedH = megaCfg->qCompletedT = NULL;
1021}
1022
1023/*
1024 * Runs through the list of pending requests
1025 * Assumes that mega_lock spin_lock has been acquired.
1026 */
1027static int mega_runpendq (mega_host_config * megaCfg)
1028{
1029        mega_scb *pScb;
1030        int rc;
1031
1032        /* Issue any pending commands to the card */
1033        for (pScb = megaCfg->qPendingH; pScb; pScb = pScb->next) {
1034                if (pScb->state == SCB_ACTIVE) {
1035                        if ((rc =
1036                             megaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) == -1)
1037                                return rc;
1038                }
1039        }
1040        return 0;
1041}
1042
1043/* Add command to the list of completed requests */
1044
1045static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status)
1046{
1047        int islogical;
1048        Scsi_Cmnd *SCpnt;
1049        mega_passthru *pthru;
1050        mega_ext_passthru *epthru;
1051        mega_mailbox *mbox;
1052        struct scatterlist *sgList;
1053        u8      c;
1054
1055        if (pScb == NULL) {
1056                TRACE (("NULL pScb in mega_cmd_done!"));
1057                printk(KERN_CRIT "NULL pScb in mega_cmd_done!");
1058        }
1059
1060        SCpnt = pScb->SCpnt;
1061
1062#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1063        pthru = pScb->pthru;
1064        epthru = pScb->epthru;
1065#else
1066        pthru = &pScb->pthru;
1067        epthru = &pScb->epthru;
1068#endif
1069
1070        mbox = (mega_mailbox *) & pScb->mboxData;
1071
1072        if (SCpnt == NULL) {
1073                TRACE (("NULL SCpnt in mega_cmd_done!"));
1074                TRACE (("pScb->idx = ", pScb->idx));
1075                TRACE (("pScb->state = ", pScb->state));
1076                TRACE (("pScb->state = ", pScb->state));
1077                panic(KERN_ERR "megaraid:Problem...!\n");
1078        }
1079
1080        islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
1081                                        (SCpnt->channel <= megaCfg->host->max_channel) );
1082#if 0
1083        islogical = (SCpnt->channel == megaCfg->host->max_channel);
1084#endif
1085
1086#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1087        /* Special Case to handle PassThrough->XferAddrress > 4GB */
1088        switch (SCpnt->cmnd[0]) {
1089        case INQUIRY:
1090        case READ_CAPACITY:
1091                memcpy (SCpnt->request_buffer,
1092                        pScb->bounce_buffer, SCpnt->request_bufflen);
1093                break;
1094        }
1095#endif
1096
1097        mega_freeSCB (megaCfg, pScb);
1098
1099        /*
1100         * Do not return the presence of hard disk on the channel so, inquiry
1101         * sent, and returned data==hard disk or removable hard disk and not
1102         * logical, request should return failure! - PJ
1103         */
1104#if 0
1105        if (SCpnt->cmnd[0] == INQUIRY && ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) && !islogical) {
1106                status = 0xF0;
1107        }
1108#endif
1109        
1110        if (SCpnt->cmnd[0] == INQUIRY && !islogical) {
1111                if ( SCpnt->use_sg ) {
1112                        sgList = (struct scatterlist *)SCpnt->request_buffer;
1113                        memcpy(&c, cpu_to_le32(sg_dma_address(&sgList[0])), 0x1);
1114                } else {
1115                        memcpy(&c, SCpnt->request_buffer, 0x1);
1116                }
1117#if 0
1118                if( (c & 0x1F ) == TYPE_DISK ) {
1119                        status = 0xF0;
1120                }
1121#endif
1122                if( IS_RAID_CH(SCpnt->channel) && ((c & 0x1F ) == TYPE_DISK) ) {
1123                        status = 0xF0;
1124                }
1125        }
1126
1127
1128        /* clear result; otherwise, success returns corrupt value */
1129        SCpnt->result = 0;
1130
1131        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 */
1132                switch (status) {
1133                case 2:
1134                case 0xF0:
1135                case 0xF4:
1136                        SCpnt->result = (DID_BAD_TARGET << 16) | status;
1137                        break;
1138                default:
1139                        SCpnt->result |= status;
1140                }               /*end of switch */
1141        } else {
1142                /* Convert MegaRAID status to Linux error code */
1143                switch (status) {
1144                case 0x00:      /* SUCCESS , i.e. SCSI_STATUS_GOOD */
1145                        SCpnt->result |= (DID_OK << 16);
1146                        break;
1147
1148                case 0x02:      /* ERROR_ABORTED, i.e. SCSI_STATUS_CHECK_CONDITION */
1149
1150                        /*set sense_buffer and result fields */
1151                        if (mbox->cmd == MEGA_MBOXCMD_PASSTHRU) {
1152                                memcpy (SCpnt->sense_buffer, pthru->reqsensearea, 14);
1153                        } else if (mbox->cmd == MEGA_MBOXCMD_EXTPASSTHRU) {
1154                                SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION < 1);
1155                                memcpy(
1156                                        SCpnt->sense_buffer,
1157                                        epthru->reqsensearea, 14
1158                                );
1159                                SCpnt->result = (DRIVER_SENSE << 24) | (DID_OK << 16) | (CHECK_CONDITION < 1);
1160                                /*SCpnt->result =
1161                                        (DRIVER_SENSE << 24) |
1162                                        (DID_ERROR << 16) | status;*/
1163                        } else {
1164                                SCpnt->sense_buffer[0] = 0x70;
1165                                SCpnt->sense_buffer[2] = ABORTED_COMMAND;
1166                                SCpnt->result |= (CHECK_CONDITION << 1);
1167                        }
1168                        break;
1169
1170                case 0x08:      /* ERR_DEST_DRIVE_FAILED, i.e. SCSI_STATUS_BUSY */
1171                        SCpnt->result |= (DID_BUS_BUSY << 16) | status;
1172                        break;
1173
1174                default:
1175                        SCpnt->result |= (DID_BAD_TARGET << 16) | status;
1176                        break;
1177                }
1178        }
1179
1180        /* Add Scsi_Command to end of completed queue */
1181        if (megaCfg->qCompletedH == NULL) {
1182                megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
1183        } else {
1184                megaCfg->qCompletedT->host_scribble = (unsigned char *) SCpnt;
1185                megaCfg->qCompletedT = SCpnt;
1186        }
1187
1188        megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
1189        megaCfg->qCcnt++;
1190}
1191
1192/*-------------------------------------------------------------------
1193 *
1194 *                 Build a SCB from a Scsi_Cmnd
1195 *
1196 * Returns a SCB pointer, or NULL
1197 * If NULL is returned, the scsi_done function MUST have been called
1198 *
1199 *-------------------------------------------------------------------*/
1200
1201static mega_scb *mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1202{
1203        mega_scb *pScb;
1204        mega_mailbox *mbox;
1205        mega_passthru *pthru;
1206        mega_ext_passthru *epthru;
1207        long seg;
1208        char islogical;
1209        int lun = SCpnt->lun;
1210        int             max_lun;
1211
1212        if ((SCpnt->cmnd[0] == MEGADEVIOC))
1213                return megadev_doioctl (megaCfg, SCpnt);
1214
1215        if ((SCpnt->cmnd[0] == M_RD_IOCTL_CMD)
1216                    || (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW))
1217#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  
1218                return mega_ioctl (megaCfg, SCpnt);     /* Handle IOCTL command */
1219#else
1220        {
1221                printk(KERN_WARNING "megaraid ioctl: older interface - "
1222                                "not supported.\n");
1223                return NULL;
1224        }
1225#endif
1226
1227        islogical = ( (SCpnt->channel >= megaCfg->productInfo.SCSIChanPresent) &&
1228                                        (SCpnt->channel <= megaCfg->host->max_channel) );
1229#if 0
1230        islogical = (IS_RAID_CH(SCpnt->channel) && /* virtual ch is raid - AM */
1231                                                (SCpnt->channel == megaCfg->host->max_channel));
1232#endif
1233
1234        if ( ! megaCfg->support_ext_cdb ) {
1235                if (!islogical && lun != 0) {
1236                        SCpnt->result = (DID_BAD_TARGET << 16);
1237                        callDone (SCpnt);
1238                        return NULL;
1239                }
1240        }
1241
1242        if (!islogical && SCpnt->target == skip_id) {
1243                SCpnt->result = (DID_BAD_TARGET << 16);
1244                callDone (SCpnt);
1245                return NULL;
1246        }
1247
1248        if (islogical) {
1249
1250                /* have just LUN 0 for each target on virtual channels */
1251                if( SCpnt->lun != 0 ) {
1252                        SCpnt->result = (DID_BAD_TARGET << 16);
1253                        callDone (SCpnt);
1254                        return NULL;
1255                }
1256
1257                lun = mega_get_lun(megaCfg, SCpnt);
1258
1259            max_lun = (megaCfg->flag & BOARD_40LD) ?
1260                                                FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
1261
1262                 /*
1263                  * max_lun increases by 0x80 if some logical drive was deleted.
1264                  */
1265                if(megaCfg->read_ldidmap) {
1266                        max_lun += 0x80;
1267                }
1268
1269                if( lun > max_lun ) {
1270                        SCpnt->result = (DID_BAD_TARGET << 16);
1271                        callDone (SCpnt);
1272                        return NULL;
1273                }
1274
1275                /*
1276                 * If we have a logical drive with boot enabled, project it first
1277                 */
1278                if( megaCfg->boot_ldrv_enabled ) {
1279                        if( lun == 0 ) {
1280                                lun = megaCfg->boot_ldrv;
1281                        }
1282                        else {
1283                                if( lun <= megaCfg->boot_ldrv ) {
1284                                        lun--;
1285                                }
1286                        }
1287                }
1288        } else {
1289                if ( lun > 7) {
1290                                /* Do not support lun >7 for physically accessed devices */
1291                        SCpnt->result = (DID_BAD_TARGET << 16);
1292                        callDone (SCpnt);
1293                        return NULL;
1294                }
1295        }
1296        /*-----------------------------------------------------
1297         *
1298         *               Logical drive commands
1299         *
1300         *-----------------------------------------------------*/
1301        if (islogical) {
1302                switch (SCpnt->cmnd[0]) {
1303                case TEST_UNIT_READY:
1304                        memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
1305                        SCpnt->result = (DID_OK << 16);
1306                        callDone (SCpnt);
1307                        return NULL;
1308
1309                case MODE_SENSE:
1310                        memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
1311                        SCpnt->result = (DID_OK << 16);
1312                        callDone (SCpnt);
1313                        return NULL;
1314
1315                case READ_CAPACITY:
1316                case INQUIRY:
1317                        /* Allocate a SCB and initialize passthru */
1318                        if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1319                                SCpnt->result = (DID_ERROR << 16);
1320                                callDone (SCpnt);
1321                                return NULL;
1322                        }
1323#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1324                        pthru = pScb->pthru;
1325#else
1326                        pthru = &pScb->pthru;
1327#endif
1328
1329                        mbox = (mega_mailbox *) & pScb->mboxData;
1330                        memset (mbox, 0, sizeof (pScb->mboxData));
1331                        memset (pthru, 0, sizeof (mega_passthru));
1332                        pthru->timeout = 0;
1333                        pthru->ars = 1;
1334                        pthru->reqsenselen = 14;
1335                        pthru->islogical = 1;
1336                        pthru->logdrv = lun;
1337                        pthru->cdblen = SCpnt->cmd_len;
1338
1339#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1340                        /*Not sure about the direction */
1341                        pScb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1342                        pScb->dma_type = M_RD_PTHRU_WITH_BULK_DATA;
1343
1344#if 0
1345/* Normal Code w/o the need for bounce buffer */
1346                        pScb->dma_h_bulkdata
1347                            = pci_map_single (megaCfg->dev,
1348                                              SCpnt->request_buffer,
1349                                              SCpnt->request_bufflen,
1350                                              pScb->dma_direction);
1351
1352                        pthru->dataxferaddr = pScb->dma_h_bulkdata;
1353#else
1354/* Special Code to use bounce buffer for READ_CAPA/INQ */
1355                        pthru->dataxferaddr = pScb->dma_bounce_buffer;
1356                        pScb->dma_type = M_RD_DMA_TYPE_NONE;
1357#endif
1358
1359#else
1360                        pthru->dataxferaddr =
1361                            virt_to_bus (SCpnt->request_buffer);
1362#endif
1363
1364                        pthru->dataxferlen = SCpnt->request_bufflen;
1365                        memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
1366
1367                        /* Initialize mailbox area */
1368                        mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1369
1370#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1371                        mbox->xferaddr = pScb->dma_passthruhandle64;
1372                        TRACE1 (("M_RD_PTHRU_WITH_BULK_DATA Enabled \n"));
1373#else
1374                        mbox->xferaddr = virt_to_bus (pthru);
1375#endif
1376                        return pScb;
1377
1378                case READ_6:
1379                case WRITE_6:
1380                case READ_10:
1381                case WRITE_10:
1382                        /* Allocate a SCB and initialize mailbox */
1383                        if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1384                                SCpnt->result = (DID_ERROR << 16);
1385                                callDone (SCpnt);
1386                                return NULL;
1387                        }
1388                        mbox = (mega_mailbox *) & pScb->mboxData;
1389
1390                        memset (mbox, 0, sizeof (pScb->mboxData));
1391                        mbox->logdrv = lun;
1392
1393                        if (megaCfg->flag & BOARD_64BIT) {
1394                                mbox->cmd = (*SCpnt->cmnd == READ_6
1395                                             || *SCpnt->cmnd ==
1396                                             READ_10) ? MEGA_MBOXCMD_LREAD64 :
1397                                    MEGA_MBOXCMD_LWRITE64;
1398                        } else {
1399                                mbox->cmd = (*SCpnt->cmnd == READ_6
1400                                             || *SCpnt->cmnd ==
1401                                             READ_10) ? MEGA_MBOXCMD_LREAD :
1402                                    MEGA_MBOXCMD_LWRITE;
1403                        }
1404
1405                        /* 6-byte */
1406                        if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
1407                                mbox->numsectors = (u32) SCpnt->cmnd[4];
1408                                mbox->lba =
1409                                    ((u32) SCpnt->cmnd[1] << 16) |
1410                                    ((u32) SCpnt->cmnd[2] << 8) |
1411                                    (u32) SCpnt->cmnd[3];
1412                                mbox->lba &= 0x1FFFFF;
1413
1414                                if (*SCpnt->cmnd == READ_6) {
1415                                        megaCfg->nReads[(int) lun]++;
1416                                        megaCfg->nReadBlocks[(int) lun] +=
1417                                            mbox->numsectors;
1418                                } else {
1419                                        megaCfg->nWrites[(int) lun]++;
1420                                        megaCfg->nWriteBlocks[(int) lun] +=
1421                                            mbox->numsectors;
1422                                }
1423                        }
1424
1425                        /* 10-byte */
1426                        if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
1427                                mbox->numsectors =
1428                                    (u32) SCpnt->cmnd[8] |
1429                                    ((u32) SCpnt->cmnd[7] << 8);
1430                                mbox->lba =
1431                                    ((u32) SCpnt->cmnd[2] << 24) |
1432                                    ((u32) SCpnt->cmnd[3] << 16) |
1433                                    ((u32) SCpnt->cmnd[4] << 8) |
1434                                    (u32) SCpnt->cmnd[5];
1435
1436                                if (*SCpnt->cmnd == READ_10) {
1437                                        megaCfg->nReads[(int) lun]++;
1438                                        megaCfg->nReadBlocks[(int) lun] +=
1439                                            mbox->numsectors;
1440                                } else {
1441                                        megaCfg->nWrites[(int) lun]++;
1442                                        megaCfg->nWriteBlocks[(int) lun] +=
1443                                            mbox->numsectors;
1444                                }
1445                        }
1446
1447                        /* 12-byte */
1448                        if (*SCpnt->cmnd == READ_12 || *SCpnt->cmnd == WRITE_12) {
1449                                mbox->lba =
1450                                    ((u32) SCpnt->cmnd[2] << 24) |
1451                                    ((u32) SCpnt->cmnd[3] << 16) |
1452                                    ((u32) SCpnt->cmnd[4] << 8) |
1453                                    (u32) SCpnt->cmnd[5];
1454
1455                                mbox->numsectors =
1456                                    ((u32) SCpnt->cmnd[6] << 24) |
1457                                    ((u32) SCpnt->cmnd[7] << 16) |
1458                                    ((u32) SCpnt->cmnd[8] << 8) |
1459                                    (u32) SCpnt->cmnd[9];
1460
1461                                if (*SCpnt->cmnd == READ_12) {
1462                                        megaCfg->nReads[(int) lun]++;
1463                                        megaCfg->nReadBlocks[(int) lun] +=
1464                                            mbox->numsectors;
1465                                } else {
1466                                        megaCfg->nWrites[(int) lun]++;
1467                                        megaCfg->nWriteBlocks[(int) lun] +=
1468                                            mbox->numsectors;
1469                                }
1470                        }
1471
1472#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1473                        if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10
1474                                        || *SCpnt->cmnd == READ_12) {
1475                                pScb->dma_direction = PCI_DMA_FROMDEVICE;
1476                        } else {        /*WRITE_6 or WRITE_10 */
1477                                pScb->dma_direction = PCI_DMA_TODEVICE;
1478                        }
1479#endif
1480
1481                        /* Calculate Scatter-Gather info */
1482                        mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
1483                                                                 (u32 *)&mbox->xferaddr, (u32 *)&seg);
1484
1485#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1486                        pScb->iDataSize = seg;
1487
1488                        if (mbox->numsgelements) {
1489                                pScb->dma_type = M_RD_SGLIST_ONLY;
1490                                TRACE1 (("M_RD_SGLIST_ONLY Enabled \n"));
1491                        } else {
1492                                pScb->dma_type = M_RD_BULK_DATA_ONLY;
1493                                TRACE1 (("M_RD_BULK_DATA_ONLY Enabled \n"));
1494                        }
1495#endif
1496
1497                        return pScb;
1498                default:
1499                        SCpnt->result = (DID_BAD_TARGET << 16);
1500                        callDone (SCpnt);
1501                        return NULL;
1502                }
1503        }
1504        /*-----------------------------------------------------
1505         *
1506         *               Passthru drive commands
1507         *
1508         *-----------------------------------------------------*/
1509        else {
1510                /* Allocate a SCB and initialize passthru */
1511                if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1512                        SCpnt->result = (DID_ERROR << 16);
1513                        callDone (SCpnt);
1514                        return NULL;
1515                }
1516
1517                mbox = (mega_mailbox *) pScb->mboxData;
1518                memset (mbox, 0, sizeof (pScb->mboxData));
1519
1520                if ( megaCfg->support_ext_cdb && SCpnt->cmd_len > 10 ) {
1521                        epthru = mega_prepare_extpassthru(megaCfg, pScb, SCpnt);
1522                        mbox->cmd = MEGA_MBOXCMD_EXTPASSTHRU;
1523#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1524                        mbox->xferaddr = pScb->dma_ext_passthruhandle64;
1525
1526                        if(epthru->numsgelements) {
1527                                pScb->dma_type = M_RD_PTHRU_WITH_SGLIST;
1528                        } else {
1529                                pScb->dma_type = M_RD_EPTHRU_WITH_BULK_DATA;
1530                        }
1531#else
1532                        mbox->xferaddr = virt_to_bus(epthru);
1533#endif
1534                }
1535                else {
1536                        pthru = mega_prepare_passthru(megaCfg, pScb, SCpnt);
1537
1538                        /* Initialize mailbox */
1539                        mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1540#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1541                        mbox->xferaddr = pScb->dma_passthruhandle64;
1542
1543                        if (pthru->numsgelements) {
1544                                pScb->dma_type = M_RD_PTHRU_WITH_SGLIST;
1545                        } else {
1546                                pScb->dma_type = M_RD_PTHRU_WITH_BULK_DATA;
1547                        }
1548#else
1549                        mbox->xferaddr = virt_to_bus(pthru);
1550#endif
1551                }
1552                return pScb;
1553        }
1554        return NULL;
1555}
1556
1557static int
1558mega_get_lun(mega_host_config *this_hba, Scsi_Cmnd *sc)
1559{
1560        int             tgt;
1561        int             lun;
1562        int             virt_chan;
1563
1564        tgt = sc->target;
1565        
1566        if ( tgt > 7 ) tgt--;   /* we do not get inquires for tgt 7 */
1567
1568        virt_chan = sc->channel - this_hba->productInfo.SCSIChanPresent;
1569        lun = (virt_chan * 15) + tgt;
1570
1571        /*
1572         * If "delete logical drive" feature is enabled on this controller.
1573         * Do only if at least one delete logical drive operation was done.
1574         *
1575         * Also, after logical drive deletion, instead of logical drive number,
1576         * the value returned should be 0x80+logical drive id.
1577         *
1578         * These is valid only for IO commands.
1579         */
1580
1581         if( this_hba->support_random_del && this_hba->read_ldidmap ) {
1582                switch(sc->cmnd[0]) {
1583                case READ_6:    /* fall through */
1584                case WRITE_6:   /* fall through */
1585                case READ_10:   /* fall through */
1586                case WRITE_10:
1587                        lun += 0x80;
1588                }
1589         }
1590
1591         return lun;
1592}
1593
1594
1595static mega_passthru *
1596mega_prepare_passthru(mega_host_config *megacfg, mega_scb *scb, Scsi_Cmnd *sc)
1597{
1598        mega_passthru *pthru;
1599
1600#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1601        pthru = scb->pthru;
1602#else
1603        pthru = &scb->pthru;
1604#endif
1605        memset (pthru, 0, sizeof (mega_passthru));
1606
1607        /* set adapter timeout value to 10 min. for tape drive  */
1608        /* 0=6sec/1=60sec/2=10min/3=3hrs                        */
1609        pthru->timeout = 2;
1610        pthru->ars = 1;
1611        pthru->reqsenselen = 14;
1612        pthru->islogical = 0;
1613        pthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
1614        pthru->target = (megacfg->flag & BOARD_40LD) ?
1615            (sc->channel << 4) | sc->target : sc->target;
1616        pthru->cdblen = sc->cmd_len;
1617        pthru->logdrv = sc->lun;
1618
1619        memcpy (pthru->cdb, sc->cmnd, sc->cmd_len);
1620
1621#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1622        /* Not sure about the direction */
1623        scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1624
1625        /* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
1626        switch (sc->cmnd[0]) {
1627        case INQUIRY:
1628        case READ_CAPACITY:
1629                pthru->numsgelements = 0;
1630                pthru->dataxferaddr = scb->dma_bounce_buffer;
1631                pthru->dataxferlen = sc->request_bufflen;
1632                break;
1633        default:
1634                pthru->numsgelements =
1635                        mega_build_sglist(
1636                                megacfg, scb, (u32 *)&pthru->dataxferaddr,
1637                                (u32 *)&pthru->dataxferlen
1638                        );
1639                break;
1640        }
1641#else
1642        pthru->numsgelements =
1643                mega_build_sglist(
1644                        megacfg, scb, (u32 *)&pthru->dataxferaddr,
1645                        (u32 *)&pthru->dataxferlen
1646                );
1647#endif
1648        return pthru;
1649}
1650
1651static mega_ext_passthru *
1652mega_prepare_extpassthru(mega_host_config *megacfg, mega_scb *scb, Scsi_Cmnd *sc)
1653{
1654        mega_ext_passthru *epthru;
1655
1656#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1657        epthru = scb->epthru;
1658#else
1659        epthru = &scb->epthru;
1660#endif
1661        memset(epthru, 0, sizeof(mega_ext_passthru));
1662
1663        /* set adapter timeout value to 10 min. for tape drive  */
1664        /* 0=6sec/1=60sec/2=10min/3=3hrs                        */
1665        epthru->timeout = 2;
1666        epthru->ars = 1;
1667        epthru->reqsenselen = 14;
1668        epthru->islogical = 0;
1669        epthru->channel = (megacfg->flag & BOARD_40LD) ? 0 : sc->channel;
1670        epthru->target = (megacfg->flag & BOARD_40LD) ?
1671            (sc->channel << 4) | sc->target : sc->target;
1672        epthru->cdblen = sc->cmd_len;
1673        epthru->logdrv = sc->lun;
1674
1675        memcpy(epthru->cdb, sc->cmnd, sc->cmd_len);
1676
1677#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1678        /* Not sure about the direction */
1679        scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1680
1681        /* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
1682        switch (sc->cmnd[0]) {
1683        case INQUIRY:
1684        case READ_CAPACITY:
1685                epthru->numsgelements = 0;
1686                epthru->dataxferaddr = scb->dma_bounce_buffer;
1687                epthru->dataxferlen = sc->request_bufflen;
1688                break;
1689        default:
1690                epthru->numsgelements =
1691                        mega_build_sglist(
1692                                megacfg, scb, (u32 *)&epthru->dataxferaddr,
1693                                (u32 *)&epthru->dataxferlen
1694                        );
1695                break;
1696        }
1697#else
1698        epthru->numsgelements =
1699                mega_build_sglist(
1700                        megacfg, scb, (u32 *)&epthru->dataxferaddr,
1701                        (u32 *)&epthru->dataxferlen
1702                );
1703#endif
1704        return epthru;
1705}
1706
1707/* Handle Driver Level IOCTLs
1708 * Return value of 0 indicates this function could not handle , so continue
1709 * processing
1710*/
1711
1712static int mega_driver_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1713{
1714        unsigned char *data = (unsigned char *) SCpnt->request_buffer;
1715        mega_driver_info driver_info;
1716
1717        /* If this is not our command dont do anything */
1718        if (SCpnt->cmnd[0] != M_RD_DRIVER_IOCTL_INTERFACE)
1719                return 0;
1720
1721        switch (SCpnt->cmnd[1]) {
1722        case GET_DRIVER_INFO:
1723                if (SCpnt->request_bufflen < sizeof (driver_info)) {
1724                        SCpnt->result = DID_BAD_TARGET << 16;
1725                        callDone (SCpnt);
1726                        return 1;
1727                }
1728
1729                driver_info.size = sizeof (driver_info) - sizeof (int);
1730                driver_info.version = MEGARAID_IOCTL_VERSION;
1731                memcpy (data, &driver_info, sizeof (driver_info));
1732                break;
1733        default:
1734                SCpnt->result = DID_BAD_TARGET << 16;
1735        }
1736
1737        callDone (SCpnt);
1738        return 1;
1739}
1740
1741static inline void set_mbox_xfer_addr (mega_host_config * megaCfg, mega_scb * pScb,
1742                    mega_ioctl_mbox * mbox, u32 direction)
1743{
1744
1745#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
1746        switch (direction) {
1747        case TO_DEVICE:
1748                pScb->dma_direction = PCI_DMA_TODEVICE;
1749                break;
1750        case FROM_DEVICE:
1751                pScb->dma_direction = PCI_DMA_FROMDEVICE;
1752                break;
1753        case FROMTO_DEVICE:
1754                pScb->dma_direction = PCI_DMA_BIDIRECTIONAL;
1755                break;
1756        }
1757
1758        pScb->dma_h_bulkdata
1759            = pci_map_single (megaCfg->dev,
1760                              pScb->buff_ptr,
1761                              pScb->iDataSize, pScb->dma_direction);
1762        mbox->xferaddr = pScb->dma_h_bulkdata;
1763        pScb->dma_type = M_RD_BULK_DATA_ONLY;
1764        TRACE1 (("M_RD_BULK_DATA_ONLY Enabled \n"));
1765#else
1766        mbox->xferaddr = virt_to_bus (pScb->buff_ptr);
1767#endif
1768}
1769
1770#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
1771
1772/*--------------------------------------------------------------------
1773 * build RAID commands for controller, passed down through ioctl()
1774 *--------------------------------------------------------------------*/
1775static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
1776{
1777        mega_scb *pScb;
1778        mega_ioctl_mbox *mbox;
1779        mega_mailbox *mailbox;
1780        mega_passthru *pthru;
1781        u8 *mboxdata;
1782        long seg, i = 0;
1783        unsigned char *data = (unsigned char *) SCpnt->request_buffer;
1784
1785        if ((pScb = mega_allocateSCB (megaCfg, SCpnt)) == NULL) {
1786                SCpnt->result = (DID_ERROR << 16);
1787                callDone (SCpnt);
1788                return NULL;
1789        }
1790        pthru = &pScb->pthru;
1791
1792        mboxdata = (u8 *) & pScb->mboxData;
1793        mbox = (mega_ioctl_mbox *) & pScb->mboxData;
1794        mailbox = (mega_mailbox *) & pScb->mboxData;
1795        memset (mailbox, 0, sizeof (pScb->mboxData));
1796
1797        if (data[0] == 0x03) {  /* passthrough command */
1798                unsigned char cdblen = data[2];
1799                memset (pthru, 0, sizeof (mega_passthru));
1800                pthru->islogical = (data[cdblen + 3] & 0x80) ? 1 : 0;
1801                pthru->timeout = data[cdblen + 3] & 0x07;
1802                pthru->reqsenselen = 14;
1803                pthru->ars = (data[cdblen + 3] & 0x08) ? 1 : 0;
1804                pthru->logdrv = data[cdblen + 4];
1805                pthru->channel = data[cdblen + 5];
1806                pthru->target = data[cdblen + 6];
1807                pthru->cdblen = cdblen;
1808                memcpy (pthru->cdb, &data[3], cdblen);
1809
1810                mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
1811
1812
1813                pthru->numsgelements = mega_build_sglist (megaCfg, pScb,
1814                                                          (u32 *) & pthru->
1815                                                          dataxferaddr,
1816                                                          (u32 *) & pthru->
1817                                                          dataxferlen);
1818
1819                mailbox->xferaddr = virt_to_bus (pthru);
1820
1821                for (i = 0; i < (SCpnt->request_bufflen - cdblen - 7); i++) {
1822                        data[i] = data[i + cdblen + 7];
1823                }
1824                return pScb;
1825        }
1826        /* else normal (nonpassthru) command */
1827
1828#if LINUX_VERSION_CODE > KERNEL_VERSION(2,0,24) /*0x020024 */
1829        /*
1830         *usage of the function copy from user is used in case of data more than
1831         *4KB.This is used only with adapters which supports more than 8 logical
1832         * drives.This feature is disabled on kernels earlier or same as 2.0.36
1833         * as the uaccess.h file is not available with those kernels.
1834         */
1835
1836        if (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
1837                /* use external data area for large xfers  */
1838                /* If cmnd[0] is set to M_RD_IOCTL_CMD_NEW then *
1839                 *   cmnd[4..7] = external user buffer     *
1840                 *   cmnd[8..11] = length of buffer        *
1841                 *                                         */
1842        char *user_area = (char *)*((u32*)&SCpnt->cmnd[4]);
1843                u32 xfer_size = *((u32 *) & SCpnt->cmnd[8]);
1844                switch (data[0]) {
1845                case FW_FIRE_WRITE:
1846                case FW_FIRE_FLASH:
1847                        if ((ulong) user_area & (PAGE_SIZE - 1)) {
1848                                printk
1849                                    ("megaraid:user address not aligned on 4K boundary.Error.\n");
1850                                SCpnt->result = (DID_ERROR << 16);
1851                                callDone (SCpnt);
1852                                return NULL;
1853                        }
1854                        break;
1855                default:
1856                        break;
1857                }
1858
1859                if (!(pScb->buff_ptr = kmalloc (xfer_size, GFP_KERNEL))) {
1860                        printk
1861                            ("megaraid: Insufficient mem for M_RD_IOCTL_CMD_NEW.\n");
1862                        SCpnt->result = (DID_ERROR << 16);
1863                        callDone (SCpnt);
1864                        return NULL;
1865                }
1866
1867                copy_from_user (pScb->buff_ptr, user_area, xfer_size);
1868                pScb->iDataSize = xfer_size;
1869
1870                switch (data[0]) {
1871                case DCMD_FC_CMD:
1872                        switch (data[1]) {
1873                        case DCMD_FC_READ_NVRAM_CONFIG:
1874                        case DCMD_GET_DISK_CONFIG:
1875                                {
1876                                        if ((ulong) pScb->
1877                                            buff_ptr & (PAGE_SIZE - 1)) {
1878                                                printk
1879                                                    ("megaraid:user address not sufficient Error.\n");
1880                                                SCpnt->result =
1881                                                    (DID_ERROR << 16);
1882                                                callDone (SCpnt);
1883                                                return NULL;
1884                                        }
1885
1886                                        /*building SG list */
1887                                        mega_build_kernel_sg (pScb->buff_ptr,
1888                                                              xfer_size,
1889                                                              pScb, mbox);
1890                                        break;
1891                                }
1892                        default:
1893                                break;
1894                        }       /*switch (data[1]) */
1895                        break;
1896                }
1897
1898        }
1899#endif
1900
1901        mbox->cmd = data[0];
1902        mbox->channel = data[1];
1903        mbox->param = data[2];
1904        mbox->pad[0] = data[3];
1905        mbox->logdrv = data[4];
1906
1907        if (SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
1908                switch (data[0]) {
1909                case FW_FIRE_WRITE:
1910                        mbox->cmd = FW_FIRE_WRITE;
1911                        mbox->channel = data[1];        /* Current Block Number */
1912                        set_mbox_xfer_addr (megaCfg, pScb, mbox, TO_DEVICE);
1913                        mbox->numsgelements = 0;
1914                        break;
1915                case FW_FIRE_FLASH:
1916                        mbox->cmd = FW_FIRE_FLASH;
1917                        mbox->channel = data[1] | 0x80; /* Origin */
1918                        set_mbox_xfer_addr (megaCfg, pScb, mbox, TO_DEVICE);
1919                        mbox->numsgelements = 0;
1920                        break;
1921                case DCMD_FC_CMD:
1922                        *(mboxdata + 0) = data[0];      /*mailbox byte 0: DCMD_FC_CMD */
1923                        *(mboxdata + 2) = data[1];      /*sub command */
1924                        switch (data[1]) {
1925                        case DCMD_FC_READ_NVRAM_CONFIG:
1926                        case DCMD_FC_READ_NVRAM_CONFIG_64:
1927                                /* number of elements in SG list */
1928                                *(mboxdata + 3) = mbox->numsgelements;
1929                                if (megaCfg->flag & BOARD_64BIT)
1930                                        *(mboxdata + 2) =
1931                                            DCMD_FC_READ_NVRAM_CONFIG_64;
1932                                break;
1933                        case DCMD_WRITE_CONFIG:
1934                        case DCMD_WRITE_CONFIG_64:
1935                                if (megaCfg->flag & BOARD_64BIT)
1936                                        *(mboxdata + 2) = DCMD_WRITE_CONFIG_64;
1937                                set_mbox_xfer_addr (megaCfg, pScb, mbox,
1938                                                    TO_DEVICE);
1939                                mbox->numsgelements = 0;
1940                                break;
1941                        case DCMD_GET_DISK_CONFIG:
1942                        case DCMD_GET_DISK_CONFIG_64:
1943                                if (megaCfg->flag & BOARD_64BIT)
1944                                        *(mboxdata + 2) =
1945                                            DCMD_GET_DISK_CONFIG_64;
1946                                *(mboxdata + 3) = data[2];      /*number of elements in SG list */
1947                                /*nr of elements in SG list */
1948                                *(mboxdata + 4) = mbox->numsgelements;
1949                                break;
1950                        case DCMD_DELETE_LOGDRV:
1951                        case DCMD_DELETE_DRIVEGROUP:
1952                        case NC_SUBOP_ENQUIRY3:
1953                                *(mboxdata + 3) = data[2];
1954                                set_mbox_xfer_addr (megaCfg, pScb, mbox,
1955                                                    FROMTO_DEVICE);
1956                                mbox->numsgelements = 0;
1957                                break;
1958                        case DCMD_CHANGE_LDNO:
1959                        case DCMD_CHANGE_LOOPID:
1960                                *(mboxdata + 3) = data[2];
1961                                *(mboxdata + 4) = data[3];
1962                                set_mbox_xfer_addr (megaCfg, pScb, mbox,
1963                                                    TO_DEVICE);
1964                                mbox->numsgelements = 0;
1965                                break;
1966                        default:
1967                                set_mbox_xfer_addr (megaCfg, pScb, mbox,
1968                                                    FROMTO_DEVICE);
1969                                mbox->numsgelements = 0;
1970                                break;
1971                        }       /*switch */
1972                        break;
1973                default:
1974                        set_mbox_xfer_addr (megaCfg, pScb, mbox, FROMTO_DEVICE);
1975                        mbox->numsgelements = 0;
1976                        break;
1977                }
1978        } else {
1979
1980                mbox->numsgelements = mega_build_sglist (megaCfg, pScb,
1981                                                         (u32 *) & mbox->
1982                                                         xferaddr,
1983                                                         (u32 *) & seg);
1984
1985                /* Handling some of the fw special commands */
1986                switch (data[0]) {
1987                case 6: /* START_DEV */
1988                        mbox->xferaddr = *((u32 *) & data[i + 6]);
1989                        break;
1990                default:
1991                        break;
1992                }
1993
1994                for (i = 0; i < (SCpnt->request_bufflen - 6); i++) {
1995                        data[i] = data[i + 6];
1996                }
1997        }
1998
1999        return (pScb);
2000}
2001
2002
2003static void mega_build_kernel_sg (char *barea, ulong xfersize, mega_scb * pScb, mega_ioctl_mbox * mbox)
2004{
2005        ulong i, buffer_area, len, end, end_page, x, idx = 0;
2006
2007        buffer_area = (ulong) barea;
2008        i = buffer_area;
2009        end = buffer_area + xfersize;
2010        end_page = (end) & ~(PAGE_SIZE - 1);
2011
2012        do {
2013                len = PAGE_SIZE - (i % PAGE_SIZE);
2014                x = pScb->sgList[idx].address =
2015                    virt_to_bus ((volatile void *) i);
2016                pScb->sgList[idx].length = len;
2017                i += len;
2018                idx++;
2019        } while (i < end_page);
2020
2021        if ((end - i) < 0) {
2022                printk ("megaraid:Error in user address\n");
2023        }
2024
2025        if (end - i) {
2026                pScb->sgList[idx].address = virt_to_bus ((volatile void *) i);
2027                pScb->sgList[idx].length = end - i;
2028                idx++;
2029        }
2030        mbox->xferaddr = virt_to_bus (pScb->sgList);
2031        mbox->numsgelements = idx;
2032}
2033#endif
2034
2035
2036#if DEBUG
2037static unsigned int cum_time = 0;
2038static unsigned int cum_time_cnt = 0;
2039
2040static void showMbox (mega_scb * pScb)
2041{
2042        mega_mailbox *mbox;
2043
2044        if (pScb == NULL)
2045                return;
2046
2047        mbox = (mega_mailbox *) pScb->mboxData;
2048        printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
2049                pScb->SCpnt->pid,
2050                mbox->cmd, mbox->cmdid, mbox->numsectors,
2051                mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements);
2052}
2053
2054#endif
2055
2056/*--------------------------------------------------------------------
2057 * Interrupt service routine
2058 *--------------------------------------------------------------------*/
2059static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
2060{
2061        IO_LOCK_T;
2062        mega_host_config * megaCfg;
2063        u_char byte, idx, sIdx, tmpBox[MAILBOX_SIZE];
2064        u32 dword = 0;
2065        mega_mailbox *mbox;
2066        mega_scb *pScb;
2067        u_char qCnt, qStatus;
2068        u_char completed[MAX_FIRMWARE_STATUS];
2069        Scsi_Cmnd *SCpnt;
2070
2071        megaCfg = (mega_host_config *) devp;
2072        mbox = (mega_mailbox *) tmpBox;
2073
2074        if (megaCfg->host->irq == irq) {
2075                if (megaCfg->flag & IN_ISR) {
2076                        TRACE (("ISR called reentrantly!!\n"));
2077                        printk ("ISR called reentrantly!!\n");
2078                }
2079                megaCfg->flag |= IN_ISR;
2080
2081                if (mega_busyWaitMbox (megaCfg)) {
2082                        printk (KERN_WARNING "Error: mailbox busy in isr!\n");
2083                }
2084
2085                /* Check if a valid interrupt is pending */
2086                if (megaCfg->flag & BOARD_QUARTZ) {
2087                        dword = RDOUTDOOR (megaCfg);
2088                        if (dword != 0x10001234) {
2089                                /* Spurious interrupt */
2090                                megaCfg->flag &= ~IN_ISR;
2091                                return;
2092                        }
2093                } else {
2094                        byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
2095                        if ((byte & VALID_INTR_BYTE) == 0) {
2096                                /* Spurious interrupt */
2097                                megaCfg->flag &= ~IN_ISR;
2098                                return;
2099                        }
2100                        WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
2101                }
2102
2103                for (idx = 0; idx < MAX_FIRMWARE_STATUS; idx++)
2104                        completed[idx] = 0;
2105
2106                IO_LOCK(megaCfg->host);
2107
2108                megaCfg->nInterrupts++;
2109                qCnt = 0xff;
2110                while ((qCnt = megaCfg->mbox->numstatus) == 0xFF) ;
2111
2112                qStatus = 0xff;
2113                while ((qStatus = megaCfg->mbox->status) == 0xFF) ;
2114
2115                /* Get list of completed requests */
2116                for (idx = 0; idx < qCnt; idx++) {
2117                        while ((sIdx = megaCfg->mbox->completed[idx]) == 0xFF) {
2118                                printk ("p");
2119                        }
2120                        completed[idx] = sIdx;
2121                        sIdx = 0xFF;
2122                }
2123
2124                if (megaCfg->flag & BOARD_QUARTZ) {
2125                        WROUTDOOR (megaCfg, dword);
2126                        /* Acknowledge interrupt */
2127#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2128                        /* In this case mbox contains physical address */
2129#if 0
2130                        WRINDOOR (megaCfg, megaCfg->adjdmahandle64 | 0x2);
2131#else
2132                        WRINDOOR (megaCfg, 0x2);
2133#endif
2134
2135#else
2136
2137#if 0
2138                        WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
2139#else
2140                        WRINDOOR (megaCfg, 0x2);
2141#endif
2142
2143#endif
2144
2145#if 0
2146                        while (RDINDOOR (megaCfg) & 0x02) ;
2147#endif
2148                } else {
2149                        CLEAR_INTR (megaCfg->host->io_port);
2150                }
2151
2152#if DEBUG
2153                if (qCnt >= MAX_FIRMWARE_STATUS) {
2154                        printk ("megaraid_isr: cmplt=%d ", qCnt);
2155                }
2156#endif
2157
2158                for (idx = 0; idx < qCnt; idx++) {
2159                        sIdx = completed[idx];
2160                        if ((sIdx > 0) && (sIdx <= MAX_COMMANDS)) {
2161                                pScb = &megaCfg->scbList[sIdx - 1];
2162
2163                                /* ASSERT(pScb->state == SCB_ISSUED); */
2164
2165#if DEBUG
2166                                if (((jiffies) - pScb->isrcount) > maxCmdTime) {
2167                                        maxCmdTime = (jiffies) - pScb->isrcount;
2168                                        printk
2169                                            ("megaraid_isr : cmd time = %u\n",
2170                                             maxCmdTime);
2171                                }
2172#endif
2173                                /*
2174                                 * Assuming that the scsi command, for which 
2175                                 * an abort request was received earlier, has 
2176                                 * completed.
2177                                 */
2178                                if (pScb->state == SCB_ABORTED) {
2179                                        SCpnt = pScb->SCpnt;
2180                                }
2181                                if (pScb->state == SCB_RESET) {
2182                                        SCpnt = pScb->SCpnt;
2183                                        mega_freeSCB (megaCfg, pScb);
2184                                        SCpnt->result = (DID_RESET << 16);
2185                                        if (megaCfg->qCompletedH == NULL) {
2186                                                megaCfg->qCompletedH =
2187                                                    megaCfg->qCompletedT =
2188                                                    SCpnt;
2189                                        } else {
2190                                                megaCfg->qCompletedT->
2191                                                    host_scribble =
2192                                                    (unsigned char *) SCpnt;
2193                                                megaCfg->qCompletedT = SCpnt;
2194                                        }
2195                                        megaCfg->qCompletedT->host_scribble =
2196                                            (unsigned char *) NULL;
2197                                        megaCfg->qCcnt++;
2198                                        continue;
2199                                }
2200
2201                                /* We don't want the ISR routine to touch M_RD_IOCTL_CMD_NEW commands, so
2202                                 * don't mark them as complete, instead we pop their semaphore so
2203                                 * that the queue routine can finish them off
2204                                 */
2205                                if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
2206                                        /* save the status byte for the queue routine to use */
2207                                        pScb->SCpnt->result = qStatus;
2208                                        up (&pScb->ioctl_sem);
2209                                } else {
2210                                        /* Mark command as completed */
2211                                        mega_cmd_done (megaCfg, pScb, qStatus);
2212                                }
2213                        } else {
2214                                printk
2215                                    ("megaraid: wrong cmd id completed from firmware:id=%x\n",
2216                                     sIdx);
2217                        }
2218                }
2219
2220                mega_rundoneq (megaCfg);
2221
2222                megaCfg->flag &= ~IN_ISR;
2223                /* Loop through any pending requests */
2224                mega_runpendq (megaCfg);
2225                IO_UNLOCK(megaCfg->host);
2226
2227        }
2228
2229}
2230
2231/*==================================================*/
2232/* Wait until the controller's mailbox is available */
2233/*==================================================*/
2234
2235static int mega_busyWaitMbox (mega_host_config * megaCfg)
2236{
2237        mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
2238        long counter;
2239
2240        for (counter = 0; counter < 10000; counter++) {
2241                if (!mbox->busy) {
2242                        return 0;
2243                }
2244                udelay (100);
2245                barrier ();
2246        }
2247        return -1;              /* give up after 1 second */
2248}
2249
2250/*=====================================================
2251 * Post a command to the card
2252 *
2253 * Arguments:
2254 *   mega_host_config *megaCfg - Controller structure
2255 *   u_char *mboxData - Mailbox area, 16 bytes
2256 *   mega_scb *pScb   - SCB posting (or NULL if N/A)
2257 *   int intr         - if 1, interrupt, 0 is blocking
2258 * Return Value: (added on 7/26 for 40ld/64bit)
2259 *   -1: the command was not actually issued out
2260 *   other cases:
2261 *     intr==0, return ScsiStatus, i.e. mbox->status
2262 *     intr==1, return 0
2263 *=====================================================
2264 */
2265static int megaIssueCmd (mega_host_config * megaCfg, u_char * mboxData, 
2266                mega_scb * pScb, int intr)
2267{
2268        volatile mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
2269
2270#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2271        volatile mega_mailbox64 *mbox64 = (mega_mailbox64 *) megaCfg->mbox64;
2272#endif
2273
2274        u_char byte;
2275
2276#ifdef __LP64__
2277        u64 phys_mbox;
2278#else
2279        u32 phys_mbox;
2280#endif
2281        u8 retval = -1;
2282
2283        mboxData[0x1] = (pScb ? pScb->idx + 1 : 0xFE);  /* Set cmdid */
2284        mboxData[0xF] = 1;      /* Set busy */
2285
2286#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2287        /* In this case mbox contains physical address */
2288        phys_mbox = megaCfg->adjdmahandle64;
2289#else
2290        phys_mbox = virt_to_bus (megaCfg->mbox);
2291#endif
2292
2293#if DEBUG
2294        ShowMbox (pScb);
2295#endif
2296
2297        /* Wait until mailbox is free */
2298        if (mega_busyWaitMbox (megaCfg)) {
2299                printk ("Blocked mailbox......!!\n");
2300                udelay (1000);
2301
2302#if DEBUG
2303                showMbox (pLastScb);
2304#endif
2305
2306                /* Abort command */
2307                if (pScb == NULL) {
2308                        TRACE (("NULL pScb in megaIssue\n"));
2309                        printk ("NULL pScb in megaIssue\n");
2310                }
2311                mega_cmd_done (megaCfg, pScb, 0x08);
2312                return -1;
2313        }
2314
2315        pLastScb = pScb;
2316
2317        /* Copy mailbox data into host structure */
2318        megaCfg->mbox64->xferSegment_lo = 0;
2319        megaCfg->mbox64->xferSegment_hi = 0;
2320
2321        memcpy ((char *) mbox, mboxData, 16);
2322
2323#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2324        switch (mboxData[0]) {
2325        case MEGA_MBOXCMD_LREAD64:
2326        case MEGA_MBOXCMD_LWRITE64:
2327                mbox64->xferSegment_lo = mbox->xferaddr;
2328                mbox64->xferSegment_hi = 0;
2329                mbox->xferaddr = 0xFFFFFFFF;
2330                break;
2331        }
2332#endif
2333
2334        /* Kick IO */
2335        if (intr) {
2336                /* Issue interrupt (non-blocking) command */
2337                if (megaCfg->flag & BOARD_QUARTZ) {
2338                        mbox->mraid_poll = 0;
2339                        mbox->mraid_ack = 0;
2340
2341                        WRINDOOR (megaCfg, phys_mbox | 0x1);
2342                } else {
2343                        ENABLE_INTR (megaCfg->host->io_port);
2344                        ISSUE_COMMAND (megaCfg->host->io_port);
2345                }
2346                pScb->state = SCB_ISSUED;
2347
2348                retval = 0;
2349        } else {                /* Issue non-ISR (blocking) command */
2350                disable_irq (megaCfg->host->irq);
2351                if (megaCfg->flag & BOARD_QUARTZ) {
2352                        mbox->mraid_poll = 0;
2353                        mbox->mraid_ack = 0;
2354                        mbox->numstatus = 0xFF;
2355                        mbox->status = 0xFF;
2356                        WRINDOOR (megaCfg, phys_mbox | 0x1);
2357
2358                        while (mbox->numstatus == 0xFF) ;
2359                        while (mbox->status == 0xFF) ;
2360                        while (mbox->mraid_poll != 0x77) ;
2361                        mbox->mraid_poll = 0;
2362                        mbox->mraid_ack = 0x77;
2363
2364                        /* while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
2365                           WROUTDOOR (megaCfg, cmdDone); */
2366
2367                        if (pScb) {
2368                                mega_cmd_done (megaCfg, pScb, mbox->status);
2369                        }
2370
2371                        WRINDOOR (megaCfg, phys_mbox | 0x2);
2372                        while (RDINDOOR (megaCfg) & 0x2) ;
2373
2374                } else {
2375                        DISABLE_INTR (megaCfg->host->io_port);
2376                        ISSUE_COMMAND (megaCfg->host->io_port);
2377
2378                        while (!
2379                               ((byte =
2380                                 READ_PORT (megaCfg->host->io_port,
2381                                            INTR_PORT)) & INTR_VALID)) ;
2382                        WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
2383
2384                        ENABLE_INTR (megaCfg->host->io_port);
2385                        CLEAR_INTR (megaCfg->host->io_port);
2386
2387                        if (pScb) {
2388                                mega_cmd_done (megaCfg, pScb, mbox->status);
2389                        } else {
2390                                TRACE (("Error: NULL pScb!\n"));
2391                        }
2392                }
2393                enable_irq (megaCfg->host->irq);
2394                retval = mbox->status;
2395        }
2396#if DEBUG
2397        while (mega_busyWaitMbox (megaCfg)) {
2398                printk(KERN_ERR "Blocked mailbox on exit......!\n");
2399                udelay (1000);
2400        }
2401#endif
2402
2403        return retval;
2404}
2405
2406/*-------------------------------------------------------------------
2407 * Copies data to SGLIST
2408 *-------------------------------------------------------------------*/
2409/* Note:
2410        For 64 bit cards, we need a minimum of one SG element for read/write
2411*/
2412
2413static int
2414mega_build_sglist (mega_host_config * megaCfg, mega_scb * scb,
2415                   u32 * buffer, u32 * length)
2416{
2417        struct scatterlist *sgList;
2418        int idx;
2419
2420#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2421        int sgcnt;
2422#endif
2423
2424        mega_mailbox *mbox = NULL;
2425
2426        mbox = (mega_mailbox *) scb->mboxData;
2427        /* Scatter-gather not used */
2428        if (scb->SCpnt->use_sg == 0) {
2429
2430#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2431                scb->dma_h_bulkdata = pci_map_single (megaCfg->dev,
2432                                      scb->SCpnt->request_buffer,
2433                                      scb->SCpnt->request_bufflen,
2434                                      scb->dma_direction);
2435                /* We need to handle special commands like READ64, WRITE64
2436                   as they need a minimum of 1 SG irrespective of actually SG
2437                 */
2438                if ((megaCfg->flag & BOARD_64BIT) &&
2439                    ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2440                     (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2441                        scb->sg64List[0].address = scb->dma_h_bulkdata;
2442                        scb->sg64List[0].length = scb->SCpnt->request_bufflen;
2443                        *buffer = scb->dma_sghandle64;
2444                        *length = 0;
2445                        scb->sglist_count = 1;
2446                        return 1;
2447                } else {
2448                        *buffer = scb->dma_h_bulkdata;
2449                        *length = (u32) scb->SCpnt->request_bufflen;
2450                }
2451#else
2452                *buffer = virt_to_bus (scb->SCpnt->request_buffer);
2453                *length = (u32) scb->SCpnt->request_bufflen;
2454#endif
2455                return 0;
2456        }
2457
2458        sgList = (struct scatterlist *) scb->SCpnt->request_buffer;
2459#if 0
2460        if (scb->SCpnt->use_sg == 1) {
2461
2462#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2463                scb->dma_h_bulkdata = pci_map_single (megaCfg->dev,
2464                                      sgList[0].address,
2465                                      sgList[0].length, scb->dma_direction);
2466
2467                if ((megaCfg->flag & BOARD_64BIT) &&
2468                    ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2469                     (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2470                        scb->sg64List[0].address = scb->dma_h_bulkdata;
2471                        scb->sg64List[0].length = scb->SCpnt->request_bufflen;
2472                        *buffer = scb->dma_sghandle64;
2473                        *length = 0;
2474                        scb->sglist_count = 1;
2475                        return 1;
2476                } else {
2477                        *buffer = scb->dma_h_bulkdata;
2478                        *length = (u32) sgList[0].length;
2479                }
2480#else
2481                *buffer = virt_to_bus (sgList[0].address);
2482                *length = (u32) sgList[0].length;
2483#endif
2484
2485                return 0;
2486        }
2487#endif
2488        /* Copy Scatter-Gather list info into controller structure */
2489#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2490        sgcnt = pci_map_sg (megaCfg->dev,
2491                            sgList, scb->SCpnt->use_sg, scb->dma_direction);
2492
2493        /* Determine the validity of the new count  */
2494        if (sgcnt == 0)
2495                printk ("pci_map_sg returned zero!!! ");
2496
2497        for (idx = 0; idx < sgcnt; idx++, sgList++) {
2498
2499                if ((megaCfg->flag & BOARD_64BIT) &&
2500                    ((mbox->cmd == MEGA_MBOXCMD_LREAD64) ||
2501                     (mbox->cmd == MEGA_MBOXCMD_LWRITE64))) {
2502                        scb->sg64List[idx].address = sg_dma_address (sgList);
2503                        scb->sg64List[idx].length = sg_dma_len (sgList);
2504                } else {
2505                        scb->sgList[idx].address = sg_dma_address (sgList);
2506                        scb->sgList[idx].length = sg_dma_len (sgList);
2507                }
2508
2509        }
2510
2511#else
2512        for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
2513                scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
2514                scb->sgList[idx].length = (u32) sgList[idx].length;
2515        }
2516#endif
2517
2518        /* Reset pointer and length fields */
2519#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2520        *buffer = scb->dma_sghandle64;
2521        scb->sglist_count = scb->SCpnt->use_sg;
2522#else
2523        *buffer = virt_to_bus (scb->sgList);
2524#endif
2525        *length = 0;
2526
2527#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2528        /* Return count of SG requests */
2529        return sgcnt;
2530#else
2531        /* Return count of SG requests */
2532        return scb->SCpnt->use_sg;
2533#endif
2534}
2535
2536/*--------------------------------------------------------------------
2537 * Initializes the address of the controller's mailbox register
2538 *  The mailbox register is used to issue commands to the card.
2539 *  Format of the mailbox area:
2540 *   00 01 command
2541 *   01 01 command id
2542 *   02 02 # of sectors
2543 *   04 04 logical bus address
2544 *   08 04 physical buffer address
2545 *   0C 01 logical drive #
2546 *   0D 01 length of scatter/gather list
2547 *   0E 01 reserved
2548 *   0F 01 mailbox busy
2549 *   10 01 numstatus byte
2550 *   11 01 status byte
2551 *--------------------------------------------------------------------*/
2552static int
2553mega_register_mailbox (mega_host_config * megaCfg, u32 paddr)
2554{
2555        /* align on 16-byte boundary */
2556#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2557        megaCfg->mbox = &megaCfg->mailbox64ptr->mailbox;
2558#else
2559        megaCfg->mbox = &megaCfg->mailbox64.mailbox;
2560#endif
2561
2562#ifdef __LP64__
2563        megaCfg->mbox = (mega_mailbox *) ((((u64) megaCfg->mbox) + 16) & ((u64) (-1) ^ 0x0F));
2564        megaCfg->adjdmahandle64 = (megaCfg->dma_handle64 + 16) & ((u64) (-1) ^ 0x0F);
2565        megaCfg->mbox64 = (mega_mailbox64 *) ((u_char *) megaCfg->mbox - sizeof (u64));
2566        paddr = (paddr + 4 + 16) & ((u64) (-1) ^ 0x0F);
2567#else
2568        megaCfg->mbox
2569            = (mega_mailbox *) ((((u32) megaCfg->mbox) + 16) & 0xFFFFFFF0);
2570
2571#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2572        megaCfg->adjdmahandle64 = ((megaCfg->dma_handle64 + 16) & 0xFFFFFFF0);
2573#endif
2574
2575        megaCfg->mbox64 = (mega_mailbox64 *) ((u_char *) megaCfg->mbox - 8);
2576        paddr = (paddr + 4 + 16) & 0xFFFFFFF0;
2577#endif
2578
2579        /* Register mailbox area with the firmware */
2580        if (!(megaCfg->flag & BOARD_QUARTZ)) {
2581                WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
2582                WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1,
2583                            (paddr >> 8) & 0xFF);
2584                WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2,
2585                            (paddr >> 16) & 0xFF);
2586                WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3,
2587                            (paddr >> 24) & 0xFF);
2588                WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION,
2589                            ENABLE_MBOX_BYTE);
2590
2591                CLEAR_INTR (megaCfg->host->io_port);
2592                ENABLE_INTR (megaCfg->host->io_port);
2593        }
2594        return 0;
2595}
2596
2597/*---------------------------------------------------------------------------
2598 * mega_Convert8ldTo40ld() -- takes all info in AdapterInquiry structure and
2599 * puts it into ProductInfo and Enquiry3 structures for later use
2600 *---------------------------------------------------------------------------*/
2601static void mega_Convert8ldTo40ld (mega_RAIDINQ * inquiry,
2602                       mega_Enquiry3 * enquiry3,
2603                       megaRaidProductInfo * productInfo)
2604{
2605        int i;
2606
2607        productInfo->MaxConcCmds = inquiry->AdpInfo.MaxConcCmds;
2608        enquiry3->rbldRate = inquiry->AdpInfo.RbldRate;
2609        productInfo->SCSIChanPresent = inquiry->AdpInfo.ChanPresent;
2610
2611        for (i = 0; i < 4; i++) {
2612                productInfo->FwVer[i] = inquiry->AdpInfo.FwVer[i];
2613                productInfo->BiosVer[i] = inquiry->AdpInfo.BiosVer[i];
2614        }
2615        enquiry3->cacheFlushInterval = inquiry->AdpInfo.CacheFlushInterval;
2616        productInfo->DramSize = inquiry->AdpInfo.DramSize;
2617
2618        enquiry3->numLDrv = inquiry->LogdrvInfo.NumLDrv;
2619
2620        for (i = 0; i < MAX_LOGICAL_DRIVES; i++) {
2621                enquiry3->lDrvSize[i] = inquiry->LogdrvInfo.LDrvSize[i];
2622                enquiry3->lDrvProp[i] = inquiry->LogdrvInfo.LDrvProp[i];
2623                enquiry3->lDrvState[i]
2624                    = inquiry->LogdrvInfo.LDrvState[i];
2625        }
2626
2627        for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++) {
2628                enquiry3->pDrvState[i]
2629                    = inquiry->PhysdrvInfo.PDrvState[i];
2630        }
2631}
2632
2633/*-------------------------------------------------------------------
2634 * Issue an adapter info query to the controller
2635 *-------------------------------------------------------------------*/
2636static int mega_i_query_adapter (mega_host_config * megaCfg)
2637{
2638        mega_Enquiry3 *enquiry3Pnt;
2639        mega_mailbox *mbox;
2640        u_char mboxData[16];
2641
2642#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2643        dma_addr_t raid_inq_dma_handle = 0, prod_info_dma_handle = 0, enquiry3_dma_handle = 0;
2644#endif
2645        u8 retval;
2646
2647        /* Initialize adapter inquiry mailbox */
2648
2649        mbox = (mega_mailbox *) mboxData;
2650
2651        memset ((void *) megaCfg->mega_buffer, 0,
2652                sizeof (megaCfg->mega_buffer));
2653        memset (mbox, 0, 16);
2654
2655/*
2656 * Try to issue Enquiry3 command
2657 * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
2658 * update enquiry3 structure
2659 */
2660#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2661        enquiry3_dma_handle = pci_map_single (megaCfg->dev,
2662                              (void *) megaCfg->mega_buffer,
2663                              (2 * 1024L), PCI_DMA_FROMDEVICE);
2664
2665        mbox->xferaddr = enquiry3_dma_handle;
2666#else
2667        /*Taken care */
2668        mbox->xferaddr = virt_to_bus ((void *) megaCfg->mega_buffer);
2669#endif
2670
2671        /* Initialize mailbox databuffer addr */
2672        enquiry3Pnt = (mega_Enquiry3 *) megaCfg->mega_buffer;
2673        /* point mega_Enguiry3 to the data buf */
2674
2675        mboxData[0] = FC_NEW_CONFIG;    /* i.e. mbox->cmd=0xA1 */
2676        mboxData[2] = NC_SUBOP_ENQUIRY3;        /* i.e. 0x0F */
2677        mboxData[3] = ENQ3_GET_SOLICITED_FULL;  /* i.e. 0x02 */
2678
2679        /* Issue a blocking command to the card */
2680        if ((retval = megaIssueCmd (megaCfg, mboxData, NULL, 0)) != 0) {        /* the adapter does not support 40ld */
2681                mega_RAIDINQ adapterInquiryData;
2682                mega_RAIDINQ *adapterInquiryPnt = &adapterInquiryData;
2683
2684#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2685                raid_inq_dma_handle = pci_map_single (megaCfg->dev,
2686                                      (void *) adapterInquiryPnt,
2687                                      sizeof (mega_RAIDINQ),
2688                                      PCI_DMA_FROMDEVICE);
2689                mbox->xferaddr = raid_inq_dma_handle;
2690#else
2691                /*taken care */
2692                mbox->xferaddr = virt_to_bus ((void *) adapterInquiryPnt);
2693#endif
2694
2695                mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;    /*issue old 0x05 command to adapter */
2696                /* Issue a blocking command to the card */ ;
2697                retval = megaIssueCmd (megaCfg, mboxData, NULL, 0);
2698
2699                pci_unmap_single (megaCfg->dev,
2700                                  raid_inq_dma_handle,
2701                                  sizeof (mega_RAIDINQ), PCI_DMA_FROMDEVICE);
2702
2703                /*update Enquiry3 and ProductInfo structures with mega_RAIDINQ structure*/
2704                mega_Convert8ldTo40ld (adapterInquiryPnt,
2705                                       enquiry3Pnt,
2706                                       (megaRaidProductInfo *) & megaCfg->
2707                                       productInfo);
2708
2709        } else {                /* adapter supports 40ld */
2710                megaCfg->flag |= BOARD_40LD;
2711
2712                pci_unmap_single (megaCfg->dev,
2713                                  enquiry3_dma_handle,
2714                                  (2 * 1024L), PCI_DMA_FROMDEVICE);
2715#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2716/*get productInfo, which is static information and will be unchanged*/
2717                prod_info_dma_handle
2718                    = pci_map_single (megaCfg->dev,
2719                                      (void *) &megaCfg->productInfo,
2720                                      sizeof (megaRaidProductInfo),
2721                                      PCI_DMA_FROMDEVICE);
2722                mbox->xferaddr = prod_info_dma_handle;
2723#else
2724                /*taken care */
2725                mbox->xferaddr = virt_to_bus ((void *) &megaCfg->productInfo);
2726#endif
2727
2728                mboxData[0] = FC_NEW_CONFIG;    /* i.e. mbox->cmd=0xA1 */
2729                mboxData[2] = NC_SUBOP_PRODUCT_INFO;    /* i.e. 0x0E */
2730
2731                if ((retval = megaIssueCmd (megaCfg, mboxData, NULL, 0)) != 0)
2732                        printk ("megaraid: Product_info cmd failed with error: %d\n",
2733                                retval);
2734
2735                pci_unmap_single (megaCfg->dev,
2736                                  prod_info_dma_handle,
2737                                  sizeof (megaRaidProductInfo),
2738                                  PCI_DMA_FROMDEVICE);
2739        }
2740
2741        /*
2742         * kernel scans the channels from 0 to <= max_channel
2743         */
2744        megaCfg->host->max_channel =
2745                megaCfg->productInfo.SCSIChanPresent + NVIRT_CHAN -1;
2746
2747        megaCfg->host->max_id = 16;     /* max targets per channel */
2748        /*(megaCfg->flag & BOARD_40LD)?FC_MAX_TARGETS_PER_CHANNEL:MAX_TARGET+1; */
2749#if 0
2750        megaCfg->host->max_lun =        /* max lun */
2751            (megaCfg->flag & BOARD_40LD) ?
2752                        FC_MAX_LOGICAL_DRIVES : MAX_LOGICAL_DRIVES;
2753#endif
2754        megaCfg->host->max_lun = 7;     /* Upto 7 luns for non disk devices */
2755
2756        megaCfg->host->cmd_per_lun = MAX_CMD_PER_LUN;
2757
2758        megaCfg->numldrv = enquiry3Pnt->numLDrv;
2759        megaCfg->max_cmds = megaCfg->productInfo.MaxConcCmds;
2760        if (megaCfg->max_cmds > MAX_COMMANDS)
2761                megaCfg->max_cmds = MAX_COMMANDS - 1;
2762
2763        megaCfg->host->can_queue = megaCfg->max_cmds - 1;
2764
2765#if 0
2766        if (megaCfg->host->can_queue >= MAX_COMMANDS) {
2767                megaCfg->host->can_queue = MAX_COMMANDS - 16;
2768        }
2769#endif
2770
2771        /* use HP firmware and bios version encoding */
2772        if (megaCfg->productInfo.subSystemVendorID == HP_SUBSYS_ID) {
2773                sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
2774                         megaCfg->productInfo.FwVer[2],
2775                         megaCfg->productInfo.FwVer[1] >> 8,
2776                         megaCfg->productInfo.FwVer[1] & 0x0f,
2777                         megaCfg->productInfo.FwVer[0] >> 8,
2778                         megaCfg->productInfo.FwVer[0] & 0x0f);
2779                sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
2780                         megaCfg->productInfo.BiosVer[2],
2781                         megaCfg->productInfo.BiosVer[1] >> 8,
2782                         megaCfg->productInfo.BiosVer[1] & 0x0f,
2783                         megaCfg->productInfo.BiosVer[0] >> 8,
2784                         megaCfg->productInfo.BiosVer[0] & 0x0f);
2785        } else {
2786                memcpy (megaCfg->fwVer, (char *) megaCfg->productInfo.FwVer, 4);
2787                megaCfg->fwVer[4] = 0;
2788
2789                memcpy (megaCfg->biosVer, (char *) megaCfg->productInfo.BiosVer, 4);
2790                megaCfg->biosVer[4] = 0;
2791        }
2792        megaCfg->support_ext_cdb = mega_support_ext_cdb(megaCfg);
2793
2794        printk (KERN_NOTICE "megaraid: [%s:%s] detected %d logical drives" M_RD_CRLFSTR,
2795                megaCfg->fwVer, megaCfg->biosVer, megaCfg->numldrv);
2796
2797        if ( megaCfg->support_ext_cdb ) {
2798                printk(KERN_NOTICE "megaraid: supports extended CDBs.\n");
2799        }
2800
2801        /*
2802         * I hope that I can unmap here, reason DMA transaction is not required any more
2803         * after this
2804         */
2805
2806        return 0;
2807}
2808
2809/*-------------------------------------------------------------------------
2810 *
2811 *                      Driver interface functions
2812 *
2813 *-------------------------------------------------------------------------*/
2814
2815/*----------------------------------------------------------
2816 * Returns data to be displayed in /proc/scsi/megaraid/X
2817 *----------------------------------------------------------*/
2818
2819int megaraid_proc_info (char *buffer, char **start, off_t offset,
2820                    int length, int host_no, int inout)
2821{
2822        *start = buffer;
2823        return 0;
2824}
2825
2826static int mega_findCard (Scsi_Host_Template * pHostTmpl,
2827               u16 pciVendor, u16 pciDev, long flag)
2828{
2829        mega_host_config *megaCfg = NULL;
2830        struct Scsi_Host *host = NULL;
2831        u_char pciBus, pciDevFun, megaIrq;
2832
2833        u16 magic;
2834#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2835        u32 magic64;
2836#endif
2837
2838        int             i;
2839
2840#ifdef __LP64__
2841        u64 megaBase;
2842#else
2843        u32 megaBase;
2844#endif
2845
2846        u16 pciIdx = 0;
2847        u16 numFound = 0;
2848        u16 subsysid, subsysvid;
2849
2850#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
2851        while (!pcibios_find_device
2852               (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
2853#else
2854
2855#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)  /*0x20300 */
2856        struct pci_dev *pdev = NULL;
2857#else
2858        struct pci_dev *pdev = pci_devices;
2859#endif
2860
2861        while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
2862                if(pci_enable_device (pdev))
2863                        continue;
2864                pciBus = pdev->bus->number;
2865                pciDevFun = pdev->devfn;
2866#endif
2867                if ((flag & BOARD_QUARTZ) && (skip_id == -1)) {
2868                        pci_read_config_word (pdev, PCI_CONF_AMISIG, &magic);
2869                        if ((magic != AMI_SIGNATURE)
2870                            && (magic != AMI_SIGNATURE_471)) {
2871                                pciIdx++;
2872                                continue;       /* not an AMI board */
2873                        }
2874#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2875                        pci_read_config_dword (pdev, PCI_CONF_AMISIG64, &magic64);
2876
2877                        if (magic64 == AMI_64BIT_SIGNATURE)
2878                                flag |= BOARD_64BIT;
2879#endif
2880                }
2881
2882                /* Hmmm...Should we not make this more modularized so that in future we dont add
2883                   for each firmware */
2884
2885                if (flag & BOARD_QUARTZ) {
2886                        /* Check to see if this is a Dell PERC RAID controller model 466 */
2887#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
2888                        pcibios_read_config_word (pciBus, pciDevFun,
2889                                                  PCI_SUBSYSTEM_VENDOR_ID,
2890                                                  &subsysvid);
2891                        pcibios_read_config_word (pciBus, pciDevFun,
2892                                                  PCI_SUBSYSTEM_ID, &subsysid);
2893#else
2894                        pci_read_config_word (pdev,
2895                                              PCI_SUBSYSTEM_VENDOR_ID,
2896                                              &subsysvid);
2897                        pci_read_config_word (pdev,
2898                                              PCI_SUBSYSTEM_ID, &subsysid);
2899#endif
2900
2901#if 0
2902                        /*
2903                         * This routine is called with well know values and we
2904                         * should not be getting what we have not asked.
2905                         * Also, the check is not right. It should have been for
2906                         * pci_vendor_id not subsysvid - AM
2907                         */
2908
2909                        /* If we dont detect this valid subsystem vendor id's 
2910                           we refuse to load the driver 
2911                           PART of PC200X compliance
2912                         */
2913
2914                        if ((subsysvid != AMI_SUBSYS_ID)
2915                            && (subsysvid != DELL_SUBSYS_ID)
2916                            && (subsysvid != HP_SUBSYS_ID))
2917                                continue;
2918#endif
2919                }
2920
2921                printk (KERN_NOTICE
2922                        "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:func %d\n",
2923                        pciVendor, pciDev, pciIdx, pciBus, PCI_SLOT (pciDevFun),
2924                        PCI_FUNC (pciDevFun));
2925                /* Read the base port and IRQ from PCI */
2926#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
2927                pcibios_read_config_dword (pciBus, pciDevFun,
2928                                           PCI_BASE_ADDRESS_0,
2929                                           (u_int *) & megaBase);
2930                pcibios_read_config_byte (pciBus, pciDevFun,
2931                                          PCI_INTERRUPT_LINE, &megaIrq);
2932#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)        /*0x20300 */
2933                megaBase = pdev->base_address[0];
2934                megaIrq = pdev->irq;
2935#else
2936
2937                megaBase = pci_resource_start (pdev, 0);
2938                megaIrq = pdev->irq;
2939#endif
2940
2941                pciIdx++;
2942
2943                if (flag & BOARD_QUARTZ) {
2944                        megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
2945                        megaBase = (long) ioremap (megaBase, 128);
2946                        if (!megaBase)
2947                                continue;
2948                } else {
2949                        megaBase &= PCI_BASE_ADDRESS_IO_MASK;
2950                        megaBase += 0x10;
2951                }
2952
2953                /* Initialize SCSI Host structure */
2954                host = scsi_register (pHostTmpl, sizeof (mega_host_config));
2955                if (!host)
2956                        goto err_unmap;
2957
2958                /*
2959                 * Comment the following initialization if you know 'max_sectors' is
2960                 * not defined for this kernel.
2961                 * This field was introduced in Linus's kernel 2.4.7pre3 and it
2962                 * greatly increases the IO performance - AM
2963                 */
2964                host->max_sectors = 1024;
2965
2966                scsi_set_pci_device(host, pdev);
2967                megaCfg = (mega_host_config *) host->hostdata;
2968                memset (megaCfg, 0, sizeof (mega_host_config));
2969
2970                printk (KERN_NOTICE "scsi%d : Found a MegaRAID controller at 0x%x, IRQ: %d"
2971                        M_RD_CRLFSTR, host->host_no, (u_int) megaBase, megaIrq);
2972
2973                if (flag & BOARD_64BIT)
2974                        printk (KERN_NOTICE "scsi%d : Enabling 64 bit support\n",
2975                                host->host_no);
2976
2977                /* Copy resource info into structure */
2978                megaCfg->qCompletedH = NULL;
2979                megaCfg->qCompletedT = NULL;
2980                megaCfg->qPendingH = NULL;
2981                megaCfg->qPendingT = NULL;
2982                megaCfg->qFreeH = NULL;
2983                megaCfg->qFreeT = NULL;
2984                megaCfg->qFcnt = 0;
2985                megaCfg->qPcnt = 0;
2986                megaCfg->qCcnt = 0;
2987                megaCfg->lock_free = SPIN_LOCK_UNLOCKED;
2988                megaCfg->lock_pend = SPIN_LOCK_UNLOCKED;
2989                megaCfg->lock_scsicmd = SPIN_LOCK_UNLOCKED;
2990                megaCfg->flag = flag;
2991                megaCfg->int_qh = NULL;
2992                megaCfg->int_qt = NULL;
2993                megaCfg->int_qlen = 0;
2994
2995#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
2996                megaCfg->dev = pdev;
2997#endif
2998                megaCfg->host = host;
2999                megaCfg->base = megaBase;
3000                megaCfg->host->irq = megaIrq;
3001                megaCfg->host->io_port = megaBase;
3002                megaCfg->host->n_io_port = 16;
3003                megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
3004                megaCtlrs[numCtlrs] = megaCfg;
3005
3006                if (!(flag & BOARD_QUARTZ)) {
3007                        /* Request our IO Range */
3008                        if (!request_region(megaBase, 16, "megaraid")) {
3009                                printk(KERN_WARNING "megaraid: Couldn't register I/O range!\n");
3010                                goto err_unregister;
3011                        }
3012                }
3013
3014                /* Request our IRQ */
3015                if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
3016                                 "megaraid", megaCfg)) {
3017                        printk (KERN_WARNING
3018                                "megaraid: Couldn't register IRQ %d!\n",
3019                                megaIrq);
3020                        goto err_release;
3021                }
3022
3023#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3024                /*
3025                 * unmap while releasing the driver, Is it required to be 
3026                 * PCI_DMA_BIDIRECTIONAL 
3027                */
3028
3029                megaCfg->mailbox64ptr
3030                    = pci_alloc_consistent (megaCfg->dev,
3031                                            sizeof (mega_mailbox64),
3032                                            &(megaCfg->dma_handle64));
3033
3034                mega_register_mailbox (megaCfg, megaCfg->dma_handle64);
3035#else
3036                mega_register_mailbox (megaCfg,
3037                                       virt_to_bus ((void *) &megaCfg->
3038                                                    mailbox64));
3039#endif
3040
3041                mega_i_query_adapter (megaCfg);
3042
3043                if ((subsysid == 0x1111) && (subsysvid == 0x1111)) {
3044
3045                        /*
3046                         * Which firmware
3047                         */
3048                        if( strcmp(megaCfg->fwVer, "3.00") == 0 ||
3049                                        strcmp(megaCfg->fwVer, "3.01") == 0 ) {
3050
3051                                printk( KERN_WARNING
3052                                        "megaraid: Your  card is a Dell PERC 2/SC RAID controller "
3053                                        "with  firmware\nmegaraid: 3.00 or 3.01.  This driver is "
3054                                        "known to have corruption issues\nmegaraid: with those "
3055                                        "firmware versions on this specific card.  In order\n"
3056                                        "megaraid: to protect your data, please upgrade your "
3057                                        "firmware to version\nmegaraid: 3.10 or later, available "
3058                                        "from the Dell Technical Support web\nmegaraid: site at\n"
3059                                        "http://support.dell.com/us/en/filelib/download/"
3060                                        "index.asp?fileid=2940\n"
3061                                );
3062                        }
3063                }
3064
3065                /*
3066                 * If we have a HP 1M(0x60E7)/2M(0x60E8) controller with
3067                 * firmware H.01.07 or H.01.08, disable 64 bit support,
3068                 * since this firmware cannot handle 64 bit addressing
3069                 */
3070
3071                if( (subsysvid == HP_SUBSYS_ID) &&
3072                                ((subsysid == 0x60E7)||(subsysid == 0x60E8)) ) {
3073
3074                        /*
3075                         * which firmware
3076                         */
3077                        if( strcmp(megaCfg->fwVer, "H01.07") == 0 ||
3078                                        strcmp(megaCfg->fwVer, "H01.08") == 0 ) {
3079                                printk(KERN_WARNING
3080                                                "megaraid: Firmware H.01.07 or H.01.08 on 1M/2M "
3081                                                "controllers\nmegaraid: do not support 64 bit "
3082                                                "addressing.\n"
3083                                                "megaraid: DISABLING 64 bit support.\n");
3084                                megaCfg->flag &= ~BOARD_64BIT;
3085                        }
3086                }
3087
3088                if (mega_is_bios_enabled (megaCfg)) {
3089                        mega_hbas[numCtlrs].is_bios_enabled = 1;
3090                }
3091
3092                /*
3093                 * Find out which channel is raid and which is scsi
3094                 */
3095                mega_enum_raid_scsi(megaCfg);
3096                for( i = 0; i < megaCfg->productInfo.SCSIChanPresent; i++ ) {
3097                        if(IS_RAID_CH(i))
3098                                printk(KERN_NOTICE"megaraid: channel[%d] is raid.\n", i+1);
3099                        else
3100                                printk(KERN_NOTICE"megaraid: channel[%d] is scsi.\n", i+1);
3101                }
3102
3103                /*
3104                 * Find out if a logical drive is set as the boot drive. If there is
3105                 * one, will make that as the first logical drive.
3106                 */
3107                mega_get_boot_ldrv(megaCfg);
3108
3109                mega_hbas[numCtlrs].hostdata_addr = megaCfg;
3110
3111                /*
3112                 * Do we support random deletion and addition of logical drives
3113                 */
3114                megaCfg->read_ldidmap = 0;      /* set it after first logdrv delete cmd */
3115                megaCfg->support_random_del = mega_support_random_del(megaCfg);
3116
3117                /* Initialize SCBs */
3118                if (mega_init_scb (megaCfg)) {
3119                        pci_free_consistent (megaCfg->dev,
3120                                             sizeof (mega_mailbox64),
3121                                             (void *) megaCfg->mailbox64ptr,
3122                                             megaCfg->dma_handle64);
3123                        scsi_unregister (host);
3124                        continue;
3125                }
3126
3127                /*
3128                 * Fill in the structure which needs to be passed back to the
3129                 * application when it does an ioctl() for controller related
3130                 * information.
3131                 */
3132
3133                i = numCtlrs;
3134                numCtlrs++;
3135
3136                mcontroller[i].base = megaBase;
3137                mcontroller[i].irq = megaIrq;
3138                mcontroller[i].numldrv = megaCfg->numldrv;
3139                mcontroller[i].pcibus = pciBus;
3140                mcontroller[i].pcidev = pciDev;
3141                mcontroller[i].pcifun = PCI_FUNC (pciDevFun);
3142                mcontroller[i].pciid = pciIdx;
3143                mcontroller[i].pcivendor = pciVendor;
3144                mcontroller[i].pcislot = PCI_SLOT (pciDevFun);
3145                mcontroller[i].uid = (pciBus << 8) | pciDevFun;
3146
3147                numFound++;
3148
3149                /* Set the Mode of addressing to 64 bit */
3150#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3151                if ((megaCfg->flag & BOARD_64BIT) && BITS_PER_LONG == 64)
3152#ifdef __LP64__
3153                        pdev->dma_mask = 0xffffffffffffffff;
3154#else
3155                        pdev->dma_mask = 0xffffffff;
3156#endif
3157#endif
3158                continue;
3159              err_release:
3160                if (flag & BOARD_QUARTZ)
3161                        release_region (megaBase, 16);
3162              err_unregister:
3163                scsi_unregister (host);
3164              err_unmap:
3165                if (flag & BOARD_QUARTZ)
3166                        iounmap ((void *) megaBase);
3167        }
3168        return numFound;
3169}
3170
3171/*---------------------------------------------------------
3172 * Detects if a megaraid controller exists in this system
3173 *---------------------------------------------------------*/
3174
3175int megaraid_detect (Scsi_Host_Template * pHostTmpl)
3176{
3177        int ctlridx = 0, count = 0;
3178
3179#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)  /*0x20300 */
3180        pHostTmpl->proc_dir = &proc_scsi_megaraid;
3181#else
3182        pHostTmpl->proc_name = "megaraid";
3183#endif
3184
3185#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)  /* 0x20100 */
3186        if (!pcibios_present ()) {
3187                printk (KERN_WARNING "megaraid: PCI bios not present."
3188                        M_RD_CRLFSTR);
3189                return 0;
3190        }
3191#endif
3192        skip_id = -1;
3193        if (megaraid && !strncmp (megaraid, "skip", strlen ("skip"))) {
3194                if (megaraid[4] != '\0') {
3195                        skip_id = megaraid[4] - '0';
3196                        if (megaraid[5] != '\0') {
3197                                skip_id = (skip_id * 10) + (megaraid[5] - '0');
3198                        }
3199                }
3200                skip_id = (skip_id > 15) ? -1 : skip_id;
3201        }
3202
3203        printk (KERN_NOTICE "megaraid: " MEGARAID_VERSION);
3204
3205        memset (mega_hbas, 0, sizeof (mega_hbas));
3206
3207        count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3208                                PCI_DEVICE_ID_AMI_MEGARAID, 0);
3209        count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3210                                PCI_DEVICE_ID_AMI_MEGARAID2, 0);
3211        count += mega_findCard (pHostTmpl, 0x8086,
3212                                PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
3213        count += mega_findCard (pHostTmpl, PCI_VENDOR_ID_AMI,
3214                                PCI_DEVICE_ID_AMI_MEGARAID3, BOARD_QUARTZ);
3215
3216
3217#ifdef CONFIG_PROC_FS
3218        if (count) {
3219#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)  /*0x20300 */
3220                mega_proc_dir_entry = proc_mkdir ("megaraid", &proc_root);
3221#else
3222                mega_proc_dir_entry = create_proc_entry ("megaraid",
3223                                                         S_IFDIR | S_IRUGO |
3224                                                         S_IXUGO, &proc_root);
3225#endif
3226                if (!mega_proc_dir_entry)
3227                        printk ("megaraid: failed to create megaraid root\n");
3228                else
3229                        for (ctlridx = 0; ctlridx < count; ctlridx++)
3230                                mega_create_proc_entry (ctlridx,
3231                                                        mega_proc_dir_entry);
3232        }
3233#endif
3234
3235        /*
3236         * Register the driver as a character device, for applications to access
3237         * it for ioctls.
3238         * Ideally, this should go in the init_module() routine, but since it is
3239         * hidden in the file "scsi_module.c" ( included in the end ), we define
3240         * it here
3241         * First argument (major) to register_chrdev implies a dynamic major
3242         * number allocation.
3243         */
3244        if (count) {
3245                major = register_chrdev (0, "megadev", &megadev_fops);
3246
3247                /*
3248                 * Register the Shutdown Notification hook in kernel
3249                 */
3250                if (register_reboot_notifier (&mega_notifier)) {
3251                        printk ("MegaRAID Shutdown routine not registered!!\n");
3252                }
3253
3254                init_MUTEX (&mimd_entry_mtx);
3255        }
3256
3257        return count;
3258}
3259
3260/*---------------------------------------------------------------------
3261 * Release the controller's resources
3262 *---------------------------------------------------------------------*/
3263int megaraid_release (struct Scsi_Host *pSHost)
3264{
3265        mega_host_config *megaCfg;
3266        mega_mailbox *mbox;
3267        u_char mboxData[16];
3268        int i;
3269
3270        megaCfg = (mega_host_config *) pSHost->hostdata;
3271        mbox = (mega_mailbox *) mboxData;
3272
3273        /* Flush cache to disk */
3274        memset (mbox, 0, 16);
3275        mboxData[0] = 0xA;
3276
3277        free_irq (megaCfg->host->irq, megaCfg); /* Must be freed first, otherwise
3278                                                   extra interrupt is generated */
3279
3280        /* Issue a blocking (interrupts disabled) command to the card */
3281        megaIssueCmd (megaCfg, mboxData, NULL, 0);
3282
3283        /* Free our resources */
3284        if (megaCfg->flag & BOARD_QUARTZ) {
3285                iounmap ((void *) megaCfg->base);
3286        } else {
3287                release_region (megaCfg->host->io_port, 16);
3288        }
3289
3290        mega_freeSgList (megaCfg);
3291        pci_free_consistent (megaCfg->dev,
3292                             sizeof (mega_mailbox64),
3293                             (void *) megaCfg->mailbox64ptr,
3294                             megaCfg->dma_handle64);
3295
3296#ifdef CONFIG_PROC_FS
3297        if (megaCfg->controller_proc_dir_entry) {
3298                remove_proc_entry ("stat", megaCfg->controller_proc_dir_entry);
3299                remove_proc_entry ("status",
3300                                   megaCfg->controller_proc_dir_entry);
3301                remove_proc_entry ("config",
3302                                   megaCfg->controller_proc_dir_entry);
3303                remove_proc_entry ("mailbox",
3304                                   megaCfg->controller_proc_dir_entry);
3305                for (i = 0; i < numCtlrs; i++) {
3306                        char buf[12] = { 0 };
3307                        sprintf (buf, "%d", i);
3308                        remove_proc_entry (buf, mega_proc_dir_entry);
3309                }
3310                remove_proc_entry ("megaraid", &proc_root);
3311        }
3312#endif
3313
3314        /*
3315         *      Release the controller memory. A word of warning this frees
3316         *      hostdata and that includes megaCfg-> so be careful what you
3317         *      dereference beyond this point
3318         */
3319         
3320        scsi_unregister (pSHost);
3321
3322        /*
3323         * Unregister the character device interface to the driver. Ideally this
3324         * should have been done in cleanup_module routine. Since this is hidden
3325         * in file "scsi_module.c", we do it here.
3326         * major is the major number of the character device returned by call to
3327         * register_chrdev() routine.
3328         */
3329
3330        unregister_chrdev (major, "megadev");
3331        unregister_reboot_notifier (&mega_notifier);
3332
3333        return 0;
3334}
3335
3336static int mega_is_bios_enabled (mega_host_config * megacfg)
3337{
3338        mega_mailbox *mboxpnt;
3339        unsigned char mbox[16];
3340        int ret;
3341
3342        mboxpnt = (mega_mailbox *) mbox;
3343
3344        memset (mbox, 0, sizeof (mbox));
3345        memset ((void *) megacfg->mega_buffer,
3346                0, sizeof (megacfg->mega_buffer));
3347
3348        /*
3349         * issue command to find out if the BIOS is enabled for this controller
3350         */
3351        mbox[0] = IS_BIOS_ENABLED;
3352        mbox[2] = GET_BIOS;
3353
3354        mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer);
3355
3356        ret = megaIssueCmd (megacfg, mbox, NULL, 0);
3357
3358        return (*(char *) megacfg->mega_buffer);
3359}
3360
3361/*
3362 * Find out what channels are RAID/SCSI
3363 */
3364void
3365mega_enum_raid_scsi(mega_host_config *megacfg)
3366{
3367        mega_mailbox *mboxp;
3368        unsigned char mbox[16];
3369        int             i;
3370
3371#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3372        dma_addr_t      dma_handle;
3373#endif
3374
3375        mboxp = (mega_mailbox *)mbox;
3376
3377        memset(mbox, 0, sizeof(mbox));
3378        /*
3379         * issue command to find out what channels are raid/scsi
3380         */
3381        mbox[0] = CHNL_CLASS;
3382        mbox[2] = GET_CHNL_CLASS;
3383
3384        memset((void *)megacfg->mega_buffer, 0, sizeof(megacfg->mega_buffer));
3385
3386#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3387        dma_handle = pci_map_single(megacfg->dev, (void *)megacfg->mega_buffer,
3388                              (2 * 1024L), PCI_DMA_FROMDEVICE);
3389
3390        mboxp->xferaddr = dma_handle;
3391#else
3392        mboxp->xferaddr = virt_to_bus((void *)megacfg->mega_buffer);
3393#endif
3394
3395        /*
3396         * Non-ROMB firware fail this command, so all channels
3397         * must be shown RAID
3398         */
3399        if( megaIssueCmd(megacfg, mbox, NULL, 0) == 0 ) {
3400                mega_ch_class = *((char *)megacfg->mega_buffer);
3401
3402                for( i = 0; i < NVIRT_CHAN; i++ ) {
3403                        /* logical drives channel is RAID */
3404                        mega_ch_class |= (0x01 << (megacfg->productInfo.SCSIChanPresent+i));
3405                }
3406        }
3407        else {
3408                mega_ch_class = 0xFF;
3409        }
3410
3411
3412#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3413        pci_unmap_single(megacfg->dev, dma_handle,
3414                                  (2 * 1024L), PCI_DMA_FROMDEVICE);
3415#endif
3416
3417}
3418
3419
3420/*
3421 * get the boot logical drive number if enabled
3422 */
3423void
3424mega_get_boot_ldrv(mega_host_config *megacfg)
3425{
3426        mega_mailbox *mboxp;
3427        unsigned char mbox[16];
3428        struct private_bios_data *prv_bios_data;
3429        u16             cksum = 0;
3430        char    *cksum_p;
3431        int             i;
3432
3433#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3434        dma_addr_t      dma_handle;
3435#endif
3436
3437        mboxp = (mega_mailbox *)mbox;
3438
3439        memset(mbox, 0, sizeof(mbox));
3440
3441        mbox[0] = BIOS_PVT_DATA;
3442        mbox[2] = GET_BIOS_PVT_DATA;
3443
3444        memset((void *)megacfg->mega_buffer, 0, sizeof(megacfg->mega_buffer));
3445
3446#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3447        dma_handle = pci_map_single(megacfg->dev, (void *)megacfg->mega_buffer,
3448                              (2 * 1024L), PCI_DMA_FROMDEVICE);
3449
3450        mboxp->xferaddr = dma_handle;
3451#else
3452        mboxp->xferaddr = virt_to_bus((void *)megacfg->mega_buffer);
3453#endif
3454
3455        megacfg->boot_ldrv_enabled = 0;
3456        megacfg->boot_ldrv = 0;
3457        if( megaIssueCmd(megacfg, mbox, NULL, 0) == 0 ) {
3458
3459                prv_bios_data = (struct private_bios_data *)megacfg->mega_buffer;
3460
3461                cksum = 0;
3462                cksum_p = (char *)prv_bios_data;
3463                for( i = 0; i < 14; i++ ) {
3464                        cksum += (u16)(*cksum_p++);
3465                }
3466
3467                if( prv_bios_data->cksum == (u16)(0-cksum) ) {
3468                        megacfg->boot_ldrv_enabled = 1;
3469                        megacfg->boot_ldrv = prv_bios_data->boot_ldrv;
3470                }
3471        }
3472
3473#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
3474        pci_unmap_single(megacfg->dev, dma_handle,
3475                                  (2 * 1024L), PCI_DMA_FROMDEVICE);
3476#endif
3477
3478}
3479
3480
3481static inline void mega_freeSgList (mega_host_config * megaCfg)
3482{
3483        int i;
3484
3485        for (i = 0; i < megaCfg->max_cmds; i++) {
3486                if (megaCfg->scbList[i].sgList)
3487                        pci_free_consistent (megaCfg->dev,
3488                                             sizeof (mega_64sglist) *
3489                                             MAX_SGLIST,
3490                                             megaCfg->scbList[i].sgList,
3491                                             megaCfg->scbList[i].
3492                                             dma_sghandle64);
3493#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)  /* 0x020400 */
3494                        kfree (megaCfg->scbList[i].sgList);     /* free sgList */
3495#endif
3496        }
3497}
3498
3499/*----------------------------------------------
3500 * Get information about the card/driver
3501 *----------------------------------------------*/
3502const char *megaraid_info (struct Scsi_Host *pSHost)
3503{
3504        static char buffer[512];
3505        mega_host_config *megaCfg;
3506
3507        megaCfg = (mega_host_config *) pSHost->hostdata;
3508
3509        sprintf (buffer,
3510                 "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
3511                 megaCfg->fwVer, megaCfg->productInfo.MaxConcCmds,
3512                 megaCfg->host->max_id, megaCfg->host->max_channel,
3513                 megaCfg->host->max_lun);
3514        return buffer;
3515}
3516
3517/*-----------------------------------------------------------------
3518 * Perform a SCSI command
3519 * Mailbox area:
3520 *   00 01 command
3521 *   01 01 command id
3522 *   02 02 # of sectors
3523 *   04 04 logical bus address
3524 *   08 04 physical buffer address
3525 *   0C 01 logical drive #
3526 *   0D 01 length of scatter/gather list
3527 *   0E 01 reserved
3528 *   0F 01 mailbox busy
3529 *   10 01 numstatus byte
3530 *   11 01 status byte
3531 *-----------------------------------------------------------------*/
3532int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
3533{
3534        DRIVER_LOCK_T mega_host_config * megaCfg;
3535        mega_scb *pScb;
3536        char *user_area = NULL;
3537
3538        megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3539        DRIVER_LOCK (megaCfg);
3540
3541        if (!(megaCfg->flag & (1L << SCpnt->channel))) {
3542                if (SCpnt->channel < megaCfg->productInfo.SCSIChanPresent)
3543                        printk ( KERN_NOTICE
3544                                "scsi%d: scanning channel %d for devices.\n",
3545                                megaCfg->host->host_no, SCpnt->channel);
3546                else
3547                        printk ( KERN_NOTICE
3548                                "scsi%d: scanning virtual channel %d for logical drives.\n",
3549                                megaCfg->host->host_no,
3550                                SCpnt->channel-megaCfg->productInfo.SCSIChanPresent+1);
3551
3552                megaCfg->flag |= (1L << SCpnt->channel);
3553        }
3554
3555        SCpnt->scsi_done = pktComp;
3556
3557        if (mega_driver_ioctl (megaCfg, SCpnt))
3558                return 0;
3559
3560        /* If driver in abort or reset.. cancel this command */
3561        if (megaCfg->flag & IN_ABORT) {
3562                SCpnt->result = (DID_ABORT << 16);
3563                /* Add Scsi_Command to end of completed queue */
3564                if (megaCfg->qCompletedH == NULL) {
3565                        megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
3566                } else {
3567                        megaCfg->qCompletedT->host_scribble =
3568                            (unsigned char *) SCpnt;
3569                        megaCfg->qCompletedT = SCpnt;
3570                }
3571                megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
3572                megaCfg->qCcnt++;
3573
3574                DRIVER_UNLOCK (megaCfg);
3575                return 0;
3576        } else if (megaCfg->flag & IN_RESET) {
3577                SCpnt->result = (DID_RESET << 16);
3578                /* Add Scsi_Command to end of completed queue */
3579                if (megaCfg->qCompletedH == NULL) {
3580                        megaCfg->qCompletedH = megaCfg->qCompletedT = SCpnt;
3581                } else {
3582                        megaCfg->qCompletedT->host_scribble =
3583                            (unsigned char *) SCpnt;
3584                        megaCfg->qCompletedT = SCpnt;
3585                }
3586                megaCfg->qCompletedT->host_scribble = (unsigned char *) NULL;
3587                megaCfg->qCcnt++;
3588
3589                DRIVER_UNLOCK (megaCfg);
3590                return 0;
3591        }
3592
3593        megaCfg->flag |= IN_QUEUE;
3594        /* Allocate and build a SCB request */
3595        if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
3596
3597                /*
3598                 * Check if the HBA is in quiescent state, e.g., during a delete
3599                 * logical drive opertion. If it is, queue the commands in the
3600                 * internal queue until the delete operation is complete.
3601                 */
3602                if( ! megaCfg->quiescent ) {
3603                        /* Add SCB to the head of the pending queue */
3604                        if (megaCfg->qPendingH == NULL) {
3605                                megaCfg->qPendingH = megaCfg->qPendingT = pScb;
3606                        } else {
3607                                megaCfg->qPendingT->next = pScb;
3608                                megaCfg->qPendingT = pScb;
3609                        }
3610                        megaCfg->qPendingT->next = NULL;
3611                        megaCfg->qPcnt++;
3612
3613                        if (mega_runpendq (megaCfg) == -1) {
3614                                DRIVER_UNLOCK (megaCfg);
3615                                return 0;
3616                        }
3617                }
3618                else {
3619                        /* Add SCB to the internal queue */
3620                        if (megaCfg->int_qh == NULL) {
3621                                megaCfg->int_qh = megaCfg->int_qt = pScb;
3622                        } else {
3623                                megaCfg->int_qt->next = pScb;
3624                                megaCfg->int_qt = pScb;
3625                        }
3626                        megaCfg->int_qt->next = NULL;
3627                        megaCfg->int_qlen++;
3628                }
3629
3630                if (pScb->SCpnt->cmnd[0] == M_RD_IOCTL_CMD_NEW) {
3631                        init_MUTEX_LOCKED (&pScb->ioctl_sem);
3632                        IO_UNLOCK_IRQ(megaCfg->host);
3633                        down (&pScb->ioctl_sem);
3634                user_area = (char *)*((u32*)&pScb->SCpnt->cmnd[4]);
3635                        if (copy_to_user
3636                            (user_area, pScb->buff_ptr, pScb->iDataSize)) {
3637                                printk
3638                                    ("megaraid: Error copying ioctl return value to user buffer.\n");
3639                                pScb->SCpnt->result = (DID_ERROR << 16);
3640                        }
3641                    IO_LOCK_IRQ(megaCfg->host);
3642                        DRIVER_LOCK (megaCfg);
3643                        kfree (pScb->buff_ptr);
3644                        pScb->buff_ptr = NULL;
3645                        mega_cmd_done (megaCfg, pScb, pScb->SCpnt->result);
3646                        mega_rundoneq (megaCfg);
3647                        mega_runpendq (megaCfg);
3648                        DRIVER_UNLOCK (megaCfg);
3649                }
3650
3651                megaCfg->flag &= ~IN_QUEUE;
3652
3653        }
3654
3655        DRIVER_UNLOCK (megaCfg);
3656        return 0;
3657}
3658
3659/*----------------------------------------------------------------------
3660 * Issue a blocking command to the controller
3661 *----------------------------------------------------------------------*/
3662volatile static int internal_done_flag = 0;
3663volatile static int internal_done_errcode = 0;
3664
3665static DECLARE_WAIT_QUEUE_HEAD (internal_wait);
3666
3667static void internal_done (Scsi_Cmnd * SCpnt)
3668{
3669        internal_done_errcode = SCpnt->result;
3670        internal_done_flag++;
3671        wake_up (&internal_wait);
3672}
3673
3674/* shouldn't be used, but included for completeness */
3675
3676int megaraid_command (Scsi_Cmnd * SCpnt)
3677{
3678        internal_done_flag = 0;
3679
3680        /* Queue command, and wait until it has completed */
3681        megaraid_queue (SCpnt, internal_done);
3682
3683        while (!internal_done_flag) {
3684                interruptible_sleep_on (&internal_wait);
3685        }
3686
3687        return internal_done_errcode;
3688}
3689
3690/*---------------------------------------------------------------------
3691 * Abort a previous SCSI request
3692 *---------------------------------------------------------------------*/
3693int megaraid_abort (Scsi_Cmnd * SCpnt)
3694{
3695        mega_host_config *megaCfg;
3696        int rc;                 /*, idx; */
3697        mega_scb *pScb;
3698
3699        rc = SCSI_ABORT_NOT_RUNNING;
3700
3701        megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3702
3703        megaCfg->flag |= IN_ABORT;
3704
3705        for (pScb = megaCfg->qPendingH; pScb; pScb = pScb->next) {
3706                if (pScb->SCpnt == SCpnt) {
3707                        /* Found an aborting command */
3708#if DEBUG
3709                        showMbox (pScb);
3710#endif
3711
3712        /*
3713         * If the command is queued to be issued to the firmware, abort the scsi cmd,
3714         * If the command is already aborted in a previous call to the _abort entry
3715         *  point, return SCSI_ABORT_SNOOZE, suggesting a reset.
3716         * If the command is issued to the firmware, which might complete after
3717         *  some time, we will mark the scb as aborted, and return to the mid layer,
3718         *  that abort could not be done.
3719         *  In the ISR, when this command actually completes, we will perform a normal
3720         *  completion.
3721         *
3722         * Oct 27, 1999
3723         */
3724
3725                        switch (pScb->state) {
3726                        case SCB_ABORTED:       /* Already aborted */
3727                                rc = SCSI_ABORT_SNOOZE;
3728                                break;
3729                        case SCB_ISSUED:        /* Waiting on ISR result */
3730                                rc = SCSI_ABORT_NOT_RUNNING;
3731                                pScb->state = SCB_ABORTED;
3732                                break;
3733                        case SCB_ACTIVE:        /* still on the pending queue */
3734                                mega_freeSCB (megaCfg, pScb);
3735                                SCpnt->result = (DID_ABORT << 16);
3736                                if (megaCfg->qCompletedH == NULL) {
3737                                        megaCfg->qCompletedH =
3738                                            megaCfg->qCompletedT = SCpnt;
3739                                } else {
3740                                        megaCfg->qCompletedT->host_scribble =
3741                                            (unsigned char *) SCpnt;
3742                                        megaCfg->qCompletedT = SCpnt;
3743                                }
3744                                megaCfg->qCompletedT->host_scribble =
3745                                    (unsigned char *) NULL;
3746                                megaCfg->qCcnt++;
3747                                rc = SCSI_ABORT_SUCCESS;
3748                                break;
3749                        default:
3750                                printk
3751                                    ("megaraid_abort: unknown command state!!\n");
3752                                rc = SCSI_ABORT_NOT_RUNNING;
3753                                break;
3754                        }
3755                        break;
3756                }
3757        }
3758
3759        megaCfg->flag &= ~IN_ABORT;
3760
3761#if DEBUG
3762        if (megaCfg->flag & IN_QUEUE)
3763                printk ("ma:flag is in queue\n");
3764        if (megaCfg->qCompletedH == NULL)
3765                printk ("ma:qchead == null\n");
3766#endif
3767
3768        /*
3769         * This is required here to complete any completed requests to be communicated
3770         * over to the mid layer.
3771         * Calling just mega_rundoneq() did not work.
3772         */
3773        if (megaCfg->qCompletedH) {
3774                SCpnt = megaCfg->qCompletedH;
3775                megaCfg->qCompletedH = (Scsi_Cmnd *) SCpnt->host_scribble;
3776                megaCfg->qCcnt--;
3777
3778                SCpnt->host_scribble = (unsigned char *) NULL;
3779                /* Callback */
3780                callDone (SCpnt);
3781        }
3782        mega_rundoneq (megaCfg);
3783
3784        return rc;
3785}
3786
3787/*---------------------------------------------------------------------
3788 * Reset a previous SCSI request
3789 *---------------------------------------------------------------------*/
3790
3791int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
3792{
3793        mega_host_config *megaCfg;
3794        int idx;
3795        int rc;
3796        mega_scb *pScb;
3797
3798        rc = SCSI_RESET_NOT_RUNNING;
3799        megaCfg = (mega_host_config *) SCpnt->host->hostdata;
3800
3801        megaCfg->flag |= IN_RESET;
3802
3803        printk
3804            ("megaraid_RESET: %.08lx cmd=%.02x <c=%d.t=%d.l=%d>, flag = %x\n",
3805             SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
3806             SCpnt->target, SCpnt->lun, rstflags);
3807
3808        TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
3809                SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel,
3810                SCpnt->target, SCpnt->lun));
3811
3812        /*
3813         * Walk list of SCBs for any that are still outstanding
3814         */
3815        for (idx = 0; idx < megaCfg->max_cmds; idx++) {
3816                if (megaCfg->scbList[idx].state != SCB_FREE) {
3817                        SCpnt = megaCfg->scbList[idx].SCpnt;
3818                        pScb = &megaCfg->scbList[idx];
3819                        if (SCpnt != NULL) {
3820                                pScb->state = SCB_RESET;
3821                                break;
3822                        }
3823                }
3824        }
3825
3826        megaCfg->flag &= ~IN_RESET;
3827
3828        mega_rundoneq (megaCfg);
3829        return rc;
3830}
3831
3832#ifdef CONFIG_PROC_FS
3833/* Following code handles /proc fs  */
3834static int proc_printf (mega_host_config * megaCfg, const char *fmt, ...)
3835{
3836        va_list args;
3837        int i;
3838
3839        if (megaCfg->procidx > PROCBUFSIZE)
3840                return 0;
3841
3842        va_start (args, fmt);
3843        i = vsprintf ((megaCfg->procbuf + megaCfg->procidx), fmt, args);
3844        va_end (args);
3845
3846        megaCfg->procidx += i;
3847        return i;
3848}
3849
3850static int proc_read_config (char *page, char **start, off_t offset,
3851                  int count, int *eof, void *data)
3852{
3853
3854        mega_host_config *megaCfg = (mega_host_config *) data;
3855
3856        *start = page;
3857
3858        if (megaCfg->productInfo.ProductName[0] != 0)
3859                proc_printf (megaCfg, "%s\n", megaCfg->productInfo.ProductName);
3860
3861        proc_printf (megaCfg, "Controller Type: ");
3862
3863        if (megaCfg->flag & BOARD_QUARTZ)
3864                proc_printf (megaCfg, "438/466/467/471/493\n");
3865        else
3866                proc_printf (megaCfg, "418/428/434\n");
3867
3868        if (megaCfg->flag & BOARD_40LD)
3869                proc_printf (megaCfg,
3870                             "Controller Supports 40 Logical Drives\n");
3871
3872        if (megaCfg->flag & BOARD_64BIT)
3873                proc_printf (megaCfg,
3874                             "Controller / Driver uses 64 bit memory addressing\n");
3875
3876        proc_printf (megaCfg, "Base = %08x, Irq = %d, ", megaCfg->base,
3877                     megaCfg->host->irq);
3878
3879        proc_printf (megaCfg, "Logical Drives = %d, Channels = %d\n",
3880                     megaCfg->numldrv, megaCfg->productInfo.SCSIChanPresent);
3881
3882        proc_printf (megaCfg, "Version =%s:%s, DRAM = %dMb\n",
3883                     megaCfg->fwVer, megaCfg->biosVer,
3884                     megaCfg->productInfo.DramSize);
3885
3886        proc_printf (megaCfg,
3887                     "Controller Queue Depth = %d, Driver Queue Depth = %d\n",
3888                     megaCfg->productInfo.MaxConcCmds, megaCfg->max_cmds);
3889        COPY_BACK;
3890        return count;
3891}
3892
3893static int proc_read_stat (char *page, char **start, off_t offset,
3894                int count, int *eof, void *data)
3895{
3896        int i;
3897        mega_host_config *megaCfg = (mega_host_config *) data;
3898
3899        *start = page;
3900
3901        proc_printf (megaCfg, "Statistical Information for this controller\n");
3902        proc_printf (megaCfg, "Interrupts Collected = %lu\n",
3903                     megaCfg->nInterrupts);
3904
3905        for (i = 0; i < megaCfg->numldrv; i++) {
3906                proc_printf (megaCfg, "Logical Drive %d:\n", i);
3907
3908                proc_printf (megaCfg,
3909                             "\tReads Issued = %lu, Writes Issued = %lu\n",
3910                             megaCfg->nReads[i], megaCfg->nWrites[i]);
3911
3912                proc_printf (megaCfg,
3913                             "\tSectors Read = %lu, Sectors Written = %lu\n\n",
3914                             megaCfg->nReadBlocks[i], megaCfg->nWriteBlocks[i]);
3915
3916        }
3917
3918        COPY_BACK;
3919        return count;
3920}
3921
3922static int proc_read_status (char *page, char **start, off_t offset,
3923                  int count, int *eof, void *data)
3924{
3925        mega_host_config *megaCfg = (mega_host_config *) data;
3926        *start = page;
3927
3928        proc_printf (megaCfg, "TBD\n");
3929        COPY_BACK;
3930        return count;
3931}
3932
3933static int proc_read_mbox (char *page, char **start, off_t offset,
3934                int count, int *eof, void *data)
3935{
3936
3937        mega_host_config *megaCfg = (mega_host_config *) data;
3938        volatile mega_mailbox *mbox = megaCfg->mbox;
3939
3940        *start = page;
3941
3942        proc_printf (megaCfg, "Contents of Mail Box Structure\n");
3943        proc_printf (megaCfg, "  Fw Command   = 0x%02x\n", mbox->cmd);
3944        proc_printf (megaCfg, "  Cmd Sequence = 0x%02x\n", mbox->cmdid);
3945        proc_printf (megaCfg, "  No of Sectors= %04d\n", mbox->numsectors);
3946        proc_printf (megaCfg, "  LBA          = 0x%02x\n", mbox->lba);
3947        proc_printf (megaCfg, "  DTA          = 0x%08x\n", mbox->xferaddr);
3948        proc_printf (megaCfg, "  Logical Drive= 0x%02x\n", mbox->logdrv);
3949        proc_printf (megaCfg, "  No of SG Elmt= 0x%02x\n", mbox->numsgelements);
3950        proc_printf (megaCfg, "  Busy         = %01x\n", mbox->busy);
3951        proc_printf (megaCfg, "  Status       = 0x%02x\n", mbox->status);
3952
3953        /* proc_printf(megaCfg, "Dump of MailBox\n");
3954        for (i = 0; i < 16; i++)
3955                proc_printf(megaCfg, "%02x ",*(mbox + i));
3956
3957        proc_printf(megaCfg, "\n\nNumber of Status = %02d\n",mbox->numstatus);
3958
3959        for (i = 0; i < 46; i++) {
3960                proc_printf(megaCfg,"%02d ",*(mbox + 16 + i));
3961        if (i%16)
3962                proc_printf(megaCfg,"\n");
3963        }
3964
3965        if (!mbox->numsgelements) {
3966                dta = phys_to_virt(mbox->xferaddr);
3967                for (i = 0; i < mbox->numsgelements; i++)
3968                        if (dta) {
3969                                proc_printf(megaCfg,"Addr = %08x\n", (ulong)*(dta + i));                        proc_printf(megaCfg,"Length = %08x\n",
3970                                        (ulong)*(dta + i + 4));
3971                        }
3972        }*/
3973        COPY_BACK;
3974        return count;
3975}
3976
3977#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)  /*0x20300 */
3978#define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string, \
3979                                         S_IRUSR | S_IFREG,\
3980                                         controller_proc_dir_entry,\
3981                                         fxn, megaCfg)
3982#else
3983#define CREATE_READ_PROC(string, fxn) create_proc_read_entry(string,S_IRUSR | S_IFREG, controller_proc_dir_entry, fxn, megaCfg)
3984
3985static struct proc_dir_entry *
3986create_proc_read_entry (const char *string,
3987                        int mode,
3988                        struct proc_dir_entry *parent,
3989                        read_proc_t * fxn, mega_host_config * megaCfg)
3990{
3991        struct proc_dir_entry *temp = NULL;
3992
3993        temp = kmalloc (sizeof (struct proc_dir_entry), GFP_KERNEL);
3994        if (!temp)
3995                return NULL;
3996        memset (temp, 0, sizeof (struct proc_dir_entry));
3997
3998        if ((temp->name = kmalloc (strlen (string) + 1, GFP_KERNEL)) == NULL) {
3999                kfree (temp);
4000                return NULL;
4001        }
4002
4003        strcpy ((char *) temp->name, string);
4004        temp->namelen = strlen (string);
4005        temp->mode = mode; /*S_IFREG | S_IRUSR */ ;
4006        temp->data = (void *) megaCfg;
4007        temp->read_proc = fxn;
4008        proc_register (parent, temp);
4009        return temp;
4010}
4011#endif
4012
4013static void mega_create_proc_entry (int index, struct proc_dir_entry *parent)
4014{
4015        u_char string[64] = { 0 };
4016        mega_host_config *megaCfg = megaCtlrs[index];
4017        struct proc_dir_entry *controller_proc_dir_entry = NULL;
4018
4019        sprintf (string, "%d", index);
4020
4021#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0)  /*0x20300 */
4022        controller_proc_dir_entry =
4023            megaCfg->controller_proc_dir_entry = proc_mkdir (string, parent);
4024#else
4025        controller_proc_dir_entry =
4026            megaCfg->controller_proc_dir_entry =
4027            create_proc_entry (string, S_IFDIR | S_IRUGO | S_IXUGO, parent);
4028#endif
4029
4030        if (!controller_proc_dir_entry)
4031                printk ("\nmegaraid: proc_mkdir failed\n");
4032        else {
4033                megaCfg->proc_read =
4034                    CREATE_READ_PROC ("config", proc_read_config);
4035                megaCfg->proc_status =
4036                    CREATE_READ_PROC ("status", proc_read_status);
4037                megaCfg->proc_stat = CREATE_READ_PROC ("stat", proc_read_stat);
4038                megaCfg->proc_mbox =
4039                    CREATE_READ_PROC ("mailbox", proc_read_mbox);
4040        }
4041
4042}
4043#endif                          /* CONFIG_PROC_FS */
4044
4045/*-------------------------------------------------------------
4046 * Return the disk geometry for a particular disk
4047 * Input:
4048 *   Disk *disk - Disk geometry
4049 *   struct block_device *dev - Device node
4050 *   int *geom  - Returns geometry fields
4051 *     geom[0] = heads
4052 *     geom[1] = sectors
4053 *     geom[2] = cylinders
4054 *-------------------------------------------------------------*/
4055int megaraid_biosparam (struct scsi_device *sdev, struct block_device *bdev,
4056                                sector_t capacity, int *geom)
4057{
4058        int heads, sectors, cylinders;
4059        mega_host_config *megaCfg;
4060
4061        /* Get pointer to host config structure */
4062        megaCfg = (mega_host_config *) sdev->host->hostdata;
4063
4064        if( IS_RAID_CH(sdev->channel)) {
4065                        /* Default heads (64) & sectors (32) */
4066                        heads = 64;
4067                        sectors = 32;
4068                        cylinders = (unsigned long)capacity >> 11;
4069
4070                        /* Handle extended translation size for logical drives > 1Gb */
4071                        if (capacity >= 0x200000) {
4072                                heads = 255;
4073                                sectors = 63;
4074                                cylinders = (unsigned long)capacity / (heads * sectors);
4075                        }
4076
4077                        /* return result */
4078                        geom[0] = heads;
4079                        geom[1] = sectors;
4080                        geom[2] = cylinders;
4081        }
4082        else {
4083                if( mega_partsize(bdev, capacity, geom) == 0 ) return 0;
4084
4085                printk(KERN_WARNING
4086                                "megaraid: invalid partition on this disk on channel %d\n",
4087                                sdev->channel);
4088
4089                /* Default heads (64) & sectors (32) */
4090                heads = 64;
4091                sectors = 32;
4092                cylinders = capacity >> 11;
4093
4094                /* Handle extended translation size for logical drives > 1Gb */
4095                if (capacity >= 0x200000) {
4096                        heads = 255;
4097                        sectors = 63;
4098                        cylinders = (unsigned long)capacity / (heads * sectors);
4099                }
4100
4101                /* return result */
4102                geom[0] = heads;
4103                geom[1] = sectors;
4104                geom[2] = cylinders;
4105        }
4106
4107        return 0;
4108}
4109
4110/*
4111 * Function : static int mega_partsize(Disk * disk, struct block_device *bdev, int *geom)
4112 *
4113 * Purpose : to determine the BIOS mapping used to create the partition
4114 *                      table, storing the results (cyls, hds, and secs) in geom
4115 *
4116 * Note:        Code is picked from scsicam.h
4117 *
4118 * Returns : -1 on failure, 0 on success.
4119 */
4120static int
4121mega_partsize(struct block_device *bdev, sector_t capacity, int *geom)
4122{
4123        struct partition *p, *largest = NULL;
4124        int i, largest_cyl;
4125        int heads, cyls, sectors;
4126        unsigned char *buf;
4127
4128        if (!(buf = scsi_bios_ptable(bdev)))
4129                return -1;
4130
4131        if( *(unsigned short *)(buf + 64) == 0xAA55 ) {
4132
4133                for( largest_cyl = -1, p = (struct partition *)buf,
4134                                i = 0; i < 4; ++i, ++p) {
4135
4136                        if (!p->sys_ind) continue;
4137
4138                        cyls = p->end_cyl + ((p->end_sector & 0xc0) << 2);
4139
4140                        if(cyls >= largest_cyl) {
4141                                largest_cyl = cyls;
4142                                largest = p;
4143                        }
4144                }
4145        }
4146
4147        if (largest) {
4148                heads = largest->end_head + 1;
4149                sectors = largest->end_sector & 0x3f;
4150
4151                if (heads == 0 || sectors == 0) {
4152                        kfree(buf);
4153                        return -1;
4154                }
4155
4156                cyls = (unsigned long)capacity/(heads * sectors);
4157
4158                geom[0] = heads;
4159                geom[1] = sectors;
4160                geom[2] = cyls;
4161
4162                kfree(buf);
4163                return 0;
4164        }
4165
4166        kfree(buf);
4167        return -1;
4168}
4169
4170
4171/*
4172 * This routine will be called when the use has done a forced shutdown on the
4173 * system. Flush the Adapter cache, that's the most we can do.
4174 */
4175static int megaraid_reboot_notify (struct notifier_block *this, unsigned long code,
4176                        void *unused)
4177{
4178        struct Scsi_Host *pSHost;
4179        mega_host_config *megaCfg;
4180        mega_mailbox *mbox;
4181        u_char mboxData[16];
4182        int i;
4183
4184        if (code == SYS_DOWN || code == SYS_HALT) {
4185                for (i = 0; i < numCtlrs; i++) {
4186                        pSHost = megaCtlrs[i]->host;
4187
4188                        megaCfg = (mega_host_config *) pSHost->hostdata;
4189                        mbox = (mega_mailbox *) mboxData;
4190
4191                        /* Flush cache to disk */
4192                        memset (mbox, 0, 16);
4193                        mboxData[0] = 0xA;
4194
4195                        /*
4196                         * Free irq, otherwise extra interrupt is generated
4197                         */
4198                        free_irq (megaCfg->host->irq, megaCfg);
4199
4200                        /*
4201                           * Issue a blocking (interrupts disabled) command to
4202                           * the card
4203                         */
4204                        megaIssueCmd (megaCfg, mboxData, NULL, 0);
4205                }
4206        }
4207        return NOTIFY_DONE;
4208}
4209
4210static int mega_init_scb (mega_host_config * megacfg)
4211{
4212        int idx;
4213
4214#if DEBUG
4215        if (megacfg->max_cmds >= MAX_COMMANDS) {
4216                printk ("megaraid:ctlr max cmds = %x : MAX_CMDS = %x",
4217                        megacfg->max_cmds, MAX_COMMANDS);
4218        }
4219#endif
4220
4221        for (idx = megacfg->max_cmds - 1; idx >= 0; idx--) {
4222
4223                megacfg->scbList[idx].idx = idx;
4224
4225                /*
4226                 * ISR will make this flag zero to indicate the command has been
4227                 * completed. This is only for user ioctl calls. Rest of the driver
4228                 * and the mid-layer operations are not connected with this flag.
4229                 */
4230
4231#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4232                megacfg->scbList[idx].sgList =
4233                    pci_alloc_consistent (megacfg->dev,
4234                                          sizeof (mega_64sglist) * MAX_SGLIST,
4235                                          &(megacfg->scbList[idx].
4236                                            dma_sghandle64));
4237
4238                megacfg->scbList[idx].sg64List =
4239                    (mega_64sglist *) megacfg->scbList[idx].sgList;
4240#else
4241                megacfg->scbList[idx].sgList = kmalloc (sizeof (mega_sglist) * MAX_SGLIST, GFP_ATOMIC | GFP_DMA);
4242#endif
4243
4244                if (megacfg->scbList[idx].sgList == NULL) {
4245                        printk (KERN_WARNING
4246                                "Can't allocate sglist for id %d\n", idx);
4247                        mega_freeSgList (megacfg);
4248                        return -1;
4249                }
4250#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4251                megacfg->scbList[idx].pthru = pci_alloc_consistent (megacfg->dev,
4252                                          sizeof (mega_passthru),
4253                                          &(megacfg->scbList[idx].
4254                                            dma_passthruhandle64));
4255
4256                if (megacfg->scbList[idx].pthru == NULL) {
4257                        printk (KERN_WARNING
4258                                "Can't allocate passthru for id %d\n", idx);
4259                }
4260
4261                megacfg->scbList[idx].epthru =
4262                        pci_alloc_consistent(
4263                                megacfg->dev, sizeof(mega_ext_passthru),
4264                                &(megacfg->scbList[idx].dma_ext_passthruhandle64)
4265                        );
4266
4267                if (megacfg->scbList[idx].epthru == NULL) {
4268                        printk (KERN_WARNING
4269                                "Can't allocate extended passthru for id %d\n", idx);
4270                }
4271                /* 
4272                 * Allocate a 256 Byte Bounce Buffer for handling INQ/RD_CAPA 
4273                 */
4274                megacfg->scbList[idx].bounce_buffer = pci_alloc_consistent (megacfg->dev,
4275                                          256,
4276                                          &(megacfg->scbList[idx].
4277                                            dma_bounce_buffer));
4278
4279                if (!megacfg->scbList[idx].bounce_buffer)
4280                        printk
4281                            ("megaraid: allocation for bounce buffer failed\n");
4282
4283                megacfg->scbList[idx].dma_type = M_RD_DMA_TYPE_NONE;
4284#endif
4285
4286                if (idx < MAX_COMMANDS) {
4287                        /*
4288                         * Link to free list
4289                         * lock not required since we are loading the driver, so no
4290                         * commands possible right now.
4291                         */
4292                        enq_scb_freelist (megacfg, &megacfg->scbList[idx],
4293                                          NO_LOCK, INTR_ENB);
4294
4295                }
4296        }
4297
4298        return 0;
4299}
4300
4301/*
4302 * Enqueues a SCB
4303 */
4304static void enq_scb_freelist (mega_host_config * megacfg, mega_scb * scb, int lock,
4305                  int intr)
4306{
4307
4308        if (lock == INTERNAL_LOCK || intr == INTR_DIS) {
4309                if (intr == INTR_DIS)
4310                        spin_lock_irq (&megacfg->lock_free);
4311                else
4312                        spin_lock (&megacfg->lock_free);
4313        }
4314
4315        scb->state = SCB_FREE;
4316        scb->SCpnt = NULL;
4317
4318        if (megacfg->qFreeH == (mega_scb *) NULL) {
4319                megacfg->qFreeH = megacfg->qFreeT = scb;
4320        } else {
4321                megacfg->qFreeT->next = scb;
4322                megacfg->qFreeT = scb;
4323        }
4324
4325        megacfg->qFreeT->next = NULL;
4326        megacfg->qFcnt++;
4327
4328        if (lock == INTERNAL_LOCK || intr == INTR_DIS) {
4329                if (intr == INTR_DIS)
4330                        spin_unlock_irq (&megacfg->lock_free);
4331                else
4332                        spin_unlock (&megacfg->lock_free);
4333        }
4334}
4335
4336static int megadev_ioctl_entry (struct inode *inode, struct file *filep,
4337                     unsigned int cmd, unsigned long arg)
4338{
4339        int ret = -1;
4340
4341        /*
4342         * We do not allow parallel ioctls to the driver as of now.
4343         */
4344        down (&mimd_entry_mtx);
4345        ret = megadev_ioctl (inode, filep, cmd, arg);
4346        up (&mimd_entry_mtx);
4347
4348        return ret;
4349
4350}
4351
4352static int megadev_ioctl (struct inode *inode, struct file *filep,
4353               unsigned int cmd, unsigned long arg)
4354{
4355        int adapno;
4356        u32 inlen;
4357        struct uioctl_t ioc;
4358        char *kvaddr = NULL;
4359        int nadap = numCtlrs;
4360        u8 opcode;
4361        u32 outlen;
4362        int ret;
4363        u8 subopcode;
4364        Scsi_Cmnd *scsicmd;
4365        struct Scsi_Host *shpnt;
4366        char *uaddr;
4367        struct uioctl_t *uioc;
4368        dma_addr_t      dma_addr;
4369        u32             length;
4370        mega_host_config *megacfg = NULL;
4371#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* 0x020400 */
4372        struct pci_dev pdev;
4373        struct pci_dev *pdevp = &pdev;
4374#else
4375        char *pdevp = NULL;
4376#endif
4377        IO_LOCK_T;
4378
4379        if (!inode)
4380                return -EINVAL;
4381
4382        if (_IOC_TYPE (cmd) != MEGAIOC_MAGIC)
4383                return (-EINVAL);
4384
4385        /*
4386         * Get the user ioctl structure
4387         */
4388        ret = verify_area (VERIFY_WRITE, (char *) arg, sizeof (struct uioctl_t));
4389
4390        if (ret)
4391                return ret;
4392
4393        if(copy_from_user (&ioc, (char *) arg, sizeof (struct uioctl_t)))
4394                return -EFAULT;
4395
4396        /*
4397         * The first call the applications should make is to find out the
4398         * number of controllers in the system. The next logical call should
4399         * be for getting the list of controllers in the system as detected
4400         * by the driver.
4401         */
4402
4403        /*
4404         * Get the opcode and subopcode for the commands
4405         */
4406        opcode = ioc.ui.fcs.opcode;
4407        subopcode = ioc.ui.fcs.subopcode;
4408
4409        switch (opcode) {
4410        case M_RD_DRIVER_IOCTL_INTERFACE:
4411                switch (subopcode) {
4412                case MEGAIOC_QDRVRVER:  /* Query driver version */
4413                        put_user (driver_ver, (u32 *) ioc.data);
4414                        return 0;
4415
4416                case MEGAIOC_QNADAP:    /* Get # of adapters */
4417                        put_user (nadap, (int *) ioc.data);
4418                        return nadap;
4419
4420                case MEGAIOC_QADAPINFO: /* Get adapter information */
4421                        /*
4422                         * which adapter?
4423                         */
4424                        adapno = ioc.ui.fcs.adapno;
4425
4426                        /*
4427                         * The adapter numbers do not start with 0, at least in
4428                         * the user space. This is just to make sure, 0 is not the
4429                         * default value which will refer to adapter 1. So the
4430                         * user needs to make use of macros MKADAP() and GETADAP()
4431                         * (See megaraid.h) while making ioctl() call.
4432                         */
4433                        adapno = GETADAP (adapno);
4434
4435                        if (adapno >= numCtlrs)
4436                                return (-ENODEV);
4437
4438                        ret = verify_area (VERIFY_WRITE,
4439                                           ioc.data,
4440                                           sizeof (struct mcontroller));
4441                        if (ret)
4442                                return ret;
4443
4444                        /*
4445                         * Copy struct mcontroller to user area
4446                         */
4447                        copy_to_user (ioc.data,
4448                                      mcontroller + adapno,
4449                                      sizeof (struct mcontroller));
4450                        return 0;
4451
4452                default:
4453                        return (-EINVAL);
4454
4455                }               /* inner switch */
4456                break;
4457
4458        case M_RD_IOCTL_CMD_NEW:
4459
4460                /*
4461                 * Deletion of logical drives is only handled in 0x80 commands
4462                 */
4463                if( ioc.mbox[0] == FC_DEL_LOGDRV && ioc.mbox[2] == OP_DEL_LOGDRV ) {
4464                        return -EINVAL;
4465                }
4466
4467                /* which adapter?  */
4468                adapno = ioc.ui.fcs.adapno;
4469
4470                /* See comment above: MEGAIOC_QADAPINFO */
4471                adapno = GETADAP(adapno);
4472
4473                if (adapno >= numCtlrs)
4474                        return(-ENODEV);
4475
4476                length = ioc.ui.fcs.length;
4477
4478                /* Check for zero length buffer or very large buffers */
4479                if( !length || length > 32*1024 )
4480                        return -EINVAL;
4481
4482                /* save the user address */
4483                uaddr = ioc.ui.fcs.buffer;
4484
4485                /*
4486                 * For M_RD_IOCTL_CMD_NEW commands, the fields outlen and inlen of
4487                 * uioctl_t structure are treated as flags. If outlen is 1, the
4488                 * data is transferred from the device and if inlen is 1, the data
4489                 * is transferred to the device.
4490                 */
4491                outlen = ioc.outlen;
4492                inlen = ioc.inlen;
4493
4494                if(outlen) {
4495                        ret = verify_area(VERIFY_WRITE, (char *)ioc.ui.fcs.buffer, length);
4496                        if (ret) return ret;
4497                }
4498                if(inlen) {
4499                        ret = verify_area(VERIFY_READ, (char *) ioc.ui.fcs.buffer, length);
4500                        if (ret) return ret;
4501                }
4502
4503                /*
4504                 * Find this host
4505                 */
4506                shpnt = megaCtlrs[adapno]->host;
4507                if(shpnt == NULL)  return -ENODEV;
4508
4509#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4510                scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
4511#else
4512                scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
4513                                                          GFP_ATOMIC | GFP_DMA);
4514#endif
4515                if(scsicmd == NULL) return -ENOMEM;
4516
4517                memset(scsicmd, 0, sizeof(Scsi_Cmnd));
4518                scsicmd->host = shpnt;
4519
4520                if( outlen || inlen ) {
4521#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4522                        pdevp = &pdev;
4523                        memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
4524                        pdevp->dma_mask = 0xffffffff;
4525#else
4526                        pdevp = NULL;
4527#endif
4528                        kvaddr = dma_alloc_consistent(pdevp, length, &dma_addr);
4529
4530                        if( kvaddr == NULL ) {
4531                                printk(KERN_WARNING "megaraid:allocation failed\n");
4532#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
4533                                kfree(scsicmd);
4534#else
4535                                scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4536#endif
4537                                return -ENOMEM;
4538                        }
4539
4540                        ioc.ui.fcs.buffer = kvaddr;
4541
4542                        if (inlen) {
4543                                /* copyin the user data */
4544                                copy_from_user(kvaddr, (char *)uaddr, length );
4545                        }
4546                }
4547
4548                scsicmd->cmnd[0] = MEGADEVIOC;
4549                scsicmd->request_buffer = (void *)&ioc;
4550
4551                init_MUTEX_LOCKED(&mimd_ioctl_sem);
4552
4553                IO_LOCK(shpnt);
4554                megaraid_queue(scsicmd, megadev_ioctl_done);
4555
4556                IO_UNLOCK(shpnt);
4557
4558                down(&mimd_ioctl_sem);
4559
4560                if( !scsicmd->result && outlen ) {
4561                        copy_to_user(uaddr, kvaddr, length);
4562                }
4563
4564                /*
4565                 * copyout the result
4566                 */
4567                uioc = (struct uioctl_t *)arg;
4568
4569                if( ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
4570                        put_user( scsicmd->result, &uioc->pthru.scsistatus );
4571                } else {
4572                        put_user(1, &uioc->mbox[16]);   /* numstatus */
4573                        /* status */
4574                        put_user (scsicmd->result, &uioc->mbox[17]);
4575                }
4576
4577                if (kvaddr) {
4578                        dma_free_consistent(pdevp, length, kvaddr, dma_addr);
4579                }
4580#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
4581                kfree (scsicmd);
4582#else
4583                scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4584#endif
4585
4586                /* restore the user address */
4587                ioc.ui.fcs.buffer = uaddr;
4588
4589                return ret;
4590
4591        case M_RD_IOCTL_CMD:
4592                /* which adapter?  */
4593                adapno = ioc.ui.fcs.adapno;
4594
4595                /* See comment above: MEGAIOC_QADAPINFO */
4596                adapno = GETADAP (adapno);
4597
4598                if (adapno >= numCtlrs)
4599                        return (-ENODEV);
4600
4601                /* save the user address */
4602                uaddr = ioc.data;
4603                outlen = ioc.outlen;
4604                inlen = ioc.inlen;
4605
4606                if ((outlen >= IOCTL_MAX_DATALEN) || (inlen >= IOCTL_MAX_DATALEN))
4607                        return (-EINVAL);
4608
4609                if (outlen) {
4610                        ret = verify_area (VERIFY_WRITE, ioc.data, outlen);
4611                        if (ret) return ret;
4612                }
4613                if (inlen) {
4614                        ret = verify_area (VERIFY_READ, ioc.data, inlen);
4615                        if (ret) return ret;
4616                }
4617
4618                /*
4619                 * Find this host
4620                 */
4621                shpnt = megaCtlrs[adapno]->host;
4622                if(shpnt == NULL)  return -ENODEV;
4623
4624                /*
4625                 * ioctls for deleting logical drives is a special case, so check
4626                 * for it first
4627                 */
4628                if( ioc.mbox[0] == FC_DEL_LOGDRV && ioc.mbox[2] == OP_DEL_LOGDRV ) {
4629
4630                        if( !megacfg->support_random_del ) {
4631                                printk("megaraid: logdrv delete on non supporting f/w.\n");
4632                                return -EINVAL;
4633                        }
4634
4635                        uioc = (struct uioctl_t *)arg;
4636
4637                        ret = mega_del_logdrv(megacfg, ioc.mbox[3]);
4638
4639                        put_user(1, &uioc->mbox[16]);   /* numstatus */
4640                        put_user(ret, &uioc->mbox[17]); /* status */
4641
4642                        /* if deletion failed, let the user know by failing ioctl */
4643                        return ret;
4644                }
4645
4646#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4647                scsicmd = (Scsi_Cmnd *)kmalloc(sizeof(Scsi_Cmnd), GFP_KERNEL|GFP_DMA);
4648#else
4649                scsicmd = (Scsi_Cmnd *)scsi_init_malloc(sizeof(Scsi_Cmnd),
4650                                                          GFP_ATOMIC | GFP_DMA);
4651#endif
4652                if(scsicmd == NULL) return -ENOMEM;
4653
4654                memset(scsicmd, 0, sizeof(Scsi_Cmnd));
4655                scsicmd->host = shpnt;
4656
4657                if (outlen || inlen) {
4658#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4659                        pdevp = &pdev;
4660                        memcpy(pdevp, megacfg->dev, sizeof(struct pci_dev));
4661                        pdevp->dma_mask = 0xffffffff;
4662#else
4663                        pdevp = NULL;
4664#endif
4665                        /*
4666                         * Allocate a page of kernel space.
4667                         */
4668                        kvaddr = dma_alloc_consistent(pdevp, PAGE_SIZE, &dma_addr);
4669
4670                        if( kvaddr == NULL ) {
4671                                printk (KERN_WARNING "megaraid:allocation failed\n");
4672#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /*0x20400 */
4673                                kfree(scsicmd);
4674#else
4675                                scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4676#endif
4677                                return -ENOMEM;
4678                        }
4679
4680                        ioc.data = kvaddr;
4681
4682                        if (inlen) {
4683                                if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4684                                        /* copyin the user data */
4685                                        copy_from_user (kvaddr, uaddr, ioc.pthru.dataxferlen);
4686                                } else {
4687                                        copy_from_user (kvaddr, uaddr, inlen);
4688                                }
4689                        }
4690                }
4691
4692                scsicmd->cmnd[0] = MEGADEVIOC;
4693                scsicmd->request_buffer = (void *) &ioc;
4694
4695                init_MUTEX_LOCKED (&mimd_ioctl_sem);
4696
4697                IO_LOCK(shpnt);
4698                megaraid_queue (scsicmd, megadev_ioctl_done);
4699
4700                IO_UNLOCK(shpnt);
4701                down (&mimd_ioctl_sem);
4702
4703                if (!scsicmd->result && outlen) {
4704                        if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4705                                copy_to_user (uaddr, kvaddr, ioc.pthru.dataxferlen);
4706                        } else {
4707                                copy_to_user (uaddr, kvaddr, outlen);
4708                        }
4709                }
4710
4711                /*
4712                 * copyout the result
4713                 */
4714                uioc = (struct uioctl_t *) arg;
4715
4716                if (ioc.mbox[0] == MEGA_MBOXCMD_PASSTHRU) {
4717                        put_user (scsicmd->result, &uioc->pthru.scsistatus);
4718                } else {
4719                        put_user (1, &uioc->mbox[16]);  /* numstatus */
4720                        put_user (scsicmd->result, &uioc->mbox[17]); /* status */
4721                }
4722
4723                if (kvaddr) {
4724                        dma_free_consistent(pdevp, PAGE_SIZE, kvaddr, dma_addr );
4725                }
4726
4727#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4728                kfree (scsicmd);
4729#else
4730                scsi_init_free((char *)scsicmd, sizeof(Scsi_Cmnd));
4731#endif
4732
4733                /* restore user pointer */
4734                ioc.data = uaddr;
4735
4736                return ret;
4737
4738        default:
4739                return (-EINVAL);
4740
4741        }/* Outer switch */
4742
4743        return 0;
4744}
4745
4746static void
4747megadev_ioctl_done(Scsi_Cmnd *sc)
4748{
4749        up (&mimd_ioctl_sem);
4750}
4751
4752static mega_scb *
4753megadev_doioctl (mega_host_config * megacfg, Scsi_Cmnd * sc)
4754{
4755        u8 cmd;
4756        struct uioctl_t *ioc = NULL;
4757        mega_mailbox *mbox = NULL;
4758        mega_ioctl_mbox *mboxioc = NULL;
4759        struct mbox_passthru *mboxpthru = NULL;
4760        mega_scb *scb = NULL;
4761        mega_passthru *pthru = NULL;
4762
4763        if ((scb = mega_allocateSCB (megacfg, sc)) == NULL) {
4764                sc->result = (DID_ERROR << 16);
4765                callDone (sc);
4766                return NULL;
4767        }
4768
4769        ioc = (struct uioctl_t *) sc->request_buffer;
4770
4771        memcpy (scb->mboxData, ioc->mbox, sizeof (scb->mboxData));
4772
4773        /* The generic mailbox */
4774        mbox = (mega_mailbox *) ioc->mbox;
4775
4776        /*
4777         * Get the user command
4778         */
4779        cmd = ioc->mbox[0];
4780
4781        switch (cmd) {
4782        case MEGA_MBOXCMD_PASSTHRU:
4783                /*
4784                   * prepare the SCB with information from the user ioctl structure
4785                 */
4786#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4787                pthru = scb->pthru;
4788#else
4789                pthru = &scb->pthru;
4790#endif
4791                memcpy (pthru, &ioc->pthru, sizeof (mega_passthru));
4792                mboxpthru = (struct mbox_passthru *) scb->mboxData;
4793#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4794                if (megacfg->flag & BOARD_64BIT) {
4795                        /* This is just a sample with one element 
4796                           * This if executes onlu on 2.4 kernels
4797                         */
4798                        mboxpthru->dataxferaddr = scb->dma_passthruhandle64;
4799                        scb->sg64List[0].address =
4800                            pci_map_single (megacfg->dev,
4801                                            ioc->data,
4802                                            4096, PCI_DMA_BIDIRECTIONAL);
4803                        scb->sg64List[0].length = 4096; // TODO: Check this
4804                        pthru->dataxferaddr = scb->dma_sghandle64;
4805                        pthru->numsgelements = 1;
4806                        mboxpthru->cmd = 0xC3;
4807                } else {
4808                        mboxpthru->dataxferaddr = scb->dma_passthruhandle64;
4809                        pthru->dataxferaddr =
4810                            pci_map_single (megacfg->dev,
4811                                            ioc->data,
4812                                            4096, PCI_DMA_BIDIRECTIONAL);
4813                        pthru->numsgelements = 0;
4814                }
4815
4816#else
4817                {
4818                        mboxpthru->dataxferaddr = virt_to_bus (&scb->pthru);
4819                        pthru->dataxferaddr = virt_to_bus (ioc->data);
4820                        pthru->numsgelements = 0;
4821                }
4822#endif
4823
4824                pthru->reqsenselen = 14;
4825                break;
4826
4827        default:                /* Normal command */
4828                mboxioc = (mega_ioctl_mbox *) scb->mboxData;
4829
4830                if (ioc->ui.fcs.opcode == M_RD_IOCTL_CMD_NEW) {
4831                        scb->buff_ptr = ioc->ui.fcs.buffer;
4832                        scb->iDataSize = ioc->ui.fcs.length;
4833                } else {
4834                        scb->buff_ptr = ioc->data;
4835                        scb->iDataSize = 4096;  // TODO:check it
4836                }
4837
4838                set_mbox_xfer_addr (megacfg, scb, mboxioc, FROMTO_DEVICE);
4839                mboxioc->numsgelements = 0;
4840                break;
4841        }
4842
4843        return scb;
4844}
4845
4846static int
4847mega_support_ext_cdb(mega_host_config *this_hba)
4848{
4849        mega_mailbox *mboxpnt;
4850        unsigned char mbox[16];
4851        int ret;
4852
4853        mboxpnt = (mega_mailbox *) mbox;
4854
4855        memset(mbox, 0, sizeof (mbox));
4856        /*
4857         * issue command to find out if controller supports extended CDBs.
4858         */
4859        mbox[0] = 0xA4;
4860        mbox[2] = 0x16;
4861
4862        ret = megaIssueCmd(this_hba, mbox, NULL, 0);
4863
4864        return !ret;
4865}
4866
4867
4868/*
4869 * Find out if this controller supports random deletion and addition of
4870 * logical drives
4871 */
4872static int
4873mega_support_random_del(mega_host_config *this_hba)
4874{
4875        mega_mailbox *mboxpnt;
4876        unsigned char mbox[16];
4877        int ret;
4878
4879        mboxpnt = (mega_mailbox *)mbox;
4880
4881        memset(mbox, 0, sizeof(mbox));
4882
4883        /*
4884         * issue command
4885         */
4886        mbox[0] = FC_DEL_LOGDRV;
4887        mbox[2] = OP_SUP_DEL_LOGDRV;
4888
4889        ret = megaIssueCmd(this_hba, mbox, NULL, 0);
4890
4891        return !ret;
4892}
4893
4894static int
4895mega_del_logdrv(mega_host_config *this_hba, int logdrv)
4896{
4897        int             rval;
4898        IO_LOCK_T;
4899        DECLARE_WAIT_QUEUE_HEAD(wq);
4900        mega_scb        *scbp;
4901
4902        /*
4903         * Stop sending commands to the controller, queue them internally.
4904         * When deletion is complete, ISR will flush the queue.
4905         */
4906        IO_LOCK(this_hba->host);
4907        this_hba->quiescent = 1;
4908        IO_UNLOCK(this_hba->host);
4909
4910        while( this_hba->qPcnt ) {
4911                        sleep_on_timeout( &wq, 1*HZ );  /* sleep for 1s */
4912        }
4913        rval = mega_do_del_logdrv(this_hba, logdrv);
4914
4915        IO_LOCK(this_hba->host);
4916        /*
4917         * Attach the internal queue to the pending queue
4918         */
4919        if( this_hba->qPendingH == NULL ) {
4920                /*
4921                 * If pending queue head is null, make internal queue as
4922                 * pending queue
4923                 */
4924                this_hba->qPendingH = this_hba->int_qh;
4925                this_hba->qPendingT = this_hba->int_qt;
4926                this_hba->qPcnt = this_hba->int_qlen;
4927        }
4928        else {
4929                /*
4930                 * Append pending queue to internal queue
4931                 */
4932                if( this_hba->int_qt ) {
4933                        this_hba->int_qt->next = this_hba->qPendingH;
4934
4935                        this_hba->qPendingH = this_hba->int_qh;
4936                        this_hba->qPcnt += this_hba->int_qlen;
4937                }
4938        }
4939
4940        this_hba->int_qh = this_hba->int_qt = NULL;
4941        this_hba->int_qlen = 0;
4942
4943        /*
4944         * If delete operation was successful, add 0x80 to the logical drive
4945         * ids for commands in the pending queue.
4946         */
4947        if( this_hba->read_ldidmap) {
4948                for( scbp = this_hba->qPendingH; scbp; scbp = scbp->next ) {
4949#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4950                        if( scbp->pthru->logdrv < 0x80 )
4951                                scbp->pthru->logdrv += 0x80;
4952#else
4953                        if( scbp->pthru.logdrv < 0x80 )
4954                                scbp->pthru.logdrv += 0x80;
4955#endif
4956                }
4957        }
4958        this_hba->quiescent = 0;
4959
4960        IO_UNLOCK(this_hba->host);
4961
4962        return rval;
4963}
4964
4965
4966static int
4967mega_do_del_logdrv(mega_host_config *this_hba, int logdrv)
4968{
4969        mega_mailbox *mboxpnt;
4970        unsigned char mbox[16];
4971        int rval;
4972
4973        mboxpnt = (mega_mailbox *)mbox;
4974
4975        memset(mbox, 0, sizeof(mbox));
4976
4977        mbox[0] = FC_DEL_LOGDRV;
4978        mbox[2] = OP_DEL_LOGDRV;
4979        mbox[3] = logdrv;
4980
4981        rval = megaIssueCmd(this_hba, mbox, NULL, 0);
4982
4983        /* log this event */
4984        if( rval != 0 ) {
4985                printk("megaraid: Attempt to delete logical drive %d failed.",
4986                                logdrv);
4987                return rval;
4988        }
4989
4990        printk("megaraid: logical drive %d deleted.\n", logdrv);
4991
4992        /*
4993         * After deleting first logical drive, the logical drives must be
4994         * addressed by adding 0x80 to the logical drive id.
4995         */
4996        this_hba->read_ldidmap = 1;
4997
4998        return rval;
4999}
5000
5001#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
5002void *
5003dma_alloc_consistent(void *dev, size_t size, dma_addr_t *dma_addr)
5004{
5005        void    *_tv;
5006        int             npages;
5007        int             order = 0;
5008
5009        /*
5010         * How many pages application needs
5011         */
5012        npages = size / PAGE_SIZE;
5013
5014        /* Do we need one more page */
5015        if(size % PAGE_SIZE)
5016                npages++;
5017
5018        order = mega_get_order(npages);
5019
5020        _tv = (void *)__get_free_pages(GFP_DMA, order);
5021
5022        if( _tv != NULL ) {
5023                memset(_tv, 0, size);
5024                *(dma_addr) = virt_to_bus(_tv);
5025        }
5026
5027        return _tv;
5028}
5029
5030/*
5031 * int mega_get_order(int)
5032 *
5033 * returns the order to be used as 2nd argument to __get_free_pages() - which
5034 * return pages equal to pow(2, order) - AM
5035 */
5036int
5037mega_get_order(int n)
5038{
5039        int             i = 0;
5040
5041        while( pow_2(i++) < n )
5042                ; /* null statement */
5043
5044        return i-1;
5045}
5046
5047/*
5048 * int pow_2(int)
5049 *
5050 * calculates pow(2, i)
5051 */
5052int
5053pow_2(int i)
5054{
5055        unsigned int    v = 1;
5056        
5057        while(i--)
5058                v <<= 1;
5059
5060        return v;
5061}
5062
5063void
5064dma_free_consistent(void *dev, size_t size, void *vaddr, dma_addr_t dma_addr)
5065{
5066        int             npages;
5067        int             order = 0;
5068
5069        npages = size / PAGE_SIZE;
5070
5071        if(size % PAGE_SIZE)
5072                npages++;
5073
5074        if (npages == 1)
5075                order = 0;
5076        else if (npages == 2)
5077                order = 1;
5078        else if (npages <= 4)
5079                order = 2;
5080        else
5081                order = 3;
5082
5083        free_pages((unsigned long)vaddr, order);
5084
5085}
5086#endif
5087
5088#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
5089static
5090#endif                          /* LINUX VERSION 2.4.XX */
5091#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) || defined(MODULE)
5092Scsi_Host_Template driver_template = MEGARAID;
5093
5094#include "scsi_module.c"
5095#endif                          /* LINUX VERSION 2.4.XX || MODULE */
5096
5097/* vi: set ts=4: */
5098
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.