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