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