linux/drivers/block/cciss.h
<<
>>
Prefs
   1#ifndef CCISS_H
   2#define CCISS_H
   3
   4#include <linux/genhd.h>
   5#include <linux/mutex.h>
   6
   7#include "cciss_cmd.h"
   8
   9
  10#define NWD_SHIFT       4
  11#define MAX_PART        (1 << NWD_SHIFT)
  12
  13#define IO_OK           0
  14#define IO_ERROR        1
  15#define IO_NEEDS_RETRY  3
  16
  17#define VENDOR_LEN      8
  18#define MODEL_LEN       16
  19#define REV_LEN         4
  20
  21struct ctlr_info;
  22typedef struct ctlr_info ctlr_info_t;
  23
  24struct access_method {
  25        void (*submit_command)(ctlr_info_t *h, CommandList_struct *c);
  26        void (*set_intr_mask)(ctlr_info_t *h, unsigned long val);
  27        unsigned long (*fifo_full)(ctlr_info_t *h);
  28        bool (*intr_pending)(ctlr_info_t *h);
  29        unsigned long (*command_completed)(ctlr_info_t *h);
  30};
  31typedef struct _drive_info_struct
  32{
  33        unsigned char LunID[8];
  34        int     usage_count;
  35        struct request_queue *queue;
  36        sector_t nr_blocks;
  37        int     block_size;
  38        int     heads;
  39        int     sectors;
  40        int     cylinders;
  41        int     raid_level; /* set to -1 to indicate that
  42                             * the drive is not in use/configured
  43                             */
  44        int     busy_configuring; /* This is set when a drive is being removed
  45                                   * to prevent it from being opened or it's
  46                                   * queue from being started.
  47                                   */
  48        struct  device dev;
  49        __u8 serial_no[16]; /* from inquiry page 0x83,
  50                             * not necc. null terminated.
  51                             */
  52        char vendor[VENDOR_LEN + 1]; /* SCSI vendor string */
  53        char model[MODEL_LEN + 1];   /* SCSI model string */
  54        char rev[REV_LEN + 1];       /* SCSI revision string */
  55        char device_initialized;     /* indicates whether dev is initialized */
  56} drive_info_struct;
  57
  58struct ctlr_info
  59{
  60        int     ctlr;
  61        char    devname[8];
  62        char    *product_name;
  63        char    firm_ver[4]; /* Firmware version */
  64        struct pci_dev *pdev;
  65        __u32   board_id;
  66        void __iomem *vaddr;
  67        unsigned long paddr;
  68        int     nr_cmds; /* Number of commands allowed on this controller */
  69        CfgTable_struct __iomem *cfgtable;
  70        int     interrupts_enabled;
  71        int     major;
  72        int     max_commands;
  73        int     commands_outstanding;
  74        int     max_outstanding; /* Debug */ 
  75        int     num_luns;
  76        int     highest_lun;
  77        int     usage_count;  /* number of opens all all minor devices */
  78        /* Need space for temp sg list
  79         * number of scatter/gathers supported
  80         * number of scatter/gathers in chained block
  81         */
  82        struct  scatterlist **scatter_list;
  83        int     maxsgentries;
  84        int     chainsize;
  85        int     max_cmd_sgentries;
  86        SGDescriptor_struct **cmd_sg_list;
  87
  88#       define PERF_MODE_INT    0
  89#       define DOORBELL_INT     1
  90#       define SIMPLE_MODE_INT  2
  91#       define MEMQ_MODE_INT    3
  92        unsigned int intr[4];
  93        int     intr_mode;
  94        int     cciss_max_sectors;
  95        BYTE    cciss_read;
  96        BYTE    cciss_write;
  97        BYTE    cciss_read_capacity;
  98
  99        /* information about each logical volume */
 100        drive_info_struct *drv[CISS_MAX_LUN];
 101
 102        struct access_method access;
 103
 104        /* queue and queue Info */ 
 105        struct list_head reqQ;
 106        struct list_head cmpQ;
 107        unsigned int Qdepth;
 108        unsigned int maxQsinceinit;
 109        unsigned int maxSG;
 110        spinlock_t lock;
 111
 112        /* pointers to command and error info pool */
 113        CommandList_struct      *cmd_pool;
 114        dma_addr_t              cmd_pool_dhandle; 
 115        ErrorInfo_struct        *errinfo_pool;
 116        dma_addr_t              errinfo_pool_dhandle; 
 117        unsigned long           *cmd_pool_bits;
 118        int                     nr_allocs;
 119        int                     nr_frees; 
 120        int                     busy_configuring;
 121        int                     busy_initializing;
 122        int                     busy_scanning;
 123        struct mutex            busy_shutting_down;
 124
 125        /* This element holds the zero based queue number of the last
 126         * queue to be started.  It is used for fairness.
 127        */
 128        int                     next_to_run;
 129
 130        /* Disk structures we need to pass back */
 131        struct gendisk   *gendisk[CISS_MAX_LUN];
 132#ifdef CONFIG_CISS_SCSI_TAPE
 133        struct cciss_scsi_adapter_data_t *scsi_ctlr;
 134#endif
 135        unsigned char alive;
 136        struct list_head scan_list;
 137        struct completion scan_wait;
 138        struct device dev;
 139        /*
 140         * Performant mode tables.
 141         */
 142        u32 trans_support;
 143        u32 trans_offset;
 144        struct TransTable_struct *transtable;
 145        unsigned long transMethod;
 146
 147        /*
 148         * Performant mode completion buffer
 149         */
 150        u64 *reply_pool;
 151        dma_addr_t reply_pool_dhandle;
 152        u64 *reply_pool_head;
 153        size_t reply_pool_size;
 154        unsigned char reply_pool_wraparound;
 155        u32 *blockFetchTable;
 156};
 157
 158/*  Defining the diffent access_methods
 159 *
 160 * Memory mapped FIFO interface (SMART 53xx cards)
 161 */
 162#define SA5_DOORBELL    0x20
 163#define SA5_REQUEST_PORT_OFFSET 0x40
 164#define SA5_REPLY_INTR_MASK_OFFSET      0x34
 165#define SA5_REPLY_PORT_OFFSET           0x44
 166#define SA5_INTR_STATUS         0x30
 167#define SA5_SCRATCHPAD_OFFSET   0xB0
 168
 169#define SA5_CTCFG_OFFSET        0xB4
 170#define SA5_CTMEM_OFFSET        0xB8
 171
 172#define SA5_INTR_OFF            0x08
 173#define SA5B_INTR_OFF           0x04
 174#define SA5_INTR_PENDING        0x08
 175#define SA5B_INTR_PENDING       0x04
 176#define FIFO_EMPTY              0xffffffff      
 177#define CCISS_FIRMWARE_READY    0xffff0000 /* value in scratchpad register */
 178/* Perf. mode flags */
 179#define SA5_PERF_INTR_PENDING   0x04
 180#define SA5_PERF_INTR_OFF       0x05
 181#define SA5_OUTDB_STATUS_PERF_BIT       0x01
 182#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
 183#define SA5_OUTDB_CLEAR         0xA0
 184#define SA5_OUTDB_CLEAR_PERF_BIT        0x01
 185#define SA5_OUTDB_STATUS        0x9C
 186
 187
 188#define  CISS_ERROR_BIT         0x02
 189
 190#define CCISS_INTR_ON   1 
 191#define CCISS_INTR_OFF  0
 192
 193
 194/* CCISS_BOARD_READY_WAIT_SECS is how long to wait for a board
 195 * to become ready, in seconds, before giving up on it.
 196 * CCISS_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait
 197 * between polling the board to see if it is ready, in
 198 * milliseconds.  CCISS_BOARD_READY_ITERATIONS is derived
 199 * the above.
 200 */
 201#define CCISS_BOARD_READY_WAIT_SECS (120)
 202#define CCISS_BOARD_NOT_READY_WAIT_SECS (100)
 203#define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100)
 204#define CCISS_BOARD_READY_ITERATIONS \
 205        ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \
 206                CCISS_BOARD_READY_POLL_INTERVAL_MSECS)
 207#define CCISS_BOARD_NOT_READY_ITERATIONS \
 208        ((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \
 209                CCISS_BOARD_READY_POLL_INTERVAL_MSECS)
 210#define CCISS_POST_RESET_PAUSE_MSECS (3000)
 211#define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (4000)
 212#define CCISS_POST_RESET_NOOP_RETRIES (12)
 213#define CCISS_POST_RESET_NOOP_TIMEOUT_MSECS (10000)
 214
 215/* 
 216        Send the command to the hardware 
 217*/
 218static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) 
 219{
 220#ifdef CCISS_DEBUG
 221        printk(KERN_WARNING "cciss%d: Sending %08x - down to controller\n",
 222                        h->ctlr, c->busaddr);
 223#endif /* CCISS_DEBUG */
 224         writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
 225        readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
 226         h->commands_outstanding++;
 227         if ( h->commands_outstanding > h->max_outstanding)
 228                h->max_outstanding = h->commands_outstanding;
 229}
 230
 231/*  
 232 *  This card is the opposite of the other cards.  
 233 *   0 turns interrupts on... 
 234 *   0x08 turns them off... 
 235 */
 236static void SA5_intr_mask(ctlr_info_t *h, unsigned long val)
 237{
 238        if (val) 
 239        { /* Turn interrupts on */
 240                h->interrupts_enabled = 1;
 241                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 242                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 243        } else /* Turn them off */
 244        {
 245                h->interrupts_enabled = 0;
 246                writel( SA5_INTR_OFF, 
 247                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 248                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 249        }
 250}
 251/*
 252 *  This card is the opposite of the other cards.
 253 *   0 turns interrupts on...
 254 *   0x04 turns them off...
 255 */
 256static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val)
 257{
 258        if (val)
 259        { /* Turn interrupts on */
 260                h->interrupts_enabled = 1;
 261                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 262                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 263        } else /* Turn them off */
 264        {
 265                h->interrupts_enabled = 0;
 266                writel( SA5B_INTR_OFF,
 267                        h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 268                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 269        }
 270}
 271
 272/* Performant mode intr_mask */
 273static void SA5_performant_intr_mask(ctlr_info_t *h, unsigned long val)
 274{
 275        if (val) { /* turn on interrupts */
 276                h->interrupts_enabled = 1;
 277                writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 278                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 279        } else {
 280                h->interrupts_enabled = 0;
 281                writel(SA5_PERF_INTR_OFF,
 282                                h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 283                (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 284        }
 285}
 286
 287/*
 288 *  Returns true if fifo is full.  
 289 * 
 290 */ 
 291static unsigned long SA5_fifo_full(ctlr_info_t *h)
 292{
 293        if( h->commands_outstanding >= h->max_commands)
 294                return(1);
 295        else 
 296                return(0);
 297
 298}
 299/* 
 300 *   returns value read from hardware. 
 301 *     returns FIFO_EMPTY if there is nothing to read 
 302 */ 
 303static unsigned long SA5_completed(ctlr_info_t *h)
 304{
 305        unsigned long register_value 
 306                = readl(h->vaddr + SA5_REPLY_PORT_OFFSET);
 307        if(register_value != FIFO_EMPTY)
 308        {
 309                h->commands_outstanding--;
 310#ifdef CCISS_DEBUG
 311                printk("cciss:  Read %lx back from board\n", register_value);
 312#endif /* CCISS_DEBUG */ 
 313        } 
 314#ifdef CCISS_DEBUG
 315        else
 316        {
 317                printk("cciss:  FIFO Empty read\n");
 318        }
 319#endif 
 320        return ( register_value); 
 321
 322}
 323
 324/* Performant mode command completed */
 325static unsigned long SA5_performant_completed(ctlr_info_t *h)
 326{
 327        unsigned long register_value = FIFO_EMPTY;
 328
 329        /* flush the controller write of the reply queue by reading
 330         * outbound doorbell status register.
 331         */
 332        register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 333        /* msi auto clears the interrupt pending bit. */
 334        if (!(h->pdev->msi_enabled || h->pdev->msix_enabled)) {
 335                writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR);
 336                /* Do a read in order to flush the write to the controller
 337                 * (as per spec.)
 338                 */
 339                register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 340        }
 341
 342        if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) {
 343                register_value = *(h->reply_pool_head);
 344                (h->reply_pool_head)++;
 345                h->commands_outstanding--;
 346        } else {
 347                register_value = FIFO_EMPTY;
 348        }
 349        /* Check for wraparound */
 350        if (h->reply_pool_head == (h->reply_pool + h->max_commands)) {
 351                h->reply_pool_head = h->reply_pool;
 352                h->reply_pool_wraparound ^= 1;
 353        }
 354
 355        return register_value;
 356}
 357/*
 358 *      Returns true if an interrupt is pending.. 
 359 */
 360static bool SA5_intr_pending(ctlr_info_t *h)
 361{
 362        unsigned long register_value  = 
 363                readl(h->vaddr + SA5_INTR_STATUS);
 364#ifdef CCISS_DEBUG
 365        printk("cciss: intr_pending %lx\n", register_value);
 366#endif  /* CCISS_DEBUG */
 367        if( register_value &  SA5_INTR_PENDING) 
 368                return  1;      
 369        return 0 ;
 370}
 371
 372/*
 373 *      Returns true if an interrupt is pending..
 374 */
 375static bool SA5B_intr_pending(ctlr_info_t *h)
 376{
 377        unsigned long register_value  =
 378                readl(h->vaddr + SA5_INTR_STATUS);
 379#ifdef CCISS_DEBUG
 380        printk("cciss: intr_pending %lx\n", register_value);
 381#endif  /* CCISS_DEBUG */
 382        if( register_value &  SA5B_INTR_PENDING)
 383                return  1;
 384        return 0 ;
 385}
 386
 387static bool SA5_performant_intr_pending(ctlr_info_t *h)
 388{
 389        unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
 390
 391        if (!register_value)
 392                return false;
 393
 394        if (h->pdev->msi_enabled || h->pdev->msix_enabled)
 395                return true;
 396
 397        /* Read outbound doorbell to flush */
 398        register_value = readl(h->vaddr + SA5_OUTDB_STATUS);
 399        return register_value & SA5_OUTDB_STATUS_PERF_BIT;
 400}
 401
 402static struct access_method SA5_access = {
 403        .submit_command = SA5_submit_command,
 404        .set_intr_mask = SA5_intr_mask,
 405        .fifo_full = SA5_fifo_full,
 406        .intr_pending = SA5_intr_pending,
 407        .command_completed = SA5_completed,
 408};
 409
 410static struct access_method SA5B_access = {
 411        .submit_command = SA5_submit_command,
 412        .set_intr_mask = SA5B_intr_mask,
 413        .fifo_full = SA5_fifo_full,
 414        .intr_pending = SA5B_intr_pending,
 415        .command_completed = SA5_completed,
 416};
 417
 418static struct access_method SA5_performant_access = {
 419        .submit_command = SA5_submit_command,
 420        .set_intr_mask = SA5_performant_intr_mask,
 421        .fifo_full = SA5_fifo_full,
 422        .intr_pending = SA5_performant_intr_pending,
 423        .command_completed = SA5_performant_completed,
 424};
 425
 426struct board_type {
 427        __u32   board_id;
 428        char    *product_name;
 429        struct access_method *access;
 430        int nr_cmds; /* Max cmds this kind of ctlr can handle. */
 431};
 432
 433#endif /* CCISS_H */
 434