Annotation of sys/dev/ic/isp_target.h, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: isp_target.h,v 1.11 2002/08/17 17:42:04 mjacob Exp $ */
2:
3: /* @(#)isp_target.h 1.3 */
4: /*
5: * Qlogic Target Mode Structure and Flag Definitions
6: *
7: * Copyright (c) 1997, 1998
8: * Patrick Stirling
9: * pms@psconsult.com
10: * All rights reserved.
11: *
12: * Additional Copyright (c) 1999, 2000, 2001
13: * Matthew Jacob
14: * mjacob@feral.com
15: * All rights reserved.
16: *
17: *
18: * Redistribution and use in source and binary forms, with or without
19: * modification, are permitted provided that the following conditions
20: * are met:
21: * 1. Redistributions of source code must retain the above copyright
22: * notice immediately at the beginning of the file, without modification,
23: * this list of conditions, and the following disclaimer.
24: * 2. The name of the author may not be used to endorse or promote products
25: * derived from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
28: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
31: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: */
38: #ifndef _ISP_TARGET_H
39: #define _ISP_TARGET_H
40:
41: /*
42: * Defines for all entry types
43: */
44: #define QLTM_SVALID 0x80
45: #define QLTM_SENSELEN 18
46:
47: /*
48: * Structure for Enable Lun and Modify Lun queue entries
49: */
50: typedef struct {
51: isphdr_t le_header;
52: u_int32_t le_reserved;
53: u_int8_t le_lun;
54: u_int8_t le_rsvd;
55: u_int8_t le_ops; /* Modify LUN only */
56: u_int8_t le_tgt; /* Not for FC */
57: u_int32_t le_flags; /* Not for FC */
58: u_int8_t le_status;
59: u_int8_t le_reserved2;
60: u_int8_t le_cmd_count;
61: u_int8_t le_in_count;
62: u_int8_t le_cdb6len; /* Not for FC */
63: u_int8_t le_cdb7len; /* Not for FC */
64: u_int16_t le_timeout;
65: u_int16_t le_reserved3[20];
66: } lun_entry_t;
67:
68: /*
69: * le_flags values
70: */
71: #define LUN_TQAE 0x00000002 /* bit1 Tagged Queue Action Enable */
72: #define LUN_DSSM 0x01000000 /* bit24 Disable Sending SDP Message */
73: #define LUN_DISAD 0x02000000 /* bit25 Disable autodisconnect */
74: #define LUN_DM 0x40000000 /* bit30 Disconnects Mandatory */
75:
76: /*
77: * le_ops values
78: */
79: #define LUN_CCINCR 0x01 /* increment command count */
80: #define LUN_CCDECR 0x02 /* decrement command count */
81: #define LUN_ININCR 0x40 /* increment immed. notify count */
82: #define LUN_INDECR 0x80 /* decrement immed. notify count */
83:
84: /*
85: * le_status values
86: */
87: #define LUN_OK 0x01 /* we be rockin' */
88: #define LUN_ERR 0x04 /* request completed with error */
89: #define LUN_INVAL 0x06 /* invalid request */
90: #define LUN_NOCAP 0x16 /* can't provide requested capability */
91: #define LUN_ENABLED 0x3E /* LUN already enabled */
92:
93: /*
94: * Immediate Notify Entry structure
95: */
96: #define IN_MSGLEN 8 /* 8 bytes */
97: #define IN_RSVDLEN 8 /* 8 words */
98: typedef struct {
99: isphdr_t in_header;
100: u_int32_t in_reserved;
101: u_int8_t in_lun; /* lun */
102: u_int8_t in_iid; /* initiator */
103: u_int8_t in_reserved2;
104: u_int8_t in_tgt; /* target */
105: u_int32_t in_flags;
106: u_int8_t in_status;
107: u_int8_t in_rsvd2;
108: u_int8_t in_tag_val; /* tag value */
109: u_int8_t in_tag_type; /* tag type */
110: u_int16_t in_seqid; /* sequence id */
111: u_int8_t in_msg[IN_MSGLEN]; /* SCSI message bytes */
112: u_int16_t in_reserved3[IN_RSVDLEN];
113: u_int8_t in_sense[QLTM_SENSELEN];/* suggested sense data */
114: } in_entry_t;
115:
116: typedef struct {
117: isphdr_t in_header;
118: u_int32_t in_reserved;
119: u_int8_t in_lun; /* lun */
120: u_int8_t in_iid; /* initiator */
121: u_int16_t in_scclun;
122: u_int32_t in_reserved2;
123: u_int16_t in_status;
124: u_int16_t in_task_flags;
125: u_int16_t in_seqid; /* sequence id */
126: } in_fcentry_t;
127:
128: /*
129: * Values for the in_status field
130: */
131: #define IN_REJECT 0x0D /* Message Reject message received */
132: #define IN_RESET 0x0E /* Bus Reset occurred */
133: #define IN_NO_RCAP 0x16 /* requested capability not available */
134: #define IN_IDE_RECEIVED 0x33 /* Initiator Detected Error msg received */
135: #define IN_RSRC_UNAVAIL 0x34 /* resource unavailable */
136: #define IN_MSG_RECEIVED 0x36 /* SCSI message received */
137: #define IN_ABORT_TASK 0x20 /* task named in RX_ID is being aborted (FC) */
138: #define IN_PORT_LOGOUT 0x29 /* port has logged out (FC) */
139: #define IN_PORT_CHANGED 0x2A /* port changed */
140: #define IN_GLOBAL_LOGO 0x2E /* all ports logged out */
141: #define IN_NO_NEXUS 0x3B /* Nexus not established */
142:
143: /*
144: * Values for the in_task_flags field- should only get one at a time!
145: */
146: #define TASK_FLAGS_ABORT_TASK (1<<9)
147: #define TASK_FLAGS_CLEAR_TASK_SET (1<<10)
148: #define TASK_FLAGS_TARGET_RESET (1<<13)
149: #define TASK_FLAGS_CLEAR_ACA (1<<14)
150: #define TASK_FLAGS_TERMINATE_TASK (1<<15)
151:
152: #ifndef MSG_ABORT_TAG
153: #define MSG_ABORT_TAG 0x06
154: #endif
155: #ifndef MSG_CLEAR_QUEUE
156: #define MSG_CLEAR_QUEUE 0x0e
157: #endif
158: #ifndef MSG_BUS_DEV_RESET
159: #define MSG_BUS_DEV_RESET 0x0b
160: #endif
161: #ifndef MSG_REL_RECOVERY
162: #define MSG_REL_RECOVERY 0x10
163: #endif
164: #ifndef MSG_TERM_IO_PROC
165: #define MSG_TERM_IO_PROC 0x11
166: #endif
167:
168:
169: /*
170: * Notify Acknowledge Entry structure
171: */
172: #define NA_RSVDLEN 22
173: typedef struct {
174: isphdr_t na_header;
175: u_int32_t na_reserved;
176: u_int8_t na_lun; /* lun */
177: u_int8_t na_iid; /* initiator */
178: u_int8_t na_reserved2;
179: u_int8_t na_tgt; /* target */
180: u_int32_t na_flags;
181: u_int8_t na_status;
182: u_int8_t na_event;
183: u_int16_t na_seqid; /* sequence id */
184: u_int16_t na_reserved3[NA_RSVDLEN];
185: } na_entry_t;
186:
187: /*
188: * Value for the na_event field
189: */
190: #define NA_RST_CLRD 0x80 /* Clear an async event notification */
191: #define NA_OK 0x01 /* Notify Acknowledge Succeeded */
192: #define NA_INVALID 0x06 /* Invalid Notify Acknowledge */
193:
194: #define NA2_RSVDLEN 21
195: typedef struct {
196: isphdr_t na_header;
197: u_int32_t na_reserved;
198: u_int8_t na_lun; /* lun */
199: u_int8_t na_iid; /* initiator */
200: u_int16_t na_scclun;
201: u_int16_t na_flags;
202: u_int16_t na_reserved2;
203: u_int16_t na_status;
204: u_int16_t na_task_flags;
205: u_int16_t na_seqid; /* sequence id */
206: u_int16_t na_reserved3[NA2_RSVDLEN];
207: } na_fcentry_t;
208: #define NAFC_RCOUNT 0x80 /* increment resource count */
209: #define NAFC_RST_CLRD 0x20 /* Clear LIP Reset */
210: /*
211: * Accept Target I/O Entry structure
212: */
213: #define ATIO_CDBLEN 26
214:
215: typedef struct {
216: isphdr_t at_header;
217: u_int16_t at_reserved;
218: u_int16_t at_handle;
219: u_int8_t at_lun; /* lun */
220: u_int8_t at_iid; /* initiator */
221: u_int8_t at_cdblen; /* cdb length */
222: u_int8_t at_tgt; /* target */
223: u_int32_t at_flags;
224: u_int8_t at_status; /* firmware status */
225: u_int8_t at_scsi_status; /* scsi status */
226: u_int8_t at_tag_val; /* tag value */
227: u_int8_t at_tag_type; /* tag type */
228: u_int8_t at_cdb[ATIO_CDBLEN]; /* received CDB */
229: u_int8_t at_sense[QLTM_SENSELEN];/* suggested sense data */
230: } at_entry_t;
231:
232: /*
233: * at_flags values
234: */
235: #define AT_NODISC 0x00008000 /* disconnect disabled */
236: #define AT_TQAE 0x00000002 /* Tagged Queue Action enabled */
237:
238: /*
239: * at_status values
240: */
241: #define AT_PATH_INVALID 0x07 /* ATIO sent to firmware for disabled lun */
242: #define AT_RESET 0x0E /* SCSI Bus Reset Occurred */
243: #define AT_PHASE_ERROR 0x14 /* Bus phase sequence error */
244: #define AT_NOCAP 0x16 /* Requested capability not available */
245: #define AT_BDR_MSG 0x17 /* Bus Device Reset msg received */
246: #define AT_CDB 0x3D /* CDB received */
247:
248: /*
249: * Macros to create and fetch and test concatenated handle and tag value macros
250: */
251:
252: #define AT_MAKE_TAGID(tid, aep) \
253: tid = ((aep)->at_handle << 16); \
254: if ((aep)->at_flags & AT_TQAE) \
255: (tid) |= ((aep)->at_tag_val + 1)
256:
257: #define CT_MAKE_TAGID(tid, ct) \
258: tid = ((ct)->ct_fwhandle << 16); \
259: if ((ct)->ct_flags & CT_TQAE) \
260: (tid) |= ((ct)->ct_tag_val + 1)
261:
262: #define AT_HAS_TAG(val) ((val) & 0xffff)
263: #define AT_GET_TAG(val) AT_HAS_TAG(val) - 1
264: #define AT_GET_HANDLE(val) ((val) >> 16)
265:
266: /*
267: * Accept Target I/O Entry structure, Type 2
268: */
269: #define ATIO2_CDBLEN 16
270:
271: typedef struct {
272: isphdr_t at_header;
273: u_int32_t at_reserved;
274: u_int8_t at_lun; /* lun or reserved */
275: u_int8_t at_iid; /* initiator */
276: u_int16_t at_rxid; /* response ID */
277: u_int16_t at_flags;
278: u_int16_t at_status; /* firmware status */
279: u_int8_t at_reserved1;
280: u_int8_t at_taskcodes;
281: u_int8_t at_taskflags;
282: u_int8_t at_execodes;
283: u_int8_t at_cdb[ATIO2_CDBLEN]; /* received CDB */
284: u_int32_t at_datalen; /* allocated data len */
285: u_int16_t at_scclun; /* SCC Lun or reserved */
286: u_int16_t at_wwpn[4]; /* WWPN of initiator */
287: u_int16_t at_reserved2[6];
288: u_int16_t at_oxid;
289: } at2_entry_t;
290:
291: #define ATIO2_WWPN_OFFSET 0x2A
292: #define ATIO2_OXID_OFFSET 0x3E
293:
294: #define ATIO2_TC_ATTR_MASK 0x7
295: #define ATIO2_TC_ATTR_SIMPLEQ 0
296: #define ATIO2_TC_ATTR_HEADOFQ 1
297: #define ATIO2_TC_ATTR_ORDERED 2
298: #define ATIO2_TC_ATTR_ACAQ 4
299: #define ATIO2_TC_ATTR_UNTAGGED 5
300:
301: /*
302: * Continue Target I/O Entry structure
303: * Request from driver. The response from the
304: * ISP firmware is the same except that the last 18
305: * bytes are overwritten by suggested sense data if
306: * the 'autosense valid' bit is set in the status byte.
307: */
308: typedef struct {
309: isphdr_t ct_header;
310: u_int16_t ct_reserved;
311: #define ct_syshandle ct_reserved /* we use this */
312: u_int16_t ct_fwhandle; /* required by f/w */
313: u_int8_t ct_lun; /* lun */
314: u_int8_t ct_iid; /* initiator id */
315: u_int8_t ct_reserved2;
316: u_int8_t ct_tgt; /* our target id */
317: u_int32_t ct_flags;
318: u_int8_t ct_status; /* isp status */
319: u_int8_t ct_scsi_status; /* scsi status */
320: u_int8_t ct_tag_val; /* tag value */
321: u_int8_t ct_tag_type; /* tag type */
322: u_int32_t ct_xfrlen; /* transfer length */
323: u_int32_t ct_resid; /* residual length */
324: u_int16_t ct_timeout;
325: u_int16_t ct_seg_count;
326: /*
327: * This is so we can share tag name space with
328: * CTIO{2,3,4} with the minimum of pain.
329: */
330: union {
331: ispds_t ct_a[ISP_RQDSEG];
332: } _u;
333: #define ct_dataseg _u.ct_a
334: } ct_entry_t;
335:
336: /*
337: * For some of the dual port SCSI adapters, port (bus #) is reported
338: * in the MSbit of ct_iid. Bit fields are a bit too awkward here.
339: *
340: * Note that this does not apply to FC adapters at all which can and
341: * do report IIDs between 129 && 255 (these represent devices that have
342: * logged in across a SCSI fabric).
343: */
344: #define GET_IID_VAL(x) (x & 0x3f)
345: #define GET_BUS_VAL(x) ((x >> 7) & 0x1)
346: #define SET_IID_VAL(y, x) y = ((y & ~0x3f) | (x & 0x3f))
347: #define SET_BUS_VAL(y, x) y = ((y & 0x3f) | ((x & 0x1) << 7))
348:
349: /*
350: * ct_flags values
351: */
352: #define CT_TQAE 0x00000002 /* bit 1, Tagged Queue Action enable */
353: #define CT_DATA_IN 0x00000040 /* bits 6&7, Data direction */
354: #define CT_DATA_OUT 0x00000080 /* bits 6&7, Data direction */
355: #define CT_NO_DATA 0x000000C0 /* bits 6&7, Data direction */
356: #define CT_CCINCR 0x00000100 /* bit 8, autoincrement atio count */
357: #define CT_DATAMASK 0x000000C0 /* bits 6&7, Data direction */
358: #define CT_INISYNCWIDE 0x00004000 /* bit 14, Do Sync/Wide Negotiation */
359: #define CT_NODISC 0x00008000 /* bit 15, Disconnects disabled */
360: #define CT_DSDP 0x01000000 /* bit 24, Disable Save Data Pointers */
361: #define CT_SENDRDP 0x04000000 /* bit 26, Send Restore Pointers msg */
362: #define CT_SENDSTATUS 0x80000000 /* bit 31, Send SCSI status byte */
363:
364: /*
365: * ct_status values
366: * - set by the firmware when it returns the CTIO
367: */
368: #define CT_OK 0x01 /* completed without error */
369: #define CT_ABORTED 0x02 /* aborted by host */
370: #define CT_ERR 0x04 /* see sense data for error */
371: #define CT_INVAL 0x06 /* request for disabled lun */
372: #define CT_NOPATH 0x07 /* invalid ITL nexus */
373: #define CT_INVRXID 0x08 /* (FC only) Invalid RX_ID */
374: #define CT_DATA_OVER 0x09 /* (FC only) Data Overrun */
375: #define CT_RSELTMO 0x0A /* reselection timeout after 2 tries */
376: #define CT_TIMEOUT 0x0B /* timed out */
377: #define CT_RESET 0x0E /* SCSI Bus Reset occurred */
378: #define CT_PARITY 0x0F /* Uncorrectable Parity Error */
379: #define CT_BUS_ERROR 0x10 /* (FC Only) DMA PCI Error */
380: #define CT_PANIC 0x13 /* Unrecoverable Error */
381: #define CT_PHASE_ERROR 0x14 /* Bus phase sequence error */
382: #define CT_BDR_MSG 0x17 /* Bus Device Reset msg received */
383: #define CT_DATA_UNDER 0x15 /* (FC only) Data Underrun */
384: #define CT_TERMINATED 0x19 /* due to Terminate Transfer mbox cmd */
385: #define CT_PORTNOTAVAIL 0x28 /* port not available */
386: #define CT_LOGOUT 0x29 /* port logout */
387: #define CT_PORTCHANGED 0x2A /* port changed */
388: #define CT_IDE 0x33 /* Initiator Detected Error */
389: #define CT_NOACK 0x35 /* Outstanding Immed. Notify. entry */
390:
391: /*
392: * When the firmware returns a CTIO entry, it may overwrite the last
393: * part of the structure with sense data. This starts at offset 0x2E
394: * into the entry, which is in the middle of ct_dataseg[1]. Rather
395: * than define a new struct for this, I'm just using the sense data
396: * offset.
397: */
398: #define CTIO_SENSE_OFFSET 0x2E
399:
400: /*
401: * Entry length in u_longs. All entries are the same size so
402: * any one will do as the numerator.
403: */
404: #define UINT32_ENTRY_SIZE (sizeof(at_entry_t)/sizeof(u_int32_t))
405:
406: /*
407: * QLA2100 CTIO (type 2) entry
408: */
409: #define MAXRESPLEN 26
410: typedef struct {
411: isphdr_t ct_header;
412: u_int16_t ct_reserved;
413: u_int16_t ct_fwhandle; /* just to match CTIO */
414: u_int8_t ct_lun; /* lun */
415: u_int8_t ct_iid; /* initiator id */
416: u_int16_t ct_rxid; /* response ID */
417: u_int16_t ct_flags;
418: u_int16_t ct_status; /* isp status */
419: u_int16_t ct_timeout;
420: u_int16_t ct_seg_count;
421: u_int32_t ct_reloff; /* relative offset */
422: int32_t ct_resid; /* residual length */
423: union {
424: /*
425: * The three different modes that the target driver
426: * can set the CTIO{2,3,4} up as.
427: *
428: * The first is for sending FCP_DATA_IUs as well as
429: * (optionally) sending a terminal SCSI status FCP_RSP_IU.
430: *
431: * The second is for sending SCSI sense data in an FCP_RSP_IU.
432: * Note that no FCP_DATA_IUs will be sent.
433: *
434: * The third is for sending FCP_RSP_IUs as built specifically
435: * in system memory as located by the isp_dataseg.
436: */
437: struct {
438: u_int32_t _reserved;
439: u_int16_t _reserved2;
440: u_int16_t ct_scsi_status;
441: u_int32_t ct_xfrlen;
442: union {
443: ispds_t ct_a[ISP_RQDSEG_T2]; /* CTIO2 */
444: ispds64_t ct_b[ISP_RQDSEG_T3]; /* CTIO3 */
445: ispdslist_t ct_c; /* CTIO4 */
446: } _u;
447: #define ct_dataseg _u.ct_a
448: #define ct_dataseg64 _u.ct_b
449: #define ct_dslist _u.ct_c
450: } m0;
451: struct {
452: u_int16_t _reserved;
453: u_int16_t _reserved2;
454: u_int16_t ct_senselen;
455: u_int16_t ct_scsi_status;
456: u_int16_t ct_resplen;
457: u_int8_t ct_resp[MAXRESPLEN];
458: } m1;
459: struct {
460: u_int32_t _reserved;
461: u_int16_t _reserved2;
462: u_int16_t _reserved3;
463: u_int32_t ct_datalen;
464: ispds_t ct_fcp_rsp_iudata;
465: } m2;
466: /*
467: * CTIO2 returned from F/W...
468: */
469: struct {
470: u_int32_t _reserved[4];
471: u_int16_t ct_scsi_status;
472: u_int8_t ct_sense[QLTM_SENSELEN];
473: } fw;
474: } rsp;
475: } ct2_entry_t;
476:
477: /*
478: * ct_flags values for CTIO2
479: */
480: #define CT2_FLAG_MMASK 0x0003
481: #define CT2_FLAG_MODE0 0x0000
482: #define CT2_FLAG_MODE1 0x0001
483: #define CT2_FLAG_MODE2 0x0002
484: #define CT2_DATA_IN CT_DATA_IN
485: #define CT2_DATA_OUT CT_DATA_OUT
486: #define CT2_NO_DATA CT_NO_DATA
487: #define CT2_DATAMASK CT_DATAMASK
488: #define CT2_CCINCR 0x0100
489: #define CT2_FASTPOST 0x0200
490: #define CT2_SENDSTATUS 0x8000
491:
492: /*
493: * ct_status values are (mostly) the same as that for ct_entry.
494: */
495:
496: /*
497: * ct_scsi_status values- the low 8 bits are the normal SCSI status
498: * we know and love. The upper 8 bits are validity markers for FCP_RSP_IU
499: * fields.
500: */
501: #define CT2_RSPLEN_VALID 0x0100
502: #define CT2_SNSLEN_VALID 0x0200
503: #define CT2_DATA_OVER 0x0400
504: #define CT2_DATA_UNDER 0x0800
505:
506: /*
507: * Debug macros
508: */
509:
510: #define ISP_TDQE(isp, msg, idx, arg) \
511: if (isp->isp_dblev & ISP_LOGTDEBUG2) isp_print_qentry(isp, msg, idx, arg)
512:
513: #ifdef ISP_TARGET_FUNCTIONS
514: /*
515: * The functions below are for the publicly available
516: * target mode functions that are internal to the Qlogic driver.
517: */
518:
519: /*
520: * This function handles new response queue entry appropriate for target mode.
521: */
522: int isp_target_notify(struct ispsoftc *, void *, u_int16_t *);
523:
524: /*
525: * Enable/Disable/Modify a logical unit.
526: * (softc, cmd, bus, tgt, lun, cmd_cnt, inotify_cnt, opaque)
527: */
528: #define DFLT_CMND_CNT 0xfe /* unmonitored */
529: #define DFLT_INOT_CNT 16
530: int isp_lun_cmd(struct ispsoftc *, int, int, int, int, int, int, u_int32_t);
531:
532: /*
533: * General request queue 'put' routine for target mode entries.
534: */
535: int isp_target_put_entry(struct ispsoftc *isp, void *);
536:
537: /*
538: * General routine to put back an ATIO entry-
539: * used for replenishing f/w resource counts.
540: * The argument is a pointer to a source ATIO
541: * or ATIO2.
542: */
543: int isp_target_put_atio(struct ispsoftc *, void *);
544:
545: /*
546: * General routine to send a final CTIO for a command- used mostly for
547: * local responses.
548: */
549: int isp_endcmd(struct ispsoftc *, void *, u_int32_t, u_int16_t);
550: #define ECMD_SVALID 0x100
551:
552: /*
553: * Handle an asynchronous event
554: *
555: * Return nonzero if the interrupt that generated this event has been dismissed.
556: */
557:
558: int isp_target_async(struct ispsoftc *, int, int);
559: #endif
560: #endif /* _ISP_TARGET_H */
CVSweb