1 | /* $NetBSD: isp_netbsd.h,v 1.75 2015/08/28 13:03:36 joerg Exp $ */ |
2 | /* |
3 | * NetBSD Specific definitions for the Qlogic ISP Host Adapter |
4 | */ |
5 | /* |
6 | * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration |
7 | * All rights reserved. |
8 | * |
9 | * Additional Copyright (C) 2000-2007 by Matthew Jacob |
10 | * All rights reserved. |
11 | * |
12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions |
14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions and the following disclaimer. |
17 | * 2. Redistributions in binary form must reproduce the above copyright |
18 | * notice, this list of conditions and the following disclaimer in the |
19 | * documentation and/or other materials provided with the distribution. |
20 | * 3. The name of the author may not be used to endorse or promote products |
21 | * derived from this software without specific prior written permission |
22 | * |
23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
24 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
25 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
26 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
27 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
28 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
30 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ |
34 | #ifndef _ISP_NETBSD_H |
35 | #define _ISP_NETBSD_H |
36 | |
37 | #include <sys/types.h> |
38 | #include <sys/param.h> |
39 | #include <sys/systm.h> |
40 | #include <sys/kernel.h> |
41 | #include <sys/errno.h> |
42 | #include <sys/ioctl.h> |
43 | #include <sys/device.h> |
44 | #include <sys/malloc.h> |
45 | #include <sys/buf.h> |
46 | #include <sys/proc.h> |
47 | #include <sys/kthread.h> |
48 | |
49 | #include <sys/bus.h> |
50 | |
51 | #include <dev/scsipi/scsi_all.h> |
52 | #include <dev/scsipi/scsipi_all.h> |
53 | #include <dev/scsipi/scsiconf.h> |
54 | |
55 | #include <dev/scsipi/scsi_message.h> |
56 | #include <dev/scsipi/scsipi_debug.h> |
57 | |
58 | #include "opt_isp.h" |
59 | |
60 | /* |
61 | * Efficiency- get rid of SBus code && tests unless we need them. |
62 | */ |
63 | #if defined(__sparcv9__ ) || defined(__sparc__) |
64 | #define ISP_SBUS_SUPPORTED 1 |
65 | #else |
66 | #define ISP_SBUS_SUPPORTED 0 |
67 | #endif |
68 | |
69 | #define ISP_PLATFORM_VERSION_MAJOR 5 |
70 | #define ISP_PLATFORM_VERSION_MINOR 0 |
71 | |
72 | struct isposinfo { |
73 | device_t dev; |
74 | struct scsipi_adapter adapter; |
75 | struct scsipi_channel * chan; |
76 | bus_dma_tag_t dmatag; |
77 | bus_dmamap_t rqdmap; |
78 | bus_dmamap_t rsdmap; |
79 | bus_dmamap_t scdmap; /* FC only */ |
80 | uint64_t wwns[256]; /* FC only */ |
81 | int splsaved; |
82 | int mboxwaiting; |
83 | uint32_t islocked; |
84 | uint32_t onintstack; |
85 | uint32_t loop_down_time; |
86 | uint32_t loop_down_limit; |
87 | uint32_t gone_device_time; |
88 | unsigned int : 16, |
89 | : 8, |
90 | gdt_running : 1, |
91 | loop_checked : 1, |
92 | mbox_sleeping : 1, |
93 | mbox_sleep_ok : 1, |
94 | mboxcmd_done : 1, |
95 | mboxbsy : 1, |
96 | paused : 1, |
97 | blocked : 1; |
98 | struct callout ldt; /* loop down timer */ |
99 | struct callout gdt; /* gone device timer */ |
100 | uint64_t wwn; |
101 | uint16_t framesize; |
102 | uint16_t exec_throttle; |
103 | struct lwp * thread; |
104 | }; |
105 | #define isp_dmatag isp_osinfo.dmatag |
106 | #define isp_rqdmap isp_osinfo.rqdmap |
107 | #define isp_rsdmap isp_osinfo.rsdmap |
108 | #define isp_scdmap isp_osinfo.scdmap |
109 | |
110 | #define ISP_MUSTPOLL(isp) \ |
111 | (isp->isp_osinfo.onintstack || isp->isp_osinfo.mbox_sleep_ok == 0) |
112 | |
113 | /* |
114 | * Required Macros/Defines |
115 | */ |
116 | |
117 | #define ISP_FC_SCRLEN 0x1000 |
118 | |
119 | #define ISP_MEMZERO(dst, a) memset((dst), 0, (a)) |
120 | #define ISP_MEMCPY(dst, src, a) memcpy((dst), (src), (a)) |
121 | #define ISP_SNPRINTF snprintf |
122 | #define ISP_DELAY DELAY |
123 | #define ISP_SLEEP(isp, x) \ |
124 | if (!ISP_MUSTPOLL(isp)) \ |
125 | ISP_UNLOCK(isp); \ |
126 | DELAY(x); \ |
127 | if (!ISP_MUSTPOLL(isp)) \ |
128 | ISP_LOCK(isp) |
129 | |
130 | #define ISP_MIN imin |
131 | #define ISP_INLINE |
132 | |
133 | #define NANOTIME_T struct timeval |
134 | #define GET_NANOTIME microtime |
135 | #define GET_NANOSEC(x) (((x)->tv_sec * 1000000 + (x)->tv_usec) * 1000) |
136 | #define NANOTIME_SUB isp_microtime_sub |
137 | |
138 | #define MAXISPREQUEST(isp) 256 |
139 | |
140 | |
141 | #define MEMORYBARRIER(isp, type, offset, size, c) \ |
142 | switch (type) { \ |
143 | case SYNC_REQUEST: \ |
144 | { \ |
145 | off_t off = (off_t) offset * QENTRY_LEN; \ |
146 | bus_dmamap_sync(isp->isp_dmatag, isp->isp_rqdmap, \ |
147 | off, size, BUS_DMASYNC_PREWRITE); \ |
148 | break; \ |
149 | } \ |
150 | case SYNC_RESULT: \ |
151 | { \ |
152 | off_t off = (off_t) offset * QENTRY_LEN; \ |
153 | bus_dmamap_sync(isp->isp_dmatag, isp->isp_rsdmap, \ |
154 | off, size, BUS_DMASYNC_POSTREAD); \ |
155 | break; \ |
156 | } \ |
157 | case SYNC_SFORDEV: \ |
158 | { \ |
159 | off_t off = (off_t) offset; \ |
160 | bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \ |
161 | off, size, BUS_DMASYNC_PREWRITE); \ |
162 | break; \ |
163 | } \ |
164 | case SYNC_SFORCPU: \ |
165 | { \ |
166 | off_t off = (off_t) offset; \ |
167 | bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \ |
168 | off, size, BUS_DMASYNC_POSTREAD); \ |
169 | break; \ |
170 | } \ |
171 | default: \ |
172 | break; \ |
173 | } |
174 | |
175 | #define MBOX_ACQUIRE isp_mbox_acquire |
176 | #define MBOX_WAIT_COMPLETE isp_mbox_wait_complete |
177 | #define MBOX_NOTIFY_COMPLETE isp_mbox_notify_done |
178 | #define MBOX_RELEASE isp_mbox_release |
179 | |
180 | #define FC_SCRATCH_ACQUIRE(isp, chan) 0 |
181 | #define FC_SCRATCH_RELEASE(isp, chan) do { } while (0) |
182 | |
183 | #ifndef SCSI_GOOD |
184 | #define SCSI_GOOD 0x0 |
185 | #endif |
186 | #ifndef SCSI_CHECK |
187 | #define SCSI_CHECK 0x2 |
188 | #endif |
189 | #ifndef SCSI_BUSY |
190 | #define SCSI_BUSY 0x8 |
191 | #endif |
192 | #ifndef SCSI_QFULL |
193 | #define SCSI_QFULL 0x28 |
194 | #endif |
195 | |
196 | #define XS_T struct scsipi_xfer |
197 | #define XS_DMA_ADDR_T bus_addr_t |
198 | #define XS_DMA_ADDR_T bus_addr_t |
199 | #define XS_GET_DMA64_SEG(a, b, c) \ |
200 | { \ |
201 | ispds64_t *d = a; \ |
202 | bus_dma_segment_t *e = b; \ |
203 | uint32_t f = c; \ |
204 | e += f; \ |
205 | d->ds_base = DMA_LO32(e->ds_addr); \ |
206 | d->ds_basehi = DMA_HI32(e->ds_addr); \ |
207 | d->ds_count = e->ds_len; \ |
208 | } |
209 | #define XS_GET_DMA_SEG(a, b, c) \ |
210 | { \ |
211 | ispds_t *d = a; \ |
212 | bus_dma_segment_t *e = b; \ |
213 | uint32_t f = c; \ |
214 | e += f; \ |
215 | d->ds_base = DMA_LO32(e->ds_addr); \ |
216 | d->ds_count = e->ds_len; \ |
217 | } |
218 | #define XS_CHANNEL(xs) \ |
219 | ((int) (xs)->xs_periph->periph_channel->chan_channel) |
220 | #define XS_ISP(xs) \ |
221 | device_private((xs)->xs_periph->periph_channel->chan_adapter->adapt_dev) |
222 | #define XS_LUN(xs) ((int) (xs)->xs_periph->periph_lun) |
223 | #define XS_TGT(xs) ((int) (xs)->xs_periph->periph_target) |
224 | #define XS_CDBP(xs) ((uint8_t *) (xs)->cmd) |
225 | #define XS_CDBLEN(xs) (xs)->cmdlen |
226 | #define XS_XFRLEN(xs) (xs)->datalen |
227 | #define XS_TIME(xs) (xs)->timeout |
228 | #define XS_GET_RESID(xs) (xs)->resid |
229 | #define XS_SET_RESID(xs, r) (xs)->resid = r |
230 | #define XS_STSP(xs) (&(xs)->status) |
231 | #define XS_SNSP(xs) (&(xs)->sense.scsi_sense) |
232 | #define XS_SNSLEN(xs) (sizeof (xs)->sense) |
233 | #define XS_SNSKEY(xs) SSD_SENSE_KEY((xs)->sense.scsi_sense.flags) |
234 | #define XS_SNSASC(xs) ((xs)->sense.scsi_sense.asc) |
235 | #define XS_SNSASCQ(xs) ((xs)->sense.scsi_sense.ascq) |
236 | /* PORTING NOTES: check to see if there's a better way of checking for tagged */ |
237 | #define XS_TAG_P(ccb) (((xs)->xs_control & XS_CTL_POLL) != 0) |
238 | /* PORTING NOTES: We elimited OTAG option for performance */ |
239 | #define XS_TAG_TYPE(xs) \ |
240 | (((xs)->xs_control & XS_CTL_URGENT) ? REQFLAG_HTAG : REQFLAG_STAG) |
241 | |
242 | #define XS_SETERR(xs, v) (xs)->error = v |
243 | |
244 | # define HBA_NOERROR XS_NOERROR |
245 | # define HBA_BOTCH XS_DRIVER_STUFFUP |
246 | # define HBA_CMDTIMEOUT XS_TIMEOUT |
247 | # define HBA_SELTIMEOUT XS_SELTIMEOUT |
248 | # define HBA_TGTBSY XS_BUSY |
249 | # define HBA_BUSRESET XS_RESET |
250 | # define HBA_ABORTED XS_DRIVER_STUFFUP |
251 | # define HBA_DATAOVR XS_DRIVER_STUFFUP |
252 | # define HBA_ARQFAIL XS_DRIVER_STUFFUP |
253 | |
254 | #define XS_ERR(xs) (xs)->error |
255 | #define XS_NOERR(xs) ((xs)->error == XS_NOERROR) |
256 | #define XS_INITERR(xs) (xs)->error = 0, XS_CMD_S_CLEAR(xs) |
257 | |
258 | #define XS_SAVE_SENSE(xs, ptr, len) \ |
259 | if (xs->error == XS_NOERROR) { \ |
260 | xs->error = XS_SENSE; \ |
261 | } \ |
262 | memcpy(&(xs)->sense, ptr, imin(XS_SNSLEN(xs), len)) |
263 | |
264 | #define XS_SENSE_VALID(xs) (xs)->error == XS_SENSE |
265 | |
266 | #define DEFAULT_FRAMESIZE(isp) (isp)->isp_osinfo.framesize |
267 | #define DEFAULT_EXEC_THROTTLE(isp) (isp)->isp_osinfo.exec_throttle |
268 | #define GET_DEFAULT_ROLE(isp, chan) ISP_ROLE_INITIATOR |
269 | #define SET_DEFAULT_ROLE(isp, chan) do { } while (0) |
270 | #define DEFAULT_IID(x, chan) 7 |
271 | #define DEFAULT_LOOPID(x, chan) 108 |
272 | #define DEFAULT_NODEWWN(isp, chan) (isp)->isp_osinfo.wwn |
273 | #define DEFAULT_PORTWWN(isp, chan) (isp)->isp_osinfo.wwn |
274 | #define ACTIVE_NODEWWN(isp, chan) \ |
275 | ((isp)->isp_osinfo.wwn? (isp)->isp_osinfo.wwn : \ |
276 | (FCPARAM(isp, chan)->isp_wwnn_nvram? \ |
277 | FCPARAM(isp, chan)->isp_wwnn_nvram : 0x400000007F000008ull)) |
278 | #define ACTIVE_PORTWWN(isp, chan) \ |
279 | ((isp)->isp_osinfo.wwn? (isp)->isp_osinfo.wwn : \ |
280 | (FCPARAM(isp, chan)->isp_wwpn_nvram? \ |
281 | FCPARAM(isp, chan)->isp_wwpn_nvram : 0x400000007F000008ull)) |
282 | |
283 | #if _BYTE_ORDER == _BIG_ENDIAN |
284 | #ifdef ISP_SBUS_SUPPORTED |
285 | #define ISP_IOXPUT_8(isp, s, d) *(d) = s |
286 | #define ISP_IOXPUT_16(isp, s, d) \ |
287 | *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap16(s) |
288 | #define ISP_IOXPUT_32(isp, s, d) \ |
289 | *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : bswap32(s) |
290 | |
291 | #define ISP_IOXGET_8(isp, s, d) d = (*((uint8_t *)s)) |
292 | #define ISP_IOXGET_16(isp, s, d) \ |
293 | d = (isp->isp_bustype == ISP_BT_SBUS)? \ |
294 | *((uint16_t *)s) : bswap16(*((uint16_t *)s)) |
295 | #define ISP_IOXGET_32(isp, s, d) \ |
296 | d = (isp->isp_bustype == ISP_BT_SBUS)? \ |
297 | *((uint32_t *)s) : bswap32(*((uint32_t *)s)) |
298 | |
299 | #else /* ISP_SBUS_SUPPORTED */ |
300 | #define ISP_IOXPUT_8(isp, s, d) *(d) = s |
301 | #define ISP_IOXPUT_16(isp, s, d) *(d) = bswap16(s) |
302 | #define ISP_IOXPUT_32(isp, s, d) *(d) = bswap32(s) |
303 | #define ISP_IOXGET_8(isp, s, d) d = (*((uint8_t *)s)) |
304 | #define ISP_IOXGET_16(isp, s, d) d = bswap16(*((uint16_t *)s)) |
305 | #define ISP_IOXGET_32(isp, s, d) d = bswap32(*((uint32_t *)s)) |
306 | #endif /* ISP_SBUS_SUPPORTED */ |
307 | #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = bswap16(*rp) |
308 | #define ISP_SWIZZLE_NVRAM_LONG(isp, rp) *rp = bswap32(*rp) |
309 | |
310 | #define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)s)) |
311 | #define ISP_IOZGET_16(isp, s, d) d = (*((uint16_t *)s)) |
312 | #define ISP_IOZGET_32(isp, s, d) d = (*((uint32_t *)s)) |
313 | #define ISP_IOZPUT_8(isp, s, d) *(d) = s |
314 | #define ISP_IOZPUT_16(isp, s, d) *(d) = s |
315 | #define ISP_IOZPUT_32(isp, s, d) *(d) = s |
316 | |
317 | #else |
318 | #define ISP_IOXPUT_8(isp, s, d) *(d) = s |
319 | #define ISP_IOXPUT_16(isp, s, d) *(d) = s |
320 | #define ISP_IOXPUT_32(isp, s, d) *(d) = s |
321 | #define ISP_IOXGET_8(isp, s, d) d = *(s) |
322 | #define ISP_IOXGET_16(isp, s, d) d = *(s) |
323 | #define ISP_IOXGET_32(isp, s, d) d = *(s) |
324 | #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) |
325 | #define ISP_SWIZZLE_NVRAM_LONG(isp, rp) |
326 | |
327 | #define ISP_IOZPUT_8(isp, s, d) *(d) = s |
328 | #define ISP_IOZPUT_16(isp, s, d) *(d) = bswap16(s) |
329 | #define ISP_IOZPUT_32(isp, s, d) *(d) = bswap32(s) |
330 | |
331 | #define ISP_IOZGET_8(isp, s, d) d = (*((uint8_t *)(s))) |
332 | #define ISP_IOZGET_16(isp, s, d) d = bswap16(*((uint16_t *)(s))) |
333 | #define ISP_IOZGET_32(isp, s, d) d = bswap32(*((uint32_t *)(s))) |
334 | |
335 | #endif |
336 | |
337 | #define ISP_SWAP16(isp, x) bswap16(x) |
338 | #define ISP_SWAP32(isp, x) bswap32(x) |
339 | |
340 | /* |
341 | * Includes of common header files |
342 | */ |
343 | |
344 | #include <dev/ic/ispreg.h> |
345 | #include <dev/ic/ispvar.h> |
346 | #include <dev/ic/ispmbox.h> |
347 | |
348 | /* |
349 | * isp_osinfo definitions, extensions and shorthand. |
350 | */ |
351 | #define isp_unit device_unit(isp_osinfo.dev) |
352 | |
353 | |
354 | /* |
355 | * Driver prototypes.. |
356 | */ |
357 | void isp_attach(ispsoftc_t *); |
358 | void isp_uninit(ispsoftc_t *); |
359 | |
360 | /* |
361 | * Driver wide data... |
362 | */ |
363 | |
364 | /* |
365 | * Locking macros... |
366 | */ |
367 | #define ISP_LOCK isp_lock |
368 | #define ISP_UNLOCK isp_unlock |
369 | #define ISP_ILOCK(x) isp_lock(x); isp->isp_osinfo.onintstack++ |
370 | #define ISP_IUNLOCK(x) isp->isp_osinfo.onintstack--; isp_unlock(x) |
371 | |
372 | /* |
373 | * Platform private flags |
374 | */ |
375 | |
376 | #define XS_PSTS_INWDOG 0x10000000 |
377 | #define XS_PSTS_GRACE 0x20000000 |
378 | #define XS_PSTS_ALL 0x30000000 |
379 | |
380 | #define XS_CMD_S_WDOG(xs) (xs)->xs_status |= XS_PSTS_INWDOG |
381 | #define XS_CMD_C_WDOG(xs) (xs)->xs_status &= ~XS_PSTS_INWDOG |
382 | #define XS_CMD_WDOG_P(xs) (((xs)->xs_status & XS_PSTS_INWDOG) != 0) |
383 | |
384 | #define XS_CMD_S_GRACE(xs) (xs)->xs_status |= XS_PSTS_GRACE |
385 | #define XS_CMD_C_GRACE(xs) (xs)->xs_status &= ~XS_PSTS_GRACE |
386 | #define XS_CMD_GRACE_P(xs) (((xs)->xs_status & XS_PSTS_GRACE) != 0) |
387 | |
388 | #define XS_CMD_S_DONE(xs) (xs)->xs_status |= XS_STS_DONE |
389 | #define XS_CMD_C_DONE(xs) (xs)->xs_status &= ~XS_STS_DONE |
390 | #define XS_CMD_DONE_P(xs) (((xs)->xs_status & XS_STS_DONE) != 0) |
391 | |
392 | #define XS_CMD_S_CLEAR(xs) (xs)->xs_status &= ~XS_PSTS_ALL |
393 | |
394 | /* |
395 | * Platform Library Functionw |
396 | */ |
397 | void isp_prt(ispsoftc_t *, int level, const char *, ...); |
398 | void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...); |
399 | void isp_lock(ispsoftc_t *); |
400 | void isp_unlock(ispsoftc_t *); |
401 | uint64_t isp_microtime_sub(struct timeval *, struct timeval *); |
402 | int isp_mbox_acquire(ispsoftc_t *); |
403 | void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *); |
404 | void isp_mbox_notify_done(ispsoftc_t *); |
405 | void isp_mbox_release(ispsoftc_t *); |
406 | |
407 | /* |
408 | * Common Library functions |
409 | */ |
410 | #include <dev/ic/isp_library.h> |
411 | |
412 | #if !defined(ISP_DISABLE_FW) && !defined(ISP_COMPILE_FW) |
413 | #define ISP_COMPILE_FW 1 |
414 | #endif |
415 | #endif /* _ISP_NETBSD_H */ |
416 | |