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