| 1 | /* $NetBSD: mpt_netbsd.h,v 1.11 2014/04/01 23:57:54 buhrow Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2003 Wasabi Systems, Inc. |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
| 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 | * 1. Redistributions of source code must retain the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer. |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in the |
| 16 | * documentation and/or other materials provided with the distribution. |
| 17 | * 3. All advertising materials mentioning features or use of this software |
| 18 | * must display the following acknowledgement: |
| 19 | * This product includes software developed for the NetBSD Project by |
| 20 | * Wasabi Systems, Inc. |
| 21 | * 4. The name of Wasabi Systems, Inc. may not be used to endorse |
| 22 | * or promote products derived from this software without specific prior |
| 23 | * written permission. |
| 24 | * |
| 25 | * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND |
| 26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 27 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC |
| 29 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 35 | * POSSIBILITY OF SUCH DAMAGE. |
| 36 | */ |
| 37 | |
| 38 | /* |
| 39 | * Copyright (c) 2000, 2001 by Greg Ansley, Adam Prewett |
| 40 | * |
| 41 | * Partially derived from Matt Jacobs ISP driver. |
| 42 | * |
| 43 | * Redistribution and use in source and binary forms, with or without |
| 44 | * modification, are permitted provided that the following conditions |
| 45 | * are met: |
| 46 | * 1. Redistributions of source code must retain the above copyright |
| 47 | * notice immediately at the beginning of the file, without modification, |
| 48 | * this list of conditions, and the following disclaimer. |
| 49 | * 2. The name of the author may not be used to endorse or promote products |
| 50 | * derived from this software without specific prior written permission. |
| 51 | * |
| 52 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 53 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 54 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 55 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR |
| 56 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 57 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 58 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 59 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 60 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 61 | */ |
| 62 | /* |
| 63 | * Additional Copyright (c) 2002 by Matthew Jacob under same license. |
| 64 | */ |
| 65 | |
| 66 | /* |
| 67 | * mpt_netbsd.h: |
| 68 | * |
| 69 | * NetBSD-specific definitions for LSI Fusion adapters. |
| 70 | * |
| 71 | * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for |
| 72 | * Wasabi Systems, Inc. |
| 73 | * |
| 74 | * Additional contributions by Garrett D'Amore on behalf of TELES AG. |
| 75 | */ |
| 76 | |
| 77 | #ifndef _DEV_IC_MPT_NETBSD_H_ |
| 78 | #define _DEV_IC_MPT_NETBSD_H_ |
| 79 | |
| 80 | #include <sys/param.h> |
| 81 | #include <sys/systm.h> |
| 82 | #include <sys/malloc.h> |
| 83 | #include <sys/kernel.h> |
| 84 | #include <sys/callout.h> |
| 85 | #include <sys/errno.h> |
| 86 | #include <sys/buf.h> |
| 87 | #include <sys/queue.h> |
| 88 | #include <sys/device.h> |
| 89 | |
| 90 | #include <sys/bus.h> |
| 91 | #include <sys/intr.h> |
| 92 | |
| 93 | #include <dev/scsipi/scsi_all.h> |
| 94 | #include <dev/scsipi/scsipi_all.h> |
| 95 | #include <dev/scsipi/scsiconf.h> |
| 96 | |
| 97 | #include <dev/ic/mpt_mpilib.h> |
| 98 | |
| 99 | /* Max MPT Reply we are willing to accept (must be a power of 2). */ |
| 100 | #define MPT_REPLY_SIZE 128 |
| 101 | |
| 102 | #define MPT_MAX_REQUESTS(mpt) ((mpt)->is_fc ? 1024 : 256) |
| 103 | #define MPT_REQUEST_AREA 512 |
| 104 | #define MPT_SENSE_SIZE 32 /* included in MPT_REQUEST_AREA */ |
| 105 | #define MPT_REQ_MEM_SIZE(mpt) (MPT_MAX_REQUESTS(mpt) * MPT_REQUEST_AREA) |
| 106 | |
| 107 | /* |
| 108 | * We cannot tell prior to getting IOC facts how big the IOC's request |
| 109 | * area is. Because of this we cannot tell at compile time how many |
| 110 | * simple SG elements we can fit within an IOC request prior to having |
| 111 | * to put in a chain element. |
| 112 | * |
| 113 | * Experimentally we know that the Ultra4 parts have a 96 byte request |
| 114 | * element size and the Fibre Channel units have a 144 byte request |
| 115 | * element size. Therefore, if we have 512-32 (== 480) bytes of request |
| 116 | * area to play with, we have room for between 3 and 5 request sized |
| 117 | * regions- the first of which is the command plus a simple SG list, |
| 118 | * the rest of which are chained continuation SG lists. Given that the |
| 119 | * normal request we use is 48 bytes w/o the first SG element, we can |
| 120 | * assume we have 480-48 == 432 bytes to have simple SG elements and/or |
| 121 | * chain elements. If we assume 32 bit addressing, this works out to |
| 122 | * 54 SG or chain elements. If we assume 5 chain elements, then we have |
| 123 | * a maximum of 49 separate actual SG segments. |
| 124 | */ |
| 125 | #define MPT_SGL_MAX 49 |
| 126 | |
| 127 | #define MPT_RQSL(mpt) ((mpt)->request_frame_size << 2) |
| 128 | #define MPT_NSGL(mpt) (MPT_RQSL(mpt) / sizeof(SGE_SIMPLE32)) |
| 129 | |
| 130 | #define MPT_NSGL_FIRST(mpt) \ |
| 131 | ((((mpt)->request_frame_size << 2) - \ |
| 132 | sizeof(MSG_SCSI_IO_REQUEST) - \ |
| 133 | sizeof(SGE_IO_UNION)) / sizeof(SGE_SIMPLE32)) |
| 134 | |
| 135 | /* |
| 136 | * Convert a physical address returned from IOC to a virtual address |
| 137 | * needed to access the data. |
| 138 | */ |
| 139 | #define MPT_REPLY_PTOV(m, x) \ |
| 140 | ((void *)(&(m)->reply[(((x) << 1) - (m)->reply_phys)])) |
| 141 | |
| 142 | enum mpt_req_state { |
| 143 | REQ_FREE, |
| 144 | REQ_IN_PROGRESS, |
| 145 | REQ_TIMEOUT, |
| 146 | REQ_ON_CHIP, |
| 147 | REQ_DONE |
| 148 | }; |
| 149 | typedef struct req_entry { |
| 150 | uint16_t index; /* index of this entry */ |
| 151 | struct scsipi_xfer *xfer; /* scsipi xfer request */ |
| 152 | void *req_vbuf; /* virtual address of entry */ |
| 153 | void *sense_vbuf; /* virtual address of sense data */ |
| 154 | bus_addr_t req_pbuf; /* physical address of entry */ |
| 155 | bus_addr_t sense_pbuf; /* physical address of sense data */ |
| 156 | bus_dmamap_t dmap; /* DMA map for data buffer */ |
| 157 | SLIST_ENTRY(req_entry) link; /* pointer to next in list */ |
| 158 | enum mpt_req_state debug; /* debugging */ |
| 159 | uint32_t sequence; /* sequence number */ |
| 160 | } request_t; |
| 161 | |
| 162 | typedef struct mpt_softc { |
| 163 | device_t sc_dev; /* base device glue */ |
| 164 | |
| 165 | /* Locking context */ |
| 166 | int mpt_splsaved; |
| 167 | uint32_t mpt_islocked; |
| 168 | |
| 169 | int verbose : 3, |
| 170 | mpt_locksetup : 1, |
| 171 | is_fc : 1, |
| 172 | is_scsi : 1, |
| 173 | is_sas : 1, |
| 174 | bus : 1, |
| 175 | : 23; |
| 176 | |
| 177 | /* IOC facts */ |
| 178 | uint16_t mpt_global_credits; |
| 179 | uint16_t request_frame_size; |
| 180 | uint8_t mpt_max_devices; |
| 181 | uint8_t mpt_max_buses; |
| 182 | |
| 183 | /* Port facts */ |
| 184 | uint16_t mpt_ini_id; |
| 185 | |
| 186 | /* Device configuration information */ |
| 187 | union { |
| 188 | struct mpt_spi_cfg { |
| 189 | fCONFIG_PAGE_SCSI_PORT_0 _port_page0; |
| 190 | fCONFIG_PAGE_SCSI_PORT_1 _port_page1; |
| 191 | fCONFIG_PAGE_SCSI_PORT_2 _port_page2; |
| 192 | fCONFIG_PAGE_SCSI_DEVICE_0 _dev_page0[16]; |
| 193 | fCONFIG_PAGE_SCSI_DEVICE_1 _dev_page1[16]; |
| 194 | uint16_t _tag_enable; |
| 195 | uint16_t _disc_enable; |
| 196 | uint16_t _update_params0; |
| 197 | uint16_t _update_params1; |
| 198 | uint16_t _report_xfer_mode; |
| 199 | } spi; |
| 200 | #define mpt_port_page0 cfg.spi._port_page0 |
| 201 | #define mpt_port_page1 cfg.spi._port_page1 |
| 202 | #define mpt_port_page2 cfg.spi._port_page2 |
| 203 | #define mpt_dev_page0 cfg.spi._dev_page0 |
| 204 | #define mpt_dev_page1 cfg.spi._dev_page1 |
| 205 | #define mpt_tag_enable cfg.spi._tag_enable |
| 206 | #define mpt_disc_enable cfg.spi._disc_enable |
| 207 | #define mpt_update_params0 cfg.spi._update_params0 |
| 208 | #define mpt_update_params1 cfg.spi._update_params1 |
| 209 | #define mpt_report_xfer_mode cfg.spi._report_xfer_mode |
| 210 | |
| 211 | struct mpt_fc_cfg { |
| 212 | uint8_t nada; |
| 213 | } fc; |
| 214 | } cfg; |
| 215 | |
| 216 | bus_space_tag_t sc_st; |
| 217 | bus_space_handle_t sc_sh; |
| 218 | bus_dma_tag_t sc_dmat; |
| 219 | |
| 220 | /* Reply memory */ |
| 221 | bus_dmamap_t reply_dmap; |
| 222 | char *reply; |
| 223 | bus_addr_t reply_phys; |
| 224 | |
| 225 | /* Request memory */ |
| 226 | bus_dmamap_t request_dmap; |
| 227 | char *request; |
| 228 | bus_addr_t request_phys; |
| 229 | |
| 230 | /* SCSIPI and software management */ |
| 231 | request_t *request_pool; |
| 232 | SLIST_HEAD(req_queue, req_entry) request_free_list; |
| 233 | request_t *mngt_req; |
| 234 | |
| 235 | struct scsipi_adapter sc_adapter; |
| 236 | struct scsipi_channel sc_channel; |
| 237 | device_t sc_scsibus_dv; /*So we can rescan in case of errors*/ |
| 238 | |
| 239 | uint32_t sequence; /* sequence number */ |
| 240 | uint32_t timeouts; /* timeout count */ |
| 241 | uint32_t success; /* success after timeout */ |
| 242 | |
| 243 | /* To restore configuration after hard reset. */ |
| 244 | void (*sc_set_config_regs)(struct mpt_softc *); |
| 245 | } mpt_softc_t; |
| 246 | |
| 247 | #define MPT_SYNC_REQ(mpt, req, ops) \ |
| 248 | bus_dmamap_sync((mpt)->sc_dmat, (mpt)->request_dmap, \ |
| 249 | (req)->req_pbuf - (mpt)->request_phys, \ |
| 250 | MPT_REQUEST_AREA, (ops)) |
| 251 | |
| 252 | #define mpt_read(mpt, reg) \ |
| 253 | bus_space_read_4((mpt)->sc_st, (mpt)->sc_sh, (reg)) |
| 254 | #define mpt_write(mpt, reg, val) \ |
| 255 | bus_space_write_4((mpt)->sc_st, (mpt)->sc_sh, (reg), (val)) |
| 256 | |
| 257 | void mpt_scsipi_attach(mpt_softc_t *); |
| 258 | int mpt_dma_mem_alloc(mpt_softc_t *); |
| 259 | int mpt_intr(void *); |
| 260 | void mpt_prt(mpt_softc_t *, const char *, ...); |
| 261 | |
| 262 | #define mpt_set_config_regs(mpt) \ |
| 263 | do { \ |
| 264 | if ((mpt)->sc_set_config_regs != NULL) \ |
| 265 | (*(mpt)->sc_set_config_regs)((mpt)); \ |
| 266 | } while (/*CONSTCOND*/0) |
| 267 | |
| 268 | #endif /* _DEV_IC_MPT_NETBSD_H_ */ |
| 269 | |