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