Merge tag 'rdma-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[firefly-linux-kernel-4.4.55.git] / drivers / scsi / hpsa.h
index 01c328349c834583088958e30c29c8f5cfada833..44235a27e1b6d0541a78c1442bfdda4794caabb5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *    Disk Array driver for HP Smart Array SAS controllers
- *    Copyright 2000, 2009 Hewlett-Packard Development Company, L.P.
+ *    Copyright 2000, 2014 Hewlett-Packard Development Company, L.P.
  *
  *    This program is free software; you can redistribute it and/or modify
  *    it under the terms of the GNU General Public License as published by
@@ -46,6 +46,15 @@ struct hpsa_scsi_dev_t {
        unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
        unsigned char model[16];        /* bytes 16-31 of inquiry data */
        unsigned char raid_level;       /* from inquiry page 0xC1 */
+       unsigned char volume_offline;   /* discovered via TUR or VPD */
+       u32 ioaccel_handle;
+       int offload_config;             /* I/O accel RAID offload configured */
+       int offload_enabled;            /* I/O accel RAID offload enabled */
+       int offload_to_mirror;          /* Send next I/O accelerator RAID
+                                        * offload request to mirror drive
+                                        */
+       struct raid_map_data raid_map;  /* I/O accelerator RAID map */
+
 };
 
 struct reply_pool {
@@ -55,6 +64,46 @@ struct reply_pool {
        u32 current_entry;
 };
 
+#pragma pack(1)
+struct bmic_controller_parameters {
+       u8   led_flags;
+       u8   enable_command_list_verification;
+       u8   backed_out_write_drives;
+       u16  stripes_for_parity;
+       u8   parity_distribution_mode_flags;
+       u16  max_driver_requests;
+       u16  elevator_trend_count;
+       u8   disable_elevator;
+       u8   force_scan_complete;
+       u8   scsi_transfer_mode;
+       u8   force_narrow;
+       u8   rebuild_priority;
+       u8   expand_priority;
+       u8   host_sdb_asic_fix;
+       u8   pdpi_burst_from_host_disabled;
+       char software_name[64];
+       char hardware_name[32];
+       u8   bridge_revision;
+       u8   snapshot_priority;
+       u32  os_specific;
+       u8   post_prompt_timeout;
+       u8   automatic_drive_slamming;
+       u8   reserved1;
+       u8   nvram_flags;
+       u8   cache_nvram_flags;
+       u8   drive_config_flags;
+       u16  reserved2;
+       u8   temp_warning_level;
+       u8   temp_shutdown_level;
+       u8   temp_condition_reset;
+       u8   max_coalesce_commands;
+       u32  max_coalesce_delay;
+       u8   orca_password[4];
+       u8   access_id[16];
+       u8   reserved[356];
+};
+#pragma pack()
+
 struct ctlr_info {
        int     ctlr;
        char    devname[8];
@@ -80,6 +129,7 @@ struct ctlr_info {
        unsigned int msi_vector;
        int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
        struct access_method access;
+       char hba_mode_enabled;
 
        /* queue and queue Info */
        struct list_head reqQ;
@@ -95,6 +145,10 @@ struct ctlr_info {
        /* pointers to command and error info pool */
        struct CommandList      *cmd_pool;
        dma_addr_t              cmd_pool_dhandle;
+       struct io_accel1_cmd    *ioaccel_cmd_pool;
+       dma_addr_t              ioaccel_cmd_pool_dhandle;
+       struct io_accel2_cmd    *ioaccel2_cmd_pool;
+       dma_addr_t              ioaccel2_cmd_pool_dhandle;
        struct ErrorInfo        *errinfo_pool;
        dma_addr_t              errinfo_pool_dhandle;
        unsigned long           *cmd_pool_bits;
@@ -128,7 +182,14 @@ struct ctlr_info {
        u8 nreply_queues;
        dma_addr_t reply_pool_dhandle;
        u32 *blockFetchTable;
+       u32 *ioaccel1_blockFetchTable;
+       u32 *ioaccel2_blockFetchTable;
+       u32 *ioaccel2_bft2_regs;
        unsigned char *hba_inquiry_data;
+       u32 driver_support;
+       u32 fw_support;
+       int ioaccel_support;
+       int ioaccel_maxsg;
        u64 last_intr_timestamp;
        u32 last_heartbeat;
        u64 last_heartbeat_timestamp;
@@ -161,7 +222,35 @@ struct ctlr_info {
 #define HPSATMF_LOG_QRY_TASK    (1 << 23)
 #define HPSATMF_LOG_QRY_TSET    (1 << 24)
 #define HPSATMF_LOG_QRY_ASYNC   (1 << 25)
+       u32 events;
+#define CTLR_STATE_CHANGE_EVENT                                (1 << 0)
+#define CTLR_ENCLOSURE_HOT_PLUG_EVENT                  (1 << 1)
+#define CTLR_STATE_CHANGE_EVENT_PHYSICAL_DRV           (1 << 4)
+#define CTLR_STATE_CHANGE_EVENT_LOGICAL_DRV            (1 << 5)
+#define CTLR_STATE_CHANGE_EVENT_REDUNDANT_CNTRL                (1 << 6)
+#define CTLR_STATE_CHANGE_EVENT_AIO_ENABLED_DISABLED   (1 << 30)
+#define CTLR_STATE_CHANGE_EVENT_AIO_CONFIG_CHANGE      (1 << 31)
+
+#define RESCAN_REQUIRED_EVENT_BITS \
+               (CTLR_STATE_CHANGE_EVENT | \
+               CTLR_ENCLOSURE_HOT_PLUG_EVENT | \
+               CTLR_STATE_CHANGE_EVENT_PHYSICAL_DRV | \
+               CTLR_STATE_CHANGE_EVENT_LOGICAL_DRV | \
+               CTLR_STATE_CHANGE_EVENT_REDUNDANT_CNTRL | \
+               CTLR_STATE_CHANGE_EVENT_AIO_ENABLED_DISABLED | \
+               CTLR_STATE_CHANGE_EVENT_AIO_CONFIG_CHANGE)
+       spinlock_t offline_device_lock;
+       struct list_head offline_device_list;
+       int     acciopath_status;
+       int     drv_req_rescan; /* flag for driver to request rescan event */
+       int     raid_offload_debug;
 };
+
+struct offline_device_entry {
+       unsigned char scsi3addr[8];
+       struct list_head offline_list;
+};
+
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
 #define HPSA_RESET_TYPE_CONTROLLER 0x00
@@ -242,6 +331,14 @@ struct ctlr_info {
 
 #define HPSA_INTR_ON   1
 #define HPSA_INTR_OFF  0
+
+/*
+ * Inbound Post Queue offsets for IO Accelerator Mode 2
+ */
+#define IOACCEL2_INBOUND_POSTQ_32      0x48
+#define IOACCEL2_INBOUND_POSTQ_64_LOW  0xd0
+#define IOACCEL2_INBOUND_POSTQ_64_HI   0xd4
+
 /*
        Send the command to the hardware
 */
@@ -254,6 +351,18 @@ static void SA5_submit_command(struct ctlr_info *h,
        (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
 }
 
+static void SA5_submit_command_ioaccel2(struct ctlr_info *h,
+       struct CommandList *c)
+{
+       dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr,
+               c->Header.Tag.lower);
+       if (c->cmd_type == CMD_IOACCEL2)
+               writel(c->busaddr, h->vaddr + IOACCEL2_INBOUND_POSTQ_32);
+       else
+               writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET);
+       (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET);
+}
+
 /*
  *  This card is the opposite of the other cards.
  *   0 turns interrupts on...
@@ -387,6 +496,50 @@ static bool SA5_performant_intr_pending(struct ctlr_info *h)
        return register_value & SA5_OUTDB_STATUS_PERF_BIT;
 }
 
+#define SA5_IOACCEL_MODE1_INTR_STATUS_CMP_BIT    0x100
+
+static bool SA5_ioaccel_mode1_intr_pending(struct ctlr_info *h)
+{
+       unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS);
+
+       return (register_value & SA5_IOACCEL_MODE1_INTR_STATUS_CMP_BIT) ?
+               true : false;
+}
+
+#define IOACCEL_MODE1_REPLY_QUEUE_INDEX  0x1A0
+#define IOACCEL_MODE1_PRODUCER_INDEX     0x1B8
+#define IOACCEL_MODE1_CONSUMER_INDEX     0x1BC
+#define IOACCEL_MODE1_REPLY_UNUSED       0xFFFFFFFFFFFFFFFFULL
+
+static unsigned long SA5_ioaccel_mode1_completed(struct ctlr_info *h, u8 q)
+{
+       u64 register_value;
+       struct reply_pool *rq = &h->reply_queue[q];
+       unsigned long flags;
+
+       BUG_ON(q >= h->nreply_queues);
+
+       register_value = rq->head[rq->current_entry];
+       if (register_value != IOACCEL_MODE1_REPLY_UNUSED) {
+               rq->head[rq->current_entry] = IOACCEL_MODE1_REPLY_UNUSED;
+               if (++rq->current_entry == rq->size)
+                       rq->current_entry = 0;
+               /*
+                * @todo
+                *
+                * Don't really need to write the new index after each command,
+                * but with current driver design this is easiest.
+                */
+               wmb();
+               writel((q << 24) | rq->current_entry, h->vaddr +
+                               IOACCEL_MODE1_CONSUMER_INDEX);
+               spin_lock_irqsave(&h->lock, flags);
+               h->commands_outstanding--;
+               spin_unlock_irqrestore(&h->lock, flags);
+       }
+       return (unsigned long) register_value;
+}
+
 static struct access_method SA5_access = {
        SA5_submit_command,
        SA5_intr_mask,
@@ -395,6 +548,22 @@ static struct access_method SA5_access = {
        SA5_completed,
 };
 
+static struct access_method SA5_ioaccel_mode1_access = {
+       SA5_submit_command,
+       SA5_performant_intr_mask,
+       SA5_fifo_full,
+       SA5_ioaccel_mode1_intr_pending,
+       SA5_ioaccel_mode1_completed,
+};
+
+static struct access_method SA5_ioaccel_mode2_access = {
+       SA5_submit_command_ioaccel2,
+       SA5_performant_intr_mask,
+       SA5_fifo_full,
+       SA5_performant_intr_pending,
+       SA5_performant_completed,
+};
+
 static struct access_method SA5_performant_access = {
        SA5_submit_command,
        SA5_performant_intr_mask,