1 /* $NetBSD: isp_netbsd.h,v 1.76 2019/09/20 14:20:45 christos 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 *, ...) __printflike(3, 4);
398 void isp_xs_prt(ispsoftc_t *, XS_T *, int level, const char *, ...)
399     __printflike(4, 5);
400 void isp_lock(ispsoftc_t *);
401 void isp_unlock(ispsoftc_t *);
402 uint64_t isp_microtime_sub(struct timeval *, struct timeval *);
403 int isp_mbox_acquire(ispsoftc_t *);
404 void isp_mbox_wait_complete(ispsoftc_t *, mbreg_t *);
405 void isp_mbox_notify_done(ispsoftc_t *);
406 void isp_mbox_release(ispsoftc_t *);
407 
408 /*
409  * Common Library functions
410  */
411 #include <dev/ic/isp_library.h>
412 
413 #if       !defined(ISP_DISABLE_FW) && !defined(ISP_COMPILE_FW)
414 #define   ISP_COMPILE_FW      1
415 #endif
416 #endif    /* _ISP_NETBSD_H */
417