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