]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cam/scsi/scsi_low.h
Merge llvm trunk r338150, and resolve conflicts.
[FreeBSD/FreeBSD.git] / sys / cam / scsi / scsi_low.h
1 /*      $FreeBSD$       */
2 /*      $NecBSD: scsi_low.h,v 1.24.10.5 2001/06/26 07:31:46 honda Exp $ */
3 /*      $NetBSD$        */
4
5 #define SCSI_LOW_DIAGNOSTIC
6 #define SCSI_LOW_ALT_QTAG_ALLOCATE
7
8 /*-
9  * SPDX-License-Identifier: BSD-3-Clause
10  *
11  * [NetBSD for NEC PC-98 series]
12  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
13  *      NetBSD/pc98 porting staff. All rights reserved.
14  *  Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
15  *      Naofumi HONDA. All rights reserved.
16  *
17  * [Ported for FreeBSD CAM]
18  *  Copyright (c) 2000, 2001
19  *      MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
20  *      All rights reserved.
21  * 
22  *  Redistribution and use in source and binary forms, with or without
23  *  modification, are permitted provided that the following conditions
24  *  are met:
25  *  1. Redistributions of source code must retain the above copyright
26  *     notice, this list of conditions and the following disclaimer.
27  *  2. Redistributions in binary form must reproduce the above copyright
28  *     notice, this list of conditions and the following disclaimer in the
29  *     documentation and/or other materials provided with the distribution.
30  *  3. The name of the author may not be used to endorse or promote products
31  *     derived from this software without specific prior written permission.
32  * 
33  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
34  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
37  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
42  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43  * POSSIBILITY OF SUCH DAMAGE.
44  */
45
46 #ifndef _SCSI_LOW_H_
47 #define _SCSI_LOW_H_
48
49 /******** includes *******************************/
50
51 #include <sys/bus.h>
52 #include <sys/kdb.h>
53 #include <cam/cam.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/cam_sim.h>
56 #include <cam/cam_xpt_sim.h>
57 #include <cam/cam_debug.h>
58
59 #include <cam/scsi/scsi_dvcfg.h>
60 /************ ccbque.h ***************************/
61
62 /*      $NetBSD$        */
63 /*-
64  * SPDX-License-Identifier: BSD-3-Clause
65  *
66  * [NetBSD for NEC PC98 series]
67  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
68  *  All rights reserved.
69  *
70  *  Redistribution and use in source and binary forms, with or without
71  *  modification, are permitted provided that the following conditions
72  *  are met:
73  *  1. Redistributions of source code must retain the above copyright
74  *     notice, this list of conditions and the following disclaimer.
75  *  2. Redistributions in binary form must reproduce the above copyright
76  *     notice, this list of conditions and the following disclaimer in the
77  *     documentation and/or other materials provided with the distribution.
78  *  3. The name of the author may not be used to endorse or promote products
79  *     derived from this software without specific prior written permission.
80  *
81  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
82  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
83  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
84  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
85  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
86  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
87  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
88  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
89  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
90  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
91  * POSSIBILITY OF SUCH DAMAGE.
92  *
93  * $FreeBSD$
94  */
95 /*
96  * Common command control queue funcs.
97  * Written by N. Honda.
98  */
99
100 #define CCB_MWANTED 0x01
101
102 /* (I)  structure and prototype */
103 #define GENERIC_CCB_ASSERT(DEV, CCBTYPE)                                \
104 TAILQ_HEAD(CCBTYPE##tab, CCBTYPE);                                      \
105 struct CCBTYPE##que {                                                   \
106         struct CCBTYPE##tab CCBTYPE##tab;                               \
107         int count;                                                      \
108         int maxccb;                                                     \
109         u_int flags;                                                    \
110 };                                                                      \
111                                                                         \
112 void DEV##_init_ccbque(int);                                            \
113 struct CCBTYPE *DEV##_get_ccb(void);                                    \
114 void DEV##_free_ccb(struct CCBTYPE *);
115
116 /******** functions macro ************************/
117
118 #undef  MSG_IDENTIFY
119
120 /*================================================
121  * Generic Scsi Low header file 
122  ================================================*/
123 /*************************************************
124  * Scsi low definitions
125  *************************************************/
126 #define SCSI_LOW_SYNC           DVF_SCSI_SYNC
127 #define SCSI_LOW_DISC           DVF_SCSI_DISC
128 #define SCSI_LOW_WAIT           DVF_SCSI_WAIT
129 #define SCSI_LOW_LINK           DVF_SCSI_LINK
130 #define SCSI_LOW_QTAG           DVF_SCSI_QTAG
131 #define SCSI_LOW_NOPARITY       DVF_SCSI_NOPARITY
132 #define SCSI_LOW_SAVESP         DVF_SCSI_SAVESP
133 #define SCSI_LOW_DEFCFG         DVF_SCSI_DEFCFG
134 #define SCSI_LOW_BITS           DVF_SCSI_BITS
135
136 #define SCSI_LOW_PERIOD(n)      DVF_SCSI_PERIOD(n)
137 #define SCSI_LOW_OFFSET(n)      DVF_SCSI_OFFSET(n)
138
139 /* host scsi id and targets macro */
140 #ifndef SCSI_LOW_NTARGETS
141 #define SCSI_LOW_NTARGETS                       8
142 #endif  /* SCSI_LOW_NTARGETS */
143 #define SCSI_LOW_NCCB                           128
144
145 #define SCSI_LOW_MAX_RETRY                      3
146 #define SCSI_LOW_MAX_SELECTION_RETRY            10
147
148 /* timeout control macro */
149 #define SCSI_LOW_TIMEOUT_HZ                     10
150 #define SCSI_LOW_MIN_TOUT                       12
151 #define SCSI_LOW_TIMEOUT_CHECK_INTERVAL         1
152 #define SCSI_LOW_POWDOWN_TC                     15
153 #define SCSI_LOW_MAX_PHCHANGES                  256
154 #define SCSI2_RESET_DELAY                       5000000
155
156 /* msg */
157 #define SCSI_LOW_MAX_MSGLEN                     32
158 #define SCSI_LOW_MSG_LOG_DATALEN                8
159
160 /*************************************************
161  * Scsi Data Pointer
162  *************************************************/
163 /* scsi pointer */
164 struct sc_p {
165         u_int8_t *scp_data;
166         int scp_datalen;
167
168         u_int8_t *scp_cmd;
169         int scp_cmdlen;
170
171         u_int8_t scp_direction;
172 #define SCSI_LOW_RWUNK  (-1)
173 #define SCSI_LOW_WRITE  0
174 #define SCSI_LOW_READ   1
175         u_int8_t scp_status;
176         u_int8_t scp_spare[2];
177 };
178
179 /*************************************************
180  * Command Control Block Structure
181  *************************************************/
182 typedef int scsi_low_tag_t;                     
183 struct targ_info;
184
185 #define SCSI_LOW_UNKLUN ((u_int) -1)
186 #define SCSI_LOW_UNKTAG ((scsi_low_tag_t) -1)
187
188 struct slccb {
189         TAILQ_ENTRY(slccb) ccb_chain;
190
191         void *osdep;                    /* os depend structure */
192
193         struct targ_info *ti;           /* targ_info */
194         struct lun_info *li;            /* lun info */
195         struct buf *bp;                 /* io bufs */
196
197         scsi_low_tag_t ccb_tag;         /* effective qtag */
198         scsi_low_tag_t ccb_otag;        /* allocated qtag */
199
200         /*****************************************
201          * Scsi data pointers (original and saved)
202          *****************************************/
203         struct sc_p ccb_scp;            /* given */
204         struct sc_p ccb_sscp;           /* saved scsi data pointer */
205         int ccb_datalen;                /* transferred data counter */
206
207         /*****************************************
208          * Msgout 
209          *****************************************/
210         u_int ccb_msgoutflag;
211         u_int ccb_omsgoutflag;
212
213         /*****************************************
214          * Error or Timeout counters
215          *****************************************/
216         u_int ccb_flags;
217 #define CCB_INTERNAL    0x0001
218 #define CCB_SENSE       0x0002
219 #define CCB_CLEARQ      0x0004
220 #define CCB_DISCQ       0x0008
221 #define CCB_STARTQ      0x0010
222 #define CCB_POLLED      0x0100  /* polling ccb */
223 #define CCB_NORETRY     0x0200  /* do NOT retry */
224 #define CCB_AUTOSENSE   0x0400  /* do a sense after CA */
225 #define CCB_URGENT      0x0800  /* an urgent ccb */
226 #define CCB_NOSDONE     0x1000  /* do not call an os done routine */
227 #define CCB_SCSIIO      0x2000  /* a normal scsi io coming from upper layer */
228 #define CCB_SILENT      0x4000  /* no terminate messages */
229
230         u_int ccb_error;
231
232         int ccb_rcnt;                   /* retry counter */
233         int ccb_selrcnt;                /* selection retry counter */
234         int ccb_tc;                     /* timer counter */
235         int ccb_tcmax;                  /* max timeout */
236
237         /*****************************************
238          * Sense data buffer
239          *****************************************/
240         u_int8_t ccb_scsi_cmd[12];
241         struct scsi_sense_data ccb_sense;
242 };
243
244 /*************************************************
245  * Slccb functions
246  *************************************************/
247 GENERIC_CCB_ASSERT(scsi_low, slccb)
248
249 /*************************************************
250  * Target and Lun structures
251  *************************************************/
252 struct scsi_low_softc;
253 LIST_HEAD(scsi_low_softc_tab, scsi_low_softc);
254 TAILQ_HEAD(targ_info_tab, targ_info);
255 LIST_HEAD(lun_info_tab, lun_info);
256
257 struct lun_info {
258         int li_lun;
259         struct targ_info *li_ti;                /* my target */
260
261         LIST_ENTRY(lun_info) lun_chain;         /* targ_info link */
262
263         struct slccbtab li_discq;                       /* disconnect queue */
264
265         /*
266          * qtag control
267          */
268         int li_maxnexus;
269         int li_maxnqio; 
270         int li_nqio;
271         int li_disc;
272
273 #define SCSI_LOW_MAXNEXUS (sizeof(u_int) * NBBY)
274         u_int li_qtagbits;
275
276 #ifdef  SCSI_LOW_ALT_QTAG_ALLOCATE
277         u_int8_t li_qtagarray[SCSI_LOW_MAXNEXUS];
278         u_int li_qd;
279 #endif  /* SCSI_LOW_ALT_QTAG_ALLOCATE */
280
281 #define SCSI_LOW_QFLAG_CA_QCLEAR        0x01
282         u_int li_qflags;
283
284         /*
285          * lun state
286          */
287 #define SCSI_LOW_LUN_SLEEP      0x00
288 #define SCSI_LOW_LUN_START      0x01
289 #define SCSI_LOW_LUN_INQ        0x02
290 #define SCSI_LOW_LUN_MODEQ      0x03
291 #define SCSI_LOW_LUN_OK         0x04
292         u_int li_state;                         /* target lun state */
293
294         /*
295          * lun control flags
296          */
297         u_int li_flags_valid;   /* valid flags */
298 #define SCSI_LOW_LUN_FLAGS_USER_VALID   0x0001
299 #define SCSI_LOW_LUN_FLAGS_DISK_VALID   0x0002
300 #define SCSI_LOW_LUN_FLAGS_QUIRKS_VALID 0x0004
301 #define SCSI_LOW_LUN_FLAGS_ALL_VALID \
302         (SCSI_LOW_LUN_FLAGS_USER_VALID | \
303          SCSI_LOW_LUN_FLAGS_DISK_VALID | SCSI_LOW_LUN_FLAGS_QUIRKS_VALID)
304
305         u_int li_flags;         /* real lun control flags */
306         u_int li_cfgflags;      /* lun control flags given by user */
307         u_int li_diskflags;     /* lun control flags given by hardware info */
308         u_int li_quirks;        /* lun control flags given by upper layer */
309
310         /* inq buffer */
311         struct scsi_low_inq_data {
312                 u_int8_t sd_type;       
313                 u_int8_t sd_sp1;
314                 u_int8_t sd_version;
315                 u_int8_t sd_resp;
316                 u_int8_t sd_len;
317                 u_int8_t sd_sp2[2];
318                 u_int8_t sd_support;
319         } __packed li_inq;
320
321         /* modeq buffer */
322         struct scsi_low_mode_sense_data {
323                 u_int8_t sms_header[4];
324                 struct {
325                         u_int8_t cmp_page;
326                         u_int8_t cmp_length;
327                         u_int8_t cmp_rlec;
328                         u_int8_t cmp_qc;
329                         u_int8_t cmp_eca;
330                         u_int8_t cmp_spare[3];
331                 } __packed sms_cmp;     
332         
333         } li_sms;       
334 };
335
336 struct scsi_low_msg_log {
337         int slml_ptr;
338         struct {
339                 u_int8_t msg[2];
340         } slml_msg[SCSI_LOW_MSG_LOG_DATALEN];
341 };
342
343 struct targ_info {
344         TAILQ_ENTRY(targ_info) ti_chain;        /* targ_info link */
345
346         struct scsi_low_softc *ti_sc;           /* our softc */
347         u_int ti_id;                            /* scsi id */
348
349         /*
350          * Lun chain
351          */
352         struct lun_info_tab ti_litab;           /* lun chain */
353
354         /*
355          * total disconnected nexus
356          */
357         int ti_disc;
358
359         /*
360          * Scsi phase control
361          */
362
363 #define PH_NULL         0x00
364 #define PH_ARBSTART     0x01
365 #define PH_SELSTART     0x02
366 #define PH_SELECTED     0x03
367 #define PH_CMD          0x04
368 #define PH_DATA         0x05
369 #define PH_MSGIN        0x06
370 #define PH_MSGOUT       0x07
371 #define PH_STAT         0x08
372 #define PH_DISC         0x09
373 #define PH_RESEL        0x0a
374         u_int ti_phase;                         /* scsi phase */
375         u_int ti_ophase;                        /* old scsi phase */
376
377         /*
378          * Msg in
379          */
380         u_int ti_msginptr;                      /* msgin ptr */
381         u_int ti_msginlen;                      /* expected msg length */
382         int ti_msgin_parity_error;              /* parity error detected */
383         u_int8_t ti_msgin[SCSI_LOW_MAX_MSGLEN]; /* msgin buffer */
384
385         /*
386          * Msg out
387          */
388         u_int ti_msgflags;                      /* msgs to be asserted */
389         u_int ti_omsgflags;                     /* msgs asserted */
390         u_int ti_emsgflags;                     /* a msg currently asserted */
391 #define SCSI_LOW_MSG_RESET      0x00000001
392 #define SCSI_LOW_MSG_REJECT     0x00000002
393 #define SCSI_LOW_MSG_PARITY     0x00000004
394 #define SCSI_LOW_MSG_ERROR      0x00000008
395 #define SCSI_LOW_MSG_IDENTIFY   0x00000010
396 #define SCSI_LOW_MSG_ABORT      0x00000020
397 #define SCSI_LOW_MSG_TERMIO     0x00000040
398 #define SCSI_LOW_MSG_SIMPLE_QTAG        0x00000080
399 #define SCSI_LOW_MSG_ORDERED_QTAG       0x00000100
400 #define SCSI_LOW_MSG_HEAD_QTAG          0x00000200
401 #define SCSI_LOW_MSG_ABORT_QTAG 0x00000400
402 #define SCSI_LOW_MSG_CLEAR_QTAG 0x00000800
403 #define SCSI_LOW_MSG_WIDE       0x00001000
404 #define SCSI_LOW_MSG_SYNCH      0x00002000
405 #define SCSI_LOW_MSG_NOOP       0x00004000
406 #define SCSI_LOW_MSG_LAST       0x00008000
407 #define SCSI_LOW_MSG_ALL        0xffffffff
408
409         /* msgout buffer */
410         u_int8_t ti_msgoutstr[SCSI_LOW_MAX_MSGLEN];     /* scsi msgout */
411         u_int ti_msgoutlen;                     /* msgout strlen */
412
413         /*
414          * target initialize msgout 
415          */
416         u_int ti_setup_msg;             /* setup msgout requests */
417         u_int ti_setup_msg_done;
418
419         /*
420          * synch and wide data info
421          */
422         u_int ti_flags_valid;   /* valid flags */
423 #define SCSI_LOW_TARG_FLAGS_USER_VALID          0x0001
424 #define SCSI_LOW_TARG_FLAGS_DISK_VALID          0x0002
425 #define SCSI_LOW_TARG_FLAGS_QUIRKS_VALID        0x0004
426 #define SCSI_LOW_TARG_FLAGS_ALL_VALID \
427         (SCSI_LOW_TARG_FLAGS_USER_VALID | \
428          SCSI_LOW_TARG_FLAGS_DISK_VALID | SCSI_LOW_TARG_FLAGS_QUIRKS_VALID)
429
430         u_int ti_diskflags;     /* given target disk flags */
431         u_int ti_quirks;        /* given target quirk */
432
433         struct synch {
434                 u_int8_t offset;
435                 u_int8_t period;
436         } ti_osynch, ti_maxsynch;               /* synch data */
437
438 #define SCSI_LOW_BUS_WIDTH_8    0
439 #define SCSI_LOW_BUS_WIDTH_16   1
440 #define SCSI_LOW_BUS_WIDTH_32   2
441         u_int ti_owidth, ti_width;
442
443         /*
444          * lun info size.
445          */
446         int ti_lunsize; 
447
448 #ifdef  SCSI_LOW_DIAGNOSTIC
449         struct scsi_low_msg_log ti_log_msgout;
450         struct scsi_low_msg_log ti_log_msgin;
451 #endif  /* SCSI_LOW_DIAGNOSTIC */
452 };
453
454 /*************************************************
455  * COMMON HEADER STRUCTURE
456  *************************************************/
457 struct scsi_low_softc;
458 struct proc;
459 typedef struct scsi_low_softc *sc_low_t;
460
461 #define SCSI_LOW_START_OK       0
462 #define SCSI_LOW_START_FAIL     1
463 #define SCSI_LOW_INFO_ALLOC     0
464 #define SCSI_LOW_INFO_REVOKE    1
465 #define SCSI_LOW_INFO_DEALLOC   2
466 #define SCSI_LOW_POWDOWN        1
467 #define SCSI_LOW_ENGAGE         2
468
469 #define SC_LOW_INIT_T (int (*)(sc_low_t, int))
470 #define SC_LOW_BUSRST_T (void (*)(sc_low_t))
471 #define SC_LOW_TARG_INIT_T (int (*)(sc_low_t, struct targ_info *, int))
472 #define SC_LOW_LUN_INIT_T (int (*)(sc_low_t, struct targ_info *, struct lun_info *, int))
473 #define SC_LOW_SELECT_T (int (*)(sc_low_t, struct slccb *))
474 #define SC_LOW_ATTEN_T (void (*)(sc_low_t))
475 #define SC_LOW_NEXUS_T (int (*)(sc_low_t))
476 #define SC_LOW_MSG_T (int (*)(sc_low_t, struct targ_info *, u_int))
477 #define SC_LOW_POLL_T (int (*)(void *))
478 #define SC_LOW_POWER_T (int (*)(sc_low_t, u_int))
479 #define SC_LOW_TIMEOUT_T (int (*)(sc_low_t))
480
481 struct scsi_low_funcs {
482         int (*scsi_low_init)(sc_low_t, int);
483         void (*scsi_low_bus_reset)(sc_low_t);
484         int (*scsi_low_targ_init)(sc_low_t, struct targ_info *, int);
485         int (*scsi_low_lun_init)(sc_low_t, struct targ_info *, struct lun_info *, int);
486         int (*scsi_low_start_bus)(sc_low_t, struct slccb *);
487         int (*scsi_low_establish_lun_nexus)(sc_low_t);
488         int (*scsi_low_establish_ccb_nexus)(sc_low_t);
489         void (*scsi_low_attention)(sc_low_t);
490         int (*scsi_low_msg)(sc_low_t, struct targ_info *, u_int);
491         int (*scsi_low_timeout)(sc_low_t);
492         int (*scsi_low_poll)(void *);
493         int (*scsi_low_power)(sc_low_t, u_int);
494         int (*scsi_low_ioctl)(sc_low_t, u_long, caddr_t, int, struct proc *);
495 };
496
497 struct scsi_low_softc {
498         device_t sl_dev;
499
500         struct cam_sim *sl_sim;
501         struct cam_path *sl_path;
502
503         int sl_poll_count;
504
505         struct mtx sl_lock;
506         struct callout sl_engage_timer;
507         struct callout sl_timeout_timer;
508 #ifdef  SCSI_LOW_POWFUNC
509         struct callout sl_recover_timer;
510 #endif
511                                 
512         /* our chain */
513         LIST_ENTRY(scsi_low_softc) sl_chain;
514
515         /* my targets */
516         struct targ_info *sl_ti[SCSI_LOW_NTARGETS];
517         struct targ_info_tab sl_titab;
518
519         /* current active T_L_Q nexus */
520         struct targ_info *sl_Tnexus;            /* Target nexus */
521         struct lun_info *sl_Lnexus;             /* Lun nexus */
522         struct slccb *sl_Qnexus;                        /* Qtag nexus */
523         int sl_nexus_call;
524
525         /* ccb start queue */
526         struct slccbtab sl_start;       
527
528         /* retry limit and phase change counter */
529         int sl_max_retry;
530         int sl_ph_count;
531         int sl_timeout_count;
532
533         /* selection & total num disconnect targets */
534         int sl_nio;
535         int sl_disc;
536         int sl_retry_sel;
537         struct slccb *sl_selid;
538
539         /* attention */
540         int sl_atten;                   /* ATN asserted */
541         int sl_clear_atten;             /* negate ATN required */
542
543         /* scsi phase suggested by scsi msg */
544         u_int sl_msgphase;      
545 #define MSGPH_NULL      0x00            /* no msg */
546 #define MSGPH_DISC      0x01            /* disconnect msg */
547 #define MSGPH_CMDC      0x02            /* cmd complete msg */
548 #define MSGPH_ABORT     0x03            /* abort seq */
549 #define MSGPH_TERM      0x04            /* current io terminate */
550 #define MSGPH_LCTERM    0x05            /* cmd link terminated */
551 #define MSGPH_RESET     0x06            /* reset target */
552
553         /* error */
554         u_int sl_error;                 /* error flags */
555 #define FATALIO         0x0001          /* generic io error & retry io */
556 #define ABORTIO         0x0002          /* generic io error & terminate io */
557 #define TIMEOUTIO       0x0004          /* watch dog timeout */
558 #define SELTIMEOUTIO    0x0008          /* selection timeout */
559 #define PDMAERR         0x0010          /* dma xfer error */
560 #define MSGERR          0x0020          /* msgsys error */
561 #define PARITYERR       0x0040          /* parity error */
562 #define BUSYERR         0x0080          /* target busy error */
563 #define STATERR         0x0100          /* status error */
564 #define UACAERR         0x0200          /* target CA state, no sense check */
565 #define SENSEIO         0x1000          /* cmd not excuted but sense data ok */
566 #define SENSEERR        0x2000          /* cmd not excuted and sense data bad */
567 #define UBFERR          0x4000          /* unexpected bus free */
568 #define PENDINGIO       0x8000          /* ccb start not yet */
569 #define SCSI_LOW_ERRORBITS "\020\017ubferr\016senseerr\015senseio\012uacaerr\011staterr\010busy\007parity\006msgerr\005pdmaerr\004seltimeout\003timeout\002abort\001fatal"
570
571         /* current scsi data pointer */
572         struct sc_p sl_scp;
573
574         /* power control */
575         u_int sl_active;                /* host is busy state */
576         int sl_powc;                    /* power down timer counter */
577         u_int sl_rstep;                 /* resume step */
578
579         /* configuration flags */
580         u_int sl_flags;         
581 #define HW_POWDOWN      0x0001
582 #define HW_RESUME       0x0002
583 #define HW_PDMASTART    0x0004
584 #define HW_INACTIVE     0x0008
585 #define HW_POWERCTRL    0x0010
586 #define HW_INITIALIZING 0x0020
587 #define HW_READ_PADDING         0x1000
588 #define HW_WRITE_PADDING        0x2000
589
590         u_int sl_cfgflags;
591 #define CFG_NODISC              0x0001
592 #define CFG_NOPARITY            0x0002
593 #define CFG_NOATTEN             0x0004
594 #define CFG_ASYNC               0x0008
595 #define CFG_NOQTAG              0x0010
596
597         int sl_show_result;
598 #define SHOW_SYNCH_NEG  0x0001
599 #define SHOW_WIDE_NEG   0x0002
600 #define SHOW_CALCF_RES  0x0010
601 #define SHOW_PROBE_RES  0x0020
602 #define SHOW_ALL_NEG    -1
603
604         /* host informations */
605         u_int sl_hostid;
606         int sl_nluns;
607         int sl_ntargs;
608         int sl_openings;
609
610         /* interface functions */
611         struct scsi_low_funcs *sl_funcs;
612
613         /* targinfo size */
614         int sl_targsize;
615 };
616
617 #define SCSI_LOW_LOCK(sl)               mtx_lock(&(sl)->sl_lock)
618 #define SCSI_LOW_UNLOCK(sl)             mtx_unlock(&(sl)->sl_lock)
619 #define SCSI_LOW_ASSERT_LOCKED(sl)      mtx_assert(&(sl)->sl_lock, MA_OWNED)
620
621 /*************************************************
622  * SCSI LOW service functions
623  *************************************************/
624 /* 
625  * Scsi low attachment function.
626  */
627 int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int);
628 int scsi_low_detach(struct scsi_low_softc *);
629
630 /* 
631  * Scsi low interface activate or deactivate functions
632  */
633 int scsi_low_is_busy(struct scsi_low_softc *);
634 int scsi_low_activate(struct scsi_low_softc *);
635 int scsi_low_deactivate(struct scsi_low_softc *);
636
637 /* 
638  * Scsi phase "bus service" functions.
639  * These functions are corresponding to each scsi bus phaeses.
640  */
641 /* bus idle phase (other initiators or targets release bus) */
642 void scsi_low_bus_idle(struct scsi_low_softc *);
643
644 /* arbitration and selection phase */
645 void scsi_low_arbit_fail(struct scsi_low_softc *, struct slccb *);
646 static __inline void scsi_low_arbit_win(struct scsi_low_softc *);
647
648 /* msgout phase */
649 #define SCSI_LOW_MSGOUT_INIT            0x00000001
650 #define SCSI_LOW_MSGOUT_UNIFY           0x00000002
651 int scsi_low_msgout(struct scsi_low_softc *, struct targ_info *, u_int);
652
653 /* msgin phase */
654 #define SCSI_LOW_DATA_PE        0x80000000
655 int scsi_low_msgin(struct scsi_low_softc *, struct targ_info *, u_int);
656
657 /* statusin phase */
658 static __inline int scsi_low_statusin(struct scsi_low_softc *, struct targ_info *, u_int);
659
660 /* data phase */
661 int scsi_low_data(struct scsi_low_softc *, struct targ_info *, struct buf **, int);
662 static __inline void scsi_low_data_finish(struct scsi_low_softc *);
663
664 /* cmd phase */
665 int scsi_low_cmd(struct scsi_low_softc *, struct targ_info *);
666
667 /* reselection phase */
668 struct targ_info *scsi_low_reselected(struct scsi_low_softc *, u_int);
669
670 /* disconnection phase */
671 int scsi_low_disconnected(struct scsi_low_softc *, struct targ_info *);
672
673 /* 
674  * Scsi bus restart function.
675  * Canncel all established nexuses => scsi system initialized => restart jobs.
676  */
677 #define SCSI_LOW_RESTART_HARD   1
678 #define SCSI_LOW_RESTART_SOFT   0
679 int scsi_low_restart(struct scsi_low_softc *, int, u_char *);
680
681 /* 
682  * Scsi utility fucntions
683  */
684 /* print current status */
685 void scsi_low_print(struct scsi_low_softc *, struct targ_info *);
686
687 /* bus reset utility */
688 void scsi_low_bus_reset(struct scsi_low_softc *);
689
690 /*************************************************
691  * Message macro defs
692  *************************************************/
693 #define SCSI_LOW_SETUP_PHASE(ti, phase)                 \
694 {                                                       \
695         (ti)->ti_ophase = ti->ti_phase;                 \
696         (ti)->ti_phase = (phase);                       \
697 }
698
699 #define SCSI_LOW_SETUP_MSGPHASE(slp, PHASE)             \
700 {                                                       \
701         (slp)->sl_msgphase = (PHASE);                   \
702 }
703
704 #define SCSI_LOW_ASSERT_ATN(slp)                        \
705 {                                                       \
706         (slp)->sl_atten = 1;                            \
707 }
708
709 #define SCSI_LOW_DEASSERT_ATN(slp)                      \
710 {                                                       \
711         (slp)->sl_atten = 0;                            \
712 }
713
714 /*************************************************
715  * Inline functions
716  *************************************************/
717 static __inline void scsi_low_attention(struct scsi_low_softc *);
718 static __inline int scsi_low_is_msgout_continue(struct targ_info *, u_int);
719 static __inline int scsi_low_assert_msg(struct scsi_low_softc *, struct targ_info *, u_int, int);
720 static __inline int scsi_low_is_disconnect_ok(struct slccb *);
721
722 static __inline int
723 scsi_low_is_msgout_continue(ti, mask)
724         struct targ_info *ti;
725         u_int mask;
726 {
727         
728         return ((ti->ti_msgflags & (~mask)) != 0);
729 }
730
731 static __inline int
732 scsi_low_is_disconnect_ok(cb)
733         struct slccb *cb;
734 {
735
736         return ((cb->li->li_flags & SCSI_LOW_DISC) != 0 &&
737                     (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) == 0);
738 }
739
740 static __inline void
741 scsi_low_attention(slp)
742         struct scsi_low_softc *slp;
743 {
744
745         if (slp->sl_atten != 0)
746                 return;
747
748         (*slp->sl_funcs->scsi_low_attention) (slp);
749         SCSI_LOW_ASSERT_ATN(slp);
750 }
751
752 static __inline int
753 scsi_low_assert_msg(slp, ti, msg, now)
754         struct scsi_low_softc *slp;
755         struct targ_info *ti;
756         u_int msg;
757         int now;
758 {
759
760         ti->ti_msgflags |= msg;
761         if (now != 0)
762                 scsi_low_attention(slp);
763         return 0;
764 }
765
766 static __inline void
767 scsi_low_arbit_win(slp)
768         struct scsi_low_softc *slp;
769 {
770
771         slp->sl_selid = NULL;
772 }
773
774 static __inline void
775 scsi_low_data_finish(slp)
776         struct scsi_low_softc *slp;
777 {
778
779         if (slp->sl_Qnexus != NULL)
780         {
781                 slp->sl_Qnexus->ccb_datalen = slp->sl_scp.scp_datalen;
782         }
783 }
784
785 static __inline int
786 scsi_low_statusin(slp, ti, c)
787         struct scsi_low_softc *slp;
788         struct targ_info *ti;
789         u_int c;
790 {
791
792         slp->sl_ph_count ++;
793         if ((c & SCSI_LOW_DATA_PE) != 0)
794         {
795                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ERROR, 0);
796                 return EIO;
797         }
798         slp->sl_scp.scp_status = (u_int8_t) c;
799         return 0;
800 }
801
802 /*************************************************
803  * Message out defs
804  *************************************************/
805 /* XXX: use scsi_message.h */
806 #define ST_GOOD         0x00
807 #define ST_CHKCOND      0x02
808 #define ST_MET          0x04
809 #define ST_BUSY         0x08
810 #define ST_INTERGOOD    0x10
811 #define ST_INTERMET     0x14
812 #define ST_CONFLICT     0x18
813 #define ST_CMDTERM      0x22
814 #define ST_QUEFULL      0x28
815 #define ST_UNKNOWN      0xff
816
817 #define MSG_COMP        0x00
818 #define MSG_EXTEND      0x01
819
820 #define MKMSG_EXTEND(XLEN, XCODE) ((((u_int)(XLEN)) << NBBY) | ((u_int)(XCODE)))
821 #define MSG_EXTEND_MDPCODE      0x00
822 #define MSG_EXTEND_MDPLEN       0x05
823 #define MSG_EXTEND_SYNCHCODE    0x01
824 #define MSG_EXTEND_SYNCHLEN     0x03
825 #define MSG_EXTEND_WIDECODE     0x03
826 #define MSG_EXTEND_WIDELEN      0x02
827
828 #define MSG_SAVESP      0x02
829 #define MSG_RESTORESP   0x03
830 #define MSG_DISCON      0x04
831 #define MSG_I_ERROR     0x05
832 #define MSG_ABORT       0x06
833 #define MSG_REJECT      0x07
834 #define MSG_NOOP        0x08
835 #define MSG_PARITY      0x09
836 #define MSG_LCOMP       0x0a
837 #define MSG_LCOMP_F     0x0b
838 #define MSG_RESET       0x0c
839 #define MSG_ABORT_QTAG  0x0d
840 #define MSG_CLEAR_QTAG  0x0e
841 #define MSG_TERM_IO     0x11
842 #define MSG_SIMPLE_QTAG 0x20
843 #define MSG_HEAD_QTAG   0x21
844 #define MSG_ORDERED_QTAG        0x22
845 #define MSG_IDENTIFY            0x80
846 #define MSG_IDENTIFY_DISCPRIV   0x40
847 #endif  /* !_SCSI_LOW_H_ */