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