1edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 2edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Disk Array driver for HP Smart Array SAS controllers 3edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Copyright 2000, 2009 Hewlett-Packard Development Company, L.P. 4edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 5edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * This program is free software; you can redistribute it and/or modify 6edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * it under the terms of the GNU General Public License as published by 7edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * the Free Software Foundation; version 2 of the License. 8edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 9edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * This program is distributed in the hope that it will be useful, 10edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * but WITHOUT ANY WARRANTY; without even the implied warranty of 11edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 12edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * NON INFRINGEMENT. See the GNU General Public License for more details. 13edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 14edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * You should have received a copy of the GNU General Public License 15edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * along with this program; if not, write to the Free Software 16edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 18edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Questions/Comments/Bugfixes to iss_storagedev@hp.com 19edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 20edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 21edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#ifndef HPSA_H 22edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_H 23edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 24edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#include <scsi/scsicam.h> 25edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 26edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define IO_OK 0 27edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define IO_ERROR 1 28edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 29edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstruct ctlr_info; 30edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 31edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstruct access_method { 32edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron void (*submit_command)(struct ctlr_info *h, 33edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct CommandList *c); 34edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron void (*set_intr_mask)(struct ctlr_info *h, unsigned long val); 35edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long (*fifo_full)(struct ctlr_info *h); 36900c54404a9456b3ff10745e5e8f64b12c3a6ef7Stephen M. Cameron bool (*intr_pending)(struct ctlr_info *h); 37edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long (*command_completed)(struct ctlr_info *h); 38edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron}; 39edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 40edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstruct hpsa_scsi_dev_t { 41edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int devtype; 42edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int bus, target, lun; /* as presented to the OS */ 43edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned char scsi3addr[8]; /* as presented to the HW */ 44edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" 45edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned char device_id[16]; /* from inquiry pg. 0x83 */ 46edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned char vendor[8]; /* bytes 8-15 of inquiry data */ 47edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned char model[16]; /* bytes 16-31 of inquiry data */ 48edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned char raid_level; /* from inquiry page 0xC1 */ 49edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron}; 50edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 51edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstruct ctlr_info { 52edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int ctlr; 53edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron char devname[8]; 54edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron char *product_name; 55edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct pci_dev *pdev; 5601a02ffcd55b74e3459bb7358140970e126d4731Stephen M. Cameron u32 board_id; 57edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron void __iomem *vaddr; 58edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long paddr; 59edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int nr_cmds; /* Number of commands allowed on this controller */ 60edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct CfgTable __iomem *cfgtable; 61edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int interrupts_enabled; 62edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int major; 63edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int max_commands; 64edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int commands_outstanding; 65edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int max_outstanding; /* Debug */ 66edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int usage_count; /* number of opens all all minor devices */ 67303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace# define PERF_MODE_INT 0 68303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace# define DOORBELL_INT 1 69edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron# define SIMPLE_MODE_INT 2 70edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron# define MEMQ_MODE_INT 3 71edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int intr[4]; 72edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int msix_vector; 73edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int msi_vector; 74a9a3a2739a44fc05dcaba0d4d36e52dc444c294fStephen M. Cameron int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */ 75edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct access_method access; 76edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 77edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron /* queue and queue Info */ 789e0fc764eaec082cd2ffcf82568dfdd086935934Stephen M. Cameron struct list_head reqQ; 799e0fc764eaec082cd2ffcf82568dfdd086935934Stephen M. Cameron struct list_head cmpQ; 80edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int Qdepth; 81edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int maxQsinceinit; 82edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned int maxSG; 83edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron spinlock_t lock; 8433a2ffce51d9598380d73c515a27fc6cff3bd9c4Stephen M. Cameron int maxsgentries; 8533a2ffce51d9598380d73c515a27fc6cff3bd9c4Stephen M. Cameron u8 max_cmd_sg_entries; 8633a2ffce51d9598380d73c515a27fc6cff3bd9c4Stephen M. Cameron int chainsize; 8733a2ffce51d9598380d73c515a27fc6cff3bd9c4Stephen M. Cameron struct SGDescriptor **cmd_sg_list; 88edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 89edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron /* pointers to command and error info pool */ 90edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct CommandList *cmd_pool; 91edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron dma_addr_t cmd_pool_dhandle; 92edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct ErrorInfo *errinfo_pool; 93edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron dma_addr_t errinfo_pool_dhandle; 94edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long *cmd_pool_bits; 95edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int nr_allocs; 96edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int nr_frees; 97a08a8471b7aed3d50df8e9c852dc2baa08ec8b01Stephen M. Cameron int scan_finished; 98a08a8471b7aed3d50df8e9c852dc2baa08ec8b01Stephen M. Cameron spinlock_t scan_lock; 99a08a8471b7aed3d50df8e9c852dc2baa08ec8b01Stephen M. Cameron wait_queue_head_t scan_wait_queue; 100edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 101edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct Scsi_Host *scsi_host; 102edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron spinlock_t devlock; /* to protect hba[ctlr]->dev[]; */ 103edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron int ndevices; /* number of used elements in .dev[] array. */ 104cfe5badcab2e993e71ebebbc07c21c270e5580c0Scott Teel struct hpsa_scsi_dev_t *dev[HPSA_MAX_DEVICES]; 105303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* 106303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace * Performant mode tables. 107303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace */ 108303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace u32 trans_support; 109303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace u32 trans_offset; 110303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace struct TransTable_struct *transtable; 111303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace unsigned long transMethod; 112303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 113303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* 114303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace * Performant mode completion buffer 115303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace */ 116303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace u64 *reply_pool; 117303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace dma_addr_t reply_pool_dhandle; 118303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace u64 *reply_pool_head; 119303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace size_t reply_pool_size; 120303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace unsigned char reply_pool_wraparound; 121303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace u32 *blockFetchTable; 122339b2b14c634da58626eb742370d915591c2fb6dStephen M. Cameron unsigned char *hba_inquiry_data; 123a0c124137a40fc22730ae87caf17e821f2dce1edStephen M. Cameron u64 last_intr_timestamp; 124a0c124137a40fc22730ae87caf17e821f2dce1edStephen M. Cameron u32 last_heartbeat; 125a0c124137a40fc22730ae87caf17e821f2dce1edStephen M. Cameron u64 last_heartbeat_timestamp; 126a0c124137a40fc22730ae87caf17e821f2dce1edStephen M. Cameron u32 lockup_detected; 127a0c124137a40fc22730ae87caf17e821f2dce1edStephen M. Cameron struct list_head lockup_list; 128edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron}; 129edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_ABORT_MSG 0 130edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_DEVICE_RESET_MSG 1 13164670ac8702ec37a00ad6e479f3cacbde0fd4efaStephen M. Cameron#define HPSA_RESET_TYPE_CONTROLLER 0x00 13264670ac8702ec37a00ad6e479f3cacbde0fd4efaStephen M. Cameron#define HPSA_RESET_TYPE_BUS 0x01 13364670ac8702ec37a00ad6e479f3cacbde0fd4efaStephen M. Cameron#define HPSA_RESET_TYPE_TARGET 0x03 13464670ac8702ec37a00ad6e479f3cacbde0fd4efaStephen M. Cameron#define HPSA_RESET_TYPE_LUN 0x04 135edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_MSG_SEND_RETRY_LIMIT 10 136516fda49e8596904a741693059c8746f11ce579cStephen M. Cameron#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000) 137edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 138edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* Maximum time in seconds driver will wait for command completions 139edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * when polling before giving up. 140edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 141edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_MAX_POLL_TIME_SECS (20) 142edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 143edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* During SCSI error recovery, HPSA_TUR_RETRY_LIMIT defines 144edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * how many times to retry TEST UNIT READY on a device 145edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * while waiting for it to become ready before giving up. 146edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * HPSA_MAX_WAIT_INTERVAL_SECS is the max wait interval 147edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * between sending TURs while waiting for a device 148edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * to become ready. 149edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 150edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_TUR_RETRY_LIMIT (20) 151edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_MAX_WAIT_INTERVAL_SECS (30) 152edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 153edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* HPSA_BOARD_READY_WAIT_SECS is how long to wait for a board 154edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * to become ready, in seconds, before giving up on it. 155edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * HPSA_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait 156edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * between polling the board to see if it is ready, in 157edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * milliseconds. HPSA_BOARD_READY_POLL_INTERVAL and 158edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * HPSA_BOARD_READY_ITERATIONS are derived from those. 159edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 160edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_BOARD_READY_WAIT_SECS (120) 1612ed7127bceb10a6a7d5a38c30ab65176d4e4bc0fStephen M. Cameron#define HPSA_BOARD_NOT_READY_WAIT_SECS (100) 162edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100) 163edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_BOARD_READY_POLL_INTERVAL \ 164edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron ((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000) 165edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_BOARD_READY_ITERATIONS \ 166edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron ((HPSA_BOARD_READY_WAIT_SECS * 1000) / \ 167edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron HPSA_BOARD_READY_POLL_INTERVAL_MSECS) 168fe5389c87f13c16cd77d976801c93422d0c05a49Stephen M. Cameron#define HPSA_BOARD_NOT_READY_ITERATIONS \ 169fe5389c87f13c16cd77d976801c93422d0c05a49Stephen M. Cameron ((HPSA_BOARD_NOT_READY_WAIT_SECS * 1000) / \ 170fe5389c87f13c16cd77d976801c93422d0c05a49Stephen M. Cameron HPSA_BOARD_READY_POLL_INTERVAL_MSECS) 171edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_POST_RESET_PAUSE_MSECS (3000) 172edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_POST_RESET_NOOP_RETRIES (12) 173edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 174edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* Defining the diffent access_menthods */ 175edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 176edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Memory mapped FIFO interface (SMART 53xx cards) 177edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 178edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_DOORBELL 0x20 179edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_REQUEST_PORT_OFFSET 0x40 180edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_REPLY_INTR_MASK_OFFSET 0x34 181edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_REPLY_PORT_OFFSET 0x44 182edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_INTR_STATUS 0x30 183edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_SCRATCHPAD_OFFSET 0xB0 184edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 185edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_CTCFG_OFFSET 0xB4 186edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_CTMEM_OFFSET 0xB8 187edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 188edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_INTR_OFF 0x08 189edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5B_INTR_OFF 0x04 190edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5_INTR_PENDING 0x08 191edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define SA5B_INTR_PENDING 0x04 192edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define FIFO_EMPTY 0xffffffff 193edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ 194edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 195edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_ERROR_BIT 0x02 196edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 197303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace/* Performant mode flags */ 198303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_PERF_INTR_PENDING 0x04 199303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_PERF_INTR_OFF 0x05 200303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_OUTDB_STATUS_PERF_BIT 0x01 201303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_OUTDB_CLEAR_PERF_BIT 0x01 202303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_OUTDB_CLEAR 0xA0 203303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_OUTDB_CLEAR_PERF_BIT 0x01 204303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace#define SA5_OUTDB_STATUS 0x9C 205303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 206303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 207edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_INTR_ON 1 208edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#define HPSA_INTR_OFF 0 209edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 210edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron Send the command to the hardware 211edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron*/ 212edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstatic void SA5_submit_command(struct ctlr_info *h, 213edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct CommandList *c) 214edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron{ 215303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace dev_dbg(&h->pdev->dev, "Sending %x, tag = %x\n", c->busaddr, 216303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace c->Header.Tag.lower); 217edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); 218fec62c368b9c8b05d5124ca6c3b8336b537f26f3Stephen M. Cameron (void) readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); 219edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->commands_outstanding++; 220edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron if (h->commands_outstanding > h->max_outstanding) 221edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->max_outstanding = h->commands_outstanding; 222edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron} 223edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 224edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 225edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * This card is the opposite of the other cards. 226edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 0 turns interrupts on... 227edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 0x08 turns them off... 228edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 229edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstatic void SA5_intr_mask(struct ctlr_info *h, unsigned long val) 230edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron{ 231edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron if (val) { /* Turn interrupts on */ 232edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->interrupts_enabled = 1; 233edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 2348cd21da71c952843f9cc215436286cf7f991cc6eStephen M. Cameron (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 235edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron } else { /* Turn them off */ 236edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->interrupts_enabled = 0; 237edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron writel(SA5_INTR_OFF, 238edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 2398cd21da71c952843f9cc215436286cf7f991cc6eStephen M. Cameron (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 240edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron } 241edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron} 242303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 243303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Bracestatic void SA5_performant_intr_mask(struct ctlr_info *h, unsigned long val) 244303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace{ 245303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if (val) { /* turn on interrupts */ 246303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->interrupts_enabled = 1; 247303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 2488cd21da71c952843f9cc215436286cf7f991cc6eStephen M. Cameron (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 249303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } else { 250303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->interrupts_enabled = 0; 251303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace writel(SA5_PERF_INTR_OFF, 252303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 2538cd21da71c952843f9cc215436286cf7f991cc6eStephen M. Cameron (void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); 254303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } 255303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace} 256303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 257303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Bracestatic unsigned long SA5_performant_completed(struct ctlr_info *h) 258303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace{ 259303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace unsigned long register_value = FIFO_EMPTY; 260303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 261303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* flush the controller write of the reply queue by reading 262303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace * outbound doorbell status register. 263303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace */ 264303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 265303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* msi auto clears the interrupt pending bit. */ 266303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if (!(h->msi_vector || h->msix_vector)) { 267303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); 268303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* Do a read in order to flush the write to the controller 269303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace * (as per spec.) 270303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace */ 271303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 272303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } 273303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 274303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { 275303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace register_value = *(h->reply_pool_head); 276303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace (h->reply_pool_head)++; 277303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->commands_outstanding--; 278303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } else { 279303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace register_value = FIFO_EMPTY; 280303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } 281303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* Check for wraparound */ 282303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { 283303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->reply_pool_head = h->reply_pool; 284303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace h->reply_pool_wraparound ^= 1; 285303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace } 286303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 287303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace return register_value; 288303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace} 289303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 290edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 291edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Returns true if fifo is full. 292edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * 293edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 294edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstatic unsigned long SA5_fifo_full(struct ctlr_info *h) 295edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron{ 296edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron if (h->commands_outstanding >= h->max_commands) 297edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron return 1; 298edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron else 299edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron return 0; 300edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 301edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron} 302edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 303edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * returns value read from hardware. 304edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * returns FIFO_EMPTY if there is nothing to read 305edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 306edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstatic unsigned long SA5_completed(struct ctlr_info *h) 307edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron{ 308edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long register_value 309edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron = readl(h->vaddr + SA5_REPLY_PORT_OFFSET); 310edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 311edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron if (register_value != FIFO_EMPTY) 312edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron h->commands_outstanding--; 313edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 314edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#ifdef HPSA_DEBUG 315edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron if (register_value != FIFO_EMPTY) 31684ca0be2a2cd9730683310b831db9d2fa60b3b0bStephen M. Cameron dev_dbg(&h->pdev->dev, "Read %lx back from board\n", 317edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron register_value); 318edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron else 319f79cfec6b1906ab10ef70dccd601db25c97bae17Stephen M. Cameron dev_dbg(&h->pdev->dev, "FIFO Empty read\n"); 320edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#endif 321edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 322edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron return register_value; 323edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron} 324edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron/* 325edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron * Returns true if an interrupt is pending.. 326edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron */ 327900c54404a9456b3ff10745e5e8f64b12c3a6ef7Stephen M. Cameronstatic bool SA5_intr_pending(struct ctlr_info *h) 328edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron{ 329edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron unsigned long register_value = 330edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron readl(h->vaddr + SA5_INTR_STATUS); 33184ca0be2a2cd9730683310b831db9d2fa60b3b0bStephen M. Cameron dev_dbg(&h->pdev->dev, "intr_pending %lx\n", register_value); 332900c54404a9456b3ff10745e5e8f64b12c3a6ef7Stephen M. Cameron return register_value & SA5_INTR_PENDING; 333edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron} 334edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 335303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Bracestatic bool SA5_performant_intr_pending(struct ctlr_info *h) 336303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace{ 337303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS); 338303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 339303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if (!register_value) 340303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace return false; 341303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 342303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace if (h->msi_vector || h->msix_vector) 343303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace return true; 344303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 345303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace /* Read outbound doorbell to flush */ 346303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace register_value = readl(h->vaddr + SA5_OUTDB_STATUS); 347303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace return register_value & SA5_OUTDB_STATUS_PERF_BIT; 348303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace} 349edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 350edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstatic struct access_method SA5_access = { 351edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron SA5_submit_command, 352edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron SA5_intr_mask, 353edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron SA5_fifo_full, 354edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron SA5_intr_pending, 355edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron SA5_completed, 356edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron}; 357edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 358303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Bracestatic struct access_method SA5_performant_access = { 359303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace SA5_submit_command, 360303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace SA5_performant_intr_mask, 361303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace SA5_fifo_full, 362303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace SA5_performant_intr_pending, 363303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace SA5_performant_completed, 364303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace}; 365303932fd4ff63e8650d5d5da6cc286a8b5f8318dDon Brace 366edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameronstruct board_type { 36701a02ffcd55b74e3459bb7358140970e126d4731Stephen M. Cameron u32 board_id; 368edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron char *product_name; 369edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron struct access_method *access; 370edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron}; 371edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 372edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron#endif /* HPSA_H */ 373edd163687ea59f01d6b43c9e1fdaa0126fa30191Stephen M. Cameron 374