2 * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $
3 * $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.11 2004/09/17 02:38:10 joerg Exp $
4 * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $
7 #define SCSI_LOW_STATICS
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define SCSI_LOW_START_UP_CHECK
12 /* #define SCSI_LOW_INFO_DETAIL */
13 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
14 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
16 #define SCSI_LOW_FLAGS_QUIRKS_OK
19 * [NetBSD for NEC PC-98 series]
20 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
21 * NetBSD/pc98 porting staff. All rights reserved.
22 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
23 * Naofumi HONDA. All rights reserved.
25 * [Ported for FreeBSD CAM]
26 * Copyright (c) 2000, 2001
27 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. The name of the author may not be used to endorse or promote products
39 * derived from this software without specific prior written permission.
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
45 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
47 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
50 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51 * POSSIBILITY OF SUCH DAMAGE.
54 /* <On the nexus establishment>
55 * When our host is reselected,
56 * nexus establish processes are little complicated.
57 * Normal steps are followings:
58 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
59 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
60 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
64 #include <sys/param.h>
67 #include <sys/devicestat.h>
68 #include <sys/errno.h>
69 #include <sys/kernel.h>
70 #include <sys/malloc.h>
71 #include <sys/queue.h>
72 #include <sys/systm.h>
74 #include <bus/cam/cam.h>
75 #include <bus/cam/cam_ccb.h>
76 #include <bus/cam/cam_sim.h>
77 #include <bus/cam/cam_debug.h>
78 #include <bus/cam/cam_periph.h>
80 #include <bus/cam/scsi/scsi_all.h>
81 #include <bus/cam/scsi/scsi_message.h>
82 #include <bus/cam/scsi/scsi_low.h>
84 /**************************************************************
86 **************************************************************/
87 #define SCSI_LOW_POLL_HZ 1000
89 /* functions return values */
90 #define SCSI_LOW_START_NO_QTAG 0
91 #define SCSI_LOW_START_QTAG 1
93 #define SCSI_LOW_DONE_COMPLETE 0
94 #define SCSI_LOW_DONE_RETRY 1
96 /* internal disk flags */
97 #define SCSI_LOW_DISK_DISC 0x00000001
98 #define SCSI_LOW_DISK_QTAG 0x00000002
99 #define SCSI_LOW_DISK_LINK 0x00000004
100 #define SCSI_LOW_DISK_PARITY 0x00000008
101 #define SCSI_LOW_DISK_SYNC 0x00010000
102 #define SCSI_LOW_DISK_WIDE_16 0x00020000
103 #define SCSI_LOW_DISK_WIDE_32 0x00040000
104 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
105 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
106 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
108 /**************************************************************
110 **************************************************************/
111 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
112 static void scsi_low_engage (void *);
113 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
114 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
115 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
116 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
117 static void scsi_low_twiddle_wait (void);
118 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
119 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
120 static void scsi_low_calcf_lun (struct lun_info *);
121 static void scsi_low_calcf_target (struct targ_info *);
122 static void scsi_low_calcf_show (struct lun_info *);
123 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
124 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
125 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
126 static int scsi_low_init (struct scsi_low_softc *, u_int);
127 static void scsi_low_start (struct scsi_low_softc *);
128 static void scsi_low_free_ti (struct scsi_low_softc *);
130 static int scsi_low_alloc_qtag (struct slccb *);
131 static int scsi_low_dealloc_qtag (struct slccb *);
132 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
133 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
134 static void scsi_low_unit_ready_cmd (struct slccb *);
135 static void scsi_low_timeout (void *);
136 static int scsi_low_timeout_check (struct scsi_low_softc *);
137 #ifdef SCSI_LOW_START_UP_CHECK
138 static int scsi_low_start_up (struct scsi_low_softc *);
139 #endif /* SCSI_LOW_START_UP_CHECK */
140 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
141 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
143 int scsi_low_version_major = 2;
144 int scsi_low_version_minor = 17;
146 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
148 /**************************************************************
149 * Debug, Run test and Statics
150 **************************************************************/
151 #ifdef SCSI_LOW_INFO_DETAIL
152 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
153 #else /* !SCSI_LOW_INFO_DETAIL */
154 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
155 #endif /* !SCSI_LOW_INFO_DETAIL */
157 #ifdef SCSI_LOW_STATICS
158 struct scsi_low_statics {
161 int nexus_disconnected;
162 int nexus_reselected;
165 #endif /* SCSI_LOW_STATICS */
167 #ifdef SCSI_LOW_DEBUG
168 #define SCSI_LOW_DEBUG_DONE 0x00001
169 #define SCSI_LOW_DEBUG_DISC 0x00002
170 #define SCSI_LOW_DEBUG_SENSE 0x00004
171 #define SCSI_LOW_DEBUG_CALCF 0x00008
172 #define SCSI_LOW_DEBUG_ACTION 0x10000
173 int scsi_low_debug = 0;
175 #define SCSI_LOW_MAX_ATTEN_CHECK 32
176 #define SCSI_LOW_ATTEN_CHECK 0x0001
177 #define SCSI_LOW_CMDLNK_CHECK 0x0002
178 #define SCSI_LOW_ABORT_CHECK 0x0004
179 #define SCSI_LOW_NEXUS_CHECK 0x0008
180 int scsi_low_test = 0;
181 int scsi_low_test_id = 0;
183 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
184 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
185 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
186 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
187 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
188 #define SCSI_LOW_DEBUG_GO(fl, id) \
189 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
190 #endif /* SCSI_LOW_DEBUG */
192 /**************************************************************
194 **************************************************************/
195 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
196 GENERIC_CCB(scsi_low, slccb, ccb_chain)
198 /**************************************************************
200 **************************************************************/
201 #define SCSI_LOW_INLINE static __inline
202 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
203 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
204 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
205 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
206 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
207 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
208 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
211 scsi_low_activate_qtag(cb)
214 struct lun_info *li = cb->li;
216 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
220 cb->ccb_tag = cb->ccb_otag;
224 scsi_low_deactivate_qtag(cb)
227 struct lun_info *li = cb->li;
229 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
233 cb->ccb_tag = SCSI_LOW_UNKTAG;
237 scsi_low_ccb_message_exec(slp, cb)
238 struct scsi_low_softc *slp;
242 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
243 cb->ccb_msgoutflag = 0;
247 scsi_low_ccb_message_assert(cb, msg)
252 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
256 scsi_low_ccb_message_retry(cb)
259 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
263 scsi_low_ccb_message_clear(cb)
266 cb->ccb_msgoutflag = 0;
270 scsi_low_init_msgsys(slp, ti)
271 struct scsi_low_softc *slp;
272 struct targ_info *ti;
276 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
277 SCSI_LOW_DEASSERT_ATN(slp);
278 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
281 /*=============================================================
282 * START OF OS switch (All OS depend fucntions should be here)
283 =============================================================*/
284 /* common os depend utitlities */
285 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
286 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
287 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
289 static u_int8_t scsi_low_cmd_flags[256] = {
290 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
291 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
292 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
293 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
294 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
297 struct scsi_low_error_code {
302 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
303 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
305 static struct slccb *
306 scsi_low_find_ccb(slp, target, lun, osdep)
307 struct scsi_low_softc *slp;
311 struct targ_info *ti;
315 ti = slp->sl_ti[target];
316 li = scsi_low_alloc_li(ti, lun, 0);
320 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
323 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
324 cb = TAILQ_NEXT(cb, ccb_chain))
326 if (cb->osdep == osdep)
330 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
331 cb = TAILQ_NEXT(cb, ccb_chain))
333 if (cb->osdep == osdep)
340 scsi_low_translate_error_code(cb, tp)
342 struct scsi_low_error_code *tp;
345 if (cb->ccb_error == 0)
346 return tp->error_code;
348 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
350 return tp->error_code;
353 /**************************************************************
354 * SCSI INTERFACE (CAM)
355 **************************************************************/
356 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_INTWAIT)
357 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
358 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
360 static void scsi_low_poll_cam (struct cam_sim *);
361 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
362 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
363 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
365 static int scsi_low_attach_cam (struct scsi_low_softc *);
366 static int scsi_low_world_start_cam (struct scsi_low_softc *);
367 static int scsi_low_dettach_cam (struct scsi_low_softc *);
368 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
369 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
370 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
372 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
374 scsi_low_world_start_cam,
375 scsi_low_dettach_cam,
376 scsi_low_ccb_setup_cam,
381 struct scsi_low_error_code scsi_low_error_code_cam[] = {
383 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
384 {SENSEERR, CAM_AUTOSENSE_FAIL},
385 {UACAERR, CAM_SCSI_STATUS_ERROR},
386 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
387 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
388 {TIMEOUTIO, CAM_CMD_TIMEOUT},
389 {PDMAERR, CAM_DATA_RUN_ERR},
390 {PARITYERR, CAM_UNCOR_PARITY},
391 {UBFERR, CAM_UNEXP_BUSFREE},
392 {ABORTIO, CAM_REQ_ABORTED},
393 {-1, CAM_UNREC_HBA_ERROR}
396 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
399 * Please check a polling hz, currently we assume scsi_low_poll() is
402 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
405 scsi_low_poll_cam(sim)
408 struct scsi_low_softc *slp = SIM2SLP(sim);
410 (*slp->sl_funcs->scsi_low_poll) (slp);
412 if (slp->sl_si.si_poll_count ++ >=
413 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
415 slp->sl_si.si_poll_count = 0;
416 scsi_low_timeout_check(slp);
421 scsi_low_cam_rescan_callback(periph, ccb)
422 struct cam_periph *periph;
426 xpt_free_path(ccb->ccb_h.path);
431 scsi_low_rescan_bus_cam(slp)
432 struct scsi_low_softc *slp;
434 struct cam_path *path;
435 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_INTWAIT);
438 bzero(ccb, sizeof(union ccb));
440 status = xpt_create_path(&path, xpt_periph,
441 cam_sim_path(slp->sl_si.sim), -1, 0);
442 if (status != CAM_REQ_CMP)
445 xpt_setup_ccb(&ccb->ccb_h, path, 5);
446 ccb->ccb_h.func_code = XPT_SCAN_BUS;
447 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
448 ccb->crcn.flags = CAM_FLAG_NONE;
453 scsi_low_scsi_action_cam(sim, ccb)
457 struct scsi_low_softc *slp = SIM2SLP(sim);
458 struct targ_info *ti;
461 u_int lun, flags, msg, target;
464 target = (u_int) (ccb->ccb_h.target_id);
465 lun = (u_int) ccb->ccb_h.target_lun;
467 #ifdef SCSI_LOW_DEBUG
468 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
470 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
471 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
473 #endif /* SCSI_LOW_DEBUG */
475 switch (ccb->ccb_h.func_code) {
476 case XPT_SCSI_IO: /* Execute the requested I/O operation */
477 #ifdef SCSI_LOW_DIAGNOSTIC
478 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
480 printf("%s: invalid target/lun\n", slp->sl_xname);
481 ccb->ccb_h.status = CAM_REQ_INVALID;
485 #endif /* SCSI_LOW_DIAGNOSTIC */
487 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
488 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
493 ti = slp->sl_ti[target];
496 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
497 flags = CCB_AUTOSENSE | CCB_SCSIIO;
501 s = SCSI_LOW_SPLSCSI();
502 li = scsi_low_alloc_li(ti, lun, 1);
504 if (ti->ti_setup_msg != 0)
506 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
509 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
511 #ifdef SCSI_LOW_DEBUG
512 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
514 scsi_low_test_abort(slp, ti, li);
516 #endif /* SCSI_LOW_DEBUG */
520 case XPT_EN_LUN: /* Enable LUN as a target */
521 case XPT_TARGET_IO: /* Execute target I/O request */
522 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
523 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
525 ccb->ccb_h.status = CAM_REQ_INVALID;
529 case XPT_ABORT: /* Abort the specified CCB */
530 #ifdef SCSI_LOW_DIAGNOSTIC
531 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
533 printf("%s: invalid target/lun\n", slp->sl_xname);
534 ccb->ccb_h.status = CAM_REQ_INVALID;
538 #endif /* SCSI_LOW_DIAGNOSTIC */
540 s = SCSI_LOW_SPLSCSI();
541 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
542 rv = scsi_low_abort_ccb(slp, cb);
546 ccb->ccb_h.status = CAM_REQ_CMP;
548 ccb->ccb_h.status = CAM_REQ_INVALID;
552 case XPT_SET_TRAN_SETTINGS: {
553 struct ccb_trans_settings *cts;
556 #ifdef SCSI_LOW_DIAGNOSTIC
557 if (target == CAM_TARGET_WILDCARD)
559 printf("%s: invalid target\n", slp->sl_xname);
560 ccb->ccb_h.status = CAM_REQ_INVALID;
564 #endif /* SCSI_LOW_DIAGNOSTIC */
566 ti = slp->sl_ti[target];
567 if (lun == CAM_LUN_WILDCARD)
570 s = SCSI_LOW_SPLSCSI();
571 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
572 CCB_TRANS_SYNC_RATE_VALID |
573 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
575 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
576 val = cts->bus_width;
577 if (val < ti->ti_width)
580 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
581 val = cts->sync_period;
582 if (val == 0 || val > ti->ti_maxsynch.period)
583 ti->ti_maxsynch.period = val;
585 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
586 val = cts->sync_offset;
587 if (val < ti->ti_maxsynch.offset)
588 ti->ti_maxsynch.offset = val;
591 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
592 scsi_low_calcf_target(ti);
595 if ((cts->valid & (CCB_TRANS_DISC_VALID |
596 CCB_TRANS_TQ_VALID)) != 0)
598 li = scsi_low_alloc_li(ti, lun, 1);
599 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
601 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
602 li->li_quirks |= SCSI_LOW_DISK_DISC;
604 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
606 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
608 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
609 li->li_quirks |= SCSI_LOW_DISK_QTAG;
611 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
614 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
615 scsi_low_calcf_target(ti);
616 scsi_low_calcf_lun(li);
617 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
618 scsi_low_calcf_show(li);
622 ccb->ccb_h.status = CAM_REQ_CMP;
627 case XPT_GET_TRAN_SETTINGS: {
628 struct ccb_trans_settings *cts;
632 #ifdef SCSI_LOW_DIAGNOSTIC
633 if (target == CAM_TARGET_WILDCARD)
635 printf("%s: invalid target\n", slp->sl_xname);
636 ccb->ccb_h.status = CAM_REQ_INVALID;
640 #endif /* SCSI_LOW_DIAGNOSTIC */
641 ti = slp->sl_ti[target];
642 if (lun == CAM_LUN_WILDCARD)
645 s = SCSI_LOW_SPLSCSI();
646 li = scsi_low_alloc_li(ti, lun, 1);
647 #ifdef CAM_NEW_TRAN_CODE
648 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
649 struct ccb_trans_settings_scsi *scsi =
650 &cts->proto_specific.scsi;
651 struct ccb_trans_settings_spi *spi =
652 &cts->xport_specific.spi;
653 #ifdef SCSI_LOW_DIAGNOSTIC
654 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
656 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
657 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
661 #endif /* SCSI_LOW_DIAGNOSTIC */
662 cts->protocol = PROTO_SCSI;
663 cts->protocol_version = SCSI_REV_2;
664 cts->transport = XPORT_SPI;
665 cts->transport_version = 2;
667 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
668 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
670 diskflags = li->li_diskflags & li->li_cfgflags;
671 if (diskflags & SCSI_LOW_DISK_DISC)
672 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
673 if (diskflags & SCSI_LOW_DISK_QTAG)
674 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
676 spi->sync_period = ti->ti_maxsynch.period;
677 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
678 spi->sync_offset = ti->ti_maxsynch.offset;
679 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
681 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
682 spi->bus_width = ti->ti_width;
684 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
685 scsi->valid = CTS_SCSI_VALID_TQ;
686 spi->valid |= CTS_SPI_VALID_DISC;
690 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
692 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
694 #ifdef SCSI_LOW_DIAGNOSTIC
695 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
697 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
698 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
702 #endif /* SCSI_LOW_DIAGNOSTIC */
703 diskflags = li->li_diskflags & li->li_cfgflags;
704 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
705 cts->flags |= CCB_TRANS_DISC_ENB;
707 cts->flags &= ~CCB_TRANS_DISC_ENB;
708 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
709 cts->flags |= CCB_TRANS_TAG_ENB;
711 cts->flags &= ~CCB_TRANS_TAG_ENB;
713 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
715 #ifdef SCSI_LOW_DIAGNOSTIC
716 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
718 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
719 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
723 #endif /* SCSI_LOW_DIAGNOSTIC */
724 if ((li->li_flags & SCSI_LOW_DISC) != 0)
725 cts->flags |= CCB_TRANS_DISC_ENB;
727 cts->flags &= ~CCB_TRANS_DISC_ENB;
728 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
729 cts->flags |= CCB_TRANS_TAG_ENB;
731 cts->flags &= ~CCB_TRANS_TAG_ENB;
735 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
739 cts->sync_period = ti->ti_maxsynch.period;
740 cts->sync_offset = ti->ti_maxsynch.offset;
741 cts->bus_width = ti->ti_width;
743 cts->valid = CCB_TRANS_SYNC_RATE_VALID
744 | CCB_TRANS_SYNC_OFFSET_VALID
745 | CCB_TRANS_BUS_WIDTH_VALID
746 | CCB_TRANS_DISC_VALID
747 | CCB_TRANS_TQ_VALID;
748 ccb->ccb_h.status = CAM_REQ_CMP;
756 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
757 cam_calc_geometry(&ccb->ccg, /*extended*/1);
762 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
763 s = SCSI_LOW_SPLSCSI();
764 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
766 ccb->ccb_h.status = CAM_REQ_CMP;
770 case XPT_TERM_IO: /* Terminate the I/O process */
771 ccb->ccb_h.status = CAM_REQ_INVALID;
775 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
776 #ifdef SCSI_LOW_DIAGNOSTIC
777 if (target == CAM_TARGET_WILDCARD)
779 printf("%s: invalid target\n", slp->sl_xname);
780 ccb->ccb_h.status = CAM_REQ_INVALID;
784 #endif /* SCSI_LOW_DIAGNOSTIC */
786 msg = SCSI_LOW_MSG_RESET;
787 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
789 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
794 ti = slp->sl_ti[target];
795 if (lun == CAM_LUN_WILDCARD)
799 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
800 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
802 flags = CCB_NORETRY | CCB_URGENT;
804 s = SCSI_LOW_SPLSCSI();
805 li = scsi_low_alloc_li(ti, lun, 1);
806 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
810 case XPT_PATH_INQ: { /* Path routing inquiry */
811 struct ccb_pathinq *cpi = &ccb->cpi;
813 cpi->version_num = scsi_low_version_major;
814 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
815 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
816 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
817 cpi->hba_inquiry |= PI_WIDE_16;
818 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
819 cpi->hba_inquiry |= PI_WIDE_32;
820 if (ti->ti_maxsynch.offset > 0)
821 cpi->hba_inquiry |= PI_SDTR_ABLE;
822 cpi->target_sprt = 0;
824 cpi->hba_eng_cnt = 0;
825 cpi->max_target = slp->sl_ntargs - 1;
826 cpi->max_lun = slp->sl_nluns - 1;
827 cpi->initiator_id = slp->sl_hostid;
828 cpi->bus_id = cam_sim_bus(sim);
829 cpi->base_transfer_speed = 3300;
830 #ifdef CAM_NEW_TRAN_CODE
831 cpi->transport = XPORT_SPI;
832 cpi->transport_version = 2;
833 cpi->protocol = PROTO_SCSI;
834 cpi->protocol_version = SCSI_REV_2;
836 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
837 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
838 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
839 cpi->unit_number = cam_sim_unit(sim);
840 cpi->ccb_h.status = CAM_REQ_CMP;
846 printf("scsi_low: non support func_code = %d ",
847 ccb->ccb_h.func_code);
848 ccb->ccb_h.status = CAM_REQ_INVALID;
855 scsi_low_attach_cam(slp)
856 struct scsi_low_softc *slp;
858 struct cam_devq *devq;
861 sprintf(slp->sl_xname, "%s%d",
862 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
864 devq = cam_simq_alloc(SCSI_LOW_NCCB);
869 * ask the adapter what subunits are present
871 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
872 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
874 DEVPORT_DEVNAME(slp->sl_dev), slp,
875 DEVPORT_DEVUNIT(slp->sl_dev),
876 slp->sl_openings, tagged_openings, devq);
877 cam_simq_release(devq);
878 if (slp->sl_si.sim == NULL) {
882 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
883 cam_sim_free(slp->sl_si.sim);
884 slp->sl_si.sim = NULL;
888 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
889 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
890 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
891 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
892 cam_sim_free(slp->sl_si.sim);
893 slp->sl_si.sim = NULL;
897 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
902 scsi_low_world_start_cam(slp)
903 struct scsi_low_softc *slp;
907 scsi_low_rescan_bus_cam(slp);
912 scsi_low_dettach_cam(slp)
913 struct scsi_low_softc *slp;
916 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
917 xpt_free_path(slp->sl_si.path);
918 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
919 cam_sim_free(slp->sl_si.sim);
920 slp->sl_si.sim = NULL;
925 scsi_low_ccb_setup_cam(slp, cb)
926 struct scsi_low_softc *slp;
929 union ccb *ccb = (union ccb *) cb->osdep;
931 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
933 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
934 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
935 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
936 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
937 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
938 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
939 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
940 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
941 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
945 scsi_low_unit_ready_cmd(cb);
947 return SCSI_LOW_START_QTAG;
951 scsi_low_done_cam(slp, cb)
952 struct scsi_low_softc *slp;
957 ccb = (union ccb *) cb->osdep;
958 if (cb->ccb_error == 0)
960 ccb->ccb_h.status = CAM_REQ_CMP;
965 if (cb->ccb_rcnt >= slp->sl_max_retry)
966 cb->ccb_error |= ABORTIO;
968 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
969 (cb->ccb_error & ABORTIO) == 0)
972 if ((cb->ccb_error & SENSEIO) != 0)
974 memcpy(&ccb->csio.sense_data,
976 sizeof(ccb->csio.sense_data));
979 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
980 &scsi_low_error_code_cam[0]);
982 #ifdef SCSI_LOW_DIAGNOSTIC
983 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
984 cb->ccb_scp.scp_cmdlen > 0 &&
985 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
986 SCSI_LOW_CMD_ABORT_WARNING) != 0)
988 printf("%s: WARNING: scsi_low IO abort\n",
990 scsi_low_print(slp, NULL);
992 #endif /* SCSI_LOW_DIAGNOSTIC */
995 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
996 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
998 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
999 ccb->csio.scsi_status = 0; /* XXX */
1001 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1003 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1009 scsi_low_timeout_cam(slp, ch, action)
1010 struct scsi_low_softc *slp;
1017 case SCSI_LOW_TIMEOUT_CH_IO:
1020 case SCSI_LOW_TIMEOUT_START:
1021 callout_reset(&slp->sl_si.timeout_ch,
1022 hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
1024 case SCSI_LOW_TIMEOUT_STOP:
1025 callout_stop(&slp->sl_si.timeout_ch);
1030 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1033 case SCSI_LOW_TIMEOUT_START:
1034 callout_reset(&slp->sl_si.engage_ch, 1,
1035 scsi_low_engage, slp);
1037 case SCSI_LOW_TIMEOUT_STOP:
1038 callout_stop(&slp->sl_si.engage_ch);
1042 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1047 /**************************************************************
1048 * scsi low deactivate and activate
1049 **************************************************************/
1051 scsi_low_is_busy(slp)
1052 struct scsi_low_softc *slp;
1055 if (slp->sl_nio > 0)
1061 scsi_low_deactivate(slp)
1062 struct scsi_low_softc *slp;
1066 s = SCSI_LOW_SPLSCSI();
1067 slp->sl_flags |= HW_INACTIVE;
1068 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1069 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1070 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1071 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1077 scsi_low_activate(slp)
1078 struct scsi_low_softc *slp;
1082 s = SCSI_LOW_SPLSCSI();
1083 slp->sl_flags &= ~HW_INACTIVE;
1084 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1086 slp->sl_flags |= HW_INACTIVE;
1091 slp->sl_timeout_count = 0;
1092 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1093 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1098 /**************************************************************
1100 **************************************************************/
1101 #ifdef SCSI_LOW_DIAGNOSTIC
1102 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1103 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1105 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1108 scsi_low_msg_log_init(slmlp)
1109 struct scsi_low_msg_log *slmlp;
1112 slmlp->slml_ptr = 0;
1116 scsi_low_msg_log_write(slmlp, datap, len)
1117 struct scsi_low_msg_log *slmlp;
1123 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1126 ptr = slmlp->slml_ptr ++;
1127 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1128 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1129 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1130 slmlp->slml_msg[ptr].msg[ind] = 0;
1134 scsi_low_msg_log_show(slmlp, s, len)
1135 struct scsi_low_msg_log *slmlp;
1141 printf("%s: (%d) ", s, slmlp->slml_ptr);
1142 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1144 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1147 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1153 #endif /* SCSI_LOW_DIAGNOSTIC */
1155 /**************************************************************
1157 **************************************************************/
1159 scsi_low_engage(arg)
1162 struct scsi_low_softc *slp = arg;
1163 int s = SCSI_LOW_SPLSCSI();
1165 switch (slp->sl_rstep)
1169 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1170 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1171 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1176 slp->sl_flags &= ~HW_RESUME;
1177 scsi_low_start(slp);
1187 scsi_low_init(slp, flags)
1188 struct scsi_low_softc *slp;
1193 slp->sl_flags |= HW_INITIALIZING;
1195 /* clear power control timeout */
1196 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1198 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1199 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1200 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1202 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1205 /* reset current nexus */
1206 scsi_low_reset_nexus(slp, flags);
1207 if ((slp->sl_flags & HW_INACTIVE) != 0)
1213 if (flags != SCSI_LOW_RESTART_SOFT)
1215 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1219 slp->sl_flags &= ~HW_INITIALIZING;
1223 /**************************************************************
1225 **************************************************************/
1226 static struct lun_info *
1227 scsi_low_alloc_li(ti, lun, alloc)
1228 struct targ_info *ti;
1232 struct scsi_low_softc *slp = ti->ti_sc;
1233 struct lun_info *li;
1235 li = LIST_FIRST(&ti->ti_litab);
1238 if (li->li_lun == lun)
1241 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1243 if (li->li_lun == lun)
1245 LIST_REMOVE(li, lun_chain);
1246 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1255 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1257 panic("no lun info mem");
1259 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1263 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1265 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1266 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1267 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1268 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1269 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1271 li->li_qtagbits = (u_int) -1;
1273 TAILQ_INIT(&li->li_discq);
1274 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1276 /* host specific structure initialization per lun */
1277 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1278 (*slp->sl_funcs->scsi_low_lun_init)
1279 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1280 scsi_low_calcf_lun(li);
1284 /**************************************************************
1285 * allocate targ_info
1286 **************************************************************/
1287 static struct targ_info *
1288 scsi_low_alloc_ti(slp, targ)
1289 struct scsi_low_softc *slp;
1292 struct targ_info *ti;
1294 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1295 TAILQ_INIT(&slp->sl_titab);
1297 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1299 panic("%s short of memory", slp->sl_xname);
1301 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1305 slp->sl_ti[targ] = ti;
1306 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1307 LIST_INIT(&ti->ti_litab);
1309 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1310 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1311 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1312 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1313 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1314 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1316 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1318 (*slp->sl_funcs->scsi_low_targ_init)
1319 (slp, ti, SCSI_LOW_INFO_ALLOC);
1321 scsi_low_calcf_target(ti);
1326 scsi_low_free_ti(slp)
1327 struct scsi_low_softc *slp;
1329 struct targ_info *ti, *tib;
1330 struct lun_info *li, *nli;
1332 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1334 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1336 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1338 (*slp->sl_funcs->scsi_low_lun_init)
1339 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1341 nli = LIST_NEXT(li, lun_chain);
1345 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1347 (*slp->sl_funcs->scsi_low_targ_init)
1348 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1350 tib = TAILQ_NEXT(ti, ti_chain);
1355 /**************************************************************
1357 **************************************************************/
1359 scsi_low_bus_idle(slp)
1360 struct scsi_low_softc *slp;
1363 slp->sl_retry_sel = 0;
1364 if (slp->sl_Tnexus == NULL)
1365 scsi_low_start(slp);
1369 scsi_low_timeout(arg)
1372 struct scsi_low_softc *slp = arg;
1375 s = SCSI_LOW_SPLSCSI();
1376 (void) scsi_low_timeout_check(slp);
1377 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1378 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1383 scsi_low_timeout_check(slp)
1384 struct scsi_low_softc *slp;
1386 struct targ_info *ti;
1387 struct lun_info *li;
1388 struct slccb *cb = NULL; /* XXX */
1390 /* selection restart */
1391 if (slp->sl_retry_sel != 0)
1393 slp->sl_retry_sel = 0;
1394 if (slp->sl_Tnexus != NULL)
1397 cb = TAILQ_FIRST(&slp->sl_start);
1401 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1403 cb->ccb_flags |= CCB_NORETRY;
1404 cb->ccb_error |= SELTIMEOUTIO;
1405 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1406 panic("%s: ccb not finished", slp->sl_xname);
1409 if (slp->sl_Tnexus == NULL)
1410 scsi_low_start(slp);
1413 /* call hardware timeout */
1415 if (slp->sl_funcs->scsi_low_timeout != NULL)
1417 (*slp->sl_funcs->scsi_low_timeout) (slp);
1420 if (slp->sl_timeout_count ++ <
1421 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1424 slp->sl_timeout_count = 0;
1425 if (slp->sl_nio > 0)
1427 if ((cb = slp->sl_Qnexus) != NULL)
1429 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1433 else if (slp->sl_disc == 0)
1435 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1438 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1442 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1443 ti = TAILQ_NEXT(ti, ti_chain))
1445 if (ti->ti_disc == 0)
1448 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1449 li = LIST_NEXT(li, lun_chain))
1451 for (cb = TAILQ_FIRST(&li->li_discq);
1453 cb = TAILQ_NEXT(cb, ccb_chain))
1456 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1464 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1466 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1469 if (slp->sl_active != 0)
1471 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1477 if (slp->sl_powc < 0)
1479 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1480 slp->sl_flags |= HW_POWDOWN;
1481 (*slp->sl_funcs->scsi_low_power)
1482 (slp, SCSI_LOW_POWDOWN);
1488 cb->ccb_error |= TIMEOUTIO;
1489 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1490 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1491 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1492 scsi_low_start(slp);
1498 scsi_low_abort_ccb(slp, cb)
1499 struct scsi_low_softc *slp;
1502 struct targ_info *ti;
1503 struct lun_info *li;
1508 if ((cb->ccb_omsgoutflag &
1509 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1514 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1515 msg = SCSI_LOW_MSG_ABORT;
1517 msg = SCSI_LOW_MSG_ABORT_QTAG;
1519 cb->ccb_error |= ABORTIO;
1520 cb->ccb_flags |= CCB_NORETRY;
1521 scsi_low_ccb_message_assert(cb, msg);
1523 if (cb == slp->sl_Qnexus)
1525 scsi_low_assert_msg(slp, ti, msg, 1);
1527 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1529 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1530 panic("%s: revoked ccb done", slp->sl_xname);
1532 cb->ccb_flags |= CCB_STARTQ;
1533 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1535 if (slp->sl_Tnexus == NULL)
1536 scsi_low_start(slp);
1540 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1541 panic("%s: revoked ccb retried", slp->sl_xname);
1546 /**************************************************************
1547 * Generic SCSI INTERFACE
1548 **************************************************************/
1550 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
1551 struct scsi_low_softc *slp;
1552 int openings, ntargs, nluns, targsize, lunsize;
1554 struct targ_info *ti;
1555 struct lun_info *li;
1558 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1560 if (slp->sl_osdep_fp == NULL)
1561 panic("scsi_low: interface not spcified");
1563 if (ntargs > SCSI_LOW_NTARGETS)
1565 printf("scsi_low: %d targets are too large\n", ntargs);
1566 printf("change kernel options SCSI_LOW_NTARGETS");
1571 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1573 slp->sl_openings = openings;
1574 slp->sl_ntargs = ntargs;
1575 slp->sl_nluns = nluns;
1576 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1578 if (lunsize < sizeof(struct lun_info))
1579 lunsize = sizeof(struct lun_info);
1581 if (targsize < sizeof(struct targ_info))
1582 targsize = sizeof(struct targ_info);
1584 slp->sl_targsize = targsize;
1585 for (i = 0; i < ntargs; i ++)
1587 ti = scsi_low_alloc_ti(slp, i);
1588 ti->ti_lunsize = lunsize;
1589 li = scsi_low_alloc_li(ti, 0, 1);
1592 /* initialize queue */
1593 nccb = openings * ntargs;
1594 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1595 nccb = SCSI_LOW_NCCB;
1596 scsi_low_init_ccbque(nccb);
1597 TAILQ_INIT(&slp->sl_start);
1599 /* call os depend attach */
1600 callout_init(&slp->sl_si.timeout_ch);
1601 callout_init(&slp->sl_si.engage_ch);
1603 s = SCSI_LOW_SPLSCSI();
1604 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1608 printf("%s: scsi_low_attach: osdep attach failed\n",
1613 /* check hardware */
1614 SCSI_LOW_DELAY(1000); /* wait for 1ms */
1615 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1618 printf("%s: scsi_low_attach: initialization failed\n",
1623 /* start watch dog */
1624 slp->sl_timeout_count = 0;
1625 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1626 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1627 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1630 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1632 #ifdef SCSI_LOW_START_UP_CHECK
1633 /* probing devices */
1634 scsi_low_start_up(slp);
1635 #endif /* SCSI_LOW_START_UP_CHECK */
1637 /* call os depend attach done*/
1638 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1644 scsi_low_dettach(slp)
1645 struct scsi_low_softc *slp;
1649 s = SCSI_LOW_SPLSCSI();
1650 if (scsi_low_is_busy(slp) != 0)
1656 scsi_low_deactivate(slp);
1658 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1665 scsi_low_free_ti(slp);
1666 LIST_REMOVE(slp, sl_chain);
1671 /**************************************************************
1673 **************************************************************/
1675 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
1676 struct scsi_low_softc *slp;
1677 struct targ_info *ti;
1678 struct lun_info *li;
1686 scsi_low_ccb_message_assert(cb, msg);
1688 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1689 scsi_low_alloc_qtag(cb);
1691 cb->ccb_flags = flags | CCB_STARTQ;
1692 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1693 cb->ccb_error |= PENDINGIO;
1695 if ((flags & CCB_URGENT) != 0)
1697 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1701 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1706 if (slp->sl_Tnexus == NULL)
1707 scsi_low_start(slp);
1712 scsi_low_message_enqueue(slp, ti, li, flags)
1713 struct scsi_low_softc *slp;
1714 struct targ_info *ti;
1715 struct lun_info *li;
1721 tmsgflags = ti->ti_setup_msg;
1722 ti->ti_setup_msg = 0;
1724 flags |= CCB_NORETRY;
1725 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1730 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1734 /**************************************************************
1735 * Generic Start & Done
1736 **************************************************************/
1737 #define SLSC_MODE_SENSE_SHORT 0x1a
1738 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1739 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1740 sizeof(struct scsi_low_mode_sense_data), 0};
1741 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1742 sizeof(struct scsi_low_inq_data), 0};
1743 static u_int8_t unit_ready_cmd[6];
1744 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1745 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1746 static int scsi_low_resume (struct scsi_low_softc *);
1749 scsi_low_unit_ready_cmd(cb)
1753 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1754 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1755 cb->ccb_scp.scp_datalen = 0;
1756 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1761 scsi_low_sense_abort_start(slp, ti, li, cb)
1762 struct scsi_low_softc *slp;
1763 struct targ_info *ti;
1764 struct lun_info *li;
1768 cb->ccb_scp.scp_cmdlen = 6;
1769 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1770 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1771 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1772 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1773 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1774 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1775 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1777 scsi_low_ccb_message_clear(cb);
1778 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1780 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1784 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1785 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1786 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1787 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1790 return SCSI_LOW_START_NO_QTAG;
1794 scsi_low_setup_start(slp, ti, li, cb)
1795 struct scsi_low_softc *slp;
1796 struct targ_info *ti;
1797 struct lun_info *li;
1801 switch(li->li_state)
1803 case SCSI_LOW_LUN_SLEEP:
1804 scsi_low_unit_ready_cmd(cb);
1807 case SCSI_LOW_LUN_START:
1808 cb->ccb_scp.scp_cmd = ss_cmd;
1809 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1810 cb->ccb_scp.scp_datalen = 0;
1811 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1815 case SCSI_LOW_LUN_INQ:
1816 cb->ccb_scp.scp_cmd = inq_cmd;
1817 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1818 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1819 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1820 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1824 case SCSI_LOW_LUN_MODEQ:
1825 cb->ccb_scp.scp_cmd = sms_cmd;
1826 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1827 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1828 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1829 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1831 return SCSI_LOW_START_QTAG;
1834 panic("%s: no setup phase", slp->sl_xname);
1837 return SCSI_LOW_START_NO_QTAG;
1841 scsi_low_resume(slp)
1842 struct scsi_low_softc *slp;
1845 if (slp->sl_flags & HW_RESUME)
1847 slp->sl_flags &= ~HW_POWDOWN;
1848 if (slp->sl_funcs->scsi_low_power != NULL)
1850 slp->sl_flags |= HW_RESUME;
1852 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1853 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1854 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1855 SCSI_LOW_TIMEOUT_START);
1863 struct scsi_low_softc *slp;
1865 struct targ_info *ti;
1866 struct lun_info *li;
1870 /* check hardware exists or under initializations ? */
1871 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1874 /* check hardware power up ? */
1875 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1878 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1880 if (scsi_low_resume(slp) == EJUSTRETURN)
1886 #ifdef SCSI_LOW_DIAGNOSTIC
1887 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1889 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
1890 panic("%s: inconsistent", slp->sl_xname);
1892 #endif /* SCSI_LOW_DIAGNOSTIC */
1894 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1895 cb = TAILQ_NEXT(cb, ccb_chain))
1899 if (li->li_disc == 0)
1901 goto scsi_low_cmd_start;
1903 else if (li->li_nqio > 0)
1905 if (li->li_nqio < li->li_maxnqio ||
1906 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1907 goto scsi_low_cmd_start;
1913 cb->ccb_flags &= ~CCB_STARTQ;
1914 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1917 /* clear all error flag bits (for restart) */
1919 cb->ccb_datalen = -1;
1920 cb->ccb_scp.scp_status = ST_UNKNOWN;
1922 /* setup nexus pointer */
1923 slp->sl_Qnexus = cb;
1924 slp->sl_Lnexus = li;
1925 slp->sl_Tnexus = ti;
1927 /* initialize msgsys */
1928 scsi_low_init_msgsys(slp, ti);
1931 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1933 /* CA state or forced abort */
1934 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1936 else if (li->li_state >= SCSI_LOW_LUN_OK)
1938 cb->ccb_flags &= ~CCB_INTERNAL;
1939 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1940 if (cb->ccb_msgoutflag != 0)
1942 scsi_low_ccb_message_exec(slp, cb);
1947 cb->ccb_flags |= CCB_INTERNAL;
1948 rv = scsi_low_setup_start(slp, ti, li, cb);
1952 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1954 if (rv == SCSI_LOW_START_QTAG &&
1955 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1960 scsi_low_activate_qtag(cb);
1961 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1962 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1963 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1964 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1965 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1967 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1968 scsi_low_assert_msg(slp, ti, qmsg, 0);
1972 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1973 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1974 cb->ccb_tc = cb->ccb_tcmax;
1976 /* setup saved scsi data pointer */
1977 cb->ccb_sscp = cb->ccb_scp;
1979 /* setup current scsi pointer */
1980 slp->sl_scp = cb->ccb_sscp;
1981 slp->sl_error = cb->ccb_error;
1983 /* assert always an identify msg */
1984 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1987 #ifdef SCSI_LOW_DIAGNOSTIC
1988 scsi_low_msg_log_init(&ti->ti_log_msgin);
1989 scsi_low_msg_log_init(&ti->ti_log_msgout);
1990 #endif /* SCSI_LOW_DIAGNOSTIC */
1992 /* selection start */
1994 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1995 if (rv == SCSI_LOW_START_OK)
1997 #ifdef SCSI_LOW_STATICS
1998 scsi_low_statics.nexus_win ++;
1999 #endif /* SCSI_LOW_STATICS */
2003 scsi_low_arbit_fail(slp, cb);
2004 #ifdef SCSI_LOW_STATICS
2005 scsi_low_statics.nexus_fail ++;
2006 #endif /* SCSI_LOW_STATICS */
2010 scsi_low_arbit_fail(slp, cb)
2011 struct scsi_low_softc *slp;
2014 struct targ_info *ti = cb->ti;
2016 scsi_low_deactivate_qtag(cb);
2017 scsi_low_ccb_message_retry(cb);
2018 cb->ccb_flags |= CCB_STARTQ;
2019 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2021 scsi_low_bus_release(slp, ti);
2024 if (slp->sl_disc == 0)
2026 #ifdef SCSI_LOW_DIAGNOSTIC
2027 printf("%s: try selection again\n", slp->sl_xname);
2028 #endif /* SCSI_LOW_DIAGNOSTIC */
2029 slp->sl_retry_sel = 1;
2034 scsi_low_bus_release(slp, ti)
2035 struct scsi_low_softc *slp;
2036 struct targ_info *ti;
2039 if (ti->ti_disc > 0)
2041 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2045 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2048 /* clear all nexus pointer */
2049 slp->sl_Qnexus = NULL;
2050 slp->sl_Lnexus = NULL;
2051 slp->sl_Tnexus = NULL;
2053 /* clear selection assert */
2054 slp->sl_selid = NULL;
2056 /* clear nexus data */
2057 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2059 /* clear phase change counter */
2060 slp->sl_ph_count = 0;
2064 scsi_low_setup_done(slp, cb)
2065 struct scsi_low_softc *slp;
2068 struct targ_info *ti;
2069 struct lun_info *li;
2074 if (cb->ccb_rcnt >= slp->sl_max_retry)
2076 cb->ccb_error |= ABORTIO;
2077 return SCSI_LOW_DONE_COMPLETE;
2080 /* XXX: special huck for selection timeout */
2081 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2082 (cb->ccb_error & SELTIMEOUTIO) != 0)
2084 cb->ccb_error |= ABORTIO;
2085 return SCSI_LOW_DONE_COMPLETE;
2088 switch(li->li_state)
2090 case SCSI_LOW_LUN_INQ:
2091 if (cb->ccb_error != 0)
2094 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2098 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2100 else if ((li->li_inq.sd_version & 7) >= 2 ||
2101 (li->li_inq.sd_len >= 4))
2103 if ((li->li_inq.sd_support & 0x2) == 0)
2104 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2105 if ((li->li_inq.sd_support & 0x8) == 0)
2106 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2109 if ((li->li_inq.sd_support & 0x10) == 0)
2110 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2111 if ((li->li_inq.sd_support & 0x20) == 0)
2112 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2113 if ((li->li_inq.sd_support & 0x40) == 0)
2114 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2119 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2122 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2124 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2126 scsi_low_calcf_target(ti);
2127 scsi_low_calcf_lun(li);
2130 case SCSI_LOW_LUN_MODEQ:
2131 if (cb->ccb_error != 0)
2133 if (cb->ccb_error & SENSEIO)
2135 #ifdef SCSI_LOW_DEBUG
2136 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2138 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2139 (u_int) cb->ccb_sense.error_code,
2140 (u_int) cb->ccb_sense.segment,
2141 (u_int) cb->ccb_sense.flags,
2142 (u_int) cb->ccb_sense.add_sense_code,
2143 (u_int) cb->ccb_sense.add_sense_code_qual);
2145 #endif /* SCSI_LOW_DEBUG */
2149 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2152 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2154 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2155 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2157 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2158 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2159 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2161 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2162 scsi_low_calcf_lun(li);
2170 if (li->li_state == SCSI_LOW_LUN_OK)
2172 scsi_low_calcf_target(ti);
2173 scsi_low_calcf_lun(li);
2174 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2175 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2177 scsi_low_calcf_show(li);
2182 return SCSI_LOW_DONE_RETRY;
2186 scsi_low_done(slp, cb)
2187 struct scsi_low_softc *slp;
2192 if (cb->ccb_error == 0)
2194 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2196 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2198 * SCSI-2 draft suggests
2199 * page 0x0a QErr bit determins if
2200 * the target aborts or continues
2201 * the queueing io's after CA state resolved.
2202 * However many targets seem not to support
2203 * the page 0x0a. Thus we should manually clear the
2204 * queuing io's after CA state.
2206 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2209 cb->ccb_flags |= CCB_CLEARQ;
2212 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2214 if ((cb->ccb_flags & CCB_SENSE) != 0)
2215 cb->ccb_error |= (SENSEIO | ABORTIO);
2216 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2218 else switch (cb->ccb_sscp.scp_status)
2224 if (cb->ccb_datalen == 0 ||
2225 cb->ccb_scp.scp_datalen == 0)
2228 if (cb->ccb_scp.scp_cmdlen > 0 &&
2229 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2230 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2233 cb->ccb_error |= PDMAERR;
2238 cb->ccb_error |= (BUSYERR | STATERR);
2242 cb->ccb_error |= (STATERR | ABORTIO);
2247 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2250 cb->ccb_flags |= CCB_SENSE;
2253 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2258 cb->ccb_error |= FATALIO;
2264 if (cb->ccb_flags & CCB_SENSE)
2266 cb->ccb_error |= (SENSEERR | ABORTIO);
2268 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2272 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2274 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2278 /* check a ccb msgout flag */
2279 if (cb->ccb_omsgoutflag != 0)
2281 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2282 SCSI_LOW_MSG_ABORT_QTAG | \
2283 SCSI_LOW_MSG_CLEAR_QTAG | \
2284 SCSI_LOW_MSG_TERMIO)
2286 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2288 cb->ccb_error |= ABORTIO;
2292 /* call OS depend done */
2293 if (cb->osdep != NULL)
2295 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2296 if (rv == EJUSTRETURN)
2299 else if (cb->ccb_error != 0)
2301 if (cb->ccb_rcnt >= slp->sl_max_retry)
2302 cb->ccb_error |= ABORTIO;
2304 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2305 (cb->ccb_error & ABORTIO) == 0)
2309 /* free our target */
2310 #ifdef SCSI_LOW_DEBUG
2311 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2313 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2314 scsi_low_print(slp, NULL);
2316 #endif /* SCSI_LOW_DEBUG */
2318 scsi_low_deactivate_qtag(cb);
2319 scsi_low_dealloc_qtag(cb);
2320 scsi_low_free_ccb(cb);
2322 return SCSI_LOW_DONE_COMPLETE;
2325 #ifdef SCSI_LOW_DEBUG
2326 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2328 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2329 scsi_low_print(slp, NULL);
2331 #endif /* SCSI_LOW_DEBUG */
2334 scsi_low_deactivate_qtag(cb);
2335 scsi_low_ccb_message_retry(cb);
2336 return SCSI_LOW_DONE_RETRY;
2339 /**************************************************************
2341 **************************************************************/
2343 scsi_low_reset_nexus_target(slp, ti, fdone)
2344 struct scsi_low_softc *slp;
2345 struct targ_info *ti;
2348 struct lun_info *li;
2350 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2351 li = LIST_NEXT(li, lun_chain))
2353 scsi_low_reset_nexus_lun(slp, li, fdone);
2354 li->li_state = SCSI_LOW_LUN_SLEEP;
2359 ti->ti_setup_msg = 0;
2360 ti->ti_setup_msg_done = 0;
2362 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2363 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2365 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2366 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2368 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2370 ((*slp->sl_funcs->scsi_low_targ_init)
2371 (slp, ti, SCSI_LOW_INFO_REVOKE));
2373 scsi_low_calcf_target(ti);
2375 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2376 li = LIST_NEXT(li, lun_chain))
2380 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2381 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2383 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2385 ((*slp->sl_funcs->scsi_low_lun_init)
2386 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2388 scsi_low_calcf_lun(li);
2393 scsi_low_reset_nexus(slp, fdone)
2394 struct scsi_low_softc *slp;
2397 struct targ_info *ti;
2398 struct slccb *cb, *topcb;
2400 if ((cb = slp->sl_Qnexus) != NULL)
2402 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2409 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2410 ti = TAILQ_NEXT(ti, ti_chain))
2412 scsi_low_reset_nexus_target(slp, ti, fdone);
2413 scsi_low_bus_release(slp, ti);
2414 scsi_low_init_msgsys(slp, ti);
2419 topcb->ccb_flags |= CCB_STARTQ;
2420 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2424 slp->sl_retry_sel = 0;
2425 slp->sl_flags &= ~HW_PDMASTART;
2430 static char tw_chars[] = "|/-\\";
2431 #define TWIDDLEWAIT 10000
2434 scsi_low_twiddle_wait(void)
2438 cnputc(tw_chars[tw_pos++]);
2439 tw_pos %= (sizeof(tw_chars) - 1);
2440 SCSI_LOW_DELAY(TWIDDLEWAIT);
2444 scsi_low_bus_reset(slp)
2445 struct scsi_low_softc *slp;
2449 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2451 printf("%s: try to reset scsi bus ", slp->sl_xname);
2452 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2453 scsi_low_twiddle_wait();
2459 scsi_low_restart(slp, flags, s)
2460 struct scsi_low_softc *slp;
2467 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2469 if ((error = scsi_low_init(slp, flags)) != 0)
2472 scsi_low_start(slp);
2476 /**************************************************************
2477 * disconnect and reselect
2478 **************************************************************/
2479 #define MSGCMD_LUN(msg) (msg & 0x07)
2481 static struct slccb *
2482 scsi_low_establish_ccb(ti, li, tag)
2483 struct targ_info *ti;
2484 struct lun_info *li;
2487 struct scsi_low_softc *slp = ti->ti_sc;
2493 cb = TAILQ_FIRST(&li->li_discq);
2494 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2495 if (cb->ccb_tag == tag)
2500 * establish our ccb nexus
2503 #ifdef SCSI_LOW_DEBUG
2504 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2506 printf("%s: nexus(0x%lx) abort check start\n",
2507 slp->sl_xname, (u_long) cb);
2508 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2509 scsi_low_revoke_ccb(slp, cb, 1);
2513 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2515 if (cb->ccb_omsgoutflag == 0)
2516 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2518 #endif /* SCSI_LOW_DEBUG */
2520 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2521 cb->ccb_flags &= ~CCB_DISCQ;
2522 slp->sl_Qnexus = cb;
2524 slp->sl_scp = cb->ccb_sscp;
2525 slp->sl_error |= cb->ccb_error;
2531 /* inform "ccb nexus established" to the host driver */
2532 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2535 if (cb->ccb_msgoutflag != 0)
2537 scsi_low_ccb_message_exec(slp, cb);
2544 scsi_low_reselected(slp, targ)
2545 struct scsi_low_softc *slp;
2548 struct targ_info *ti;
2553 * Check select vs reselected collision.
2556 if ((cb = slp->sl_selid) != NULL)
2558 scsi_low_arbit_fail(slp, cb);
2559 #ifdef SCSI_LOW_STATICS
2560 scsi_low_statics.nexus_conflict ++;
2561 #endif /* SCSI_LOW_STATICS */
2565 * Check if no current active nexus.
2567 if (slp->sl_Tnexus != NULL)
2574 * Check a valid target id asserted ?
2576 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2578 s = "scsi id illegal";
2583 * Check the target scsi status.
2585 ti = slp->sl_ti[targ];
2586 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2588 s = "phase mismatch";
2596 scsi_low_init_msgsys(slp, ti);
2599 * Establish our target nexus
2601 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2602 slp->sl_Tnexus = ti;
2603 #ifdef SCSI_LOW_STATICS
2604 scsi_low_statics.nexus_reselected ++;
2605 #endif /* SCSI_LOW_STATICS */
2609 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2610 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2611 "reselect: scsi world confused");
2615 /**************************************************************
2616 * cmd out pointer setup
2617 **************************************************************/
2619 scsi_low_cmd(slp, ti)
2620 struct scsi_low_softc *slp;
2621 struct targ_info *ti;
2623 struct slccb *cb = slp->sl_Qnexus;
2625 slp->sl_ph_count ++;
2631 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2632 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2633 slp->sl_scp.scp_datalen = 0;
2634 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2635 slp->sl_error |= FATALIO;
2636 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2637 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2642 #ifdef SCSI_LOW_DEBUG
2643 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2645 scsi_low_test_cmdlnk(slp, cb);
2647 #endif /* SCSI_LOW_DEBUG */
2652 /**************************************************************
2653 * data out pointer setup
2654 **************************************************************/
2656 scsi_low_data(slp, ti, bp, direction)
2657 struct scsi_low_softc *slp;
2658 struct targ_info *ti;
2662 struct slccb *cb = slp->sl_Qnexus;
2664 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2670 slp->sl_error |= (FATALIO | PDMAERR);
2671 slp->sl_scp.scp_datalen = 0;
2672 slp->sl_scp.scp_direction = direction;
2673 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2674 if (ti->ti_ophase != ti->ti_phase)
2679 s = "DATA PHASE: ccb nexus not found";
2681 s = "DATA PHASE: xfer direction mismatch";
2682 SCSI_LOW_INFO(slp, ti, s);
2689 /**************************************************************
2691 **************************************************************/
2692 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2693 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2694 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2695 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2696 #define MSGIN_DATA_LAST 0x30
2698 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2699 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2700 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2701 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2703 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2704 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2705 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2706 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2707 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2708 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2709 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2711 struct scsi_low_msgout_data {
2714 int (*md_msgfunc) (struct scsi_low_softc *);
2715 int (*md_errfunc) (struct scsi_low_softc *, u_int);
2716 #define MSG_RELEASE_ATN 0x0001
2720 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2721 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2722 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2723 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2724 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2725 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2726 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2727 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2728 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2729 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2730 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2731 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2732 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2733 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2734 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2735 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2736 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2739 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2740 static int scsi_low_synch (struct scsi_low_softc *);
2741 static int scsi_low_wide (struct scsi_low_softc *);
2742 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2743 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2744 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2745 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2746 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2747 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2748 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2749 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2750 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2751 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2752 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2754 struct scsi_low_msgin_data {
2756 int (*md_msgfunc) (struct scsi_low_softc *);
2759 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2760 /* 0 */ {1, scsi_low_msginfunc_cc},
2761 /* 1 */ {2, scsi_low_msginfunc_ext},
2762 /* 2 */ {1, scsi_low_msginfunc_sdp},
2763 /* 3 */ {1, scsi_low_msginfunc_rp},
2764 /* 4 */ {1, scsi_low_msginfunc_disc},
2765 /* 5 */ {1, scsi_low_msginfunc_rejop},
2766 /* 6 */ {1, scsi_low_msginfunc_rejop},
2767 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2768 /* 8 */ {1, scsi_low_msginfunc_noop},
2769 /* 9 */ {1, scsi_low_msginfunc_parity},
2770 /* a */ {1, scsi_low_msginfunc_lcc},
2771 /* b */ {1, scsi_low_msginfunc_lcc},
2772 /* c */ {1, scsi_low_msginfunc_rejop},
2773 /* d */ {2, scsi_low_msginfunc_rejop},
2774 /* e */ {1, scsi_low_msginfunc_rejop},
2775 /* f */ {1, scsi_low_msginfunc_rejop},
2776 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2777 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2778 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2779 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2780 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2781 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2782 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2783 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2784 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2785 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2786 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2787 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2788 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2789 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2790 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2791 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2792 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2793 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2794 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2795 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2796 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2797 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2798 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2799 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2800 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2801 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2802 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2803 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2804 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2805 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2806 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2807 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2808 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2811 /**************************************************************
2813 **************************************************************/
2815 scsi_low_msgfunc_synch(slp)
2816 struct scsi_low_softc *slp;
2818 struct targ_info *ti = slp->sl_Tnexus;
2819 int ptr = ti->ti_msgoutlen;
2821 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2822 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2823 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2824 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2825 return MSG_EXTEND_SYNCHLEN + 2;
2829 scsi_low_msgfunc_wide(slp)
2830 struct scsi_low_softc *slp;
2832 struct targ_info *ti = slp->sl_Tnexus;
2833 int ptr = ti->ti_msgoutlen;
2835 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2836 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2837 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2838 return MSG_EXTEND_WIDELEN + 2;
2842 scsi_low_msgfunc_identify(slp)
2843 struct scsi_low_softc *slp;
2845 struct targ_info *ti = slp->sl_Tnexus;
2846 struct lun_info *li = slp->sl_Lnexus;
2847 struct slccb *cb = slp->sl_Qnexus;
2848 int ptr = ti->ti_msgoutlen;
2854 slp->sl_error |= FATALIO;
2855 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2856 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2860 if (scsi_low_is_disconnect_ok(cb) != 0)
2861 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2865 if (ti->ti_phase == PH_MSGOUT)
2867 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2868 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2870 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2874 ti->ti_msgoutstr[ptr + 0] = msg;
2879 scsi_low_msgfunc_abort(slp)
2880 struct scsi_low_softc *slp;
2883 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2888 scsi_low_msgfunc_qabort(slp)
2889 struct scsi_low_softc *slp;
2892 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2897 scsi_low_msgfunc_reset(slp)
2898 struct scsi_low_softc *slp;
2901 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2906 scsi_low_msgfunc_qtag(slp)
2907 struct scsi_low_softc *slp;
2909 struct targ_info *ti = slp->sl_Tnexus;
2910 struct slccb *cb = slp->sl_Qnexus;
2911 int ptr = ti->ti_msgoutlen;
2913 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2915 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2920 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2921 if (ti->ti_phase == PH_MSGOUT)
2923 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2930 * The following functions are called when targets give unexpected
2931 * responces in msgin (after msgout).
2934 scsi_low_errfunc_identify(slp, msgflags)
2935 struct scsi_low_softc *slp;
2939 if (slp->sl_Lnexus != NULL)
2941 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2942 scsi_low_calcf_lun(slp->sl_Lnexus);
2948 scsi_low_errfunc_synch(slp, msgflags)
2949 struct scsi_low_softc *slp;
2952 struct targ_info *ti = slp->sl_Tnexus;
2954 MSGIN_PERIOD(ti) = 0;
2955 MSGIN_OFFSET(ti) = 0;
2956 scsi_low_synch(slp);
2961 scsi_low_errfunc_wide(slp, msgflags)
2962 struct scsi_low_softc *slp;
2965 struct targ_info *ti = slp->sl_Tnexus;
2967 MSGIN_WIDTHP(ti) = 0;
2973 scsi_low_errfunc_qtag(slp, msgflags)
2974 struct scsi_low_softc *slp;
2978 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2980 if (slp->sl_Qnexus != NULL)
2982 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2984 if (slp->sl_Lnexus != NULL)
2986 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2987 scsi_low_calcf_lun(slp->sl_Lnexus);
2989 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2996 scsi_low_msgout(slp, ti, fl)
2997 struct scsi_low_softc *slp;
2998 struct targ_info *ti;
3001 struct scsi_low_msgout_data *mdp;
3004 #ifdef SCSI_LOW_DIAGNOSTIC
3005 if (ti != slp->sl_Tnexus)
3007 scsi_low_print(slp, NULL);
3008 panic("scsi_low_msgout: Target nexus inconsistent");
3010 #endif /* SCSI_LOW_DIAGNOSTIC */
3012 slp->sl_ph_count ++;
3013 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3015 printf("%s: too many phase changes\n", slp->sl_xname);
3016 slp->sl_error |= FATALIO;
3017 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3021 * Scsi phase changes.
3022 * Previously msgs asserted are accepted by our target or
3023 * processed by scsi_low_msgin.
3024 * Thus clear all saved informations.
3026 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3028 ti->ti_omsgflags = 0;
3029 ti->ti_emsgflags = 0;
3031 else if (slp->sl_atten == 0)
3034 * We did not assert attention, however still our target required
3035 * msgs. Resend previous msgs.
3037 ti->ti_msgflags |= ti->ti_omsgflags;
3038 ti->ti_omsgflags = 0;
3039 #ifdef SCSI_LOW_DIAGNOSTIC
3040 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3041 #endif /* SCSI_LOW_DIAGNOSTIC */
3045 * We have no msgs. send MSG_NOOP (OK?)
3047 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3048 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3053 ti->ti_msgoutlen = 0;
3054 slp->sl_clear_atten = 0;
3055 mdp = &scsi_low_msgout_data[0];
3056 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3058 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3060 ti->ti_omsgflags |= mdp->md_flags;
3061 ti->ti_msgflags &= ~mdp->md_flags;
3062 ti->ti_emsgflags = mdp->md_flags;
3064 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3065 if (mdp->md_msgfunc != NULL)
3066 len = (*mdp->md_msgfunc) (slp);
3070 #ifdef SCSI_LOW_DIAGNOSTIC
3071 scsi_low_msg_log_write(&ti->ti_log_msgout,
3072 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3073 #endif /* SCSI_LOW_DIAGNOSTIC */
3075 ti->ti_msgoutlen += len;
3076 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3078 slp->sl_clear_atten = 1;
3082 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3083 ti->ti_msgflags == 0)
3086 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3091 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3092 slp->sl_clear_atten = 1;
3094 return ti->ti_msgoutlen;
3097 /**************************************************************
3099 **************************************************************/
3101 scsi_low_msginfunc_noop(slp)
3102 struct scsi_low_softc *slp;
3109 scsi_low_msginfunc_rejop(slp)
3110 struct scsi_low_softc *slp;
3112 struct targ_info *ti = slp->sl_Tnexus;
3113 u_int8_t msg = ti->ti_msgin[0];
3115 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3116 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3121 scsi_low_msginfunc_cc(slp)
3122 struct scsi_low_softc *slp;
3124 struct lun_info *li;
3126 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3128 /* validate status */
3129 if (slp->sl_Qnexus == NULL)
3132 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3133 li = slp->sl_Lnexus;
3134 switch (slp->sl_scp.scp_status)
3137 li->li_maxnqio = li->li_maxnexus;
3142 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3143 scsi_low_reset_nexus_lun(slp, li, 0);
3151 if (li->li_maxnexus >= li->li_nqio)
3152 li->li_maxnexus = li->li_nqio - 1;
3153 li->li_maxnqio = li->li_maxnexus;
3158 slp->sl_error |= MSGERR;
3168 scsi_low_msginfunc_lcc(slp)
3169 struct scsi_low_softc *slp;
3171 struct targ_info *ti;
3172 struct lun_info *li;
3173 struct slccb *ncb, *cb;
3175 ti = slp->sl_Tnexus;
3176 li = slp->sl_Lnexus;
3177 if ((cb = slp->sl_Qnexus) == NULL)
3180 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3181 switch (slp->sl_scp.scp_status)
3185 li->li_maxnqio = li->li_maxnexus;
3189 slp->sl_error |= MSGERR;
3193 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3196 cb->ccb_error |= slp->sl_error;
3197 if (cb->ccb_error != 0)
3200 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3201 ncb = TAILQ_NEXT(ncb, ccb_chain))
3204 goto cmd_link_start;
3209 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3210 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3214 ncb->ccb_flags &= ~CCB_STARTQ;
3215 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3217 scsi_low_dealloc_qtag(ncb);
3218 ncb->ccb_tag = cb->ccb_tag;
3219 ncb->ccb_otag = cb->ccb_otag;
3220 cb->ccb_tag = SCSI_LOW_UNKTAG;
3221 cb->ccb_otag = SCSI_LOW_UNKTAG;
3222 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3223 panic("%s: linked ccb retried", slp->sl_xname);
3225 slp->sl_Qnexus = ncb;
3226 slp->sl_ph_count = 0;
3229 ncb->ccb_datalen = -1;
3230 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3231 ncb->ccb_flags &= ~CCB_INTERNAL;
3233 scsi_low_init_msgsys(slp, ti);
3235 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3237 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3238 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3239 ncb->ccb_tc = ncb->ccb_tcmax;
3241 /* setup saved scsi data pointer */
3242 ncb->ccb_sscp = ncb->ccb_scp;
3243 slp->sl_scp = ncb->ccb_sscp;
3244 slp->sl_error = ncb->ccb_error;
3246 #ifdef SCSI_LOW_DIAGNOSTIC
3247 scsi_low_msg_log_init(&ti->ti_log_msgin);
3248 scsi_low_msg_log_init(&ti->ti_log_msgout);
3249 #endif /* SCSI_LOW_DIAGNOSTIC */
3254 scsi_low_msginfunc_disc(slp)
3255 struct scsi_low_softc *slp;
3258 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3263 scsi_low_msginfunc_sdp(slp)
3264 struct scsi_low_softc *slp;
3266 struct slccb *cb = slp->sl_Qnexus;
3270 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3271 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3274 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3279 scsi_low_msginfunc_rp(slp)
3280 struct scsi_low_softc *slp;
3283 if (slp->sl_Qnexus != NULL)
3284 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3286 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3292 struct scsi_low_softc *slp;
3294 struct targ_info *ti = slp->sl_Tnexus;
3295 u_int period = 0, offset = 0, speed;
3299 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3300 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3301 MSGIN_OFFSET(ti) == 0)
3303 if ((offset = MSGIN_OFFSET(ti)) != 0)
3304 period = MSGIN_PERIOD(ti);
3305 s = offset ? "synchronous" : "async";
3310 * Target seems to be brain damaged.
3311 * Force async transfer.
3313 ti->ti_maxsynch.period = 0;
3314 ti->ti_maxsynch.offset = 0;
3315 printf("%s: target brain damaged. async transfer\n",
3320 ti->ti_maxsynch.period = period;
3321 ti->ti_maxsynch.offset = offset;
3323 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3327 * Current period and offset are not acceptable
3329 * The adapter changes max synch and max offset.
3331 printf("%s: synch neg failed. retry synch msg neg ...\n",
3336 ti->ti_osynch = ti->ti_maxsynch;
3339 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3343 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3345 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3346 struct slccb *cb = slp->sl_Qnexus;
3348 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3350 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3352 printf("%s(%d:*): <%s> offset %d period %dns ",
3353 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3357 speed = 1000 * 10 / (period * 4);
3358 printf("%d.%d M/s", speed / 10, speed % 10);
3367 struct scsi_low_softc *slp;
3369 struct targ_info *ti = slp->sl_Tnexus;
3372 ti->ti_width = MSGIN_WIDTHP(ti);
3373 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3377 * Current width is not acceptable for our adapter.
3378 * The adapter changes max width.
3380 printf("%s: wide neg failed. retry wide msg neg ...\n",
3385 ti->ti_owidth = ti->ti_width;
3386 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3388 ti->ti_setup_msg_done |=
3389 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3393 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3395 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3396 struct slccb *cb = slp->sl_Qnexus;
3398 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3400 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3402 printf("%s(%d:*): transfer width %d bits\n",
3403 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3409 scsi_low_msginfunc_simple_qtag(slp)
3410 struct scsi_low_softc *slp;
3412 struct targ_info *ti = slp->sl_Tnexus;
3413 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3415 if (slp->sl_Qnexus != NULL)
3417 if (slp->sl_Qnexus->ccb_tag != etag)
3419 slp->sl_error |= FATALIO;
3420 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3421 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3424 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3426 #ifdef SCSI_LOW_DEBUG
3427 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3429 #endif /* SCSI_LOW_DEBUG */
3431 slp->sl_error |= FATALIO;
3432 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3433 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3439 scsi_low_msginfunc_i_wide_residue(slp)
3440 struct scsi_low_softc *slp;
3442 struct targ_info *ti = slp->sl_Tnexus;
3443 struct slccb *cb = slp->sl_Qnexus;
3444 int res = (int) ti->ti_msgin[1];
3446 if (cb == NULL || res <= 0 ||
3447 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3448 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3451 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3454 slp->sl_scp.scp_datalen += res;
3455 slp->sl_scp.scp_data -= res;
3456 scsi_low_data_finish(slp);
3461 scsi_low_msginfunc_ext(slp)
3462 struct scsi_low_softc *slp;
3464 struct slccb *cb = slp->sl_Qnexus;
3465 struct lun_info *li = slp->sl_Lnexus;
3466 struct targ_info *ti = slp->sl_Tnexus;
3470 if (ti->ti_msginptr == 2)
3472 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3476 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3478 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3482 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3483 count = (int) htonl((long) (*ptr));
3484 if(slp->sl_scp.scp_datalen - count < 0 ||
3485 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3488 slp->sl_scp.scp_datalen -= count;
3489 slp->sl_scp.scp_data += count;
3492 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3496 retry = scsi_low_synch(slp);
3497 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3498 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3500 #ifdef SCSI_LOW_DEBUG
3501 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3503 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3505 #endif /* SCSI_LOW_DEBUG */
3508 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3512 retry = scsi_low_wide(slp);
3513 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3514 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3522 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3527 scsi_low_msginfunc_parity(slp)
3528 struct scsi_low_softc *slp;
3530 struct targ_info *ti = slp->sl_Tnexus;
3532 /* only I -> T, invalid! */
3533 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3538 scsi_low_msginfunc_msg_reject(slp)
3539 struct scsi_low_softc *slp;
3541 struct targ_info *ti = slp->sl_Tnexus;
3542 struct scsi_low_msgout_data *mdp;
3545 if (ti->ti_emsgflags != 0)
3547 printf("%s: msg flags [0x%x] rejected\n",
3548 slp->sl_xname, ti->ti_emsgflags);
3549 msgflags = SCSI_LOW_MSG_REJECT;
3550 mdp = &scsi_low_msgout_data[0];
3551 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3553 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3555 ti->ti_emsgflags &= ~mdp->md_flags;
3556 if (mdp->md_errfunc != NULL)
3557 (*mdp->md_errfunc) (slp, msgflags);
3565 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3566 slp->sl_error |= MSGERR;
3572 scsi_low_msgin(slp, ti, c)
3573 struct scsi_low_softc *slp;
3574 struct targ_info *ti;
3577 struct scsi_low_msgin_data *sdp;
3578 struct lun_info *li;
3581 #ifdef SCSI_LOW_DIAGNOSTIC
3582 if (ti != slp->sl_Tnexus)
3584 scsi_low_print(slp, NULL);
3585 panic("scsi_low_msgin: Target nexus inconsistent");
3587 #endif /* SCSI_LOW_DIAGNOSTIC */
3590 * Phase changes, clear the pointer.
3592 if (ti->ti_ophase != ti->ti_phase)
3595 ti->ti_msgin_parity_error = 0;
3597 slp->sl_ph_count ++;
3598 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3600 printf("%s: too many phase changes\n", slp->sl_xname);
3601 slp->sl_error |= FATALIO;
3602 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3607 * Store a current messages byte into buffer and
3608 * wait for the completion of the current msg.
3610 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3611 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3613 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3614 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3618 * Check parity errors.
3620 if ((c & SCSI_LOW_DATA_PE) != 0)
3622 ti->ti_msgin_parity_error ++;
3623 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3627 if (ti->ti_msgin_parity_error != 0)
3631 * Calculate messages length.
3633 msg = ti->ti_msgin[0];
3634 if (msg < MSGIN_DATA_LAST)
3635 sdp = &scsi_low_msgin_data[msg];
3637 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3639 if (ti->ti_msginlen == 0)
3641 ti->ti_msginlen = sdp->md_len;
3647 if (ti->ti_msginptr < ti->ti_msginlen)
3653 if ((msg & MSG_IDENTIFY) == 0)
3655 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3660 li = slp->sl_Lnexus;
3663 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3666 slp->sl_Lnexus = li;
3667 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3671 if (MSGCMD_LUN(msg) != li->li_lun)
3675 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3677 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3679 #ifdef SCSI_LOW_DEBUG
3680 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3684 #endif /* SCSI_LOW_DEBUG */
3692 * Msg process completed, reset msgin pointer and assert ATN if desired.
3695 slp->sl_error |= FATALIO;
3696 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3697 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3700 if (ti->ti_msginptr < ti->ti_msginlen)
3703 #ifdef SCSI_LOW_DIAGNOSTIC
3704 scsi_low_msg_log_write(&ti->ti_log_msgin,
3705 &ti->ti_msgin[0], ti->ti_msginlen);
3706 #endif /* SCSI_LOW_DIAGNOSTIC */
3712 /**********************************************************
3714 **********************************************************/
3716 scsi_low_disconnected(slp, ti)
3717 struct scsi_low_softc *slp;
3718 struct targ_info *ti;
3720 struct slccb *cb = slp->sl_Qnexus;
3722 /* check phase completion */
3723 switch (slp->sl_msgphase)
3726 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3727 scsi_low_msginfunc_cc(slp);
3728 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3732 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3733 scsi_low_msginfunc_cc(slp);
3734 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3738 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3739 scsi_low_msginfunc_cc(slp);
3745 struct lun_info *li;
3748 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3749 cb->ccb_flags |= CCB_DISCQ;
3750 cb->ccb_error |= slp->sl_error;
3756 #ifdef SCSI_LOW_STATICS
3757 scsi_low_statics.nexus_disconnected ++;
3758 #endif /* SCSI_LOW_STATICS */
3760 #ifdef SCSI_LOW_DEBUG
3761 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3763 printf("## SCSI_LOW_DISCONNECTED ===============\n");
3764 scsi_low_print(slp, NULL);
3766 #endif /* SCSI_LOW_DEBUG */
3770 slp->sl_error |= FATALIO;
3771 if (ti->ti_phase == PH_SELSTART)
3772 slp->sl_error |= SELTIMEOUTIO;
3774 slp->sl_error |= UBFERR;
3783 #ifdef SCSI_LOW_DEBUG
3784 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3786 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3787 (cb->ccb_msgoutflag != 0 ||
3788 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3790 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3793 #endif /* SCSI_LOW_DEBUG */
3795 cb->ccb_error |= slp->sl_error;
3796 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3798 cb->ccb_flags |= CCB_STARTQ;
3799 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3804 scsi_low_bus_release(slp, ti);
3805 scsi_low_start(slp);
3809 /**********************************************************
3811 **********************************************************/
3813 scsi_low_alloc_qtag(cb)
3816 struct lun_info *li = cb->li;
3817 scsi_low_tag_t etag;
3819 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3822 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3823 etag = ffs(li->li_qtagbits);
3827 li->li_qtagbits &= ~(1 << (etag - 1));
3828 cb->ccb_otag = etag;
3831 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3832 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3833 if (li->li_qtagarray[li->li_qd] == 0)
3836 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3837 if (li->li_qtagarray[li->li_qd] == 0)
3843 li->li_qtagarray[li->li_qd] ++;
3844 cb->ccb_otag = (li->li_qd ++);
3846 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3850 scsi_low_dealloc_qtag(cb)
3853 struct lun_info *li = cb->li;
3854 scsi_low_tag_t etag;
3856 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3859 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3860 etag = cb->ccb_otag - 1;
3861 #ifdef SCSI_LOW_DIAGNOSTIC
3862 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3863 panic("scsi_low_dealloc_tag: illegal tag");
3864 #endif /* SCSI_LOW_DIAGNOSTIC */
3865 li->li_qtagbits |= (1 << etag);
3867 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3868 etag = cb->ccb_otag;
3869 #ifdef SCSI_LOW_DIAGNOSTIC
3870 if (etag >= SCSI_LOW_MAXNEXUS)
3871 panic("scsi_low_dealloc_tag: illegal tag");
3872 #endif /* SCSI_LOW_DIAGNOSTIC */
3873 li->li_qtagarray[etag] --;
3874 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3876 cb->ccb_otag = SCSI_LOW_UNKTAG;
3881 scsi_low_revoke_ccb(slp, cb, fdone)
3882 struct scsi_low_softc *slp;
3886 struct targ_info *ti = cb->ti;
3887 struct lun_info *li = cb->li;
3889 #ifdef SCSI_LOW_DIAGNOSTIC
3890 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3891 (CCB_STARTQ | CCB_DISCQ))
3893 panic("%s: ccb in both queue", slp->sl_xname);
3895 #endif /* SCSI_LOW_DIAGNOSTIC */
3897 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3899 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3902 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3904 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3910 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3911 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3914 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3915 (cb->ccb_flags & CCB_NORETRY) != 0))
3917 cb->ccb_error |= FATALIO;
3918 cb->ccb_flags &= ~CCB_AUTOSENSE;
3919 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3920 panic("%s: done ccb retried", slp->sl_xname);
3925 cb->ccb_error |= PENDINGIO;
3926 scsi_low_deactivate_qtag(cb);
3927 scsi_low_ccb_message_retry(cb);
3928 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3934 scsi_low_reset_nexus_lun(slp, li, fdone)
3935 struct scsi_low_softc *slp;
3936 struct lun_info *li;
3939 struct slccb *cb, *ncb, *ecb;
3945 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3947 ncb = TAILQ_NEXT(cb, ccb_chain);
3948 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3952 * presumely keep ordering of io
3954 cb->ccb_flags |= CCB_STARTQ;
3957 TAILQ_INSERT_HEAD(&slp->sl_start,\
3962 TAILQ_INSERT_AFTER(&slp->sl_start,\
3963 ecb, cb, ccb_chain);
3970 /**************************************************************
3972 **************************************************************/
3974 scsi_low_calcf_lun(li)
3975 struct lun_info *li;
3977 struct targ_info *ti = li->li_ti;
3978 struct scsi_low_softc *slp = ti->ti_sc;
3979 u_int cfgflags, diskflags;
3981 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3982 cfgflags = li->li_cfgflags;
3986 diskflags = li->li_diskflags & li->li_quirks;
3989 li->li_flags &= ~SCSI_LOW_DISC;
3990 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3991 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3992 (cfgflags & SCSI_LOW_DISC) != 0)
3993 li->li_flags |= SCSI_LOW_DISC;
3996 li->li_flags |= SCSI_LOW_NOPARITY;
3997 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3998 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3999 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4000 li->li_flags &= ~SCSI_LOW_NOPARITY;
4003 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4004 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4005 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4007 li->li_flags |= SCSI_LOW_QTAG;
4008 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4009 li->li_maxnqio = li->li_maxnexus;
4013 li->li_flags &= ~SCSI_LOW_QTAG;
4014 li->li_maxnexus = 0;
4015 li->li_maxnqio = li->li_maxnexus;
4019 li->li_flags &= ~SCSI_LOW_LINK;
4020 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4021 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4022 li->li_flags |= SCSI_LOW_LINK;
4024 /* compatible flags */
4025 li->li_flags &= ~SCSI_LOW_SYNC;
4026 if (ti->ti_maxsynch.offset > 0)
4027 li->li_flags |= SCSI_LOW_SYNC;
4029 #ifdef SCSI_LOW_DEBUG
4030 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4032 scsi_low_calcf_show(li);
4034 #endif /* SCSI_LOW_DEBUG */
4038 scsi_low_calcf_target(ti)
4039 struct targ_info *ti;
4041 struct scsi_low_softc *slp = ti->ti_sc;
4042 u_int offset, period, diskflags;
4044 diskflags = ti->ti_diskflags & ti->ti_quirks;
4047 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4048 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4050 offset = ti->ti_maxsynch.offset;
4051 period = ti->ti_maxsynch.period;
4052 if (offset == 0 || period == 0)
4053 offset = period = 0;
4057 offset = period = 0;
4060 ti->ti_maxsynch.offset = offset;
4061 ti->ti_maxsynch.period = period;
4064 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4065 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4066 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4068 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4069 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4070 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4072 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4074 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4075 ti->ti_maxsynch.period != ti->ti_osynch.period)
4076 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4077 if (ti->ti_width != ti->ti_owidth)
4078 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4080 ti->ti_osynch = ti->ti_maxsynch;
4081 ti->ti_owidth = ti->ti_width;
4084 #ifdef SCSI_LOW_DEBUG
4085 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4087 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4088 slp->sl_xname, ti->ti_id,
4089 ti->ti_maxsynch.period * 4,
4090 ti->ti_maxsynch.offset,
4093 #endif /* SCSI_LOW_DEBUG */
4097 scsi_low_calcf_show(li)
4098 struct lun_info *li;
4100 struct targ_info *ti = li->li_ti;
4101 struct scsi_low_softc *slp = ti->ti_sc;
4103 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4104 slp->sl_xname, ti->ti_id, li->li_lun,
4105 ti->ti_maxsynch.period * 4,
4106 ti->ti_maxsynch.offset,
4108 li->li_flags, SCSI_LOW_BITS);
4111 #ifdef SCSI_LOW_START_UP_CHECK
4112 /**************************************************************
4113 * scsi world start up
4114 **************************************************************/
4115 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
4118 scsi_low_start_up(slp)
4119 struct scsi_low_softc *slp;
4121 struct targ_info *ti;
4122 struct lun_info *li;
4126 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4128 for (target = 0; target < slp->sl_ntargs; target ++)
4130 if (target == slp->sl_hostid)
4132 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4134 printf("%s: scsi_low: target %d (host card)\n",
4135 slp->sl_xname, target);
4140 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4142 printf("%s: scsi_low: target %d lun ",
4143 slp->sl_xname, target);
4146 ti = slp->sl_ti[target];
4147 for (lun = 0; lun < slp->sl_nluns; lun ++)
4149 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4155 li = scsi_low_alloc_li(ti, lun, 1);
4157 scsi_low_enqueue(slp, ti, li, cb,
4158 CCB_AUTOSENSE | CCB_POLLED, 0);
4160 scsi_low_poll(slp, cb);
4162 if (li->li_state != SCSI_LOW_LUN_OK)
4165 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4171 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4180 scsi_low_poll(slp, cb)
4181 struct scsi_low_softc *slp;
4187 while (slp->sl_nio > 0)
4189 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4191 (*slp->sl_funcs->scsi_low_poll) (slp);
4192 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4196 scsi_low_timeout_check(slp);
4201 #endif /* SCSI_LOW_START_UP_CHECK */
4203 /**********************************************************
4205 **********************************************************/
4206 #ifdef SCSI_LOW_DEBUG
4208 scsi_low_test_abort(slp, ti, li)
4209 struct scsi_low_softc *slp;
4210 struct targ_info *ti;
4211 struct lun_info *li;
4215 if (li->li_disc > 1)
4217 acb = TAILQ_FIRST(&li->li_discq);
4218 if (scsi_low_abort_ccb(slp, acb) == 0)
4220 printf("%s: aborting ccb(0x%lx) start\n",
4221 slp->sl_xname, (u_long) acb);
4227 scsi_low_test_atten(slp, ti, msg)
4228 struct scsi_low_softc *slp;
4229 struct targ_info *ti;
4233 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4234 scsi_low_assert_msg(slp, ti, msg, 0);
4236 printf("%s: atten check OK\n", slp->sl_xname);
4240 scsi_low_test_cmdlnk(slp, cb)
4241 struct scsi_low_softc *slp;
4244 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4246 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4249 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4250 slp->sl_scp.scp_cmdlen);
4251 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4252 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4254 #endif /* SCSI_LOW_DEBUG */
4257 scsi_low_info(slp, ti, s)
4258 struct scsi_low_softc *slp;
4259 struct targ_info *ti;
4264 slp = LIST_FIRST(&sl_tab);
4268 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4271 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4272 ti = TAILQ_NEXT(ti, ti_chain))
4274 scsi_low_print(slp, ti);
4279 scsi_low_print(slp, ti);
4283 static u_char *phase[] =
4285 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4286 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4290 scsi_low_print(slp, ti)
4291 struct scsi_low_softc *slp;
4292 struct targ_info *ti;
4294 struct lun_info *li;
4298 if (ti == NULL || ti == slp->sl_Tnexus)
4300 ti = slp->sl_Tnexus;
4301 li = slp->sl_Lnexus;
4302 cb = slp->sl_Qnexus;
4306 li = LIST_FIRST(&ti->ti_litab);
4307 cb = TAILQ_FIRST(&li->li_discq);
4311 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4312 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4318 u_int flags = 0, maxnqio = 0, nqio = 0;
4324 flags = li->li_flags;
4325 maxnqio = li->li_maxnqio;
4329 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4331 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4332 phase[(int) ti->ti_phase], ti->ti_disc,
4337 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4338 (u_int) cb->ccb_scp.scp_cmd[0],
4339 cb->ccb_scp.scp_cmdlen,
4341 cb->ccb_scp.scp_datalen,
4342 (u_int) cb->ccb_sscp.scp_status,
4343 cb->ccb_error, SCSI_LOW_ERRORBITS);
4346 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4347 (u_int) (ti->ti_msginptr),
4348 (u_int) (ti->ti_msgin[0]),
4349 (u_int) (ti->ti_msgin[1]),
4350 (u_int) (ti->ti_msgin[2]),
4351 (u_int) (ti->ti_msgin[3]),
4352 (u_int) (ti->ti_msgin[4]),
4355 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4356 (u_int) ti->ti_msgflags,
4357 (u_int) (ti->ti_msgoutstr[0]),
4358 (u_int) (ti->ti_msgoutstr[1]),
4359 (u_int) (ti->ti_msgoutstr[2]),
4360 (u_int) (ti->ti_msgoutstr[3]),
4361 (u_int) (ti->ti_msgoutstr[4]),
4363 flags, SCSI_LOW_BITS);
4365 #ifdef SCSI_LOW_DIAGNOSTIC
4366 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4367 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4368 #endif /* SCSI_LOW_DIAGNOSTIC */
4372 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4373 (u_long) sp->scp_data,
4375 (u_int) sp->scp_status,
4376 slp->sl_error, SCSI_LOW_ERRORBITS);