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 wherever 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_Host *, 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  ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
 393static void 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         = 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_lck(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
1140static DEF_SCSI_QCMD(ips_queue)
1141
1142/****************************************************************************/
1143/*                                                                          */
1144/* Routine Name: ips_biosparam                                              */
1145/*                                                                          */
1146/* Routine Description:                                                     */
1147/*                                                                          */
1148/*   Set bios geometry for the controller                                   */
1149/*                                                                          */
1150/****************************************************************************/
1151static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1152                         sector_t capacity, int geom[])
1153{
1154        ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1155        int heads;
1156        int sectors;
1157        int cylinders;
1158
1159        METHOD_TRACE("ips_biosparam", 1);
1160
1161        if (!ha)
1162                /* ?!?! host adater info invalid */
1163                return (0);
1164
1165        if (!ha->active)
1166                return (0);
1167
1168        if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1169                /* ?!?! Enquiry command failed */
1170                return (0);
1171
1172        if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1173                heads = IPS_NORM_HEADS;
1174                sectors = IPS_NORM_SECTORS;
1175        } else {
1176                heads = IPS_COMP_HEADS;
1177                sectors = IPS_COMP_SECTORS;
1178        }
1179
1180        cylinders = (unsigned long) capacity / (heads * sectors);
1181
1182        DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1183                  heads, sectors, cylinders);
1184
1185        geom[0] = heads;
1186        geom[1] = sectors;
1187        geom[2] = cylinders;
1188
1189        return (0);
1190}
1191
1192/****************************************************************************/
1193/*                                                                          */
1194/* Routine Name: ips_slave_configure                                        */
1195/*                                                                          */
1196/* Routine Description:                                                     */
1197/*                                                                          */
1198/*   Set queue depths on devices once scan is complete                      */
1199/*                                                                          */
1200/****************************************************************************/
1201static int
1202ips_slave_configure(struct scsi_device * SDptr)
1203{
1204        ips_ha_t *ha;
1205        int min;
1206
1207        ha = IPS_HA(SDptr->host);
1208        if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1209                min = ha->max_cmds / 2;
1210                if (ha->enq->ucLogDriveCount <= 2)
1211                        min = ha->max_cmds - 1;
1212                scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1213        }
1214
1215        SDptr->skip_ms_page_8 = 1;
1216        SDptr->skip_ms_page_3f = 1;
1217        return 0;
1218}
1219
1220/****************************************************************************/
1221/*                                                                          */
1222/* Routine Name: do_ipsintr                                                 */
1223/*                                                                          */
1224/* Routine Description:                                                     */
1225/*                                                                          */
1226/*   Wrapper for the interrupt handler                                      */
1227/*                                                                          */
1228/****************************************************************************/
1229static irqreturn_t
1230do_ipsintr(int irq, void *dev_id)
1231{
1232        ips_ha_t *ha;
1233        struct Scsi_Host *host;
1234        int irqstatus;
1235
1236        METHOD_TRACE("do_ipsintr", 2);
1237
1238        ha = (ips_ha_t *) dev_id;
1239        if (!ha)
1240                return IRQ_NONE;
1241        host = ips_sh[ha->host_num];
1242        /* interrupt during initialization */
1243        if (!host) {
1244                (*ha->func.intr) (ha);
1245                return IRQ_HANDLED;
1246        }
1247
1248        spin_lock(host->host_lock);
1249
1250        if (!ha->active) {
1251                spin_unlock(host->host_lock);
1252                return IRQ_HANDLED;
1253        }
1254
1255        irqstatus = (*ha->func.intr) (ha);
1256
1257        spin_unlock(host->host_lock);
1258
1259        /* start the next command */
1260        ips_next(ha, IPS_INTR_ON);
1261        return IRQ_RETVAL(irqstatus);
1262}
1263
1264/****************************************************************************/
1265/*                                                                          */
1266/* Routine Name: ips_intr_copperhead                                        */
1267/*                                                                          */
1268/* Routine Description:                                                     */
1269/*                                                                          */
1270/*   Polling interrupt handler                                              */
1271/*                                                                          */
1272/*   ASSUMES interrupts are disabled                                        */
1273/*                                                                          */
1274/****************************************************************************/
1275int
1276ips_intr_copperhead(ips_ha_t * ha)
1277{
1278        ips_stat_t *sp;
1279        ips_scb_t *scb;
1280        IPS_STATUS cstatus;
1281        int intrstatus;
1282
1283        METHOD_TRACE("ips_intr", 2);
1284
1285        if (!ha)
1286                return 0;
1287
1288        if (!ha->active)
1289                return 0;
1290
1291        intrstatus = (*ha->func.isintr) (ha);
1292
1293        if (!intrstatus) {
1294                /*
1295                 * Unexpected/Shared interrupt
1296                 */
1297
1298                return 0;
1299        }
1300
1301        while (TRUE) {
1302                sp = &ha->sp;
1303
1304                intrstatus = (*ha->func.isintr) (ha);
1305
1306                if (!intrstatus)
1307                        break;
1308                else
1309                        cstatus.value = (*ha->func.statupd) (ha);
1310
1311                if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1312                        /* Spurious Interrupt ? */
1313                        continue;
1314                }
1315
1316                ips_chkstatus(ha, &cstatus);
1317                scb = (ips_scb_t *) sp->scb_addr;
1318
1319                /*
1320                 * use the callback function to finish things up
1321                 * NOTE: interrupts are OFF for this
1322                 */
1323                (*scb->callback) (ha, scb);
1324        }                       /* end while */
1325        return 1;
1326}
1327
1328/****************************************************************************/
1329/*                                                                          */
1330/* Routine Name: ips_intr_morpheus                                          */
1331/*                                                                          */
1332/* Routine Description:                                                     */
1333/*                                                                          */
1334/*   Polling interrupt handler                                              */
1335/*                                                                          */
1336/*   ASSUMES interrupts are disabled                                        */
1337/*                                                                          */
1338/****************************************************************************/
1339int
1340ips_intr_morpheus(ips_ha_t * ha)
1341{
1342        ips_stat_t *sp;
1343        ips_scb_t *scb;
1344        IPS_STATUS cstatus;
1345        int intrstatus;
1346
1347        METHOD_TRACE("ips_intr_morpheus", 2);
1348
1349        if (!ha)
1350                return 0;
1351
1352        if (!ha->active)
1353                return 0;
1354
1355        intrstatus = (*ha->func.isintr) (ha);
1356
1357        if (!intrstatus) {
1358                /*
1359                 * Unexpected/Shared interrupt
1360                 */
1361
1362                return 0;
1363        }
1364
1365        while (TRUE) {
1366                sp = &ha->sp;
1367
1368                intrstatus = (*ha->func.isintr) (ha);
1369
1370                if (!intrstatus)
1371                        break;
1372                else
1373                        cstatus.value = (*ha->func.statupd) (ha);
1374
1375                if (cstatus.value == 0xffffffff)
1376                        /* No more to process */
1377                        break;
1378
1379                if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1380                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
1381                                   "Spurious interrupt; no ccb.\n");
1382
1383                        continue;
1384                }
1385
1386                ips_chkstatus(ha, &cstatus);
1387                scb = (ips_scb_t *) sp->scb_addr;
1388
1389                /*
1390                 * use the callback function to finish things up
1391                 * NOTE: interrupts are OFF for this
1392                 */
1393                (*scb->callback) (ha, scb);
1394        }                       /* end while */
1395        return 1;
1396}
1397
1398/****************************************************************************/
1399/*                                                                          */
1400/* Routine Name: ips_info                                                   */
1401/*                                                                          */
1402/* Routine Description:                                                     */
1403/*                                                                          */
1404/*   Return info about the driver                                           */
1405/*                                                                          */
1406/****************************************************************************/
1407static const char *
1408ips_info(struct Scsi_Host *SH)
1409{
1410        static char buffer[256];
1411        char *bp;
1412        ips_ha_t *ha;
1413
1414        METHOD_TRACE("ips_info", 1);
1415
1416        ha = IPS_HA(SH);
1417
1418        if (!ha)
1419                return (NULL);
1420
1421        bp = &buffer[0];
1422        memset(bp, 0, sizeof (buffer));
1423
1424        sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1425                IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1426
1427        if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1428                strcat(bp, " <");
1429                strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1430                strcat(bp, ">");
1431        }
1432
1433        return (bp);
1434}
1435
1436/****************************************************************************/
1437/*                                                                          */
1438/* Routine Name: ips_proc_info                                              */
1439/*                                                                          */
1440/* Routine Description:                                                     */
1441/*                                                                          */
1442/*   The passthru interface for the driver                                  */
1443/*                                                                          */
1444/****************************************************************************/
1445static int
1446ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1447              int length, int func)
1448{
1449        int i;
1450        int ret;
1451        ips_ha_t *ha = NULL;
1452
1453        METHOD_TRACE("ips_proc_info", 1);
1454
1455        /* Find our host structure */
1456        for (i = 0; i < ips_next_controller; i++) {
1457                if (ips_sh[i]) {
1458                        if (ips_sh[i] == host) {
1459                                ha = (ips_ha_t *) ips_sh[i]->hostdata;
1460                                break;
1461                        }
1462                }
1463        }
1464
1465        if (!ha)
1466                return (-EINVAL);
1467
1468        if (func) {
1469                /* write */
1470                return (0);
1471        } else {
1472                /* read */
1473                if (start)
1474                        *start = buffer;
1475
1476                ret = ips_host_info(ha, buffer, offset, length);
1477
1478                return (ret);
1479        }
1480}
1481
1482/*--------------------------------------------------------------------------*/
1483/* Helper Functions                                                         */
1484/*--------------------------------------------------------------------------*/
1485
1486/****************************************************************************/
1487/*                                                                          */
1488/* Routine Name: ips_is_passthru                                            */
1489/*                                                                          */
1490/* Routine Description:                                                     */
1491/*                                                                          */
1492/*   Determine if the specified SCSI command is really a passthru command   */
1493/*                                                                          */
1494/****************************************************************************/
1495static int ips_is_passthru(struct scsi_cmnd *SC)
1496{
1497        unsigned long flags;
1498
1499        METHOD_TRACE("ips_is_passthru", 1);
1500
1501        if (!SC)
1502                return (0);
1503
1504        if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1505            (SC->device->channel == 0) &&
1506            (SC->device->id == IPS_ADAPTER_ID) &&
1507            (SC->device->lun == 0) && scsi_sglist(SC)) {
1508                struct scatterlist *sg = scsi_sglist(SC);
1509                char  *buffer;
1510
1511                /* kmap_atomic() ensures addressability of the user buffer.*/
1512                /* local_irq_save() protects the KM_IRQ0 address slot.     */
1513                local_irq_save(flags);
1514                buffer = kmap_atomic(sg_page(sg)) + sg->offset;
1515                if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
1516                    buffer[2] == 'P' && buffer[3] == 'P') {
1517                        kunmap_atomic(buffer - sg->offset);
1518                        local_irq_restore(flags);
1519                        return 1;
1520                }
1521                kunmap_atomic(buffer - sg->offset);
1522                local_irq_restore(flags);
1523        }
1524        return 0;
1525}
1526
1527/****************************************************************************/
1528/*                                                                          */
1529/* Routine Name: ips_alloc_passthru_buffer                                  */
1530/*                                                                          */
1531/* Routine Description:                                                     */
1532/*   allocate a buffer large enough for the ioctl data if the ioctl buffer  */
1533/*   is too small or doesn't exist                                          */
1534/****************************************************************************/
1535static int
1536ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1537{
1538        void *bigger_buf;
1539        dma_addr_t dma_busaddr;
1540
1541        if (ha->ioctl_data && length <= ha->ioctl_len)
1542                return 0;
1543        /* there is no buffer or it's not big enough, allocate a new one */
1544        bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1545        if (bigger_buf) {
1546                /* free the old memory */
1547                pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1548                                    ha->ioctl_busaddr);
1549                /* use the new memory */
1550                ha->ioctl_data = (char *) bigger_buf;
1551                ha->ioctl_len = length;
1552                ha->ioctl_busaddr = dma_busaddr;
1553        } else {
1554                return -1;
1555        }
1556        return 0;
1557}
1558
1559/****************************************************************************/
1560/*                                                                          */
1561/* Routine Name: ips_make_passthru                                          */
1562/*                                                                          */
1563/* Routine Description:                                                     */
1564/*                                                                          */
1565/*   Make a passthru command out of the info in the Scsi block              */
1566/*                                                                          */
1567/****************************************************************************/
1568static int
1569ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
1570{
1571        ips_passthru_t *pt;
1572        int length = 0;
1573        int i, ret;
1574        struct scatterlist *sg = scsi_sglist(SC);
1575
1576        METHOD_TRACE("ips_make_passthru", 1);
1577
1578        scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
1579                length += sg->length;
1580
1581        if (length < sizeof (ips_passthru_t)) {
1582                /* wrong size */
1583                DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1584                          ips_name, ha->host_num);
1585                return (IPS_FAILURE);
1586        }
1587        if (ips_alloc_passthru_buffer(ha, length)) {
1588                /* allocation failure!  If ha->ioctl_data exists, use it to return
1589                   some error codes.  Return a failed command to the scsi layer. */
1590                if (ha->ioctl_data) {
1591                        pt = (ips_passthru_t *) ha->ioctl_data;
1592                        ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1593                        pt->BasicStatus = 0x0B;
1594                        pt->ExtendedStatus = 0x00;
1595                        ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1596                }
1597                return IPS_FAILURE;
1598        }
1599        ha->ioctl_datasize = length;
1600
1601        ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1602        pt = (ips_passthru_t *) ha->ioctl_data;
1603
1604        /*
1605         * Some notes about the passthru interface used
1606         *
1607         * IF the scsi op_code == 0x0d then we assume
1608         * that the data came along with/goes with the
1609         * packet we received from the sg driver. In this
1610         * case the CmdBSize field of the pt structure is
1611         * used for the size of the buffer.
1612         */
1613
1614        switch (pt->CoppCmd) {
1615        case IPS_NUMCTRLS:
1616                memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1617                       &ips_num_controllers, sizeof (int));
1618                ips_scmd_buf_write(SC, ha->ioctl_data,
1619                                   sizeof (ips_passthru_t) + sizeof (int));
1620                SC->result = DID_OK << 16;
1621
1622                return (IPS_SUCCESS_IMM);
1623
1624        case IPS_COPPUSRCMD:
1625        case IPS_COPPIOCCMD:
1626                if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1627                        if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1628                                /* wrong size */
1629                                DEBUG_VAR(1,
1630                                          "(%s%d) Passthru structure wrong size",
1631                                          ips_name, ha->host_num);
1632
1633                                return (IPS_FAILURE);
1634                        }
1635
1636                        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
1637                            pt->CoppCP.cmd.flashfw.op_code ==
1638                            IPS_CMD_RW_BIOSFW) {
1639                                ret = ips_flash_copperhead(ha, pt, scb);
1640                                ips_scmd_buf_write(SC, ha->ioctl_data,
1641                                                   sizeof (ips_passthru_t));
1642                                return ret;
1643                        }
1644                        if (ips_usrcmd(ha, pt, scb))
1645                                return (IPS_SUCCESS);
1646                        else
1647                                return (IPS_FAILURE);
1648                }
1649
1650                break;
1651
1652        }                       /* end switch */
1653
1654        return (IPS_FAILURE);
1655}
1656
1657/****************************************************************************/
1658/* Routine Name: ips_flash_copperhead                                       */
1659/* Routine Description:                                                     */
1660/*   Flash the BIOS/FW on a Copperhead style controller                     */
1661/****************************************************************************/
1662static int
1663ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1664{
1665        int datasize;
1666
1667        /* Trombone is the only copperhead that can do packet flash, but only
1668         * for firmware. No one said it had to make sense. */
1669        if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1670                if (ips_usrcmd(ha, pt, scb))
1671                        return IPS_SUCCESS;
1672                else
1673                        return IPS_FAILURE;
1674        }
1675        pt->BasicStatus = 0x0B;
1676        pt->ExtendedStatus = 0;
1677        scb->scsi_cmd->result = DID_OK << 16;
1678        /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
1679        /* avoid allocating a huge buffer per adapter ( which can fail ). */
1680        if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1681            pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1682                pt->BasicStatus = 0;
1683                return ips_flash_bios(ha, pt, scb);
1684        } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1685                if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1686                        ha->flash_data = ips_FlashData;
1687                        ha->flash_busaddr = ips_flashbusaddr;
1688                        ha->flash_len = PAGE_SIZE << 7;
1689                        ha->flash_datasize = 0;
1690                } else if (!ha->flash_data) {
1691                        datasize = pt->CoppCP.cmd.flashfw.total_packets *
1692                            pt->CoppCP.cmd.flashfw.count;
1693                        ha->flash_data = pci_alloc_consistent(ha->pcidev,
1694                                                              datasize,
1695                                                              &ha->flash_busaddr);
1696                        if (!ha->flash_data){
1697                                printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1698                                return IPS_FAILURE;
1699                        }
1700                        ha->flash_datasize = 0;
1701                        ha->flash_len = datasize;
1702                } else
1703                        return IPS_FAILURE;
1704        } else {
1705                if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1706                    ha->flash_len) {
1707                        ips_free_flash_copperhead(ha);
1708                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
1709                                   "failed size sanity check\n");
1710                        return IPS_FAILURE;
1711                }
1712        }
1713        if (!ha->flash_data)
1714                return IPS_FAILURE;
1715        pt->BasicStatus = 0;
1716        memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1717               pt->CoppCP.cmd.flashfw.count);
1718        ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1719        if (pt->CoppCP.cmd.flashfw.packet_num ==
1720            pt->CoppCP.cmd.flashfw.total_packets - 1) {
1721                if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1722                        return ips_flash_bios(ha, pt, scb);
1723                else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1724                        return ips_flash_firmware(ha, pt, scb);
1725        }
1726        return IPS_SUCCESS_IMM;
1727}
1728
1729/****************************************************************************/
1730/* Routine Name: ips_flash_bios                                             */
1731/* Routine Description:                                                     */
1732/*   flashes the bios of a copperhead adapter                               */
1733/****************************************************************************/
1734static int
1735ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1736{
1737
1738        if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1739            pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1740                if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1741                    (!ha->func.verifybios))
1742                        goto error;
1743                if ((*ha->func.erasebios) (ha)) {
1744                        DEBUG_VAR(1,
1745                                  "(%s%d) flash bios failed - unable to erase flash",
1746                                  ips_name, ha->host_num);
1747                        goto error;
1748                } else
1749                    if ((*ha->func.programbios) (ha,
1750                                                 ha->flash_data +
1751                                                 IPS_BIOS_HEADER,
1752                                                 ha->flash_datasize -
1753                                                 IPS_BIOS_HEADER, 0)) {
1754                        DEBUG_VAR(1,
1755                                  "(%s%d) flash bios failed - unable to flash",
1756                                  ips_name, ha->host_num);
1757                        goto error;
1758                } else
1759                    if ((*ha->func.verifybios) (ha,
1760                                                ha->flash_data +
1761                                                IPS_BIOS_HEADER,
1762                                                ha->flash_datasize -
1763                                                IPS_BIOS_HEADER, 0)) {
1764                        DEBUG_VAR(1,
1765                                  "(%s%d) flash bios failed - unable to verify flash",
1766                                  ips_name, ha->host_num);
1767                        goto error;
1768                }
1769                ips_free_flash_copperhead(ha);
1770                return IPS_SUCCESS_IMM;
1771        } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1772                   pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1773                if (!ha->func.erasebios)
1774                        goto error;
1775                if ((*ha->func.erasebios) (ha)) {
1776                        DEBUG_VAR(1,
1777                                  "(%s%d) flash bios failed - unable to erase flash",
1778                                  ips_name, ha->host_num);
1779                        goto error;
1780                }
1781                return IPS_SUCCESS_IMM;
1782        }
1783      error:
1784        pt->BasicStatus = 0x0B;
1785        pt->ExtendedStatus = 0x00;
1786        ips_free_flash_copperhead(ha);
1787        return IPS_FAILURE;
1788}
1789
1790/****************************************************************************/
1791/*                                                                          */
1792/* Routine Name: ips_fill_scb_sg_single                                     */
1793/*                                                                          */
1794/* Routine Description:                                                     */
1795/*   Fill in a single scb sg_list element from an address                   */
1796/*   return a -1 if a breakup occurred                                      */
1797/****************************************************************************/
1798static int
1799ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1800                       ips_scb_t * scb, int indx, unsigned int e_len)
1801{
1802
1803        int ret_val = 0;
1804
1805        if ((scb->data_len + e_len) > ha->max_xfer) {
1806                e_len = ha->max_xfer - scb->data_len;
1807                scb->breakup = indx;
1808                ++scb->sg_break;
1809                ret_val = -1;
1810        } else {
1811                scb->breakup = 0;
1812                scb->sg_break = 0;
1813        }
1814        if (IPS_USE_ENH_SGLIST(ha)) {
1815                scb->sg_list.enh_list[indx].address_lo =
1816                    cpu_to_le32(pci_dma_lo32(busaddr));
1817                scb->sg_list.enh_list[indx].address_hi =
1818                    cpu_to_le32(pci_dma_hi32(busaddr));
1819                scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1820        } else {
1821                scb->sg_list.std_list[indx].address =
1822                    cpu_to_le32(pci_dma_lo32(busaddr));
1823                scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1824        }
1825
1826        ++scb->sg_len;
1827        scb->data_len += e_len;
1828        return ret_val;
1829}
1830
1831/****************************************************************************/
1832/* Routine Name: ips_flash_firmware                                         */
1833/* Routine Description:                                                     */
1834/*   flashes the firmware of a copperhead adapter                           */
1835/****************************************************************************/
1836static int
1837ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1838{
1839        IPS_SG_LIST sg_list;
1840        uint32_t cmd_busaddr;
1841
1842        if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1843            pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1844                memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1845                pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1846                pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1847        } else {
1848                pt->BasicStatus = 0x0B;
1849                pt->ExtendedStatus = 0x00;
1850                ips_free_flash_copperhead(ha);
1851                return IPS_FAILURE;
1852        }
1853        /* Save the S/G list pointer so it doesn't get clobbered */
1854        sg_list.list = scb->sg_list.list;
1855        cmd_busaddr = scb->scb_busaddr;
1856        /* copy in the CP */
1857        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1858        /* FIX stuff that might be wrong */
1859        scb->sg_list.list = sg_list.list;
1860        scb->scb_busaddr = cmd_busaddr;
1861        scb->bus = scb->scsi_cmd->device->channel;
1862        scb->target_id = scb->scsi_cmd->device->id;
1863        scb->lun = scb->scsi_cmd->device->lun;
1864        scb->sg_len = 0;
1865        scb->data_len = 0;
1866        scb->flags = 0;
1867        scb->op_code = 0;
1868        scb->callback = ipsintr_done;
1869        scb->timeout = ips_cmd_timeout;
1870
1871        scb->data_len = ha->flash_datasize;
1872        scb->data_busaddr =
1873            pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1874                           IPS_DMA_DIR(scb));
1875        scb->flags |= IPS_SCB_MAP_SINGLE;
1876        scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
1877        scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
1878        if (pt->TimeOut)
1879                scb->timeout = pt->TimeOut;
1880        scb->scsi_cmd->result = DID_OK << 16;
1881        return IPS_SUCCESS;
1882}
1883
1884/****************************************************************************/
1885/* Routine Name: ips_free_flash_copperhead                                  */
1886/* Routine Description:                                                     */
1887/*   release the memory resources used to hold the flash image              */
1888/****************************************************************************/
1889static void
1890ips_free_flash_copperhead(ips_ha_t * ha)
1891{
1892        if (ha->flash_data == ips_FlashData)
1893                test_and_clear_bit(0, &ips_FlashDataInUse);
1894        else if (ha->flash_data)
1895                pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
1896                                    ha->flash_busaddr);
1897        ha->flash_data = NULL;
1898}
1899
1900/****************************************************************************/
1901/*                                                                          */
1902/* Routine Name: ips_usrcmd                                                 */
1903/*                                                                          */
1904/* Routine Description:                                                     */
1905/*                                                                          */
1906/*   Process a user command and make it ready to send                       */
1907/*                                                                          */
1908/****************************************************************************/
1909static int
1910ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1911{
1912        IPS_SG_LIST sg_list;
1913        uint32_t cmd_busaddr;
1914
1915        METHOD_TRACE("ips_usrcmd", 1);
1916
1917        if ((!scb) || (!pt) || (!ha))
1918                return (0);
1919
1920        /* Save the S/G list pointer so it doesn't get clobbered */
1921        sg_list.list = scb->sg_list.list;
1922        cmd_busaddr = scb->scb_busaddr;
1923        /* copy in the CP */
1924        memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1925        memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
1926
1927        /* FIX stuff that might be wrong */
1928        scb->sg_list.list = sg_list.list;
1929        scb->scb_busaddr = cmd_busaddr;
1930        scb->bus = scb->scsi_cmd->device->channel;
1931        scb->target_id = scb->scsi_cmd->device->id;
1932        scb->lun = scb->scsi_cmd->device->lun;
1933        scb->sg_len = 0;
1934        scb->data_len = 0;
1935        scb->flags = 0;
1936        scb->op_code = 0;
1937        scb->callback = ipsintr_done;
1938        scb->timeout = ips_cmd_timeout;
1939        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
1940
1941        /* we don't support DCDB/READ/WRITE Scatter Gather */
1942        if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
1943            (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
1944            (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
1945                return (0);
1946
1947        if (pt->CmdBSize) {
1948                scb->data_len = pt->CmdBSize;
1949                scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
1950        } else {
1951                scb->data_busaddr = 0L;
1952        }
1953
1954        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1955                scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
1956                                                         (unsigned long) &scb->
1957                                                         dcdb -
1958                                                         (unsigned long) scb);
1959
1960        if (pt->CmdBSize) {
1961                if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1962                        scb->dcdb.buffer_pointer =
1963                            cpu_to_le32(scb->data_busaddr);
1964                else
1965                        scb->cmd.basic_io.sg_addr =
1966                            cpu_to_le32(scb->data_busaddr);
1967        }
1968
1969        /* set timeouts */
1970        if (pt->TimeOut) {
1971                scb->timeout = pt->TimeOut;
1972
1973                if (pt->TimeOut <= 10)
1974                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
1975                else if (pt->TimeOut <= 60)
1976                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
1977                else
1978                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
1979        }
1980
1981        /* assume success */
1982        scb->scsi_cmd->result = DID_OK << 16;
1983
1984        /* success */
1985        return (1);
1986}
1987
1988/****************************************************************************/
1989/*                                                                          */
1990/* Routine Name: ips_cleanup_passthru                                       */
1991/*                                                                          */
1992/* Routine Description:                                                     */
1993/*                                                                          */
1994/*   Cleanup after a passthru command                                       */
1995/*                                                                          */
1996/****************************************************************************/
1997static void
1998ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
1999{
2000        ips_passthru_t *pt;
2001
2002        METHOD_TRACE("ips_cleanup_passthru", 1);
2003
2004        if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
2005                DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2006                          ips_name, ha->host_num);
2007
2008                return;
2009        }
2010        pt = (ips_passthru_t *) ha->ioctl_data;
2011
2012        /* Copy data back to the user */
2013        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)      /* Copy DCDB Back to Caller's Area */
2014                memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2015
2016        pt->BasicStatus = scb->basic_status;
2017        pt->ExtendedStatus = scb->extended_status;
2018        pt->AdapterType = ha->ad_type;
2019
2020        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
2021            (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2022             scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2023                ips_free_flash_copperhead(ha);
2024
2025        ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2026}
2027
2028/****************************************************************************/
2029/*                                                                          */
2030/* Routine Name: ips_host_info                                              */
2031/*                                                                          */
2032/* Routine Description:                                                     */
2033/*                                                                          */
2034/*   The passthru interface for the driver                                  */
2035/*                                                                          */
2036/****************************************************************************/
2037static int
2038ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2039{
2040        IPS_INFOSTR info;
2041
2042        METHOD_TRACE("ips_host_info", 1);
2043
2044        info.buffer = ptr;
2045        info.length = len;
2046        info.offset = offset;
2047        info.pos = 0;
2048        info.localpos = 0;
2049
2050        copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2051
2052        if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2053            (le16_to_cpu(ha->nvram->adapter_type) != 0))
2054                copy_info(&info, "\tController Type                   : %s\n",
2055                          ips_adapter_name[ha->ad_type - 1]);
2056        else
2057                copy_info(&info,
2058                          "\tController Type                   : Unknown\n");
2059
2060        if (ha->io_addr)
2061                copy_info(&info,
2062                          "\tIO region                         : 0x%lx (%d bytes)\n",
2063                          ha->io_addr, ha->io_len);
2064
2065        if (ha->mem_addr) {
2066                copy_info(&info,
2067                          "\tMemory region                     : 0x%lx (%d bytes)\n",
2068                          ha->mem_addr, ha->mem_len);
2069                copy_info(&info,
2070                          "\tShared memory address             : 0x%lx\n",
2071                          ha->mem_ptr);
2072        }
2073
2074        copy_info(&info, "\tIRQ number                        : %d\n", ha->pcidev->irq);
2075
2076    /* For the Next 3 lines Check for Binary 0 at the end and don't include it if it's there. */
2077    /* That keeps everything happy for "text" operations on the proc file.                    */
2078
2079        if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2080        if (ha->nvram->bios_low[3] == 0) {
2081            copy_info(&info,
2082                                  "\tBIOS Version                      : %c%c%c%c%c%c%c\n",
2083                                  ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2084                                  ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2085                                  ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2086                                  ha->nvram->bios_low[2]);
2087
2088        } else {
2089                    copy_info(&info,
2090                                  "\tBIOS Version                      : %c%c%c%c%c%c%c%c\n",
2091                                  ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2092                                  ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2093                                  ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2094                                  ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2095        }
2096
2097    }
2098
2099    if (ha->enq->CodeBlkVersion[7] == 0) {
2100        copy_info(&info,
2101                          "\tFirmware Version                  : %c%c%c%c%c%c%c\n",
2102                          ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2103                          ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2104                          ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2105                          ha->enq->CodeBlkVersion[6]);
2106    } else {
2107        copy_info(&info,
2108                          "\tFirmware Version                  : %c%c%c%c%c%c%c%c\n",
2109                          ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2110                          ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2111                          ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2112                          ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2113    }
2114
2115    if (ha->enq->BootBlkVersion[7] == 0) {
2116        copy_info(&info,
2117                          "\tBoot Block Version                : %c%c%c%c%c%c%c\n",
2118                          ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2119                          ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2120                          ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2121                          ha->enq->BootBlkVersion[6]);
2122    } else {
2123        copy_info(&info,
2124                          "\tBoot Block Version                : %c%c%c%c%c%c%c%c\n",
2125                          ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2126                          ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2127                          ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2128                          ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2129    }
2130
2131        copy_info(&info, "\tDriver Version                    : %s%s\n",
2132                  IPS_VERSION_HIGH, IPS_VERSION_LOW);
2133
2134        copy_info(&info, "\tDriver Build                      : %d\n",
2135                  IPS_BUILD_IDENT);
2136
2137        copy_info(&info, "\tMax Physical Devices              : %d\n",
2138                  ha->enq->ucMaxPhysicalDevices);
2139        copy_info(&info, "\tMax Active Commands               : %d\n",
2140                  ha->max_cmds);
2141        copy_info(&info, "\tCurrent Queued Commands           : %d\n",
2142                  ha->scb_waitlist.count);
2143        copy_info(&info, "\tCurrent Active Commands           : %d\n",
2144                  ha->scb_activelist.count - ha->num_ioctl);
2145        copy_info(&info, "\tCurrent Queued PT Commands        : %d\n",
2146                  ha->copp_waitlist.count);
2147        copy_info(&info, "\tCurrent Active PT Commands        : %d\n",
2148                  ha->num_ioctl);
2149
2150        copy_info(&info, "\n");
2151
2152        return (info.localpos);
2153}
2154
2155/****************************************************************************/
2156/*                                                                          */
2157/* Routine Name: copy_mem_info                                              */
2158/*                                                                          */
2159/* Routine Description:                                                     */
2160/*                                                                          */
2161/*   Copy data into an IPS_INFOSTR structure                                */
2162/*                                                                          */
2163/****************************************************************************/
2164static void
2165copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2166{
2167        METHOD_TRACE("copy_mem_info", 1);
2168
2169        if (info->pos + len < info->offset) {
2170                info->pos += len;
2171                return;
2172        }
2173
2174        if (info->pos < info->offset) {
2175                data += (info->offset - info->pos);
2176                len -= (info->offset - info->pos);
2177                info->pos += (info->offset - info->pos);
2178        }
2179
2180        if (info->localpos + len > info->length)
2181                len = info->length - info->localpos;
2182
2183        if (len > 0) {
2184                memcpy(info->buffer + info->localpos, data, len);
2185                info->pos += len;
2186                info->localpos += len;
2187        }
2188}
2189
2190/****************************************************************************/
2191/*                                                                          */
2192/* Routine Name: copy_info                                                  */
2193/*                                                                          */
2194/* Routine Description:                                                     */
2195/*                                                                          */
2196/*   printf style wrapper for an info structure                             */
2197/*                                                                          */
2198/****************************************************************************/
2199static int
2200copy_info(IPS_INFOSTR * info, char *fmt, ...)
2201{
2202        va_list args;
2203        char buf[128];
2204        int len;
2205
2206        METHOD_TRACE("copy_info", 1);
2207
2208        va_start(args, fmt);
2209        len = vsprintf(buf, fmt, args);
2210        va_end(args);
2211
2212        copy_mem_info(info, buf, len);
2213
2214        return (len);
2215}
2216
2217/****************************************************************************/
2218/*                                                                          */
2219/* Routine Name: ips_identify_controller                                    */
2220/*                                                                          */
2221/* Routine Description:                                                     */
2222/*                                                                          */
2223/*   Identify this controller                                               */
2224/*                                                                          */
2225/****************************************************************************/
2226static void
2227ips_identify_controller(ips_ha_t * ha)
2228{
2229        METHOD_TRACE("ips_identify_controller", 1);
2230
2231        switch (ha->pcidev->device) {
2232        case IPS_DEVICEID_COPPERHEAD:
2233                if (ha->pcidev->revision <= IPS_REVID_SERVERAID) {
2234                        ha->ad_type = IPS_ADTYPE_SERVERAID;
2235                } else if (ha->pcidev->revision == IPS_REVID_SERVERAID2) {
2236                        ha->ad_type = IPS_ADTYPE_SERVERAID2;
2237                } else if (ha->pcidev->revision == IPS_REVID_NAVAJO) {
2238                        ha->ad_type = IPS_ADTYPE_NAVAJO;
2239                } else if ((ha->pcidev->revision == IPS_REVID_SERVERAID2)
2240                           && (ha->slot_num == 0)) {
2241                        ha->ad_type = IPS_ADTYPE_KIOWA;
2242                } else if ((ha->pcidev->revision >= IPS_REVID_CLARINETP1) &&
2243                           (ha->pcidev->revision <= IPS_REVID_CLARINETP3)) {
2244                        if (ha->enq->ucMaxPhysicalDevices == 15)
2245                                ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2246                        else
2247                                ha->ad_type = IPS_ADTYPE_SERVERAID3;
2248                } else if ((ha->pcidev->revision >= IPS_REVID_TROMBONE32) &&
2249                           (ha->pcidev->revision <= IPS_REVID_TROMBONE64)) {
2250                        ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2251                }
2252                break;
2253
2254        case IPS_DEVICEID_MORPHEUS:
2255                switch (ha->pcidev->subsystem_device) {
2256                case IPS_SUBDEVICEID_4L:
2257                        ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2258                        break;
2259
2260                case IPS_SUBDEVICEID_4M:
2261                        ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2262                        break;
2263
2264                case IPS_SUBDEVICEID_4MX:
2265                        ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2266                        break;
2267
2268                case IPS_SUBDEVICEID_4LX:
2269                        ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2270                        break;
2271
2272                case IPS_SUBDEVICEID_5I2:
2273                        ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2274                        break;
2275
2276                case IPS_SUBDEVICEID_5I1:
2277                        ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2278                        break;
2279                }
2280
2281                break;
2282
2283        case IPS_DEVICEID_MARCO:
2284                switch (ha->pcidev->subsystem_device) {
2285                case IPS_SUBDEVICEID_6M:
2286                        ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2287                        break;
2288                case IPS_SUBDEVICEID_6I:
2289                        ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2290                        break;
2291                case IPS_SUBDEVICEID_7k:
2292                        ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2293                        break;
2294                case IPS_SUBDEVICEID_7M:
2295                        ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2296                        break;
2297                }
2298                break;
2299        }
2300}
2301
2302/****************************************************************************/
2303/*                                                                          */
2304/* Routine Name: ips_get_bios_version                                       */
2305/*                                                                          */
2306/* Routine Description:                                                     */
2307/*                                                                          */
2308/*   Get the BIOS revision number                                           */
2309/*                                                                          */
2310/****************************************************************************/
2311static void
2312ips_get_bios_version(ips_ha_t * ha, int intr)
2313{
2314        ips_scb_t *scb;
2315        int ret;
2316        uint8_t major;
2317        uint8_t minor;
2318        uint8_t subminor;
2319        uint8_t *buffer;
2320        char hexDigits[] =
2321            { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2322     'D', 'E', 'F' };
2323
2324        METHOD_TRACE("ips_get_bios_version", 1);
2325
2326        major = 0;
2327        minor = 0;
2328
2329        strncpy(ha->bios_version, "       ?", 8);
2330
2331        if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD) {
2332                if (IPS_USE_MEMIO(ha)) {
2333                        /* Memory Mapped I/O */
2334
2335                        /* test 1st byte */
2336                        writel(0, ha->mem_ptr + IPS_REG_FLAP);
2337                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2338                                udelay(25);     /* 25 us */
2339
2340                        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2341                                return;
2342
2343                        writel(1, ha->mem_ptr + IPS_REG_FLAP);
2344                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2345                                udelay(25);     /* 25 us */
2346
2347                        if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2348                                return;
2349
2350                        /* Get Major version */
2351                        writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2352                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2353                                udelay(25);     /* 25 us */
2354
2355                        major = readb(ha->mem_ptr + IPS_REG_FLDP);
2356
2357                        /* Get Minor version */
2358                        writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2359                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2360                                udelay(25);     /* 25 us */
2361                        minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2362
2363                        /* Get SubMinor version */
2364                        writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2365                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2366                                udelay(25);     /* 25 us */
2367                        subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2368
2369                } else {
2370                        /* Programmed I/O */
2371
2372                        /* test 1st byte */
2373                        outl(0, ha->io_addr + IPS_REG_FLAP);
2374                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2375                                udelay(25);     /* 25 us */
2376
2377                        if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2378                                return;
2379
2380                        outl(1, ha->io_addr + IPS_REG_FLAP);
2381                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2382                                udelay(25);     /* 25 us */
2383
2384                        if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2385                                return;
2386
2387                        /* Get Major version */
2388                        outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
2389                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2390                                udelay(25);     /* 25 us */
2391
2392                        major = inb(ha->io_addr + IPS_REG_FLDP);
2393
2394                        /* Get Minor version */
2395                        outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
2396                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2397                                udelay(25);     /* 25 us */
2398
2399                        minor = inb(ha->io_addr + IPS_REG_FLDP);
2400
2401                        /* Get SubMinor version */
2402                        outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
2403                        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2404                                udelay(25);     /* 25 us */
2405
2406                        subminor = inb(ha->io_addr + IPS_REG_FLDP);
2407
2408                }
2409        } else {
2410                /* Morpheus Family - Send Command to the card */
2411
2412                buffer = ha->ioctl_data;
2413
2414                memset(buffer, 0, 0x1000);
2415
2416                scb = &ha->scbs[ha->max_cmds - 1];
2417
2418                ips_init_scb(ha, scb);
2419
2420                scb->timeout = ips_cmd_timeout;
2421                scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2422
2423                scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2424                scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2425                scb->cmd.flashfw.type = 1;
2426                scb->cmd.flashfw.direction = 0;
2427                scb->cmd.flashfw.count = cpu_to_le32(0x800);
2428                scb->cmd.flashfw.total_packets = 1;
2429                scb->cmd.flashfw.packet_num = 0;
2430                scb->data_len = 0x1000;
2431                scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2432
2433                /* issue the command */
2434                if (((ret =
2435                      ips_send_wait(ha, scb, ips_cmd_timeout,
2436                                    intr)) == IPS_FAILURE)
2437                    || (ret == IPS_SUCCESS_IMM)
2438                    || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2439                        /* Error occurred */
2440
2441                        return;
2442                }
2443
2444                if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2445                        major = buffer[0x1ff + 0xC0];   /* Offset 0x1ff after the header (0xc0) */
2446                        minor = buffer[0x1fe + 0xC0];   /* Offset 0x1fe after the header (0xc0) */
2447                        subminor = buffer[0x1fd + 0xC0];        /* Offset 0x1fd after the header (0xc0) */
2448                } else {
2449                        return;
2450                }
2451        }
2452
2453        ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2454        ha->bios_version[1] = '.';
2455        ha->bios_version[2] = hexDigits[major & 0x0F];
2456        ha->bios_version[3] = hexDigits[subminor];
2457        ha->bios_version[4] = '.';
2458        ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2459        ha->bios_version[6] = hexDigits[minor & 0x0F];
2460        ha->bios_version[7] = 0;
2461}
2462
2463/****************************************************************************/
2464/*                                                                          */
2465/* Routine Name: ips_hainit                                                 */
2466/*                                                                          */
2467/* Routine Description:                                                     */
2468/*                                                                          */
2469/*   Initialize the controller                                              */
2470/*                                                                          */
2471/* NOTE: Assumes to be called from with a lock                              */
2472/*                                                                          */
2473/****************************************************************************/
2474static int
2475ips_hainit(ips_ha_t * ha)
2476{
2477        int i;
2478        struct timeval tv;
2479
2480        METHOD_TRACE("ips_hainit", 1);
2481
2482        if (!ha)
2483                return (0);
2484
2485        if (ha->func.statinit)
2486                (*ha->func.statinit) (ha);
2487
2488        if (ha->func.enableint)
2489                (*ha->func.enableint) (ha);
2490
2491        /* Send FFDC */
2492        ha->reset_count = 1;
2493        do_gettimeofday(&tv);
2494        ha->last_ffdc = tv.tv_sec;
2495        ips_ffdc_reset(ha, IPS_INTR_IORL);
2496
2497        if (!ips_read_config(ha, IPS_INTR_IORL)) {
2498                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2499                           "unable to read config from controller.\n");
2500
2501                return (0);
2502        }
2503        /* end if */
2504        if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2505                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2506                           "unable to read controller status.\n");
2507
2508                return (0);
2509        }
2510
2511        /* Identify this controller */
2512        ips_identify_controller(ha);
2513
2514        if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2515                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2516                           "unable to read subsystem parameters.\n");
2517
2518                return (0);
2519        }
2520
2521        /* write nvram user page 5 */
2522        if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2523                IPS_PRINTK(KERN_WARNING, ha->pcidev,
2524                           "unable to write driver info to controller.\n");
2525
2526                return (0);
2527        }
2528
2529        /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
2530        if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2531                ips_clear_adapter(ha, IPS_INTR_IORL);
2532
2533        /* set limits on SID, LUN, BUS */
2534        ha->ntargets = IPS_MAX_TARGETS + 1;
2535        ha->nlun = 1;
2536        ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2537
2538        switch (ha->conf->logical_drive[0].ucStripeSize) {
2539        case 4:
2540                ha->max_xfer = 0x10000;
2541                break;
2542
2543        case 5:
2544                ha->max_xfer = 0x20000;
2545                break;
2546
2547        case 6:
2548                ha->max_xfer = 0x40000;
2549                break;
2550
2551        case 7:
2552        default:
2553                ha->max_xfer = 0x80000;
2554                break;
2555        }
2556
2557        /* setup max concurrent commands */
2558        if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2559                /* Use the new method */
2560                ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2561        } else {
2562                /* use the old method */
2563                switch (ha->conf->logical_drive[0].ucStripeSize) {
2564                case 4:
2565                        ha->max_cmds = 32;
2566                        break;
2567
2568                case 5:
2569                        ha->max_cmds = 16;
2570                        break;
2571
2572                case 6:
2573                        ha->max_cmds = 8;
2574                        break;
2575
2576                case 7:
2577                default:
2578                        ha->max_cmds = 4;
2579                        break;
2580                }
2581        }
2582
2583        /* Limit the Active Commands on a Lite Adapter */
2584        if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2585            (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2586            (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2587                if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2588                        ha->max_cmds = MaxLiteCmds;
2589        }
2590
2591        /* set controller IDs */
2592        ha->ha_id[0] = IPS_ADAPTER_ID;
2593        for (i = 1; i < ha->nbus; i++) {
2594                ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2595                ha->dcdb_active[i - 1] = 0;
2596        }
2597
2598        return (1);
2599}
2600
2601/****************************************************************************/
2602/*                                                                          */
2603/* Routine Name: ips_next                                                   */
2604/*                                                                          */
2605/* Routine Description:                                                     */
2606/*                                                                          */
2607/*   Take the next command off the queue and send it to the controller      */
2608/*                                                                          */
2609/****************************************************************************/
2610static void
2611ips_next(ips_ha_t * ha, int intr)
2612{
2613        ips_scb_t *scb;
2614        struct scsi_cmnd *SC;
2615        struct scsi_cmnd *p;
2616        struct scsi_cmnd *q;
2617        ips_copp_wait_item_t *item;
2618        int ret;
2619        struct Scsi_Host *host;
2620        METHOD_TRACE("ips_next", 1);
2621
2622        if (!ha)
2623                return;
2624        host = ips_sh[ha->host_num];
2625        /*
2626         * Block access to the queue function so
2627         * this command won't time out
2628         */
2629        if (intr == IPS_INTR_ON)
2630                spin_lock(host->host_lock);
2631
2632        if ((ha->subsys->param[3] & 0x300000)
2633            && (ha->scb_activelist.count == 0)) {
2634                struct timeval tv;
2635
2636                do_gettimeofday(&tv);
2637
2638                if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2639                        ha->last_ffdc = tv.tv_sec;
2640                        ips_ffdc_time(ha);
2641                }
2642        }
2643
2644        /*
2645         * Send passthru commands
2646         * These have priority over normal I/O
2647         * but shouldn't affect performance too much
2648         * since we limit the number that can be active
2649         * on the card at any one time
2650         */
2651        while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2652               (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2653
2654                item = ips_removeq_copp_head(&ha->copp_waitlist);
2655                ha->num_ioctl++;
2656                if (intr == IPS_INTR_ON)
2657                        spin_unlock(host->host_lock);
2658                scb->scsi_cmd = item->scsi_cmd;
2659                kfree(item);
2660
2661                ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2662
2663                if (intr == IPS_INTR_ON)
2664                        spin_lock(host->host_lock);
2665                switch (ret) {
2666                case IPS_FAILURE:
2667                        if (scb->scsi_cmd) {
2668                                scb->scsi_cmd->result = DID_ERROR << 16;
2669                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2670                        }
2671
2672                        ips_freescb(ha, scb);
2673                        break;
2674                case IPS_SUCCESS_IMM:
2675                        if (scb->scsi_cmd) {
2676                                scb->scsi_cmd->result = DID_OK << 16;
2677                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2678                        }
2679
2680                        ips_freescb(ha, scb);
2681                        break;
2682                default:
2683                        break;
2684                }               /* end case */
2685
2686                if (ret != IPS_SUCCESS) {
2687                        ha->num_ioctl--;
2688                        continue;
2689                }
2690
2691                ret = ips_send_cmd(ha, scb);
2692
2693                if (ret == IPS_SUCCESS)
2694                        ips_putq_scb_head(&ha->scb_activelist, scb);
2695                else
2696                        ha->num_ioctl--;
2697
2698                switch (ret) {
2699                case IPS_FAILURE:
2700                        if (scb->scsi_cmd) {
2701                                scb->scsi_cmd->result = DID_ERROR << 16;
2702                        }
2703
2704                        ips_freescb(ha, scb);
2705                        break;
2706                case IPS_SUCCESS_IMM:
2707                        ips_freescb(ha, scb);
2708                        break;
2709                default:
2710                        break;
2711                }               /* end case */
2712
2713        }
2714
2715        /*
2716         * Send "Normal" I/O commands
2717         */
2718
2719        p = ha->scb_waitlist.head;
2720        while ((p) && (scb = ips_getscb(ha))) {
2721                if ((scmd_channel(p) > 0)
2722                    && (ha->
2723                        dcdb_active[scmd_channel(p) -
2724                                    1] & (1 << scmd_id(p)))) {
2725                        ips_freescb(ha, scb);
2726                        p = (struct scsi_cmnd *) p->host_scribble;
2727                        continue;
2728                }
2729
2730                q = p;
2731                SC = ips_removeq_wait(&ha->scb_waitlist, q);
2732
2733                if (intr == IPS_INTR_ON)
2734                        spin_unlock(host->host_lock);   /* Unlock HA after command is taken off queue */
2735
2736                SC->result = DID_OK;
2737                SC->host_scribble = NULL;
2738
2739                scb->target_id = SC->device->id;
2740                scb->lun = SC->device->lun;
2741                scb->bus = SC->device->channel;
2742                scb->scsi_cmd = SC;
2743                scb->breakup = 0;
2744                scb->data_len = 0;
2745                scb->callback = ipsintr_done;
2746                scb->timeout = ips_cmd_timeout;
2747                memset(&scb->cmd, 0, 16);
2748
2749                /* copy in the CDB */
2750                memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2751
2752                scb->sg_count = scsi_dma_map(SC);
2753                BUG_ON(scb->sg_count < 0);
2754                if (scb->sg_count) {
2755                        struct scatterlist *sg;
2756                        int i;
2757
2758                        scb->flags |= IPS_SCB_MAP_SG;
2759
2760                        scsi_for_each_sg(SC, sg, scb->sg_count, i) {
2761                                if (ips_fill_scb_sg_single
2762                                    (ha, sg_dma_address(sg), scb, i,
2763                                     sg_dma_len(sg)) < 0)
2764                                        break;
2765                        }
2766                        scb->dcdb.transfer_length = scb->data_len;
2767                } else {
2768                        scb->data_busaddr = 0L;
2769                        scb->sg_len = 0;
2770                        scb->data_len = 0;
2771                        scb->dcdb.transfer_length = 0;
2772                }
2773
2774                scb->dcdb.cmd_attribute =
2775                    ips_command_direction[scb->scsi_cmd->cmnd[0]];
2776
2777                /* Allow a WRITE BUFFER Command to Have no Data */
2778                /* This is Used by Tape Flash Utilites          */
2779                if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) &&
2780                                (scb->data_len == 0))
2781                        scb->dcdb.cmd_attribute = 0;
2782
2783                if (!(scb->dcdb.cmd_attribute & 0x3))
2784                        scb->dcdb.transfer_length = 0;
2785
2786                if (scb->data_len >= IPS_MAX_XFER) {
2787                        scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2788                        scb->dcdb.transfer_length = 0;
2789                }
2790                if (intr == IPS_INTR_ON)
2791                        spin_lock(host->host_lock);
2792
2793                ret = ips_send_cmd(ha, scb);
2794
2795                switch (ret) {
2796                case IPS_SUCCESS:
2797                        ips_putq_scb_head(&ha->scb_activelist, scb);
2798                        break;
2799                case IPS_FAILURE:
2800                        if (scb->scsi_cmd) {
2801                                scb->scsi_cmd->result = DID_ERROR << 16;
2802                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2803                        }
2804
2805                        if (scb->bus)
2806                                ha->dcdb_active[scb->bus - 1] &=
2807                                    ~(1 << scb->target_id);
2808
2809                        ips_freescb(ha, scb);
2810                        break;
2811                case IPS_SUCCESS_IMM:
2812                        if (scb->scsi_cmd)
2813                                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2814
2815                        if (scb->bus)
2816                                ha->dcdb_active[scb->bus - 1] &=
2817                                    ~(1 << scb->target_id);
2818
2819                        ips_freescb(ha, scb);
2820                        break;
2821                default:
2822                        break;
2823                }               /* end case */
2824
2825                p = (struct scsi_cmnd *) p->host_scribble;
2826
2827        }                       /* end while */
2828
2829        if (intr == IPS_INTR_ON)
2830                spin_unlock(host->host_lock);
2831}
2832
2833/****************************************************************************/
2834/*                                                                          */
2835/* Routine Name: ips_putq_scb_head                                          */
2836/*                                                                          */
2837/* Routine Description:                                                     */
2838/*                                                                          */
2839/*   Add an item to the head of the queue                                   */
2840/*                                                                          */
2841/* ASSUMED to be called from within the HA lock                             */
2842/*                                                                          */
2843/****************************************************************************/
2844static void
2845ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2846{
2847        METHOD_TRACE("ips_putq_scb_head", 1);
2848
2849        if (!item)
2850                return;
2851
2852        item->q_next = queue->head;
2853        queue->head = item;
2854
2855        if (!queue->tail)
2856                queue->tail = item;
2857
2858        queue->count++;
2859}
2860
2861/****************************************************************************/
2862/*                                                                          */
2863/* Routine Name: ips_removeq_scb_head                                       */
2864/*                                                                          */
2865/* Routine Description:                                                     */
2866/*                                                                          */
2867/*   Remove the head of the queue                                           */
2868/*                                                                          */
2869/* ASSUMED to be called from within the HA lock                             */
2870/*                                                                          */
2871/****************************************************************************/
2872static ips_scb_t *
2873ips_removeq_scb_head(ips_scb_queue_t * queue)
2874{
2875        ips_scb_t *item;
2876
2877        METHOD_TRACE("ips_removeq_scb_head", 1);
2878
2879        item = queue->head;
2880
2881        if (!item) {
2882                return (NULL);
2883        }
2884
2885        queue->head = item->q_next;
2886        item->q_next = NULL;
2887
2888        if (queue->tail == item)
2889                queue->tail = NULL;
2890
2891        queue->count--;
2892
2893        return (item);
2894}
2895
2896/****************************************************************************/
2897/*                                                                          */
2898/* Routine Name: ips_removeq_scb                                            */
2899/*                                                                          */
2900/* Routine Description:                                                     */
2901/*                                                                          */
2902/*   Remove an item from a queue                                            */
2903/*                                                                          */
2904/* ASSUMED to be called from within the HA lock                             */
2905/*                                                                          */
2906/****************************************************************************/
2907static ips_scb_t *
2908ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
2909{
2910        ips_scb_t *p;
2911
2912        METHOD_TRACE("ips_removeq_scb", 1);
2913
2914        if (!item)
2915                return (NULL);
2916
2917        if (item == queue->head) {
2918                return (ips_removeq_scb_head(queue));
2919        }
2920
2921        p = queue->head;
2922
2923        while ((p) && (item != p->q_next))
2924                p = p->q_next;
2925
2926        if (p) {
2927                /* found a match */
2928                p->q_next = item->q_next;
2929
2930                if (!item->q_next)
2931                        queue->tail = p;
2932
2933                item->q_next = NULL;
2934                queue->count--;
2935
2936                return (item);
2937        }
2938
2939        return (NULL);
2940}
2941
2942/****************************************************************************/
2943/*                                                                          */
2944/* Routine Name: ips_putq_wait_tail                                         */
2945/*                                                                          */
2946/* Routine Description:                                                     */
2947/*                                                                          */
2948/*   Add an item to the tail of the queue                                   */
2949/*                                                                          */
2950/* ASSUMED to be called from within the HA lock                             */
2951/*                                                                          */
2952/****************************************************************************/
2953static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
2954{
2955        METHOD_TRACE("ips_putq_wait_tail", 1);
2956
2957        if (!item)
2958                return;
2959
2960        item->host_scribble = NULL;
2961
2962        if (queue->tail)
2963                queue->tail->host_scribble = (char *) item;
2964
2965        queue->tail = item;
2966
2967        if (!queue->head)
2968                queue->head = item;
2969
2970        queue->count++;
2971}
2972
2973/****************************************************************************/
2974/*                                                                          */
2975/* Routine Name: ips_removeq_wait_head                                      */
2976/*                                                                          */
2977/* Routine Description:                                                     */
2978/*                                                                          */
2979/*   Remove the head of the queue                                           */
2980/*                                                                          */
2981/* ASSUMED to be called from within the HA lock                             */
2982/*                                                                          */
2983/****************************************************************************/
2984static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
2985{
2986        struct scsi_cmnd *item;
2987
2988        METHOD_TRACE("ips_removeq_wait_head", 1);
2989
2990        item = queue->head;
2991
2992        if (!item) {
2993                return (NULL);
2994        }
2995
2996        queue->head = (struct scsi_cmnd *) item->host_scribble;
2997        item->host_scribble = NULL;
2998
2999        if (queue->tail == item)
3000                queue->tail = NULL;
3001
3002        queue->count--;
3003
3004        return (item);
3005}
3006
3007/****************************************************************************/
3008/*                                                                          */
3009/* Routine Name: ips_removeq_wait                                           */
3010/*                                                                          */
3011/* Routine Description:                                                     */
3012/*                                                                          */
3013/*   Remove an item from a queue                                            */
3014/*                                                                          */
3015/* ASSUMED to be called from within the HA lock                             */
3016/*                                                                          */
3017/****************************************************************************/
3018static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
3019                                          struct scsi_cmnd *item)
3020{
3021        struct scsi_cmnd *p;
3022
3023        METHOD_TRACE("ips_removeq_wait", 1);
3024
3025        if (!item)
3026                return (NULL);
3027
3028        if (item == queue->head) {
3029                return (ips_removeq_wait_head(queue));
3030        }
3031
3032        p = queue->head;
3033
3034        while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
3035                p = (struct scsi_cmnd *) p->host_scribble;
3036
3037        if (p) {
3038                /* found a match */
3039                p->host_scribble = item->host_scribble;
3040
3041                if (!item->host_scribble)
3042                        queue->tail = p;
3043
3044                item->host_scribble = NULL;
3045                queue->count--;
3046
3047                return (item);
3048        }
3049
3050        return (NULL);
3051}
3052
3053/****************************************************************************/
3054/*                                                                          */
3055/* Routine Name: ips_putq_copp_tail                                         */
3056/*                                                                          */
3057/* Routine Description:                                                     */
3058/*                                                                          */
3059/*   Add an item to the tail of the queue                                   */
3060/*                                                                          */
3061/* ASSUMED to be called from within the HA lock                             */
3062/*                                                                          */
3063/****************************************************************************/
3064static void
3065ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3066{
3067        METHOD_TRACE("ips_putq_copp_tail", 1);
3068
3069        if (!item)
3070                return;
3071
3072        item->next = NULL;
3073
3074        if (queue->tail)
3075                queue->tail->next = item;
3076
3077        queue->tail = item;
3078
3079        if (!queue->head)
3080                queue->head = item;
3081
3082        queue->count++;
3083}
3084
3085/****************************************************************************/
3086/*                                                                          */
3087/* Routine Name: ips_removeq_copp_head                                      */
3088/*                                                                          */
3089/* Routine Description:                                                     */
3090/*                                                                          */
3091/*   Remove the head of the queue                                           */
3092/*                                                                          */
3093/* ASSUMED to be called from within the HA lock                             */
3094/*                                                                          */
3095/****************************************************************************/
3096static ips_copp_wait_item_t *
3097ips_removeq_copp_head(ips_copp_queue_t * queue)
3098{
3099        ips_copp_wait_item_t *item;
3100
3101        METHOD_TRACE("ips_removeq_copp_head", 1);
3102
3103        item = queue->head;
3104
3105        if (!item) {
3106                return (NULL);
3107        }
3108
3109        queue->head = item->next;
3110        item->next = NULL;
3111
3112        if (queue->tail == item)
3113                queue->tail = NULL;
3114
3115        queue->count--;
3116
3117        return (item);
3118}
3119
3120/****************************************************************************/
3121/*                                                                          */
3122/* Routine Name: ips_removeq_copp                                           */
3123/*                                                                          */
3124/* Routine Description:                                                     */
3125/*                                                                          */
3126/*   Remove an item from a queue                                            */
3127/*                                                                          */
3128/* ASSUMED to be called from within the HA lock                             */
3129/*                                                                          */
3130/****************************************************************************/
3131static ips_copp_wait_item_t *
3132ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3133{
3134        ips_copp_wait_item_t *p;
3135
3136        METHOD_TRACE("ips_removeq_copp", 1);
3137
3138        if (!item)
3139                return (NULL);
3140
3141        if (item == queue->head) {
3142                return (ips_removeq_copp_head(queue));
3143        }
3144
3145        p = queue->head;
3146
3147        while ((p) && (item != p->next))
3148                p = p->next;
3149
3150        if (p) {
3151                /* found a match */
3152                p->next = item->next;
3153
3154                if (!item->next)
3155                        queue->tail = p;
3156
3157                item->next = NULL;
3158                queue->count--;
3159
3160                return (item);
3161        }
3162
3163        return (NULL);
3164}
3165
3166/****************************************************************************/
3167/*                                                                          */
3168/* Routine Name: ipsintr_blocking                                           */
3169/*                                                                          */
3170/* Routine Description:                                                     */
3171/*                                                                          */
3172/*   Finalize an interrupt for internal commands                            */
3173/*                                                                          */
3174/****************************************************************************/
3175static void
3176ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3177{
3178        METHOD_TRACE("ipsintr_blocking", 2);
3179
3180        ips_freescb(ha, scb);
3181        if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3182                ha->waitflag = FALSE;
3183
3184                return;
3185        }
3186}
3187
3188/****************************************************************************/
3189/*                                                                          */
3190/* Routine Name: ipsintr_done                                               */
3191/*                                                                          */
3192/* Routine Description:                                                     */
3193/*                                                                          */
3194/*   Finalize an interrupt for non-internal commands                        */
3195/*                                                                          */
3196/****************************************************************************/
3197static void
3198ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3199{
3200        METHOD_TRACE("ipsintr_done", 2);
3201
3202        if (!scb) {
3203                IPS_PRINTK(KERN_WARNING, ha->pcidev,
3204                           "Spurious interrupt; scb NULL.\n");
3205
3206                return;
3207        }
3208
3209        if (scb->scsi_cmd == NULL) {
3210                /* unexpected interrupt */
3211                IPS_PRINTK(KERN_WARNING, ha->pcidev,
3212                           "Spurious interrupt; scsi_cmd not set.\n");
3213
3214                return;
3215        }
3216
3217        ips_done(ha, scb);
3218}
3219
3220/****************************************************************************/
3221/*                                                                          */
3222/* Routine Name: ips_done                                                   */
3223/*                                                                          */
3224/* Routine Description:                                                     */
3225/*                                                                          */
3226/*   Do housekeeping on completed commands                                  */
3227/*  ASSUMED to be called form within the request lock                       */
3228/****************************************************************************/
3229static void
3230ips_done(ips_ha_t * ha, ips_scb_t * scb)
3231{
3232        int ret;
3233
3234        METHOD_TRACE("ips_done", 1);
3235
3236        if (!scb)
3237                return;
3238
3239        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3240                ips_cleanup_passthru(ha, scb);
3241                ha->num_ioctl--;
3242        } else {
3243                /*
3244                 * Check to see if this command had too much
3245                 * data and had to be broke up.  If so, queue
3246                 * the rest of the data and continue.
3247                 */
3248                if ((scb->breakup) || (scb->sg_break)) {
3249                        struct scatterlist *sg;
3250                        int i, sg_dma_index, ips_sg_index = 0;
3251
3252                        /* we had a data breakup */
3253                        scb->data_len = 0;
3254
3255                        sg = scsi_sglist(scb->scsi_cmd);
3256
3257                        /* Spin forward to last dma chunk */
3258                        sg_dma_index = scb->breakup;
3259                        for (i = 0; i < scb->breakup; i++)
3260                                sg = sg_next(sg);
3261
3262                        /* Take care of possible partial on last chunk */
3263                        ips_fill_scb_sg_single(ha,
3264                                               sg_dma_address(sg),
3265                                               scb, ips_sg_index++,
3266                                               sg_dma_len(sg));
3267
3268                        for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
3269                             sg_dma_index++, sg = sg_next(sg)) {
3270                                if (ips_fill_scb_sg_single
3271                                    (ha,
3272                                     sg_dma_address(sg),
3273                                     scb, ips_sg_index++,
3274                                     sg_dma_len(sg)) < 0)
3275                                        break;
3276                        }
3277
3278                        scb->dcdb.transfer_length = scb->data_len;
3279                        scb->dcdb.cmd_attribute |=
3280                            ips_command_direction[scb->scsi_cmd->cmnd[0]];
3281
3282                        if (!(scb->dcdb.cmd_attribute & 0x3))
3283                                scb->dcdb.transfer_length = 0;
3284
3285                        if (scb->data_len >= IPS_MAX_XFER) {
3286                                scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3287                                scb->dcdb.transfer_length = 0;
3288                        }
3289
3290                        ret = ips_send_cmd(ha, scb);
3291
3292                        switch (ret) {
3293                        case IPS_FAILURE:
3294                                if (scb->scsi_cmd) {
3295                                        scb->scsi_cmd->result = DID_ERROR << 16;
3296                                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3297                                }
3298
3299                                ips_freescb(ha, scb);
3300                                break;
3301                        case IPS_SUCCESS_IMM:
3302                                if (scb->scsi_cmd) {
3303                                        scb->scsi_cmd->result = DID_ERROR << 16;
3304                                        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3305                                }
3306
3307                                ips_freescb(ha, scb);
3308                                break;
3309                        default:
3310                                break;
3311                        }       /* end case */
3312
3313                        return;
3314                }
3315        }                       /* end if passthru */
3316
3317        if (scb->bus) {
3318                ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3319        }
3320
3321        scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3322
3323        ips_freescb(ha, scb);
3324}
3325
3326/****************************************************************************/
3327/*                                                                          */
3328/* Routine Name: ips_map_status                                             */
3329/*                                                                          */
3330/* Routine Description:                                                     */
3331/*                                                                          */
3332/*   Map Controller Error codes to Linux Error Codes                        */
3333/*                                                                          */
3334/****************************************************************************/
3335static int
3336ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3337{
3338        int errcode;
3339        int device_error;
3340        uint32_t transfer_len;
3341        IPS_DCDB_TABLE_TAPE *tapeDCDB;
3342        IPS_SCSI_INQ_DATA inquiryData;
3343
3344        METHOD_TRACE("ips_map_status", 1);
3345
3346        if (scb->bus) {
3347                DEBUG_VAR(2,
3348                          "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3349                          ips_name, ha->host_num,
3350                          scb->scsi_cmd->device->channel,
3351                          scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3352                          scb->basic_status, scb->extended_status,
3353                          scb->extended_status ==
3354                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3355                          scb->extended_status ==
3356                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3357                          scb->extended_status ==
3358                          IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3359        }
3360
3361        /* default driver error */
3362        errcode = DID_ERROR;
3363        device_error = 0;
3364
3365        switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3366        case IPS_CMD_TIMEOUT:
3367                errcode = DID_TIME_OUT;
3368                break;
3369
3370        case IPS_INVAL_OPCO:
3371        case IPS_INVAL_CMD_BLK:
3372        case IPS_INVAL_PARM_BLK:
3373        case IPS_LD_ERROR:
3374        case IPS_CMD_CMPLT_WERROR:
3375                break;
3376
3377        case IPS_PHYS_DRV_ERROR:
3378                switch (scb->extended_status) {
3379                case IPS_ERR_SEL_TO:
3380                        if (scb->bus)
3381                                errcode = DID_NO_CONNECT;
3382
3383                        break;
3384
3385                case IPS_ERR_OU_RUN:
3386                        if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3387                            (scb->cmd.dcdb.op_code ==
3388                             IPS_CMD_EXTENDED_DCDB_SG)) {
3389                                tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3390                                transfer_len = tapeDCDB->transfer_length;
3391                        } else {
3392                                transfer_len =
3393                                    (uint32_t) scb->dcdb.transfer_length;
3394                        }
3395
3396                        if ((scb->bus) && (transfer_len < scb->data_len)) {
3397                                /* Underrun - set default to no error */
3398                                errcode = DID_OK;
3399
3400                                /* Restrict access to physical DASD */
3401                                if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3402                                    ips_scmd_buf_read(scb->scsi_cmd,
3403                                      &inquiryData, sizeof (inquiryData));
3404                                    if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
3405                                        errcode = DID_TIME_OUT;
3406                                        break;
3407                                    }
3408                                }
3409                        } else
3410                                errcode = DID_ERROR;
3411
3412                        break;
3413
3414                case IPS_ERR_RECOVERY:
3415                        /* don't fail recovered errors */
3416                        if (scb->bus)
3417                                errcode = DID_OK;
3418
3419                        break;
3420
3421                case IPS_ERR_HOST_RESET:
3422                case IPS_ERR_DEV_RESET:
3423                        errcode = DID_RESET;
3424                        break;
3425
3426                case IPS_ERR_CKCOND:
3427                        if (scb->bus) {
3428                                if ((scb->cmd.dcdb.op_code ==
3429                                     IPS_CMD_EXTENDED_DCDB)
3430                                    || (scb->cmd.dcdb.op_code ==
3431                                        IPS_CMD_EXTENDED_DCDB_SG)) {
3432                                        tapeDCDB =
3433                                            (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3434                                        memcpy(scb->scsi_cmd->sense_buffer,
3435                                               tapeDCDB->sense_info,
3436                                               SCSI_SENSE_BUFFERSIZE);
3437                                } else {
3438                                        memcpy(scb->scsi_cmd->sense_buffer,
3439                                               scb->dcdb.sense_info,
3440                                               SCSI_SENSE_BUFFERSIZE);
3441                                }
3442                                device_error = 2;       /* check condition */
3443                        }
3444
3445                        errcode = DID_OK;
3446
3447                        break;
3448
3449                default:
3450                        errcode = DID_ERROR;
3451                        break;
3452
3453                }               /* end switch */
3454        }                       /* end switch */
3455
3456        scb->scsi_cmd->result = device_error | (errcode << 16);
3457
3458        return (1);
3459}
3460
3461/****************************************************************************/
3462/*                                                                          */
3463/* Routine Name: ips_send_wait                                              */
3464/*                                                                          */
3465/* Routine Description:                                                     */
3466/*                                                                          */
3467/*   Send a command to the controller and wait for it to return             */
3468/*                                                                          */
3469/*   The FFDC Time Stamp use this function for the callback, but doesn't    */
3470/*   actually need to wait.                                                 */
3471/****************************************************************************/
3472static int
3473ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3474{
3475        int ret;
3476
3477        METHOD_TRACE("ips_send_wait", 1);
3478
3479        if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
3480                ha->waitflag = TRUE;
3481                ha->cmd_in_progress = scb->cdb[0];
3482        }
3483        scb->callback = ipsintr_blocking;
3484        ret = ips_send_cmd(ha, scb);
3485
3486        if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3487                return (ret);
3488
3489        if (intr != IPS_FFDC)   /* Don't Wait around if this is a Time Stamp */
3490                ret = ips_wait(ha, timeout, intr);
3491
3492        return (ret);
3493}
3494
3495/****************************************************************************/
3496/*                                                                          */
3497/* Routine Name: ips_scmd_buf_write                                         */
3498/*                                                                          */
3499/* Routine Description:                                                     */
3500/*  Write data to struct scsi_cmnd request_buffer at proper offsets         */
3501/****************************************************************************/
3502static void
3503ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
3504{
3505        unsigned long flags;
3506
3507        local_irq_save(flags);
3508        scsi_sg_copy_from_buffer(scmd, data, count);
3509        local_irq_restore(flags);
3510}
3511
3512/****************************************************************************/
3513/*                                                                          */
3514/* Routine Name: ips_scmd_buf_read                                          */
3515/*                                                                          */
3516/* Routine Description:                                                     */
3517/*  Copy data from a struct scsi_cmnd to a new, linear buffer               */
3518/****************************************************************************/
3519static void
3520ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
3521{
3522        unsigned long flags;
3523
3524        local_irq_save(flags);
3525        scsi_sg_copy_to_buffer(scmd, data, count);
3526        local_irq_restore(flags);
3527}
3528
3529/****************************************************************************/
3530/*                                                                          */
3531/* Routine Name: ips_send_cmd                                               */
3532/*                                                                          */
3533/* Routine Description:                                                     */
3534/*                                                                          */
3535/*   Map SCSI commands to ServeRAID commands for logical drives             */
3536/*                                                                          */
3537/****************************************************************************/
3538static int
3539ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3540{
3541        int ret;
3542        char *sp;
3543        int device_error;
3544        IPS_DCDB_TABLE_TAPE *tapeDCDB;
3545        int TimeOut;
3546
3547        METHOD_TRACE("ips_send_cmd", 1);
3548
3549        ret = IPS_SUCCESS;
3550
3551        if (!scb->scsi_cmd) {
3552                /* internal command */
3553
3554                if (scb->bus > 0) {
3555                        /* Controller commands can't be issued */
3556                        /* to real devices -- fail them        */
3557                        if ((ha->waitflag == TRUE) &&
3558                            (ha->cmd_in_progress == scb->cdb[0])) {
3559                                ha->waitflag = FALSE;
3560                        }
3561
3562                        return (1);
3563                }
3564        } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3565                /* command to logical bus -- interpret */
3566                ret = IPS_SUCCESS_IMM;
3567
3568                switch (scb->scsi_cmd->cmnd[0]) {
3569                case ALLOW_MEDIUM_REMOVAL:
3570                case REZERO_UNIT:
3571                case ERASE:
3572                case WRITE_FILEMARKS:
3573                case SPACE:
3574                        scb->scsi_cmd->result = DID_ERROR << 16;
3575                        break;
3576
3577                case START_STOP:
3578                        scb->scsi_cmd->result = DID_OK << 16;
3579
3580                case TEST_UNIT_READY:
3581                case INQUIRY:
3582                        if (scb->target_id == IPS_ADAPTER_ID) {
3583                                /*
3584                                 * Either we have a TUR
3585                                 * or we have a SCSI inquiry
3586                                 */
3587                                if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3588                                        scb->scsi_cmd->result = DID_OK << 16;
3589
3590                                if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3591                                        IPS_SCSI_INQ_DATA inquiry;
3592
3593                                        memset(&inquiry, 0,
3594                                               sizeof (IPS_SCSI_INQ_DATA));
3595
3596                                        inquiry.DeviceType =
3597                                            IPS_SCSI_INQ_TYPE_PROCESSOR;
3598                                        inquiry.DeviceTypeQualifier =
3599                                            IPS_SCSI_INQ_LU_CONNECTED;
3600                                        inquiry.Version = IPS_SCSI_INQ_REV2;
3601                                        inquiry.ResponseDataFormat =
3602                                            IPS_SCSI_INQ_RD_REV2;
3603                                        inquiry.AdditionalLength = 31;
3604                                        inquiry.Flags[0] =
3605                                            IPS_SCSI_INQ_Address16;
3606                                        inquiry.Flags[1] =
3607                                            IPS_SCSI_INQ_WBus16 |
3608                                            IPS_SCSI_INQ_Sync;
3609                                        strncpy(inquiry.VendorId, "IBM     ",
3610                                                8);
3611                                        strncpy(inquiry.ProductId,
3612                                                "SERVERAID       ", 16);
3613                                        strncpy(inquiry.ProductRevisionLevel,
3614                                                "1.00", 4);
3615
3616                                        ips_scmd_buf_write(scb->scsi_cmd,
3617                                                           &inquiry,
3618                                                           sizeof (inquiry));
3619
3620                                        scb->scsi_cmd->result = DID_OK << 16;
3621                                }
3622                        } else {
3623                                scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3624                                scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3625                                scb->cmd.logical_info.reserved = 0;
3626                                scb->cmd.logical_info.reserved2 = 0;
3627                                scb->data_len = sizeof (IPS_LD_INFO);
3628                                scb->data_busaddr = ha->logical_drive_info_dma_addr;
3629                                scb->flags = 0;
3630                                scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3631                                ret = IPS_SUCCESS;
3632                        }
3633
3634                        break;
3635
3636                case REQUEST_SENSE:
3637                        ips_reqsen(ha, scb);
3638                        scb->scsi_cmd->result = DID_OK << 16;
3639                        break;
3640
3641                case READ_6:
3642                case WRITE_6:
3643                        if (!scb->sg_len) {
3644                                scb->cmd.basic_io.op_code =
3645                                    (scb->scsi_cmd->cmnd[0] ==
3646                                     READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3647                                scb->cmd.basic_io.enhanced_sg = 0;
3648                                scb->cmd.basic_io.sg_addr =
3649                                    cpu_to_le32(scb->data_busaddr);
3650                        } else {
3651                                scb->cmd.basic_io.op_code =
3652                                    (scb->scsi_cmd->cmnd[0] ==
3653                                     READ_6) ? IPS_CMD_READ_SG :
3654                                    IPS_CMD_WRITE_SG;
3655                                scb->cmd.basic_io.enhanced_sg =
3656                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3657                                scb->cmd.basic_io.sg_addr =
3658                                    cpu_to_le32(scb->sg_busaddr);
3659                        }
3660
3661                        scb->cmd.basic_io.segment_4G = 0;
3662                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3663                        scb->cmd.basic_io.log_drv = scb->target_id;
3664                        scb->cmd.basic_io.sg_count = scb->sg_len;
3665
3666                        if (scb->cmd.basic_io.lba)
3667                                le32_add_cpu(&scb->cmd.basic_io.lba,
3668                                                le16_to_cpu(scb->cmd.basic_io.
3669                                                            sector_count));
3670                        else
3671                                scb->cmd.basic_io.lba =
3672                                    (((scb->scsi_cmd->
3673                                       cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3674                                                                 cmnd[2] << 8) |
3675                                     (scb->scsi_cmd->cmnd[3]));
3676
3677                        scb->cmd.basic_io.sector_count =
3678                            cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3679
3680                        if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3681                                scb->cmd.basic_io.sector_count =
3682                                    cpu_to_le16(256);
3683
3684                        ret = IPS_SUCCESS;
3685                        break;
3686
3687                case READ_10:
3688                case WRITE_10:
3689                        if (!scb->sg_len) {
3690                                scb->cmd.basic_io.op_code =
3691                                    (scb->scsi_cmd->cmnd[0] ==
3692                                     READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3693                                scb->cmd.basic_io.enhanced_sg = 0;
3694                                scb->cmd.basic_io.sg_addr =
3695                                    cpu_to_le32(scb->data_busaddr);
3696                        } else {
3697                                scb->cmd.basic_io.op_code =
3698                                    (scb->scsi_cmd->cmnd[0] ==
3699                                     READ_10) ? IPS_CMD_READ_SG :
3700                                    IPS_CMD_WRITE_SG;
3701                                scb->cmd.basic_io.enhanced_sg =
3702                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3703                                scb->cmd.basic_io.sg_addr =
3704                                    cpu_to_le32(scb->sg_busaddr);
3705                        }
3706
3707                        scb->cmd.basic_io.segment_4G = 0;
3708                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3709                        scb->cmd.basic_io.log_drv = scb->target_id;
3710                        scb->cmd.basic_io.sg_count = scb->sg_len;
3711
3712                        if (scb->cmd.basic_io.lba)
3713                                le32_add_cpu(&scb->cmd.basic_io.lba,
3714                                                le16_to_cpu(scb->cmd.basic_io.
3715                                                            sector_count));
3716                        else
3717                                scb->cmd.basic_io.lba =
3718                                    ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3719                                                                       scsi_cmd->
3720                                                                       cmnd[3]
3721                                                                       << 16) |
3722                                     (scb->scsi_cmd->cmnd[4] << 8) | scb->
3723                                     scsi_cmd->cmnd[5]);
3724
3725                        scb->cmd.basic_io.sector_count =
3726                            cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3727
3728                        if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3729                                /*
3730                                 * This is a null condition
3731                                 * we don't have to do anything
3732                                 * so just return
3733                                 */
3734                                scb->scsi_cmd->result = DID_OK << 16;
3735                        } else
3736                                ret = IPS_SUCCESS;
3737
3738                        break;
3739
3740                case RESERVE:
3741                case RELEASE:
3742                        scb->scsi_cmd->result = DID_OK << 16;
3743                        break;
3744
3745                case MODE_SENSE:
3746                        scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3747                        scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3748                        scb->cmd.basic_io.segment_4G = 0;
3749                        scb->cmd.basic_io.enhanced_sg = 0;
3750                        scb->data_len = sizeof (*ha->enq);
3751                        scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3752                        ret = IPS_SUCCESS;
3753                        break;
3754
3755                case READ_CAPACITY:
3756                        scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3757                        scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3758                        scb->cmd.logical_info.reserved = 0;
3759                        scb->cmd.logical_info.reserved2 = 0;
3760                        scb->cmd.logical_info.reserved3 = 0;
3761                        scb->data_len = sizeof (IPS_LD_INFO);
3762                        scb->data_busaddr = ha->logical_drive_info_dma_addr;
3763                        scb->flags = 0;
3764                        scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3765                        ret = IPS_SUCCESS;
3766                        break;
3767
3768                case SEND_DIAGNOSTIC:
3769                case REASSIGN_BLOCKS:
3770                case FORMAT_UNIT:
3771                case SEEK_10:
3772                case VERIFY:
3773                case READ_DEFECT_DATA:
3774                case READ_BUFFER:
3775                case WRITE_BUFFER:
3776                        scb->scsi_cmd->result = DID_OK << 16;
3777                        break;
3778
3779                default:
3780                        /* Set the Return Info to appear like the Command was */
3781                        /* attempted, a Check Condition occurred, and Sense   */
3782                        /* Data indicating an Invalid CDB OpCode is returned. */
3783                        sp = (char *) scb->scsi_cmd->sense_buffer;
3784
3785                        sp[0] = 0x70;   /* Error Code               */
3786                        sp[2] = ILLEGAL_REQUEST;        /* Sense Key 5 Illegal Req. */
3787                        sp[7] = 0x0A;   /* Additional Sense Length  */
3788                        sp[12] = 0x20;  /* ASC = Invalid OpCode     */
3789                        sp[13] = 0x00;  /* ASCQ                     */
3790
3791                        device_error = 2;       /* Indicate Check Condition */
3792                        scb->scsi_cmd->result = device_error | (DID_OK << 16);
3793                        break;
3794                }               /* end switch */
3795        }
3796        /* end if */
3797        if (ret == IPS_SUCCESS_IMM)
3798                return (ret);
3799
3800        /* setup DCDB */
3801        if (scb->bus > 0) {
3802
3803                /* If we already know the Device is Not there, no need to attempt a Command   */
3804                /* This also protects an NT FailOver Controller from getting CDB's sent to it */
3805                if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
3806                        scb->scsi_cmd->result = DID_NO_CONNECT << 16;
3807                        return (IPS_SUCCESS_IMM);
3808                }
3809
3810                ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
3811                scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
3812                scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
3813                                                         (unsigned long) &scb->
3814                                                         dcdb -
3815                                                         (unsigned long) scb);
3816                scb->cmd.dcdb.reserved = 0;
3817                scb->cmd.dcdb.reserved2 = 0;
3818                scb->cmd.dcdb.reserved3 = 0;
3819                scb->cmd.dcdb.segment_4G = 0;
3820                scb->cmd.dcdb.enhanced_sg = 0;
3821
3822                TimeOut = scb->scsi_cmd->request->timeout;
3823
3824                if (ha->subsys->param[4] & 0x00100000) {        /* If NEW Tape DCDB is Supported */
3825                        if (!scb->sg_len) {
3826                                scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
3827                        } else {
3828                                scb->cmd.dcdb.op_code =
3829                                    IPS_CMD_EXTENDED_DCDB_SG;
3830                                scb->cmd.dcdb.enhanced_sg =
3831                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3832                        }
3833
3834                        tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
3835                        tapeDCDB->device_address =
3836                            ((scb->bus - 1) << 4) | scb->target_id;
3837                        tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3838                        tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K;    /* Always Turn OFF 64K Size Flag */
3839
3840                        if (TimeOut) {
3841                                if (TimeOut < (10 * HZ))
3842                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT10;       /* TimeOut is 10 Seconds */
3843                                else if (TimeOut < (60 * HZ))
3844                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT60;       /* TimeOut is 60 Seconds */
3845                                else if (TimeOut < (1200 * HZ))
3846                                        tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;      /* TimeOut is 20 Minutes */
3847                        }
3848
3849                        tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
3850                        tapeDCDB->reserved_for_LUN = 0;
3851                        tapeDCDB->transfer_length = scb->data_len;
3852                        if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
3853                                tapeDCDB->buffer_pointer =
3854                                    cpu_to_le32(scb->sg_busaddr);
3855                        else
3856                                tapeDCDB->buffer_pointer =
3857                                    cpu_to_le32(scb->data_busaddr);
3858                        tapeDCDB->sg_count = scb->sg_len;
3859                        tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
3860                        tapeDCDB->scsi_status = 0;
3861                        tapeDCDB->reserved = 0;
3862                        memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
3863                               scb->scsi_cmd->cmd_len);
3864                } else {
3865                        if (!scb->sg_len) {
3866                                scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
3867                        } else {
3868                                scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
3869                                scb->cmd.dcdb.enhanced_sg =
3870                                    IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3871                        }
3872
3873                        scb->dcdb.device_address =
3874                            ((scb->bus - 1) << 4) | scb->target_id;
3875                        scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3876
3877                        if (TimeOut) {
3878                                if (TimeOut < (10 * HZ))
3879                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;       /* TimeOut is 10 Seconds */
3880                                else if (TimeOut < (60 * HZ))
3881                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;       /* TimeOut is 60 Seconds */
3882                                else if (TimeOut < (1200 * HZ))
3883                                        scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;      /* TimeOut is 20 Minutes */
3884                        }
3885
3886                        scb->dcdb.transfer_length = scb->data_len;
3887                        if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
3888                                scb->dcdb.transfer_length = 0;
3889                        if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
3890                                scb->dcdb.buffer_pointer =
3891                                    cpu_to_le32(scb->sg_busaddr);
3892                        else
3893                                scb->dcdb.buffer_pointer =
3894                                    cpu_to_le32(scb->data_busaddr);
3895                        scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
3896                        scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
3897                        scb->dcdb.sg_count = scb->sg_len;
3898                        scb->dcdb.reserved = 0;
3899                        memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
3900                               scb->scsi_cmd->cmd_len);
3901                        scb->dcdb.scsi_status = 0;
3902                        scb->dcdb.reserved2[0] = 0;
3903                        scb->dcdb.reserved2[1] = 0;
3904                        scb->dcdb.reserved2[2] = 0;
3905                }
3906        }
3907
3908        return ((*ha->func.issue) (ha, scb));
3909}
3910
3911/****************************************************************************/
3912/*                                                                          */
3913/* Routine Name: ips_chk_status                                             */
3914/*                                                                          */
3915/* Routine Description:                                                     */
3916/*                                                                          */
3917/*   Check the status of commands to logical drives                         */
3918/*   Assumed to be called with the HA lock                                  */
3919/****************************************************************************/
3920static void
3921ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
3922{
3923        ips_scb_t *scb;
3924        ips_stat_t *sp;
3925        uint8_t basic_status;
3926        uint8_t ext_status;
3927        int errcode;
3928        IPS_SCSI_INQ_DATA inquiryData;
3929
3930        METHOD_TRACE("ips_chkstatus", 1);
3931
3932        scb = &ha->scbs[pstatus->fields.command_id];
3933        scb->basic_status = basic_status =
3934            pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
3935        scb->extended_status = ext_status = pstatus->fields.extended_status;
3936
3937        sp = &ha->sp;
3938        sp->residue_len = 0;
3939        sp->scb_addr = (void *) scb;
3940
3941        /* Remove the item from the active queue */
3942        ips_removeq_scb(&ha->scb_activelist, scb);
3943
3944        if (!scb->scsi_cmd)
3945                /* internal commands are handled in do_ipsintr */
3946                return;
3947
3948        DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
3949                  ips_name,
3950                  ha->host_num,
3951                  scb->cdb[0],
3952                  scb->cmd.basic_io.command_id,
3953                  scb->bus, scb->target_id, scb->lun);
3954
3955        if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
3956                /* passthru - just returns the raw result */
3957                return;
3958
3959        errcode = DID_OK;
3960
3961        if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
3962            ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
3963
3964                if (scb->bus == 0) {
3965                        if ((basic_status & IPS_GSC_STATUS_MASK) ==
3966                            IPS_CMD_RECOVERED_ERROR) {
3967                                DEBUG_VAR(1,
3968                                          "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
3969                                          ips_name, ha->host_num,
3970                                          scb->cmd.basic_io.op_code,
3971                                          basic_status, ext_status);
3972                        }
3973
3974                        switch (scb->scsi_cmd->cmnd[0]) {
3975                        case ALLOW_MEDIUM_REMOVAL:
3976                        case REZERO_UNIT:
3977                        case ERASE:
3978                        case WRITE_FILEMARKS:
3979                        case SPACE:
3980                                errcode = DID_ERROR;
3981                                break;
3982
3983                        case START_STOP:
3984                                break;
3985
3986                        case TEST_UNIT_READY:
3987                                if (!ips_online(ha, scb)) {
3988                                        errcode = DID_TIME_OUT;
3989                                }
3990                                break;
3991
3992                        case INQUIRY:
3993                                if (ips_online(ha, scb)) {
3994                                        ips_inquiry(ha, scb);
3995                                } else {
3996                                        errcode = DID_TIME_OUT;
3997                                }
3998                                break;
3999
4000                        case REQUEST_SENSE:
4001                                ips_reqsen(ha, scb);
4002                                break;
4003
4004                        case READ_6:
4005                        case WRITE_6:
4006                        case READ_10:
4007                        case WRITE_10:
4008                        case RESERVE:
4009                        case RELEASE:
4010                                break;
4011
4012                        case MODE_SENSE:
4013                                if (!ips_online(ha, scb)
4014                                    || !ips_msense(ha, scb)) {
4015                                        errcode = DID_ERROR;
4016                                }
4017                                break;
4018
4019                        case READ_CAPACITY:
4020                                if (ips_online(ha, scb))
4021                                        ips_rdcap(ha, scb);
4022                                else {
4023                                        errcode = DID_TIME_OUT;
4024                                }
4025                                break;
4026
4027                        case SEND_DIAGNOSTIC:
4028                        case REASSIGN_BLOCKS:
4029                                break;
4030
4031                        case FORMAT_UNIT:
4032                                errcode = DID_ERROR;
4033                                break;
4034
4035                        case SEEK_10:
4036                        case VERIFY:
4037                        case READ_DEFECT_DATA:
4038                        case READ_BUFFER:
4039                        case WRITE_BUFFER:
4040                                break;
4041
4042                        default:
4043                                errcode = DID_ERROR;
4044                        }       /* end switch */
4045
4046                        scb->scsi_cmd->result = errcode << 16;
4047                } else {        /* bus == 0 */
4048                        /* restrict access to physical drives */
4049                        if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4050                            ips_scmd_buf_read(scb->scsi_cmd,
4051                                  &inquiryData, sizeof (inquiryData));
4052                            if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
4053                                scb->scsi_cmd->result = DID_TIME_OUT << 16;
4054                        }
4055                }               /* else */
4056        } else {                /* recovered error / success */
4057                if (scb->bus == 0) {
4058                        DEBUG_VAR(1,
4059                                  "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4060                                  ips_name, ha->host_num,
4061                                  scb->cmd.basic_io.op_code, basic_status,
4062                                  ext_status);
4063                }
4064
4065                ips_map_status(ha, scb, sp);
4066        }                       /* else */
4067}
4068
4069/****************************************************************************/
4070/*                                                                          */
4071/* Routine Name: ips_online                                                 */
4072/*                                                                          */
4073/* Routine Description:                                                     */
4074/*                                                                          */
4075/*   Determine if a logical drive is online                                 */
4076/*                                                                          */
4077/****************************************************************************/
4078static int
4079ips_online(ips_ha_t * ha, ips_scb_t * scb)
4080{
4081        METHOD_TRACE("ips_online", 1);
4082
4083        if (scb->target_id >= IPS_MAX_LD)
4084                return (0);
4085
4086        if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4087                memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4088                return (0);
4089        }
4090
4091        if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4092            IPS_LD_OFFLINE
4093            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4094            IPS_LD_FREE
4095            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4096            IPS_LD_CRS
4097            && ha->logical_drive_info->drive_info[scb->target_id].state !=
4098            IPS_LD_SYS)
4099                return (1);
4100        else
4101                return (0);
4102}
4103
4104/****************************************************************************/
4105/*                                                                          */
4106/* Routine Name: ips_inquiry                                                */
4107/*                                                                          */
4108/* Routine Description:                                                     */
4109/*                                                                          */
4110/*   Simulate an inquiry command to a logical drive                         */
4111/*                                                                          */
4112/****************************************************************************/
4113static int
4114ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4115{
4116        IPS_SCSI_INQ_DATA inquiry;
4117
4118        METHOD_TRACE("ips_inquiry", 1);
4119
4120        memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4121
4122        inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4123        inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4124        inquiry.Version = IPS_SCSI_INQ_REV2;
4125        inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4126        inquiry.AdditionalLength = 31;
4127        inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4128        inquiry.Flags[1] =
4129            IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4130        strncpy(inquiry.VendorId, "IBM     ", 8);
4131        strncpy(inquiry.ProductId, "SERVERAID       ", 16);
4132        strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4133
4134        ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4135
4136        return (1);
4137}
4138
4139/****************************************************************************/
4140/*                                                                          */
4141/* Routine Name: ips_rdcap                                                  */
4142/*                                                                          */
4143/* Routine Description:                                                     */
4144/*                                                                          */
4145/*   Simulate a read capacity command to a logical drive                    */
4146/*                                                                          */
4147/****************************************************************************/
4148static int
4149ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4150{
4151        IPS_SCSI_CAPACITY cap;
4152
4153        METHOD_TRACE("ips_rdcap", 1);
4154
4155        if (scsi_bufflen(scb->scsi_cmd) < 8)
4156                return (0);
4157
4158        cap.lba =
4159            cpu_to_be32(le32_to_cpu
4160                        (ha->logical_drive_info->
4161                         drive_info[scb->target_id].sector_count) - 1);
4162        cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4163
4164        ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4165
4166        return (1);
4167}
4168
4169/****************************************************************************/
4170/*                                                                          */
4171/* Routine Name: ips_msense                                                 */
4172/*                                                                          */
4173/* Routine Description:                                                     */
4174/*                                                                          */
4175/*   Simulate a mode sense command to a logical drive                       */
4176/*                                                                          */
4177/****************************************************************************/
4178static int
4179ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4180{
4181        uint16_t heads;
4182        uint16_t sectors;
4183        uint32_t cylinders;
4184        IPS_SCSI_MODE_PAGE_DATA mdata;
4185
4186        METHOD_TRACE("ips_msense", 1);
4187
4188        if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4189            (ha->enq->ucMiscFlag & 0x8) == 0) {
4190                heads = IPS_NORM_HEADS;
4191                sectors = IPS_NORM_SECTORS;
4192        } else {
4193                heads = IPS_COMP_HEADS;
4194                sectors = IPS_COMP_SECTORS;
4195        }
4196
4197        cylinders =
4198            (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4199             1) / (heads * sectors);
4200
4201        memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4202
4203        mdata.hdr.BlockDescLength = 8;
4204
4205        switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4206        case 0x03:              /* page 3 */
4207                mdata.pdata.pg3.PageCode = 3;
4208                mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4209                mdata.hdr.DataLength =
4210                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4211                mdata.pdata.pg3.TracksPerZone = 0;
4212                mdata.pdata.pg3.AltSectorsPerZone = 0;
4213                mdata.pdata.pg3.AltTracksPerZone = 0;
4214                mdata.pdata.pg3.AltTracksPerVolume = 0;
4215                mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4216                mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4217                mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4218                mdata.pdata.pg3.TrackSkew = 0;
4219                mdata.pdata.pg3.CylinderSkew = 0;
4220                mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4221                break;
4222
4223        case 0x4:
4224                mdata.pdata.pg4.PageCode = 4;
4225                mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4226                mdata.hdr.DataLength =
4227                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4228                mdata.pdata.pg4.CylindersHigh =
4229                    cpu_to_be16((cylinders >> 8) & 0xFFFF);
4230                mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4231                mdata.pdata.pg4.Heads = heads;
4232                mdata.pdata.pg4.WritePrecompHigh = 0;
4233                mdata.pdata.pg4.WritePrecompLow = 0;
4234                mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4235                mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4236                mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4237                mdata.pdata.pg4.LandingZoneHigh = 0;
4238                mdata.pdata.pg4.LandingZoneLow = 0;
4239                mdata.pdata.pg4.flags = 0;
4240                mdata.pdata.pg4.RotationalOffset = 0;
4241                mdata.pdata.pg4.MediumRotationRate = 0;
4242                break;
4243        case 0x8:
4244                mdata.pdata.pg8.PageCode = 8;
4245                mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4246                mdata.hdr.DataLength =
4247                    3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4248                /* everything else is left set to 0 */
4249                break;
4250
4251        default:
4252                return (0);
4253        }                       /* end switch */
4254
4255        ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4256
4257        return (1);
4258}
4259
4260/****************************************************************************/
4261/*                                                                          */
4262/* Routine Name: ips_reqsen                                                 */
4263/*                                                                          */
4264/* Routine Description:                                                     */
4265/*                                                                          */
4266/*   Simulate a request sense command to a logical drive                    */
4267/*                                                                          */
4268/****************************************************************************/
4269static int
4270ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4271{
4272        IPS_SCSI_REQSEN reqsen;
4273
4274        METHOD_TRACE("ips_reqsen", 1);
4275
4276        memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4277
4278        reqsen.ResponseCode =
4279            IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4280        reqsen.AdditionalLength = 10;
4281        reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4282        reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4283
4284        ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4285
4286        return (1);
4287}
4288
4289/****************************************************************************/
4290/*                                                                          */
4291/* Routine Name: ips_free                                                   */
4292/*                                                                          */
4293/* Routine Description:                                                     */
4294/*                                                                          */
4295/*   Free any allocated space for this controller                           */
4296/*                                                                          */
4297/****************************************************************************/
4298static void
4299ips_free(ips_ha_t * ha)
4300{
4301
4302        METHOD_TRACE("ips_free", 1);
4303
4304        if (ha) {
4305                if (ha->enq) {
4306                        pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4307                                            ha->enq, ha->enq_busaddr);
4308                        ha->enq = NULL;
4309                }
4310
4311                kfree(ha->conf);
4312                ha->conf = NULL;
4313
4314                if (ha->adapt) {
4315                        pci_free_consistent(ha->pcidev,
4316                                            sizeof (IPS_ADAPTER) +
4317                                            sizeof (IPS_IO_CMD), ha->adapt,
4318                                            ha->adapt->hw_status_start);
4319                        ha->adapt = NULL;
4320                }
4321
4322                if (ha->logical_drive_info) {
4323                        pci_free_consistent(ha->pcidev,
4324                                            sizeof (IPS_LD_INFO),
4325                                            ha->logical_drive_info,
4326                                            ha->logical_drive_info_dma_addr);
4327                        ha->logical_drive_info = NULL;
4328                }
4329
4330                kfree(ha->nvram);
4331                ha->nvram = NULL;
4332
4333                kfree(ha->subsys);
4334                ha->subsys = NULL;
4335
4336                if (ha->ioctl_data) {
4337                        pci_free_consistent(ha->pcidev, ha->ioctl_len,
4338                                            ha->ioctl_data, ha->ioctl_busaddr);
4339                        ha->ioctl_data = NULL;
4340                        ha->ioctl_datasize = 0;
4341                        ha->ioctl_len = 0;
4342                }
4343                ips_deallocatescbs(ha, ha->max_cmds);
4344
4345                /* free memory mapped (if applicable) */
4346                if (ha->mem_ptr) {
4347                        iounmap(ha->ioremap_ptr);
4348                        ha->ioremap_ptr = NULL;
4349                        ha->mem_ptr = NULL;
4350                }
4351
4352                ha->mem_addr = 0;
4353
4354        }
4355}
4356
4357/****************************************************************************/
4358/*                                                                          */
4359/* Routine Name: ips_deallocatescbs                                         */
4360/*                                                                          */
4361/* Routine Description:                                                     */
4362/*                                                                          */
4363/*   Free the command blocks                                                */
4364/*                                                                          */
4365/****************************************************************************/
4366static int
4367ips_deallocatescbs(ips_ha_t * ha, int cmds)
4368{
4369        if (ha->scbs) {
4370                pci_free_consistent(ha->pcidev,
4371                                    IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
4372                                    ha->scbs->sg_list.list,
4373                                    ha->scbs->sg_busaddr);
4374                pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
4375                                    ha->scbs, ha->scbs->scb_busaddr);
4376                ha->scbs = NULL;
4377        }                       /* end if */
4378        return 1;
4379}
4380
4381/****************************************************************************/
4382/*                                                                          */
4383/* Routine Name: ips_allocatescbs                                           */
4384/*                                                                          */
4385/* Routine Description:                                                     */
4386/*                                                                          */
4387/*   Allocate the command blocks                                            */
4388/*                                                                          */
4389/****************************************************************************/
4390static int
4391ips_allocatescbs(ips_ha_t * ha)
4392{
4393        ips_scb_t *scb_p;
4394        IPS_SG_LIST ips_sg;
4395        int i;
4396        dma_addr_t command_dma, sg_dma;
4397
4398        METHOD_TRACE("ips_allocatescbs", 1);
4399
4400        /* Allocate memory for the SCBs */
4401        ha->scbs =
4402            pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
4403                                 &command_dma);
4404        if (ha->scbs == NULL)
4405                return 0;
4406        ips_sg.list =
4407            pci_alloc_consistent(ha->pcidev,
4408                                 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
4409                                 ha->max_cmds, &sg_dma);
4410        if (ips_sg.list == NULL) {
4411                pci_free_consistent(ha->pcidev,
4412                                    ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
4413                                    command_dma);
4414                return 0;
4415        }
4416
4417        memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
4418
4419        for (i = 0; i < ha->max_cmds; i++) {
4420                scb_p = &ha->scbs[i];
4421                scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
4422                /* set up S/G list */
4423                if (IPS_USE_ENH_SGLIST(ha)) {
4424                        scb_p->sg_list.enh_list =
4425                            ips_sg.enh_list + i * IPS_MAX_SG;
4426                        scb_p->sg_busaddr =
4427                            sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4428                } else {
4429                        scb_p->sg_list.std_list =
4430                            ips_sg.std_list + i * IPS_MAX_SG;
4431                        scb_p->sg_busaddr =
4432                            sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4433                }
4434
4435                /* add to the free list */
4436                if (i < ha->max_cmds - 1) {
4437                        scb_p->q_next = ha->scb_freelist;
4438                        ha->scb_freelist = scb_p;
4439                }
4440        }
4441
4442        /* success */
4443        return (1);
4444}
4445
4446/****************************************************************************/
4447/*                                                                          */
4448/* Routine Name: ips_init_scb                                               */
4449/*                                                                          */
4450/* Routine Description:                                                     */
4451/*                                                                          */
4452/*   Initialize a CCB to default values                                     */
4453/*                                                                          */
4454/****************************************************************************/
4455static void
4456ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
4457{
4458        IPS_SG_LIST sg_list;
4459        uint32_t cmd_busaddr, sg_busaddr;
4460        METHOD_TRACE("ips_init_scb", 1);
4461
4462        if (scb == NULL)
4463                return;
4464
4465        sg_list.list = scb->sg_list.list;
4466        cmd_busaddr = scb->scb_busaddr;
4467        sg_busaddr = scb->sg_busaddr;
4468        /* zero fill */
4469        memset(scb, 0, sizeof (ips_scb_t));
4470        memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
4471
4472        /* Initialize dummy command bucket */
4473        ha->dummy->op_code = 0xFF;
4474        ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
4475                                       + sizeof (IPS_ADAPTER));
4476        ha->dummy->command_id = IPS_MAX_CMDS;
4477
4478        /* set bus address of scb */
4479        scb->scb_busaddr = cmd_busaddr;
4480        scb->sg_busaddr = sg_busaddr;
4481        scb->sg_list.list = sg_list.list;
4482
4483        /* Neptune Fix */
4484        scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
4485        scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
4486                                              + sizeof (IPS_ADAPTER));
4487}
4488
4489/****************************************************************************/
4490/*                                                                          */
4491/* Routine Name: ips_get_scb                                                */
4492/*                                                                          */
4493/* Routine Description:                                                     */
4494/*                                                                          */
4495/*   Initialize a CCB to default values                                     */
4496/*                                                                          */
4497/* ASSUMED to be called from within a lock                                 */
4498/*                                                                          */
4499/****************************************************************************/
4500static ips_scb_t *
4501ips_getscb(ips_ha_t * ha)
4502{
4503        ips_scb_t *scb;
4504
4505        METHOD_TRACE("ips_getscb", 1);
4506
4507        if ((scb = ha->scb_freelist) == NULL) {
4508
4509                return (NULL);
4510        }
4511
4512        ha->scb_freelist = scb->q_next;
4513        scb->flags = 0;
4514        scb->q_next = NULL;
4515
4516        ips_init_scb(ha, scb);
4517
4518        return (scb);
4519}
4520
4521/****************************************************************************/
4522/*                                                                          */
4523/* Routine Name: ips_free_scb                                               */
4524/*                                                                          */
4525/* Routine Description:                                                     */
4526/*                                                                          */
4527/*   Return an unused CCB back to the free list                             */
4528/*                                                                          */
4529/* ASSUMED to be called from within a lock                                  */
4530/*                                                                          */
4531/****************************************************************************/
4532static void
4533ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
4534{
4535
4536        METHOD_TRACE("ips_freescb", 1);
4537        if (scb->flags & IPS_SCB_MAP_SG)
4538                scsi_dma_unmap(scb->scsi_cmd);
4539        else if (scb->flags & IPS_SCB_MAP_SINGLE)
4540                pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
4541                                 IPS_DMA_DIR(scb));
4542
4543        /* check to make sure this is not our "special" scb */
4544        if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
4545                scb->q_next = ha->scb_freelist;
4546                ha->scb_freelist = scb;
4547        }
4548}
4549
4550/****************************************************************************/
4551/*                                                                          */
4552/* Routine Name: ips_isinit_copperhead                                      */
4553/*                                                                          */
4554/* Routine Description:                                                     */
4555/*                                                                          */
4556/*   Is controller initialized ?                                            */
4557/*                                                                          */
4558/****************************************************************************/
4559static int
4560ips_isinit_copperhead(ips_ha_t * ha)
4561{
4562        uint8_t scpr;
4563        uint8_t isr;
4564
4565        METHOD_TRACE("ips_isinit_copperhead", 1);
4566
4567        isr = inb(ha->io_addr + IPS_REG_HISR);
4568        scpr = inb(ha->io_addr + IPS_REG_SCPR);
4569
4570        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4571                return (0);
4572        else
4573                return (1);
4574}
4575
4576/****************************************************************************/
4577/*                                                                          */
4578/* Routine Name: ips_isinit_copperhead_memio                                */
4579/*                                                                          */
4580/* Routine Description:                                                     */
4581/*                                                                          */
4582/*   Is controller initialized ?                                            */
4583/*                                                                          */
4584/****************************************************************************/
4585static int
4586ips_isinit_copperhead_memio(ips_ha_t * ha)
4587{
4588        uint8_t isr = 0;
4589        uint8_t scpr;
4590
4591        METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4592
4593        isr = readb(ha->mem_ptr + IPS_REG_HISR);
4594        scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
4595
4596        if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4597                return (0);
4598        else
4599                return (1);
4600}
4601
4602/****************************************************************************/
4603/*                                                                          */
4604/* Routine Name: ips_isinit_morpheus                                        */
4605/*                                                                          */
4606/* Routine Description:                                                     */
4607/*                                                                          */
4608/*   Is controller initialized ?                                            */
4609/*                                                                          */
4610/****************************************************************************/
4611static int
4612ips_isinit_morpheus(ips_ha_t * ha)
4613{
4614        uint32_t post;
4615        uint32_t bits;
4616
4617        METHOD_TRACE("ips_is_init_morpheus", 1);
4618
4619        if (ips_isintr_morpheus(ha))
4620            ips_flush_and_reset(ha);
4621
4622        post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
4623        bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4624
4625        if (post == 0)
4626                return (0);
4627        else if (bits & 0x3)
4628                return (0);
4629        else
4630                return (1);
4631}
4632
4633/****************************************************************************/
4634/*                                                                          */
4635/* Routine Name: ips_flush_and_reset                                        */
4636/*                                                                          */
4637/* Routine Description:                                                     */
4638/*                                                                          */
4639/*   Perform cleanup ( FLUSH and RESET ) when the adapter is in an unknown  */
4640/*   state ( was trying to INIT and an interrupt was already pending ) ...  */
4641/*                                                                          */
4642/****************************************************************************/
4643static void
4644ips_flush_and_reset(ips_ha_t *ha)
4645{
4646        ips_scb_t *scb;
4647        int  ret;
4648        int  time;
4649        int  done;
4650        dma_addr_t command_dma;
4651
4652        /* Create a usuable SCB */
4653        scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
4654        if (scb) {
4655            memset(scb, 0, sizeof(ips_scb_t));
4656            ips_init_scb(ha, scb);
4657            scb->scb_busaddr = command_dma;
4658
4659            scb->timeout = ips_cmd_timeout;
4660            scb->cdb[0] = IPS_CMD_FLUSH;
4661
4662            scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
4663            scb->cmd.flush_cache.command_id = IPS_MAX_CMDS;   /* Use an ID that would otherwise not exist */
4664            scb->cmd.flush_cache.state = IPS_NORM_STATE;
4665            scb->cmd.flush_cache.reserved = 0;
4666            scb->cmd.flush_cache.reserved2 = 0;
4667            scb->cmd.flush_cache.reserved3 = 0;
4668            scb->cmd.flush_cache.reserved4 = 0;
4669
4670            ret = ips_send_cmd(ha, scb);                      /* Send the Flush Command */
4671
4672            if (ret == IPS_SUCCESS) {
4673                time = 60 * IPS_ONE_SEC;                      /* Max Wait time is 60 seconds */
4674                done = 0;
4675
4676                while ((time > 0) && (!done)) {
4677                   done = ips_poll_for_flush_complete(ha);
4678                   /* This may look evil, but it's only done during extremely rare start-up conditions ! */
4679                   udelay(1000);
4680                   time--;
4681                }
4682        }
4683        }
4684
4685        /* Now RESET and INIT the adapter */
4686        (*ha->func.reset) (ha);
4687
4688        pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
4689        return;
4690}
4691
4692/****************************************************************************/
4693/*                                                                          */
4694/* Routine Name: ips_poll_for_flush_complete                                */
4695/*                                                                          */
4696/* Routine Description:                                                     */
4697/*                                                                          */
4698/*   Poll for the Flush Command issued by ips_flush_and_reset() to complete */
4699/*   All other responses are just taken off the queue and ignored           */
4700/*                                                                          */
4701/****************************************************************************/
4702static int
4703ips_poll_for_flush_complete(ips_ha_t * ha)
4704{
4705        IPS_STATUS cstatus;
4706
4707        while (TRUE) {
4708            cstatus.value = (*ha->func.statupd) (ha);
4709
4710            if (cstatus.value == 0xffffffff)      /* If No Interrupt to process */
4711                        break;
4712
4713            /* Success is when we see the Flush Command ID */
4714            if (cstatus.fields.command_id == IPS_MAX_CMDS)
4715                return 1;
4716         }
4717
4718        return 0;
4719}
4720
4721/****************************************************************************/
4722/*                                                                          */
4723/* Routine Name: ips_enable_int_copperhead                                  */
4724/*                                                                          */
4725/* Routine Description:                                                     */
4726/*   Turn on interrupts                                                     */
4727/*                                                                          */
4728/****************************************************************************/
4729static void
4730ips_enable_int_copperhead(ips_ha_t * ha)
4731{
4732        METHOD_TRACE("ips_enable_int_copperhead", 1);
4733
4734        outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
4735        inb(ha->io_addr + IPS_REG_HISR);        /*Ensure PCI Posting Completes*/
4736}
4737
4738/****************************************************************************/
4739/*                                                                          */
4740/* Routine Name: ips_enable_int_copperhead_memio                            */
4741/*                                                                          */
4742/* Routine Description:                                                     */
4743/*   Turn on interrupts                                                     */
4744/*                                                                          */
4745/****************************************************************************/
4746static void
4747ips_enable_int_copperhead_memio(ips_ha_t * ha)
4748{
4749        METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4750
4751        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4752        readb(ha->mem_ptr + IPS_REG_HISR);      /*Ensure PCI Posting Completes*/
4753}
4754
4755/****************************************************************************/
4756/*                                                                          */
4757/* Routine Name: ips_enable_int_morpheus                                    */
4758/*                                                                          */
4759/* Routine Description:                                                     */
4760/*   Turn on interrupts                                                     */
4761/*                                                                          */
4762/****************************************************************************/
4763static void
4764ips_enable_int_morpheus(ips_ha_t * ha)
4765{
4766        uint32_t Oimr;
4767
4768        METHOD_TRACE("ips_enable_int_morpheus", 1);
4769
4770        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4771        Oimr &= ~0x08;
4772        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
4773        readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/
4774}
4775
4776/****************************************************************************/
4777/*                                                                          */
4778/* Routine Name: ips_init_copperhead                                        */
4779/*                                                                          */
4780/* Routine Description:                                                     */
4781/*                                                                          */
4782/*   Initialize a copperhead controller                                     */
4783/*                                                                          */
4784/****************************************************************************/
4785static int
4786ips_init_copperhead(ips_ha_t * ha)
4787{
4788        uint8_t Isr;
4789        uint8_t Cbsp;
4790        uint8_t PostByte[IPS_MAX_POST_BYTES];
4791        uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4792        int i, j;
4793
4794        METHOD_TRACE("ips_init_copperhead", 1);
4795
4796        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4797                for (j = 0; j < 45; j++) {
4798                        Isr = inb(ha->io_addr + IPS_REG_HISR);
4799                        if (Isr & IPS_BIT_GHI)
4800                                break;
4801
4802                        /* Delay for 1 Second */
4803                        MDELAY(IPS_ONE_SEC);
4804                }
4805
4806                if (j >= 45)
4807                        /* error occurred */
4808                        return (0);
4809
4810                PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4811                outb(Isr, ha->io_addr + IPS_REG_HISR);
4812        }
4813
4814        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4815                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4816                           "reset controller fails (post status %x %x).\n",
4817                           PostByte[0], PostByte[1]);
4818
4819                return (0);
4820        }
4821
4822        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4823                for (j = 0; j < 240; j++) {
4824                        Isr = inb(ha->io_addr + IPS_REG_HISR);
4825                        if (Isr & IPS_BIT_GHI)
4826                                break;
4827
4828                        /* Delay for 1 Second */
4829                        MDELAY(IPS_ONE_SEC);
4830                }
4831
4832                if (j >= 240)
4833                        /* error occurred */
4834                        return (0);
4835
4836                ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4837                outb(Isr, ha->io_addr + IPS_REG_HISR);
4838        }
4839
4840        for (i = 0; i < 240; i++) {
4841                Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
4842
4843                if ((Cbsp & IPS_BIT_OP) == 0)
4844                        break;
4845
4846                /* Delay for 1 Second */
4847                MDELAY(IPS_ONE_SEC);
4848        }
4849
4850        if (i >= 240)
4851                /* reset failed */
4852                return (0);
4853
4854        /* setup CCCR */
4855        outl(0x1010, ha->io_addr + IPS_REG_CCCR);
4856
4857        /* Enable busmastering */
4858        outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
4859
4860        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4861                /* fix for anaconda64 */
4862                outl(0, ha->io_addr + IPS_REG_NDAE);
4863
4864        /* Enable interrupts */
4865        outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
4866
4867        return (1);
4868}
4869
4870/****************************************************************************/
4871/*                                                                          */
4872/* Routine Name: ips_init_copperhead_memio                                  */
4873/*                                                                          */
4874/* Routine Description:                                                     */
4875/*                                                                          */
4876/*   Initialize a copperhead controller with memory mapped I/O              */
4877/*                                                                          */
4878/****************************************************************************/
4879static int
4880ips_init_copperhead_memio(ips_ha_t * ha)
4881{
4882        uint8_t Isr = 0;
4883        uint8_t Cbsp;
4884        uint8_t PostByte[IPS_MAX_POST_BYTES];
4885        uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4886        int i, j;
4887
4888        METHOD_TRACE("ips_init_copperhead_memio", 1);
4889
4890        for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4891                for (j = 0; j < 45; j++) {
4892                        Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4893                        if (Isr & IPS_BIT_GHI)
4894                                break;
4895
4896                        /* Delay for 1 Second */
4897                        MDELAY(IPS_ONE_SEC);
4898                }
4899
4900                if (j >= 45)
4901                        /* error occurred */
4902                        return (0);
4903
4904                PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4905                writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4906        }
4907
4908        if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4909                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4910                           "reset controller fails (post status %x %x).\n",
4911                           PostByte[0], PostByte[1]);
4912
4913                return (0);
4914        }
4915
4916        for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4917                for (j = 0; j < 240; j++) {
4918                        Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4919                        if (Isr & IPS_BIT_GHI)
4920                                break;
4921
4922                        /* Delay for 1 Second */
4923                        MDELAY(IPS_ONE_SEC);
4924                }
4925
4926                if (j >= 240)
4927                        /* error occurred */
4928                        return (0);
4929
4930                ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4931                writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4932        }
4933
4934        for (i = 0; i < 240; i++) {
4935                Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
4936
4937                if ((Cbsp & IPS_BIT_OP) == 0)
4938                        break;
4939
4940                /* Delay for 1 Second */
4941                MDELAY(IPS_ONE_SEC);
4942        }
4943
4944        if (i >= 240)
4945                /* error occurred */
4946                return (0);
4947
4948        /* setup CCCR */
4949        writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
4950
4951        /* Enable busmastering */
4952        writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
4953
4954        if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4955                /* fix for anaconda64 */
4956                writel(0, ha->mem_ptr + IPS_REG_NDAE);
4957
4958        /* Enable interrupts */
4959        writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4960
4961        /* if we get here then everything went OK */
4962        return (1);
4963}
4964
4965/****************************************************************************/
4966/*                                                                          */
4967/* Routine Name: ips_init_morpheus                                          */
4968/*                                                                          */
4969/* Routine Description:                                                     */
4970/*                                                                          */
4971/*   Initialize a morpheus controller                                       */
4972/*                                                                          */
4973/****************************************************************************/
4974static int
4975ips_init_morpheus(ips_ha_t * ha)
4976{
4977        uint32_t Post;
4978        uint32_t Config;
4979        uint32_t Isr;
4980        uint32_t Oimr;
4981        int i;
4982
4983        METHOD_TRACE("ips_init_morpheus", 1);
4984
4985        /* Wait up to 45 secs for Post */
4986        for (i = 0; i < 45; i++) {
4987                Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4988
4989                if (Isr & IPS_BIT_I960_MSG0I)
4990                        break;
4991
4992                /* Delay for 1 Second */
4993                MDELAY(IPS_ONE_SEC);
4994        }
4995
4996        if (i >= 45) {
4997                /* error occurred */
4998                IPS_PRINTK(KERN_WARNING, ha->pcidev,
4999                           "timeout waiting for post.\n");
5000
5001                return (0);
5002        }
5003
5004        Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5005
5006        if (Post == 0x4F00) {   /* If Flashing the Battery PIC         */
5007                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5008                           "Flashing Battery PIC, Please wait ...\n");
5009
5010                /* Clear the interrupt bit */
5011                Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5012                writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5013
5014                for (i = 0; i < 120; i++) {     /*    Wait Up to 2 Min. for Completion */
5015                        Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5016                        if (Post != 0x4F00)
5017                                break;
5018                        /* Delay for 1 Second */
5019                        MDELAY(IPS_ONE_SEC);
5020                }
5021
5022                if (i >= 120) {
5023                        IPS_PRINTK(KERN_WARNING, ha->pcidev,
5024                                   "timeout waiting for Battery PIC Flash\n");
5025                        return (0);
5026                }
5027
5028        }
5029
5030        /* Clear the interrupt bit */
5031        Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5032        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5033
5034        if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5035                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5036                           "reset controller fails (post status %x).\n", Post);
5037
5038                return (0);
5039        }
5040
5041        /* Wait up to 240 secs for config bytes */
5042        for (i = 0; i < 240; i++) {
5043                Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5044
5045                if (Isr & IPS_BIT_I960_MSG1I)
5046                        break;
5047
5048                /* Delay for 1 Second */
5049                MDELAY(IPS_ONE_SEC);
5050        }
5051
5052        if (i >= 240) {
5053                /* error occurred */
5054                IPS_PRINTK(KERN_WARNING, ha->pcidev,
5055                           "timeout waiting for config.\n");
5056
5057                return (0);
5058        }
5059
5060        Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5061
5062        /* Clear interrupt bit */
5063        Isr = (uint32_t) IPS_BIT_I960_MSG1I;
5064        writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5065
5066        /* Turn on the interrupts */
5067        Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5068        Oimr &= ~0x8;
5069        writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5070
5071        /* if we get here then everything went OK */
5072
5073        /* Since we did a RESET, an EraseStripeLock may be needed */
5074        if (Post == 0xEF10) {
5075                if ((Config == 0x000F) || (Config == 0x0009))
5076                        ha->requires_esl = 1;
5077        }
5078
5079        return (1);
5080}
5081
5082/****************************************************************************/
5083/*                                                                          */
5084/* Routine Name: ips_reset_copperhead                                       */
5085/*                                                                          */
5086/* Routine Description:                                                     */
5087/*                                                                          */
5088/*   Reset the controller                                                   */
5089/*                                                                          */
5090/****************************************************************************/
5091static int
5092ips_reset_copperhead(ips_ha_t * ha)
5093{
5094        int reset_counter;
5095
5096        METHOD_TRACE("ips_reset_copperhead", 1);
5097
5098        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5099                  ips_name, ha->host_num, ha->io_addr, ha->pcidev->irq);
5100
5101        reset_counter = 0;
5102
5103        while (reset_counter < 2) {
5104                reset_counter++;
5105
5106                outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5107
5108                /* Delay for 1 Second */
5109                MDELAY(IPS_ONE_SEC);
5110
5111                outb(0, ha->io_addr + IPS_REG_SCPR);
5112
5113                /* Delay for 1 Second */
5114                MDELAY(IPS_ONE_SEC);
5115
5116                if ((*ha->func.init) (ha))
5117                        break;
5118                else if (reset_counter >= 2) {
5119
5120                        return (0);
5121                }
5122        }
5123
5124        return (1);
5125}
5126
5127/****************************************************************************/
5128/*                                                                          */
5129/* Routine Name: ips_reset_copperhead_memio                                 */
5130/*                                                                          */
5131/* Routine Description:                                                     */
5132/*                                                                          */
5133/*   Reset the controller                                                   */
5134/*                                                                          */
5135/****************************************************************************/
5136static int
5137ips_reset_copperhead_memio(ips_ha_t * ha)
5138{
5139        int reset_counter;
5140
5141        METHOD_TRACE("ips_reset_copperhead_memio", 1);
5142
5143        DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5144                  ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5145
5146        reset_counter = 0;
5147
5148        while (reset_counter < 2) {
5149                reset_counter++;
5150
5151                writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
5152
5153                /* Delay for 1 Second */
5154                MDELAY(IPS_ONE_SEC);
5155
5156                writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5157
5158                /* Delay for 1 Second */
5159                MDELAY(IPS_ONE_SEC);
5160
5161                if ((*ha->func.init) (ha))
5162                        break;
5163                else if (reset_counter >= 2) {
5164
5165                        return (0);
5166                }
5167        }
5168
5169        return (1);
5170}
5171
5172/****************************************************************************/
5173/*                                                                          */
5174/* Routine Name: ips_reset_morpheus                                         */
5175/*                                                                          */
5176/* Routine Description:                                                     */
5177/*                                                                          */
5178/*   Reset the controller                                                   */
5179/*                                                                          */
5180/****************************************************************************/
5181static int
5182ips_reset_morpheus(ips_ha_t * ha)
5183{
5184        int reset_counter;
5185        uint8_t junk;
5186
5187        METHOD_TRACE("ips_reset_morpheus", 1);
5188
5189        DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5190                  ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5191
5192        reset_counter = 0;
5193
5194        while (reset_counter < 2) {
5195                reset_counter++;
5196
5197                writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
5198
5199                /* Delay for 5 Seconds */
5200                MDELAY(5 * IPS_ONE_SEC);
5201
5202                /* Do a PCI config read to wait for adapter */
5203                pci_read_config_byte(ha->pcidev, 4, &junk);
5204
5205                if ((*ha->func.init) (ha))
5206                        break;
5207                else if (reset_counter >= 2) {
5208
5209                        return (0);
5210                }
5211        }
5212
5213        return (1);
5214}
5215
5216/****************************************************************************/
5217/*                                                                          */
5218/* Routine Name: ips_statinit                                               */
5219/*                                                                          */
5220/* Routine Description:                                                     */
5221/*                                                                          */
5222/*   Initialize the status queues on the controller                         */
5223/*                                                                          */
5224/****************************************************************************/
5225static void
5226ips_statinit(ips_ha_t * ha)
5227{
5228        uint32_t phys_status_start;
5229
5230        METHOD_TRACE("ips_statinit", 1);