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