linux/drivers/scsi/ips.c
<<
>>
Prefs
   1/*****************************************************************************/
   2/* ips.c -- driver for the Adaptec / IBM ServeRAID controller                */
   3/*                                                                           */
   4/* Written By: Keith Mitchell, IBM Corporation                               */
   5/*             Jack Hammer, Adaptec, Inc.                                    */
   6/*             David Jeffery, Adaptec, Inc.                                  */
   7/*                                                                           */
   8/* Copyright (C) 2000 IBM Corporation                                        */
   9/* Copyright (C) 2002,2003 Adaptec, Inc.                                     */
  10/*                                                                           */
  11/* This program is free software; you can redistribute it and/or modify      */
  12/* it under the terms of the GNU General Public License as published by      */
  13/* the Free Software Foundation; either version 2 of the License, or         */
  14/* (at your option) any later version.                                       */
  15/*                                                                           */
  16/* This program is distributed in the hope that it will be useful,           */
  17/* but WITHOUT ANY WARRANTY; without even the implied warranty of            */
  18/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
  19/* GNU General Public License for more details.                              */
  20/*                                                                           */
  21/* NO WARRANTY                                                               */
  22/* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR        */
  23/* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT      */
  24/* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,      */
  25/* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is    */
  26/* solely responsible for determining the appropriateness of using and       */
  27/* distributing the Program and assumes all risks associated with its        */
  28/* exercise of rights under this Agreement, including but not limited to     */
  29/* the risks and costs of program errors, damage to or loss of data,         */
  30/* programs or equipment, and unavailability or interruption of operations.  */
  31/*                                                                           */
  32/* DISCLAIMER OF LIABILITY                                                   */
  33/* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY   */
  34/* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL        */
  35/* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND   */
  36/* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR     */
  37/* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE    */
  38/* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED  */
  39/* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES             */
  40/*                                                                           */
  41/* You should have received a copy of the GNU General Public License         */
  42/* along with this program; if not, write to the Free Software               */
  43/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  44/*                                                                           */
  45/* Bugs/Comments/Suggestions about this driver should be mailed to:          */
  46/*      ipslinux@adaptec.com                                                 */
  47/*                                                                           */
  48/* For system support issues, contact your local IBM Customer support.       */
  49/* Directions to find IBM Customer Support for each country can be found at: */
  50/*      http://www.ibm.com/planetwide/                                       */
  51/*                                                                           */
  52/*****************************************************************************/
  53
  54/*****************************************************************************/
  55/* Change Log                                                                */
  56/*                                                                           */
  57/* 0.99.02  - Breakup commands that are bigger than 8 * the stripe size      */
  58/* 0.99.03  - Make interrupt routine handle all completed request on the     */
  59/*            adapter not just the first one                                 */
  60/*          - Make sure passthru commands get woken up if we run out of      */
  61/*            SCBs                                                           */
  62/*          - Send all of the commands on the queue at once rather than      */
  63/*            one at a time since the card will support it.                  */
  64/* 0.99.04  - Fix race condition in the passthru mechanism -- this required  */
  65/*            the interface to the utilities to change                       */
  66/*          - Fix error recovery code                                        */
  67/* 0.99.05  - Fix an oops when we get certain passthru commands              */
  68/* 1.00.00  - Initial Public Release                                         */
  69/*            Functionally equivalent to 0.99.05                             */
  70/* 3.60.00  - Bump max commands to 128 for use with firmware 3.60            */
  71/*          - Change version to 3.60 to coincide with release numbering.     */
  72/* 3.60.01  - Remove bogus error check in passthru routine                   */
  73/* 3.60.02  - Make DCDB direction based on lookup table                      */
  74/*          - Only allow one DCDB command to a SCSI ID at a time             */
  75/* 4.00.00  - Add support for ServeRAID 4                                    */
  76/* 4.00.01  - Add support for First Failure Data Capture                     */
  77/* 4.00.02  - Fix problem with PT DCDB with no buffer                        */
  78/* 4.00.03  - Add alternative passthru interface                             */
  79/*          - Add ability to flash BIOS                                      */
  80/* 4.00.04  - Rename structures/constants to be prefixed with IPS_           */
  81/* 4.00.05  - Remove wish_block from init routine                            */
  82/*          - Use linux/spinlock.h instead of asm/spinlock.h for kernels     */
  83/*            2.3.18 and later                                               */
  84/*          - Sync with other changes from the 2.3 kernels                   */
  85/* 4.00.06  - Fix timeout with initial FFDC command                          */
  86/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@infradead.org> */
  87/* 4.10.00  - Add support for ServeRAID 4M/4L                                */
  88/* 4.10.13  - Fix for dynamic unload and proc file system                    */
  89/* 4.20.03  - Rename version to coincide with new release schedules          */
  90/*            Performance fixes                                              */
  91/*            Fix truncation of /proc files with cat                         */
  92/*            Merge in changes through kernel 2.4.0test1ac21                 */
  93/* 4.20.13  - Fix some failure cases / reset code                            */
  94/*          - Hook into the reboot_notifier to flush the controller cache    */
  95/* 4.50.01  - Fix problem when there is a hole in logical drive numbering    */
  96/* 4.70.09  - Use a Common ( Large Buffer ) for Flashing from the JCRM CD    */
  97/*          - Add IPSSEND Flash Support                                      */
  98/*          - Set Sense Data for Unknown SCSI Command                        */
  99/*          - Use Slot Number from NVRAM Page 5                              */
 100/*          - Restore caller's DCDB Structure                                */
 101/* 4.70.12  - Corrective actions for bad controller ( during initialization )*/
 102/* 4.70.13  - Don't Send CDB's if we already know the device is not present  */
 103/*          - Don't release HA Lock in ips_next() until SC taken off queue   */
 104/*          - Unregister SCSI device in ips_release()                        */
 105/* 4.70.15  - Fix Breakup for very large ( non-SG ) requests in ips_done()   */
 106/* 4.71.00  - Change all memory allocations to not use GFP_DMA flag          */
 107/*            Code Clean-Up for 2.4.x kernel                                 */
 108/* 4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     */
 109/* 4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    */
 110/*          - Don't Issue Internal FFDC Command if there are Active Commands */
 111/*          - Close Window for getting too many IOCTL's active               */
 112/* 4.80.00  - Make ia64 Safe                                                 */
 113/* 4.80.04  - Eliminate calls to strtok() if 2.4.x or greater                */
 114/*          - Adjustments to Device Queue Depth                              */
 115/* 4.80.14  - Take all semaphores off stack                                  */
 116/*          - Clean Up New_IOCTL path                                        */
 117/* 4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
 118/*          - 5 second delay needed after resetting an i960 adapter          */
 119/* 4.80.26  - Clean up potential code problems ( Arjan's recommendations )   */
 120/* 4.90.01  - Version Matching for FirmWare, BIOS, and Driver                */
 121/* 4.90.05  - Use New PCI Architecture to facilitate Hot Plug Development    */
 122/* 4.90.08  - Increase Delays in Flashing ( Trombone Only - 4H )             */
 123/* 4.90.08  - Data Corruption if First Scatter Gather Element is > 64K       */
 124/* 4.90.11  - Don't actually RESET unless it's physically required           */
 125/*          - Remove unused compile options                                  */
 126/* 5.00.01  - Sarasota ( 5i ) adapters must always be scanned first          */
 127/*          - Get rid on IOCTL_NEW_COMMAND code                              */
 128/*          - Add Extended DCDB Commands for Tape Support in 5I              */
 129/* 5.10.12  - use pci_dma interfaces, update for 2.5 kernel changes          */
 130/* 5.10.15  - remove unused code (sem, macros, etc.)                         */
 131/* 5.30.00  - use __devexit_p()                                              */
 132/* 6.00.00  - Add 6x Adapters and Battery Flash                              */
 133/* 6.10.00  - Remove 1G Addressing Limitations                               */
 134/* 6.11.xx  - Get VersionInfo buffer off the stack !              DDTS 60401 */
 135/* 6.11.xx  - Make Logical Drive Info structure safe for DMA      DDTS 60639 */
 136/* 7.10.18  - Add highmem_io flag in SCSI Templete for 2.4 kernels           */
 137/*          - Fix path/name for scsi_hosts.h include for 2.6 kernels         */
 138/*          - Fix sort order of 7k                                           */
 139/*          - Remove 3 unused "inline" functions                             */
 140/* 7.12.xx  - Use STATIC functions whereever possible                        */
 141/*          - Clean up deprecated MODULE_PARM calls                          */
 142/* 7.12.05  - Remove Version Matching per IBM request                        */
 143/*****************************************************************************/
 144
 145/*
 146 * Conditional Compilation directives for this driver:
 147 *
 148 * IPS_DEBUG            - Turn on debugging info
 149 *
 150 * Parameters:
 151 *
 152 * debug:<number>       - Set debug level to <number>
 153 *                        NOTE: only works when IPS_DEBUG compile directive is used.
 154 *       1              - Normal debug messages
 155 *       2              - Verbose debug messages
 156 *       11             - Method trace (non interrupt)
 157 *       12             - Method trace (includes interrupt)
 158 *
 159 * noi2o                - Don't use I2O Queues (ServeRAID 4 only)
 160 * nommap               - Don't use memory mapped I/O
 161 * ioctlsize            - Initial size of the IOCTL buffer
 162 */
 163
 164#include <asm/io.h>
 165#include <asm/byteorder.h>
 166#include <asm/page.h>
 167#include <linux/stddef.h>
 168#include <linux/string.h>
 169#include <linux/errno.h>
 170#include <linux/kernel.h>
 171#include <linux/ioport.h>
 172#include <linux/slab.h>
 173#include <linux/delay.h>
 174#include <linux/pci.h>
 175#include <linux/proc_fs.h>
 176#include <linux/reboot.h>
 177#include <linux/interrupt.h>
 178
 179#include <linux/blkdev.h>
 180#include <linux/types.h>
 181#include <linux/dma-mapping.h>
 182
 183#include <scsi/sg.h>
 184#include "scsi.h"
 185#include <scsi/scsi_host.h>
 186
 187#include "ips.h"
 188
 189#include <linux/module.h>
 190
 191#include <linux/stat.h>
 192
 193#include <linux/spinlock.h>
 194#include <linux/init.h>
 195
 196#include <linux/smp.h>
 197
 198#ifdef MODULE
 199static char *ips = NULL;
 200module_param(ips, charp, 0);
 201#endif
 202
 203/*
 204 * DRIVER_VER
 205 */
 206#define IPS_VERSION_HIGH        IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
 207#define IPS_VERSION_LOW         "." IPS_VER_BUILD_STRING " "
 208
 209#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
 210#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
 211#endif
 212
 213#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
 214                         DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
 215                         PCI_DMA_BIDIRECTIONAL : \
 216                         scb->scsi_cmd->sc_data_direction)
 217
 218#ifdef IPS_DEBUG
 219#define METHOD_TRACE(s, i)    if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
 220#define DEBUG(i, s)           if (ips_debug >= i) printk(KERN_NOTICE s "\n");
 221#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
 222#else
 223#define METHOD_TRACE(s, i)
 224#define DEBUG(i, s)
 225#define DEBUG_VAR(i, s, v...)
 226#endif
 227
 228/*
 229 * Function prototypes
 230 */
 231static int ips_detect(struct scsi_host_template *);
 232static int ips_release(struct Scsi_Host *);
 233static int ips_eh_abort(struct scsi_cmnd *);
 234static int ips_eh_reset(struct scsi_cmnd *);
 235static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
 236static const char *ips_info(struct Scsi_Host *);
 237static irqreturn_t do_ipsintr(int, void *);
 238static int ips_hainit(ips_ha_t *);
 239static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
 240static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
 241static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
 242static int ips_online(ips_ha_t *, ips_scb_t *);
 243static int ips_inquiry(ips_ha_t *, ips_scb_t *);
 244static int ips_rdcap(ips_ha_t *, ips_scb_t *);
 245static int ips_msense(ips_ha_t *, ips_scb_t *);
 246static int ips_reqsen(ips_ha_t *, ips_scb_t *);
 247static int ips_deallocatescbs(ips_ha_t *, int);
 248static int ips_allocatescbs(ips_ha_t *);
 249static int ips_reset_copperhead(ips_ha_t *);
 250static int ips_reset_copperhead_memio(ips_ha_t *);
 251static int ips_reset_morpheus(ips_ha_t *);
 252static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
 253static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
 254static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
 255static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
 256static int ips_isintr_copperhead(ips_ha_t *);
 257static int ips_isintr_copperhead_memio(ips_ha_t *);
 258static int ips_isintr_morpheus(ips_ha_t *);
 259static int ips_wait(ips_ha_t *, int, int);
 260static int ips_write_driver_status(ips_ha_t *, int);
 261static int ips_read_adapter_status(ips_ha_t *, int);
 262static int ips_read_subsystem_parameters(ips_ha_t *, int);
 263static int ips_read_config(ips_ha_t *, int);
 264static int ips_clear_adapter(ips_ha_t *, int);
 265static int ips_readwrite_page5(ips_ha_t *, int, int);
 266static int ips_init_copperhead(ips_ha_t *);
 267static int ips_init_copperhead_memio(ips_ha_t *);
 268static int ips_init_morpheus(ips_ha_t *);
 269static int ips_isinit_copperhead(ips_ha_t *);
 270static int ips_isinit_copperhead_memio(ips_ha_t *);
 271static int ips_isinit_morpheus(ips_ha_t *);
 272static int ips_erase_bios(ips_ha_t *);
 273static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
 274static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
 275static int ips_erase_bios_memio(ips_ha_t *);
 276static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
 277static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
 278static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 279static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 280static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 281static void ips_free_flash_copperhead(ips_ha_t * ha);
 282static void ips_get_bios_version(ips_ha_t *, int);
 283static void ips_identify_controller(ips_ha_t *);
 284static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
 285static void ips_enable_int_copperhead(ips_ha_t *);
 286static void ips_enable_int_copperhead_memio(ips_ha_t *);
 287static void ips_enable_int_morpheus(ips_ha_t *);
 288static int ips_intr_copperhead(ips_ha_t *);
 289static int ips_intr_morpheus(ips_ha_t *);
 290static void ips_next(ips_ha_t *, int);
 291static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
 292static void ipsintr_done(ips_ha_t *, struct ips_scb *);
 293static void ips_done(ips_ha_t *, ips_scb_t *);
 294static void ips_free(ips_ha_t *);
 295static void ips_init_scb(ips_ha_t *, ips_scb_t *);
 296static void ips_freescb(ips_ha_t *, ips_scb_t *);
 297static void ips_setup_funclist(ips_ha_t *);
 298static void ips_statinit(ips_ha_t *);
 299static void ips_statinit_memio(ips_ha_t *);
 300static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
 301static void ips_ffdc_reset(ips_ha_t *, int);
 302static void ips_ffdc_time(ips_ha_t *);
 303static uint32_t ips_statupd_copperhead(ips_ha_t *);
 304static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
 305static uint32_t ips_statupd_morpheus(ips_ha_t *);
 306static ips_scb_t *ips_getscb(ips_ha_t *);
 307static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
 308static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *);
 309static void ips_putq_copp_tail(ips_copp_queue_t *,
 310                                      ips_copp_wait_item_t *);
 311static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
 312static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
 313static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
 314static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *,
 315                                          struct scsi_cmnd *);
 316static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
 317                                                     ips_copp_wait_item_t *);
 318static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
 319
 320static int ips_is_passthru(struct scsi_cmnd *);
 321static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
 322static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 323static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
 324static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
 325                               unsigned int count);
 326static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
 327                              unsigned int count);
 328
 329static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 330static int ips_host_info(ips_ha_t *, char *, off_t, int);
 331static void copy_mem_info(IPS_INFOSTR *, char *, int);
 332static int copy_info(IPS_INFOSTR *, char *, ...);
 333static int ips_abort_init(ips_ha_t * ha, int index);
 334static int ips_init_phase2(int index);
 335
 336static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
 337static int ips_register_scsi(int index);
 338
 339static int  ips_poll_for_flush_complete(ips_ha_t * ha);
 340static void ips_flush_and_reset(ips_ha_t *ha);
 341
 342/*
 343 * global variables
 344 */
 345static const char ips_name[] = "ips";
 346static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS];      /* Array of host controller structures */
 347static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS];      /* Array of HA structures */
 348static unsigned int ips_next_controller;
 349static unsigned int ips_num_controllers;
 350static unsigned int ips_released_controllers;
 351static int ips_hotplug;
 352static int ips_cmd_timeout = 60;
 353static int ips_reset_timeout = 60 * 5;
 354static int ips_force_memio = 1;         /* Always use Memory Mapped I/O    */
 355static int ips_force_i2o = 1;   /* Always use I2O command delivery */
 356static int ips_ioctlsize = IPS_IOCTL_SIZE;      /* Size of the ioctl buffer        */
 357static int ips_cd_boot;                 /* Booting from Manager CD         */
 358static char *ips_FlashData = NULL;      /* CD Boot - Flash Data Buffer      */
 359static dma_addr_t ips_flashbusaddr;
 360static long ips_FlashDataInUse;         /* CD Boot - Flash Data In Use Flag */
 361static uint32_t MaxLiteCmds = 32;       /* Max Active Cmds for a Lite Adapter */
 362static struct scsi_host_template ips_driver_template = {
 363        .detect                 = ips_detect,
 364        .release                = ips_release,
 365        .info                   = ips_info,
 366        .queuecommand           = ips_queue,
 367        .eh_abort_handler       = ips_eh_abort,
 368        .eh_host_reset_handler  = ips_eh_reset,
 369        .proc_name              = "ips",
 370        .proc_info              = ips_proc_info,
 371        .slave_configure        = ips_slave_configure,
 372        .bios_param             = ips_biosparam,
 373        .this_id                = -1,
 374        .sg_tablesize           = IPS_MAX_SG,
 375        .cmd_per_lun            = 3,
 376        .use_clustering         = ENABLE_CLUSTERING,
 377};
 378
 379
 380/* This table describes all ServeRAID Adapters */
 381static struct  pci_device_id  ips_pci_table[] = {
 382        { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
 383        { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
 384        { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
 385        { 0, }
 386};
 387
 388MODULE_DEVICE_TABLE( pci, ips_pci_table );
 389
 390static char ips_hot_plug_name[] = "ips";
 391
 392static int __devinit  ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
 393static void __devexit ips_remove_device(struct pci_dev *pci_dev);
 394
 395static struct pci_driver ips_pci_driver = {
 396        .name           = ips_hot_plug_name,
 397        .id_table       = ips_pci_table,
 398        .probe          = ips_insert_device,
 399        .remove         = __devexit_p(ips_remove_device),
 400};
 401
 402
 403/*
 404 * Necessary forward function protoypes
 405 */
 406static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
 407
 408#define MAX_ADAPTER_NAME 15
 409
 410static char ips_adapter_name[][30] = {
 411        "ServeRAID",
 412        "ServeRAID II",
 413        "ServeRAID on motherboard",
 414        "ServeRAID on motherboard",
 415        "ServeRAID 3H",
 416        "ServeRAID 3L",
 417        "ServeRAID 4H",
 418        "ServeRAID 4M",
 419        "ServeRAID 4L",
 420        "ServeRAID 4Mx",
 421        "ServeRAID 4Lx",
 422        "ServeRAID 5i",
 423        "ServeRAID 5i",
 424        "ServeRAID 6M",
 425        "ServeRAID 6i",
 426        "ServeRAID 7t",
 427        "ServeRAID 7k",
 428        "ServeRAID 7M"
 429};
 430
 431static struct notifier_block ips_notifier = {
 432        ips_halt, NULL, 0
 433};
 434
 435/*
 436 * Direction table
 437 */
 438static char ips_command_direction[] = {
 439        IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
 440        IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
 441        IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 442        IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
 443        IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
 444        IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
 445        IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
 446        IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
 447        IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
 448        IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
 449        IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
 450        IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
 451        IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
 452        IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
 453        IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
 454        IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
 455        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 456        IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 457        IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 458        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 459        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 460        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 461        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 462        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 463        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 464        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 465        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 466        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 467        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 468        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 469        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 470        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 471        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 472        IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
 473        IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
 474        IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
 475        IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
 476        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 477        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 478        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 479        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 480        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 481        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 482        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 483        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 484        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 485        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
 486        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 487        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 488        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
 489        IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
 490};
 491
 492
 493/****************************************************************************/
 494/*                                                                          */
 495/* Routine Name: ips_setup                                                  */
 496/*                                                                          */
 497/* Routine Description:                                                     */
 498/*                                                                          */
 499/*   setup parameters to the driver                                         */
 500/*                                                                          */
 501/****************************************************************************/
 502static int
 503ips_setup(char *ips_str)
 504{
 505
 506        int i;
 507        char *key;
 508        char *value;
 509        IPS_OPTION options[] = {
 510                {"noi2o", &ips_force_i2o, 0},
 511                {"nommap", &ips_force_memio, 0},
 512                {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
 513                {"cdboot", &ips_cd_boot, 0},
 514                {"maxcmds", &MaxLiteCmds, 32},
 515        };
 516
 517        /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
 518        /* Search for value */
 519        while ((key = strsep(&ips_str, ",."))) {
 520                if (!*key)
 521                        continue;
 522                value = strchr(key, ':');
 523                if (value)
 524                        *value++ = '\0';
 525                /*
 526                 * We now have key/value pairs.
 527                 * Update the variables
 528                 */
 529                for (i = 0; i < ARRAY_SIZE(options); i++) {
 530                        if (strnicmp
 531                            (key, options[i].option_name,
 532                             strlen(options[i].option_name)) == 0) {
 533                                if (value)
 534                                        *options[i].option_flag =
 535                                            simple_strtoul(value, NULL, 0);
 536                                else
 537                                        *options[i].option_flag =
 538                                            options[i].option_value;
 539                                break;
 540                        }
 541                }
 542        }
 543
 544        return (1);
 545}
 546
 547__setup("ips=", ips_setup);
 548
 549/****************************************************************************/
 550/*                                                                          */
 551/* Routine Name: ips_detect                                                 */
 552/*                                                                          */
 553/* Routine Description:                                                     */
 554/*                                                                          */
 555/*   Detect and initialize the driver                                       */
 556/*                                                                          */
 557/* NOTE: this routine is called under the io_request_lock spinlock          */
 558/*                                                                          */
 559/****************************************************************************/
 560static int
 561ips_detect(struct scsi_host_template * SHT)
 562{
 563        int i;
 564
 565        METHOD_TRACE("ips_detect", 1);
 566
 567#ifdef MODULE
 568        if (ips)
 569                ips_setup(ips);
 570#endif
 571
 572        for (i = 0; i < ips_num_controllers; i++) {
 573                if (ips_register_scsi(i))
 574                        ips_free(ips_ha[i]);
 575                ips_released_controllers++;
 576        }
 577        ips_hotplug = 1;
 578        return (ips_num_controllers);
 579}
 580
 581/****************************************************************************/
 582/*   configure the function pointers to use the functions that will work    */
 583/*   with the found version of the adapter                                  */
 584/****************************************************************************/
 585static void
 586ips_setup_funclist(ips_ha_t * ha)
 587{
 588
 589        /*
 590         * Setup Functions
 591         */
 592        if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
 593                /* morpheus / marco / sebring */
 594                ha->func.isintr = ips_isintr_morpheus;
 595                ha->func.isinit = ips_isinit_morpheus;
 596                ha->func.issue = ips_issue_i2o_memio;
 597                ha->func.init = ips_init_morpheus;
 598                ha->func.statupd = ips_statupd_morpheus;
 599                ha->func.reset = ips_reset_morpheus;
 600                ha->func.intr = ips_intr_morpheus;
 601                ha->func.enableint = ips_enable_int_morpheus;
 602        } else if (IPS_USE_MEMIO(ha)) {
 603                /* copperhead w/MEMIO */
 604                ha->func.isintr = ips_isintr_copperhead_memio;
 605                ha->func.isinit = ips_isinit_copperhead_memio;
 606                ha->func.init = ips_init_copperhead_memio;
 607                ha->func.statupd = ips_statupd_copperhead_memio;
 608                ha->func.statinit = ips_statinit_memio;
 609                ha->func.reset = ips_reset_copperhead_memio;
 610                ha->func.intr = ips_intr_copperhead;
 611                ha->func.erasebios = ips_erase_bios_memio;
 612                ha->func.programbios = ips_program_bios_memio;
 613                ha->func.verifybios = ips_verify_bios_memio;
 614                ha->func.enableint = ips_enable_int_copperhead_memio;
 615                if (IPS_USE_I2O_DELIVER(ha))
 616                        ha->func.issue = ips_issue_i2o_memio;
 617                else
 618                        ha->func.issue = ips_issue_copperhead_memio;
 619        } else {
 620                /* copperhead */
 621                ha->func.isintr = ips_isintr_copperhead;
 622                ha->func.isinit = ips_isinit_copperhead;
 623                ha->func.init = ips_init_copperhead;
 624                ha->func.statupd = ips_statupd_copperhead;
 625                ha->func.statinit = ips_statinit;
 626                ha->func.reset = ips_reset_copperhead;
 627                ha->func.intr = ips_intr_copperhead;
 628                ha->func.erasebios = ips_erase_bios;
 629                ha->func.programbios = ips_program_bios;
 630                ha->func.verifybios = ips_verify_bios;
 631                ha->func.enableint = ips_enable_int_copperhead;
 632
 633                if (IPS_USE_I2O_DELIVER(ha))
 634                        ha->func.issue = ips_issue_i2o;
 635                else
 636                        ha->func.issue = ips_issue_copperhead;
 637        }
 638}
 639
 640/****************************************************************************/
 641/*                                                                          */
 642/* Routine Name: ips_release                                                */
 643/*                                                                          */
 644/* Routine Description:                                                     */
 645/*                                                                          */
 646/*   Remove a driver                                                        */
 647/*                                                                          */
 648/****************************************************************************/
 649static int
 650ips_release(struct Scsi_Host *sh)
 651{
 652        ips_scb_t *scb;
 653        ips_ha_t *ha;
 654        int i;
 655
 656        METHOD_TRACE("ips_release", 1);
 657
 658        scsi_remove_host(sh);
 659
 660        for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
 661
 662        if (i == IPS_MAX_ADAPTERS) {
 663                printk(KERN_WARNING
 664                       "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
 665                BUG();
 666                return (FALSE);
 667        }
 668
 669        ha = IPS_HA(sh);
 670
 671        if (!ha)
 672                return (FALSE);
 673
 674        /* flush the cache on the controller */
 675        scb = &ha->scbs[ha->max_cmds - 1];
 676
 677        ips_init_scb(ha, scb);
 678
 679        scb->timeout = ips_cmd_timeout;
 680        scb->cdb[0] = IPS_CMD_FLUSH;
 681
 682        scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
 683        scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
 684        scb->cmd.flush_cache.state = IPS_NORM_STATE;
 685        scb->cmd.flush_cache.reserved = 0;
 686        scb->cmd.flush_cache.reserved2 = 0;
 687        scb->cmd.flush_cache.reserved3 = 0;
 688        scb->cmd.flush_cache.reserved4 = 0;
 689
 690        IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
 691
 692        /* send command */
 693        if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
 694                IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
 695
 696        IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
 697
 698        ips_sh[i] = NULL;
 699        ips_ha[i] = NULL;
 700
 701        /* free extra memory */
 702        ips_free(ha);
 703
 704        /* free IRQ */
 705        free_irq(ha->pcidev->irq, ha);
 706
 707        scsi_host_put(sh);
 708
 709        ips_released_controllers++;
 710
 711        return (FALSE);
 712}
 713
 714/****************************************************************************/
 715/*                                                                          */
 716/* Routine Name: ips_halt                                                   */
 717/*                                                                          */
 718/* Routine Description:                                                     */
 719/*                                                                          */
 720/*   Perform cleanup when the system reboots                                */
 721/*                                                                          */
 722/****************************************************************************/
 723static int
 724ips_halt(struct notifier_block *nb, ulong event, void *buf)
 725{
 726        ips_scb_t *scb;
 727        ips_ha_t *ha;
 728        int i;
 729
 730        if ((event != SYS_RESTART) && (event != SYS_HALT) &&
 731            (event != SYS_POWER_OFF))
 732                return (NOTIFY_DONE);
 733
 734        for (i = 0; i < ips_next_controller; i++) {
 735                ha = (ips_ha_t *) ips_ha[i];
 736
 737                if (!ha)
 738                        continue;
 739
 740                if (!ha->active)
 741                        continue;
 742
 743                /* flush the cache on the controller */
 744                scb = &ha->scbs[ha->max_cmds - 1];
 745
 746                ips_init_scb(ha, scb);
 747
 748                scb->timeout = ips_cmd_timeout;
 749                scb->cdb[0] = IPS_CMD_FLUSH;
 750
 751                scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
 752                scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
 753                scb->cmd.flush_cache.state = IPS_NORM_STATE;
 754                scb->cmd.flush_cache.reserved = 0;
 755                scb->cmd.flush_cache.reserved2 = 0;
 756                scb->cmd.flush_cache.reserved3 = 0;
 757                scb->cmd.flush_cache.reserved4 = 0;
 758
 759                IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
 760
 761                /* send command */
 762                if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
 763                    IPS_FAILURE)
 764                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
 765                                   "Incomplete Flush.\n");
 766                else
 767                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
 768                                   "Flushing Complete.\n");
 769        }
 770
 771        return (NOTIFY_OK);
 772}
 773
 774/****************************************************************************/
 775/*                                                                          */
 776/* Routine Name: ips_eh_abort                                               */
 777/*                                                                          */
 778/* Routine Description:                                                     */
 779/*                                                                          */
 780/*   Abort a command (using the new error code stuff)                       */
 781/* Note: this routine is called under the io_request_lock                   */
 782/****************************************************************************/
 783int ips_eh_abort(struct scsi_cmnd *SC)
 784{
 785        ips_ha_t *ha;
 786        ips_copp_wait_item_t *item;
 787        int ret;
 788        struct Scsi_Host *host;
 789
 790        METHOD_TRACE("ips_eh_abort", 1);
 791
 792        if (!SC)
 793                return (FAILED);
 794
 795        host = SC->device->host;
 796        ha = (ips_ha_t *) SC->device->host->hostdata;
 797
 798        if (!ha)
 799                return (FAILED);
 800
 801        if (!ha->active)
 802                return (FAILED);
 803
 804        spin_lock(host->host_lock);
 805
 806        /* See if the command is on the copp queue */
 807        item = ha->copp_waitlist.head;
 808        while ((item) && (item->scsi_cmd != SC))
 809                item = item->next;
 810
 811        if (item) {
 812                /* Found it */
 813                ips_removeq_copp(&ha->copp_waitlist, item);
 814                ret = (SUCCESS);
 815
 816                /* See if the command is on the wait queue */
 817        } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
 818                /* command not sent yet */
 819                ret = (SUCCESS);
 820        } else {
 821                /* command must have already been sent */
 822                ret = (FAILED);
 823        }
 824
 825        spin_unlock(host->host_lock);
 826        return ret;
 827}
 828
 829/****************************************************************************/
 830/*                                                                          */
 831/* Routine Name: ips_eh_reset                                               */
 832/*                                                                          */
 833/* Routine Description:                                                     */
 834/*                                                                          */
 835/*   Reset the controller (with new eh error code)                          */
 836/*                                                                          */
 837/* NOTE: this routine is called under the io_request_lock spinlock          */
 838/*                                                                          */
 839/****************************************************************************/
 840static int __ips_eh_reset(struct scsi_cmnd *SC)
 841{
 842        int ret;
 843        int i;
 844        ips_ha_t *ha;
 845        ips_scb_t *scb;
 846        ips_copp_wait_item_t *item;
 847
 848        METHOD_TRACE("ips_eh_reset", 1);
 849
 850#ifdef NO_IPS_RESET
 851        return (FAILED);
 852#else
 853
 854        if (!SC) {
 855                DEBUG(1, "Reset called with NULL scsi command");
 856
 857                return (FAILED);
 858        }
 859
 860        ha = (ips_ha_t *) SC->device->host->hostdata;
 861
 862        if (!ha) {
 863                DEBUG(1, "Reset called with NULL ha struct");
 864
 865                return (FAILED);
 866        }
 867
 868        if (!ha->active)
 869                return (FAILED);
 870
 871        /* See if the command is on the copp queue */
 872        item = ha->copp_waitlist.head;
 873        while ((item) && (item->scsi_cmd != SC))
 874                item = item->next;
 875
 876        if (item) {
 877                /* Found it */
 878                ips_removeq_copp(&ha->copp_waitlist, item);
 879                return (SUCCESS);
 880        }
 881
 882        /* See if the command is on the wait queue */
 883        if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
 884                /* command not sent yet */
 885                return (SUCCESS);
 886        }
 887
 888        /* An explanation for the casual observer:                              */
 889        /* Part of the function of a RAID controller is automatic error         */
 890        /* detection and recovery.  As such, the only problem that physically   */
 891        /* resetting an adapter will ever fix is when, for some reason,         */
 892        /* the driver is not successfully communicating with the adapter.       */
 893        /* Therefore, we will attempt to flush this adapter.  If that succeeds, */
 894        /* then there's no real purpose in a physical reset. This will complete */
 895        /* much faster and avoids any problems that might be caused by a        */
 896        /* physical reset ( such as having to fail all the outstanding I/O's ). */
 897
 898        if (ha->ioctl_reset == 0) {     /* IF Not an IOCTL Requested Reset */
 899                scb = &ha->scbs[ha->max_cmds - 1];
 900
 901                ips_init_scb(ha, scb);
 902
 903                scb->timeout = ips_cmd_timeout;
 904                scb->cdb[0] = IPS_CMD_FLUSH;
 905
 906                scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
 907                scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
 908                scb->cmd.flush_cache.state = IPS_NORM_STATE;
 909                scb->cmd.flush_cache.reserved = 0;
 910                scb->cmd.flush_cache.reserved2 = 0;
 911                scb->cmd.flush_cache.reserved3 = 0;
 912                scb->cmd.flush_cache.reserved4 = 0;
 913
 914                /* Attempt the flush command */
 915                ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
 916                if (ret == IPS_SUCCESS) {
 917                        IPS_PRINTK(KERN_NOTICE, ha->pcidev,
 918                                   "Reset Request - Flushed Cache\n");
 919                        return (SUCCESS);
 920                }
 921        }
 922
 923        /* Either we can't communicate with the adapter or it's an IOCTL request */
 924        /* from a utility.  A physical reset is needed at this point.            */
 925
 926        ha->ioctl_reset = 0;    /* Reset the IOCTL Requested Reset Flag */
 927
 928        /*
 929         * command must have already been sent
 930         * reset the controller
 931         */
 932        IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
 933        ret = (*ha->func.reset) (ha);
 934
 935        if (!ret) {
 936                struct scsi_cmnd *scsi_cmd;
 937
 938                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
 939                           "Controller reset failed - controller now offline.\n");
 940
 941                /* Now fail all of the active commands */
 942                DEBUG_VAR(1, "(%s%d) Failing active commands",
 943                          ips_name, ha->host_num);
 944
 945                while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
 946                        scb->scsi_cmd->result = DID_ERROR << 16;
 947                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
 948                        ips_freescb(ha, scb);
 949                }
 950
 951                /* Now fail all of the pending commands */
 952                DEBUG_VAR(1, "(%s%d) Failing pending commands",
 953                          ips_name, ha->host_num);
 954
 955                while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
 956                        scsi_cmd->result = DID_ERROR;
 957                        scsi_cmd->scsi_done(scsi_cmd);
 958                }
 959
 960                ha->active = FALSE;
 961                return (FAILED);
 962        }
 963
 964        if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
 965                struct scsi_cmnd *scsi_cmd;
 966
 967                IPS_PRINTK(KERN_NOTICE, ha->pcidev,
 968                           "Controller reset failed - controller now offline.\n");
 969
 970                /* Now fail all of the active commands */
 971                DEBUG_VAR(1, "(%s%d) Failing active commands",
 972                          ips_name, ha->host_num);
 973
 974                while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
 975                        scb->scsi_cmd->result = DID_ERROR << 16;
 976                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
 977                        ips_freescb(ha, scb);
 978                }
 979
 980                /* Now fail all of the pending commands */
 981                DEBUG_VAR(1, "(%s%d) Failing pending commands",
 982                          ips_name, ha->host_num);
 983
 984                while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
 985                        scsi_cmd->result = DID_ERROR << 16;
 986                        scsi_cmd->scsi_done(scsi_cmd);
 987                }
 988
 989                ha->active = FALSE;
 990                return (FAILED);
 991        }
 992
 993        /* FFDC */
 994        if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
 995                struct timeval tv;
 996
 997                do_gettimeofday(&tv);
 998                ha->last_ffdc = tv.tv_sec;
 999                ha->reset_count++;
