Annotation of sys/dev/ic/isp_openbsd.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: isp_openbsd.h,v 1.26 2004/08/02 19:55:45 art Exp $ */
2: /*
3: * OpenBSD Specific definitions for the Qlogic ISP Host Adapter
4: */
5: /*
6: * Copyright (C) 1999, 2000, 2001 by Matthew Jacob
7: * All rights reserved.
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. The name of the author may not be used to endorse or promote products
15: * derived from this software without specific prior written permission
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: */
28: #ifndef _ISP_OPENBSD_H
29: #define _ISP_OPENBSD_H
30:
31: #include <sys/types.h>
32: #include <sys/param.h>
33: #include <sys/systm.h>
34: #include <sys/kernel.h>
35: #include <sys/errno.h>
36: #include <sys/ioctl.h>
37: #include <sys/device.h>
38: #include <sys/malloc.h>
39: #include <sys/buf.h>
40: #include <sys/proc.h>
41: #include <sys/user.h>
42: #include <sys/queue.h>
43:
44: #if !(defined(__sparc__) && !defined(__sparcv9__))
45: #include <machine/bus.h>
46: #endif
47:
48: #include <scsi/scsi_all.h>
49: #include <scsi/scsiconf.h>
50:
51: #include <scsi/scsi_message.h>
52: #include <scsi/scsi_debug.h>
53:
54: #include <uvm/uvm_extern.h>
55:
56: /*
57: * Efficiency- get rid of SBus code && tests unless we need them.
58: */
59: #if defined(__sparcv9__ ) || defined(__sparc__)
60: #define ISP_SBUS_SUPPORTED 1
61: #else
62: #define ISP_SBUS_SUPPORTED 0
63: #endif
64:
65: #define ISP_PLATFORM_VERSION_MAJOR 2
66: #define ISP_PLATFORM_VERSION_MINOR 1
67:
68: struct isposinfo {
69: struct device _dev;
70: struct scsi_link _link[2];
71: struct scsi_adapter _adapter;
72: int hiwater;
73: int splsaved;
74: int mboxwaiting;
75: u_int32_t islocked;
76: u_int32_t onintstack;
77: #if !(defined(__sparc__) && !defined(__sparcv9__))
78: bus_dma_tag_t dmatag;
79: bus_dmamap_t rqdmap;
80: bus_dmamap_t rsdmap;
81: bus_dmamap_t scdmap; /* FC only */
82: #define isp_dmatag isp_osinfo.dmatag
83: #define isp_rqdmap isp_osinfo.rqdmap
84: #define isp_rsdmap isp_osinfo.rsdmap
85: #define isp_scdmap isp_osinfo.scdmap
86: #endif
87: unsigned int : 28,
88:
89: rtpend : 1,
90: no_mbox_ints : 1,
91: blocked : 2;
92: union {
93: u_int64_t _wwn;
94: u_int16_t _discovered[2];
95: } un;
96: #define discovered un._discovered
97: struct scsi_xfer *wqf, *wqt;
98: struct timeout rqt;
99: };
100: #define MUST_POLL(isp) \
101: (isp->isp_osinfo.onintstack || isp->isp_osinfo.no_mbox_ints)
102:
103: /*
104: * Locking macros...
105: */
106: #define ISP_LOCK isp_lock
107: #define ISP_UNLOCK isp_unlock
108:
109: /*
110: * Required Macros/Defines
111: */
112:
113: #define INLINE __inline
114:
115: /* We don't want expensive inline functions. */
116: #define EXP_INLINE
117:
118: #define ISP2100_SCRLEN 0x800
119:
120: #define MEMZERO bzero
121: #define MEMCPY(dst, src, amt) bcopy((src), (dst), (amt))
122: #define SNPRINTF snprintf
123: #define USEC_DELAY(x) delay(x)
124: #define USEC_SLEEP(isp, x) \
125: if (!MUST_POLL(isp)) \
126: ISP_UNLOCK(isp); \
127: delay(x); \
128: if (!MUST_POLL(isp)) \
129: ISP_LOCK(isp)
130:
131: #define NANOTIME_T struct timespec
132: #define GET_NANOTIME nanotime
133: #define GET_NANOSEC(x) (((x)->tv_sec * 1000000000 + (x)->tv_nsec))
134: #define NANOTIME_SUB isp_nanotime_sub
135:
136: #define MAXISPREQUEST(isp) 256
137:
138: #if !(defined(__sparc__) && !defined(__sparcv9__))
139: #define MEMORYBARRIER(isp, type, offset, size) \
140: switch (type) { \
141: case SYNC_REQUEST: \
142: { \
143: off_t off = (off_t) offset * QENTRY_LEN; \
144: bus_dmamap_sync(isp->isp_dmatag, isp->isp_rqdmap, \
145: off, size, BUS_DMASYNC_PREWRITE); \
146: break; \
147: } \
148: case SYNC_RESULT: \
149: { \
150: off_t off = (off_t) offset * QENTRY_LEN; \
151: bus_dmamap_sync(isp->isp_dmatag, isp->isp_rsdmap, \
152: off, size, BUS_DMASYNC_POSTREAD); \
153: break; \
154: } \
155: case SYNC_SFORDEV: \
156: { \
157: off_t off = (off_t) offset; \
158: bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \
159: off, size, BUS_DMASYNC_PREWRITE); \
160: break; \
161: } \
162: case SYNC_SFORCPU: \
163: { \
164: off_t off = (off_t) offset; \
165: bus_dmamap_sync(isp->isp_dmatag, isp->isp_scdmap, \
166: off, size, BUS_DMASYNC_POSTREAD); \
167: break; \
168: } \
169: case SYNC_REG: \
170: default: \
171: break; \
172: }
173: #else
174: #define MEMORYBARRIER(isp, type, offset, size)
175: #endif
176:
177: #define MBOX_ACQUIRE(isp)
178: #define MBOX_WAIT_COMPLETE isp_wait_complete
179:
180: #define MBOX_NOTIFY_COMPLETE(isp) \
181: if (isp->isp_osinfo.mboxwaiting) { \
182: isp->isp_osinfo.mboxwaiting = 0; \
183: wakeup(&isp->isp_osinfo.mboxwaiting); \
184: } \
185: isp->isp_mboxbsy = 0
186:
187: #define MBOX_RELEASE(isp)
188:
189: #define FC_SCRATCH_ACQUIRE(isp)
190: #define FC_SCRATCH_RELEASE(isp)
191:
192: #ifndef SCSI_GOOD
193: #define SCSI_GOOD 0x0
194: #endif
195: #ifndef SCSI_CHECK
196: #define SCSI_CHECK 0x2
197: #endif
198: #ifndef SCSI_BUSY
199: #define SCSI_BUSY 0x8
200: #endif
201: #ifndef SCSI_QFULL
202: #define SCSI_QFULL 0x28
203: #endif
204:
205: #define XS_T struct scsi_xfer
206: #define XS_CHANNEL(xs) (((xs)->sc_link->flags & SDEV_2NDBUS)? 1 : 0)
207: #define XS_ISP(xs) (xs)->sc_link->adapter_softc
208: #define XS_LUN(xs) ((int) (xs)->sc_link->lun)
209: #define XS_TGT(xs) ((int) (xs)->sc_link->target)
210: #define XS_CDBP(xs) ((caddr_t) (xs)->cmd)
211: #define XS_CDBLEN(xs) (xs)->cmdlen
212: #define XS_XFRLEN(xs) (xs)->datalen
213: #define XS_TIME(xs) (xs)->timeout
214: #define XS_RESID(xs) (xs)->resid
215: #define XS_STSP(xs) (&(xs)->status)
216: #define XS_SNSP(xs) (&(xs)->sense)
217: #define XS_SNSLEN(xs) (sizeof (xs)->sense)
218: #define XS_SNSKEY(xs) ((xs)->sense.flags)
219: #define XS_TAG_P(xs) (((xs)->flags & SCSI_POLL) != 0)
220: #define XS_TAG_TYPE(xs) REQFLAG_STAG
221:
222: #define XS_SETERR(xs, v) (xs)->error = v
223:
224: # define HBA_NOERROR XS_NOERROR
225: # define HBA_BOTCH XS_DRIVER_STUFFUP
226: # define HBA_CMDTIMEOUT XS_TIMEOUT
227: # define HBA_SELTIMEOUT XS_SELTIMEOUT
228: # define HBA_TGTBSY XS_BUSY
229: # define HBA_BUSRESET XS_RESET
230: # define HBA_ABORTED XS_DRIVER_STUFFUP
231: # define HBA_DATAOVR XS_DRIVER_STUFFUP
232: # define HBA_ARQFAIL XS_DRIVER_STUFFUP
233:
234: #define XS_ERR(xs) (xs)->error
235:
236: #define XS_NOERR(xs) (xs)->error == XS_NOERROR
237:
238: #define XS_INITERR(xs) (xs)->error = 0, XS_CMD_S_CLEAR(xs)
239:
240: #define XS_SAVE_SENSE(xs, sp) \
241: if (xs->error == XS_NOERROR) { \
242: xs->error = XS_SENSE; \
243: } \
244: bcopy(sp->req_sense_data, &(xs)->sense, \
245: imin(XS_SNSLEN(xs), sp->req_sense_len))
246:
247: #define XS_SET_STATE_STAT(a, b, c)
248:
249: #define DEFAULT_IID(x) 7
250: #define DEFAULT_LOOPID(x) 107
251: #define DEFAULT_NODEWWN(isp) (isp)->isp_osinfo.un._wwn
252: #define DEFAULT_PORTWWN(isp) (isp)->isp_osinfo.un._wwn
253: #define ISP_NODEWWN(isp) FCPARAM(isp)->isp_nodewwn
254: #define ISP_PORTWWN(isp) FCPARAM(isp)->isp_portwwn
255:
256: #if BYTE_ORDER == BIG_ENDIAN
257: #ifdef ISP_SBUS_SUPPORTED
258: #define ISP_IOXPUT_8(isp, s, d) *(d) = s
259: #define ISP_IOXPUT_16(isp, s, d) \
260: *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : swap16(s)
261: #define ISP_IOXPUT_32(isp, s, d) \
262: *(d) = (isp->isp_bustype == ISP_BT_SBUS)? s : swap32(s)
263:
264: #define ISP_IOXGET_8(isp, s, d) d = (*((u_int8_t *)s))
265: #define ISP_IOXGET_16(isp, s, d) \
266: d = (isp->isp_bustype == ISP_BT_SBUS)? \
267: *((u_int16_t *)s) : swap16(*((u_int16_t *)s))
268: #define ISP_IOXGET_32(isp, s, d) \
269: d = (isp->isp_bustype == ISP_BT_SBUS)? \
270: *((u_int32_t *)s) : swap32(*((u_int32_t *)s))
271: #else
272: #define ISP_IOXPUT_8(isp, s, d) *(d) = s
273: #define ISP_IOXPUT_16(isp, s, d) *(d) = swap16(s)
274: #define ISP_IOXPUT_32(isp, s, d) *(d) = swap32(s)
275: #define ISP_IOXGET_8(isp, s, d) d = (*((u_int8_t *)s))
276: #define ISP_IOXGET_16(isp, s, d) d = swap16(*((u_int16_t *)s))
277: #define ISP_IOXGET_32(isp, s, d) d = swap32(*((u_int32_t *)s))
278: #endif
279: #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = swap16(*rp)
280: #else
281: #define ISP_IOXPUT_8(isp, s, d) *(d) = s
282: #define ISP_IOXPUT_16(isp, s, d) *(d) = s
283: #define ISP_IOXPUT_32(isp, s, d) *(d) = s
284: #define ISP_IOXGET_8(isp, s, d) d = *(s)
285: #define ISP_IOXGET_16(isp, s, d) d = *(s)
286: #define ISP_IOXGET_32(isp, s, d) d = *(s)
287: #define ISP_SWIZZLE_NVRAM_WORD(isp, rp)
288: #endif
289:
290: /*
291: * Includes of common header files
292: */
293:
294: #include <dev/ic/ispreg.h>
295: #include <dev/ic/ispvar.h>
296: #include <dev/ic/ispmbox.h>
297:
298: /*
299: * isp_osinfo definitions, extensions and shorthand.
300: */
301: #define isp_name isp_osinfo._dev.dv_xname
302: #define isp_unit isp_osinfo._dev.dv_unit
303:
304: /*
305: * Driver prototypes..
306: */
307: void isp_attach(struct ispsoftc *);
308: void isp_uninit(struct ispsoftc *);
309:
310: static INLINE void isp_lock(struct ispsoftc *);
311: static INLINE void isp_unlock(struct ispsoftc *);
312: static INLINE u_int64_t
313: isp_nanotime_sub(struct timespec *, struct timespec *);
314: static void isp_wait_complete(struct ispsoftc *);
315:
316: /*
317: * Driver wide data...
318: */
319:
320: /*
321: * Platform private flags
322: */
323:
324: #define XS_PSTS_INWDOG 0x10000
325: #define XS_PSTS_GRACE 0x20000
326: #define XS_PSTS_TIMED 0x40000
327: #define XS_PSTS_ALL SCSI_PRIVATE
328:
329: #define XS_CMD_S_WDOG(xs) (xs)->flags |= XS_PSTS_INWDOG
330: #define XS_CMD_C_WDOG(xs) (xs)->flags &= ~XS_PSTS_INWDOG
331: #define XS_CMD_WDOG_P(xs) (((xs)->flags & XS_PSTS_INWDOG) != 0)
332:
333: #define XS_CMD_S_TIMER(xs) (xs)->flags |= XS_PSTS_TIMED
334: #define XS_CMD_C_TIMER(xs) (xs)->flags &= ~XS_PSTS_TIMED
335: #define XS_CMD_TIMER_P(xs) (((xs)->flags & XS_PSTS_TIMED) != 0)
336:
337: #define XS_CMD_S_GRACE(xs) (xs)->flags |= XS_PSTS_GRACE
338: #define XS_CMD_C_GRACE(xs) (xs)->flags &= ~XS_PSTS_GRACE
339: #define XS_CMD_GRACE_P(xs) (((xs)->flags & XS_PSTS_GRACE) != 0)
340:
341: #define XS_CMD_S_DONE(xs) (xs)->flags |= ITSDONE
342: #define XS_CMD_C_DONE(xs) (xs)->flags &= ~ITSDONE
343: #define XS_CMD_DONE_P(xs) (((xs)->flags & ITSDONE) != 0)
344:
345: #define XS_CMD_S_CLEAR(xs) (xs)->flags &= ~XS_PSTS_ALL
346:
347: /*
348: * Platform specific 'INLINE' or support functions
349: */
350: static INLINE void
351: isp_lock(struct ispsoftc *isp)
352: {
353: int s = splbio();
354: if (isp->isp_osinfo.islocked++ == 0) {
355: isp->isp_osinfo.splsaved = s;
356: } else {
357: splx(s);
358: }
359: }
360:
361: static INLINE void
362: isp_unlock(struct ispsoftc *isp)
363: {
364: if (isp->isp_osinfo.islocked-- <= 1) {
365: isp->isp_osinfo.islocked = 0;
366: splx(isp->isp_osinfo.splsaved);
367: }
368: }
369:
370: static INLINE u_int64_t
371: isp_nanotime_sub(struct timespec *b, struct timespec *a)
372: {
373: struct timespec x;
374: u_int64_t elapsed;
375: timespecsub(b, a, &x);
376: elapsed = GET_NANOSEC(&x);
377: if (elapsed == 0)
378: elapsed++;
379: return (elapsed);
380: }
381:
382: static INLINE void
383: isp_wait_complete(struct ispsoftc *isp)
384: {
385: int delaytime;
386: if (isp->isp_mbxwrk0)
387: delaytime = 60;
388: else
389: delaytime = 5;
390: if (MUST_POLL(isp)) {
391: int usecs = 0;
392: delaytime *= 1000000; /* convert to usecs */
393: while (usecs < delaytime) {
394: u_int16_t isr, sema, mbox;
395: if (isp->isp_mboxbsy == 0) {
396: break;
397: }
398: if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
399: isp_intr(isp, isr, sema, mbox);
400: if (isp->isp_mboxbsy == 0) {
401: break;
402: }
403: }
404: USEC_DELAY(500);
405: usecs += 500;
406: }
407: if (isp->isp_mboxbsy != 0) {
408: isp_prt(isp, ISP_LOGWARN,
409: "Polled Mailbox Command (0x%x) Timeout",
410: isp->isp_lastmbxcmd);
411: }
412: } else {
413: int rv = 0;
414: isp->isp_osinfo.mboxwaiting = 1;
415: while (isp->isp_osinfo.mboxwaiting && rv == 0) {
416: rv = tsleep(&isp->isp_osinfo.mboxwaiting,
417: PRIBIO, "isp_mboxcmd", delaytime * hz);
418: }
419: if (rv == EWOULDBLOCK) {
420: isp->isp_mboxbsy = 0;
421: isp->isp_osinfo.mboxwaiting = 0;
422: isp_prt(isp, ISP_LOGWARN,
423: "Interrupting Mailbox Command (0x%x) Timeout",
424: isp->isp_lastmbxcmd);
425: }
426: }
427: }
428:
429: /*
430: * Common INLINE functions
431: */
432: #include <dev/ic/isp_inline.h>
433:
434: #endif /* _ISP_NETBSD_H */
CVSweb