1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2010, LSI Corp. 5 * All rights reserved. 6 * Author : Manjunath Ranganathaiah 7 * Support: freebsdraid@lsi.com 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 3. Neither the name of the <ORGANIZATION> nor the names of its 20 * contributors may be used to endorse or promote products derived 21 * from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 33 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 * 36 * $FreeBSD$ 37 */ 38 39 #include <sys/param.h> /* defines used in kernel.h */ 40 #include <sys/bus.h> /* structs, prototypes for pci bus stuff */ 41 #include <sys/conf.h> /* cdevsw struct */ 42 #include <sys/errno.h> 43 #include <sys/kernel.h> /* types used in module initialization */ 44 #include <sys/lock.h> 45 #include <sys/malloc.h> 46 #include <sys/module.h> 47 #include <sys/mutex.h> 48 #include <sys/proc.h> 49 #include <sys/systm.h> 50 #include <sys/uio.h> /* uio struct */ 51 52 #include <machine/bus.h> 53 #include <sys/rman.h> 54 #include <machine/resource.h> 55 56 #include <dev/pci/pcivar.h> /* For pci_get macros! */ 57 #include <dev/pci/pcireg.h> 58 59 #include <sys/types.h> 60 #include <sys/sysctl.h> 61 #include <sys/stat.h> 62 63 64 #define TWS_PULL_MODE_ENABLE 1 65 66 MALLOC_DECLARE(M_TWS); 67 /* externs */ 68 extern int tws_queue_depth; 69 70 71 #define TWS_DRIVER_VERSION_STRING "10.80.00.005" 72 #define TWS_MAX_NUM_UNITS 65 73 #define TWS_MAX_NUM_LUNS 32 74 #define TWS_MAX_IRQS 2 75 #define TWS_SCSI_INITIATOR_ID 66 76 #define TWS_MAX_IO_SIZE 0x20000 /* 128kB */ 77 #define TWS_SECTOR_SIZE 0x200 78 #define TWS_POLL_TIMEOUT 60 79 #define TWS_IO_TIMEOUT 60 80 #define TWS_IOCTL_TIMEOUT 60 81 #define TWS_RESET_TIMEOUT 60 82 83 #define TWS_PCI_BAR0 0x10 84 #define TWS_PCI_BAR1 0x14 85 #define TWS_PCI_BAR2 0x1C 86 87 #define TWS_VENDOR_ID 0x13C1 88 #define TWS_DEVICE_ID 0x1010 89 90 #define TWS_INVALID_REQID 0xFFFF 91 92 /* bus tag related */ 93 #define TWS_ALIGNMENT 4 94 #define TWS_IN_MF_ALIGNMENT 16 95 #define TWS_OUT_MF_ALIGNMENT 4 96 97 #define TWS_MAX_32BIT_SG_ELEMENTS 93 /* max 32-bit sg elements */ 98 #define TWS_MAX_64BIT_SG_ELEMENTS 46 /* max 64-bit sg elements */ 99 100 #define TWS_MAX_QS 4 101 #define TWS_MAX_REQS 256 102 #define TWS_RESERVED_REQS 4 103 104 /* Request states */ 105 #define TWS_REQ_STATE_FREE 0 106 #define TWS_REQ_STATE_BUSY 1 107 #define TWS_REQ_STATE_TRAN 2 108 #define TWS_REQ_STATE_COMPLETE 3 109 110 /* Request types */ 111 #define TWS_REQ_TYPE_INTERNAL_CMD 0x0 112 #define TWS_REQ_TYPE_AEN_FETCH 0x1 113 #define TWS_REQ_TYPE_PASSTHRU 0x2 114 #define TWS_REQ_TYPE_GETSET_PARAM 0x3 115 #define TWS_REQ_TYPE_SCSI_IO 0x4 116 117 /* Driver states */ 118 119 enum tws_states { 120 TWS_INIT=50, 121 TWS_UNINIT, 122 TWS_OFFLINE, 123 TWS_ONLINE, 124 TWS_RESET, 125 }; 126 127 /* events */ 128 129 enum tws_events { 130 TWS_INIT_START=100, 131 TWS_INIT_COMPLETE, 132 TWS_UNINIT_START, 133 TWS_RESET_START, 134 TWS_RESET_COMPLETE, 135 TWS_SCAN_FAILURE, 136 }; 137 138 enum tws_req_flags { 139 TWS_DIR_UNKNOWN = 0x1, 140 TWS_DIR_IN = 0x2, 141 TWS_DIR_OUT = 0x4, 142 TWS_DIR_NONE = 0x8, 143 TWS_DATA_CCB = 0x10, 144 }; 145 146 enum tws_intrs { 147 TWS_INTx, 148 TWS_MSI, 149 TWS_MSIX, 150 }; 151 152 struct tws_msix_info { 153 int tbl_res_id; 154 bus_space_tag_t tbl_tag; 155 bus_space_handle_t tbl_handle; 156 struct resource *tbl_res; 157 }; 158 159 struct tws_ioctl_lock { 160 u_int32_t lock; 161 time_t timeout; 162 }; 163 164 165 #define TWS_TRACE_FNAME_LEN 10 166 #define TWS_TRACE_FUNC_LEN 15 167 #define TWS_TRACE_DESC_LEN 10 168 struct tws_trace_rec { 169 struct timespec ts; 170 char fname[TWS_TRACE_FNAME_LEN]; 171 char func[TWS_TRACE_FUNC_LEN]; 172 int linenum; 173 char desc[TWS_TRACE_DESC_LEN]; 174 u_int64_t val1; 175 u_int64_t val2; 176 }; 177 178 struct tws_circular_q { 179 volatile int16_t head; 180 volatile int16_t tail; 181 u_int16_t depth; 182 u_int8_t overflow; 183 void * q; 184 }; 185 186 187 188 struct tws_stats { 189 u_int64_t reqs_in; 190 u_int64_t reqs_out; 191 u_int64_t reqs_errored; 192 u_int64_t spurios_intrs; 193 u_int64_t num_intrs; 194 u_int64_t num_aens; 195 u_int64_t ioctls; 196 u_int64_t scsi_ios; 197 }; 198 199 struct tws_init_connect_info { 200 u_int16_t working_srl; 201 u_int16_t working_branch; 202 u_int16_t working_build; 203 u_int16_t fw_on_ctlr_srl; 204 u_int16_t fw_on_ctlr_branch; 205 u_int16_t fw_on_ctlr_build; 206 207 }; 208 209 210 /* ------------ boolean types ------------------- */ 211 212 #ifndef __bool_true_false_are_defined 213 typedef enum _boolean { false, true } boolean; 214 #else 215 #define boolean bool 216 #endif 217 enum err { SUCCESS, FAILURE }; 218 219 /* ----------- per instance data ---------------- */ 220 221 /* The softc holds our per-instance data. */ 222 struct tws_softc { 223 device_t tws_dev; /* bus device */ 224 struct cdev *tws_cdev; /* controller device */ 225 u_int32_t device_id; /* device id */ 226 u_int32_t subvendor_id; /* device id */ 227 u_int32_t subdevice_id; /* device id */ 228 u_int8_t tws_state; /* driver state */ 229 u_int8_t tws_prev_state; /* driver prev state */ 230 struct sysctl_ctx_list tws_clist; /* sysctl context */ 231 struct sysctl_oid *tws_oidp; /* sysctl context */ 232 struct resource *reg_res; /* register interface window */ 233 struct resource *mfa_res; /* mfa interface window */ 234 int reg_res_id; /* register resource id */ 235 int mfa_res_id; /* register resource id */ 236 bus_space_handle_t bus_handle; /* bus space handle */ 237 bus_space_handle_t bus_mfa_handle; /* bus space handle */ 238 bus_space_tag_t bus_tag; /* bus space tag */ 239 bus_space_tag_t bus_mfa_tag; /* bus space tag for mfa's */ 240 u_int64_t mfa_base; /* mfa base address */ 241 struct resource *irq_res[TWS_MAX_IRQS];/* interrupt resource */ 242 int irq_res_id[TWS_MAX_IRQS]; /* intr resource id */ 243 void *intr_handle[TWS_MAX_IRQS]; /* interrupt handle */ 244 int irqs; /* intrs used */ 245 struct tws_msix_info msix; /* msix info */ 246 struct cam_sim *sim; /* sim for this controller */ 247 struct cam_path *path; /* Ctlr path to CAM */ 248 struct mtx q_lock; /* queue lock */ 249 struct mtx sim_lock; /* sim lock */ 250 struct mtx gen_lock; /* general driver lock */ 251 struct mtx io_lock; /* IO lock */ 252 struct tws_ioctl_lock ioctl_lock; /* ioctl lock */ 253 u_int32_t seq_id; /* Sequence id */ 254 struct tws_circular_q aen_q; /* aen q */ 255 struct tws_circular_q trace_q; /* trace q */ 256 struct tws_stats stats; /* I/O stats */ 257 struct tws_init_connect_info cinfo; /* compatibility info */ 258 boolean is64bit; /* True - 64bit else 32bit */ 259 u_int8_t intr_type; /* Interrupt type used */ 260 bus_dma_tag_t parent_tag; /* parent DMA tag */ 261 bus_dma_tag_t cmd_tag; /* command DMA tag */ 262 bus_dmamap_t cmd_map; /* command map */ 263 void *dma_mem; /* pointer to dmable memory */ 264 u_int64_t dma_mem_phys; /* phy addr */ 265 bus_dma_tag_t data_tag; /* data DMA tag */ 266 void *ioctl_data_mem; /* ioctl dmable memory */ 267 bus_dmamap_t ioctl_data_map; /* ioctl data map */ 268 struct tws_request *reqs; /* pointer to requests */ 269 struct tws_sense *sense_bufs; /* pointer to sense buffers */ 270 boolean obfl_q_overrun; /* OBFL overrun flag */ 271 union ccb *scan_ccb; /* pointer to a ccb */ 272 struct tws_request *q_head[TWS_MAX_QS]; /* head pointers to q's */ 273 struct tws_request *q_tail[TWS_MAX_QS]; /* tail pointers to q's */ 274 struct callout stats_timer; 275 }; 276