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 | |