si3124var.h revision 13071:ec9d94ce123b
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_LOGBUF_LEN 512 38 39#define SI_SUCCESS (0) /* successful return */ 40#define SI_TIMEOUT (1) /* timed out */ 41#define SI_FAILURE (-1) /* unsuccessful return */ 42 43#define SI_MAX_SGT_TABLES_PER_PRB 21844 44#define SI_DEFAULT_SGT_TABLES_PER_PRB 85 45#define SI_MIN_SGT_TABLES_PER_PRB 1 46/* 47 * While the si_sge_t and si_sgt_t correspond to the actual SGE and SGT 48 * definitions as per the datasheet, the si_sgblock_t (i.e scatter gather 49 * block) is a logical data structure which can hold dynamic SGEs and it 50 * is tunable through global variables /etc/system si3124:si_dma_sg_number. 51 * The idea is to use multiple tunable chained SGT tables per each PRB request. 52 */ 53 54typedef struct si_sgblock { 55 si_sgt_t sgb_sgt[1]; 56} si_sgblock_t; 57 58/* 59 * Each SGT (Scatter Gather Table) has 4 SGEs (Scatter Gather Entries). 60 * But each SGT effectively can host only 3 SGEs since the last SGE entry 61 * is used to hold a link to the next SGT in the chain. However the last 62 * SGT in the chain can host all the 4 entries since it does not need to 63 * link any more. 64 */ 65#define SGE_LENGTH(x) (3*(x)+1) 66#define SI_DEFAULT_SGL_LENGTH SGE_LENGTH(SI_DEFAULT_SGT_TABLES_PER_PRB) 67 68/* Argument to be used for calls to timeout() */ 69typedef struct si_event_arg { 70 void *siea_ctlp; 71 int siea_port; 72} si_event_arg_t; 73 74typedef struct si_portmult_state { 75 int sipm_num_ports; 76 uint8_t sipm_port_type[15]; 77 /* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */ 78 79 /* 80 * sipm_port_type[] is good enough to capture the state of ports 81 * behind the multiplier. Since any of the port behind a multiplier 82 * is accessed through the same main controller port, we don't need 83 * additional si_port_state_t here. 84 */ 85 86} si_portmult_state_t; 87 88 89/* The following are for port types */ 90#define PORT_TYPE_NODEV 0x0 91#define PORT_TYPE_MULTIPLIER 0x1 92#define PORT_TYPE_ATAPI 0x2 93#define PORT_TYPE_DISK 0x3 94#define PORT_TYPE_UNKNOWN 0x4 95 96/* The following are for active state */ 97#define PORT_INACTIVE 0x0 98#define PORT_ACTIVE 0x1 99 100typedef struct si_port_state { 101 struct si_ctl_state *siport_ctlp; /* back pointer to controller */ 102 103 uint8_t siport_port_type; 104 /* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */ 105 106 uint8_t siport_active; /* one of ACTIVE or INACTIVE */ 107 108 uint8_t siport_port_num; /* port number */ 109 110 si_portmult_state_t siport_portmult_state; 111 112 si_prb_t *siport_prbpool; /* These are 31 incore PRBs */ 113 uint64_t siport_prbpool_physaddr; 114 ddi_dma_handle_t siport_prbpool_dma_handle; 115 ddi_acc_handle_t siport_prbpool_acc_handle; 116 117 118 si_sgblock_t *siport_sgbpool; /* These are 31 incore sg blocks */ 119 uint64_t siport_sgbpool_physaddr; 120 ddi_dma_handle_t siport_sgbpool_dma_handle; 121 ddi_acc_handle_t siport_sgbpool_acc_handle; 122 123 kmutex_t siport_mutex; /* main per port mutex */ 124 uint32_t siport_pending_tags; /* remembers the pending tags */ 125 sata_pkt_t *siport_slot_pkts[SI_NUM_SLOTS]; 126 127 /* 128 * While the reset is in progress, we don't accept any more commands 129 * until we receive the command with SATA_CLEAR_DEV_RESET_STATE flag. 130 * However any commands with SATA_IGNORE_DEV_RESET_STATE are allowed in 131 * during such blockage. 132 */ 133 int siport_reset_in_progress; 134 135 /* Argument to be used for calls to timeout() */ 136 si_event_arg_t *siport_event_args; 137 138 /* 139 * We mop the commands for either abort, reset, timeout or 140 * error handling cases. This counts how many mops are in progress. 141 * It is also used to return BUSY in tran_start if a mop is going on. 142 */ 143 int mopping_in_progress; 144 145 /* error recovery related info */ 146 uint32_t siport_err_tags_SDBERROR; 147 uint32_t siport_err_tags_nonSDBERROR; 148 int siport_pending_ncq_count; 149 150} si_port_state_t; 151 152/* Warlock annotation */ 153_NOTE(MUTEX_PROTECTS_DATA(si_port_state_t::siport_mutex, si_port_state_t)) 154_NOTE(READ_ONLY_DATA(si_port_state_t::siport_prbpool_dma_handle)) 155_NOTE(READ_ONLY_DATA(si_port_state_t::siport_sgbpool_dma_handle)) 156_NOTE(DATA_READABLE_WITHOUT_LOCK(si_port_state_t::siport_ctlp)) 157_NOTE(DATA_READABLE_WITHOUT_LOCK(si_port_state_t::siport_port_num)) 158 159 160typedef struct si_ctl_state { 161 162 dev_info_t *sictl_devinfop; 163 164 int sictl_num_ports; /* number of controller ports */ 165 si_port_state_t *sictl_ports[SI_MAX_PORTS]; 166 167 int sictl_devid; /* whether it is 3124 or 3132 */ 168 int sictl_flags; /* some important state of controller */ 169 int sictl_power_level; 170 171 /* pci config space handle */ 172 ddi_acc_handle_t sictl_pci_conf_handle; 173 174 /* mapping into bar 0 */ 175 ddi_acc_handle_t sictl_global_acc_handle; 176 uintptr_t sictl_global_addr; 177 178 /* mapping into bar 1 */ 179 ddi_acc_handle_t sictl_port_acc_handle; 180 uintptr_t sictl_port_addr; 181 182 struct sata_hba_tran *sictl_sata_hba_tran; 183 timeout_id_t sictl_timeout_id; 184 185 kmutex_t sictl_mutex; /* per controller mutex */ 186 187 ddi_intr_handle_t *sictl_htable; /* For array of interrupts */ 188 int sictl_intr_type; /* What type of interrupt */ 189 int sictl_intr_cnt; /* # of intrs count returned */ 190 size_t sictl_intr_size; /* Size of intr array */ 191 uint_t sictl_intr_pri; /* Interrupt priority */ 192 int sictl_intr_cap; /* Interrupt capabilities */ 193 int fm_capabilities; /* FMA capabilities */ 194 195} si_ctl_state_t; 196 197/* Warlock annotation */ 198_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 199 si_ctl_state_t::sictl_ports)) 200_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 201 si_ctl_state_t::sictl_power_level)) 202_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 203 si_ctl_state_t::sictl_flags)) 204_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex, 205 si_ctl_state_t::sictl_timeout_id)) 206_NOTE(DATA_READABLE_WITHOUT_LOCK(si_ctl_state_t::sictl_ports)) 207/* 208 * flags for si_flags 209 */ 210#define SI_PM 0x01 211#define SI_ATTACH 0x02 212#define SI_DETACH 0x04 213#define SI_NO_TIMEOUTS 0x08 214#define SI_FRAMEWORK_ATTACHED 0x10 /* are we attached to framework ? */ 215 216/* progress values for si_attach */ 217#define ATTACH_PROGRESS_NONE (1<<0) 218#define ATTACH_PROGRESS_STATEP_ALLOC (1<<1) 219#define ATTACH_PROGRESS_INIT_FMA (1<<2) 220#define ATTACH_PROGRESS_CONF_HANDLE (1<<3) 221#define ATTACH_PROGRESS_BAR0_MAP (1<<4) 222#define ATTACH_PROGRESS_BAR1_MAP (1<<5) 223#define ATTACH_PROGRESS_INTR_ADDED (1<<6) 224#define ATTACH_PROGRESS_MUTEX_INIT (1<<7) 225#define ATTACH_PROGRESS_HW_INIT (1<<8) 226 227#define SI_10MS_TICKS (drv_usectohz(10000)) /* ticks in 10 millisec */ 228#define SI_1MS_TICKS (drv_usectohz(1000)) /* ticks in 1 millisec */ 229#define SI_1MS_USECS (1000) /* usecs in 1 millisec */ 230#define SI_POLLRATE_SOFT_RESET 1000 231#define SI_POLLRATE_SSTATUS 10 232#define SI_POLLRATE_PORTREADY 50 233#define SI_POLLRATE_SLOTSTATUS 50 234#define SI_POLLRATE_RECOVERPORTMULT 1000 235 236#define PORTMULT_CONTROL_PORT 0xf 237 238/* clearing & setting the n'th bit in a given tag */ 239#define CLEAR_BIT(tag, bit) (tag &= ~(0x1<<bit)) 240#define SET_BIT(tag, bit) (tag |= (0x1<<bit)) 241 242#if DEBUG 243 244#define SI_DEBUG 1 245 246#endif /* DEBUG */ 247 248/* si_debug_flags */ 249#define SIDBG_TEST 0x0001 250#define SIDBG_INIT 0x0002 251#define SIDBG_ENTRY 0x0004 252#define SIDBG_DUMP_PRB 0x0008 253#define SIDBG_EVENT 0x0010 254#define SIDBG_POLL_LOOP 0x0020 255#define SIDBG_PKTCOMP 0x0040 256#define SIDBG_TIMEOUT 0x0080 257#define SIDBG_INFO 0x0100 258#define SIDBG_VERBOSE 0x0200 259#define SIDBG_INTR 0x0400 260#define SIDBG_ERRS 0x0800 261#define SIDBG_COOKIES 0x1000 262#define SIDBG_POWER 0x2000 263#define SIDBG_RESET 0x4000 264 265extern uint32_t si_debug_flags; 266 267#define SIDBG(flag, format, args ...) \ 268 if (si_debug_flags & (flag)) { \ 269 si_log(NULL, NULL, format, ## args); \ 270 } 271 272#define SIDBG_P(flag, si_portp, format, args ...) \ 273 if (si_debug_flags & (flag)) { \ 274 si_log(NULL, si_portp, format, ## args); \ 275 } 276 277#define SIDBG_C(flag, si_ctlp, format, args ...) \ 278 if (si_debug_flags & (flag)) { \ 279 si_log(si_ctlp, NULL, format, ## args); \ 280 } 281 282 283/* Flags controlling the reset behavior */ 284#define SI_PORT_RESET 0x1 /* Reset the port */ 285#define SI_DEVICE_RESET 0x2 /* Reset the device, not the port */ 286#define SI_RESET_NO_EVENTS_UP 0x4 /* Don't send reset events up */ 287 288#ifdef __cplusplus 289} 290#endif 291 292#endif /* _SI3124VAR_H */ 293