linux/drivers/scsi/hpsa.h
<<
>>
Prefs
   1/*
   2 *    Disk Array driver for HP Smart Array SAS controllers
   3 *    Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
   4 *
   5 *    This program is free software; you can redistribute it and/or modify
   6 *    it under the terms of the GNU General Public License as published by
   7 *    the Free Software Foundation; version 2 of the License.
   8 *
   9 *    This program is distributed in the hope that it will be useful,
  10 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 *    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  12 *    NON INFRINGEMENT.  See the GNU General Public License for more details.
  13 *
  14 *    You should have received a copy of the GNU General Public License
  15 *    along with this program; if not, write to the Free Software
  16 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17 *
  18 *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  19 *
  20 */
  21#ifndef HPSA_H
  22#define HPSA_H
  23
  24#include <scsi/scsicam.h>
  25
  26#define IO_OK           0
  27#define IO_ERROR        1
  28
  29struct ctlr_info;
  30
  31struct access_method {
  32        void (*submit_command)(struct ctlr_info *h,
  33                struct CommandList *c);
  34        void (*set_intr_mask)(struct ctlr_info *h, unsigned long val);
  35        unsigned long (*fifo_full)(struct ctlr_info *h);
  36        bool (*intr_pending)(struct ctlr_info *h);
  37        unsigned long (*command_completed)(struct ctlr_info *h);
  38};
  39
  40struct hpsa_scsi_dev_t {
  41        int devtype;
  42        int bus, target, lun;           /* as presented to the OS */
  43        unsigned char scsi3addr[8];     /* as presented to the HW */
  44#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
  45        unsigned char device_id[16];    /* from inquiry pg. 0x83 */
  46        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
  47        unsigned char model[16];        /* bytes 16-31 of inquiry data */
  48        unsigned char raid_level;       /* from inquiry page 0xC1 */
  49};
  50
  51struct ctlr_info {
  52        int     ctlr;
  53        char    devname[8];
  54        char    *product_name;
  55        struct pci_dev *pdev;
  56        u32     board_id;
  57        void __iomem *vaddr;
  58        unsigned long paddr;
  59        int     nr_cmds; /* Number of commands allowed on this controller */
  60        struct CfgTable __iomem *cfgtable;
  61        int     max_sg_entries;
  62        int     interrupts_enabled;
  63        int     major;
  64        int     max_commands;
  65        int     commands_outstanding;
  66        int     max_outstanding; /* Debug */
  67        int     usage_count;  /* number of opens all all minor devices */
  68#       define PERF_MODE_INT    0
  69#       define DOORBELL_INT     1
  70#       define SIMPLE_MODE_INT  2
  71#       define MEMQ_MODE_INT    3
  72        unsigned int intr[4];
  73        unsigned int msix_vector;
  74        unsigned int msi_vector;
  75        int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
  76        struct access_method access;
  77
  78        /* queue and queue Info */
  79        struct list_head reqQ;
  80        struct list_head cmpQ;
  81        unsigned int Qdepth;
  82        unsigned int maxQsinceinit;
  83        unsigned int maxSG;
  84        spinlock_t lock;
  85        int maxsgentries;
  86        u8 max_cmd_sg_entries;
  87        int chainsize;
  88        struct SGDescriptor **cmd_sg_list;
  89
  90        /* pointers to command and error info pool */
  91        struct CommandList      *cmd_pool;
  92        dma_addr_t              cmd_pool_dhandle;
  93        struct ErrorInfo        *errinfo_pool;
  94        dma_addr_t              errinfo_pool_dhandle;
  95        unsigned long           *cmd_pool_bits;
  96        int                     nr_allocs;
  97        int                     nr_frees;
  98        int                     scan_finished;
  99        spinlock_t              scan_lock;
 100        wait_queue_head_t       scan_wait_queue;
 101
 102        struct Scsi_Host *scsi_host;
 103        spinlock_t devlock; /* to protect hba[ctlr]->dev[];  */
 104        int ndevices; /* number of used elements in .dev[] array. */
 105        struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES];
 106        /*
 107         * Performant mode tables.
 108         */
 109        u32 trans_support;
 110        u32 trans_offset;
 111        struct TransTable_struct *transtable;
 112        unsigned long transMethod;
 113
 114        /*
 115         * Performant mode completion buffer
 116         */
 117        u64 *reply_pool;
 118        dma_addr_t reply_pool_dhandle;
 119        u64 *reply_pool_head;
 120        size_t reply_pool_size;
 121        unsigned char reply_pool_wraparound;
 122        u32 *blockFetchTable;
 123        unsigned char *hba_inquiry_data;
 124        u64 last_intr_timestamp;
 125        u32 last_heartbeat;
 126        u64 last_heartbeat_timestamp;
 127        u32 lockup_detected;
 128        struct list_head lockup_list;
 129};
 130#define HPSA_ABORT_MSG 0
 131#define HPSA_DEVICE_RESET_MSG 1
 132#define HPSA_RESET_TYPE_CONTROLLER 0x00
 133#define HPSA_RESET_TYPE_BUS 0x01
 134#define HPSA_RESET_TYPE_TARGET 0x03
 135#define HPSA_RESET_TYPE_LUN 0x04
 136#define HPSA_MSG_SEND_RETRY_LIMIT 10
 137#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
 138
 139/* Maximum time in seconds driver will wait for command completions
 140 * when polling before giving up.
 141 */
 142#define HPSA_MAX_POLL_TIME_SECS (20)
 143
 144/* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines
 145 * how many times to retry TEST UNIT READY on a device
 146 * while waiting for it to become ready before giving up.
 147 * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval
 148 * between sending TURs while waiting for a device
 149 * to become ready.
 150 */
 151#define HPSA_TUR_RETRY_LIMIT (20)
 152#define HPSA_MAX_WAIT_INTERVAL_SECS (30)
 153
 154/* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board
 155 * to become ready, in seconds, before giving up on it.
 156 * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait
 157 * between polling the board to see if it is ready, in
 158 * milliseconds.  HPSA_BOARD_READY_POLL_INTERVAL and
 159 * HPSA_BOARD_READY_ITERATIONS are derived from those.
 160 */
 161#define HPSA_BOARD_READY_WAIT_SECS (120)
 162#define HPSA_BOARD_NOT_READY_WAIT_SECS (100)
 163#define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100)
 164#define HPSA_BOARD_READY_POLL_INTERVAL \
 165        ((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000)
 166#define HPSA_BOARD_READY_ITERATIONS \
 167        ((HPSA_BOARD_READY_WAIT_SECS * 1000) / \
 168                HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
 169#define HPSA_BOARD_NOT_READY_ITERATIONS \
 170        ((HPSA_BOARD_NOT_READY_WAIT_SECS * 1000) / \
 171                HPSA_BOARD_READY_POLL_INTERVAL_MSECS)
 172#define HPSA_POST_RESET_PAUSE_MSECS (3000)
 173#define HPSA_POST_RESET_NOOP_RETRIES (12)
 174
 175/*  Defining the diffent access_menthods */
 176/*
 177 * Memory mapped FIFO interface (SMART 53xx cards)
 178 */
 179#define SA5_DOORBELL    0x20
 180#define SA5_REQUEST_PORT_OFFSET 0x40
 181#define SA5_REPLY_INTR_MASK_OFFSET      0x34
 182#define SA5_REPLY_PORT_OFFSET           0x44
 183#define SA5_INTR_STATUS         0x30
 184#define SA5_SCRATCHPAD_OFFSET   0xB0
 185
 186#define SA5_CTCFG_OFFSET        0xB4
 187#define SA5_CTMEM_OFFSET        0xB8
 188
 189#define SA5_INTR_OFF            0x08
 190#define SA5B_INTR_OFF           0x04
 191#define SA5_INTR_PENDING        0x08
 192#define SA5B_INTR_PENDING       0x04
 193#define FIFO_EMPTY              0xffffffff
 194#define HPSA_FIRMWARE_READY     0xffff0000 /* value in scratchpad register */
 195
 196#define HPSA_ERROR_BIT          0x02
 197
 198/* Performant mode flags */
 199#define SA5_PERF_INTR_PENDING   0x04
 200#define SA5_PERF_INTR_OFF       0x05
 201#define SA5_OUTDB_STATUS_PERF_BIT       0x01
 202#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
 203#define SA5_OUTDB_CLEAR         0xA0
 204#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
 205#define SA5_OUTDB_STATUS        0x9C
 206
 207
 208#define HPSA_INTR_ON    1
 209#define HPSA_INTR_OFF   0
 210/*
 211        Send the command to the hardware
 212*/
 213static void SA5_submit_command(struct ctlr_info *h,
 214        struct CommandList *c)
 215{
 216        dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
 217                c->Header.Tag.lower);
 218        writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
 219        (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
 220        h->commands_outstanding++;
 221        if (h->commands_outstanding > h->max_outstanding)
 222                h->max_outstanding = h->commands_outstanding;
 223}
 224
 225/*
 226 *  This card is the opposite of the other cards.
 227 *   0 turns interrupts on...
 228 *   0x08 turns them off...
 229 */
 230static void SA5_intr_mask(struct ctlr_info *h, unsigned long val)
 231{
 232        if (val) { /* Turn interrupts on */
 233                h->interrupts_enabled = 1;
 234                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 235                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 236        } else { /* Turn them off */
 237                h->interrupts_enabled = 0;
 238                writel(SA5_INTR_OFF,
 239                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 240                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 241        }
 242}
 243
 244static void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val)
 245{
 246        if (val) { /* turn on interrupts */
 247                h->interrupts_enabled = 1;
 248                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 249                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 250        } else {
 251                h->interrupts_enabled = 0;
 252                writel(SA5_PERF_INTR_OFF,
 253                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 254                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 255        }
 256}
 257
 258static unsigned long SA5_performant_completed(struct ctlr_info *h)
 259{
 260        unsigned long register_value = FIFO_EMPTY;
 261
 262        /* flush the controller write of the reply queue by reading
 263         * outbound doorbell status register.
 264         */
 265        register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 266        /* msi auto clears the interrupt pending bit. */
 267        if (!(h->msi_vector || h->msix_vector)) {
 268                writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR);
 269                /* Do a read in order to flush the write to the controller
 270                 * (as per spec.)
 271                 */
 272                register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 273        }
 274
 275        if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
 276                register_value = *(h->reply_pool_head);
 277                (h->reply_pool_head)++;
 278                h->commands_outstanding--;
 279        } else {
 280                register_value = FIFO_EMPTY;
 281        }
 282        /* Check for wraparound */
 283        if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
 284                h->reply_pool_head = h->reply_pool;
 285                h->reply_pool_wraparound ^= 1;
 286        }
 287
 288        return register_value;
 289}
 290
 291/*
 292 *  Returns true if fifo is full.
 293 *
 294 */
 295static unsigned long SA5_fifo_full(struct ctlr_info *h)
 296{
 297        if (h->commands_outstanding >= h->max_commands)
 298                return 1;
 299        else
 300                return 0;
 301
 302}
 303/*
 304 *   returns value read from hardware.
 305 *     returns FIFO_EMPTY if there is nothing to read
 306 */
 307static unsigned long SA5_completed(struct ctlr_info *h)
 308{
 309        unsigned long register_value
 310                = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
 311
 312        if (register_value != FIFO_EMPTY)
 313                h->commands_outstanding--;
 314
 315#ifdef HPSA_DEBUG
 316        if (register_value != FIFO_EMPTY)
 317                dev_dbg(&h->pdev->dev, "Read %lx back from board\n",
 318                        register_value);
 319        else
 320                dev_dbg(&h->pdev->dev, "hpsa: FIFO Empty read\n");
 321#endif
 322
 323        return register_value;
 324}
 325/*
 326 *      Returns true if an interrupt is pending..
 327 */
 328static bool SA5_intr_pending(struct ctlr_info *h)
 329{
 330        unsigned long register_value  =
 331                readl(h->vaddr + SA5_INTR_STATUS);
 332        dev_dbg(&h->pdev->dev, "intr_pending %lx\n", register_value);
 333        return register_value & SA5_INTR_PENDING;
 334}
 335
 336static bool SA5_performant_intr_pending(struct ctlr_info *h)
 337{
 338        unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
 339
 340        if (!register_value)
 341                return false;
 342
 343        if (h->msi_vector || h->msix_vector)
 344                return true;
 345
 346        /* Read outbound doorbell to flush */
 347        register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 348        return register_value & SA5_OUTDB_STATUS_PERF_BIT;
 349}
 350
 351static struct access_method SA5_access = {
 352        SA5_submit_command,
 353        SA5_intr_mask,
 354        SA5_fifo_full,
 355        SA5_intr_pending,
 356        SA5_completed,
 357};
 358
 359static struct access_method SA5_performant_access = {
 360        SA5_submit_command,
 361        SA5_performant_intr_mask,
 362        SA5_fifo_full,
 363        SA5_performant_intr_pending,
 364        SA5_performant_completed,
 365};
 366
 367struct board_type {
 368        u32     board_id;
 369        char    *product_name;
 370        struct access_method *access;
 371};
 372
 373#endif /* HPSA_H */
 374
 375
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.