2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2010, LSI Corp.
6 * Author : Manjunath Ranganathaiah
7 * Support: freebsdraid@lsi.com
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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
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.
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.
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 */
45 #include <sys/malloc.h>
46 #include <sys/module.h>
47 #include <sys/mutex.h>
49 #include <sys/systm.h>
50 #include <sys/uio.h> /* uio struct */
52 #include <machine/bus.h>
54 #include <machine/resource.h>
56 #include <dev/pci/pcivar.h> /* For pci_get macros! */
57 #include <dev/pci/pcireg.h>
59 #include <sys/types.h>
60 #include <sys/sysctl.h>
64 #define TWS_PULL_MODE_ENABLE 1
66 MALLOC_DECLARE(M_TWS);
68 extern int tws_queue_depth;
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
83 #define TWS_PCI_BAR0 0x10
84 #define TWS_PCI_BAR1 0x14
85 #define TWS_PCI_BAR2 0x1C
87 #define TWS_VENDOR_ID 0x13C1
88 #define TWS_DEVICE_ID 0x1010
90 #define TWS_INVALID_REQID 0xFFFF
93 #define TWS_ALIGNMENT 4
94 #define TWS_IN_MF_ALIGNMENT 16
95 #define TWS_OUT_MF_ALIGNMENT 4
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 */
101 #define TWS_MAX_REQS 256
102 #define TWS_RESERVED_REQS 4
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
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
139 TWS_DIR_UNKNOWN = 0x1,
152 struct tws_msix_info {
154 bus_space_tag_t tbl_tag;
155 bus_space_handle_t tbl_handle;
156 struct resource *tbl_res;
159 struct tws_ioctl_lock {
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 {
170 char fname[TWS_TRACE_FNAME_LEN];
171 char func[TWS_TRACE_FUNC_LEN];
173 char desc[TWS_TRACE_DESC_LEN];
178 struct tws_circular_q {
179 volatile int16_t head;
180 volatile int16_t tail;
191 u_int64_t reqs_errored;
192 u_int64_t spurios_intrs;
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;
210 /* ------------ boolean types ------------------- */
212 #ifndef __bool_true_false_are_defined
213 typedef enum _boolean { false, true } boolean;
217 enum err { SUCCESS, FAILURE };
219 /* ----------- per instance data ---------------- */
221 /* The softc holds our per-instance data. */
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;