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