12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427 |
- /*
- * linux/drivers/scsi/esas2r/esas2r.h
- * For use with ATTO ExpressSAS R6xx SAS/SATA RAID controllers
- *
- * Copyright (c) 2001-2013 ATTO Technology, Inc.
- * (mailto:linuxdrivers@attotech.com)
- *
- * 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 the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * NO WARRANTY
- * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
- * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
- * solely responsible for determining the appropriateness of using and
- * distributing the Program and assumes all risks associated with its
- * exercise of rights under this Agreement, including but not limited to
- * the risks and costs of program errors, damage to or loss of data,
- * programs or equipment, and unavailability or interruption of operations.
- *
- * DISCLAIMER OF LIABILITY
- * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
- * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
- * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
- */
- #include <linux/kernel.h>
- #include <linux/delay.h>
- #include <linux/pci.h>
- #include <linux/proc_fs.h>
- #include <linux/workqueue.h>
- #include <linux/interrupt.h>
- #include <linux/module.h>
- #include <linux/vmalloc.h>
- #include <scsi/scsi.h>
- #include <scsi/scsi_host.h>
- #include <scsi/scsi_cmnd.h>
- #include <scsi/scsi_device.h>
- #include <scsi/scsi_eh.h>
- #include <scsi/scsi_tcq.h>
- #include "esas2r_log.h"
- #include "atioctl.h"
- #include "atvda.h"
- #ifndef ESAS2R_H
- #define ESAS2R_H
- /* Global Variables */
- extern struct esas2r_adapter *esas2r_adapters[];
- extern u8 *esas2r_buffered_ioctl;
- extern dma_addr_t esas2r_buffered_ioctl_addr;
- extern u32 esas2r_buffered_ioctl_size;
- extern struct pci_dev *esas2r_buffered_ioctl_pcid;
- #define SGL_PG_SZ_MIN 64
- #define SGL_PG_SZ_MAX 1024
- extern int sgl_page_size;
- #define NUM_SGL_MIN 8
- #define NUM_SGL_MAX 2048
- extern int num_sg_lists;
- #define NUM_REQ_MIN 4
- #define NUM_REQ_MAX 256
- extern int num_requests;
- #define NUM_AE_MIN 2
- #define NUM_AE_MAX 8
- extern int num_ae_requests;
- extern int cmd_per_lun;
- extern int can_queue;
- extern int esas2r_max_sectors;
- extern int sg_tablesize;
- extern int interrupt_mode;
- extern int num_io_requests;
- /* Macro defintions */
- #define ESAS2R_MAX_ID 255
- #define MAX_ADAPTERS 32
- #define ESAS2R_DRVR_NAME "esas2r"
- #define ESAS2R_LONGNAME "ATTO ExpressSAS 6GB RAID Adapter"
- #define ESAS2R_MAX_DEVICES 32
- #define ATTONODE_NAME "ATTONode"
- #define ESAS2R_MAJOR_REV 1
- #define ESAS2R_MINOR_REV 00
- #define ESAS2R_VERSION_STR DEFINED_NUM_TO_STR(ESAS2R_MAJOR_REV) "." \
- DEFINED_NUM_TO_STR(ESAS2R_MINOR_REV)
- #define ESAS2R_COPYRIGHT_YEARS "2001-2013"
- #define ESAS2R_DEFAULT_SGL_PAGE_SIZE 384
- #define ESAS2R_DEFAULT_CMD_PER_LUN 64
- #define ESAS2R_DEFAULT_NUM_SG_LISTS 1024
- #define DEFINED_NUM_TO_STR(num) NUM_TO_STR(num)
- #define NUM_TO_STR(num) #num
- #define ESAS2R_SGL_ALIGN 16
- #define ESAS2R_LIST_ALIGN 16
- #define ESAS2R_LIST_EXTRA ESAS2R_NUM_EXTRA
- #define ESAS2R_DATA_BUF_LEN 256
- #define ESAS2R_DEFAULT_TMO 5000
- #define ESAS2R_DISC_BUF_LEN 512
- #define ESAS2R_FWCOREDUMP_SZ 0x80000
- #define ESAS2R_NUM_PHYS 8
- #define ESAS2R_TARG_ID_INV 0xFFFF
- #define ESAS2R_INT_STS_MASK MU_INTSTAT_MASK
- #define ESAS2R_INT_ENB_MASK MU_INTSTAT_MASK
- #define ESAS2R_INT_DIS_MASK 0
- #define ESAS2R_MAX_TARGETS 256
- #define ESAS2R_KOBJ_NAME_LEN 20
- /* u16 (WORD) component macros */
- #define LOBYTE(w) ((u8)(u16)(w))
- #define HIBYTE(w) ((u8)(((u16)(w)) >> 8))
- #define MAKEWORD(lo, hi) ((u16)((u8)(lo) | ((u16)(u8)(hi) << 8)))
- /* u32 (DWORD) component macros */
- #define LOWORD(d) ((u16)(u32)(d))
- #define HIWORD(d) ((u16)(((u32)(d)) >> 16))
- #define MAKEDWORD(lo, hi) ((u32)((u16)(lo) | ((u32)(u16)(hi) << 16)))
- /* macro to get the lowest nonzero bit of a value */
- #define LOBIT(x) ((x) & (0 - (x)))
- /* These functions are provided to access the chip's control registers.
- * The register is specified by its byte offset from the register base
- * for the adapter.
- */
- #define esas2r_read_register_dword(a, reg) \
- readl((void __iomem *)a->regs + (reg) + MW_REG_OFFSET_HWREG)
- #define esas2r_write_register_dword(a, reg, data) \
- writel(data, (void __iomem *)(a->regs + (reg) + MW_REG_OFFSET_HWREG))
- #define esas2r_flush_register_dword(a, r) esas2r_read_register_dword(a, r)
- /* This function is provided to access the chip's data window. The
- * register is specified by its byte offset from the window base
- * for the adapter.
- */
- #define esas2r_read_data_byte(a, reg) \
- readb((void __iomem *)a->data_window + (reg))
- /* ATTO vendor and device Ids */
- #define ATTO_VENDOR_ID 0x117C
- #define ATTO_DID_INTEL_IOP348 0x002C
- #define ATTO_DID_MV_88RC9580 0x0049
- #define ATTO_DID_MV_88RC9580TS 0x0066
- #define ATTO_DID_MV_88RC9580TSE 0x0067
- #define ATTO_DID_MV_88RC9580TL 0x0068
- /* ATTO subsystem device Ids */
- #define ATTO_SSDID_TBT 0x4000
- #define ATTO_TSSC_3808 0x4066
- #define ATTO_TSSC_3808E 0x4067
- #define ATTO_TLSH_1068 0x4068
- #define ATTO_ESAS_R680 0x0049
- #define ATTO_ESAS_R608 0x004A
- #define ATTO_ESAS_R60F 0x004B
- #define ATTO_ESAS_R6F0 0x004C
- #define ATTO_ESAS_R644 0x004D
- #define ATTO_ESAS_R648 0x004E
- /*
- * flash definitions & structures
- * define the code types
- */
- #define FBT_CPYR 0xAA00
- #define FBT_SETUP 0xAA02
- #define FBT_FLASH_VER 0xAA04
- /* offsets to various locations in flash */
- #define FLS_OFFSET_BOOT (u32)(0x00700000)
- #define FLS_OFFSET_NVR (u32)(0x007C0000)
- #define FLS_OFFSET_CPYR FLS_OFFSET_NVR
- #define FLS_LENGTH_BOOT (FLS_OFFSET_CPYR - FLS_OFFSET_BOOT)
- #define FLS_BLOCK_SIZE (u32)(0x00020000)
- #define FI_NVR_2KB 0x0800
- #define FI_NVR_8KB 0x2000
- #define FM_BUF_SZ 0x800
- /*
- * marvell frey (88R9580) register definitions
- * chip revision identifiers
- */
- #define MVR_FREY_B2 0xB2
- /*
- * memory window definitions. window 0 is the data window with definitions
- * of MW_DATA_XXX. window 1 is the register window with definitions of
- * MW_REG_XXX.
- */
- #define MW_REG_WINDOW_SIZE (u32)(0x00040000)
- #define MW_REG_OFFSET_HWREG (u32)(0x00000000)
- #define MW_REG_OFFSET_PCI (u32)(0x00008000)
- #define MW_REG_PCI_HWREG_DELTA (MW_REG_OFFSET_PCI - MW_REG_OFFSET_HWREG)
- #define MW_DATA_WINDOW_SIZE (u32)(0x00020000)
- #define MW_DATA_ADDR_SER_FLASH (u32)(0xEC000000)
- #define MW_DATA_ADDR_SRAM (u32)(0xF4000000)
- #define MW_DATA_ADDR_PAR_FLASH (u32)(0xFC000000)
- /*
- * the following registers are for the communication
- * list interface (AKA message unit (MU))
- */
- #define MU_IN_LIST_ADDR_LO (u32)(0x00004000)
- #define MU_IN_LIST_ADDR_HI (u32)(0x00004004)
- #define MU_IN_LIST_WRITE (u32)(0x00004018)
- #define MU_ILW_TOGGLE (u32)(0x00004000)
- #define MU_IN_LIST_READ (u32)(0x0000401C)
- #define MU_ILR_TOGGLE (u32)(0x00004000)
- #define MU_ILIC_LIST (u32)(0x0000000F)
- #define MU_ILIC_LIST_F0 (u32)(0x00000000)
- #define MU_ILIC_DEST (u32)(0x00000F00)
- #define MU_ILIC_DEST_DDR (u32)(0x00000200)
- #define MU_IN_LIST_IFC_CONFIG (u32)(0x00004028)
- #define MU_IN_LIST_CONFIG (u32)(0x0000402C)
- #define MU_ILC_ENABLE (u32)(0x00000001)
- #define MU_ILC_ENTRY_MASK (u32)(0x000000F0)
- #define MU_ILC_ENTRY_4_DW (u32)(0x00000020)
- #define MU_ILC_DYNAMIC_SRC (u32)(0x00008000)
- #define MU_ILC_NUMBER_MASK (u32)(0x7FFF0000)
- #define MU_ILC_NUMBER_SHIFT 16
- #define MU_OUT_LIST_ADDR_LO (u32)(0x00004050)
- #define MU_OUT_LIST_ADDR_HI (u32)(0x00004054)
- #define MU_OUT_LIST_COPY_PTR_LO (u32)(0x00004058)
- #define MU_OUT_LIST_COPY_PTR_HI (u32)(0x0000405C)
- #define MU_OUT_LIST_WRITE (u32)(0x00004068)
- #define MU_OLW_TOGGLE (u32)(0x00004000)
- #define MU_OUT_LIST_COPY (u32)(0x0000406C)
- #define MU_OLC_TOGGLE (u32)(0x00004000)
- #define MU_OLC_WRT_PTR (u32)(0x00003FFF)
- #define MU_OUT_LIST_IFC_CONFIG (u32)(0x00004078)
- #define MU_OLIC_LIST (u32)(0x0000000F)
- #define MU_OLIC_LIST_F0 (u32)(0x00000000)
- #define MU_OLIC_SOURCE (u32)(0x00000F00)
- #define MU_OLIC_SOURCE_DDR (u32)(0x00000200)
- #define MU_OUT_LIST_CONFIG (u32)(0x0000407C)
- #define MU_OLC_ENABLE (u32)(0x00000001)
- #define MU_OLC_ENTRY_MASK (u32)(0x000000F0)
- #define MU_OLC_ENTRY_4_DW (u32)(0x00000020)
- #define MU_OLC_NUMBER_MASK (u32)(0x7FFF0000)
- #define MU_OLC_NUMBER_SHIFT 16
- #define MU_OUT_LIST_INT_STAT (u32)(0x00004088)
- #define MU_OLIS_INT (u32)(0x00000001)
- #define MU_OUT_LIST_INT_MASK (u32)(0x0000408C)
- #define MU_OLIS_MASK (u32)(0x00000001)
- /*
- * the maximum size of the communication lists is two greater than the
- * maximum amount of VDA requests. the extra are to prevent queue overflow.
- */
- #define ESAS2R_MAX_NUM_REQS 256
- #define ESAS2R_NUM_EXTRA 2
- #define ESAS2R_MAX_COMM_LIST_SIZE (ESAS2R_MAX_NUM_REQS + ESAS2R_NUM_EXTRA)
- /*
- * the following registers are for the CPU interface
- */
- #define MU_CTL_STATUS_IN (u32)(0x00010108)
- #define MU_CTL_IN_FULL_RST (u32)(0x00000020)
- #define MU_CTL_STATUS_IN_B2 (u32)(0x00010130)
- #define MU_CTL_IN_FULL_RST2 (u32)(0x80000000)
- #define MU_DOORBELL_IN (u32)(0x00010460)
- #define DRBL_RESET_BUS (u32)(0x00000002)
- #define DRBL_PAUSE_AE (u32)(0x00000004)
- #define DRBL_RESUME_AE (u32)(0x00000008)
- #define DRBL_MSG_IFC_DOWN (u32)(0x00000010)
- #define DRBL_FLASH_REQ (u32)(0x00000020)
- #define DRBL_FLASH_DONE (u32)(0x00000040)
- #define DRBL_FORCE_INT (u32)(0x00000080)
- #define DRBL_MSG_IFC_INIT (u32)(0x00000100)
- #define DRBL_POWER_DOWN (u32)(0x00000200)
- #define DRBL_DRV_VER_1 (u32)(0x00010000)
- #define DRBL_DRV_VER DRBL_DRV_VER_1
- #define MU_DOORBELL_IN_ENB (u32)(0x00010464)
- #define MU_DOORBELL_OUT (u32)(0x00010480)
- #define DRBL_PANIC_REASON_MASK (u32)(0x00F00000)
- #define DRBL_UNUSED_HANDLER (u32)(0x00100000)
- #define DRBL_UNDEF_INSTR (u32)(0x00200000)
- #define DRBL_PREFETCH_ABORT (u32)(0x00300000)
- #define DRBL_DATA_ABORT (u32)(0x00400000)
- #define DRBL_JUMP_TO_ZERO (u32)(0x00500000)
- #define DRBL_FW_RESET (u32)(0x00080000)
- #define DRBL_FW_VER_MSK (u32)(0x00070000)
- #define DRBL_FW_VER_0 (u32)(0x00000000)
- #define DRBL_FW_VER_1 (u32)(0x00010000)
- #define DRBL_FW_VER DRBL_FW_VER_1
- #define MU_DOORBELL_OUT_ENB (u32)(0x00010484)
- #define DRBL_ENB_MASK (u32)(0x00F803FF)
- #define MU_INT_STATUS_OUT (u32)(0x00010200)
- #define MU_INTSTAT_POST_OUT (u32)(0x00000010)
- #define MU_INTSTAT_DRBL_IN (u32)(0x00000100)
- #define MU_INTSTAT_DRBL (u32)(0x00001000)
- #define MU_INTSTAT_MASK (u32)(0x00001010)
- #define MU_INT_MASK_OUT (u32)(0x0001020C)
- /* PCI express registers accessed via window 1 */
- #define MVR_PCI_WIN1_REMAP (u32)(0x00008438)
- #define MVRPW1R_ENABLE (u32)(0x00000001)
- /* structures */
- /* inbound list dynamic source entry */
- struct esas2r_inbound_list_source_entry {
- u64 address;
- u32 length;
- #define HWILSE_INTERFACE_F0 0x00000000
- u32 reserved;
- };
- /* PCI data structure in expansion ROM images */
- struct __packed esas2r_boot_header {
- char signature[4];
- u16 vendor_id;
- u16 device_id;
- u16 VPD;
- u16 struct_length;
- u8 struct_revision;
- u8 class_code[3];
- u16 image_length;
- u16 code_revision;
- u8 code_type;
- #define CODE_TYPE_PC 0
- #define CODE_TYPE_OPEN 1
- #define CODE_TYPE_EFI 3
- u8 indicator;
- #define INDICATOR_LAST 0x80
- u8 reserved[2];
- };
- struct __packed esas2r_boot_image {
- u16 signature;
- u8 reserved[22];
- u16 header_offset;
- u16 pnp_offset;
- };
- struct __packed esas2r_pc_image {
- u16 signature;
- u8 length;
- u8 entry_point[3];
- u8 checksum;
- u16 image_end;
- u16 min_size;
- u8 rom_flags;
- u8 reserved[12];
- u16 header_offset;
- u16 pnp_offset;
- struct esas2r_boot_header boot_image;
- };
- struct __packed esas2r_efi_image {
- u16 signature;
- u16 length;
- u32 efi_signature;
- #define EFI_ROM_SIG 0x00000EF1
- u16 image_type;
- #define EFI_IMAGE_APP 10
- #define EFI_IMAGE_BSD 11
- #define EFI_IMAGE_RTD 12
- u16 machine_type;
- #define EFI_MACHINE_IA32 0x014c
- #define EFI_MACHINE_IA64 0x0200
- #define EFI_MACHINE_X64 0x8664
- #define EFI_MACHINE_EBC 0x0EBC
- u16 compression;
- #define EFI_UNCOMPRESSED 0x0000
- #define EFI_COMPRESSED 0x0001
- u8 reserved[8];
- u16 efi_offset;
- u16 header_offset;
- u16 reserved2;
- struct esas2r_boot_header boot_image;
- };
- struct esas2r_adapter;
- struct esas2r_sg_context;
- struct esas2r_request;
- typedef void (*RQCALLBK) (struct esas2r_adapter *a,
- struct esas2r_request *rq);
- typedef bool (*RQBUILDSGL) (struct esas2r_adapter *a,
- struct esas2r_sg_context *sgc);
- struct esas2r_component_header {
- u8 img_type;
- #define CH_IT_FW 0x00
- #define CH_IT_NVR 0x01
- #define CH_IT_BIOS 0x02
- #define CH_IT_MAC 0x03
- #define CH_IT_CFG 0x04
- #define CH_IT_EFI 0x05
- u8 status;
- #define CH_STAT_PENDING 0xff
- #define CH_STAT_FAILED 0x00
- #define CH_STAT_SUCCESS 0x01
- #define CH_STAT_RETRY 0x02
- #define CH_STAT_INVALID 0x03
- u8 pad[2];
- u32 version;
- u32 length;
- u32 image_offset;
- };
- #define FI_REL_VER_SZ 16
- struct esas2r_flash_img_v0 {
- u8 fi_version;
- #define FI_VERSION_0 00
- u8 status;
- u8 adap_typ;
- u8 action;
- u32 length;
- u16 checksum;
- u16 driver_error;
- u16 flags;
- u16 num_comps;
- #define FI_NUM_COMPS_V0 5
- u8 rel_version[FI_REL_VER_SZ];
- struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V0];
- u8 scratch_buf[FM_BUF_SZ];
- };
- struct esas2r_flash_img {
- u8 fi_version;
- #define FI_VERSION_1 01
- u8 status;
- #define FI_STAT_SUCCESS 0x00
- #define FI_STAT_FAILED 0x01
- #define FI_STAT_REBOOT 0x02
- #define FI_STAT_ADAPTYP 0x03
- #define FI_STAT_INVALID 0x04
- #define FI_STAT_CHKSUM 0x05
- #define FI_STAT_LENGTH 0x06
- #define FI_STAT_UNKNOWN 0x07
- #define FI_STAT_IMG_VER 0x08
- #define FI_STAT_BUSY 0x09
- #define FI_STAT_DUAL 0x0A
- #define FI_STAT_MISSING 0x0B
- #define FI_STAT_UNSUPP 0x0C
- #define FI_STAT_ERASE 0x0D
- #define FI_STAT_FLASH 0x0E
- #define FI_STAT_DEGRADED 0x0F
- u8 adap_typ;
- #define FI_AT_UNKNWN 0xFF
- #define FI_AT_SUN_LAKE 0x0B
- #define FI_AT_MV_9580 0x0F
- u8 action;
- #define FI_ACT_DOWN 0x00
- #define FI_ACT_UP 0x01
- #define FI_ACT_UPSZ 0x02
- #define FI_ACT_MAX 0x02
- #define FI_ACT_DOWN1 0x80
- u32 length;
- u16 checksum;
- u16 driver_error;
- u16 flags;
- #define FI_FLG_NVR_DEF 0x0001
- u16 num_comps;
- #define FI_NUM_COMPS_V1 6
- u8 rel_version[FI_REL_VER_SZ];
- struct esas2r_component_header cmp_hdr[FI_NUM_COMPS_V1];
- u8 scratch_buf[FM_BUF_SZ];
- };
- /* definitions for flash script (FS) commands */
- struct esas2r_ioctlfs_command {
- u8 command;
- #define ESAS2R_FS_CMD_ERASE 0
- #define ESAS2R_FS_CMD_READ 1
- #define ESAS2R_FS_CMD_BEGINW 2
- #define ESAS2R_FS_CMD_WRITE 3
- #define ESAS2R_FS_CMD_COMMIT 4
- #define ESAS2R_FS_CMD_CANCEL 5
- u8 checksum;
- u8 reserved[2];
- u32 flash_addr;
- u32 length;
- u32 image_offset;
- };
- struct esas2r_ioctl_fs {
- u8 version;
- #define ESAS2R_FS_VER 0
- u8 status;
- u8 driver_error;
- u8 adap_type;
- #define ESAS2R_FS_AT_ESASRAID2 3
- #define ESAS2R_FS_AT_TSSASRAID2 4
- #define ESAS2R_FS_AT_TSSASRAID2E 5
- #define ESAS2R_FS_AT_TLSASHBA 6
- u8 driver_ver;
- u8 reserved[11];
- struct esas2r_ioctlfs_command command;
- u8 data[1];
- };
- struct esas2r_sas_nvram {
- u8 signature[4];
- u8 version;
- #define SASNVR_VERSION_0 0x00
- #define SASNVR_VERSION SASNVR_VERSION_0
- u8 checksum;
- #define SASNVR_CKSUM_SEED 0x5A
- u8 max_lun_for_target;
- u8 pci_latency;
- #define SASNVR_PCILAT_DIS 0x00
- #define SASNVR_PCILAT_MIN 0x10
- #define SASNVR_PCILAT_MAX 0xF8
- u8 options1;
- #define SASNVR1_BOOT_DRVR 0x01
- #define SASNVR1_BOOT_SCAN 0x02
- #define SASNVR1_DIS_PCI_MWI 0x04
- #define SASNVR1_FORCE_ORD_Q 0x08
- #define SASNVR1_CACHELINE_0 0x10
- #define SASNVR1_DIS_DEVSORT 0x20
- #define SASNVR1_PWR_MGT_EN 0x40
- #define SASNVR1_WIDEPORT 0x80
- u8 options2;
- #define SASNVR2_SINGLE_BUS 0x01
- #define SASNVR2_SLOT_BIND 0x02
- #define SASNVR2_EXP_PROG 0x04
- #define SASNVR2_CMDTHR_LUN 0x08
- #define SASNVR2_HEARTBEAT 0x10
- #define SASNVR2_INT_CONNECT 0x20
- #define SASNVR2_SW_MUX_CTRL 0x40
- #define SASNVR2_DISABLE_NCQ 0x80
- u8 int_coalescing;
- #define SASNVR_COAL_DIS 0x00
- #define SASNVR_COAL_LOW 0x01
- #define SASNVR_COAL_MED 0x02
- #define SASNVR_COAL_HI 0x03
- u8 cmd_throttle;
- #define SASNVR_CMDTHR_NONE 0x00
- u8 dev_wait_time;
- u8 dev_wait_count;
- u8 spin_up_delay;
- #define SASNVR_SPINUP_MAX 0x14
- u8 ssp_align_rate;
- u8 sas_addr[8];
- u8 phy_speed[16];
- #define SASNVR_SPEED_AUTO 0x00
- #define SASNVR_SPEED_1_5GB 0x01
- #define SASNVR_SPEED_3GB 0x02
- #define SASNVR_SPEED_6GB 0x03
- #define SASNVR_SPEED_12GB 0x04
- u8 phy_mux[16];
- #define SASNVR_MUX_DISABLED 0x00
- #define SASNVR_MUX_1_5GB 0x01
- #define SASNVR_MUX_3GB 0x02
- #define SASNVR_MUX_6GB 0x03
- u8 phy_flags[16];
- #define SASNVR_PHF_DISABLED 0x01
- #define SASNVR_PHF_RD_ONLY 0x02
- u8 sort_type;
- #define SASNVR_SORT_SAS_ADDR 0x00
- #define SASNVR_SORT_H308_CONN 0x01
- #define SASNVR_SORT_PHY_ID 0x02
- #define SASNVR_SORT_SLOT_ID 0x03
- u8 dpm_reqcmd_lmt;
- u8 dpm_stndby_time;
- u8 dpm_active_time;
- u8 phy_target_id[16];
- #define SASNVR_PTI_DISABLED 0xFF
- u8 virt_ses_mode;
- #define SASNVR_VSMH_DISABLED 0x00
- u8 read_write_mode;
- #define SASNVR_RWM_DEFAULT 0x00
- u8 link_down_to;
- u8 reserved[0xA1];
- };
- typedef u32 (*PGETPHYSADDR) (struct esas2r_sg_context *sgc, u64 *addr);
- struct esas2r_sg_context {
- struct esas2r_adapter *adapter;
- struct esas2r_request *first_req;
- u32 length;
- u8 *cur_offset;
- PGETPHYSADDR get_phys_addr;
- union {
- struct {
- struct atto_vda_sge *curr;
- struct atto_vda_sge *last;
- struct atto_vda_sge *limit;
- struct atto_vda_sge *chain;
- } a64;
- struct {
- struct atto_physical_region_description *curr;
- struct atto_physical_region_description *chain;
- u32 sgl_max_cnt;
- u32 sge_cnt;
- } prd;
- } sge;
- struct scatterlist *cur_sgel;
- u8 *exp_offset;
- int num_sgel;
- int sgel_count;
- };
- struct esas2r_target {
- u8 flags;
- #define TF_PASS_THRU 0x01
- #define TF_USED 0x02
- u8 new_target_state;
- u8 target_state;
- u8 buffered_target_state;
- #define TS_NOT_PRESENT 0x00
- #define TS_PRESENT 0x05
- #define TS_LUN_CHANGE 0x06
- #define TS_INVALID 0xFF
- u32 block_size;
- u32 inter_block;
- u32 inter_byte;
- u16 virt_targ_id;
- u16 phys_targ_id;
- u8 identifier_len;
- u64 sas_addr;
- u8 identifier[60];
- struct atto_vda_ae_lu lu_event;
- };
- struct esas2r_request {
- struct list_head comp_list;
- struct list_head req_list;
- union atto_vda_req *vrq;
- struct esas2r_mem_desc *vrq_md;
- union {
- void *data_buf;
- union atto_vda_rsp_data *vda_rsp_data;
- };
- u8 *sense_buf;
- struct list_head sg_table_head;
- struct esas2r_mem_desc *sg_table;
- u32 timeout;
- #define RQ_TIMEOUT_S1 0xFFFFFFFF
- #define RQ_TIMEOUT_S2 0xFFFFFFFE
- #define RQ_MAX_TIMEOUT 0xFFFFFFFD
- u16 target_id;
- u8 req_type;
- #define RT_INI_REQ 0x01
- #define RT_DISC_REQ 0x02
- u8 sense_len;
- union atto_vda_func_rsp func_rsp;
- RQCALLBK comp_cb;
- RQCALLBK interrupt_cb;
- void *interrupt_cx;
- u8 flags;
- #define RF_1ST_IBLK_BASE 0x04
- #define RF_FAILURE_OK 0x08
- u8 req_stat;
- u16 vda_req_sz;
- #define RQ_SIZE_DEFAULT 0
- u64 lba;
- RQCALLBK aux_req_cb;
- void *aux_req_cx;
- u32 blk_len;
- u32 max_blk_len;
- union {
- struct scsi_cmnd *cmd;
- u8 *task_management_status_ptr;
- };
- };
- struct esas2r_flash_context {
- struct esas2r_flash_img *fi;
- RQCALLBK interrupt_cb;
- u8 *sgc_offset;
- u8 *scratch;
- u32 fi_hdr_len;
- u8 task;
- #define FMTSK_ERASE_BOOT 0
- #define FMTSK_WRTBIOS 1
- #define FMTSK_READBIOS 2
- #define FMTSK_WRTMAC 3
- #define FMTSK_READMAC 4
- #define FMTSK_WRTEFI 5
- #define FMTSK_READEFI 6
- #define FMTSK_WRTCFG 7
- #define FMTSK_READCFG 8
- u8 func;
- u16 num_comps;
- u32 cmp_len;
- u32 flsh_addr;
- u32 curr_len;
- u8 comp_typ;
- struct esas2r_sg_context sgc;
- };
- struct esas2r_disc_context {
- u8 disc_evt;
- #define DCDE_DEV_CHANGE 0x01
- #define DCDE_DEV_SCAN 0x02
- u8 state;
- #define DCS_DEV_RMV 0x00
- #define DCS_DEV_ADD 0x01
- #define DCS_BLOCK_DEV_SCAN 0x02
- #define DCS_RAID_GRP_INFO 0x03
- #define DCS_PART_INFO 0x04
- #define DCS_PT_DEV_INFO 0x05
- #define DCS_PT_DEV_ADDR 0x06
- #define DCS_DISC_DONE 0xFF
- u16 flags;
- #define DCF_DEV_CHANGE 0x0001
- #define DCF_DEV_SCAN 0x0002
- #define DCF_POLLED 0x8000
- u32 interleave;
- u32 block_size;
- u16 dev_ix;
- u8 part_num;
- u8 raid_grp_ix;
- char raid_grp_name[16];
- struct esas2r_target *curr_targ;
- u16 curr_virt_id;
- u16 curr_phys_id;
- u8 scan_gen;
- u8 dev_addr_type;
- u64 sas_addr;
- };
- struct esas2r_mem_desc {
- struct list_head next_desc;
- void *virt_addr;
- u64 phys_addr;
- void *pad;
- void *esas2r_data;
- u32 esas2r_param;
- u32 size;
- };
- enum fw_event_type {
- fw_event_null,
- fw_event_lun_change,
- fw_event_present,
- fw_event_not_present,
- fw_event_vda_ae
- };
- struct esas2r_vda_ae {
- u32 signature;
- #define ESAS2R_VDA_EVENT_SIG 0x4154544F
- u8 bus_number;
- u8 devfn;
- u8 pad[2];
- union atto_vda_ae vda_ae;
- };
- struct esas2r_fw_event_work {
- struct list_head list;
- struct delayed_work work;
- struct esas2r_adapter *a;
- enum fw_event_type type;
- u8 data[sizeof(struct esas2r_vda_ae)];
- };
- enum state {
- FW_INVALID_ST,
- FW_STATUS_ST,
- FW_COMMAND_ST
- };
- struct esas2r_firmware {
- enum state state;
- struct esas2r_flash_img header;
- u8 *data;
- u64 phys;
- int orig_len;
- void *header_buff;
- u64 header_buff_phys;
- };
- struct esas2r_adapter {
- struct esas2r_target targetdb[ESAS2R_MAX_TARGETS];
- struct esas2r_target *targetdb_end;
- unsigned char *regs;
- unsigned char *data_window;
- long flags;
- #define AF_PORT_CHANGE 0
- #define AF_CHPRST_NEEDED 1
- #define AF_CHPRST_PENDING 2
- #define AF_CHPRST_DETECTED 3
- #define AF_BUSRST_NEEDED 4
- #define AF_BUSRST_PENDING 5
- #define AF_BUSRST_DETECTED 6
- #define AF_DISABLED 7
- #define AF_FLASH_LOCK 8
- #define AF_OS_RESET 9
- #define AF_FLASHING 10
- #define AF_POWER_MGT 11
- #define AF_NVR_VALID 12
- #define AF_DEGRADED_MODE 13
- #define AF_DISC_PENDING 14
- #define AF_TASKLET_SCHEDULED 15
- #define AF_HEARTBEAT 16
- #define AF_HEARTBEAT_ENB 17
- #define AF_NOT_PRESENT 18
- #define AF_CHPRST_STARTED 19
- #define AF_FIRST_INIT 20
- #define AF_POWER_DOWN 21
- #define AF_DISC_IN_PROG 22
- #define AF_COMM_LIST_TOGGLE 23
- #define AF_LEGACY_SGE_MODE 24
- #define AF_DISC_POLLED 25
- long flags2;
- #define AF2_SERIAL_FLASH 0
- #define AF2_DEV_SCAN 1
- #define AF2_DEV_CNT_OK 2
- #define AF2_COREDUMP_AVAIL 3
- #define AF2_COREDUMP_SAVED 4
- #define AF2_VDA_POWER_DOWN 5
- #define AF2_THUNDERLINK 6
- #define AF2_THUNDERBOLT 7
- #define AF2_INIT_DONE 8
- #define AF2_INT_PENDING 9
- #define AF2_TIMER_TICK 10
- #define AF2_IRQ_CLAIMED 11
- #define AF2_MSI_ENABLED 12
- atomic_t disable_cnt;
- atomic_t dis_ints_cnt;
- u32 int_stat;
- u32 int_mask;
- u32 volatile *outbound_copy;
- struct list_head avail_request;
- spinlock_t request_lock;
- spinlock_t sg_list_lock;
- spinlock_t queue_lock;
- spinlock_t mem_lock;
- struct list_head free_sg_list_head;
- struct esas2r_mem_desc *sg_list_mds;
- struct list_head active_list;
- struct list_head defer_list;
- struct esas2r_request **req_table;
- union {
- u16 prev_dev_cnt;
- u32 heartbeat_time;
- #define ESAS2R_HEARTBEAT_TIME (3000)
- };
- u32 chip_uptime;
- #define ESAS2R_CHP_UPTIME_MAX (60000)
- #define ESAS2R_CHP_UPTIME_CNT (20000)
- u64 uncached_phys;
- u8 *uncached;
- struct esas2r_sas_nvram *nvram;
- struct esas2r_request general_req;
- u8 init_msg;
- #define ESAS2R_INIT_MSG_START 1
- #define ESAS2R_INIT_MSG_INIT 2
- #define ESAS2R_INIT_MSG_GET_INIT 3
- #define ESAS2R_INIT_MSG_REINIT 4
- u16 cmd_ref_no;
- u32 fw_version;
- u32 fw_build;
- u32 chip_init_time;
- #define ESAS2R_CHPRST_TIME (180000)
- #define ESAS2R_CHPRST_WAIT_TIME (2000)
- u32 last_tick_time;
- u32 window_base;
- RQBUILDSGL build_sgl;
- struct esas2r_request *first_ae_req;
- u32 list_size;
- u32 last_write;
- u32 last_read;
- u16 max_vdareq_size;
- u16 disc_wait_cnt;
- struct esas2r_mem_desc inbound_list_md;
- struct esas2r_mem_desc outbound_list_md;
- struct esas2r_disc_context disc_ctx;
- u8 *disc_buffer;
- u32 disc_start_time;
- u32 disc_wait_time;
- u32 flash_ver;
- char flash_rev[16];
- char fw_rev[16];
- char image_type[16];
- struct esas2r_flash_context flash_context;
- u32 num_targets_backend;
- u32 ioctl_tunnel;
- struct tasklet_struct tasklet;
- struct pci_dev *pcid;
- struct Scsi_Host *host;
- unsigned int index;
- char name[32];
- struct timer_list timer;
- struct esas2r_firmware firmware;
- wait_queue_head_t nvram_waiter;
- int nvram_command_done;
- wait_queue_head_t fm_api_waiter;
- int fm_api_command_done;
- wait_queue_head_t vda_waiter;
- int vda_command_done;
- u8 *vda_buffer;
- u64 ppvda_buffer;
- #define VDA_BUFFER_HEADER_SZ (offsetof(struct atto_ioctl_vda, data))
- #define VDA_MAX_BUFFER_SIZE (0x40000 + VDA_BUFFER_HEADER_SZ)
- wait_queue_head_t fs_api_waiter;
- int fs_api_command_done;
- u64 ppfs_api_buffer;
- u8 *fs_api_buffer;
- u32 fs_api_buffer_size;
- wait_queue_head_t buffered_ioctl_waiter;
- int buffered_ioctl_done;
- int uncached_size;
- struct workqueue_struct *fw_event_q;
- struct list_head fw_event_list;
- spinlock_t fw_event_lock;
- u8 fw_events_off; /* if '1', then ignore events */
- char fw_event_q_name[ESAS2R_KOBJ_NAME_LEN];
- /*
- * intr_mode stores the interrupt mode currently being used by this
- * adapter. it is based on the interrupt_mode module parameter, but
- * can be changed based on the ability (or not) to utilize the
- * mode requested by the parameter.
- */
- int intr_mode;
- #define INTR_MODE_LEGACY 0
- #define INTR_MODE_MSI 1
- #define INTR_MODE_MSIX 2
- struct esas2r_sg_context fm_api_sgc;
- u8 *save_offset;
- struct list_head vrq_mds_head;
- struct esas2r_mem_desc *vrq_mds;
- int num_vrqs;
- struct semaphore fm_api_semaphore;
- struct semaphore fs_api_semaphore;
- struct semaphore nvram_semaphore;
- struct atto_ioctl *local_atto_ioctl;
- u8 fw_coredump_buff[ESAS2R_FWCOREDUMP_SZ];
- unsigned int sysfs_fw_created:1;
- unsigned int sysfs_fs_created:1;
- unsigned int sysfs_vda_created:1;
- unsigned int sysfs_hw_created:1;
- unsigned int sysfs_live_nvram_created:1;
- unsigned int sysfs_default_nvram_created:1;
- };
- /*
- * Function Declarations
- * SCSI functions
- */
- int esas2r_release(struct Scsi_Host *);
- const char *esas2r_info(struct Scsi_Host *);
- int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq,
- struct esas2r_sas_nvram *data);
- int esas2r_ioctl_handler(void *hostdata, int cmd, void __user *arg);
- int esas2r_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
- u8 handle_hba_ioctl(struct esas2r_adapter *a,
- struct atto_ioctl *ioctl_hba);
- int esas2r_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd);
- int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh);
- long esas2r_proc_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
- /* SCSI error handler (eh) functions */
- int esas2r_eh_abort(struct scsi_cmnd *cmd);
- int esas2r_device_reset(struct scsi_cmnd *cmd);
- int esas2r_host_reset(struct scsi_cmnd *cmd);
- int esas2r_bus_reset(struct scsi_cmnd *cmd);
- int esas2r_target_reset(struct scsi_cmnd *cmd);
- /* Internal functions */
- int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
- int index);
- int esas2r_cleanup(struct Scsi_Host *host);
- int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count);
- int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off,
- int count);
- int esas2r_read_vda(struct esas2r_adapter *a, char *buf, long off, int count);
- int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,
- int count);
- int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count);
- int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,
- int count);
- void esas2r_adapter_tasklet(unsigned long context);
- irqreturn_t esas2r_interrupt(int irq, void *dev_id);
- irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id);
- void esas2r_kickoff_timer(struct esas2r_adapter *a);
- int esas2r_suspend(struct pci_dev *pcid, pm_message_t state);
- int esas2r_resume(struct pci_dev *pcid);
- void esas2r_fw_event_off(struct esas2r_adapter *a);
- void esas2r_fw_event_on(struct esas2r_adapter *a);
- bool esas2r_nvram_write(struct esas2r_adapter *a, struct esas2r_request *rq,
- struct esas2r_sas_nvram *nvram);
- void esas2r_nvram_get_defaults(struct esas2r_adapter *a,
- struct esas2r_sas_nvram *nvram);
- void esas2r_complete_request_cb(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- void esas2r_reset_detected(struct esas2r_adapter *a);
- void esas2r_target_state_changed(struct esas2r_adapter *ha, u16 targ_id,
- u8 state);
- int esas2r_req_status_to_error(u8 req_stat);
- void esas2r_kill_adapter(int i);
- void esas2r_free_request(struct esas2r_adapter *a, struct esas2r_request *rq);
- struct esas2r_request *esas2r_alloc_request(struct esas2r_adapter *a);
- u32 esas2r_get_uncached_size(struct esas2r_adapter *a);
- bool esas2r_init_adapter_struct(struct esas2r_adapter *a,
- void **uncached_area);
- bool esas2r_check_adapter(struct esas2r_adapter *a);
- bool esas2r_init_adapter_hw(struct esas2r_adapter *a, bool init_poll);
- void esas2r_start_request(struct esas2r_adapter *a, struct esas2r_request *rq);
- bool esas2r_send_task_mgmt(struct esas2r_adapter *a,
- struct esas2r_request *rqaux, u8 task_mgt_func);
- void esas2r_do_tasklet_tasks(struct esas2r_adapter *a);
- void esas2r_adapter_interrupt(struct esas2r_adapter *a);
- void esas2r_do_deferred_processes(struct esas2r_adapter *a);
- void esas2r_reset_bus(struct esas2r_adapter *a);
- void esas2r_reset_adapter(struct esas2r_adapter *a);
- void esas2r_timer_tick(struct esas2r_adapter *a);
- const char *esas2r_get_model_name(struct esas2r_adapter *a);
- const char *esas2r_get_model_name_short(struct esas2r_adapter *a);
- u32 esas2r_stall_execution(struct esas2r_adapter *a, u32 start_time,
- u32 *delay);
- void esas2r_build_flash_req(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- u8 sub_func,
- u8 cksum,
- u32 addr,
- u32 length);
- void esas2r_build_mgt_req(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- u8 sub_func,
- u8 scan_gen,
- u16 dev_index,
- u32 length,
- void *data);
- void esas2r_build_ae_req(struct esas2r_adapter *a, struct esas2r_request *rq);
- void esas2r_build_cli_req(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- u32 length,
- u32 cmd_rsp_len);
- void esas2r_build_ioctl_req(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- u32 length,
- u8 sub_func);
- void esas2r_build_cfg_req(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- u8 sub_func,
- u32 length,
- void *data);
- void esas2r_power_down(struct esas2r_adapter *a);
- bool esas2r_power_up(struct esas2r_adapter *a, bool init_poll);
- void esas2r_wait_request(struct esas2r_adapter *a, struct esas2r_request *rq);
- u32 esas2r_map_data_window(struct esas2r_adapter *a, u32 addr_lo);
- bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,
- struct esas2r_ioctl_fs *fs,
- struct esas2r_request *rq,
- struct esas2r_sg_context *sgc);
- bool esas2r_read_flash_block(struct esas2r_adapter *a, void *to, u32 from,
- u32 size);
- bool esas2r_read_mem_block(struct esas2r_adapter *a, void *to, u32 from,
- u32 size);
- bool esas2r_fm_api(struct esas2r_adapter *a, struct esas2r_flash_img *fi,
- struct esas2r_request *rq, struct esas2r_sg_context *sgc);
- void esas2r_force_interrupt(struct esas2r_adapter *a);
- void esas2r_local_start_request(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- void esas2r_process_adapter_reset(struct esas2r_adapter *a);
- void esas2r_complete_request(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- void esas2r_dummy_complete(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- void esas2r_ae_complete(struct esas2r_adapter *a, struct esas2r_request *rq);
- void esas2r_start_vda_request(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- bool esas2r_read_flash_rev(struct esas2r_adapter *a);
- bool esas2r_read_image_type(struct esas2r_adapter *a);
- bool esas2r_nvram_read_direct(struct esas2r_adapter *a);
- bool esas2r_nvram_validate(struct esas2r_adapter *a);
- void esas2r_nvram_set_defaults(struct esas2r_adapter *a);
- bool esas2r_print_flash_rev(struct esas2r_adapter *a);
- void esas2r_send_reset_ae(struct esas2r_adapter *a, bool pwr_mgt);
- bool esas2r_init_msgs(struct esas2r_adapter *a);
- bool esas2r_is_adapter_present(struct esas2r_adapter *a);
- void esas2r_nuxi_mgt_data(u8 function, void *data);
- void esas2r_nuxi_cfg_data(u8 function, void *data);
- void esas2r_nuxi_ae_data(union atto_vda_ae *ae);
- void esas2r_reset_chip(struct esas2r_adapter *a);
- void esas2r_log_request_failure(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- void esas2r_polled_interrupt(struct esas2r_adapter *a);
- bool esas2r_ioreq_aborted(struct esas2r_adapter *a, struct esas2r_request *rq,
- u8 status);
- bool esas2r_build_sg_list_sge(struct esas2r_adapter *a,
- struct esas2r_sg_context *sgc);
- bool esas2r_build_sg_list_prd(struct esas2r_adapter *a,
- struct esas2r_sg_context *sgc);
- void esas2r_targ_db_initialize(struct esas2r_adapter *a);
- void esas2r_targ_db_remove_all(struct esas2r_adapter *a, bool notify);
- void esas2r_targ_db_report_changes(struct esas2r_adapter *a);
- struct esas2r_target *esas2r_targ_db_add_raid(struct esas2r_adapter *a,
- struct esas2r_disc_context *dc);
- struct esas2r_target *esas2r_targ_db_add_pthru(struct esas2r_adapter *a,
- struct esas2r_disc_context *dc,
- u8 *ident,
- u8 ident_len);
- void esas2r_targ_db_remove(struct esas2r_adapter *a, struct esas2r_target *t);
- struct esas2r_target *esas2r_targ_db_find_by_sas_addr(struct esas2r_adapter *a,
- u64 *sas_addr);
- struct esas2r_target *esas2r_targ_db_find_by_ident(struct esas2r_adapter *a,
- void *identifier,
- u8 ident_len);
- u16 esas2r_targ_db_find_next_present(struct esas2r_adapter *a, u16 target_id);
- struct esas2r_target *esas2r_targ_db_find_by_virt_id(struct esas2r_adapter *a,
- u16 virt_id);
- u16 esas2r_targ_db_get_tgt_cnt(struct esas2r_adapter *a);
- void esas2r_disc_initialize(struct esas2r_adapter *a);
- void esas2r_disc_start_waiting(struct esas2r_adapter *a);
- void esas2r_disc_check_for_work(struct esas2r_adapter *a);
- void esas2r_disc_check_complete(struct esas2r_adapter *a);
- void esas2r_disc_queue_event(struct esas2r_adapter *a, u8 disc_evt);
- bool esas2r_disc_start_port(struct esas2r_adapter *a);
- void esas2r_disc_local_start_request(struct esas2r_adapter *a,
- struct esas2r_request *rq);
- bool esas2r_set_degraded_mode(struct esas2r_adapter *a, char *error_str);
- bool esas2r_process_vda_ioctl(struct esas2r_adapter *a,
- struct atto_ioctl_vda *vi,
- struct esas2r_request *rq,
- struct esas2r_sg_context *sgc);
- void esas2r_queue_fw_event(struct esas2r_adapter *a,
- enum fw_event_type type,
- void *data,
- int data_sz);
- /* Inline functions */
- /* Allocate a chip scatter/gather list entry */
- static inline struct esas2r_mem_desc *esas2r_alloc_sgl(struct esas2r_adapter *a)
- {
- unsigned long flags;
- struct list_head *sgl;
- struct esas2r_mem_desc *result = NULL;
- spin_lock_irqsave(&a->sg_list_lock, flags);
- if (likely(!list_empty(&a->free_sg_list_head))) {
- sgl = a->free_sg_list_head.next;
- result = list_entry(sgl, struct esas2r_mem_desc, next_desc);
- list_del_init(sgl);
- }
- spin_unlock_irqrestore(&a->sg_list_lock, flags);
- return result;
- }
- /* Initialize a scatter/gather context */
- static inline void esas2r_sgc_init(struct esas2r_sg_context *sgc,
- struct esas2r_adapter *a,
- struct esas2r_request *rq,
- struct atto_vda_sge *first)
- {
- sgc->adapter = a;
- sgc->first_req = rq;
- /*
- * set the limit pointer such that an SGE pointer above this value
- * would be the first one to overflow the SGL.
- */
- sgc->sge.a64.limit = (struct atto_vda_sge *)((u8 *)rq->vrq
- + (sizeof(union
- atto_vda_req) /
- 8)
- - sizeof(struct
- atto_vda_sge));
- if (first) {
- sgc->sge.a64.last =
- sgc->sge.a64.curr = first;
- rq->vrq->scsi.sg_list_offset = (u8)
- ((u8 *)first -
- (u8 *)rq->vrq);
- } else {
- sgc->sge.a64.last =
- sgc->sge.a64.curr = &rq->vrq->scsi.u.sge[0];
- rq->vrq->scsi.sg_list_offset =
- (u8)offsetof(struct atto_vda_scsi_req, u.sge);
- }
- sgc->sge.a64.chain = NULL;
- }
- static inline void esas2r_rq_init_request(struct esas2r_request *rq,
- struct esas2r_adapter *a)
- {
- union atto_vda_req *vrq = rq->vrq;
- INIT_LIST_HEAD(&rq->sg_table_head);
- rq->data_buf = (void *)(vrq + 1);
- rq->interrupt_cb = NULL;
- rq->comp_cb = esas2r_complete_request_cb;
- rq->flags = 0;
- rq->timeout = 0;
- rq->req_stat = RS_PENDING;
- rq->req_type = RT_INI_REQ;
- /* clear the outbound response */
- rq->func_rsp.dwords[0] = 0;
- rq->func_rsp.dwords[1] = 0;
- /*
- * clear the size of the VDA request. esas2r_build_sg_list() will
- * only allow the size of the request to grow. there are some
- * management requests that go through there twice and the second
- * time through sets a smaller request size. if this is not modified
- * at all we'll set it to the size of the entire VDA request.
- */
- rq->vda_req_sz = RQ_SIZE_DEFAULT;
- /* req_table entry should be NULL at this point - if not, halt */
- if (a->req_table[LOWORD(vrq->scsi.handle)])
- esas2r_bugon();
- /* fill in the table for this handle so we can get back to the
- * request.
- */
- a->req_table[LOWORD(vrq->scsi.handle)] = rq;
- /*
- * add a reference number to the handle to make it unique (until it
- * wraps of course) while preserving the least significant word
- */
- vrq->scsi.handle = (a->cmd_ref_no++ << 16) | (u16)vrq->scsi.handle;
- /*
- * the following formats a SCSI request. the caller can override as
- * necessary. clear_vda_request can be called to clear the VDA
- * request for another type of request.
- */
- vrq->scsi.function = VDA_FUNC_SCSI;
- vrq->scsi.sense_len = SENSE_DATA_SZ;
- /* clear out sg_list_offset and chain_offset */
- vrq->scsi.sg_list_offset = 0;
- vrq->scsi.chain_offset = 0;
- vrq->scsi.flags = 0;
- vrq->scsi.reserved = 0;
- /* set the sense buffer to be the data payload buffer */
- vrq->scsi.ppsense_buf
- = cpu_to_le64(rq->vrq_md->phys_addr +
- sizeof(union atto_vda_req));
- }
- static inline void esas2r_rq_free_sg_lists(struct esas2r_request *rq,
- struct esas2r_adapter *a)
- {
- unsigned long flags;
- if (list_empty(&rq->sg_table_head))
- return;
- spin_lock_irqsave(&a->sg_list_lock, flags);
- list_splice_tail_init(&rq->sg_table_head, &a->free_sg_list_head);
- spin_unlock_irqrestore(&a->sg_list_lock, flags);
- }
- static inline void esas2r_rq_destroy_request(struct esas2r_request *rq,
- struct esas2r_adapter *a)
- {
- esas2r_rq_free_sg_lists(rq, a);
- a->req_table[LOWORD(rq->vrq->scsi.handle)] = NULL;
- rq->data_buf = NULL;
- }
- static inline bool esas2r_is_tasklet_pending(struct esas2r_adapter *a)
- {
- return test_bit(AF_BUSRST_NEEDED, &a->flags) ||
- test_bit(AF_BUSRST_DETECTED, &a->flags) ||
- test_bit(AF_CHPRST_NEEDED, &a->flags) ||
- test_bit(AF_CHPRST_DETECTED, &a->flags) ||
- test_bit(AF_PORT_CHANGE, &a->flags);
- }
- /*
- * Build the scatter/gather list for an I/O request according to the
- * specifications placed in the esas2r_sg_context. The caller must initialize
- * struct esas2r_sg_context prior to the initial call by calling
- * esas2r_sgc_init()
- */
- static inline bool esas2r_build_sg_list(struct esas2r_adapter *a,
- struct esas2r_request *rq,
- struct esas2r_sg_context *sgc)
- {
- if (unlikely(le32_to_cpu(rq->vrq->scsi.length) == 0))
- return true;
- return (*a->build_sgl)(a, sgc);
- }
- static inline void esas2r_disable_chip_interrupts(struct esas2r_adapter *a)
- {
- if (atomic_inc_return(&a->dis_ints_cnt) == 1)
- esas2r_write_register_dword(a, MU_INT_MASK_OUT,
- ESAS2R_INT_DIS_MASK);
- }
- static inline void esas2r_enable_chip_interrupts(struct esas2r_adapter *a)
- {
- if (atomic_dec_return(&a->dis_ints_cnt) == 0)
- esas2r_write_register_dword(a, MU_INT_MASK_OUT,
- ESAS2R_INT_ENB_MASK);
- }
- /* Schedule a TASKLET to perform non-interrupt tasks that may require delays
- * or long completion times.
- */
- static inline void esas2r_schedule_tasklet(struct esas2r_adapter *a)
- {
- /* make sure we don't schedule twice */
- if (!test_and_set_bit(AF_TASKLET_SCHEDULED, &a->flags))
- tasklet_hi_schedule(&a->tasklet);
- }
- static inline void esas2r_enable_heartbeat(struct esas2r_adapter *a)
- {
- if (!test_bit(AF_DEGRADED_MODE, &a->flags) &&
- !test_bit(AF_CHPRST_PENDING, &a->flags) &&
- (a->nvram->options2 & SASNVR2_HEARTBEAT))
- set_bit(AF_HEARTBEAT_ENB, &a->flags);
- else
- clear_bit(AF_HEARTBEAT_ENB, &a->flags);
- }
- static inline void esas2r_disable_heartbeat(struct esas2r_adapter *a)
- {
- clear_bit(AF_HEARTBEAT_ENB, &a->flags);
- clear_bit(AF_HEARTBEAT, &a->flags);
- }
- /* Set the initial state for resetting the adapter on the next pass through
- * esas2r_do_deferred.
- */
- static inline void esas2r_local_reset_adapter(struct esas2r_adapter *a)
- {
- esas2r_disable_heartbeat(a);
- set_bit(AF_CHPRST_NEEDED, &a->flags);
- set_bit(AF_CHPRST_PENDING, &a->flags);
- set_bit(AF_DISC_PENDING, &a->flags);
- }
- /* See if an interrupt is pending on the adapter. */
- static inline bool esas2r_adapter_interrupt_pending(struct esas2r_adapter *a)
- {
- u32 intstat;
- if (a->int_mask == 0)
- return false;
- intstat = esas2r_read_register_dword(a, MU_INT_STATUS_OUT);
- if ((intstat & a->int_mask) == 0)
- return false;
- esas2r_disable_chip_interrupts(a);
- a->int_stat = intstat;
- a->int_mask = 0;
- return true;
- }
- static inline u16 esas2r_targ_get_id(struct esas2r_target *t,
- struct esas2r_adapter *a)
- {
- return (u16)(uintptr_t)(t - a->targetdb);
- }
- /* Build and start an asynchronous event request */
- static inline void esas2r_start_ae_request(struct esas2r_adapter *a,
- struct esas2r_request *rq)
- {
- unsigned long flags;
- esas2r_build_ae_req(a, rq);
- spin_lock_irqsave(&a->queue_lock, flags);
- esas2r_start_vda_request(a, rq);
- spin_unlock_irqrestore(&a->queue_lock, flags);
- }
- static inline void esas2r_comp_list_drain(struct esas2r_adapter *a,
- struct list_head *comp_list)
- {
- struct esas2r_request *rq;
- struct list_head *element, *next;
- list_for_each_safe(element, next, comp_list) {
- rq = list_entry(element, struct esas2r_request, comp_list);
- list_del_init(element);
- esas2r_complete_request(a, rq);
- }
- }
- /* sysfs handlers */
- extern struct bin_attribute bin_attr_fw;
- extern struct bin_attribute bin_attr_fs;
- extern struct bin_attribute bin_attr_vda;
- extern struct bin_attribute bin_attr_hw;
- extern struct bin_attribute bin_attr_live_nvram;
- extern struct bin_attribute bin_attr_default_nvram;
- #endif /* ESAS2R_H */
|