1000                ips_ffdc_reset(ha, IPS_INTR_IORL);
1001        }
1002
1003        /* Now fail all of the active commands */
1004        DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1005
1006        while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1007                scb->scsi_cmd->result = DID_RESET << 16;
1008                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1009                ips_freescb(ha, scb);
1010        }
1011
1012        /* Reset DCDB active command bits */
1013        for (i = 1; i < ha->nbus; i++)
1014                ha->dcdb_active[i - 1] = 0;
1015
1016        /* Reset the number of active IOCTLs */
1017        ha->num_ioctl = 0;
1018
1019        ips_next(ha, IPS_INTR_IORL);
1020
1021        return (SUCCESS);
1022#endif                          /* NO_IPS_RESET */
1023
1024}
1025
1026static int ips_eh_reset(struct scsi_cmnd *SC)
1027{
1028        int rc;
1029
1030        spin_lock_irq(SC->device->host->host_lock);
1031        rc = __ips_eh_reset(SC);
1032        spin_unlock_irq(SC->device->host->host_lock);
1033
1034        return rc;
1035}
1036
1037/****************************************************************************/
1038/*                                                                          */
1039/* Routine Name: ips_queue                                                  */
1040/*                                                                          */
1041/* Routine Description:                                                     */
1042/*                                                                          */
1043/*   Send a command to the controller                                       */
1044/*                                                                          */
1045/* NOTE:                                                                    */
1046/*    Linux obtains io_request_lock before calling this function            */
1047/*                                                                          */
1048/****************************************************************************/
1049static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
1050{
1051        ips_ha_t *ha;
1052        ips_passthru_t *pt;
1053
1054        METHOD_TRACE("ips_queue", 1);
1055
1056        ha = (ips_ha_t *) SC->device->host->hostdata;
1057
1058        if (!ha)
1059                return (1);
1060
1061        if (!ha->active)
1062                return (DID_ERROR);
1063
1064        if (ips_is_passthru(SC)) {
1065                if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1066                        SC->result = DID_BUS_BUSY << 16;
1067                        done(SC);
1068
1069                        return (0);
1070                }
1071        } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1072                SC->result = DID_BUS_BUSY << 16;
1073                done(SC);
1074
1075                return (0);
1076        }
1077
1078        SC->scsi_done = done;
1079
1080        DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1081                  ips_name,
1082                  ha->host_num,
1083                  SC->cmnd[0],
1084                  SC->device->channel, SC->device->id, SC->device->lun);
1085
1086        /* Check for command to initiator IDs */
1087        if ((scmd_channel(SC) > 0)
1088            && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
1089                SC->result = DID_NO_CONNECT << 16;
1090                done(SC);
1091
1092                return (0);
1093        }
1094
1095        if (ips_is_passthru(SC)) {
1096
1097                ips_copp_wait_item_t *scratch;
1098
1099                /* A Reset IOCTL is only sent by the boot CD in extreme cases.           */
1100                /* There can never be any system activity ( network or disk ), but check */
1101                /* anyway just as a good practice.                                       */
1102                pt = (ips_passthru_t *) scsi_sglist(SC);
1103                if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
1104                    (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
1105                        if (ha->scb_activelist.count != 0) {
1106                                SC->result = DID_BUS_BUSY << 16;
1107                                done(SC);
1108                                return (0);
1109                        }
1110                        ha->ioctl_reset = 1;    /* This reset request is from an IOCTL */
1111                        __ips_eh_reset(SC);
1112                        SC->result = DID_OK << 16;
1113                        SC->scsi_done(SC);
1114                        return (0);
1115                }
1116
1117                /* allocate space for the scribble */
1118                scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
1119
1120                if (!scratch) {
1121                        SC->result = DID_ERROR << 16;
1122                        done(SC);
1123
1124                        return (0);
1125                }
1126
1127                scratch->scsi_cmd = SC;
1128                scratch->next = NULL;
1129
1130                ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1131        } else {
1132                ips_putq_wait_tail(&ha->scb_waitlist, SC);
1133        }
1134
1135        ips_next(ha, IPS_INTR_IORL);
1136
1137        return (0);
1138}
1139
1140/****************************************************************************/
1141/*                                                                          */
1142/* Routine Name: ips_biosparam                                              */
1143/*                                                                          */
1144/* Routine Description:                                                     */
1145/*                                                                          */
1146/*   Set bios geometry for the controller                                   */
1147/*                                                                          */
1148/****************************************************************************/
1149static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1150                         sector_t capacity, int geom[])
1151{
1152        ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1153        int heads;
1154        int sectors;
1155        int cylinders;
1156
1157        METHOD_TRACE("ips_biosparam", 1);
1158
1159        if (!ha)
1160                /* ?!?! host adater info invalid */
1161                return (0);
1162
1163        if (!ha->active)
1164                return (0);
1165
1166        if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1167                /* ?!?! Enquiry command failed */
1168                return (0);
1169
1170        if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1171                heads = IPS_NORM_HEADS;
1172                sectors = IPS_NORM_SECTORS;
1173        } else {
1174                heads = IPS_COMP_HEADS;
1175                sectors = IPS_COMP_SECTORS;
1176        }
1177
1178        cylinders = (unsigned long) capacity / (heads * sectors);
1179
1180        DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1181                  heads, sectors, cylinders);
1182
1183        geom[0] = heads;
1184        geom[1] = sectors;
1185        geom[2] = cylinders;
1186
1187        return (0);
1188}
1189
1190/****************************************************************************/
1191/*                                                                          */
1192/* Routine Name: ips_slave_configure                                        */
1193/*                                                                          */
1194/* Routine Description:                                                     */
1195/*                                                                          */
1196/*   Set queue depths on devices once scan is complete                      */
1197/*                                                                          */
1198/****************************************************************************/
1199static int
1200ips_slave_configure(struct scsi_device * SDptr)
1201{
1202        ips_ha_t *ha;
1203        int min;
1204
1205        ha = IPS_HA(SDptr->host);
1206        if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1207                min = ha->max_cmds / 2;
1208                if (ha->enq->ucLogDriveCount <= 2)
1209                        min = ha->max_cmds - 1;
1210                scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1211        }
1212
1213        SDptr->skip_ms_page_8 = 1;
1214        SDptr->skip_ms_page_3f = 1;
1215        return 0;
1216}
1217
1218/****************************************************************************/
1219/*                                                                          */
1220/* Routine Name: do_ipsintr                                                 */
1221/*                                                                          */
1222/* Routine Description:                                                     */
1223/*                                                                          */
1224/*   Wrapper for the interrupt handler                                      */
1225/*                                                                          */
1226/****************************************************************************/
1227static irqreturn_t
1228do_ipsintr(int irq, void *dev_id)
1229{
1230        ips_ha_t *ha;
1231        struct Scsi_Host *host;
1232        int irqstatus;
1233
1234        METHOD_TRACE("do_ipsintr", 2);
1235
1236        ha = (ips_ha_t *) dev_id;
1237        if (!ha)
1238                return IRQ_NONE;
1239        host = ips_sh[ha->host_num];
1240        /* interrupt during initialization */
1241        if (!host) {
1242                (*ha->func.intr) (ha);
1243                return IRQ_HANDLED;
1244        }
1245
1246        spin_lock(host->host_lock);
1247
1248        if (!ha->active) {
1249                spin_unlock(host->host_lock);
1250                return IRQ_HANDLED;
1251        }
1252
1253        irqstatus = (*ha->func.intr) (ha);
1254
1255        spin_unlock(host->host_lock);
1256
1257        /* start the next command */
1258        ips_next(ha, IPS_INTR_ON);
1259        return IRQ_RETVAL(irqstatus);
1260}
1261
1262/****************************************************************************/
1263/*                                                                          */
1264/* Routine Name: ips_intr_copperhead                                        */
1265/*                                                                          */
1266/* Routine Description:                                                     */
1267/*                                                                          */
1268/*   Polling interrupt handler                                              */
1269/*                                                                          */
1270/*   ASSUMES interrupts are disabled                                        */
1271/*                                                                          */
1272/****************************************************************************/
1273int
1274ips_intr_copperhead(ips_ha_t * ha)
1275{
1276        ips_stat_t *sp;
1277        ips_scb_t *scb;
1278        IPS_STATUS cstatus;
1279        int intrstatus;
1280
1281        METHOD_TRACE("ips_intr", 2);
1282
1283        if (!ha)
1284                return 0;
1285
1286        if (!ha->active)
1287                return 0;
1288
1289        intrstatus = (*ha->func.isintr) (ha);
1290
1291        if (!intrstatus) {
1292                /*
1293                 * Unexpected/Shared interrupt
1294                 */
1295
1296                return 0;
1297        }
1298
1299        while (TRUE) {
1300                sp = &ha->sp;
1301
1302                intrstatus = (*ha->func.isintr) (ha);
1303
1304                if (!intrstatus)
1305                        break;
1306                else
1307                        cstatus.value = (*ha->func.statupd) (ha);
1308
1309                if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1310                        /* Spurious Interrupt ? */
1311                        continue;
1312                }
1313
1314                ips_chkstatus(ha, &cstatus);
1315                scb = (ips_scb_t *) sp->scb_addr;
1316
1317                /*
1318                 * use the callback function to finish things up
1319                 * NOTE: interrupts are OFF for this
1320                 */
1321                (*scb->callback) (ha, scb);
1322        }                       /* end while */
1323        return 1;
1324}
1325
1326/****************************************************************************/
1327/*                                                                          */
1328/* Routine Name: ips_intr_morpheus                                          */
1329/*                                                                          */
1330/* Routine Description:                                                     */
1331/*                                                                          */
1332/*   Polling interrupt handler                                              */
1333/*                                                                          */
1334/*   ASSUMES interrupts are disabled                                        */
1335/*                                                                          */
1336/****************************************************************************/
1337int
1338ips_intr_morpheus(ips_ha_t * ha)
1339{
1340        ips_stat_t *sp;
1341        ips_scb_t *scb;
1342        IPS_STATUS cstatus;
1343        int intrstatus;
1344
1345        METHOD_TRACE("ips_intr_morpheus", 2);
1346
1347        if (!ha)
1348                return 0;
1349
1350        if (!ha->active)
1351                return 0;
1352
1353        intrstatus = (*ha->func.isintr) (ha);
1354
1355        if (!intrstatus) {
1356                /*
1357                 * Unexpected/Shared interrupt
1358                 */
1359
1360                return 0;
1361        }
1362
1363        while (TRUE) {
1364                sp = &ha->sp;
1365
1366                intrstatus = (*ha->func.isintr) (ha);
1367
1368                if (!intrstatus)
1369                        break;
1370                else
1371                        cstatus.value = (*ha->func.statupd) (ha);
1372
1373                if (cstatus.value == 0xffffffff)
1374                        /* No more to process */
1375                        break;
1376
1377                if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1378                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
1379                                   "Spurious interrupt; no ccb.\n");
1380
1381                        continue;
1382                }
1383
1384                ips_chkstatus(ha, &cstatus);
1385                scb = (ips_scb_t *) sp->scb_addr;
1386
1387                /*
1388                 * use the callback function to finish things up
1389                 * NOTE: interrupts are OFF for this
1390                 */
1391                (*scb->callback) (ha, scb);
1392        }                       /* end while */
1393        return 1;
1394}
1395
1396/****************************************************************************/
1397/*                                                                          */
1398/* Routine Name: ips_info                                                   */
1399/*                                                                          */
1400/* Routine Description:                                                     */
1401/*                                                                          */
1402/*   Return info about the driver                                           */
1403/*                                                                          */
1404/****************************************************************************/
1405static const char *
1406ips_info(struct Scsi_Host *SH)
1407{
1408        static char buffer[256];
1409        char *bp;
1410        ips_ha_t *ha;
1411
1412        METHOD_TRACE("ips_info", 1);
1413
1414        ha = IPS_HA(SH);
1415
1416        if (!ha)
1417                return (NULL);
1418
1419        bp = &buffer[0];
1420        memset(bp, 0, sizeof (buffer));
1421
1422        sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1423                IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1424
1425        if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1426                strcat(bp, " <");
1427                strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1428                strcat(bp, ">");
1429        }
1430
1431        return (bp);
1432}
1433
1434/****************************************************************************/
1435/*                                                                          */
1436/* Routine Name: ips_proc_info                                              */
1437/*                                                                          */
1438/* Routine Description:                                                     */
1439/*                                                                          */
1440/*   The passthru interface for the driver                                  */
1441/*                                                                          */
1442/****************************************************************************/
1443static int
1444ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1445              int length, int func)
1446{
1447        int i;
1448        int ret;
1449        ips_ha_t *ha = NULL;
1450
1451        METHOD_TRACE("ips_proc_info", 1);
1452
1453        /* Find our host structure */
1454        for (i = 0; i < ips_next_controller; i++) {
1455                if (ips_sh[i]) {
1456                        if (ips_sh[i] == host) {
1457                                ha = (ips_ha_t *) ips_sh[i]->hostdata;
1458                                break;
1459                        }
1460                }
1461        }
1462
1463        if (!ha)
1464                return (-EINVAL);
1465
1466        if (func) {
1467                /* write */
1468                return (0);
1469        } else {
1470                /* read */
1471                if (start)
1472                        *start = buffer;
1473
1474                ret = ips_host_info(ha, buffer, offset, length);
1475
1476                return (ret);
1477        }
1478}
1479
1480/*--------------------------------------------------------------------------*/
1481/* Helper Functions                                                         */
1482/*--------------------------------------------------------------------------*/
1483
1484/****************************************************************************/
1485/*                                                                          */
1486/* Routine Name: ips_is_passthru                                            */
1487/*                                                                          */
1488/* Routine Description:                                                     */
1489/*                                                                          */
1490/*   Determine if the specified SCSI command is really a passthru command   */
1491/*                                                                          */
1492/****************************************************************************/
1493static int ips_is_passthru(struct scsi_cmnd *SC)
1494{
1495        unsigned long flags;
1496
1497        METHOD_TRACE("ips_is_passthru", 1);
1498
1499        if (!SC)
1500                return (0);
1501
1502        if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1503            (SC->device->channel == 0) &&
1504            (SC->device->id == IPS_ADAPTER_ID) &&
1505            (SC->device->lun == 0) && scsi_sglist(SC)) {
1506                struct scatterlist *sg = scsi_sglist(SC);
1507                char  *buffer;
1508
1509                /* kmap_atomic() ensures addressability of the user buffer.*/
1510                /* local_irq_save() protects the KM_IRQ0 address slot.     */
1511                local_irq_save(flags);
1512                buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
1513                if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
1514                    buffer[2] == 'P' && buffer[3] == 'P') {
1515                        kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1516                        local_irq_restore(flags);
1517                        return 1;
1518                }
1519                kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1520                local_irq_restore(flags);
1521        }
1522        return 0;
1523}
1524
1525/****************************************************************************/
1526/*                                                                          */
1527/* Routine Name: ips_alloc_passthru_buffer                                  */
1528/*                                                                          */
1529/* Routine Description:                                                     */
1530/*   allocate a buffer large enough for the ioctl data if the ioctl buffer  */
1531/*   is too small or doesn't exist                                          */
1532/****************************************************************************/
1533static int
1534ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1535{
1536        void *bigger_buf;
1537        dma_addr_t dma_busaddr;
1538
1539        if (ha->ioctl_data && length <= ha->ioctl_len)
1540                return 0;
1541        /* there is no buffer or it's not big enough, allocate a new one */
1542        bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1543        if (bigger_buf) {
1544                /* free the old memory */
1545                pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1546                                    ha->ioctl_busaddr);
1547                /* use the new memory */
1548                ha->ioctl_data = (char *) bigger_buf;
1549                ha->ioctl_len = length;
1550                ha->ioctl_busaddr = dma_busaddr;
1551        } else {
1552                return -1;
1553        }
1554        return 0;
1555}
1556
1557/****************************************************************************/
1558/*                                                                          */
1559/* Routine Name: ips_make_passthru                                          */
1560/*                                                                          */
1561/* Routine Description:                                                     */
1562/*                                                                          */
1563/*   Make a passthru command out of the info in the Scsi block              */
1564/*                                                                          */
1565/****************************************************************************/
1566static int
1567ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
1568{
1569        ips_passthru_t *pt;
1570        int length = 0;
1571        int i, ret;
1572        struct scatterlist *sg = scsi_sglist(SC);
1573
1574        METHOD_TRACE("ips_make_passthru", 1);
1575
1576        scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
1577                length += sg->length;
1578
1579        if (length < sizeof (ips_passthru_t)) {
1580                /* wrong size */
1581                DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1582                          ips_name, ha->host_num);
1583                return (IPS_FAILURE);
1584        }
1585        if (ips_alloc_passthru_buffer(ha, length)) {
1586                /* allocation failure!  If ha->ioctl_data exists, use it to return
1587                   some error codes.  Return a failed command to the scsi layer. */
1588                if (ha->ioctl_data) {
1589                        pt = (ips_passthru_t *) ha->ioctl_data;
1590                        ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1591                        pt->BasicStatus = 0x0B;
1592                        pt->ExtendedStatus = 0x00;
1593                        ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1594                }
1595                return IPS_FAILURE;
1596        }
1597        ha->ioctl_datasize = length;
1598
1599        ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1600        pt = (ips_passthru_t *) ha->ioctl_data;
1601
1602        /*
1603         * Some notes about the passthru interface used
1604         *
1605         * IF the scsi op_code == 0x0d then we assume
1606         * that the data came along with/goes with the
1607         * packet we received from the sg driver. In this
1608         * case the CmdBSize field of the pt structure is
1609         * used for the size of the buffer.
1610         */
1611
1612        switch (pt->CoppCmd) {
1613        case IPS_NUMCTRLS:
1614                memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1615                       &ips_num_controllers, sizeof (int));
1616                ips_scmd_buf_write(SC, ha->ioctl_data,
1617                                   sizeof (ips_passthru_t) + sizeof (int));
1618                SC->result = DID_OK << 16;
1619
1620                return (IPS_SUCCESS_IMM);
1621
1622        case IPS_COPPUSRCMD:
1623        case IPS_COPPIOCCMD:
1624                if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1625                        if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1626                                /* wrong size */
1627                                DEBUG_VAR(1,
1628                                          "(%s%d) Passthru structure wrong size",
1629                                          ips_name, ha->host_num);
1630
1631                                return (IPS_FAILURE);
1632                        }
1633
1634                        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
1635                            pt->CoppCP.cmd.flashfw.op_code ==
1636                            IPS_CMD_RW_BIOSFW) {
1637                                ret = ips_flash_copperhead(ha, pt, scb);
1638                                ips_scmd_buf_write(SC, ha->ioctl_data,
1639                                                   sizeof (ips_passthru_t));
1640                                return ret;
1641                        }
1642                        if (ips_usrcmd(ha, pt, scb))
1643                                return (IPS_SUCCESS);
1644                        else
1645                                return (IPS_FAILURE);
1646                }
1647
1648                break;
1649
1650        }                       /* end switch */
1651
1652        return (IPS_FAILURE);
1653}
1654
1655/****************************************************************************/
1656/* Routine Name: ips_flash_copperhead                                       */
1657/* Routine Description:                                                     */
1658/*   Flash the BIOS/FW on a Copperhead style controller                     */
1659/****************************************************************************/
1660static int
1661ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1662{
1663        int datasize;
1664
1665        /* Trombone is the only copperhead that can do packet flash, but only
1666         * for firmware. No one said it had to make sence. */
1667        if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1668                if (ips_usrcmd(ha, pt, scb))
1669                        return IPS_SUCCESS;
1670                else
1671                        return IPS_FAILURE;
1672        }
1673        pt->BasicStatus = 0x0B;
1674        pt->ExtendedStatus = 0;
1675        scb->scsi_cmd->result = DID_OK << 16;
1676        /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
1677        /* avoid allocating a huge buffer per adapter ( which can fail ). */
1678        if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1679            pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1680                pt->BasicStatus = 0;
1681                return ips_flash_bios(ha, pt, scb);
1682        } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1683                if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1684                        ha->flash_data = ips_FlashData;
1685                        ha->flash_busaddr = ips_flashbusaddr;
1686                        ha->flash_len = PAGE_SIZE << 7;
1687                        ha->flash_datasize = 0;
1688                } else if (!ha->flash_data) {
1689                        datasize = pt->CoppCP.cmd.flashfw.total_packets *
1690                            pt->CoppCP.cmd.flashfw.count;
1691                        ha->flash_data = pci_alloc_consistent(ha->pcidev,
1692                                                              datasize,
1693                                                              &ha->flash_busaddr);
1694                        if (!ha->flash_data){
1695                                printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1696                                return IPS_FAILURE;
1697                        }
1698                        ha->flash_datasize = 0;
1699                        ha->flash_len = datasize;
1700                } else
1701                        return IPS_FAILURE;
1702        } else {
1703                if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1704                    ha->flash_len) {
1705                        ips_free_flash_copperhead(ha);
1706                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
1707                                   "failed size sanity check\n");
1708                        return IPS_FAILURE;
1709                }
1710        }
1711        if (!ha->flash_data)
1712                return IPS_FAILURE;
1713        pt->BasicStatus = 0;
1714        memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1715               pt->CoppCP.cmd.flashfw.count);
1716        ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1717        if (pt->CoppCP.cmd.flashfw.packet_num ==
1718            pt->CoppCP.cmd.flashfw.total_packets - 1) {
1719                if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1720                        return ips_flash_bios(ha, pt, scb);
1721                else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1722                        return ips_flash_firmware(ha, pt, scb);
1723        }
1724        return IPS_SUCCESS_IMM;
1725}
1726
1727/****************************************************************************/
1728/* Routine Name: ips_flash_bios                                             */
1729/* Routine Description:                                                     */
1730/*   flashes the bios of a copperhead adapter                               */
1731/****************************************************************************/
1732static int
1733ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1734{
1735
1736        if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1737            pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1738                if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1739                    (!ha->func.verifybios))
1740                        goto error;
1741                if ((*ha->func.erasebios) (ha)) {
1742                        DEBUG_VAR(1,
1743                                  "(%s%d) flash bios failed - unable to erase flash",
1744                                  ips_name, ha->host_num);
1745                        goto error;
1746                } else
1747                    if ((*ha->func.programbios) (ha,
1748                                                 ha->flash_data +
1749                                                 IPS_BIOS_HEADER,
1750                                                 ha->flash_datasize -
1751                                                 IPS_BIOS_HEADER, 0)) {
1752                        DEBUG_VAR(1,
1753                                  "(%s%d) flash bios failed - unable to flash",
1754                                  ips_name, ha->host_num);
1755                        goto error;
1756                } else
1757                    if ((*ha->func.verifybios) (ha,
1758                                                ha->flash_data +
1759                                                IPS_BIOS_HEADER,
1760                                                ha->flash_datasize -
1761                                                IPS_BIOS_HEADER, 0)) {
1762                        DEBUG_VAR(1,
1763                                  "(%s%d) flash bios failed - unable to verify flash",
1764                                  ips_name, ha->host_num);
1765                        goto error;
1766                }
1767                ips_free_flash_copperhead(ha);
1768                return IPS_SUCCESS_IMM;
1769        } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1770                   pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1771                if (!ha->func.erasebios)
1772                        goto error;
1773                if ((*ha->func.erasebios) (ha)) {
1774                        DEBUG_VAR(1,
1775                                  "(%s%d) flash bios failed - unable to erase flash",
1776                                  ips_name, ha->host_num);
1777                        goto error;
1778                }
1779                return IPS_SUCCESS_IMM;
1780        }
1781      error:
1782        pt->BasicStatus = 0x0B;
1783        pt->ExtendedStatus = 0x00;
1784        ips_free_flash_copperhead(ha);
1785        return IPS_FAILURE;
1786}
1787
1788/****************************************************************************/
1789/*                                                                          */
1790/* Routine Name: ips_fill_scb_sg_single                                     */
1791/*                                                                          */
1792/* Routine Description:                                                     */
1793/*   Fill in a single scb sg_list element from an address                   */
1794/*   return a -1 if a breakup occurred                                      */
1795/****************************************************************************/
1796static int
1797ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1798                       ips_scb_t * scb, int indx, unsigned int e_len)
1799{
1800
1801        int ret_val = 0;
1802
1803        if ((scb->data_len + e_len) > ha->max_xfer) {
1804                e_len = ha->max_xfer - scb->data_len;
1805                scb->breakup = indx;
1806                ++scb->sg_break;
1807                ret_val = -1;
1808        } else {
1809                scb->breakup = 0;
1810                scb->sg_break = 0;
1811        }
1812        if (IPS_USE_ENH_SGLIST(ha)) {
1813                scb->sg_list.enh_list[indx].address_lo =
1814                    cpu_to_le32(pci_dma_lo32(busaddr));
1815                scb->sg_list.enh_list[indx].address_hi =
1816                    cpu_to_le32(pci_dma_hi32(busaddr));
1817                scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1818        } else {
1819                scb->sg_list.std_list[indx].address =
1820                    cpu_to_le32(pci_dma_lo32(busaddr));
1821                scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1822        }
1823
1824        ++scb->sg_len;
1825        scb->data_len += e_len;
1826        return ret_val;
1827}
1828
1829/****************************************************************************/
1830/* Routine Name: ips_flash_firmware                                         */
1831/* Routine Description:                                                     */
1832/*   flashes the firmware of a copperhead adapter                           */
1833/****************************************************************************/
1834static int
1835ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1836{
1837        IPS_SG_LIST sg_list;
1838        uint32_t cmd_busaddr;
1839
1840        if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1841            pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1842                memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1843                pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1844                pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1845        } else {
1846                pt->BasicStatus = 0x0B;
1847                pt->ExtendedStatus = 0x00;
1848                ips_free_flash_copperhead(ha);
1849                return IPS_FAILURE;
1850        }
1851        /* Save the S/G list pointer so it doesn't get clobbered */
1852        sg_list.list = scb->sg_list.list;
1853        cmd_busaddr = scb->scb_busaddr;
1854        /* copy in the CP */
1855        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1856        /* FIX stuff that might be wrong */
1857        scb->sg_list.list = sg_list.list;
1858        scb->scb_busaddr = cmd_busaddr;
1859        scb->bus = scb->scsi_cmd->device->channel;
1860        scb->target_id = scb->scsi_cmd->device->id;
1861        scb->lun = scb->scsi_cmd->device->lun;
1862        scb->sg_len = 0;
1863        scb->data_len = 0;
1864        scb->flags = 0;
1865        scb->op_code = 0;
1866        scb->callback = ipsintr_done;
1867        scb->timeout = ips_cmd_timeout;
1868
1869        scb->data_len = ha->flash_datasize;
1870        scb->data_busaddr =
1871            pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1872                           IPS_DMA_DIR(scb));
1873        scb->flags |= IPS_SCB_MAP_SINGLE;
1874        scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
1875        scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
1876        if (pt->TimeOut)
1877                scb->timeout = pt->TimeOut;
1878        scb->scsi_cmd->result = DID_OK << 16;
1879        return IPS_SUCCESS;
1880}
1881
1882/****************************************************************************/
1883/* Routine Name: ips_free_flash_copperhead                                  */
1884/* Routine Description:                                                     */
1885/*   release the memory resources used to hold the flash image              */
1886/****************************************************************************/
1887static void
1888ips_free_flash_copperhead(ips_ha_t * ha)
1889{
1890        if (ha->flash_data == ips_FlashData)
1891                test_and_clear_bit(0, &ips_FlashDataInUse);
1892        else if (ha->flash_data)
1893                pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
1894                                    ha->flash_busaddr);
1895        ha->flash_data = NULL;
1896}
1897
1898/****************************************************************************/
1899/*                                                                          */
1900/* Routine Name: ips_usrcmd                                                 */
1901/*                                                                          */
1902/* Routine Description:                                                     */
1903/*                                                                          */
1904/*   Process a user command and make it ready to send                       */
1905/*                                                                          */
1906/****************************************************************************/
1907static int
1908ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1909{
1910        IPS_SG_LIST sg_list;
1911        uint32_t cmd_busaddr;
1912
1913        METHOD_TRACE("ips_usrcmd", 1);
1914
1915        if ((!scb) || (!pt) || (!ha))
1916                return (0);
1917
1918        /* Save the S/G list pointer so it doesn't get clobbered */
1919        sg_list.list = scb->sg_list.list;
1920        cmd_busaddr = scb->scb_busaddr;
1921        /* copy in the CP */
1922        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1923        memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
1924
1925        /* FIX stuff that might be wrong */
1926        scb->sg_list.list = sg_list.list;
1927        scb->scb_busaddr = cmd_busaddr;
1928        scb->bus = scb->scsi_cmd->device->channel;
1929        scb->target_id = scb->scsi_cmd->device->id;
1930        scb->lun = scb->scsi_cmd->device->lun;
1931        scb->sg_len = 0;
1932        scb->data_len = 0;
1933        scb->flags = 0;
1934        scb->op_code = 0;
1935        scb->callback = ipsintr_done;
1936        scb->timeout = ips_cmd_timeout;
1937        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
1938
1939        /* we don't support DCDB/READ/WRITE Scatter Gather */
1940        if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
1941            (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
1942            (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
1943                return (0);
1944
1945        if (pt->CmdBSize) {
1946                scb->data_len = pt->CmdBSize;
1947                scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
1948        } else {
1949                scb->data_busaddr = 0L;
1950        }
1951
1952        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1953                scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
1954                                                         (unsigned long) &scb->
1955                                                         dcdb -
1956                                                         (unsigned long) scb);
1957
1958        if (pt->CmdBSize) {
1959                if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1960                        scb->dcdb.buffer_pointer =
1961                            cpu_to_le32(scb->data_busaddr);
1962                else
1963                        scb->cmd.basic_io.sg_addr =
1964                            cpu_to_le32(scb->data_busaddr);
1965        }
1966
1967        /* set timeouts */
1968        if (pt->TimeOut) {
1969                scb->timeout = pt->TimeOut;
1970
1971                if (pt->TimeOut <= 10)
1972                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
1973                else if (pt->TimeOut <= 60)
1974                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
1975                else
1976                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
1977        }
1978
1979        /* assume success */
1980        scb->scsi_cmd->result = DID_OK << 16;
1981
1982        /* success */
1983        return (1);
1984}
1985
1986/****************************************************************************/
1987/*                                                                          */
1988/* Routine Name: ips_cleanup_passthru                                       */
1989/*                                                                          */
1990/* Routine Description:                                                     */
1991/*                                                                          */
1992/*   Cleanup after a passthru command                                       */
1993/*                                                                          */
1994/****************************************************************************/
1995static void
1996ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
1997{
1998        ips_passthru_t *pt;
1999
2000        METHOD_TRACE("ips_cleanup_passthru", 1);
2001
2002        if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
2003                DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2004                          ips_name, ha->host_num);
2005
2006                return;
2007        }
2008        pt = (ips_passthru_t *) ha->ioctl_data;
2009
2010        /* Copy data back to the user */
2011        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)      /* Copy DCDB Back to Caller's Area */
2012                memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2013
2014        pt->BasicStatus = scb->basic_status;
2015        pt->ExtendedStatus = scb->extended_status;
2016        pt->AdapterType = ha->ad_type;
2017
2018        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
2019            (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2020             scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2021                ips_free_flash_copperhead(ha);
2022
2023        ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2024}
2025
2026/****************************************************************************/
2027/*                                                                          */
2028/* Routine Name: ips_host_info                                              */
2029/*                                                                          */
2030/* Routine Description:                                                     */
2031/*                                                                          */
2032/*   The passthru interface for the driver                                  */
2033/*                                                                          */
2034/****************************************************************************/
2035static int
2036ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2037{
2038        IPS_INFOSTR info;
2039
2040        METHOD_TRACE("ips_host_info", 1);
2041
2042        info.buffer = ptr;
2043        info.length = len;
2044        info.offset = offset;
2045        info.pos = 0;
2046        info.localpos = 0;
2047
2048        copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2049
2050        if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2051            (le16_to_cpu(ha->nvram->adapter_type) != 0))
2052                copy_info(&info, "\tController Type                   : %s\n",
2053                          ips_adapter_name[ha->ad_type - 1]);
2054        else
2055                copy_info(&info,
2056                          "\tController Type                   : Unknown\n");
2057
2058        if (ha->io_addr)
2059                copy_info(&info,
2060                          "\tIO region                         : 0x%lx (%d bytes)\n",
2061                          ha->io_addr, ha->io_len);
2062
2063        if (ha->mem_addr) {
2064                copy_info(&info,
2065                          "\tMemory region                     : 0x%lx (%d bytes)\n",
2066                          ha->mem_addr, ha->mem_len);
2067                copy_info(&info,
2068                          "\tShared memory address             : 0x%lx\n",
2069                          ha->mem_ptr);
2070        }
2071
2072        copy_info(&info, "\tIRQ number                        : %d\n", ha->pcidev->irq);
2073
2074    /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
2075    /* That keeps everything happy for "text" operations on the proc file.                    */
2076
2077        if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2078        if (ha->nvram->bios_low[3] == 0) {
2079            copy_info(&info,
2080                                  "\tBIOS Version                      : %c%c%c%c%c%c%c\n",
2081                                  ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2082                                  ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2083                                  ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2084                                  ha->nvram->bios_low[2]);
2085
2086        } else {
2087                    copy_info(&info,
2088                                  "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
2089                                  ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2090                                  ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2091                                  ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2092                                  ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2093        }
2094
2095    }
2096
2097    if (ha->enq->CodeBlkVersion[7] == 0) {
2098        copy_info(&info,
2099                          "\tFirmware Version                  : %c%c%c%c%c%c%c\n",
2100                          ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2101                          ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2102                          ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2103                          ha->enq->CodeBlkVersion[6]);
2104    } else {
2105        copy_info(&info,
2106                          "\tFirmware Version                  : %c%c%c%c%c%c%c%c\n",
2107                          ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2108                          ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2109                          ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2110                          ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2111    }
2112
2113    if (ha->enq->BootBlkVersion[7] == 0) {
2114        copy_info(&info,
2115                          "\tBoot Block Version                : %c%c%c%c%c%c%c\n",
2116                          ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2117                          ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2118                          ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2119                          ha->enq->BootBlkVersion[6]);
2120    } else {
2121        copy_info(&info,
2122                          "\tBoot Block Version                : %c%c%c%c%c%c%c%c\n",
2123                          ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2124                          ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2125                          ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2126                          ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2127    }
2128
2129        copy_info(&info, "\tDriver Version                    : %s%s\n",
2130                  IPS_VERSION_HIGH, IPS_VERSION_LOW);
2131
2132        copy_info(&info, "\tDriver Build                      : %d\n",
2133                  IPS_BUILD_IDENT);
2134
2135        copy_info(&info, "\tMax Physical Devices              : %d\n",
2136                  ha->enq->ucMaxPhysicalDevices);
2137        copy_info(&info, "\tMax Active Commands               : %d\n",
2138                  ha->max_cmds);
2139        copy_info(&info, "\tCurrent Queued Commands           : %d\n",
2140                  ha->scb_waitlist.count);
2141        copy_info(&info, "\tCurrent Active Commands           : %d\n",
2142                  ha->scb_activelist.count - ha->num_ioctl);
2143        copy_info(&info, "\tCurrent Queued PT Commands        : %d\n",
2144                  ha->copp_waitlist.count);
2145        copy_info(&info, "\tCurrent Active PT Commands        : %d\n",
2146                  ha->num_ioctl);
2147
2148        copy_info(&info, "\n");
2149
2150        return (info.localpos);
2151}
2152
2153/****************************************************************************/
2154/*                                                                          */
2155/* Routine Name: copy_mem_info                                              */
2156/*                                                                          */
2157/* Routine Description:                                                     */
2158/*                                                                          */
2159/*   Copy data into an IPS_INFOSTR structure                                */
2160/*                                                                          */
2161/****************************************************************************/
2162static void
2163copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2164{
2165        METHOD_TRACE("copy_mem_info", 1);
2166
2167        if (info->pos + len < info->offset) {
2168                info->pos += len;
2169                return;
2170        }
2171
2172        if (info->pos < info->offset) {
2173                data += (info->offset - info->pos);
2174                len -= (info->offset - info->pos);
2175                info->pos += (info->offset - info->pos);
2176        }
2177
2178        if (info->localpos + len > info->length)
2179                len = info->length - info->localpos;
2180
2181        if (len > 0) {
2182                memcpy(info->buffer + info->localpos, data, len);
2183                info->pos += len;
2184                info->localpos += len;
2185        }
2186}
2187
2188/****************************************************************************/
2189/*                                                                          */
2190/* Routine Name: copy_info                                                  */
2191/*                                                                          */
2192/* Routine Description:                                                     */
2193/*                                                                          */
2194/*   printf style wrapper for an info structure                             */
2195/*                                                                          */
2196/****************************************************************************/
2197static int
2198copy_info(IPS_INFOSTR * info, char *fmt, ...)
2199{
2200        va_list args;
2201        char buf[128];
2202        int len;
2203
2204        METHOD_TRACE("copy_info", 1);
2205
2206        va_start(args, fmt);
2207        len = vsprintf(buf, fmt, args);
2208        va_end(args);
2209
2210        copy_mem_info(info, buf, len);
2211
2212        return (len);
2213}
2214
2215/****************************************************************************/
2216/*                                                                          */
2217/* Routine Name: ips_identify_controller                                    */
2218/*                                                                          */
2219/* Routine Description:                                                     */
2220/*                                                                          */
2221/*   Identify this controller                                               */
2222/*                                                                          */
2223/****************************************************************************/
2224static void
2225ips_identify_controller(ips_ha_t * ha)
2226{
2227        METHOD_TRACE("ips_identify_controller", 1);
2228
2229        switch (ha->pcidev->device) {
2230        case IPS_DEVICEID_COPPERHEAD:
2231                if (ha->pcidev->revision <= IPS_REVID_SERVERAID) {
2232                        ha->ad_type = IPS_ADTYPE_SERVERAID;
2233                } else if (ha->pcidev->revision == IPS_REVID_SERVERAID2) {
2234                        ha->ad_type = IPS_ADTYPE_SERVERAID2;
2235                } else if (ha->pcidev->revision == IPS_REVID_NAVAJO) {
2236                        ha->ad_type = IPS_ADTYPE_NAVAJO;
2237                } else if ((ha->pcidev->revision == IPS_REVID_SERVERAID2)
2238                           && (ha->slot_num == 0)) {
2239                        ha->ad_type = IPS_ADTYPE_KIOWA;
2240                } else if ((ha->pcidev->revision >= IPS_REVID_CLARINETP1) &&
2241                           (ha->pcidev->revision <= IPS_REVID_CLARINETP3)) {
2242                        if (ha->enq->ucMaxPhysicalDevices == 15)
2243                                ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2244                        else
2245                                ha->ad_type = IPS_ADTYPE_SERVERAID3;
2246                } else if ((ha->pcidev->revision >= IPS_REVID_TROMBONE32) &&
2247                           (ha->pcidev->revision <= IPS_REVID_TROMBONE64)) {
2248                        ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2249                }
2250                break;
2251
2252        case IPS_DEVICEID_MORPHEUS:
2253                switch (ha->pcidev->subsystem_device) {
2254                case IPS_SUBDEVICEID_4L:
2255                        ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2256                        break;
2257
2258                case IPS_SUBDEVICEID_4M:
2259                        ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2260                        break;
2261
2262                case IPS_SUBDEVICEID_4MX:
2263                        ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2264                        break;
2265
2266                case IPS_SUBDEVICEID_4LX:
2267                        ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2268                        break;
2269
2270                case IPS_SUBDEVICEID_5I2:
2271                        ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2272                        break;
2273
2274                case IPS_SUBDEVICEID_5I1:
2275                        ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2276                        break;
2277                }
2278
2279                break;
2280
2281        case IPS_DEVICEID_MARCO:
2282                switch (ha->pcidev->subsystem_device) {
2283                case IPS_SUBDEVICEID_6M:
2284                        ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2285                        break;
2286                case IPS_SUBDEVICEID_6I:
2287                        ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2288                        break;
2289                case IPS_SUBDEVICEID_7k:
2290                        ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2291                        break;
2292                case IPS_SUBDEVICEID_7M:
2293                        ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2294                        break;
2295                }
2296                break;
2297        }
2298}
2299
2300/****************************************************************************/
2301/*                                                                          */
2302/* Routine Name: ips_get_bios_version                                       */
2303/*                                                                          */
2304/* Routine Description:                                                     */
2305/*                                                                          */
2306/*   Get the BIOS revision number                                           */
2307/*                                                                          */
2308/****************************************************************************/
2309static void
2310ips_get_bios_version(ips_ha_t * ha, int intr)
2311{
2312        ips_scb_t *scb;
2313        int ret;
2314        uint8_t major;
2315        uint8_t minor;
2316        uint8_t subminor;
2317        uint8_t *buffer;
2318        char hexDigits[] =
2319            { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2320     'D', 'E', 'F' };
2321
2322        METHOD_TRACE("ips_get_bios_version", 1);
2323
2324        major = 0;
2325        minor = 0;
2326
2327        strncpy(ha->bios_version, "       ?", 8);
2328
2329        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD) {
2330                if (IPS_USE_MEMIO(ha)) {
2331                        /* Memory Mapped I/O */
2332
2333                        /* test 1st byte */
2334                        writel(0, ha->mem_ptr + IPS_REG_FLAP);
2335                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2336                                udelay(25);     /* 25 us */
2337
2338                        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2339                                return;
2340
2341                        writel(1, ha->mem_ptr + IPS_REG_FLAP);
2342                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2343                                udelay(25);     /* 25 us */
2344
2345                        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2346                                return;
2347
2348                        /* Get Major version */
2349                        writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2350                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2351                                udelay(25);     /* 25 us */
2352
2353                        major = readb(ha->mem_ptr + IPS_REG_FLDP);
2354
2355                        /* Get Minor version */
2356                        writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2357                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2358                                udelay(25);     /* 25 us */
2359                        minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2360
2361                        /* Get SubMinor version */
2362                        writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2363                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2364                                udelay(25);     /* 25 us */
2365                        subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2366
2367                } else {
2368                        /* Programmed I/O */
2369
2370                        /* test 1st byte */
2371                        outl(0, ha->io_addr + IPS_REG_FLAP);
2372                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2373                                udelay(25);     /* 25 us */
2374
2375                        if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2376                                return;
2377
2378                        outl(1, ha->io_addr + IPS_REG_FLAP);
2379                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2380                                udelay(25);     /* 25 us */
2381
2382                        if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2383                                return;
2384
2385                        /* Get Major version */
2386                        outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
2387                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2388                                udelay(25);     /* 25 us */
2389
2390                        major = inb(ha->io_addr + IPS_REG_FLDP);
2391
2392                        /* Get Minor version */
2393                        outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
2394                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2395                                udelay(25);     /* 25 us */
2396
2397                        minor = inb(ha->io_addr + IPS_REG_FLDP);
2398
2399                        /* Get SubMinor version */
2400                        outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
2401                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2402                                udelay(25);     /* 25 us */
2403
2404                        subminor = inb(ha->io_addr + IPS_REG_FLDP);
2405
2406                }
2407        } else {
2408                /* Morpheus Family - Send Command to the card */
2409
2410                buffer = ha->ioctl_data;
2411
2412                memset(buffer, 0, 0x1000);
2413
2414                scb = &ha->scbs[ha->max_cmds - 1];
2415
2416                ips_init_scb(ha, scb);
2417
2418                scb->timeout = ips_cmd_timeout;
2419                scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2420
2421                scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2422                scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2423                scb->cmd.flashfw.type = 1;
2424                scb->cmd.flashfw.direction = 0;
2425                scb->cmd.flashfw.count = cpu_to_le32(0x800);
2426                scb->cmd.flashfw.total_packets = 1;
2427                scb->cmd.flashfw.packet_num = 0;
2428                scb->data_len = 0x1000;
2429                scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2430
2431                /* issue the command */
2432                if (((ret =
2433                      ips_send_wait(ha, scb, ips_cmd_timeout,
2434                                    intr)) == IPS_FAILURE)
2435                    || (ret == IPS_SUCCESS_IMM)
2436                    || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2437                        /* Error occurred */
2438
2439                        return;
2440                }
2441
2442                if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2443                        major = buffer[0x1ff + 0xC0];   /* Offset 0x1ff after the header (0xc0) */
2444                        minor = buffer[0x1fe + 0xC0];   /* Offset 0x1fe after the header (0xc0) */
2445                        subminor = buffer[0x1fd + 0xC0];        /* Offset 0x1fd after the header (0xc0) */
2446                } else {
2447                        return;
2448                }
2449        }
2450
2451        ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2452        ha->bios_version[1] = '.';
2453        ha->bios_version[2] = hexDigits[major & 0x0F];
2454        ha->bios_version[3] = hexDigits[subminor];
2455        ha->bios_version[4] = '.';
2456        ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2457        ha->bios_version[6] = hexDigits[minor & 0x0F];
2458        ha->bios_version[7] = 0;
2459}
2460
2461/****************************************************************************/
2462/*                                                                          */
2463/* Routine Name: ips_hainit                                                 */
2464/*                                                                          */
2465/* Routine Description:                                                     */
2466/*                                                                          */
2467/*   Initialize the controller                                              */
2468/*                                                                          */
2469/* NOTE: Assumes to be called from with a lock                              */
2470/*                                                                          */
2471/****************************************************************************/
2472static int
2473ips_hainit(ips_ha_t * ha)
2474{
2475        int i;
2476        struct timeval tv;
2477
2478        METHOD_TRACE("ips_hainit", 1);
2479
2480        if (!ha)
2481                return (0);
2482
2483        if (ha->func.statinit)
2484                (*ha->func.statinit) (ha);
2485
2486        if (ha->func.enableint)
2487                (*ha->func.enableint) (ha);
2488
2489        /* Send FFDC */
2490        ha->reset_count = 1;
2491        do_gettimeofday(&tv);
2492        ha->last_ffdc = tv.tv_sec;
2493        ips_ffdc_reset(ha, IPS_INTR_IORL);
2494
2495        if (!ips_read_config(ha, IPS_INTR_IORL)) {
2496                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2497                           "unable to read config from controller.\n");
2498
2499                return (0);
2500        }
2501        /* end if */
2502        if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2503                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2504                           "unable to read controller status.\n");
2505
2506                return (0);
2507        }
2508
2509        /* Identify this controller */
2510        ips_identify_controller(ha);
2511
2512        if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2513                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2514                           "unable to read subsystem parameters.\n");
2515
2516                return (0);
2517        }
2518
2519        /* write nvram user page 5 */
2520        if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2521                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2522                           "unable to write driver info to controller.\n");
2523
2524                return (0);
2525        }
2526
2527        /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
2528        if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2529                ips_clear_adapter(ha, IPS_INTR_IORL);
2530
2531        /* set limits on SID, LUN, BUS */
2532        ha->ntargets = IPS_MAX_TARGETS + 1;
2533        ha->nlun = 1;
2534        ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2535
2536        switch (ha->conf->logical_drive[0].ucStripeSize) {
2537        case 4:
2538                ha->max_xfer = 0x10000;
2539                break;
2540
2541        case 5:
2542                ha->max_xfer = 0x20000;
2543                break;
2544
2545        case 6:
2546                ha->max_xfer = 0x40000;
2547                break;
2548
2549        case 7:
2550        default:
2551                ha->max_xfer = 0x80000;
2552                break;
2553        }
2554
2555        /* setup max concurrent commands */
2556        if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2557                /* Use the new method */
2558                ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2559        } else {
2560                /* use the old method */
2561                switch (ha->conf->logical_drive[0].ucStripeSize) {
2562                case 4:
2563                        ha->max_cmds = 32;
2564                        break;
2565
2566                case 5:
2567                        ha->max_cmds = 16;
2568                        break;
2569
2570                case 6:
2571                        ha->max_cmds = 8;
2572                        break;
2573
2574                case 7:
2575                default:
2576                        ha->max_cmds = 4;
2577                        break;
2578                }
2579        }
2580
2581        /* Limit the Active Commands on a Lite Adapter */
2582        if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2583            (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2584            (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2585                if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2586                        ha->max_cmds = MaxLiteCmds;
2587        }
2588
2589        /* set controller IDs */
2590        ha->ha_id[0] = IPS_ADAPTER_ID;
2591        for (i = 1; i < ha->nbus; i++) {
2592                ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2593                ha->dcdb_active[i - 1] = 0;
2594        }
2595
2596        return (1);
2597}
2598
2599/****************************************************************************/
2600/*                                                                          */
2601/* Routine Name: ips_next                                                   */
2602/*                                                                          */
2603/* Routine Description:                                                     */
2604/*                                                                          */
2605/*   Take the next command off the queue and send it to the controller      */
2606/*                                                                          */
2607/****************************************************************************/
2608static void
2609ips_next(ips_ha_t * ha, int intr)
2610{
2611        ips_scb_t *scb;
2612        struct scsi_cmnd *SC;
2613        struct scsi_cmnd *p;
2614        struct scsi_cmnd *q;
2615        ips_copp_wait_item_t *item;
2616        int ret;
2617        struct Scsi_Host *host;
2618        METHOD_TRACE("ips_next", 1);
2619
2620        if (!ha)
2621                return;
2622        host = ips_sh[ha->host_num];
2623        /*
2624         * Block access to the queue function so
2625         * this command won't time out
2626         */
2627        if (intr == IPS_INTR_ON)
2628                spin_lock(host->host_lock);
2629
2630        if ((ha->subsys->param[3] & 0x300000)
2631            && (ha->scb_activelist.count == 0)) {
2632                struct timeval tv;
2633
2634                do_gettimeofday(&tv);
2635
2636                if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2637                        ha->last_ffdc = tv.tv_sec;
2638                        ips_ffdc_time(ha);
2639                }
2640        }
2641
2642        /*
2643         * Send passthru commands
2644         * These have priority over normal I/O
2645         * but shouldn't affect performance too much
2646         * since we limit the number that can be active
2647         * on the card at any one time
2648         */
2649        while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2650               (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2651
2652                item = ips_removeq_copp_head(&ha->copp_waitlist);
2653                ha->num_ioctl++;
2654                if (intr == IPS_INTR_ON)
2655                        spin_unlock(host->host_lock);
2656                scb->scsi_cmd = item->scsi_cmd;
2657                kfree(item);
2658
2659                ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2660
2661                if (intr == IPS_INTR_ON)
2662                        spin_lock(host->host_lock);
2663                switch (ret) {
2664                case IPS_FAILURE:
2665                        if (scb->scsi_cmd) {
2666                                scb->scsi_cmd->result = DID_ERROR << 16;
2667                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2668                        }
2669
2670                        ips_freescb(ha, scb);
2671                        break;
2672                case IPS_SUCCESS_IMM:
2673                        if (scb->scsi_cmd) {
2674                                scb->scsi_cmd->result = DID_OK << 16;
2675                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2676                        }
2677
2678                        ips_freescb(ha, scb);
2679                        break;
2680                default:
2681                        break;
2682                }               /* end case */
2683
2684                if (ret != IPS_SUCCESS) {
2685                        ha->num_ioctl--;
2686                        continue;
2687                }
2688
2689                ret = ips_send_cmd(ha, scb);
2690
2691                if (ret == IPS_SUCCESS)
2692                        ips_putq_scb_head(&ha->scb_activelist, scb);
2693                else
2694                        ha->num_ioctl--;
2695
2696                switch (ret) {
2697                case IPS_FAILURE:
2698                        if (scb->scsi_cmd) {
2699                                scb->scsi_cmd->result = DID_ERROR << 16;
2700                        }
2701
2702                        ips_freescb(ha, scb);
2703                        break;
2704                case IPS_SUCCESS_IMM:
2705                        ips_freescb(ha, scb);
2706                        break;
2707                default:
2708                        break;
2709                }               /* end case */
2710
2711        }
2712
2713        /*
2714         * Send "Normal" I/O commands
2715         */
2716
2717        p = ha->scb_waitlist.head;
2718        while ((p) && (scb = ips_getscb(ha))) {
2719                if ((scmd_channel(p) > 0)
2720                    && (ha->
2721                        dcdb_active[scmd_channel(p) -
2722                                    1] & (1 << scmd_id(p)))) {
2723                        ips_freescb(ha, scb);
2724                        p = (struct scsi_cmnd *) p->host_scribble;
2725                        continue;
2726                }
2727
2728                q = p;
2729                SC = ips_removeq_wait(&ha->scb_waitlist, q);
2730
2731                if (intr == IPS_INTR_ON)
2732                        spin_unlock(host->host_lock);   /* Unlock HA after command is taken off queue */
2733
2734                SC->result = DID_OK;
2735                SC->host_scribble = NULL;
2736
2737                scb->target_id = SC->device->id;
2738                scb->lun = SC->device->lun;
2739                scb->bus = SC->device->channel;
2740                scb->scsi_cmd = SC;
2741                scb->breakup = 0;
2742                scb->data_len = 0;
2743                scb->callback = ipsintr_done;
2744                scb->timeout = ips_cmd_timeout;
2745                memset(&scb->cmd, 0, 16);
2746
2747                /* copy in the CDB */
2748                memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2749
2750                scb->sg_count = scsi_dma_map(SC);
2751                BUG_ON(scb->sg_count < 0);
2752                if (scb->sg_count) {
2753                        struct scatterlist *sg;
2754                        int i;
2755
2756                        scb->flags |= IPS_SCB_MAP_SG;
2757
2758                        scsi_for_each_sg(SC, sg, scb->sg_count, i) {
2759                                if (ips_fill_scb_sg_single
2760                                    (ha, sg_dma_address(sg), scb, i,
2761                                     sg_dma_len(sg)) < 0)
2762                                        break;
2763                        }
2764                        scb->dcdb.transfer_length = scb->data_len;
2765                } else {
2766                        scb->data_busaddr = 0L;
2767                        scb->sg_len = 0;
2768                        scb->data_len = 0;
2769                        scb->dcdb.transfer_length = 0;
2770                }
2771
2772                scb->dcdb.cmd_attribute =
2773                    ips_command_direction[scb->scsi_cmd->cmnd[0]];
2774
2775                /* Allow a WRITE BUFFER Command to Have no Data */
2776                /* This is Used by Tape Flash Utilites          */
2777                if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) &&
2778                                (scb->data_len == 0))
2779                        scb->dcdb.cmd_attribute = 0;
2780
2781                if (!(scb->dcdb.cmd_attribute & 0x3))
2782                        scb->dcdb.transfer_length = 0;
2783
2784                if (scb->data_len >= IPS_MAX_XFER) {
2785                        scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2786                        scb->dcdb.transfer_length = 0;
2787                }
2788                if (intr == IPS_INTR_ON)
2789                        spin_lock(host->host_lock);
2790
2791                ret = ips_send_cmd(ha, scb);
2792
2793                switch (ret) {
2794                case IPS_SUCCESS:
2795                        ips_putq_scb_head(&ha->scb_activelist, scb);
2796                        break;
2797                case IPS_FAILURE:
2798                        if (scb->scsi_cmd) {
2799                                scb->scsi_cmd->result = DID_ERROR << 16;
2800                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2801                        }
2802
2803                        if (scb->bus)
2804                                ha->dcdb_active[scb->bus - 1] &=
2805                                    ~(1 << scb->target_id);
2806
2807                        ips_freescb(ha, scb);
2808                        break;
2809                case IPS_SUCCESS_IMM:
2810                        if (scb->scsi_cmd)
2811                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2812
2813                        if (scb->bus)
2814                                ha->dcdb_active[scb->bus - 1] &=
2815                                    ~(1 << scb->target_id);
2816
2817                        ips_freescb(ha, scb);
2818                        break;
2819                default:
2820                        break;
2821                }               /* end case */
2822
2823                p = (struct scsi_cmnd *) p->host_scribble;
2824
2825        }                       /* end while */
2826
2827        if (intr == IPS_INTR_ON)
2828                spin_unlock(host->host_lock);
2829}
2830
2831/****************************************************************************/
2832/*                                                                          */
2833/* Routine Name: ips_putq_scb_head                                          */
2834/*                                                                          */
2835/* Routine Description:                                                     */
2836/*                                                                          */
2837/*   Add an item to the head of the queue                                   */
2838/*                                                                          */
2839/* ASSUMED to be called from within the HA lock                             */
2840/*                                                                          */
2841/****************************************************************************/
2842static void
2843ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2844{
2845        METHOD_TRACE("ips_putq_scb_head", 1);
2846
2847        if (!item)
2848                return;
2849
2850        item->q_next = queue->head;
2851        queue->head = item;
2852
2853        if (!queue->tail)
2854                queue->tail = item;
2855
2856        queue->count++;
2857}
2858
2859/****************************************************************************/
2860/*                                                                          */
2861/* Routine Name: ips_removeq_scb_head                                       */
2862/*                                                                          */
2863/* Routine Description:                                                     */
2864/*                                                                          */
2865/*   Remove the head of the queue                                           */
2866/*                                                                          */
2867/* ASSUMED to be called from within the HA lock                             */
2868/*                                                                          */
2869/****************************************************************************/
2870static ips_scb_t *
2871ips_removeq_scb_head(ips_scb_queue_t * queue)
2872{
2873        ips_scb_t *item;
2874
2875        METHOD_TRACE("ips_removeq_scb_head", 1);
2876
2877        item = queue->head;
2878
2879        if (!item) {
2880                return (NULL);
2881        }
2882
2883        queue->head = item->q_next;
2884        item->q_next = NULL;
2885
2886        if (queue->tail == item)
2887                queue->tail = NULL;
2888
2889        queue->count--;
2890
2891        return (item);
2892}
2893
2894/****************************************************************************/
2895/*                                                                          */
2896/* Routine Name: ips_removeq_scb                                            */
2897/*                                                                          */
2898/* Routine Description:                                                     */
2899/*                                                                          */
2900/*   Remove an item from a queue                                            */
2901/*                                                                          */
2902/* ASSUMED to be called from within the HA lock                             */
2903/*                                                                          */
2904/****************************************************************************/
2905static ips_scb_t *
2906ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
2907{
2908        ips_scb_t *p;
2909
2910        METHOD_TRACE("ips_removeq_scb", 1);
2911
2912        if (!item)
2913                return (NULL);
2914
2915        if (item == queue->head) {
2916                return (ips_removeq_scb_head(queue));
2917        }
2918
2919        p = queue->head;
2920
2921        while ((p) && (item != p->q_next))
2922                p = p->q_next;
2923
2924        if (p) {
2925                /* found a match */
2926                p->q_next = item->q_next;
2927
2928                if (!item->q_next)
2929                        queue->tail = p;
2930
2931                item->q_next = NULL;
2932                queue->count--;
2933
2934                return (item);
2935        }
2936
2937        return (NULL);
2938}
2939
2940/****************************************************************************/
2941/*                                                                          */
2942/* Routine Name: ips_putq_wait_tail                                         */
2943/*                                                                          */
2944/* Routine Description:                                                     */
2945/*                                                                          */
2946/*   Add an item to the tail of the queue                                   */
2947/*                                                                          */
2948/* ASSUMED to be called from within the HA lock                             */
2949/*                                                                          */
2950/****************************************************************************/
2951static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
2952{
2953        METHOD_TRACE("ips_putq_wait_tail", 1);
2954
2955        if (!item)
2956                return;
2957
2958        item->host_scribble = NULL;
2959
2960        if (queue->tail)
2961                queue->tail->host_scribble = (char *) item;
2962
2963        queue->tail = item;
2964
2965        if (!queue->head)
2966                queue->head = item;
2967
2968        queue->count++;
2969}
2970
2971/****************************************************************************/
2972/*                                                                          */
2973/* Routine Name: ips_removeq_wait_head                                      */
2974/*                                                                          */
2975/* Routine Description:                                                     */
2976/*                                                                          */
2977/*   Remove the head of the queue                                           */
2978/*                                                                          */
2979/* ASSUMED to be called from within the HA lock                             */
2980/*                                                                          */
2981/****************************************************************************/
2982static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
2983{
2984        struct scsi_cmnd *item;
2985
2986        METHOD_TRACE("ips_removeq_wait_head", 1);
2987
2988        item = queue->head;
2989
2990        if (!item) {
2991                return (NULL);
2992        }
2993
2994        queue->head = (struct scsi_cmnd *) item->host_scribble;
2995        item->host_scribble = NULL;
2996
2997        if (queue->tail == item)
2998                queue->tail = NULL;
2999
3000        queue->count--;
3001
3002        return (item);
3003}
3004
3005/****************************************************************************/
3006/*                                                                          */
3007/* Routine Name: ips_removeq_wait                                           */
3008/*                                                                          */
3009/* Routine Description:                                                     */
3010/*                                                                          */
3011/*   Remove an item from a queue                                            */
3012/*                                                                          */
3013/* ASSUMED to be called from within the HA lock                             */
3014/*                                                                          */
3015/****************************************************************************/
3016static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
3017                                          struct scsi_cmnd *item)
3018{
3019        struct scsi_cmnd *p;
3020
3021        METHOD_TRACE("ips_removeq_wait", 1);
3022
3023        if (!item)
3024                return (NULL);
3025
3026        if (item == queue->head) {
3027                return (ips_removeq_wait_head(queue));
3028        }
3029
3030        p = queue->head;
3031
3032        while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
3033                p = (struct scsi_cmnd *) p->host_scribble;
3034
3035        if (p) {
3036                /* found a match */
3037                p->host_scribble = item->host_scribble;
3038
3039                if (!item->host_scribble)
3040                        queue->tail = p;
3041
3042                item->host_scribble = NULL;
3043                queue->count--;
3044
3045                return (item);
3046        }
3047
3048        return (NULL);
3049}
3050
3051/****************************************************************************/
3052/*                                                                          */
3053/* Routine Name: ips_putq_copp_tail                                         */
3054/*                                                                          */
3055/* Routine Description:                                                     */
3056/*                                                                          */
3057/*   Add an item to the tail of the queue                                   */
3058/*                                                                          */
3059/* ASSUMED to be called from within the HA lock                             */
3060/*                                                                          */
3061/****************************************************************************/
3062static void
3063ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3064{
3065        METHOD_TRACE("ips_putq_copp_tail", 1);
3066
3067        if (!item)
3068                return;
3069
3070        item->next = NULL;
3071
3072        if (queue->tail)
3073                queue->tail->next = item;
3074
3075        queue->tail = item;
3076
3077        if (!queue->head)
3078                queue->head = item;
3079
3080        queue->count++;
3081}
3082
3083/****************************************************************************/
3084/*                                                                          */
3085/* Routine Name: ips_removeq_copp_head                                      */
3086/*                                                                          */
3087/* Routine Description:                                                     */
3088/*                                                                          */
3089/*   Remove the head of the queue                                           */
3090/*                                                                          */
3091/* ASSUMED to be called from within the HA lock                             */
3092/*                                                                          */
3093/****************************************************************************/
3094static ips_copp_wait_item_t *
3095ips_removeq_copp_head(ips_copp_queue_t * queue)
3096{
3097        ips_copp_wait_item_t *item;
3098
3099        METHOD_TRACE("ips_removeq_copp_head", 1);
3100
3101        item = queue->head;
3102
3103        if (!item) {
3104                return (NULL);
3105        }
3106
3107        queue->head = item->next;
3108        item->next = NULL;
3109
3110        if (queue->tail == item)
3111                queue->tail = NULL;
3112
3113        queue->count--;
3114
3115        return (item);
3116}
3117
3118/****************************************************************************/
3119/*                                                                          */
3120/* Routine Name: ips_removeq_copp                                           */
3121/*                                                                          */
3122/* Routine Description:                                                     */
3123/*                                                                          */
3124/*   Remove an item from a queue                                            */
3125/*                                                                          */
3126/* ASSUMED to be called from within the HA lock                             */
3127/*                                                                          */
3128/****************************************************************************/
3129static ips_copp_wait_item_t *
3130ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3131{
3132        ips_copp_wait_item_t *p;
3133
3134        METHOD_TRACE("ips_removeq_copp", 1);
3135
3136        if (!item)
3137                return (NULL);
3138
3139        if (item == queue->head) {
3140                return (ips_removeq_copp_head(queue));
3141        }
3142
3143        p = queue->head;
3144
3145        while ((p) && (item != p->next))
3146                p = p->next;
3147
3148        if (p) {
3149                /* found a match */
3150                p->next = item->next;
3151
3152                if (!item->next)
3153                        queue->tail = p;
3154
3155                item->next = NULL;
3156                queue->count--;
3157
3158                return (item);
3159        }
3160
3161        return (NULL);
3162}
3163
3164/****************************************************************************/
3165/*                                                                          */
3166/* Routine Name: ipsintr_blocking                                           */
3167/*                                                                          */
3168/* Routine Description:                                                     */
3169/*                                                                          */
3170/*   Finalize an interrupt for internal commands                            */
3171/*                                                                          */
3172/****************************************************************************/
3173static void
3174ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3175{
3176        METHOD_TRACE("ipsintr_blocking", 2);
3177
3178        ips_freescb(ha, scb);
3179        if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3180                ha->waitflag = FALSE;
3181
3182                return;
3183        }
3184}
3185
3186/****************************************************************************/
3187/*                                                                          */
3188/* Routine Name: ipsintr_done                                               */
3189/*                                                                          */
3190/* Routine Description:                                                     */
3191/*                                                                          */
3192/*   Finalize an interrupt for non-internal commands                        */
3193/*                                                                          */
3194/****************************************************************************/
3195static void
3196ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3197{
3198        METHOD_TRACE("ipsintr_done", 2);
3199
3200        if (!scb) {
3201                IPS_PRINTK(KERN_WARNING, ha->pcidev,
3202                           "Spurious interrupt; scb NULL.\n");
3203
3204                return;
3205        }
3206
3207        if (scb->scsi_cmd == NULL) {
3208                /* unexpected interrupt */
3209                IPS_PRINTK(KERN_WARNING, ha->pcidev,
3210                           "Spurious interrupt; scsi_cmd not set.\n");
3211
3212                return;
3213        }
3214
3215        ips_done(ha, scb);
3216}
3217
3218/****************************************************************************/
3219/*                                                                          */
3220/* Routine Name: ips_done                                                   */
3221/*                                                                          */
3222/* Routine Description:                                                     */
3223/*                                                                          */
3224/*   Do housekeeping on completed commands                                  */
3225/*  ASSUMED to be called form within the request lock                       */
3226/****************************************************************************/
3227static void
3228ips_done(ips_ha_t * ha, ips_scb_t * scb)
3229{
3230        int ret;
3231
3232        METHOD_TRACE("ips_done", 1);
3233
3234        if (!scb)
3235                return;
3236
3237        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3238                ips_cleanup_passthru(ha, scb);
3239                ha->num_ioctl--;
3240        } else {
3241                /*
3242                 * Check to see if this command had too much
3243                 * data and had to be broke up.  If so, queue
3244                 * the rest of the data and continue.
3245                 */
3246                if ((scb->breakup) || (scb->sg_break)) {
3247                        struct scatterlist *sg;
3248                        int i, sg_dma_index, ips_sg_index = 0;
3249
3250                        /* we had a data breakup */
3251                        scb->data_len = 0;
3252
3253                        sg = scsi_sglist(scb->scsi_cmd);
3254
3255                        /* Spin forward to last dma chunk */
3256                        sg_dma_index = scb->breakup;
3257                        for (i = 0; i < scb->breakup; i++)
3258                                sg = sg_next(sg);
3259
3260                        /* Take care of possible partial on last chunk */
3261                        ips_fill_scb_sg_single(ha,
3262                                               sg_dma_address(sg),
3263                                               scb, ips_sg_index++,
3264                                               sg_dma_len(sg));
3265
3266                        for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
3267                             sg_dma_index++, sg = sg_next(sg)) {
3268                                if (ips_fill_scb_sg_single
3269                                    (ha,
3270                                     sg_dma_address(sg),
3271                                     scb, ips_sg_index++,
3272                                     sg_dma_len(sg)) < 0)
3273                                        break;
3274                        }
3275
3276                        scb->dcdb.transfer_length = scb->data_len;
3277                        scb->dcdb.cmd_attribute |=
3278                            ips_command_direction[scb->scsi_cmd->cmnd[0]];
3279
3280                        if (!(scb->dcdb.cmd_attribute & 0x3))
3281                                scb->dcdb.transfer_length = 0;
3282
3283                        if (scb->data_len >= IPS_MAX_XFER) {
3284                                scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3285                                scb->dcdb.transfer_length = 0;
3286                        }
3287
3288                        ret = ips_send_cmd(ha, scb);
3289
3290                        switch (ret) {
3291                        case IPS_FAILURE:
3292                                if (scb->scsi_cmd) {
3293                                        scb->scsi_cmd->result = DID_ERROR << 16;
3294                                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3295                                }
3296
3297                                ips_freescb(ha, scb);
3298                                break;
3299                        case IPS_SUCCESS_IMM:
3300                                if (scb->scsi_cmd) {
3301                                        scb->scsi_cmd->result = DID_ERROR << 16;
3302                                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3303                                }
3304
3305                                ips_freescb(ha, scb);
3306                                break;
3307                        default:
3308                                break;
3309                        }       /* end case */
3310
3311                        return;
3312                }
3313        }                       /* end if passthru */
3314
3315        if (scb->bus) {
3316                ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3317        }
3318
3319        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3320
3321        ips_freescb(ha, scb);
3322}
3323
3324/****************************************************************************/
3325/*                                                                          */
3326/* Routine Name: ips_map_status                                             */
3327/*                                                                          */
3328/* Routine Description:                                                     */
3329/*                                                                          */
3330/*   Map Controller Error codes to Linux Error Codes                        */
3331/*                                                                          */
3332/****************************************************************************/
3333static int
3334ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3335{
3336        int errcode;
3337        int device_error;
3338        uint32_t transfer_len;
3339        IPS_DCDB_TABLE_TAPE *tapeDCDB;
3340        IPS_SCSI_INQ_DATA inquiryData;
3341
3342        METHOD_TRACE("ips_map_status", 1);
3343
3344        if (scb->bus) {
3345                DEBUG_VAR(2,
3346                          "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3347                          ips_name, ha->host_num,
3348                          scb->scsi_cmd->device->channel,
3349                          scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3350                          scb->basic_status, scb->extended_status,
3351                          scb->extended_status ==
3352                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3353                          scb->extended_status ==
3354                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3355                          scb->extended_status ==
3356                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3357        }
3358
3359        /* default driver error */
3360        errcode = DID_ERROR;
3361        device_error = 0;
3362
3363        switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3364        case IPS_CMD_TIMEOUT:
3365                errcode = DID_TIME_OUT;
3366                break;
3367
3368        case IPS_INVAL_OPCO:
3369        case IPS_INVAL_CMD_BLK:
3370        case IPS_INVAL_PARM_BLK:
3371        case IPS_LD_ERROR:
3372        case IPS_CMD_CMPLT_WERROR:
3373                break;
3374
3375        case IPS_PHYS_DRV_ERROR:
3376                switch (scb->extended_status) {
3377                case IPS_ERR_SEL_TO:
3378                        if (scb->bus)
3379                                errcode = DID_NO_CONNECT;
3380
3381                        break;
3382
3383                case IPS_ERR_OU_RUN:
3384                        if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3385                            (scb->cmd.dcdb.op_code ==
3386                             IPS_CMD_EXTENDED_DCDB_SG)) {
3387                                tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3388                                transfer_len = tapeDCDB->transfer_length;
3389                        } else {
3390                                transfer_len =
3391                                    (uint32_t) scb->dcdb.transfer_length;
3392                        }
3393
3394                        if ((scb->bus) && (transfer_len < scb->data_len)) {
3395                                /* Underrun - set default to no error */
3396                                errcode = DID_OK;
3397
3398                                /* Restrict access to physical DASD */
3399                                if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3400                                    ips_scmd_buf_read(scb->scsi_cmd,
3401                                      &inquiryData, sizeof (inquiryData));
3402                                    if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
3403                                        errcode = DID_TIME_OUT;
3404                                        break;
3405                                    }
3406                                }
3407                        } else
3408                                errcode = DID_ERROR;
3409
3410                        break;
3411
3412                case IPS_ERR_RECOVERY:
3413                        /* don't fail recovered errors */
3414                        if (scb->bus)
3415                                errcode = DID_OK;
3416
3417                        break;
3418
3419                case IPS_ERR_HOST_RESET:
3420                case IPS_ERR_DEV_RESET:
3421                        errcode = DID_RESET;
3422                        break;
3423
3424                case IPS_ERR_CKCOND:
3425                        if (scb->bus) {
3426                                if ((scb->cmd.dcdb.op_code ==
3427                                     IPS_CMD_EXTENDED_DCDB)
3428                                    || (scb->cmd.dcdb.op_code ==
3429                                        IPS_CMD_EXTENDED_DCDB_SG)) {
3430                                        tapeDCDB =
3431                                            (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3432                                        memcpy(scb->scsi_cmd->sense_buffer,
3433                                               tapeDCDB->sense_info,
3434                                               SCSI_SENSE_BUFFERSIZE);
3435                                } else {
3436                                        memcpy(scb->scsi_cmd->sense_buffer,
3437                                               scb->dcdb.sense_info,
3438                                               SCSI_SENSE_BUFFERSIZE);
3439                                }
3440                                device_error = 2;       /* check condition */
3441                        }
3442
3443                        errcode = DID_OK;
3444
3445                        break;
3446
3447                default:
3448                        errcode = DID_ERROR;
3449                        break;
3450
3451                }               /* end switch */
3452        }                       /* end switch */
3453
3454        scb->scsi_cmd->result = device_error | (errcode << 16);
3455
3456        return (1);
3457}
3458
3459/****************************************************************************/
3460/*                                                                          */
3461/* Routine Name: ips_send_wait                                              */
3462/*                                                                          */
3463/* Routine Description:                                                     */
3464/*                                                                          */
3465/*   Send a command to the controller and wait for it to return             */
3466/*                                                                          */
3467/*   The FFDC Time Stamp use this function for the callback, but doesn't    */
3468/*   actually need to wait.                                                 */
3469/****************************************************************************/
3470static int
3471ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3472{
3473        int ret;
3474
3475        METHOD_TRACE("ips_send_wait", 1);
3476
3477        if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
3478                ha->waitflag = TRUE;
3479                ha->cmd_in_progress = scb->cdb[0];
3480        }
3481        scb->callback = ipsintr_blocking;
3482        ret = ips_send_cmd(ha, scb);
3483
3484        if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3485                return (ret);
3486
3487        if (intr != IPS_FFDC)   /* Don't Wait around if this is a Time Stamp */
3488                ret = ips_wait(ha, timeout, intr);
3489
3490        return (ret);
3491}
3492
3493/****************************************************************************/
3494/*                                                                          */
3495/* Routine Name: ips_scmd_buf_write                                         */
3496/*                                                                          */
3497/* Routine Description:                                                     */
3498/*  Write data to struct scsi_cmnd request_buffer at proper offsets         */
3499/****************************************************************************/
3500static void
3501ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
3502{
3503        unsigned long flags;
3504
3505        local_irq_save(flags);
3506        scsi_sg_copy_from_buffer(scmd, data, count);
3507        local_irq_restore(flags);
3508}
3509
3510/****************************************************************************/
3511/*                                                                          */
3512/* Routine Name: ips_scmd_buf_read                                          */
3513/*                                                                          */
3514/* Routine Description:                                                     */
3515/*  Copy data from a struct scsi_cmnd to a new, linear buffer               */
3516/****************************************************************************/
3517static void
3518ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
3519{
3520        unsigned long flags;
3521
3522        local_irq_save(flags);
3523        scsi_sg_copy_to_buffer(scmd, data, count);
3524        local_irq_restore(flags);
3525}
3526
3527/****************************************************************************/
3528/*                                                                          */
3529/* Routine Name: ips_send_cmd                                               */
3530/*                                                                          */
3531/* Routine Description:                                                     */
3532/*                                                                          */
3533/*   Map SCSI commands to ServeRAID commands for logical drives             */
3534/*                                                                          */
3535/****************************************************************************/
3536static int
3537ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3538{
3539        int ret;
3540        char *sp;
3541        int device_error;
3542        IPS_DCDB_TABLE_TAPE *tapeDCDB;
3543        int TimeOut;
3544
3545        METHOD_TRACE("ips_send_cmd", 1);
3546
3547        ret = IPS_SUCCESS;
3548
3549        if (!scb->scsi_cmd) {
3550                /* internal command */
3551
3552                if (scb->bus > 0) {
3553                        /* Controller commands can't be issued */
3554                        /* to real devices -- fail them        */
3555                        if ((ha->waitflag == TRUE) &&
3556                            (ha->cmd_in_progress == scb->cdb[0])) {
3557                                ha->waitflag = FALSE;
3558                        }
3559
3560                        return (1);
3561                }
3562        } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3563                /* command to logical bus -- interpret */
3564                ret = IPS_SUCCESS_IMM;
3565
3566                switch (scb->scsi_cmd->cmnd[0]) {
3567                case ALLOW_MEDIUM_REMOVAL:
3568                case REZERO_UNIT:
3569                case ERASE:
3570                case WRITE_FILEMARKS:
3571                case SPACE:
3572                        scb->scsi_cmd->result = DID_ERROR << 16;
3573                        break;
3574
3575                case START_STOP:
3576                        scb->scsi_cmd->result = DID_OK << 16;
3577
3578                case TEST_UNIT_READY:
3579                case INQUIRY:
3580                        if (scb->target_id == IPS_ADAPTER_ID) {
3581                                /*
3582                                 * Either we have a TUR
3583                                 * or we have a SCSI inquiry
3584                                 */
3585                                if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3586                                        scb->scsi_cmd->result = DID_OK << 16;
3587
3588                                if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3589                                        IPS_SCSI_INQ_DATA inquiry;
3590
3591                                        memset(&inquiry, 0,
3592                                               sizeof (IPS_SCSI_INQ_DATA));
3593
3594                                        inquiry.DeviceType =
3595                                            IPS_SCSI_INQ_TYPE_PROCESSOR;
3596                                        inquiry.DeviceTypeQualifier =
3597                                            IPS_SCSI_INQ_LU_CONNECTED;
3598                                        inquiry.Version = IPS_SCSI_INQ_REV2;
3599                                        inquiry.ResponseDataFormat =
3600                                            IPS_SCSI_INQ_RD_REV2;
3601                                        inquiry.AdditionalLength = 31;
3602                                        inquiry.Flags[0] =
3603                                            IPS_SCSI_INQ_Address16;
3604                                        inquiry.Flags[1] =
3605                                            IPS_SCSI_INQ_WBus16 |
3606                                            IPS_SCSI_INQ_Sync;
3607                                        strncpy(inquiry.VendorId, "IBM     ",
3608                                                8);
3609                                        strncpy(inquiry.ProductId,
3610                                                "SERVERAID       ", 16);
3611                                        strncpy(inquiry.ProductRevisionLevel,
3612                                                "1.00", 4);
3613
3614                                        ips_scmd_buf_write(scb->scsi_cmd,
3615                                                           &inquiry,
3616                                                           sizeof (inquiry));
3617
3618                                        scb->scsi_cmd->result = DID_OK << 16;
3619                                }
3620                        } else {
3621                                scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3622                                scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3623                                scb->cmd.logical_info.reserved = 0;
3624                                scb->cmd.logical_info.reserved2 = 0;
3625                                scb->data_len = sizeof (IPS_LD_INFO);
3626                                scb->data_busaddr = ha->logical_drive_info_dma_addr;
3627                                scb->flags = 0;
3628                                scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3629                                ret = IPS_SUCCESS;
3630                        }
3631
3632                        break;
3633
3634                case REQUEST_SENSE:
3635                        ips_reqsen(ha, scb);
3636                        scb->scsi_cmd->result = DID_OK << 16;
3637                        break;
3638
3639                case READ_6:
3640                case WRITE_6:
3641                        if (!scb->sg_len) {
3642                                scb->cmd.basic_io.op_code =
3643                                    (scb->scsi_cmd->cmnd[0] ==
3644                                     READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3645                                scb->cmd.basic_io.enhanced_sg = 0;
3646                                scb->cmd.basic_io.sg_addr =
3647                                    cpu_to_le32(scb->data_busaddr);
3648                        } else {
3649                                scb->cmd.basic_io.op_code =
3650                                    (scb->scsi_cmd->cmnd[0] ==
3651                                     READ_6) ? IPS_CMD_READ_SG :
3652                                    IPS_CMD_WRITE_SG;
3653                                scb->cmd.basic_io.enhanced_sg =
3654                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3655                                scb->cmd.basic_io.sg_addr =
3656                                    cpu_to_le32(scb->sg_busaddr);
3657                        }
3658
3659                        scb->cmd.basic_io.segment_4G = 0;
3660                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3661                        scb->cmd.basic_io.log_drv = scb->target_id;
3662                        scb->cmd.basic_io.sg_count = scb->sg_len;
3663
3664                        if (scb->cmd.basic_io.lba)
3665                                le32_add_cpu(&scb->cmd.basic_io.lba,
3666                                                le16_to_cpu(scb->cmd.basic_io.
3667                                                            sector_count));
3668                        else
3669                                scb->cmd.basic_io.lba =
3670                                    (((scb->scsi_cmd->
3671                                       cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3672                                                                 cmnd[2] << 8) |
3673                                     (scb->scsi_cmd->cmnd[3]));
3674
3675                        scb->cmd.basic_io.sector_count =
3676                            cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3677
3678                        if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3679                                scb->cmd.basic_io.sector_count =
3680                                    cpu_to_le16(256);
3681
3682                        ret = IPS_SUCCESS;
3683                        break;
3684
3685                case READ_10:
3686                case WRITE_10:
3687                        if (!scb->sg_len) {
3688                                scb->cmd.basic_io.op_code =
3689                                    (scb->scsi_cmd->cmnd[0] ==
3690                                     READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3691                                scb->cmd.basic_io.enhanced_sg = 0;
3692                                scb->cmd.basic_io.sg_addr =
3693                                    cpu_to_le32(scb->data_busaddr);
3694                        } else {
3695                                scb->cmd.basic_io.op_code =
3696                                    (scb->scsi_cmd->cmnd[0] ==
3697                                     READ_10) ? IPS_CMD_READ_SG :
3698                                    IPS_CMD_WRITE_SG;
3699                                scb->cmd.basic_io.enhanced_sg =
3700                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3701                                scb->cmd.basic_io.sg_addr =
3702                                    cpu_to_le32(scb->sg_busaddr);
3703                        }
3704
3705                        scb->cmd.basic_io.segment_4G = 0;
3706                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3707                        scb->cmd.basic_io.log_drv = scb->target_id;
3708                        scb->cmd.basic_io.sg_count = scb->sg_len;
3709
3710                        if (scb->cmd.basic_io.lba)
3711                                le32_add_cpu(&scb->cmd.basic_io.lba,
3712                                                le16_to_cpu(scb->cmd.basic_io.
3713                                                            sector_count));
3714                        else
3715                                scb->cmd.basic_io.lba =
3716                                    ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3717                                                                       scsi_cmd->
3718                                                                       cmnd[3]
3719                                                                       << 16) |
3720                                     (scb->scsi_cmd->cmnd[4] << 8) | scb->
3721                                     scsi_cmd->cmnd[5]);
3722
3723                        scb->cmd.basic_io.sector_count =
3724                            cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3725
3726                        if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3727                                /*
3728                                 * This is a null condition
3729                                 * we don't have to do anything
3730                                 * so just return
3731                                 */
3732                                scb->scsi_cmd->result = DID_OK << 16;
3733                        } else
3734                                ret = IPS_SUCCESS;
3735
3736                        break;
3737
3738                case RESERVE:
3739                case RELEASE:
3740                        scb->scsi_cmd->result = DID_OK << 16;
3741                        break;
3742
3743                case MODE_SENSE:
3744                        scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3745                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3746                        scb->cmd.basic_io.segment_4G = 0;
3747                        scb->cmd.basic_io.enhanced_sg = 0;
3748                        scb->data_len = sizeof (*ha->enq);
3749                        scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3750                        ret = IPS_SUCCESS;
3751                        break;
3752
3753                case READ_CAPACITY:
3754                        scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3755                        scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3756                        scb->cmd.logical_info.reserved = 0;
3757                        scb->cmd.logical_info.reserved2 = 0;
3758                        scb->cmd.logical_info.reserved3 = 0;
3759                        scb->data_len = sizeof (IPS_LD_INFO);
3760                        scb->data_busaddr = ha->logical_drive_info_dma_addr;
3761                        scb->flags = 0;
3762                        scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3763                        ret = IPS_SUCCESS;
3764                        break;
3765
3766                case SEND_DIAGNOSTIC:
3767                case REASSIGN_BLOCKS:
3768                case FORMAT_UNIT:
3769                case SEEK_10:
3770                case VERIFY:
3771                case READ_DEFECT_DATA:
3772                case READ_BUFFER:
3773                case WRITE_BUFFER:
3774                        scb->scsi_cmd->result = DID_OK << 16;
3775                        break;
3776
3777                default:
3778                        /* Set the Return Info to appear like the Command was */
3779                        /* attempted, a Check Condition occurred, and Sense   */
3780                        /* Data indicating an Invalid CDB OpCode is returned. */
3781                        sp = (char *) scb->scsi_cmd->sense_buffer;
3782
3783                        sp[0] = 0x70;   /* Error Code               */
3784                        sp[2] = ILLEGAL_REQUEST;        /* Sense Key 5 Illegal Req. */
3785                        sp[7] = 0x0A;   /* Additional Sense Length  */
3786                        sp[12] = 0x20;  /* ASC = Invalid OpCode     */
3787                        sp[13] = 0x00;  /* ASCQ                     */
3788
3789                        device_error = 2;       /* Indicate Check Condition */
3790                        scb->scsi_cmd->result = device_error | (DID_OK << 16);
3791                        break;
3792                }               /* end switch */
3793        }
3794        /* end if */
3795        if (ret == IPS_SUCCESS_IMM)
3796                return (ret);
3797
3798        /* setup DCDB */
3799        if (scb->bus > 0) {
3800
3801                /* If we already know the Device is Not there, no need to attempt a Command   */
3802                /* This also protects an NT FailOver Controller from getting CDB's sent to it */
3803                if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
3804                        scb->scsi_cmd->result = DID_NO_CONNECT << 16;
3805                        return (IPS_SUCCESS_IMM);
3806                }
3807
3808                ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
3809                scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
3810                scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
3811                                                         (unsigned long) &scb->
3812                                                         dcdb -
3813                                                         (unsigned long) scb);
3814                scb->cmd.dcdb.reserved = 0;
3815                scb->cmd.dcdb.reserved2 = 0;
3816                scb->cmd.dcdb.reserved3 = 0;
3817                scb->cmd.dcdb.segment_4G = 0;
3818                scb->cmd.dcdb.enhanced_sg = 0;
3819
3820                TimeOut = scb->scsi_cmd->request->timeout;
3821
3822                if (ha->subsys->param[4] & 0x00100000) {        /* If NEW Tape DCDB is Supported */
3823                        if (!scb->sg_len) {
3824                                scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
3825                        } else {
3826                                scb->cmd.dcdb.op_code =
3827                                    IPS_CMD_EXTENDED_DCDB_SG;
3828                                scb->cmd.dcdb.enhanced_sg =
3829                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3830                        }
3831
3832                        tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
3833                        tapeDCDB->device_address =
3834                            ((scb->bus - 1) << 4) | scb->target_id;
3835                        tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3836                        tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K;    /* Always Turn OFF 64K Size Flag */
3837
3838                        if (TimeOut) {
3839                                if (TimeOut < (10 * HZ))
3840                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT10;       /* TimeOut is 10 Seconds */
3841                                else if (TimeOut < (60 * HZ))
3842                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT60;       /* TimeOut is 60 Seconds */
3843                                else if (TimeOut < (1200 * HZ))
3844                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;      /* TimeOut is 20 Minutes */
3845                        }
3846
3847                        tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
3848                        tapeDCDB->reserved_for_LUN = 0;
3849                        tapeDCDB->transfer_length = scb->data_len;
3850                        if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
3851                                tapeDCDB->buffer_pointer =
3852                                    cpu_to_le32(scb->sg_busaddr);
3853                        else
3854                                tapeDCDB->buffer_pointer =
3855                                    cpu_to_le32(scb->data_busaddr);
3856                        tapeDCDB->sg_count = scb->sg_len;
3857                        tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
3858                        tapeDCDB->scsi_status = 0;
3859                        tapeDCDB->reserved = 0;
3860                        memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
3861                               scb->scsi_cmd->cmd_len);
3862                } else {
3863                        if (!scb->sg_len) {
3864                                scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
3865                        } else {
3866                                scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
3867                                scb->cmd.dcdb.enhanced_sg =
3868                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3869                        }
3870
3871                        scb->dcdb.device_address =
3872                            ((scb->bus - 1) << 4) | scb->target_id;
3873                        scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3874
3875                        if (TimeOut) {
3876                                if (TimeOut < (10 * HZ))
3877                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;       /* TimeOut is 10 Seconds */
3878                                else if (TimeOut < (60 * HZ))
3879                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;       /* TimeOut is 60 Seconds */
3880                                else if (TimeOut < (1200 * HZ))
3881                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;      /* TimeOut is 20 Minutes */
3882                        }
3883
3884                        scb->dcdb.transfer_length = scb->data_len;
3885                        if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
3886                                scb->dcdb.transfer_length = 0;
3887                        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
3888                                scb->dcdb.buffer_pointer =
3889                                    cpu_to_le32(scb->sg_busaddr);
3890                        else
3891                                scb->dcdb.buffer_pointer =
3892                                    cpu_to_le32(scb->data_busaddr);
3893                        scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
3894                        scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
3895                        scb->dcdb.sg_count = scb->sg_len;
3896                        scb->dcdb.reserved = 0;
3897                        memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
3898                               scb->scsi_cmd->cmd_len);
3899                        scb->dcdb.scsi_status = 0;
3900                        scb->dcdb.reserved2[0] = 0;
3901                        scb->dcdb.reserved2[1] = 0;
3902                        scb->dcdb.reserved2[2] = 0;
3903                }
3904        }
3905
3906        return ((*ha->func.issue) (ha, scb));
3907}
3908
3909/****************************************************************************/
3910/*                                                                          */
3911/* Routine Name: ips_chk_status                                             */
3912/*                                                                          */
3913/* Routine Description:                                                     */
3914/*                                                                          */
3915/*   Check the status of commands to logical drives                         */
3916/*   Assumed to be called with the HA lock                                  */
3917/****************************************************************************/
3918static void
3919ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
3920{
3921        ips_scb_t *scb;
3922        ips_stat_t *sp;
3923        uint8_t basic_status;
3924        uint8_t ext_status;
3925        int errcode;
3926        IPS_SCSI_INQ_DATA inquiryData;
3927
3928        METHOD_TRACE("ips_chkstatus", 1);
3929
3930        scb = &ha->scbs[pstatus->fields.command_id];
3931        scb->basic_status = basic_status =
3932            pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
3933        scb->extended_status = ext_status = pstatus->fields.extended_status;
3934
3935        sp = &ha->sp;
3936        sp->residue_len = 0;
3937        sp->scb_addr = (void *) scb;
3938
3939        /* Remove the item from the active queue */
3940        ips_removeq_scb(&ha->scb_activelist, scb);
3941
3942        if (!scb->scsi_cmd)
3943                /* internal commands are handled in do_ipsintr */
3944                return;
3945
3946        DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
3947                  ips_name,
3948                  ha->host_num,
3949                  scb->cdb[0],
3950                  scb->cmd.basic_io.command_id,
3951                  scb->bus, scb->target_id, scb->lun);
3952
3953        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
3954                /* passthru - just returns the raw result */
3955                return;
3956
3957        errcode = DID_OK;
3958
3959        if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
3960            ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
3961
3962                if (scb->bus == 0) {
3963                        if ((basic_status & IPS_GSC_STATUS_MASK) ==
3964                            IPS_CMD_RECOVERED_ERROR) {
3965                                DEBUG_VAR(1,
3966                                          "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
3967                                          ips_name, ha->host_num,
3968                                          scb->cmd.basic_io.op_code,
3969                                          basic_status, ext_status);
3970                        }
3971
3972                        switch (scb->scsi_cmd->cmnd[0]) {
3973                        case ALLOW_MEDIUM_REMOVAL:
3974                        case REZERO_UNIT:
3975                        case ERASE:
3976                        case WRITE_FILEMARKS:
3977                        case SPACE:
3978                                errcode = DID_ERROR;
3979                                break;
3980
3981                        case START_STOP:
3982                                break;
3983
3984                        case TEST_UNIT_READY:
3985                                if (!ips_online(ha, scb)) {
3986                                        errcode = DID_TIME_OUT;
3987                                }
3988                                break;
3989
3990                        case INQUIRY:
3991                                if (ips_online(ha, scb)) {
3992                                        ips_inquiry(ha, scb);
3993                                } else {
3994                                        errcode = DID_TIME_OUT;
3995                                }
3996                                break;
3997
3998                        case REQUEST_SENSE:
3999                                ips_reqsen(ha, scb);
4000                                break;
4001
4002                        case READ_6:
4003                        case WRITE_6:
4004                        case READ_10:
4005                        case WRITE_10:
4006                        case RESERVE:
4007                        case RELEASE:
4008                                break;
4009
4010                        case MODE_SENSE:
4011                                if (!ips_online(ha, scb)
4012                                    || !ips_msense(ha, scb)) {
4013                                        errcode = DID_ERROR;
4014                                }
4015                                break;
4016
4017                        case READ_CAPACITY:
4018                                if (ips_online(ha, scb))
4019                                        ips_rdcap(ha, scb);
4020                                else {
4021                                        errcode = DID_TIME_OUT;
4022                                }
4023                                break;
4024
4025                        case SEND_DIAGNOSTIC:
4026                        case REASSIGN_BLOCKS:
4027                                break;
4028
4029                        case FORMAT_UNIT:
4030                                errcode = DID_ERROR;
4031                                break;
4032
4033                        case SEEK_10:
4034                        case VERIFY:
4035                        case READ_DEFECT_DATA:
4036                        case READ_BUFFER:
4037                        case WRITE_BUFFER:
4038                                break;
4039
4040                        default:
4041                                errcode = DID_ERROR;
4042                        }       /* end switch */
4043
4044                        scb->scsi_cmd->result = errcode << 16;
4045                } else {        /* bus == 0 */
4046                        /* restrict access to physical drives */
4047                        if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4048                            ips_scmd_buf_read(scb->scsi_cmd,
4049                                  &inquiryData, sizeof (inquiryData));
4050                            if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
4051                                scb->scsi_cmd->result = DID_TIME_OUT << 16;
4052                        }
4053                }               /* else */
4054        } else {                /* recovered error / success */
4055                if (scb->bus == 0) {
4056                        DEBUG_VAR(1,
4057                                  "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4058                                  ips_name, ha->host_num,
4059                                  scb->cmd.basic_io.op_code, basic_status,
4060                                  ext_status);
4061                }
4062
4063                ips_map_status(ha, scb, sp);
4064        }                       /* else */
4065}
4066
4067/****************************************************************************/
4068/*                                                                          */
4069/* Routine Name: ips_online                                                 */
4070/*                                                                          */
4071/* Routine Description:                                                     */
4072/*                                                                          */
4073/*   Determine if a logical drive is online                                 */
4074/*                                                                          */
4075/****************************************************************************/
4076static int
4077ips_online(ips_ha_t * ha, ips_scb_t * scb)
4078{
4079        METHOD_TRACE("ips_online", 1);
4080
4081        if (scb->target_id >= IPS_MAX_LD)
4082                return (0);
4083
4084        if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4085                memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4086                return (0);
4087        }
4088
4089        if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4090            IPS_LD_OFFLINE
4091            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4092            IPS_LD_FREE
4093            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4094            IPS_LD_CRS
4095            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4096            IPS_LD_SYS)
4097                return (1);
4098        else
4099                return (0);
4100}
4101
4102/****************************************************************************/
4103/*                                                                          */
4104/* Routine Name: ips_inquiry                                                */
4105/*                                                                          */
4106/* Routine Description:                                                     */
4107/*                                                                          */
4108/*   Simulate an inquiry command to a logical drive                         */
4109/*                                                                          */
4110/****************************************************************************/
4111static int
4112ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4113{
4114        IPS_SCSI_INQ_DATA inquiry;
4115
4116        METHOD_TRACE("ips_inquiry", 1);
4117
4118        memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4119
4120        inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4121        inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4122        inquiry.Version = IPS_SCSI_INQ_REV2;
4123        inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4124        inquiry.AdditionalLength = 31;
4125        inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4126        inquiry.Flags[1] =
4127            IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4128        strncpy(inquiry.VendorId, "IBM     ", 8);
4129        strncpy(inquiry.ProductId, "SERVERAID       ", 16);
4130        strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4131
4132        ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4133
4134        return (1);
4135}
4136
4137/****************************************************************************/
4138/*                                                                          */
4139/* Routine Name: ips_rdcap                                                  */
4140/*                                                                          */
4141/* Routine Description:                                                     */
4142/*                                                                          */
4143/*   Simulate a read capacity command to a logical drive                    */
4144/*                                                                          */
4145/****************************************************************************/
4146static int
4147ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4148{
4149        IPS_SCSI_CAPACITY cap;
4150
4151        METHOD_TRACE("ips_rdcap", 1);
4152
4153        if (scsi_bufflen(scb->scsi_cmd) < 8)
4154                return (0);
4155
4156        cap.lba =
4157            cpu_to_be32(le32_to_cpu
4158                        (ha->logical_drive_info->
4159                         drive_info[scb->target_id].sector_count) - 1);
4160        cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4161
4162        ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4163
4164        return (1);
4165}
4166
4167/****************************************************************************/
4168/*                                                                          */
4169/* Routine Name: ips_msense                                                 */
4170/*                                                                          */
4171/* Routine Description:                                                     */
4172/*                                                                          */
4173/*   Simulate a mode sense command to a logical drive                       */
4174/*                                                                          */
4175/****************************************************************************/
4176static int
4177ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4178{
4179        uint16_t heads;
4180        uint16_t sectors;
4181        uint32_t cylinders;
4182        IPS_SCSI_MODE_PAGE_DATA mdata;
4183
4184        METHOD_TRACE("ips_msense", 1);
4185
4186        if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4187            (ha->enq->ucMiscFlag & 0x8) == 0) {
4188                heads = IPS_NORM_HEADS;
4189                sectors = IPS_NORM_SECTORS;
4190        } else {
4191                heads = IPS_COMP_HEADS;
4192                sectors = IPS_COMP_SECTORS;
4193        }
4194
4195        cylinders =
4196            (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4197             1) / (heads * sectors);
4198
4199        memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4200
4201        mdata.hdr.BlockDescLength = 8;
4202
4203        switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4204        case 0x03:              /* page 3 */
4205                mdata.pdata.pg3.PageCode = 3;
4206                mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4207                mdata.hdr.DataLength =
4208                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4209                mdata.pdata.pg3.TracksPerZone = 0;
4210                mdata.pdata.pg3.AltSectorsPerZone = 0;
4211                mdata.pdata.pg3.AltTracksPerZone = 0;
4212                mdata.pdata.pg3.AltTracksPerVolume = 0;
4213                mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4214                mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4215                mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4216                mdata.pdata.pg3.TrackSkew = 0;
4217                mdata.pdata.pg3.CylinderSkew = 0;
4218                mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4219                break;
4220
4221        case 0x4:
4222                mdata.pdata.pg4.PageCode = 4;
4223                mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4224                mdata.hdr.DataLength =
4225                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4226                mdata.pdata.pg4.CylindersHigh =
4227                    cpu_to_be16((cylinders >> 8) & 0xFFFF);
4228                mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4229                mdata.pdata.pg4.Heads = heads;
4230                mdata.pdata.pg4.WritePrecompHigh = 0;
4231                mdata.pdata.pg4.WritePrecompLow = 0;
4232                mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4233                mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4234                mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4235                mdata.pdata.pg4.LandingZoneHigh = 0;
4236                mdata.pdata.pg4.LandingZoneLow = 0;
4237                mdata.pdata.pg4.flags = 0;
4238                mdata.pdata.pg4.RotationalOffset = 0;
4239                mdata.pdata.pg4.MediumRotationRate = 0;
4240                break;
4241        case 0x8:
4242                mdata.pdata.pg8.PageCode = 8;
4243                mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4244                mdata.hdr.DataLength =
4245                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4246                /* everything else is left set to 0 */
4247                break;
4248
4249        default:
4250                return (0);
4251        }                       /* end switch */
4252
4253        ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4254
4255        return (1);
4256}
4257
4258/****************************************************************************/
4259/*                                                                          */
4260/* Routine Name: ips_reqsen                                                 */
4261/*                                                                          */
4262/* Routine Description:                                                     */
4263/*                                                                          */
4264/*   Simulate a request sense command to a logical drive                    */
4265/*                                                                          */
4266/****************************************************************************/
4267static int
4268ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4269{
4270        IPS_SCSI_REQSEN reqsen;
4271
4272        METHOD_TRACE("ips_reqsen", 1);
4273
4274        memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4275
4276        reqsen.ResponseCode =
4277            IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4278        reqsen.AdditionalLength = 10;
4279        reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4280        reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4281
4282        ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4283
4284        return (1);
4285}
4286
4287/****************************************************************************/
4288/*                                                                          */
4289/* Routine Name: ips_free                                                   */
4290/*                                                                          */
4291/* Routine Description:                                                     */
4292/*                                                                          */
4293/*   Free any allocated space for this controller                           */
4294/*                                                                          */
4295/****************************************************************************/
4296static void
4297ips_free(ips_ha_t * ha)
4298{
4299
4300        METHOD_TRACE("ips_free", 1);
4301
4302        if (ha) {
4303                if (ha->enq) {
4304                        pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4305                                            ha->enq, ha->enq_busaddr);
4306                        ha->enq = NULL;
4307                }
4308
4309                kfree(ha->conf);
4310                ha->conf = NULL;
4311
4312                if (ha->adapt) {
4313                        pci_free_consistent(ha->pcidev,
4314                                            sizeof (IPS_ADAPTER) +
4315                                            sizeof (IPS_IO_CMD), ha->adapt,
4316                                            ha->adapt->hw_status_start);
4317                        ha->adapt = NULL;
4318                }
4319
4320                if (ha->logical_drive_info) {
4321                        pci_free_consistent(ha->pcidev,
4322                                            sizeof (IPS_LD_INFO),
4323                                            ha->logical_drive_info,
4324                                            ha->logical_drive_info_dma_addr);
4325                        ha->logical_drive_info = NULL;
4326                }
4327
4328                kfree(ha->nvram);
4329                ha->nvram = NULL;
4330
4331                kfree(ha->subsys);
4332                ha->subsys = NULL;
4333
4334                if (ha->ioctl_data) {
4335                        pci_free_consistent(ha->pcidev, ha->ioctl_len,
4336                                            ha->ioctl_data, ha->ioctl_busaddr);
4337                        ha->ioctl_data = NULL;
4338                        ha->ioctl_datasize = 0;
4339                        ha->ioctl_len = 0;
4340                }
4341                ips_deallocatescbs(ha, ha->max_cmds);
4342
4343                /* free memory mapped (if applicable) */
4344                if (ha->mem_ptr) {
4345                        iounmap(ha->ioremap_ptr);
4346                        ha->ioremap_ptr = NULL;
4347                        ha->mem_ptr = NULL;
4348                }
4349
4350                ha->mem_addr = 0;
4351
4352        }
4353}
4354
4355/****************************************************************************/
4356/*                                                                          */
4357/* Routine Name: ips_deallocatescbs                                         */
4358/*                                                                          */
4359/* Routine Description:                                                     */
4360/*                                                                          */
4361/*   Free the command blocks                                                */
4362/*                                                                          */
4363/****************************************************************************/
4364static int
4365ips_deallocatescbs(ips_ha_t * ha, int cmds)
4366{
4367        if (ha->scbs) {
4368                pci_free_consistent(ha->pcidev,
4369                                    IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
4370                                    ha->scbs->sg_list.list,
4371                                    ha->scbs->sg_busaddr);
4372                pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
4373                                    ha->scbs, ha->scbs->scb_busaddr);
4374                ha->scbs = NULL;
4375        }                       /* end if */
4376        return 1;
4377}
4378
4379/****************************************************************************/
4380/*                                                                          */
4381/* Routine Name: ips_allocatescbs                                           */
4382/*                                                                          */
4383/* Routine Description:                                                     */
4384/*                                                                          */
4385/*   Allocate the command blocks                                            */
4386/*                                                                          */
4387/****************************************************************************/
4388static int
4389ips_allocatescbs(ips_ha_t * ha)
4390{
4391        ips_scb_t *scb_p;
4392        IPS_SG_LIST ips_sg;
4393        int i;
4394        dma_addr_t command_dma, sg_dma;
4395
4396        METHOD_TRACE("ips_allocatescbs", 1);
4397
4398        /* Allocate memory for the SCBs */
4399        ha->scbs =
4400            pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
4401                                 &command_dma);
4402        if (ha->scbs == NULL)
4403                return 0;
4404        ips_sg.list =
4405            pci_alloc_consistent(ha->pcidev,
4406                                 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
4407                                 ha->max_cmds, &sg_dma);
4408        if (ips_sg.list == NULL) {
4409                pci_free_consistent(ha->pcidev,
4410                                    ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
4411                                    command_dma);
4412                return 0;
4413        }
4414
4415        memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
4416
4417        for (i = 0; i < ha->max_cmds; i++) {
4418                scb_p = &ha->scbs[i];
4419                scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
4420                /* set up S/G list */
4421                if (IPS_USE_ENH_SGLIST(ha)) {
4422                        scb_p->sg_list.enh_list =
4423                            ips_sg.enh_list + i * IPS_MAX_SG;
4424                        scb_p->sg_busaddr =
4425                            sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4426                } else {
4427                        scb_p->sg_list.std_list =
4428                            ips_sg.std_list + i * IPS_MAX_SG;
4429                        scb_p->sg_busaddr =
4430                            sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4431                }
4432
4433                /* add to the free list */
4434                if (i < ha->max_cmds - 1) {
4435                        scb_p->q_next = ha->scb_freelist;
4436                        ha->scb_freelist = scb_p;
4437                }
4438        }
4439
4440        /* success */
4441        return (1);
4442}
4443
4444/****************************************************************************/
4445/*                                                                          */
4446/* Routine Name: ips_init_scb                                               */
4447/*                                                                          */
4448/* Routine Description:                                                     */
4449/*                                                                          */
4450/*   Initialize a CCB to default values                                     */
4451/*                                                                          */
4452/****************************************************************************/
4453static void
4454ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
4455{
4456        IPS_SG_LIST sg_list;
4457        uint32_t cmd_busaddr, sg_busaddr;
4458        METHOD_TRACE("ips_init_scb", 1);
4459
4460        if (scb == NULL)
4461                return;
4462
4463        sg_list.list = scb->sg_list.list;
4464        cmd_busaddr = scb->scb_busaddr;
4465        sg_busaddr = scb->sg_busaddr;
4466        /* zero fill */
4467        memset(scb, 0, sizeof (ips_scb_t));
4468        memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
4469
4470        /* Initialize dummy command bucket */
4471        ha->dummy->op_code = 0xFF;
4472        ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
4473                                       + sizeof (IPS_ADAPTER));
4474        ha->dummy->command_id = IPS_MAX_CMDS;
4475
4476        /* set bus address of scb */
4477        scb->scb_busaddr = cmd_busaddr;
4478        scb->sg_busaddr = sg_busaddr;
4479        scb->sg_list.list = sg_list.list;
4480
4481        /* Neptune Fix */
4482        scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
4483        scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
4484                                              + sizeof (IPS_ADAPTER));
4485}
4486
4487/****************************************************************************/
4488/*                                                                          */
4489/* Routine Name: ips_get_scb                                                */
4490/*                                                                          */
4491/* Routine Description:                                                     */
4492/*                                                                          */
4493/*   Initialize a CCB to default values                                     */
4494/*                                                                          */
4495/* ASSUMED to be callled from within a lock                                 */
4496/*                                                                          */
4497/****************************************************************************/
4498static ips_scb_t *
4499ips_getscb(ips_ha_t * ha)
4500{
4501        ips_scb_t *scb;
4502
4503        METHOD_TRACE("ips_getscb", 1);
4504
4505        if ((scb = ha->scb_freelist) == NULL) {
4506
4507                return (NULL);
4508        }
4509
4510        ha->scb_freelist = scb->q_next;
4511        scb->flags = 0;
4512        scb->q_next = NULL;
4513
4514        ips_init_scb(ha, scb);
4515
4516        return (scb);
4517}
4518
4519/****************************************************************************/
4520/*                                                                          */
4521/* Routine Name: ips_free_scb                                               */
4522/*                                                                          */
4523/* Routine Description:                                                     */
4524/*                                                                          */
4525/*   Return an unused CCB back to the free list                             */
4526/*                                                                          */
4527/* ASSUMED to be called from within a lock                                  */
4528/*                                                                          */
4529/****************************************************************************/
4530static void
4531ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
4532{
4533
4534        METHOD_TRACE("ips_freescb", 1);
4535        if (scb->flags & IPS_SCB_MAP_SG)
4536                scsi_dma_unmap(scb->scsi_cmd);
4537        else if (scb->flags & IPS_SCB_MAP_SINGLE)
4538                pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
4539                                 IPS_DMA_DIR(scb));
4540
4541        /* check to make sure this is not our "special" scb */
4542        if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
4543                scb->q_next = ha->scb_freelist;
4544                ha->scb_freelist = scb;
4545        }
4546}
4547
4548/****************************************************************************/
4549/*                                                                          */
4550/* Routine Name: ips_isinit_copperhead                                      */
4551/*                                                                          */
4552/* Routine Description:                                                     */
4553/*                                                                          */
4554/*   Is controller initialized ?                                            */
4555/*                                                                          */
4556/****************************************************************************/
4557static int
4558ips_isinit_copperhead(ips_ha_t * ha)
4559{
4560        uint8_t scpr;
4561        uint8_t isr;
4562
4563        METHOD_TRACE("ips_isinit_copperhead", 1);
4564
4565        isr = inb(ha->io_addr + IPS_REG_HISR);
4566        scpr = inb(ha->io_addr + IPS_REG_SCPR);
4567
4568        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4569                return (0);
4570        else
4571                return (1);
4572}
4573
4574/****************************************************************************/
4575/*                                                                          */
4576/* Routine Name: ips_isinit_copperhead_memio                                */
4577/*                                                                          */
4578/* Routine Description:                                                     */
4579/*                                                                          */
4580/*   Is controller initialized ?                                            */
4581/*                                                                          */
4582/****************************************************************************/
4583static int
4584ips_isinit_copperhead_memio(ips_ha_t * ha)
4585{
4586        uint8_t isr = 0;
4587        uint8_t scpr;
4588
4589        METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4590
4591        isr = readb(ha->mem_ptr + IPS_REG_HISR);
4592        scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
4593
4594        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4595                return (0);
4596        else
4597                return (1);
4598}
4599
4600/****************************************************************************/
4601/*                                                                          */
4602/* Routine Name: ips_isinit_morpheus                                        */
4603/*                                                                          */
4604/* Routine Description:                                                     */
4605/*                                                                          */
4606/*   Is controller initialized ?                                            */
4607/*                                                                          */
4608/****************************************************************************/
4609static int
4610ips_isinit_morpheus(ips_ha_t * ha)
4611{
4612        uint32_t post;
4613        uint32_t bits;
4614
4615        METHOD_TRACE("ips_is_init_morpheus", 1);
4616
4617        if (ips_isintr_morpheus(ha))
4618            ips_flush_and_reset(ha);
4619
4620        post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
4621        bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4622
4623        if (post == 0)
4624                return (0);
4625        else if (bits & 0x3)
4626                return (0);
4627        else
4628                return (1);
4629}
4630
4631/****************************************************************************/
4632/*                                                                          */
4633/* Routine Name: ips_flush_and_reset                                        */
4634/*                                                                          */
4635/* Routine Description:                                                     */
4636/*                                                                          */
4637/*   Perform cleanup ( FLUSH and RESET ) when the adapter is in an unknown  */
4638/*   state ( was trying to INIT and an interrupt was already pending ) ...  */
4639/*                                                                          */
4640/****************************************************************************/
4641static void
4642ips_flush_and_reset(ips_ha_t *ha)
4643{
4644        ips_scb_t *scb;
4645        int  ret;
4646        int  time;
4647        int  done;
4648        dma_addr_t command_dma;
4649
4650        /* Create a usuable SCB */
4651        scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
4652        if (scb) {
4653            memset(scb, 0, sizeof(ips_scb_t));
4654            ips_init_scb(ha, scb);
4655            scb->scb_busaddr = command_dma;
4656
4657            scb->timeout = ips_cmd_timeout;
4658            scb->cdb[0] = IPS_CMD_FLUSH;
4659
4660            scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
4661            scb->cmd.flush_cache.command_id = IPS_MAX_CMDS;   /* Use an ID that would otherwise not exist */
4662            scb->cmd.flush_cache.state = IPS_NORM_STATE;
4663            scb->cmd.flush_cache.reserved = 0;
4664            scb->cmd.flush_cache.reserved2 = 0;
4665            scb->cmd.flush_cache.reserved3 = 0;
4666            scb->cmd.flush_cache.reserved4 = 0;
4667
4668            ret = ips_send_cmd(ha, scb);                      /* Send the Flush Command */
4669
4670            if (ret == IPS_SUCCESS) {
4671                time = 60 * IPS_ONE_SEC;                      /* Max Wait time is 60 seconds */
4672                done = 0;
4673
4674                while ((time > 0) && (!done)) {
4675                   done = ips_poll_for_flush_complete(ha);
4676                   /* This may look evil, but it's only done during extremely rare start-up conditions ! */
4677                   udelay(1000);
4678                   time--;
4679                }
4680        }
4681        }
4682
4683        /* Now RESET and INIT the adapter */
4684        (*ha->func.reset) (ha);
4685
4686        pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
4687        return;
4688}
4689
4690/****************************************************************************/
4691/*                                                                          */
4692/* Routine Name: ips_poll_for_flush_complete                                */
4693/*                                                                          */
4694/* Routine Description:                                                     */
4695/*                                                                          */
4696/*   Poll for the Flush Command issued by ips_flush_and_reset() to complete */
4697/*   All other responses are just taken off the queue and ignored           */
4698/*                                                                          */
4699/****************************************************************************/
4700static int
4701ips_poll_for_flush_complete(ips_ha_t * ha)
4702{
4703        IPS_STATUS cstatus;
4704
4705        while (TRUE) {
4706            cstatus.value = (*ha->func.statupd) (ha);
4707
4708            if (cstatus.value == 0xffffffff)      /* If No Interrupt to process */
4709                        break;
4710
4711            /* Success is when we see the Flush Command ID */
4712            if (cstatus.fields.command_id == IPS_MAX_CMDS)
4713                return 1;
4714         }
4715
4716        return 0;
4717}
4718
4719/****************************************************************************/
4720/*                                                                          */
4721/* Routine Name: ips_enable_int_copperhead                                  */
4722/*                                                                          */
4723/* Routine Description:                                                     */
4724/*   Turn on interrupts                                                     */
4725/*                                                                          */
4726/****************************************************************************/
4727static void
4728ips_enable_int_copperhead(ips_ha_t * ha)
4729{
4730        METHOD_TRACE("ips_enable_int_copperhead", 1);
4731
4732        outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
4733        inb(ha->io_addr + IPS_REG_HISR);        /*Ensure PCI Posting Completes*/
4734}
4735
4736/****************************************************************************/
4737/*                                                                          */
4738/* Routine Name: ips_enable_int_copperhead_memio                            */
4739/*                                                                          */
4740/* Routine Description:                                                     */
4741/*   Turn on interrupts                                                     */
4742/*                                                                          */
4743/****************************************************************************/
4744static void
4745ips_enable_int_copperhead_memio(ips_ha_t * ha)
4746{
4747        METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4748
4749        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4750        readb(ha->mem_ptr + IPS_REG_HISR);      /*Ensure PCI Posting Completes*/
4751}
4752
4753/****************************************************************************/
4754/*                                                                          */
4755/* Routine Name: ips_enable_int_morpheus                                    */
4756/*                                                                          */
4757/* Routine Description:                                                     */
4758/*   Turn on interrupts                                                     */
4759/*                                                                          */
4760/****************************************************************************/
4761static void
4762ips_enable_int_morpheus(ips_ha_t * ha)
4763{
4764        uint32_t Oimr;
4765
4766        METHOD_TRACE("ips_enable_int_morpheus", 1);
4767
4768        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4769        Oimr &= ~0x08;
4770        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
4771        readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/
4772}
4773
4774/****************************************************************************/
4775/*                                                                          */
4776/* Routine Name: ips_init_copperhead                                        */
4777/*                                                                          */
4778/* Routine Description:                                                     */
4779/*                                                                          */
4780/*   Initialize a copperhead controller                                     */
4781/*                                                                          */
4782/****************************************************************************/
4783static int
4784ips_init_copperhead(ips_ha_t * ha)
4785{
4786        uint8_t Isr;
4787        uint8_t Cbsp;
4788        uint8_t PostByte[IPS_MAX_POST_BYTES];
4789        uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4790        int i, j;
4791
4792        METHOD_TRACE("ips_init_copperhead", 1);
4793
4794        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4795                for (j = 0; j < 45; j++) {
4796                        Isr = inb(ha->io_addr + IPS_REG_HISR);
4797                        if (Isr & IPS_BIT_GHI)
4798                                break;
4799
4800                        /* Delay for 1 Second */
4801                        MDELAY(IPS_ONE_SEC);
4802                }
4803
4804                if (j >= 45)
4805                        /* error occurred */
4806                        return (0);
4807
4808                PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4809                outb(Isr, ha->io_addr + IPS_REG_HISR);
4810        }
4811
4812        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4813                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4814                           "reset controller fails (post status %x %x).\n",
4815                           PostByte[0], PostByte[1]);
4816
4817                return (0);
4818        }
4819
4820        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4821                for (j = 0; j < 240; j++) {
4822                        Isr = inb(ha->io_addr + IPS_REG_HISR);
4823                        if (Isr & IPS_BIT_GHI)
4824                                break;
4825
4826                        /* Delay for 1 Second */
4827                        MDELAY(IPS_ONE_SEC);
4828                }
4829
4830                if (j >= 240)
4831                        /* error occurred */
4832                        return (0);
4833
4834                ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4835                outb(Isr, ha->io_addr + IPS_REG_HISR);
4836        }
4837
4838        for (i = 0; i < 240; i++) {
4839                Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
4840
4841                if ((Cbsp & IPS_BIT_OP) == 0)
4842                        break;
4843
4844                /* Delay for 1 Second */
4845                MDELAY(IPS_ONE_SEC);
4846        }
4847
4848        if (i >= 240)
4849                /* reset failed */
4850                return (0);
4851
4852        /* setup CCCR */
4853        outl(0x1010, ha->io_addr + IPS_REG_CCCR);
4854
4855        /* Enable busmastering */
4856        outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
4857
4858        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4859                /* fix for anaconda64 */
4860                outl(0, ha->io_addr + IPS_REG_NDAE);
4861
4862        /* Enable interrupts */
4863        outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
4864
4865        return (1);
4866}
4867
4868/****************************************************************************/
4869/*                                                                          */
4870/* Routine Name: ips_init_copperhead_memio                                  */
4871/*                                                                          */
4872/* Routine Description:                                                     */
4873/*                                                                          */
4874/*   Initialize a copperhead controller with memory mapped I/O              */
4875/*                                                                          */
4876/****************************************************************************/
4877static int
4878ips_init_copperhead_memio(ips_ha_t * ha)
4879{
4880        uint8_t Isr = 0;
4881        uint8_t Cbsp;
4882        uint8_t PostByte[IPS_MAX_POST_BYTES];
4883        uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4884        int i, j;
4885
4886        METHOD_TRACE("ips_init_copperhead_memio", 1);
4887
4888        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4889                for (j = 0; j < 45; j++) {
4890                        Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4891                        if (Isr & IPS_BIT_GHI)
4892                                break;
4893
4894                        /* Delay for 1 Second */
4895                        MDELAY(IPS_ONE_SEC);
4896                }
4897
4898                if (j >= 45)
4899                        /* error occurred */
4900                        return (0);
4901
4902                PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4903                writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4904        }
4905
4906        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4907                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4908                           "reset controller fails (post status %x %x).\n",
4909                           PostByte[0], PostByte[1]);
4910
4911                return (0);
4912        }
4913
4914        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4915                for (j = 0; j < 240; j++) {
4916                        Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4917                        if (Isr & IPS_BIT_GHI)
4918                                break;
4919
4920                        /* Delay for 1 Second */
4921                        MDELAY(IPS_ONE_SEC);
4922                }
4923
4924                if (j >= 240)
4925                        /* error occurred */
4926                        return (0);
4927
4928                ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4929                writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4930        }
4931
4932        for (i = 0; i < 240; i++) {
4933                Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
4934
4935                if ((Cbsp & IPS_BIT_OP) == 0)
4936                        break;
4937
4938                /* Delay for 1 Second */
4939                MDELAY(IPS_ONE_SEC);
4940        }
4941
4942        if (i >= 240)
4943                /* error occurred */
4944                return (0);
4945
4946        /* setup CCCR */
4947        writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
4948
4949        /* Enable busmastering */
4950        writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
4951
4952        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4953                /* fix for anaconda64 */
4954                writel(0, ha->mem_ptr + IPS_REG_NDAE);
4955
4956        /* Enable interrupts */
4957        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4958
4959        /* if we get here then everything went OK */
4960        return (1);
4961}
4962
4963/****************************************************************************/
4964/*                                                                          */
4965/* Routine Name: ips_init_morpheus                                          */
4966/*                                                                          */
4967/* Routine Description:                                                     */
4968/*                                                                          */
4969/*   Initialize a morpheus controller                                       */
4970/*                                                                          */
4971/****************************************************************************/
4972static int
4973ips_init_morpheus(ips_ha_t * ha)
4974{
4975        uint32_t Post;
4976        uint32_t Config;
4977        uint32_t Isr;
4978        uint32_t Oimr;
4979        int i;
4980
4981        METHOD_TRACE("ips_init_morpheus", 1);
4982
4983        /* Wait up to 45 secs for Post */
4984        for (i = 0; i < 45; i++) {
4985                Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4986
4987                if (Isr & IPS_BIT_I960_MSG0I)
4988                        break;
4989
4990                /* Delay for 1 Second */
4991                MDELAY(IPS_ONE_SEC);
4992        }
4993
4994        if (i >= 45) {
4995                /* error occurred */
4996                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4997                           "timeout waiting for post.\n");
4998
4999                return (0);
5000        }
5001
5002        Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5003
5004        if (Post == 0x4F00) {   /* If Flashing the Battery PIC         */
5005                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5006                           "Flashing Battery PIC, Please wait ...\n");
5007
5008                /* Clear the interrupt bit */
5009                Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5010                writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5011
5012                for (i = 0; i < 120; i++) {     /*    Wait Up to 2 Min. for Completion */
5013                        Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5014                        if (Post != 0x4F00)
5015                                break;
5016                        /* Delay for 1 Second */
5017                        MDELAY(IPS_ONE_SEC);
5018                }
5019
5020                if (i >= 120) {
5021                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
5022                                   "timeout waiting for Battery PIC Flash\n");
5023                        return (0);
5024                }
5025
5026        }
5027
5028        /* Clear the interrupt bit */
5029        Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5030        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5031
5032        if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5033                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5034                           "reset controller fails (post status %x).\n", Post);
5035
5036                return (0);
5037        }
5038
5039        /* Wait up to 240 secs for config bytes */
5040        for (i = 0; i < 240; i++) {
5041                Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5042
5043                if (Isr & IPS_BIT_I960_MSG1I)
5044                        break;
5045
5046                /* Delay for 1 Second */
5047                MDELAY(IPS_ONE_SEC);
5048        }
5049
5050        if (i >= 240) {
5051                /* error occurred */
5052                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5053                           "timeout waiting for config.\n");
5054
5055                return (0);
5056        }
5057
5058        Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5059
5060        /* Clear interrupt bit */
5061        Isr = (uint32_t) IPS_BIT_I960_MSG1I;
5062        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5063
5064        /* Turn on the interrupts */
5065        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5066        Oimr &= ~0x8;
5067        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5068
5069        /* if we get here then everything went OK */
5070
5071        /* Since we did a RESET, an EraseStripeLock may be needed */
5072        if (Post == 0xEF10) {
5073                if ((Config == 0x000F) || (Config == 0x0009))
5074                        ha->requires_esl = 1;
5075        }
5076
5077        return (1);
5078}
5079
5080/****************************************************************************/
5081/*                                                                          */
5082/* Routine Name: ips_reset_copperhead                                       */
5083/*                                                                          */
5084/* Routine Description:                                                     */
5085/*                                                                          */
5086/*   Reset the controller                                                   */
5087/*                                                                          */
5088/****************************************************************************/
5089static int
5090ips_reset_copperhead(ips_ha_t * ha)
5091{
5092        int reset_counter;
5093
5094        METHOD_TRACE("ips_reset_copperhead", 1);
5095
5096        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5097                  ips_name, ha->host_num, ha->io_addr, ha->pcidev->irq);
5098
5099        reset_counter = 0;
5100
5101        while (reset_counter < 2) {
5102                reset_counter++;
5103
5104                outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5105
5106                /* Delay for 1 Second */
5107                MDELAY(IPS_ONE_SEC);
5108
5109                outb(0, ha->io_addr + IPS_REG_SCPR);
5110
5111                /* Delay for 1 Second */
5112                MDELAY(IPS_ONE_SEC);
5113
5114                if ((*ha->func.init) (ha))
5115                        break;
5116                else if (reset_counter >= 2) {
5117
5118                        return (0);
5119                }
5120        }
5121
5122        return (1);
5123}
5124
5125/****************************************************************************/
5126/*                                                                          */
5127/* Routine Name: ips_reset_copperhead_memio                                 */
5128/*                                                                          */
5129/* Routine Description:                                                     */
5130/*                                                                          */
5131/*   Reset the controller                                                   */
5132/*                                                                          */
5133/****************************************************************************/
5134static int
5135ips_reset_copperhead_memio(ips_ha_t * ha)
5136{
5137        int reset_counter;
5138
5139        METHOD_TRACE("ips_reset_copperhead_memio", 1);
5140
5141        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5142                  ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5143
5144        reset_counter = 0;
5145
5146        while (reset_counter < 2) {
5147                reset_counter++;
5148
5149                writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
5150
5151                /* Delay for 1 Second */
5152                MDELAY(IPS_ONE_SEC);
5153
5154                writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5155
5156                /* Delay for 1 Second */
5157                MDELAY(IPS_ONE_SEC);
5158
5159                if ((*ha->func.init) (ha))
5160                        break;
5161                else if (reset_counter >= 2) {
5162
5163                        return (0);
5164                }
5165        }
5166
5167        return (1);
5168}
5169
5170/****************************************************************************/
5171/*                                                                          */
5172/* Routine Name: ips_reset_morpheus                                         */
5173/*                                                                          */
5174/* Routine Description:                                                     */
5175/*                                                                          */
5176/*   Reset the controller                                                   */
5177/*                                                                          */
5178/****************************************************************************/
5179static int
5180ips_reset_morpheus(ips_ha_t * ha)
5181{
5182        int reset_counter;
5183        uint8_t junk;
5184
5185        METHOD_TRACE("ips_reset_morpheus", 1);
5186
5187        DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5188                  ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5189
5190        reset_counter = 0;
5191
5192        while (reset_counter < 2) {
5193                reset_counter++;
5194
5195                writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
5196
5197                /* Delay for 5 Seconds */
5198                MDELAY(5 * IPS_ONE_SEC);
5199
5200                /* Do a PCI config read to wait for adapter */
5201                pci_read_config_byte(ha->pcidev, 4, &junk);
5202
5203                if ((*ha->func.init) (ha))
5204                        break;
5205                else if (reset_counter >= 2) {
5206
5207                        return (0);
5208                }
5209        }
5210
5211        return (1);
5212}
5213
5214/****************************************************************************/
5215/*                                                                          */
5216/* Routine Name: ips_statinit                                               */
5217/*                                                                          */
5218/* Routine Description:                                                     */
5219/*                                                                          */
5220/*   Initialize the status queues on the controller                         */
5221/*                                                                          */
5222/****************************************************************************/
5223static void
5224ips_statinit(ips_ha_t * ha)
5225{
5226        uint32_t phys_status_start;
5227
5228        METHOD_TRACE("ips_statinit"