si3124var.h revision 12308:4150d9d3c1ce
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26#ifndef _SI3124VAR_H 27#define _SI3124VAR_H 28 29#ifdef __cplusplus 30extern "C" { 31#endif 32 33#define SI3124_MAX_PORTS 4 34#define SI3132_MAX_PORTS 2 35#define SI_MAX_PORTS SI3124_MAX_PORTS 36 37#define SI_SUCCESS (0) /* successful return */ 38#define SI_TIMEOUT (1) /* timed out */ 39#define SI_FAILURE (-1) /* unsuccessful return */ 40 41#define SI_MAX_SGT_TABLES_PER_PRB 10 42 43/* 44 * While the si_sge_t and si_sgt_t correspond to the actual SGE and SGT 45 * definitions as per the datasheet, the si_sgblock_t (i.e scatter gather 46 * block) is a logical data structure which holds multiple SGT tables. 47 * The idea is to use multiple chained SGT tables per each PRB request. 48 */ 49 50typedef struct si_sgblock { 51 si_sgt_t sgb_sgt[SI_MAX_SGT_TABLES_PER_PRB]; 52} si_sgblock_t; 53 54/* 55 * Each SGT (Scatter Gather Table) has 4 SGEs (Scatter Gather Entries). 56 * But each SGT effectively can host only 3 SGEs since the last SGE entry 57 * is used to hold a link to the next SGT in the chain. However the last 58 * SGT in the chain can host all the 4 entries since it does not need to 59 * link any more. 60 */ 61#define SI_MAX_SGL_LENGTH (3*SI_MAX_SGT_TABLES_PER_PRB)+1 62 63typedef struct si_portmult_state { 64 int sipm_num_ports; 65 uint8_t sipm_port_type[15]; 66 /* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */ 67 68 /* 69 * sipm_port_type[] is good enough to capture the state of ports 70 * behind the multiplier. Since any of the port behind a multiplier 71 * is accessed through the same main controller port, we don't need 72 * additional si_port_state_t here. 73 */ 74 75} si_portmult_state_t; 76 77 78/* The following are for port types */ 79#define PORT_TYPE_NODEV 0x0 80#define PORT_TYPE_MULTIPLIER 0x1 81#define PORT_TYPE_ATAPI 0x2 82#define PORT_TYPE_DISK 0x3 83#define PORT_TYPE_UNKNOWN 0x4 84 85/* The following are for active state */ 86#define PORT_INACTIVE 0x0 87#define PORT_ACTIVE 0x1 88 89typedef struct si_port_state { 90 uint8_t siport_port_type; 91 /* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */ 92 93 uint8_t siport_active; /* one of ACTIVE or INACTIVE */ 94 95 si_portmult_state_t siport_portmult_state; 96 97 si_prb_t *siport_prbpool; /* These are 31 incore PRBs */ 98 uint64_t siport_prbpool_physaddr; 99 ddi_dma_handle_t siport_prbpool_dma_handle; 100 ddi_acc_handle_t siport_prbpool_acc_handle; 101 102 103 si_sgblock_t *siport_sgbpool; /* These are 31 incore sg blocks */ 104 uint64_t siport_sgbpool_physaddr; 105 ddi_dma_handle_t siport_sgbpool_dma_handle; 106 ddi_acc_handle_t siport_sgbpool_acc_handle; 107 108 kmutex_t siport_mutex; /* main per port mutex */ 109 uint32_t siport_pending_tags; /* remembers the pending tags */ 110 sata_pkt_t *siport_slot_pkts[SI_NUM_SLOTS]; 111 112 /* 113 * While the reset is in progress, we don't accept any more commands 114 * until we receive the command with SATA_CLEAR_DEV_RESET_STATE flag. 115 * However any commands with SATA_IGNORE_DEV_RESET_STATE are allowed in 116 * during such blockage. 117 */ 118 int siport_reset_in_progress; 119 120 /* 121 * We mop the commands for either abort, reset, timeout or 122 * error handling cases. This counts how many mops are in progress. 123 * It is also used to return BUSY in tran_start if a mop is going on. 124 */ 125 int mopping_in_progress; 126 127 /* error recovery related info */ 128 uint32_t siport_err_tags_SDBERROR; 129 uint32_t siport_err_tags_nonSDBERROR; 130 int siport_pending_ncq_count; 131 132} si_port_state_t; 133 134/* Warlock annotation */ 135_NOTE(MUTEX_PROTECTS_DATA(si_port_state_t::siport_mutex, si_port_state_t)) 136_NOTE(READ_ONLY_DATA(si_port_state_t::siport_prbpool_dma_handle)) 137_NOTE(READ_ONLY_DATA(si_port_state_t::siport_sgbpool_dma_handle)) 138 139 140typedef struct si_ctl_state { 141 142 dev_info_t *sictl_devinfop; 143 144 int sictl_num_ports; /* number of controller ports */ 145 si_port_state_t *sictl_ports[SI_MAX_PORTS]; 146 147 int sictl_devid; /* whether it is 3124 or 3132 */ 148 int sictl_flags; /* some important state of controller */ 149 int sictl_power_level; 150 151 /* pci config space handle */ 152 ddi_acc_handle_t sictl_pci_conf_handle; 153 154 /* mapping into bar 0 */ 155 ddi_acc_handle_t sictl_global_acc_handle; 156 uintptr_t sictl_global_addr; 157 158 /* mapping into bar 1 */ 159 ddi_acc_handle_t sictl_port_acc_handle; 160 uintptr_t sictl_port_addr; 161 162 struct sata_hba_tran *sictl_sata_hba_tran; 163 timeout_id_t sictl_timeout_id; 164 165 kmutex_t sictl_mutex; /* per controller mutex */ 166 167 ddi_intr_handle_t *sictl_htable; /* For array of interrupts */ 168 int sictl_intr_type; /* What type of interrupt */ 169 int sictl_intr_cnt; /* # of intrs count returned */ 170 size_t sictl_intr_size; /* Size of intr array */ 171 uint_t sictl_intr_pri; /* Interrupt priority */ 172 int sictl_intr_cap; /* Interrupt capabilities */ 173 int fm_capabilities; /* FMA capabilities */ 174 175} si_ctl_state_t; 176 177/* Warlock annotation */ 178_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 179 si_ctl_state_t::sictl_ports)) 180_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 181 si_ctl_state_t::sictl_power_level)) 182_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 183 si_ctl_state_t::sictl_flags)) 184_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 185 si_ctl_state_t::sictl_timeout_id)) 186/* 187 * flags for si_flags 188 */ 189#define SI_PM 0x01 190#define SI_ATTACH 0x02 191#define SI_DETACH 0x04 192#define SI_NO_TIMEOUTS 0x08 193#define SI_FRAMEWORK_ATTACHED 0x10 /* are we attached to framework ? */ 194 195/* progress values for si_attach */ 196#define ATTACH_PROGRESS_NONE (1<<0) 197#define ATTACH_PROGRESS_STATEP_ALLOC (1<<1) 198#define ATTACH_PROGRESS_INIT_FMA (1<<2) 199#define ATTACH_PROGRESS_CONF_HANDLE (1<<3) 200#define ATTACH_PROGRESS_BAR0_MAP (1<<4) 201#define ATTACH_PROGRESS_BAR1_MAP (1<<5) 202#define ATTACH_PROGRESS_INTR_ADDED (1<<6) 203#define ATTACH_PROGRESS_MUTEX_INIT (1<<7) 204#define ATTACH_PROGRESS_HW_INIT (1<<8) 205 206#define SI_10MS_TICKS (drv_usectohz(10000)) /* ticks in 10 millisec */ 207#define SI_1MS_TICKS (drv_usectohz(1000)) /* ticks in 1 millisec */ 208#define SI_1MS_USECS (1000) /* usecs in 1 millisec */ 209#define SI_POLLRATE_SOFT_RESET 1000 210#define SI_POLLRATE_SSTATUS 10 211#define SI_POLLRATE_PORTREADY 50 212#define SI_POLLRATE_SLOTSTATUS 50 213#define SI_POLLRATE_RECOVERPORTMULT 1000 214 215#define PORTMULT_CONTROL_PORT 0xf 216 217/* clearing & setting the n'th bit in a given tag */ 218#define CLEAR_BIT(tag, bit) (tag &= ~(0x1<<bit)) 219#define SET_BIT(tag, bit) (tag |= (0x1<<bit)) 220 221#if DEBUG 222 223#define SI_DEBUG 1 224 225#define SIDBG_TEST 0x0001 226#define SIDBG_INIT 0x0002 227#define SIDBG_ENTRY 0x0004 228#define SIDBG_DUMP_PRB 0x0008 229#define SIDBG_EVENT 0x0010 230#define SIDBG_POLL_LOOP 0x0020 231#define SIDBG_PKTCOMP 0x0040 232#define SIDBG_TIMEOUT 0x0080 233#define SIDBG_INFO 0x0100 234#define SIDBG_VERBOSE 0x0200 235#define SIDBG_INTR 0x0400 236#define SIDBG_ERRS 0x0800 237#define SIDBG_COOKIES 0x1000 238#define SIDBG_POWER 0x2000 239 240extern uint32_t si_debug_flags; 241 242#define SIDBG0(flag, softp, format) \ 243 if (si_debug_flags & (flag)) { \ 244 si_log(softp, CE_WARN, format); \ 245 } 246 247#define SIDBG1(flag, softp, format, arg1) \ 248 if (si_debug_flags & (flag)) { \ 249 si_log(softp, CE_WARN, format, arg1); \ 250 } 251 252#define SIDBG2(flag, softp, format, arg1, arg2) \ 253 if (si_debug_flags & (flag)) { \ 254 si_log(softp, CE_WARN, format, arg1, arg2); \ 255 } 256 257#define SIDBG3(flag, softp, format, arg1, arg2, arg3) \ 258 if (si_debug_flags & (flag)) { \ 259 si_log(softp, CE_WARN, format, arg1, arg2, arg3); \ 260 } 261 262#define SIDBG4(flag, softp, format, arg1, arg2, arg3, arg4) \ 263 if (si_debug_flags & (flag)) { \ 264 si_log(softp, CE_WARN, format, arg1, arg2, arg3, arg4); \ 265 } 266#else 267 268#define SIDBG0(flag, dip, frmt) 269#define SIDBG1(flag, dip, frmt, arg1) 270#define SIDBG2(flag, dip, frmt, arg1, arg2) 271#define SIDBG3(flag, dip, frmt, arg1, arg2, arg3) 272#define SIDBG4(flag, dip, frmt, arg1, arg2, arg3, arg4) 273 274#endif /* DEBUG */ 275 276/* Flags controlling the reset behavior */ 277#define SI_PORT_RESET 0x1 /* Reset the port */ 278#define SI_DEVICE_RESET 0x2 /* Reset the device, not the port */ 279#define SI_RESET_NO_EVENTS_UP 0x4 /* Don't send reset events up */ 280 281#ifdef __cplusplus 282} 283#endif 284 285#endif /* _SI3124VAR_H */ 286