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