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