1426 lines · c
1/*2 * linux/drivers/scsi/esas2r/esas2r.h3 * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers4 *5 * Copyright (c) 2001-2013 ATTO Technology, Inc.6 * (mailto:linuxdrivers@attotech.com)7 *8 * This program is free software; you can redistribute it and/or9 * modify it under the terms of the GNU General Public License10 * as published by the Free Software Foundation; either version 211 * of the License, or (at your option) any later version.12 *13 * This program is distributed in the hope that it will be useful,14 * but WITHOUT ANY WARRANTY; without even the implied warranty of15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16 * GNU General Public License for more details.17 *18 * NO WARRANTY19 * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR20 * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT21 * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,22 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is23 * solely responsible for determining the appropriateness of using and24 * distributing the Program and assumes all risks associated with its25 * exercise of rights under this Agreement, including but not limited to26 * the risks and costs of program errors, damage to or loss of data,27 * programs or equipment, and unavailability or interruption of operations.28 *29 * DISCLAIMER OF LIABILITY30 * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL32 * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR34 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE35 * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED36 * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES37 *38 * You should have received a copy of the GNU General Public License39 * along with this program; if not, write to the Free Software40 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,41 * USA.42 */43 44#include <linux/kernel.h>45#include <linux/delay.h>46#include <linux/pci.h>47#include <linux/proc_fs.h>48#include <linux/workqueue.h>49#include <linux/interrupt.h>50#include <linux/module.h>51#include <linux/vmalloc.h>52#include <scsi/scsi.h>53#include <scsi/scsi_host.h>54#include <scsi/scsi_cmnd.h>55#include <scsi/scsi_device.h>56#include <scsi/scsi_eh.h>57#include <scsi/scsi_tcq.h>58 59#include "esas2r_log.h"60#include "atioctl.h"61#include "atvda.h"62 63#ifndef ESAS2R_H64#define ESAS2R_H65 66/* Global Variables */67extern struct esas2r_adapter *esas2r_adapters[];68extern u8 *esas2r_buffered_ioctl;69extern dma_addr_t esas2r_buffered_ioctl_addr;70extern u32 esas2r_buffered_ioctl_size;71extern struct pci_dev *esas2r_buffered_ioctl_pcid;72#define SGL_PG_SZ_MIN 6473#define SGL_PG_SZ_MAX 102474extern int sgl_page_size;75#define NUM_SGL_MIN 876#define NUM_SGL_MAX 204877extern int num_sg_lists;78#define NUM_REQ_MIN 479#define NUM_REQ_MAX 25680extern int num_requests;81#define NUM_AE_MIN 282#define NUM_AE_MAX 883extern int num_ae_requests;84extern int cmd_per_lun;85extern int can_queue;86extern int esas2r_max_sectors;87extern int sg_tablesize;88extern int interrupt_mode;89extern int num_io_requests;90 91/* Macro defintions */92#define ESAS2R_MAX_ID 25593#define MAX_ADAPTERS 3294#define ESAS2R_DRVR_NAME "esas2r"95#define ESAS2R_LONGNAME "ATTO ExpressSAS 6GB RAID Adapter"96#define ESAS2R_MAX_DEVICES 3297#define ATTONODE_NAME "ATTONode"98#define ESAS2R_MAJOR_REV 199#define ESAS2R_MINOR_REV 00100#define ESAS2R_VERSION_STR DEFINED_NUM_TO_STR(ESAS2R_MAJOR_REV) "." \101 DEFINED_NUM_TO_STR(ESAS2R_MINOR_REV)102#define ESAS2R_COPYRIGHT_YEARS "2001-2013"103#define ESAS2R_DEFAULT_SGL_PAGE_SIZE 384104#define ESAS2R_DEFAULT_CMD_PER_LUN 64105#define ESAS2R_DEFAULT_NUM_SG_LISTS 1024106#define DEFINED_NUM_TO_STR(num) NUM_TO_STR(num)107#define NUM_TO_STR(num) #num108 109#define ESAS2R_SGL_ALIGN 16110#define ESAS2R_LIST_ALIGN 16111#define ESAS2R_LIST_EXTRA ESAS2R_NUM_EXTRA112#define ESAS2R_DATA_BUF_LEN 256113#define ESAS2R_DEFAULT_TMO 5000114#define ESAS2R_DISC_BUF_LEN 512115#define ESAS2R_FWCOREDUMP_SZ 0x80000116#define ESAS2R_NUM_PHYS 8117#define ESAS2R_TARG_ID_INV 0xFFFF118#define ESAS2R_INT_STS_MASK MU_INTSTAT_MASK119#define ESAS2R_INT_ENB_MASK MU_INTSTAT_MASK120#define ESAS2R_INT_DIS_MASK 0121#define ESAS2R_MAX_TARGETS 256122#define ESAS2R_KOBJ_NAME_LEN 20123 124/* u16 (WORD) component macros */125#define LOBYTE(w) ((u8)(u16)(w))126#define HIBYTE(w) ((u8)(((u16)(w)) >> 8))127#define MAKEWORD(lo, hi) ((u16)((u8)(lo) | ((u16)(u8)(hi) << 8)))128 129/* u32 (DWORD) component macros */130#define LOWORD(d) ((u16)(u32)(d))131#define HIWORD(d) ((u16)(((u32)(d)) >> 16))132#define MAKEDWORD(lo, hi) ((u32)((u16)(lo) | ((u32)(u16)(hi) << 16)))133 134/* macro to get the lowest nonzero bit of a value */135#define LOBIT(x) ((x) & (0 - (x)))136 137/* These functions are provided to access the chip's control registers.138 * The register is specified by its byte offset from the register base139 * for the adapter.140 */141#define esas2r_read_register_dword(a, reg) \142 readl((void __iomem *)a->regs + (reg) + MW_REG_OFFSET_HWREG)143 144#define esas2r_write_register_dword(a, reg, data) \145 writel(data, (void __iomem *)(a->regs + (reg) + MW_REG_OFFSET_HWREG))146 147#define esas2r_flush_register_dword(a, r) esas2r_read_register_dword(a, r)148 149/* This function is provided to access the chip's data window. The150 * register is specified by its byte offset from the window base151 * for the adapter.152 */153#define esas2r_read_data_byte(a, reg) \154 readb((void __iomem *)a->data_window + (reg))155 156/* ATTO vendor and device Ids */157#define ATTO_VENDOR_ID 0x117C158#define ATTO_DID_INTEL_IOP348 0x002C159#define ATTO_DID_MV_88RC9580 0x0049160#define ATTO_DID_MV_88RC9580TS 0x0066161#define ATTO_DID_MV_88RC9580TSE 0x0067162#define ATTO_DID_MV_88RC9580TL 0x0068163 164/* ATTO subsystem device Ids */165#define ATTO_SSDID_TBT 0x4000166#define ATTO_TSSC_3808 0x4066167#define ATTO_TSSC_3808E 0x4067168#define ATTO_TLSH_1068 0x4068169#define ATTO_ESAS_R680 0x0049170#define ATTO_ESAS_R608 0x004A171#define ATTO_ESAS_R60F 0x004B172#define ATTO_ESAS_R6F0 0x004C173#define ATTO_ESAS_R644 0x004D174#define ATTO_ESAS_R648 0x004E175 176/*177 * flash definitions & structures178 * define the code types179 */180#define FBT_CPYR 0xAA00181#define FBT_SETUP 0xAA02182#define FBT_FLASH_VER 0xAA04183 184/* offsets to various locations in flash */185#define FLS_OFFSET_BOOT (u32)(0x00700000)186#define FLS_OFFSET_NVR (u32)(0x007C0000)187#define FLS_OFFSET_CPYR FLS_OFFSET_NVR188#define FLS_LENGTH_BOOT (FLS_OFFSET_CPYR - FLS_OFFSET_BOOT)189#define FLS_BLOCK_SIZE (u32)(0x00020000)190#define FI_NVR_2KB 0x0800191#define FI_NVR_8KB 0x2000192#define FM_BUF_SZ 0x800193 194/*195 * marvell frey (88R9580) register definitions196 * chip revision identifiers197 */198#define MVR_FREY_B2 0xB2199 200/*201 * memory window definitions. window 0 is the data window with definitions202 * of MW_DATA_XXX. window 1 is the register window with definitions of203 * MW_REG_XXX.204 */205#define MW_REG_WINDOW_SIZE (u32)(0x00040000)206#define MW_REG_OFFSET_HWREG (u32)(0x00000000)207#define MW_REG_OFFSET_PCI (u32)(0x00008000)208#define MW_REG_PCI_HWREG_DELTA (MW_REG_OFFSET_PCI - MW_REG_OFFSET_HWREG)209#define MW_DATA_WINDOW_SIZE (u32)(0x00020000)210#define MW_DATA_ADDR_SER_FLASH (u32)(0xEC000000)211#define MW_DATA_ADDR_SRAM (u32)(0xF4000000)212#define MW_DATA_ADDR_PAR_FLASH (u32)(0xFC000000)213 214/*215 * the following registers are for the communication216 * list interface (AKA message unit (MU))217 */218#define MU_IN_LIST_ADDR_LO (u32)(0x00004000)219#define MU_IN_LIST_ADDR_HI (u32)(0x00004004)220 221#define MU_IN_LIST_WRITE (u32)(0x00004018)222 #define MU_ILW_TOGGLE (u32)(0x00004000)223 224#define MU_IN_LIST_READ (u32)(0x0000401C)225 #define MU_ILR_TOGGLE (u32)(0x00004000)226 #define MU_ILIC_LIST (u32)(0x0000000F)227 #define MU_ILIC_LIST_F0 (u32)(0x00000000)228 #define MU_ILIC_DEST (u32)(0x00000F00)229 #define MU_ILIC_DEST_DDR (u32)(0x00000200)230#define MU_IN_LIST_IFC_CONFIG (u32)(0x00004028)231 232#define MU_IN_LIST_CONFIG (u32)(0x0000402C)233 #define MU_ILC_ENABLE (u32)(0x00000001)234 #define MU_ILC_ENTRY_MASK (u32)(0x000000F0)235 #define MU_ILC_ENTRY_4_DW (u32)(0x00000020)236 #define MU_ILC_DYNAMIC_SRC (u32)(0x00008000)237 #define MU_ILC_NUMBER_MASK (u32)(0x7FFF0000)238 #define MU_ILC_NUMBER_SHIFT 16239 240#define MU_OUT_LIST_ADDR_LO (u32)(0x00004050)241#define MU_OUT_LIST_ADDR_HI (u32)(0x00004054)242 243#define MU_OUT_LIST_COPY_PTR_LO (u32)(0x00004058)244#define MU_OUT_LIST_COPY_PTR_HI (u32)(0x0000405C)245 246#define MU_OUT_LIST_WRITE (u32)(0x00004068)247 #define MU_OLW_TOGGLE (u32)(0x00004000)248 249#define MU_OUT_LIST_COPY (u32)(0x0000406C)250 #define MU_OLC_TOGGLE (u32)(0x00004000)251 #define MU_OLC_WRT_PTR (u32)(0x00003FFF)252 253#define MU_OUT_LIST_IFC_CONFIG (u32)(0x00004078)254 #define MU_OLIC_LIST (u32)(0x0000000F)255 #define MU_OLIC_LIST_F0 (u32)(0x00000000)256 #define MU_OLIC_SOURCE (u32)(0x00000F00)257 #define MU_OLIC_SOURCE_DDR (u32)(0x00000200)258 259#define MU_OUT_LIST_CONFIG (u32)(0x0000407C)260 #define MU_OLC_ENABLE (u32)(0x00000001)261 #define MU_OLC_ENTRY_MASK (u32)(0x000000F0)262 #define MU_OLC_ENTRY_4_DW (u32)(0x00000020)263 #define MU_OLC_NUMBER_MASK (u32)(0x7FFF0000)264 #define MU_OLC_NUMBER_SHIFT 16265 266#define MU_OUT_LIST_INT_STAT (u32)(0x00004088)267 #define MU_OLIS_INT (u32)(0x00000001)268 269#define MU_OUT_LIST_INT_MASK (u32)(0x0000408C)270 #define MU_OLIS_MASK (u32)(0x00000001)271 272/*273 * the maximum size of the communication lists is two greater than the274 * maximum amount of VDA requests. the extra are to prevent queue overflow.275 */276#define ESAS2R_MAX_NUM_REQS 256277#define ESAS2R_NUM_EXTRA 2278#define ESAS2R_MAX_COMM_LIST_SIZE (ESAS2R_MAX_NUM_REQS + ESAS2R_NUM_EXTRA)279 280/*281 * the following registers are for the CPU interface282 */283#define MU_CTL_STATUS_IN (u32)(0x00010108)284 #define MU_CTL_IN_FULL_RST (u32)(0x00000020)285#define MU_CTL_STATUS_IN_B2 (u32)(0x00010130)286 #define MU_CTL_IN_FULL_RST2 (u32)(0x80000000)287#define MU_DOORBELL_IN (u32)(0x00010460)288 #define DRBL_RESET_BUS (u32)(0x00000002)289 #define DRBL_PAUSE_AE (u32)(0x00000004)290 #define DRBL_RESUME_AE (u32)(0x00000008)291 #define DRBL_MSG_IFC_DOWN (u32)(0x00000010)292 #define DRBL_FLASH_REQ (u32)(0x00000020)293 #define DRBL_FLASH_DONE (u32)(0x00000040)294 #define DRBL_FORCE_INT (u32)(0x00000080)295 #define DRBL_MSG_IFC_INIT (u32)(0x00000100)296 #define DRBL_POWER_DOWN (u32)(0x00000200)297 #define DRBL_DRV_VER_1 (u32)(0x00010000)298 #define DRBL_DRV_VER DRBL_DRV_VER_1299#define MU_DOORBELL_IN_ENB (u32)(0x00010464)300#define MU_DOORBELL_OUT (u32)(0x00010480)301 #define DRBL_PANIC_REASON_MASK (u32)(0x00F00000)302 #define DRBL_UNUSED_HANDLER (u32)(0x00100000)303 #define DRBL_UNDEF_INSTR (u32)(0x00200000)304 #define DRBL_PREFETCH_ABORT (u32)(0x00300000)305 #define DRBL_DATA_ABORT (u32)(0x00400000)306 #define DRBL_JUMP_TO_ZERO (u32)(0x00500000)307 #define DRBL_FW_RESET (u32)(0x00080000)308 #define DRBL_FW_VER_MSK (u32)(0x00070000)309 #define DRBL_FW_VER_0 (u32)(0x00000000)310 #define DRBL_FW_VER_1 (u32)(0x00010000)311 #define DRBL_FW_VER DRBL_FW_VER_1312#define MU_DOORBELL_OUT_ENB (u32)(0x00010484)313 #define DRBL_ENB_MASK (u32)(0x00F803FF)314#define MU_INT_STATUS_OUT (u32)(0x00010200)315 #define MU_INTSTAT_POST_OUT (u32)(0x00000010)316 #define MU_INTSTAT_DRBL_IN (u32)(0x00000100)317 #define MU_INTSTAT_DRBL (u32)(0x00001000)318 #define MU_INTSTAT_MASK (u32)(0x00001010)319#define MU_INT_MASK_OUT (u32)(0x0001020C)320 321/* PCI express registers accessed via window 1 */322#define MVR_PCI_WIN1_REMAP (u32)(0x00008438)323 #define MVRPW1R_ENABLE (u32)(0x00000001)324 325 326/* structures */327 328/* inbound list dynamic source entry */329struct esas2r_inbound_list_source_entry {330 u64 address;331 u32 length;332 #define HWILSE_INTERFACE_F0 0x00000000333 u32 reserved;334};335 336/* PCI data structure in expansion ROM images */337struct __packed esas2r_boot_header {338 char signature[4];339 u16 vendor_id;340 u16 device_id;341 u16 VPD;342 u16 struct_length;343 u8 struct_revision;344 u8 class_code[3];345 u16 image_length;346 u16 code_revision;347 u8 code_type;348 #define CODE_TYPE_PC 0349 #define CODE_TYPE_OPEN 1350 #define CODE_TYPE_EFI 3351 u8 indicator;352 #define INDICATOR_LAST 0x80353 u8 reserved[2];354};355 356struct __packed esas2r_boot_image {357 u16 signature;358 u8 reserved[22];359 u16 header_offset;360 u16 pnp_offset;361};362 363struct __packed esas2r_pc_image {364 u16 signature;365 u8 length;366 u8 entry_point[3];367 u8 checksum;368 u16 image_end;369 u16 min_size;370 u8 rom_flags;371 u8 reserved[12];372 u16 header_offset;373 u16 pnp_offset;374 struct esas2r_boot_header boot_image;375};376 377struct __packed esas2r_efi_image {378 u16 signature;379 u16 length;380 u32 efi_signature;381 #define EFI_ROM_SIG 0x00000EF1382 u16 image_type;383 #define EFI_IMAGE_APP 10384 #define EFI_IMAGE_BSD 11385 #define EFI_IMAGE_RTD 12386 u16 machine_type;387 #define EFI_MACHINE_IA32 0x014c388 #define EFI_MACHINE_IA64 0x0200389 #define EFI_MACHINE_X64 0x8664390 #define EFI_MACHINE_EBC 0x0EBC391 u16 compression;392 #define EFI_UNCOMPRESSED 0x0000393 #define EFI_COMPRESSED 0x0001394 u8 reserved[8];395 u16 efi_offset;396 u16 header_offset;397 u16 reserved2;398 struct esas2r_boot_header boot_image;399};400 401struct esas2r_adapter;402struct esas2r_sg_context;403struct esas2r_request;404 405typedef void (*RQCALLBK) (struct esas2r_adapter *a,406 struct esas2r_request *rq);407typedef bool (*RQBUILDSGL) (struct esas2r_adapter *a,408 struct esas2r_sg_context *sgc);409 410struct esas2r_component_header {411 u8 img_type;412 #define CH_IT_FW 0x00413 #define CH_IT_NVR 0x01414 #define CH_IT_BIOS 0x02415 #define CH_IT_MAC 0x03416 #define CH_IT_CFG 0x04417 #define CH_IT_EFI 0x05418 u8 status;419 #define CH_STAT_PENDING 0xff420 #define CH_STAT_FAILED 0x00421 #define CH_STAT_SUCCESS 0x01422 #define CH_STAT_RETRY 0x02423 #define CH_STAT_INVALID 0x03424 u8 pad[2];425 u32 version;426 u32 length;427 u32 image_offset;428};429 430#define FI_REL_VER_SZ 16431 432struct esas2r_flash_img_v0 {433 u8 fi_version;434 #define FI_VERSION_0 00435 u8 status;436 u8 adap_typ;437 u8 action;438 u32 length;439 u16 checksum;440 u16 driver_error;441 u16 flags;442 u16 num_comps;443 #define FI_NUM_COMPS_V0 5444 u8 rel_version[FI_REL_VER_SZ];445 struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V0];446 u8 scratch_buf[FM_BUF_SZ];447};448 449struct esas2r_flash_img {450 u8 fi_version;451 #define FI_VERSION_1 01452 u8 status;453 #define FI_STAT_SUCCESS 0x00454 #define FI_STAT_FAILED 0x01455 #define FI_STAT_REBOOT 0x02456 #define FI_STAT_ADAPTYP 0x03457 #define FI_STAT_INVALID 0x04458 #define FI_STAT_CHKSUM 0x05459 #define FI_STAT_LENGTH 0x06460 #define FI_STAT_UNKNOWN 0x07461 #define FI_STAT_IMG_VER 0x08462 #define FI_STAT_BUSY 0x09463 #define FI_STAT_DUAL 0x0A464 #define FI_STAT_MISSING 0x0B465 #define FI_STAT_UNSUPP 0x0C466 #define FI_STAT_ERASE 0x0D467 #define FI_STAT_FLASH 0x0E468 #define FI_STAT_DEGRADED 0x0F469 u8 adap_typ;470 #define FI_AT_UNKNWN 0xFF471 #define FI_AT_SUN_LAKE 0x0B472 #define FI_AT_MV_9580 0x0F473 u8 action;474 #define FI_ACT_DOWN 0x00475 #define FI_ACT_UP 0x01476 #define FI_ACT_UPSZ 0x02477 #define FI_ACT_MAX 0x02478 #define FI_ACT_DOWN1 0x80479 u32 length;480 u16 checksum;481 u16 driver_error;482 u16 flags;483 #define FI_FLG_NVR_DEF 0x0001484 u16 num_comps;485 #define FI_NUM_COMPS_V1 6486 u8 rel_version[FI_REL_VER_SZ];487 struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V1];488 u8 scratch_buf[FM_BUF_SZ];489};490 491/* definitions for flash script (FS) commands */492struct esas2r_ioctlfs_command {493 u8 command;494 #define ESAS2R_FS_CMD_ERASE 0495 #define ESAS2R_FS_CMD_READ 1496 #define ESAS2R_FS_CMD_BEGINW 2497 #define ESAS2R_FS_CMD_WRITE 3498 #define ESAS2R_FS_CMD_COMMIT 4499 #define ESAS2R_FS_CMD_CANCEL 5500 u8 checksum;501 u8 reserved[2];502 u32 flash_addr;503 u32 length;504 u32 image_offset;505};506 507struct esas2r_ioctl_fs {508 u8 version;509 #define ESAS2R_FS_VER 0510 u8 status;511 u8 driver_error;512 u8 adap_type;513 #define ESAS2R_FS_AT_ESASRAID2 3514 #define ESAS2R_FS_AT_TSSASRAID2 4515 #define ESAS2R_FS_AT_TSSASRAID2E 5516 #define ESAS2R_FS_AT_TLSASHBA 6517 u8 driver_ver;518 u8 reserved[11];519 struct esas2r_ioctlfs_command command;520 u8 data[1];521};522 523struct esas2r_sas_nvram {524 u8 signature[4];525 u8 version;526 #define SASNVR_VERSION_0 0x00527 #define SASNVR_VERSION SASNVR_VERSION_0528 u8 checksum;529 #define SASNVR_CKSUM_SEED 0x5A530 u8 max_lun_for_target;531 u8 pci_latency;532 #define SASNVR_PCILAT_DIS 0x00533 #define SASNVR_PCILAT_MIN 0x10534 #define SASNVR_PCILAT_MAX 0xF8535 u8 options1;536 #define SASNVR1_BOOT_DRVR 0x01537 #define SASNVR1_BOOT_SCAN 0x02538 #define SASNVR1_DIS_PCI_MWI 0x04539 #define SASNVR1_FORCE_ORD_Q 0x08540 #define SASNVR1_CACHELINE_0 0x10541 #define SASNVR1_DIS_DEVSORT 0x20542 #define SASNVR1_PWR_MGT_EN 0x40543 #define SASNVR1_WIDEPORT 0x80544 u8 options2;545 #define SASNVR2_SINGLE_BUS 0x01546 #define SASNVR2_SLOT_BIND 0x02547 #define SASNVR2_EXP_PROG 0x04548 #define SASNVR2_CMDTHR_LUN 0x08549 #define SASNVR2_HEARTBEAT 0x10550 #define SASNVR2_INT_CONNECT 0x20551 #define SASNVR2_SW_MUX_CTRL 0x40552 #define SASNVR2_DISABLE_NCQ 0x80553 u8 int_coalescing;554 #define SASNVR_COAL_DIS 0x00555 #define SASNVR_COAL_LOW 0x01556 #define SASNVR_COAL_MED 0x02557 #define SASNVR_COAL_HI 0x03558 u8 cmd_throttle;559 #define SASNVR_CMDTHR_NONE 0x00560 u8 dev_wait_time;561 u8 dev_wait_count;562 u8 spin_up_delay;563 #define SASNVR_SPINUP_MAX 0x14564 u8 ssp_align_rate;565 u8 sas_addr[8];566 u8 phy_speed[16];567 #define SASNVR_SPEED_AUTO 0x00568 #define SASNVR_SPEED_1_5GB 0x01569 #define SASNVR_SPEED_3GB 0x02570 #define SASNVR_SPEED_6GB 0x03571 #define SASNVR_SPEED_12GB 0x04572 u8 phy_mux[16];573 #define SASNVR_MUX_DISABLED 0x00574 #define SASNVR_MUX_1_5GB 0x01575 #define SASNVR_MUX_3GB 0x02576 #define SASNVR_MUX_6GB 0x03577 u8 phy_flags[16];578 #define SASNVR_PHF_DISABLED 0x01579 #define SASNVR_PHF_RD_ONLY 0x02580 u8 sort_type;581 #define SASNVR_SORT_SAS_ADDR 0x00582 #define SASNVR_SORT_H308_CONN 0x01583 #define SASNVR_SORT_PHY_ID 0x02584 #define SASNVR_SORT_SLOT_ID 0x03585 u8 dpm_reqcmd_lmt;586 u8 dpm_stndby_time;587 u8 dpm_active_time;588 u8 phy_target_id[16];589 #define SASNVR_PTI_DISABLED 0xFF590 u8 virt_ses_mode;591 #define SASNVR_VSMH_DISABLED 0x00592 u8 read_write_mode;593 #define SASNVR_RWM_DEFAULT 0x00594 u8 link_down_to;595 u8 reserved[0xA1];596};597 598typedef u32 (*PGETPHYSADDR) (struct esas2r_sg_context *sgc, u64 *addr);599 600struct esas2r_sg_context {601 struct esas2r_adapter *adapter;602 struct esas2r_request *first_req;603 u32 length;604 u8 *cur_offset;605 PGETPHYSADDR get_phys_addr;606 union {607 struct {608 struct atto_vda_sge *curr;609 struct atto_vda_sge *last;610 struct atto_vda_sge *limit;611 struct atto_vda_sge *chain;612 } a64;613 struct {614 struct atto_physical_region_description *curr;615 struct atto_physical_region_description *chain;616 u32 sgl_max_cnt;617 u32 sge_cnt;618 } prd;619 } sge;620 struct scatterlist *cur_sgel;621 u8 *exp_offset;622 int num_sgel;623 int sgel_count;624};625 626struct esas2r_target {627 u8 flags;628 #define TF_PASS_THRU 0x01629 #define TF_USED 0x02630 u8 new_target_state;631 u8 target_state;632 u8 buffered_target_state;633#define TS_NOT_PRESENT 0x00634#define TS_PRESENT 0x05635#define TS_LUN_CHANGE 0x06636#define TS_INVALID 0xFF637 u32 block_size;638 u32 inter_block;639 u32 inter_byte;640 u16 virt_targ_id;641 u16 phys_targ_id;642 u8 identifier_len;643 u64 sas_addr;644 u8 identifier[60];645 struct atto_vda_ae_lu lu_event;646};647 648struct esas2r_request {649 struct list_head comp_list;650 struct list_head req_list;651 union atto_vda_req *vrq;652 struct esas2r_mem_desc *vrq_md;653 union {654 void *data_buf;655 union atto_vda_rsp_data *vda_rsp_data;656 };657 u8 *sense_buf;658 struct list_head sg_table_head;659 struct esas2r_mem_desc *sg_table;660 u32 timeout;661 #define RQ_TIMEOUT_S1 0xFFFFFFFF662 #define RQ_TIMEOUT_S2 0xFFFFFFFE663 #define RQ_MAX_TIMEOUT 0xFFFFFFFD664 u16 target_id;665 u8 req_type;666 #define RT_INI_REQ 0x01667 #define RT_DISC_REQ 0x02668 u8 sense_len;669 union atto_vda_func_rsp func_rsp;670 RQCALLBK comp_cb;671 RQCALLBK interrupt_cb;672 void *interrupt_cx;673 u8 flags;674 #define RF_1ST_IBLK_BASE 0x04675 #define RF_FAILURE_OK 0x08676 u8 req_stat;677 u16 vda_req_sz;678 #define RQ_SIZE_DEFAULT 0679 u64 lba;680 RQCALLBK aux_req_cb;681 void *aux_req_cx;682 u32 blk_len;683 u32 max_blk_len;684 union {685 struct scsi_cmnd *cmd;686 u8 *task_management_status_ptr;687 };688};689 690struct esas2r_flash_context {691 struct esas2r_flash_img *fi;692 RQCALLBK interrupt_cb;693 u8 *sgc_offset;694 u8 *scratch;695 u32 fi_hdr_len;696 u8 task;697 #define FMTSK_ERASE_BOOT 0698 #define FMTSK_WRTBIOS 1699 #define FMTSK_READBIOS 2700 #define FMTSK_WRTMAC 3701 #define FMTSK_READMAC 4702 #define FMTSK_WRTEFI 5703 #define FMTSK_READEFI 6704 #define FMTSK_WRTCFG 7705 #define FMTSK_READCFG 8706 u8 func;707 u16 num_comps;708 u32 cmp_len;709 u32 flsh_addr;710 u32 curr_len;711 u8 comp_typ;712 struct esas2r_sg_context sgc;713};714 715struct esas2r_disc_context {716 u8 disc_evt;717 #define DCDE_DEV_CHANGE 0x01718 #define DCDE_DEV_SCAN 0x02719 u8 state;720 #define DCS_DEV_RMV 0x00721 #define DCS_DEV_ADD 0x01722 #define DCS_BLOCK_DEV_SCAN 0x02723 #define DCS_RAID_GRP_INFO 0x03724 #define DCS_PART_INFO 0x04725 #define DCS_PT_DEV_INFO 0x05726 #define DCS_PT_DEV_ADDR 0x06727 #define DCS_DISC_DONE 0xFF728 u16 flags;729 #define DCF_DEV_CHANGE 0x0001730 #define DCF_DEV_SCAN 0x0002731 #define DCF_POLLED 0x8000732 u32 interleave;733 u32 block_size;734 u16 dev_ix;735 u8 part_num;736 u8 raid_grp_ix;737 char raid_grp_name[16];738 struct esas2r_target *curr_targ;739 u16 curr_virt_id;740 u16 curr_phys_id;741 u8 scan_gen;742 u8 dev_addr_type;743 u64 sas_addr;744};745 746struct esas2r_mem_desc {747 struct list_head next_desc;748 void *virt_addr;749 u64 phys_addr;750 void *pad;751 void *esas2r_data;752 u32 esas2r_param;753 u32 size;754};755 756enum fw_event_type {757 fw_event_null,758 fw_event_lun_change,759 fw_event_present,760 fw_event_not_present,761 fw_event_vda_ae762};763 764struct esas2r_vda_ae {765 u32 signature;766#define ESAS2R_VDA_EVENT_SIG 0x4154544F767 u8 bus_number;768 u8 devfn;769 u8 pad[2];770 union atto_vda_ae vda_ae;771};772 773struct esas2r_fw_event_work {774 struct list_head list;775 struct delayed_work work;776 struct esas2r_adapter *a;777 enum fw_event_type type;778 u8 data[sizeof(struct esas2r_vda_ae)];779};780 781enum state {782 FW_INVALID_ST,783 FW_STATUS_ST,784 FW_COMMAND_ST785};786 787struct esas2r_firmware {788 enum state state;789 struct esas2r_flash_img header;790 u8 *data;791 u64 phys;792 int orig_len;793 void *header_buff;794 u64 header_buff_phys;795};796 797struct esas2r_adapter {798 struct esas2r_target targetdb[ESAS2R_MAX_TARGETS];799 struct esas2r_target *targetdb_end;800 unsigned char *regs;801 unsigned char *data_window;802 long flags;803 #define AF_PORT_CHANGE 0804 #define AF_CHPRST_NEEDED 1805 #define AF_CHPRST_PENDING 2806 #define AF_CHPRST_DETECTED 3807 #define AF_BUSRST_NEEDED 4808 #define AF_BUSRST_PENDING 5809 #define AF_BUSRST_DETECTED 6810 #define AF_DISABLED 7811 #define AF_FLASH_LOCK 8812 #define AF_OS_RESET 9813 #define AF_FLASHING 10814 #define AF_POWER_MGT 11815 #define AF_NVR_VALID 12816 #define AF_DEGRADED_MODE 13817 #define AF_DISC_PENDING 14818 #define AF_TASKLET_SCHEDULED 15819 #define AF_HEARTBEAT 16820 #define AF_HEARTBEAT_ENB 17821 #define AF_NOT_PRESENT 18822 #define AF_CHPRST_STARTED 19823 #define AF_FIRST_INIT 20824 #define AF_POWER_DOWN 21825 #define AF_DISC_IN_PROG 22826 #define AF_COMM_LIST_TOGGLE 23827 #define AF_LEGACY_SGE_MODE 24828 #define AF_DISC_POLLED 25829 long flags2;830 #define AF2_SERIAL_FLASH 0831 #define AF2_DEV_SCAN 1832 #define AF2_DEV_CNT_OK 2833 #define AF2_COREDUMP_AVAIL 3834 #define AF2_COREDUMP_SAVED 4835 #define AF2_VDA_POWER_DOWN 5836 #define AF2_THUNDERLINK 6837 #define AF2_THUNDERBOLT 7838 #define AF2_INIT_DONE 8839 #define AF2_INT_PENDING 9840 #define AF2_TIMER_TICK 10841 #define AF2_IRQ_CLAIMED 11842 #define AF2_MSI_ENABLED 12843 atomic_t disable_cnt;844 atomic_t dis_ints_cnt;845 u32 int_stat;846 u32 int_mask;847 u32 volatile *outbound_copy;848 struct list_head avail_request;849 spinlock_t request_lock;850 spinlock_t sg_list_lock;851 spinlock_t queue_lock;852 spinlock_t mem_lock;853 struct list_head free_sg_list_head;854 struct esas2r_mem_desc *sg_list_mds;855 struct list_head active_list;856 struct list_head defer_list;857 struct esas2r_request **req_table;858 union {859 u16 prev_dev_cnt;860 u32 heartbeat_time;861 #define ESAS2R_HEARTBEAT_TIME (3000)862 };863 u32 chip_uptime;864 #define ESAS2R_CHP_UPTIME_MAX (60000)865 #define ESAS2R_CHP_UPTIME_CNT (20000)866 u64 uncached_phys;867 u8 *uncached;868 struct esas2r_sas_nvram *nvram;869 struct esas2r_request general_req;870 u8 init_msg;871 #define ESAS2R_INIT_MSG_START 1872 #define ESAS2R_INIT_MSG_INIT 2873 #define ESAS2R_INIT_MSG_GET_INIT 3874 #define ESAS2R_INIT_MSG_REINIT 4875 u16 cmd_ref_no;876 u32 fw_version;877 u32 fw_build;878 u32 chip_init_time;879 #define ESAS2R_CHPRST_TIME (180000)880 #define ESAS2R_CHPRST_WAIT_TIME (2000)881 u32 last_tick_time;882 u32 window_base;883 RQBUILDSGL build_sgl;884 struct esas2r_request *first_ae_req;885 u32 list_size;886 u32 last_write;887 u32 last_read;888 u16 max_vdareq_size;889 u16 disc_wait_cnt;890 struct esas2r_mem_desc inbound_list_md;891 struct esas2r_mem_desc outbound_list_md;892 struct esas2r_disc_context disc_ctx;893 u8 *disc_buffer;894 u32 disc_start_time;895 u32 disc_wait_time;896 u32 flash_ver;897 char flash_rev[16];898 char fw_rev[16];899 char image_type[16];900 struct esas2r_flash_context flash_context;901 u32 num_targets_backend;902 u32 ioctl_tunnel;903 struct tasklet_struct tasklet;904 struct pci_dev *pcid;905 struct Scsi_Host *host;906 unsigned int index;907 char name[32];908 struct timer_list timer;909 struct esas2r_firmware firmware;910 wait_queue_head_t nvram_waiter;911 int nvram_command_done;912 wait_queue_head_t fm_api_waiter;913 int fm_api_command_done;914 wait_queue_head_t vda_waiter;915 int vda_command_done;916 u8 *vda_buffer;917 u64 ppvda_buffer;918#define VDA_BUFFER_HEADER_SZ (offsetof(struct atto_ioctl_vda, data))919#define VDA_MAX_BUFFER_SIZE (0x40000 + VDA_BUFFER_HEADER_SZ)920 wait_queue_head_t fs_api_waiter;921 int fs_api_command_done;922 u64 ppfs_api_buffer;923 u8 *fs_api_buffer;924 u32 fs_api_buffer_size;925 wait_queue_head_t buffered_ioctl_waiter;926 int buffered_ioctl_done;927 int uncached_size;928 struct workqueue_struct *fw_event_q;929 struct list_head fw_event_list;930 spinlock_t fw_event_lock;931 u8 fw_events_off; /* if '1', then ignore events */932 /*933 * intr_mode stores the interrupt mode currently being used by this934 * adapter. it is based on the interrupt_mode module parameter, but935 * can be changed based on the ability (or not) to utilize the936 * mode requested by the parameter.937 */938 int intr_mode;939#define INTR_MODE_LEGACY 0940#define INTR_MODE_MSI 1941#define INTR_MODE_MSIX 2942 struct esas2r_sg_context fm_api_sgc;943 u8 *save_offset;944 struct list_head vrq_mds_head;945 struct esas2r_mem_desc *vrq_mds;946 int num_vrqs;947 struct mutex fm_api_mutex;948 struct mutex fs_api_mutex;949 struct semaphore nvram_semaphore;950 struct atto_ioctl *local_atto_ioctl;951 u8 fw_coredump_buff[ESAS2R_FWCOREDUMP_SZ];952 unsigned int sysfs_fw_created:1;953 unsigned int sysfs_fs_created:1;954 unsigned int sysfs_vda_created:1;955 unsigned int sysfs_hw_created:1;956 unsigned int sysfs_live_nvram_created:1;957 unsigned int sysfs_default_nvram_created:1;958};959 960/*961 * Function Declarations962 * SCSI functions963 */964const char *esas2r_info(struct Scsi_Host *);965int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,966 struct esas2r_sas_nvram *data);967int esas2r_ioctl_handler(void *hostdata, unsigned int cmd, void __user *arg);968int esas2r_ioctl(struct scsi_device *dev, unsigned int cmd, void __user *arg);969u8 handle_hba_ioctl(struct esas2r_adapter *a,970 struct atto_ioctl *ioctl_hba);971int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd);972int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh);973long esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);974 975/* SCSI error handler (eh) functions */976int esas2r_eh_abort(struct scsi_cmnd *cmd);977int esas2r_device_reset(struct scsi_cmnd *cmd);978int esas2r_host_reset(struct scsi_cmnd *cmd);979int esas2r_bus_reset(struct scsi_cmnd *cmd);980int esas2r_target_reset(struct scsi_cmnd *cmd);981 982/* Internal functions */983int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,984 int index);985int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count);986int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,987 int count);988int esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count);989int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,990 int count);991int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count);992int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,993 int count);994void esas2r_adapter_tasklet(unsigned long context);995irqreturn_t esas2r_interrupt(int irq, void *dev_id);996irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id);997void esas2r_kickoff_timer(struct esas2r_adapter *a);998 999extern const struct dev_pm_ops esas2r_pm_ops;1000 1001void esas2r_fw_event_off(struct esas2r_adapter *a);1002void esas2r_fw_event_on(struct esas2r_adapter *a);1003bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,1004 struct esas2r_sas_nvram *nvram);1005void esas2r_nvram_get_defaults(struct esas2r_adapter *a,1006 struct esas2r_sas_nvram *nvram);1007void esas2r_complete_request_cb(struct esas2r_adapter *a,1008 struct esas2r_request *rq);1009void esas2r_reset_detected(struct esas2r_adapter *a);1010void esas2r_target_state_changed(struct esas2r_adapter *ha, u16 targ_id,1011 u8 state);1012int esas2r_req_status_to_error(u8 req_stat);1013void esas2r_kill_adapter(int i);1014void esas2r_free_request(struct esas2r_adapter *a, struct esas2r_request *rq);1015struct esas2r_request *esas2r_alloc_request(struct esas2r_adapter *a);1016u32 esas2r_get_uncached_size(struct esas2r_adapter *a);1017bool esas2r_init_adapter_struct(struct esas2r_adapter *a,1018 void **uncached_area);1019bool esas2r_check_adapter(struct esas2r_adapter *a);1020bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll);1021void esas2r_start_request(struct esas2r_adapter *a, struct esas2r_request *rq);1022bool esas2r_send_task_mgmt(struct esas2r_adapter *a,1023 struct esas2r_request *rqaux, u8 task_mgt_func);1024void esas2r_do_tasklet_tasks(struct esas2r_adapter *a);1025void esas2r_adapter_interrupt(struct esas2r_adapter *a);1026void esas2r_do_deferred_processes(struct esas2r_adapter *a);1027void esas2r_reset_bus(struct esas2r_adapter *a);1028void esas2r_reset_adapter(struct esas2r_adapter *a);1029void esas2r_timer_tick(struct esas2r_adapter *a);1030const char *esas2r_get_model_name(struct esas2r_adapter *a);1031const char *esas2r_get_model_name_short(struct esas2r_adapter *a);1032u32 esas2r_stall_execution(struct esas2r_adapter *a, u32 start_time,1033 u32 *delay);1034void esas2r_build_flash_req(struct esas2r_adapter *a,1035 struct esas2r_request *rq,1036 u8 sub_func,1037 u8 cksum,1038 u32 addr,1039 u32 length);1040void esas2r_build_mgt_req(struct esas2r_adapter *a,1041 struct esas2r_request *rq,1042 u8 sub_func,1043 u8 scan_gen,1044 u16 dev_index,1045 u32 length,1046 void *data);1047void esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq);1048void esas2r_build_cli_req(struct esas2r_adapter *a,1049 struct esas2r_request *rq,1050 u32 length,1051 u32 cmd_rsp_len);1052void esas2r_build_ioctl_req(struct esas2r_adapter *a,1053 struct esas2r_request *rq,1054 u32 length,1055 u8 sub_func);1056void esas2r_build_cfg_req(struct esas2r_adapter *a,1057 struct esas2r_request *rq,1058 u8 sub_func,1059 u32 length,1060 void *data);1061void esas2r_power_down(struct esas2r_adapter *a);1062bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll);1063void esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq);1064u32 esas2r_map_data_window(struct esas2r_adapter *a, u32 addr_lo);1065bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,1066 struct esas2r_ioctl_fs *fs,1067 struct esas2r_request *rq,1068 struct esas2r_sg_context *sgc);1069bool esas2r_read_flash_block(struct esas2r_adapter *a, void *to, u32 from,1070 u32 size);1071bool esas2r_read_mem_block(struct esas2r_adapter *a, void *to, u32 from,1072 u32 size);1073bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,1074 struct esas2r_request *rq, struct esas2r_sg_context *sgc);1075void esas2r_force_interrupt(struct esas2r_adapter *a);1076void esas2r_local_start_request(struct esas2r_adapter *a,1077 struct esas2r_request *rq);1078void esas2r_process_adapter_reset(struct esas2r_adapter *a);1079void esas2r_complete_request(struct esas2r_adapter *a,1080 struct esas2r_request *rq);1081void esas2r_dummy_complete(struct esas2r_adapter *a,1082 struct esas2r_request *rq);1083void esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq);1084void esas2r_start_vda_request(struct esas2r_adapter *a,1085 struct esas2r_request *rq);1086bool esas2r_read_flash_rev(struct esas2r_adapter *a);1087bool esas2r_read_image_type(struct esas2r_adapter *a);1088bool esas2r_nvram_read_direct(struct esas2r_adapter *a);1089bool esas2r_nvram_validate(struct esas2r_adapter *a);1090void esas2r_nvram_set_defaults(struct esas2r_adapter *a);1091bool esas2r_print_flash_rev(struct esas2r_adapter *a);1092void esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt);1093bool esas2r_init_msgs(struct esas2r_adapter *a);1094bool esas2r_is_adapter_present(struct esas2r_adapter *a);1095void esas2r_nuxi_mgt_data(u8 function, void *data);1096void esas2r_nuxi_cfg_data(u8 function, void *data);1097void esas2r_nuxi_ae_data(union atto_vda_ae *ae);1098void esas2r_reset_chip(struct esas2r_adapter *a);1099void esas2r_log_request_failure(struct esas2r_adapter *a,1100 struct esas2r_request *rq);1101void esas2r_polled_interrupt(struct esas2r_adapter *a);1102bool esas2r_ioreq_aborted(struct esas2r_adapter *a, struct esas2r_request *rq,1103 u8 status);1104bool esas2r_build_sg_list_sge(struct esas2r_adapter *a,1105 struct esas2r_sg_context *sgc);1106bool esas2r_build_sg_list_prd(struct esas2r_adapter *a,1107 struct esas2r_sg_context *sgc);1108void esas2r_targ_db_initialize(struct esas2r_adapter *a);1109void esas2r_targ_db_remove_all(struct esas2r_adapter *a, bool notify);1110void esas2r_targ_db_report_changes(struct esas2r_adapter *a);1111struct esas2r_target *esas2r_targ_db_add_raid(struct esas2r_adapter *a,1112 struct esas2r_disc_context *dc);1113struct esas2r_target *esas2r_targ_db_add_pthru(struct esas2r_adapter *a,1114 struct esas2r_disc_context *dc,1115 u8 *ident,1116 u8 ident_len);1117void esas2r_targ_db_remove(struct esas2r_adapter *a, struct esas2r_target *t);1118struct esas2r_target *esas2r_targ_db_find_by_sas_addr(struct esas2r_adapter *a,1119 u64 *sas_addr);1120struct esas2r_target *esas2r_targ_db_find_by_ident(struct esas2r_adapter *a,1121 void *identifier,1122 u8 ident_len);1123u16 esas2r_targ_db_find_next_present(struct esas2r_adapter *a, u16 target_id);1124struct esas2r_target *esas2r_targ_db_find_by_virt_id(struct esas2r_adapter *a,1125 u16 virt_id);1126u16 esas2r_targ_db_get_tgt_cnt(struct esas2r_adapter *a);1127void esas2r_disc_initialize(struct esas2r_adapter *a);1128void esas2r_disc_start_waiting(struct esas2r_adapter *a);1129void esas2r_disc_check_for_work(struct esas2r_adapter *a);1130void esas2r_disc_check_complete(struct esas2r_adapter *a);1131void esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt);1132bool esas2r_disc_start_port(struct esas2r_adapter *a);1133void esas2r_disc_local_start_request(struct esas2r_adapter *a,1134 struct esas2r_request *rq);1135bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str);1136bool esas2r_process_vda_ioctl(struct esas2r_adapter *a,1137 struct atto_ioctl_vda *vi,1138 struct esas2r_request *rq,1139 struct esas2r_sg_context *sgc);1140void esas2r_queue_fw_event(struct esas2r_adapter *a,1141 enum fw_event_type type,1142 void *data,1143 int data_sz);1144 1145/* Inline functions */1146 1147/* Allocate a chip scatter/gather list entry */1148static inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a)1149{1150 unsigned long flags;1151 struct list_head *sgl;1152 struct esas2r_mem_desc *result = NULL;1153 1154 spin_lock_irqsave(&a->sg_list_lock, flags);1155 if (likely(!list_empty(&a->free_sg_list_head))) {1156 sgl = a->free_sg_list_head.next;1157 result = list_entry(sgl, struct esas2r_mem_desc, next_desc);1158 list_del_init(sgl);1159 }1160 spin_unlock_irqrestore(&a->sg_list_lock, flags);1161 1162 return result;1163}1164 1165/* Initialize a scatter/gather context */1166static inline void esas2r_sgc_init(struct esas2r_sg_context *sgc,1167 struct esas2r_adapter *a,1168 struct esas2r_request *rq,1169 struct atto_vda_sge *first)1170{1171 sgc->adapter = a;1172 sgc->first_req = rq;1173 1174 /*1175 * set the limit pointer such that an SGE pointer above this value1176 * would be the first one to overflow the SGL.1177 */1178 sgc->sge.a64.limit = (struct atto_vda_sge *)((u8 *)rq->vrq1179 + (sizeof(union1180 atto_vda_req) /1181 8)1182 - sizeof(struct1183 atto_vda_sge));1184 if (first) {1185 sgc->sge.a64.last =1186 sgc->sge.a64.curr = first;1187 rq->vrq->scsi.sg_list_offset = (u8)1188 ((u8 *)first -1189 (u8 *)rq->vrq);1190 } else {1191 sgc->sge.a64.last =1192 sgc->sge.a64.curr = &rq->vrq->scsi.u.sge[0];1193 rq->vrq->scsi.sg_list_offset =1194 (u8)offsetof(struct atto_vda_scsi_req, u.sge);1195 }1196 sgc->sge.a64.chain = NULL;1197}1198 1199static inline void esas2r_rq_init_request(struct esas2r_request *rq,1200 struct esas2r_adapter *a)1201{1202 union atto_vda_req *vrq = rq->vrq;1203 1204 INIT_LIST_HEAD(&rq->sg_table_head);1205 rq->data_buf = (void *)(vrq + 1);1206 rq->interrupt_cb = NULL;1207 rq->comp_cb = esas2r_complete_request_cb;1208 rq->flags = 0;1209 rq->timeout = 0;1210 rq->req_stat = RS_PENDING;1211 rq->req_type = RT_INI_REQ;1212 1213 /* clear the outbound response */1214 rq->func_rsp.dwords[0] = 0;1215 rq->func_rsp.dwords[1] = 0;1216 1217 /*1218 * clear the size of the VDA request. esas2r_build_sg_list() will1219 * only allow the size of the request to grow. there are some1220 * management requests that go through there twice and the second1221 * time through sets a smaller request size. if this is not modified1222 * at all we'll set it to the size of the entire VDA request.1223 */1224 rq->vda_req_sz = RQ_SIZE_DEFAULT;1225 1226 /* req_table entry should be NULL at this point - if not, halt */1227 1228 if (a->req_table[LOWORD(vrq->scsi.handle)]) {1229 esas2r_bugon();1230 }1231 1232 /* fill in the table for this handle so we can get back to the1233 * request.1234 */1235 a->req_table[LOWORD(vrq->scsi.handle)] = rq;1236 1237 /*1238 * add a reference number to the handle to make it unique (until it1239 * wraps of course) while preserving the least significant word1240 */1241 vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle;1242 1243 /*1244 * the following formats a SCSI request. the caller can override as1245 * necessary. clear_vda_request can be called to clear the VDA1246 * request for another type of request.1247 */1248 vrq->scsi.function = VDA_FUNC_SCSI;1249 vrq->scsi.sense_len = SENSE_DATA_SZ;1250 1251 /* clear out sg_list_offset and chain_offset */1252 vrq->scsi.sg_list_offset = 0;1253 vrq->scsi.chain_offset = 0;1254 vrq->scsi.flags = 0;1255 vrq->scsi.reserved = 0;1256 1257 /* set the sense buffer to be the data payload buffer */1258 vrq->scsi.ppsense_buf1259 = cpu_to_le64(rq->vrq_md->phys_addr +1260 sizeof(union atto_vda_req));1261}1262 1263static inline void esas2r_rq_free_sg_lists(struct esas2r_request *rq,1264 struct esas2r_adapter *a)1265{1266 unsigned long flags;1267 1268 if (list_empty(&rq->sg_table_head))1269 return;1270 1271 spin_lock_irqsave(&a->sg_list_lock, flags);1272 list_splice_tail_init(&rq->sg_table_head, &a->free_sg_list_head);1273 spin_unlock_irqrestore(&a->sg_list_lock, flags);1274}1275 1276static inline void esas2r_rq_destroy_request(struct esas2r_request *rq,1277 struct esas2r_adapter *a)1278 1279{1280 esas2r_rq_free_sg_lists(rq, a);1281 a->req_table[LOWORD(rq->vrq->scsi.handle)] = NULL;1282 rq->data_buf = NULL;1283}1284 1285static inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a)1286{1287 1288 return test_bit(AF_BUSRST_NEEDED, &a->flags) ||1289 test_bit(AF_BUSRST_DETECTED, &a->flags) ||1290 test_bit(AF_CHPRST_NEEDED, &a->flags) ||1291 test_bit(AF_CHPRST_DETECTED, &a->flags) ||1292 test_bit(AF_PORT_CHANGE, &a->flags);1293 1294}1295 1296/*1297 * Build the scatter/gather list for an I/O request according to the1298 * specifications placed in the esas2r_sg_context. The caller must initialize1299 * struct esas2r_sg_context prior to the initial call by calling1300 * esas2r_sgc_init()1301 */1302static inline bool esas2r_build_sg_list(struct esas2r_adapter *a,1303 struct esas2r_request *rq,1304 struct esas2r_sg_context *sgc)1305{1306 if (unlikely(le32_to_cpu(rq->vrq->scsi.length) == 0))1307 return true;1308 1309 return (*a->build_sgl)(a, sgc);1310}1311 1312static inline void esas2r_disable_chip_interrupts(struct esas2r_adapter *a)1313{1314 if (atomic_inc_return(&a->dis_ints_cnt) == 1)1315 esas2r_write_register_dword(a, MU_INT_MASK_OUT,1316 ESAS2R_INT_DIS_MASK);1317}1318 1319static inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a)1320{1321 if (atomic_dec_return(&a->dis_ints_cnt) == 0)1322 esas2r_write_register_dword(a, MU_INT_MASK_OUT,1323 ESAS2R_INT_ENB_MASK);1324}1325 1326/* Schedule a TASKLET to perform non-interrupt tasks that may require delays1327 * or long completion times.1328 */1329static inline void esas2r_schedule_tasklet(struct esas2r_adapter *a)1330{1331 /* make sure we don't schedule twice */1332 if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags))1333 tasklet_hi_schedule(&a->tasklet);1334}1335 1336static inline void esas2r_enable_heartbeat(struct esas2r_adapter *a)1337{1338 if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&1339 !test_bit(AF_CHPRST_PENDING, &a->flags) &&1340 (a->nvram->options2 & SASNVR2_HEARTBEAT))1341 set_bit(AF_HEARTBEAT_ENB, &a->flags);1342 else1343 clear_bit(AF_HEARTBEAT_ENB, &a->flags);1344}1345 1346static inline void esas2r_disable_heartbeat(struct esas2r_adapter *a)1347{1348 clear_bit(AF_HEARTBEAT_ENB, &a->flags);1349 clear_bit(AF_HEARTBEAT, &a->flags);1350}1351 1352/* Set the initial state for resetting the adapter on the next pass through1353 * esas2r_do_deferred.1354 */1355static inline void esas2r_local_reset_adapter(struct esas2r_adapter *a)1356{1357 esas2r_disable_heartbeat(a);1358 1359 set_bit(AF_CHPRST_NEEDED, &a->flags);1360 set_bit(AF_CHPRST_PENDING, &a->flags);1361 set_bit(AF_DISC_PENDING, &a->flags);1362}1363 1364/* See if an interrupt is pending on the adapter. */1365static inline bool esas2r_adapter_interrupt_pending(struct esas2r_adapter *a)1366{1367 u32 intstat;1368 1369 if (a->int_mask == 0)1370 return false;1371 1372 intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);1373 1374 if ((intstat & a->int_mask) == 0)1375 return false;1376 1377 esas2r_disable_chip_interrupts(a);1378 1379 a->int_stat = intstat;1380 a->int_mask = 0;1381 1382 return true;1383}1384 1385static inline u16 esas2r_targ_get_id(struct esas2r_target *t,1386 struct esas2r_adapter *a)1387{1388 return (u16)(uintptr_t)(t - a->targetdb);1389}1390 1391/* Build and start an asynchronous event request */1392static inline void esas2r_start_ae_request(struct esas2r_adapter *a,1393 struct esas2r_request *rq)1394{1395 unsigned long flags;1396 1397 esas2r_build_ae_req(a, rq);1398 1399 spin_lock_irqsave(&a->queue_lock, flags);1400 esas2r_start_vda_request(a, rq);1401 spin_unlock_irqrestore(&a->queue_lock, flags);1402}1403 1404static inline void esas2r_comp_list_drain(struct esas2r_adapter *a,1405 struct list_head *comp_list)1406{1407 struct esas2r_request *rq;1408 struct list_head *element, *next;1409 1410 list_for_each_safe(element, next, comp_list) {1411 rq = list_entry(element, struct esas2r_request, comp_list);1412 list_del_init(element);1413 esas2r_complete_request(a, rq);1414 }1415}1416 1417/* sysfs handlers */1418extern struct bin_attribute bin_attr_fw;1419extern struct bin_attribute bin_attr_fs;1420extern struct bin_attribute bin_attr_vda;1421extern struct bin_attribute bin_attr_hw;1422extern struct bin_attribute bin_attr_live_nvram;1423extern struct bin_attribute bin_attr_default_nvram;1424 1425#endif /* ESAS2R_H */1426