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.13 2005/06/02 20:40:31 dillon 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>
73 #include <sys/thread2.h>
75 #include <bus/cam/cam.h>
76 #include <bus/cam/cam_ccb.h>
77 #include <bus/cam/cam_sim.h>
78 #include <bus/cam/cam_debug.h>
79 #include <bus/cam/cam_periph.h>
81 #include <bus/cam/scsi/scsi_all.h>
82 #include <bus/cam/scsi/scsi_message.h>
83 #include <bus/cam/scsi/scsi_low.h>
85 /**************************************************************
87 **************************************************************/
88 #define SCSI_LOW_POLL_HZ 1000
90 /* functions return values */
91 #define SCSI_LOW_START_NO_QTAG 0
92 #define SCSI_LOW_START_QTAG 1
94 #define SCSI_LOW_DONE_COMPLETE 0
95 #define SCSI_LOW_DONE_RETRY 1
97 /* internal disk flags */
98 #define SCSI_LOW_DISK_DISC 0x00000001
99 #define SCSI_LOW_DISK_QTAG 0x00000002
100 #define SCSI_LOW_DISK_LINK 0x00000004
101 #define SCSI_LOW_DISK_PARITY 0x00000008
102 #define SCSI_LOW_DISK_SYNC 0x00010000
103 #define SCSI_LOW_DISK_WIDE_16 0x00020000
104 #define SCSI_LOW_DISK_WIDE_32 0x00040000
105 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
106 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
107 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
109 /**************************************************************
111 **************************************************************/
112 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
113 static void scsi_low_engage (void *);
114 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
115 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
116 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
117 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
118 static void scsi_low_twiddle_wait (void);
119 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
120 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
121 static void scsi_low_calcf_lun (struct lun_info *);
122 static void scsi_low_calcf_target (struct targ_info *);
123 static void scsi_low_calcf_show (struct lun_info *);
124 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
125 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
126 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
127 static int scsi_low_init (struct scsi_low_softc *, u_int);
128 static void scsi_low_start (struct scsi_low_softc *);
129 static void scsi_low_free_ti (struct scsi_low_softc *);
131 static int scsi_low_alloc_qtag (struct slccb *);
132 static int scsi_low_dealloc_qtag (struct slccb *);
133 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
134 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
135 static void scsi_low_unit_ready_cmd (struct slccb *);
136 static void scsi_low_timeout (void *);
137 static int scsi_low_timeout_check (struct scsi_low_softc *);
138 #ifdef SCSI_LOW_START_UP_CHECK
139 static int scsi_low_start_up (struct scsi_low_softc *);
140 #endif /* SCSI_LOW_START_UP_CHECK */
141 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
142 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
144 int scsi_low_version_major = 2;
145 int scsi_low_version_minor = 17;
147 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
149 /**************************************************************
150 * Debug, Run test and Statics
151 **************************************************************/
152 #ifdef SCSI_LOW_INFO_DETAIL
153 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
154 #else /* !SCSI_LOW_INFO_DETAIL */
155 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
156 #endif /* !SCSI_LOW_INFO_DETAIL */
158 #ifdef SCSI_LOW_STATICS
159 struct scsi_low_statics {
162 int nexus_disconnected;
163 int nexus_reselected;
166 #endif /* SCSI_LOW_STATICS */
168 #ifdef SCSI_LOW_DEBUG
169 #define SCSI_LOW_DEBUG_DONE 0x00001
170 #define SCSI_LOW_DEBUG_DISC 0x00002
171 #define SCSI_LOW_DEBUG_SENSE 0x00004
172 #define SCSI_LOW_DEBUG_CALCF 0x00008
173 #define SCSI_LOW_DEBUG_ACTION 0x10000
174 int scsi_low_debug = 0;
176 #define SCSI_LOW_MAX_ATTEN_CHECK 32
177 #define SCSI_LOW_ATTEN_CHECK 0x0001
178 #define SCSI_LOW_CMDLNK_CHECK 0x0002
179 #define SCSI_LOW_ABORT_CHECK 0x0004
180 #define SCSI_LOW_NEXUS_CHECK 0x0008
181 int scsi_low_test = 0;
182 int scsi_low_test_id = 0;
184 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
185 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
186 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
187 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
188 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
189 #define SCSI_LOW_DEBUG_GO(fl, id) \
190 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
191 #endif /* SCSI_LOW_DEBUG */
193 /**************************************************************
195 **************************************************************/
196 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
197 GENERIC_CCB(scsi_low, slccb, ccb_chain)
199 /**************************************************************
201 **************************************************************/
202 #define SCSI_LOW_INLINE static __inline
203 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
204 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
205 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
206 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
207 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
208 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
209 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
212 scsi_low_activate_qtag(cb)
215 struct lun_info *li = cb->li;
217 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
221 cb->ccb_tag = cb->ccb_otag;
225 scsi_low_deactivate_qtag(cb)
228 struct lun_info *li = cb->li;
230 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
234 cb->ccb_tag = SCSI_LOW_UNKTAG;
238 scsi_low_ccb_message_exec(slp, cb)
239 struct scsi_low_softc *slp;
243 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
244 cb->ccb_msgoutflag = 0;
248 scsi_low_ccb_message_assert(cb, msg)
253 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
257 scsi_low_ccb_message_retry(cb)
260 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
264 scsi_low_ccb_message_clear(cb)
267 cb->ccb_msgoutflag = 0;
271 scsi_low_init_msgsys(slp, ti)
272 struct scsi_low_softc *slp;
273 struct targ_info *ti;
277 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
278 SCSI_LOW_DEASSERT_ATN(slp);
279 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
282 /*=============================================================
283 * START OF OS switch (All OS depend fucntions should be here)
284 =============================================================*/
285 /* common os depend utitlities */
286 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
287 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
288 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
290 static u_int8_t scsi_low_cmd_flags[256] = {
291 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
292 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
293 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
294 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
295 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
298 struct scsi_low_error_code {
303 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
304 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
306 static struct slccb *
307 scsi_low_find_ccb(slp, target, lun, osdep)
308 struct scsi_low_softc *slp;
312 struct targ_info *ti;
316 ti = slp->sl_ti[target];
317 li = scsi_low_alloc_li(ti, lun, 0);
321 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
324 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
325 cb = TAILQ_NEXT(cb, ccb_chain))
327 if (cb->osdep == osdep)
331 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
332 cb = TAILQ_NEXT(cb, ccb_chain))
334 if (cb->osdep == osdep)
341 scsi_low_translate_error_code(cb, tp)
343 struct scsi_low_error_code *tp;
346 if (cb->ccb_error == 0)
347 return tp->error_code;
349 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
351 return tp->error_code;
354 /**************************************************************
355 * SCSI INTERFACE (CAM)
356 **************************************************************/
357 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_INTWAIT)
358 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
359 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
361 static void scsi_low_poll_cam (struct cam_sim *);
362 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
363 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
364 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
366 static int scsi_low_attach_cam (struct scsi_low_softc *);
367 static int scsi_low_world_start_cam (struct scsi_low_softc *);
368 static int scsi_low_dettach_cam (struct scsi_low_softc *);
369 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
370 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
371 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
373 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
375 scsi_low_world_start_cam,
376 scsi_low_dettach_cam,
377 scsi_low_ccb_setup_cam,
382 struct scsi_low_error_code scsi_low_error_code_cam[] = {
384 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
385 {SENSEERR, CAM_AUTOSENSE_FAIL},
386 {UACAERR, CAM_SCSI_STATUS_ERROR},
387 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
388 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
389 {TIMEOUTIO, CAM_CMD_TIMEOUT},
390 {PDMAERR, CAM_DATA_RUN_ERR},
391 {PARITYERR, CAM_UNCOR_PARITY},
392 {UBFERR, CAM_UNEXP_BUSFREE},
393 {ABORTIO, CAM_REQ_ABORTED},
394 {-1, CAM_UNREC_HBA_ERROR}
397 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
400 * Please check a polling hz, currently we assume scsi_low_poll() is
403 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
406 scsi_low_poll_cam(sim)
409 struct scsi_low_softc *slp = SIM2SLP(sim);
411 (*slp->sl_funcs->scsi_low_poll) (slp);
413 if (slp->sl_si.si_poll_count ++ >=
414 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
416 slp->sl_si.si_poll_count = 0;
417 scsi_low_timeout_check(slp);
422 scsi_low_cam_rescan_callback(periph, ccb)
423 struct cam_periph *periph;
427 xpt_free_path(ccb->ccb_h.path);
432 scsi_low_rescan_bus_cam(slp)
433 struct scsi_low_softc *slp;
435 struct cam_path *path;
436 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_INTWAIT | M_ZERO);
439 status = xpt_create_path(&path, xpt_periph,
440 cam_sim_path(slp->sl_si.sim), -1, 0);
441 if (status != CAM_REQ_CMP)
444 xpt_setup_ccb(&ccb->ccb_h, path, 5);
445 ccb->ccb_h.func_code = XPT_SCAN_BUS;
446 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
447 ccb->crcn.flags = CAM_FLAG_NONE;
452 scsi_low_scsi_action_cam(sim, ccb)
456 struct scsi_low_softc *slp = SIM2SLP(sim);
457 struct targ_info *ti;
460 u_int lun, flags, msg, target;
463 target = (u_int) (ccb->ccb_h.target_id);
464 lun = (u_int) ccb->ccb_h.target_lun;
466 #ifdef SCSI_LOW_DEBUG
467 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
469 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
470 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
472 #endif /* SCSI_LOW_DEBUG */
474 switch (ccb->ccb_h.func_code) {
475 case XPT_SCSI_IO: /* Execute the requested I/O operation */
476 #ifdef SCSI_LOW_DIAGNOSTIC
477 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
479 printf("%s: invalid target/lun\n", slp->sl_xname);
480 ccb->ccb_h.status = CAM_REQ_INVALID;
484 #endif /* SCSI_LOW_DIAGNOSTIC */
486 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
487 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
492 ti = slp->sl_ti[target];
495 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
496 flags = CCB_AUTOSENSE | CCB_SCSIIO;
501 li = scsi_low_alloc_li(ti, lun, 1);
503 if (ti->ti_setup_msg != 0)
505 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
508 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
510 #ifdef SCSI_LOW_DEBUG
511 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
513 scsi_low_test_abort(slp, ti, li);
515 #endif /* SCSI_LOW_DEBUG */
519 case XPT_EN_LUN: /* Enable LUN as a target */
520 case XPT_TARGET_IO: /* Execute target I/O request */
521 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
522 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
524 ccb->ccb_h.status = CAM_REQ_INVALID;
528 case XPT_ABORT: /* Abort the specified CCB */
529 #ifdef SCSI_LOW_DIAGNOSTIC
530 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
532 printf("%s: invalid target/lun\n", slp->sl_xname);
533 ccb->ccb_h.status = CAM_REQ_INVALID;
537 #endif /* SCSI_LOW_DIAGNOSTIC */
540 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
541 rv = scsi_low_abort_ccb(slp, cb);
545 ccb->ccb_h.status = CAM_REQ_CMP;
547 ccb->ccb_h.status = CAM_REQ_INVALID;
551 case XPT_SET_TRAN_SETTINGS: {
552 struct ccb_trans_settings *cts;
555 #ifdef SCSI_LOW_DIAGNOSTIC
556 if (target == CAM_TARGET_WILDCARD)
558 printf("%s: invalid target\n", slp->sl_xname);
559 ccb->ccb_h.status = CAM_REQ_INVALID;
563 #endif /* SCSI_LOW_DIAGNOSTIC */
565 ti = slp->sl_ti[target];
566 if (lun == CAM_LUN_WILDCARD)
570 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
571 CCB_TRANS_SYNC_RATE_VALID |
572 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
574 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
575 val = cts->bus_width;
576 if (val < ti->ti_width)
579 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
580 val = cts->sync_period;
581 if (val == 0 || val > ti->ti_maxsynch.period)
582 ti->ti_maxsynch.period = val;
584 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
585 val = cts->sync_offset;
586 if (val < ti->ti_maxsynch.offset)
587 ti->ti_maxsynch.offset = val;
590 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
591 scsi_low_calcf_target(ti);
594 if ((cts->valid & (CCB_TRANS_DISC_VALID |
595 CCB_TRANS_TQ_VALID)) != 0)
597 li = scsi_low_alloc_li(ti, lun, 1);
598 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
600 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
601 li->li_quirks |= SCSI_LOW_DISK_DISC;
603 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
605 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
607 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
608 li->li_quirks |= SCSI_LOW_DISK_QTAG;
610 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
613 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
614 scsi_low_calcf_target(ti);
615 scsi_low_calcf_lun(li);
616 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
617 scsi_low_calcf_show(li);
621 ccb->ccb_h.status = CAM_REQ_CMP;
626 case XPT_GET_TRAN_SETTINGS: {
627 struct ccb_trans_settings *cts;
631 #ifdef SCSI_LOW_DIAGNOSTIC
632 if (target == CAM_TARGET_WILDCARD)
634 printf("%s: invalid target\n", slp->sl_xname);
635 ccb->ccb_h.status = CAM_REQ_INVALID;
639 #endif /* SCSI_LOW_DIAGNOSTIC */
640 ti = slp->sl_ti[target];
641 if (lun == CAM_LUN_WILDCARD)
645 li = scsi_low_alloc_li(ti, lun, 1);
646 #ifdef CAM_NEW_TRAN_CODE
647 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
648 struct ccb_trans_settings_scsi *scsi =
649 &cts->proto_specific.scsi;
650 struct ccb_trans_settings_spi *spi =
651 &cts->xport_specific.spi;
652 #ifdef SCSI_LOW_DIAGNOSTIC
653 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
655 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
656 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
660 #endif /* SCSI_LOW_DIAGNOSTIC */
661 cts->protocol = PROTO_SCSI;
662 cts->protocol_version = SCSI_REV_2;
663 cts->transport = XPORT_SPI;
664 cts->transport_version = 2;
666 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
667 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
669 diskflags = li->li_diskflags & li->li_cfgflags;
670 if (diskflags & SCSI_LOW_DISK_DISC)
671 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
672 if (diskflags & SCSI_LOW_DISK_QTAG)
673 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
675 spi->sync_period = ti->ti_maxsynch.period;
676 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
677 spi->sync_offset = ti->ti_maxsynch.offset;
678 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
680 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
681 spi->bus_width = ti->ti_width;
683 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
684 scsi->valid = CTS_SCSI_VALID_TQ;
685 spi->valid |= CTS_SPI_VALID_DISC;
689 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
691 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
693 #ifdef SCSI_LOW_DIAGNOSTIC
694 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
696 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
697 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
701 #endif /* SCSI_LOW_DIAGNOSTIC */
702 diskflags = li->li_diskflags & li->li_cfgflags;
703 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
704 cts->flags |= CCB_TRANS_DISC_ENB;
706 cts->flags &= ~CCB_TRANS_DISC_ENB;
707 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
708 cts->flags |= CCB_TRANS_TAG_ENB;
710 cts->flags &= ~CCB_TRANS_TAG_ENB;
712 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
714 #ifdef SCSI_LOW_DIAGNOSTIC
715 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
717 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
718 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
722 #endif /* SCSI_LOW_DIAGNOSTIC */
723 if ((li->li_flags & SCSI_LOW_DISC) != 0)
724 cts->flags |= CCB_TRANS_DISC_ENB;
726 cts->flags &= ~CCB_TRANS_DISC_ENB;
727 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
728 cts->flags |= CCB_TRANS_TAG_ENB;
730 cts->flags &= ~CCB_TRANS_TAG_ENB;
734 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
738 cts->sync_period = ti->ti_maxsynch.period;
739 cts->sync_offset = ti->ti_maxsynch.offset;
740 cts->bus_width = ti->ti_width;
742 cts->valid = CCB_TRANS_SYNC_RATE_VALID
743 | CCB_TRANS_SYNC_OFFSET_VALID
744 | CCB_TRANS_BUS_WIDTH_VALID
745 | CCB_TRANS_DISC_VALID
746 | CCB_TRANS_TQ_VALID;
747 ccb->ccb_h.status = CAM_REQ_CMP;
755 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
756 cam_calc_geometry(&ccb->ccg, /*extended*/1);
761 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
763 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
765 ccb->ccb_h.status = CAM_REQ_CMP;
769 case XPT_TERM_IO: /* Terminate the I/O process */
770 ccb->ccb_h.status = CAM_REQ_INVALID;
774 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
775 #ifdef SCSI_LOW_DIAGNOSTIC
776 if (target == CAM_TARGET_WILDCARD)
778 printf("%s: invalid target\n", slp->sl_xname);
779 ccb->ccb_h.status = CAM_REQ_INVALID;
783 #endif /* SCSI_LOW_DIAGNOSTIC */
785 msg = SCSI_LOW_MSG_RESET;
786 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
788 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
793 ti = slp->sl_ti[target];
794 if (lun == CAM_LUN_WILDCARD)
798 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
799 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
801 flags = CCB_NORETRY | CCB_URGENT;
804 li = scsi_low_alloc_li(ti, lun, 1);
805 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
809 case XPT_PATH_INQ: { /* Path routing inquiry */
810 struct ccb_pathinq *cpi = &ccb->cpi;
812 cpi->version_num = scsi_low_version_major;
813 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
814 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
815 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
816 cpi->hba_inquiry |= PI_WIDE_16;
817 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
818 cpi->hba_inquiry |= PI_WIDE_32;
819 if (ti->ti_maxsynch.offset > 0)
820 cpi->hba_inquiry |= PI_SDTR_ABLE;
821 cpi->target_sprt = 0;
823 cpi->hba_eng_cnt = 0;
824 cpi->max_target = slp->sl_ntargs - 1;
825 cpi->max_lun = slp->sl_nluns - 1;
826 cpi->initiator_id = slp->sl_hostid;
827 cpi->bus_id = cam_sim_bus(sim);
828 cpi->base_transfer_speed = 3300;
829 #ifdef CAM_NEW_TRAN_CODE
830 cpi->transport = XPORT_SPI;
831 cpi->transport_version = 2;
832 cpi->protocol = PROTO_SCSI;
833 cpi->protocol_version = SCSI_REV_2;
835 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
836 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
837 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
838 cpi->unit_number = cam_sim_unit(sim);
839 cpi->ccb_h.status = CAM_REQ_CMP;
845 printf("scsi_low: non support func_code = %d ",
846 ccb->ccb_h.func_code);
847 ccb->ccb_h.status = CAM_REQ_INVALID;
854 scsi_low_attach_cam(slp)
855 struct scsi_low_softc *slp;
857 struct cam_devq *devq;
860 sprintf(slp->sl_xname, "%s%d",
861 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
863 devq = cam_simq_alloc(SCSI_LOW_NCCB);
868 * ask the adapter what subunits are present
870 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
871 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
873 DEVPORT_DEVNAME(slp->sl_dev), slp,
874 DEVPORT_DEVUNIT(slp->sl_dev),
875 slp->sl_openings, tagged_openings, devq);
876 cam_simq_release(devq);
877 if (slp->sl_si.sim == NULL) {
881 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
882 cam_sim_free(slp->sl_si.sim);
883 slp->sl_si.sim = NULL;
887 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
888 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
889 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
890 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
891 cam_sim_free(slp->sl_si.sim);
892 slp->sl_si.sim = NULL;
896 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
901 scsi_low_world_start_cam(slp)
902 struct scsi_low_softc *slp;
906 scsi_low_rescan_bus_cam(slp);
911 scsi_low_dettach_cam(slp)
912 struct scsi_low_softc *slp;
915 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
916 xpt_free_path(slp->sl_si.path);
917 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
918 cam_sim_free(slp->sl_si.sim);
919 slp->sl_si.sim = NULL;
924 scsi_low_ccb_setup_cam(slp, cb)
925 struct scsi_low_softc *slp;
928 union ccb *ccb = (union ccb *) cb->osdep;
930 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
932 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
933 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
934 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
935 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
936 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
937 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
938 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
939 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
940 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
944 scsi_low_unit_ready_cmd(cb);
946 return SCSI_LOW_START_QTAG;
950 scsi_low_done_cam(slp, cb)
951 struct scsi_low_softc *slp;
956 ccb = (union ccb *) cb->osdep;
957 if (cb->ccb_error == 0)
959 ccb->ccb_h.status = CAM_REQ_CMP;
964 if (cb->ccb_rcnt >= slp->sl_max_retry)
965 cb->ccb_error |= ABORTIO;
967 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
968 (cb->ccb_error & ABORTIO) == 0)
971 if ((cb->ccb_error & SENSEIO) != 0)
973 memcpy(&ccb->csio.sense_data,
975 sizeof(ccb->csio.sense_data));
978 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
979 &scsi_low_error_code_cam[0]);
981 #ifdef SCSI_LOW_DIAGNOSTIC
982 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
983 cb->ccb_scp.scp_cmdlen > 0 &&
984 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
985 SCSI_LOW_CMD_ABORT_WARNING) != 0)
987 printf("%s: WARNING: scsi_low IO abort\n",
989 scsi_low_print(slp, NULL);
991 #endif /* SCSI_LOW_DIAGNOSTIC */
994 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
995 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
997 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
998 ccb->csio.scsi_status = 0; /* XXX */
1000 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1002 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1008 scsi_low_timeout_cam(slp, ch, action)
1009 struct scsi_low_softc *slp;
1016 case SCSI_LOW_TIMEOUT_CH_IO:
1019 case SCSI_LOW_TIMEOUT_START:
1020 callout_reset(&slp->sl_si.timeout_ch,
1021 hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
1023 case SCSI_LOW_TIMEOUT_STOP:
1024 callout_stop(&slp->sl_si.timeout_ch);
1029 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1032 case SCSI_LOW_TIMEOUT_START:
1033 callout_reset(&slp->sl_si.engage_ch, 1,
1034 scsi_low_engage, slp);
1036 case SCSI_LOW_TIMEOUT_STOP:
1037 callout_stop(&slp->sl_si.engage_ch);
1041 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1046 /**************************************************************
1047 * scsi low deactivate and activate
1048 **************************************************************/
1050 scsi_low_is_busy(slp)
1051 struct scsi_low_softc *slp;
1054 if (slp->sl_nio > 0)
1060 scsi_low_deactivate(slp)
1061 struct scsi_low_softc *slp;
1064 slp->sl_flags |= HW_INACTIVE;
1065 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1066 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1067 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1068 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1074 scsi_low_activate(slp)
1075 struct scsi_low_softc *slp;
1080 slp->sl_flags &= ~HW_INACTIVE;
1081 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1083 slp->sl_flags |= HW_INACTIVE;
1088 slp->sl_timeout_count = 0;
1089 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1090 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1095 /**************************************************************
1097 **************************************************************/
1098 #ifdef SCSI_LOW_DIAGNOSTIC
1099 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1100 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1102 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1105 scsi_low_msg_log_init(slmlp)
1106 struct scsi_low_msg_log *slmlp;
1109 slmlp->slml_ptr = 0;
1113 scsi_low_msg_log_write(slmlp, datap, len)
1114 struct scsi_low_msg_log *slmlp;
1120 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1123 ptr = slmlp->slml_ptr ++;
1124 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1125 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1126 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1127 slmlp->slml_msg[ptr].msg[ind] = 0;
1131 scsi_low_msg_log_show(slmlp, s, len)
1132 struct scsi_low_msg_log *slmlp;
1138 printf("%s: (%d) ", s, slmlp->slml_ptr);
1139 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1141 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1144 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1150 #endif /* SCSI_LOW_DIAGNOSTIC */
1152 /**************************************************************
1154 **************************************************************/
1156 scsi_low_engage(arg)
1159 struct scsi_low_softc *slp = arg;
1163 switch (slp->sl_rstep)
1167 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1168 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1169 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1174 slp->sl_flags &= ~HW_RESUME;
1175 scsi_low_start(slp);
1185 scsi_low_init(slp, flags)
1186 struct scsi_low_softc *slp;
1191 slp->sl_flags |= HW_INITIALIZING;
1193 /* clear power control timeout */
1194 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1196 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1197 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1198 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1200 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1203 /* reset current nexus */
1204 scsi_low_reset_nexus(slp, flags);
1205 if ((slp->sl_flags & HW_INACTIVE) != 0)
1211 if (flags != SCSI_LOW_RESTART_SOFT)
1213 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1217 slp->sl_flags &= ~HW_INITIALIZING;
1221 /**************************************************************
1223 **************************************************************/
1224 static struct lun_info *
1225 scsi_low_alloc_li(ti, lun, alloc)
1226 struct targ_info *ti;
1230 struct scsi_low_softc *slp = ti->ti_sc;
1231 struct lun_info *li;
1233 li = LIST_FIRST(&ti->ti_litab);
1236 if (li->li_lun == lun)
1239 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1241 if (li->li_lun == lun)
1243 LIST_REMOVE(li, lun_chain);
1244 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1253 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1255 panic("no lun info mem");
1257 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1261 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1263 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1264 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1265 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1266 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1267 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1269 li->li_qtagbits = (u_int) -1;
1271 TAILQ_INIT(&li->li_discq);
1272 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1274 /* host specific structure initialization per lun */
1275 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1276 (*slp->sl_funcs->scsi_low_lun_init)
1277 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1278 scsi_low_calcf_lun(li);
1282 /**************************************************************
1283 * allocate targ_info
1284 **************************************************************/
1285 static struct targ_info *
1286 scsi_low_alloc_ti(slp, targ)
1287 struct scsi_low_softc *slp;
1290 struct targ_info *ti;
1292 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1293 TAILQ_INIT(&slp->sl_titab);
1295 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1297 panic("%s short of memory", slp->sl_xname);
1299 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1303 slp->sl_ti[targ] = ti;
1304 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1305 LIST_INIT(&ti->ti_litab);
1307 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1308 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1309 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1310 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1311 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1312 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1314 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1316 (*slp->sl_funcs->scsi_low_targ_init)
1317 (slp, ti, SCSI_LOW_INFO_ALLOC);
1319 scsi_low_calcf_target(ti);
1324 scsi_low_free_ti(slp)
1325 struct scsi_low_softc *slp;
1327 struct targ_info *ti, *tib;
1328 struct lun_info *li, *nli;
1330 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1332 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1334 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1336 (*slp->sl_funcs->scsi_low_lun_init)
1337 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1339 nli = LIST_NEXT(li, lun_chain);
1343 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1345 (*slp->sl_funcs->scsi_low_targ_init)
1346 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1348 tib = TAILQ_NEXT(ti, ti_chain);
1353 /**************************************************************
1355 **************************************************************/
1357 scsi_low_bus_idle(slp)
1358 struct scsi_low_softc *slp;
1361 slp->sl_retry_sel = 0;
1362 if (slp->sl_Tnexus == NULL)
1363 scsi_low_start(slp);
1367 scsi_low_timeout(arg)
1370 struct scsi_low_softc *slp = arg;
1373 (void) scsi_low_timeout_check(slp);
1374 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1375 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1380 scsi_low_timeout_check(slp)
1381 struct scsi_low_softc *slp;
1383 struct targ_info *ti;
1384 struct lun_info *li;
1385 struct slccb *cb = NULL; /* XXX */
1387 /* selection restart */
1388 if (slp->sl_retry_sel != 0)
1390 slp->sl_retry_sel = 0;
1391 if (slp->sl_Tnexus != NULL)
1394 cb = TAILQ_FIRST(&slp->sl_start);
1398 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1400 cb->ccb_flags |= CCB_NORETRY;
1401 cb->ccb_error |= SELTIMEOUTIO;
1402 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1403 panic("%s: ccb not finished", slp->sl_xname);
1406 if (slp->sl_Tnexus == NULL)
1407 scsi_low_start(slp);
1410 /* call hardware timeout */
1412 if (slp->sl_funcs->scsi_low_timeout != NULL)
1414 (*slp->sl_funcs->scsi_low_timeout) (slp);
1417 if (slp->sl_timeout_count ++ <
1418 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1421 slp->sl_timeout_count = 0;
1422 if (slp->sl_nio > 0)
1424 if ((cb = slp->sl_Qnexus) != NULL)
1426 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1430 else if (slp->sl_disc == 0)
1432 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1435 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1439 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1440 ti = TAILQ_NEXT(ti, ti_chain))
1442 if (ti->ti_disc == 0)
1445 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1446 li = LIST_NEXT(li, lun_chain))
1448 for (cb = TAILQ_FIRST(&li->li_discq);
1450 cb = TAILQ_NEXT(cb, ccb_chain))
1453 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1461 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1463 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1466 if (slp->sl_active != 0)
1468 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1474 if (slp->sl_powc < 0)
1476 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1477 slp->sl_flags |= HW_POWDOWN;
1478 (*slp->sl_funcs->scsi_low_power)
1479 (slp, SCSI_LOW_POWDOWN);
1485 cb->ccb_error |= TIMEOUTIO;
1486 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1487 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1488 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1489 scsi_low_start(slp);
1495 scsi_low_abort_ccb(slp, cb)
1496 struct scsi_low_softc *slp;
1499 struct targ_info *ti;
1500 struct lun_info *li;
1505 if ((cb->ccb_omsgoutflag &
1506 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1511 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1512 msg = SCSI_LOW_MSG_ABORT;
1514 msg = SCSI_LOW_MSG_ABORT_QTAG;
1516 cb->ccb_error |= ABORTIO;
1517 cb->ccb_flags |= CCB_NORETRY;
1518 scsi_low_ccb_message_assert(cb, msg);
1520 if (cb == slp->sl_Qnexus)
1522 scsi_low_assert_msg(slp, ti, msg, 1);
1524 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1526 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1527 panic("%s: revoked ccb done", slp->sl_xname);
1529 cb->ccb_flags |= CCB_STARTQ;
1530 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1532 if (slp->sl_Tnexus == NULL)
1533 scsi_low_start(slp);
1537 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1538 panic("%s: revoked ccb retried", slp->sl_xname);
1543 /**************************************************************
1544 * Generic SCSI INTERFACE
1545 **************************************************************/
1547 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
1548 struct scsi_low_softc *slp;
1549 int openings, ntargs, nluns, targsize, lunsize;
1551 struct targ_info *ti;
1552 struct lun_info *li;
1555 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1557 if (slp->sl_osdep_fp == NULL)
1558 panic("scsi_low: interface not spcified");
1560 if (ntargs > SCSI_LOW_NTARGETS)
1562 printf("scsi_low: %d targets are too large\n", ntargs);
1563 printf("change kernel options SCSI_LOW_NTARGETS");
1568 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1570 slp->sl_openings = openings;
1571 slp->sl_ntargs = ntargs;
1572 slp->sl_nluns = nluns;
1573 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1575 if (lunsize < sizeof(struct lun_info))
1576 lunsize = sizeof(struct lun_info);
1578 if (targsize < sizeof(struct targ_info))
1579 targsize = sizeof(struct targ_info);
1581 slp->sl_targsize = targsize;
1582 for (i = 0; i < ntargs; i ++)
1584 ti = scsi_low_alloc_ti(slp, i);
1585 ti->ti_lunsize = lunsize;
1586 li = scsi_low_alloc_li(ti, 0, 1);
1589 /* initialize queue */
1590 nccb = openings * ntargs;
1591 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1592 nccb = SCSI_LOW_NCCB;
1593 scsi_low_init_ccbque(nccb);
1594 TAILQ_INIT(&slp->sl_start);
1596 /* call os depend attach */
1597 callout_init(&slp->sl_si.timeout_ch);
1598 callout_init(&slp->sl_si.engage_ch);
1601 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1605 printf("%s: scsi_low_attach: osdep attach failed\n",
1610 /* check hardware */
1611 SCSI_LOW_DELAY(1000); /* wait for 1ms */
1612 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1615 printf("%s: scsi_low_attach: initialization failed\n",
1620 /* start watch dog */
1621 slp->sl_timeout_count = 0;
1622 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1623 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1624 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1627 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1629 #ifdef SCSI_LOW_START_UP_CHECK
1630 /* probing devices */
1631 scsi_low_start_up(slp);
1632 #endif /* SCSI_LOW_START_UP_CHECK */
1634 /* call os depend attach done*/
1635 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1641 scsi_low_dettach(slp)
1642 struct scsi_low_softc *slp;
1647 if (scsi_low_is_busy(slp) != 0)
1653 scsi_low_deactivate(slp);
1655 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1662 scsi_low_free_ti(slp);
1663 LIST_REMOVE(slp, sl_chain);
1668 /**************************************************************
1670 **************************************************************/
1672 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
1673 struct scsi_low_softc *slp;
1674 struct targ_info *ti;
1675 struct lun_info *li;
1683 scsi_low_ccb_message_assert(cb, msg);
1685 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1686 scsi_low_alloc_qtag(cb);
1688 cb->ccb_flags = flags | CCB_STARTQ;
1689 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1690 cb->ccb_error |= PENDINGIO;
1692 if ((flags & CCB_URGENT) != 0)
1694 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1698 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1703 if (slp->sl_Tnexus == NULL)
1704 scsi_low_start(slp);
1709 scsi_low_message_enqueue(slp, ti, li, flags)
1710 struct scsi_low_softc *slp;
1711 struct targ_info *ti;
1712 struct lun_info *li;
1718 tmsgflags = ti->ti_setup_msg;
1719 ti->ti_setup_msg = 0;
1721 flags |= CCB_NORETRY;
1722 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1727 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1731 /**************************************************************
1732 * Generic Start & Done
1733 **************************************************************/
1734 #define SLSC_MODE_SENSE_SHORT 0x1a
1735 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1736 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1737 sizeof(struct scsi_low_mode_sense_data), 0};
1738 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1739 sizeof(struct scsi_low_inq_data), 0};
1740 static u_int8_t unit_ready_cmd[6];
1741 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1742 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1743 static int scsi_low_resume (struct scsi_low_softc *);
1746 scsi_low_unit_ready_cmd(cb)
1750 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1751 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1752 cb->ccb_scp.scp_datalen = 0;
1753 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1758 scsi_low_sense_abort_start(slp, ti, li, cb)
1759 struct scsi_low_softc *slp;
1760 struct targ_info *ti;
1761 struct lun_info *li;
1765 cb->ccb_scp.scp_cmdlen = 6;
1766 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1767 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1768 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1769 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1770 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1771 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1772 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1774 scsi_low_ccb_message_clear(cb);
1775 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1777 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1781 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1782 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1783 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1784 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1787 return SCSI_LOW_START_NO_QTAG;
1791 scsi_low_setup_start(slp, ti, li, cb)
1792 struct scsi_low_softc *slp;
1793 struct targ_info *ti;
1794 struct lun_info *li;
1798 switch(li->li_state)
1800 case SCSI_LOW_LUN_SLEEP:
1801 scsi_low_unit_ready_cmd(cb);
1804 case SCSI_LOW_LUN_START:
1805 cb->ccb_scp.scp_cmd = ss_cmd;
1806 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1807 cb->ccb_scp.scp_datalen = 0;
1808 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1812 case SCSI_LOW_LUN_INQ:
1813 cb->ccb_scp.scp_cmd = inq_cmd;
1814 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1815 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1816 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1817 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1821 case SCSI_LOW_LUN_MODEQ:
1822 cb->ccb_scp.scp_cmd = sms_cmd;
1823 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1824 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1825 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1826 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1828 return SCSI_LOW_START_QTAG;
1831 panic("%s: no setup phase", slp->sl_xname);
1834 return SCSI_LOW_START_NO_QTAG;
1838 scsi_low_resume(slp)
1839 struct scsi_low_softc *slp;
1842 if (slp->sl_flags & HW_RESUME)
1844 slp->sl_flags &= ~HW_POWDOWN;
1845 if (slp->sl_funcs->scsi_low_power != NULL)
1847 slp->sl_flags |= HW_RESUME;
1849 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1850 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1851 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1852 SCSI_LOW_TIMEOUT_START);
1860 struct scsi_low_softc *slp;
1862 struct targ_info *ti;
1863 struct lun_info *li;
1867 /* check hardware exists or under initializations ? */
1868 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1871 /* check hardware power up ? */
1872 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1875 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1877 if (scsi_low_resume(slp) == EJUSTRETURN)
1883 #ifdef SCSI_LOW_DIAGNOSTIC
1884 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1886 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
1887 panic("%s: inconsistent", slp->sl_xname);
1889 #endif /* SCSI_LOW_DIAGNOSTIC */
1891 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1892 cb = TAILQ_NEXT(cb, ccb_chain))
1896 if (li->li_disc == 0)
1898 goto scsi_low_cmd_start;
1900 else if (li->li_nqio > 0)
1902 if (li->li_nqio < li->li_maxnqio ||
1903 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1904 goto scsi_low_cmd_start;
1910 cb->ccb_flags &= ~CCB_STARTQ;
1911 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1914 /* clear all error flag bits (for restart) */
1916 cb->ccb_datalen = -1;
1917 cb->ccb_scp.scp_status = ST_UNKNOWN;
1919 /* setup nexus pointer */
1920 slp->sl_Qnexus = cb;
1921 slp->sl_Lnexus = li;
1922 slp->sl_Tnexus = ti;
1924 /* initialize msgsys */
1925 scsi_low_init_msgsys(slp, ti);
1928 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1930 /* CA state or forced abort */
1931 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1933 else if (li->li_state >= SCSI_LOW_LUN_OK)
1935 cb->ccb_flags &= ~CCB_INTERNAL;
1936 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1937 if (cb->ccb_msgoutflag != 0)
1939 scsi_low_ccb_message_exec(slp, cb);
1944 cb->ccb_flags |= CCB_INTERNAL;
1945 rv = scsi_low_setup_start(slp, ti, li, cb);
1949 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1951 if (rv == SCSI_LOW_START_QTAG &&
1952 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1957 scsi_low_activate_qtag(cb);
1958 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1959 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1960 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1961 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1962 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1964 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1965 scsi_low_assert_msg(slp, ti, qmsg, 0);
1969 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1970 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1971 cb->ccb_tc = cb->ccb_tcmax;
1973 /* setup saved scsi data pointer */
1974 cb->ccb_sscp = cb->ccb_scp;
1976 /* setup current scsi pointer */
1977 slp->sl_scp = cb->ccb_sscp;
1978 slp->sl_error = cb->ccb_error;
1980 /* assert always an identify msg */
1981 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1984 #ifdef SCSI_LOW_DIAGNOSTIC
1985 scsi_low_msg_log_init(&ti->ti_log_msgin);
1986 scsi_low_msg_log_init(&ti->ti_log_msgout);
1987 #endif /* SCSI_LOW_DIAGNOSTIC */
1989 /* selection start */
1991 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1992 if (rv == SCSI_LOW_START_OK)
1994 #ifdef SCSI_LOW_STATICS
1995 scsi_low_statics.nexus_win ++;
1996 #endif /* SCSI_LOW_STATICS */
2000 scsi_low_arbit_fail(slp, cb);
2001 #ifdef SCSI_LOW_STATICS
2002 scsi_low_statics.nexus_fail ++;
2003 #endif /* SCSI_LOW_STATICS */
2007 scsi_low_arbit_fail(slp, cb)
2008 struct scsi_low_softc *slp;
2011 struct targ_info *ti = cb->ti;
2013 scsi_low_deactivate_qtag(cb);
2014 scsi_low_ccb_message_retry(cb);
2015 cb->ccb_flags |= CCB_STARTQ;
2016 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2018 scsi_low_bus_release(slp, ti);
2021 if (slp->sl_disc == 0)
2023 #ifdef SCSI_LOW_DIAGNOSTIC
2024 printf("%s: try selection again\n", slp->sl_xname);
2025 #endif /* SCSI_LOW_DIAGNOSTIC */
2026 slp->sl_retry_sel = 1;
2031 scsi_low_bus_release(slp, ti)
2032 struct scsi_low_softc *slp;
2033 struct targ_info *ti;
2036 if (ti->ti_disc > 0)
2038 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2042 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2045 /* clear all nexus pointer */
2046 slp->sl_Qnexus = NULL;
2047 slp->sl_Lnexus = NULL;
2048 slp->sl_Tnexus = NULL;
2050 /* clear selection assert */
2051 slp->sl_selid = NULL;
2053 /* clear nexus data */
2054 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2056 /* clear phase change counter */
2057 slp->sl_ph_count = 0;
2061 scsi_low_setup_done(slp, cb)
2062 struct scsi_low_softc *slp;
2065 struct targ_info *ti;
2066 struct lun_info *li;
2071 if (cb->ccb_rcnt >= slp->sl_max_retry)
2073 cb->ccb_error |= ABORTIO;
2074 return SCSI_LOW_DONE_COMPLETE;
2077 /* XXX: special huck for selection timeout */
2078 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2079 (cb->ccb_error & SELTIMEOUTIO) != 0)
2081 cb->ccb_error |= ABORTIO;
2082 return SCSI_LOW_DONE_COMPLETE;
2085 switch(li->li_state)
2087 case SCSI_LOW_LUN_INQ:
2088 if (cb->ccb_error != 0)
2091 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2095 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2097 else if ((li->li_inq.sd_version & 7) >= 2 ||
2098 (li->li_inq.sd_len >= 4))
2100 if ((li->li_inq.sd_support & 0x2) == 0)
2101 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2102 if ((li->li_inq.sd_support & 0x8) == 0)
2103 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2106 if ((li->li_inq.sd_support & 0x10) == 0)
2107 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2108 if ((li->li_inq.sd_support & 0x20) == 0)
2109 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2110 if ((li->li_inq.sd_support & 0x40) == 0)
2111 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2116 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2119 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2121 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2123 scsi_low_calcf_target(ti);
2124 scsi_low_calcf_lun(li);
2127 case SCSI_LOW_LUN_MODEQ:
2128 if (cb->ccb_error != 0)
2130 if (cb->ccb_error & SENSEIO)
2132 #ifdef SCSI_LOW_DEBUG
2133 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2135 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2136 (u_int) cb->ccb_sense.error_code,
2137 (u_int) cb->ccb_sense.segment,
2138 (u_int) cb->ccb_sense.flags,
2139 (u_int) cb->ccb_sense.add_sense_code,
2140 (u_int) cb->ccb_sense.add_sense_code_qual);
2142 #endif /* SCSI_LOW_DEBUG */
2146 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2149 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2151 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2152 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2154 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2155 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2156 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2158 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2159 scsi_low_calcf_lun(li);
2167 if (li->li_state == SCSI_LOW_LUN_OK)
2169 scsi_low_calcf_target(ti);
2170 scsi_low_calcf_lun(li);
2171 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2172 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2174 scsi_low_calcf_show(li);
2179 return SCSI_LOW_DONE_RETRY;
2183 scsi_low_done(slp, cb)
2184 struct scsi_low_softc *slp;
2189 if (cb->ccb_error == 0)
2191 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2193 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2195 * SCSI-2 draft suggests
2196 * page 0x0a QErr bit determins if
2197 * the target aborts or continues
2198 * the queueing io's after CA state resolved.
2199 * However many targets seem not to support
2200 * the page 0x0a. Thus we should manually clear the
2201 * queuing io's after CA state.
2203 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2206 cb->ccb_flags |= CCB_CLEARQ;
2209 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2211 if ((cb->ccb_flags & CCB_SENSE) != 0)
2212 cb->ccb_error |= (SENSEIO | ABORTIO);
2213 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2215 else switch (cb->ccb_sscp.scp_status)
2221 if (cb->ccb_datalen == 0 ||
2222 cb->ccb_scp.scp_datalen == 0)
2225 if (cb->ccb_scp.scp_cmdlen > 0 &&
2226 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2227 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2230 cb->ccb_error |= PDMAERR;
2235 cb->ccb_error |= (BUSYERR | STATERR);
2239 cb->ccb_error |= (STATERR | ABORTIO);
2244 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2247 cb->ccb_flags |= CCB_SENSE;
2250 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2255 cb->ccb_error |= FATALIO;
2261 if (cb->ccb_flags & CCB_SENSE)
2263 cb->ccb_error |= (SENSEERR | ABORTIO);
2265 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2269 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2271 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2275 /* check a ccb msgout flag */
2276 if (cb->ccb_omsgoutflag != 0)
2278 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2279 SCSI_LOW_MSG_ABORT_QTAG | \
2280 SCSI_LOW_MSG_CLEAR_QTAG | \
2281 SCSI_LOW_MSG_TERMIO)
2283 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2285 cb->ccb_error |= ABORTIO;
2289 /* call OS depend done */
2290 if (cb->osdep != NULL)
2292 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2293 if (rv == EJUSTRETURN)
2296 else if (cb->ccb_error != 0)
2298 if (cb->ccb_rcnt >= slp->sl_max_retry)
2299 cb->ccb_error |= ABORTIO;
2301 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2302 (cb->ccb_error & ABORTIO) == 0)
2306 /* free our target */
2307 #ifdef SCSI_LOW_DEBUG
2308 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2310 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2311 scsi_low_print(slp, NULL);
2313 #endif /* SCSI_LOW_DEBUG */
2315 scsi_low_deactivate_qtag(cb);
2316 scsi_low_dealloc_qtag(cb);
2317 scsi_low_free_ccb(cb);
2319 return SCSI_LOW_DONE_COMPLETE;
2322 #ifdef SCSI_LOW_DEBUG
2323 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2325 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2326 scsi_low_print(slp, NULL);
2328 #endif /* SCSI_LOW_DEBUG */
2331 scsi_low_deactivate_qtag(cb);
2332 scsi_low_ccb_message_retry(cb);
2333 return SCSI_LOW_DONE_RETRY;
2336 /**************************************************************
2338 **************************************************************/
2340 scsi_low_reset_nexus_target(slp, ti, fdone)
2341 struct scsi_low_softc *slp;
2342 struct targ_info *ti;
2345 struct lun_info *li;
2347 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2348 li = LIST_NEXT(li, lun_chain))
2350 scsi_low_reset_nexus_lun(slp, li, fdone);
2351 li->li_state = SCSI_LOW_LUN_SLEEP;
2356 ti->ti_setup_msg = 0;
2357 ti->ti_setup_msg_done = 0;
2359 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2360 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2362 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2363 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2365 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2367 ((*slp->sl_funcs->scsi_low_targ_init)
2368 (slp, ti, SCSI_LOW_INFO_REVOKE));
2370 scsi_low_calcf_target(ti);
2372 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2373 li = LIST_NEXT(li, lun_chain))
2377 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2378 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2380 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2382 ((*slp->sl_funcs->scsi_low_lun_init)
2383 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2385 scsi_low_calcf_lun(li);
2390 scsi_low_reset_nexus(slp, fdone)
2391 struct scsi_low_softc *slp;
2394 struct targ_info *ti;
2395 struct slccb *cb, *topcb;
2397 if ((cb = slp->sl_Qnexus) != NULL)
2399 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2406 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2407 ti = TAILQ_NEXT(ti, ti_chain))
2409 scsi_low_reset_nexus_target(slp, ti, fdone);
2410 scsi_low_bus_release(slp, ti);
2411 scsi_low_init_msgsys(slp, ti);
2416 topcb->ccb_flags |= CCB_STARTQ;
2417 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2421 slp->sl_retry_sel = 0;
2422 slp->sl_flags &= ~HW_PDMASTART;
2427 static char tw_chars[] = "|/-\\";
2428 #define TWIDDLEWAIT 10000
2431 scsi_low_twiddle_wait(void)
2435 cnputc(tw_chars[tw_pos++]);
2436 tw_pos %= (sizeof(tw_chars) - 1);
2437 SCSI_LOW_DELAY(TWIDDLEWAIT);
2441 scsi_low_bus_reset(slp)
2442 struct scsi_low_softc *slp;
2446 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2448 printf("%s: try to reset scsi bus ", slp->sl_xname);
2449 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2450 scsi_low_twiddle_wait();
2456 scsi_low_restart(slp, flags, s)
2457 struct scsi_low_softc *slp;
2464 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2466 if ((error = scsi_low_init(slp, flags)) != 0)
2469 scsi_low_start(slp);
2473 /**************************************************************
2474 * disconnect and reselect
2475 **************************************************************/
2476 #define MSGCMD_LUN(msg) (msg & 0x07)
2478 static struct slccb *
2479 scsi_low_establish_ccb(ti, li, tag)
2480 struct targ_info *ti;
2481 struct lun_info *li;
2484 struct scsi_low_softc *slp = ti->ti_sc;
2490 cb = TAILQ_FIRST(&li->li_discq);
2491 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2492 if (cb->ccb_tag == tag)
2497 * establish our ccb nexus
2500 #ifdef SCSI_LOW_DEBUG
2501 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2503 printf("%s: nexus(0x%lx) abort check start\n",
2504 slp->sl_xname, (u_long) cb);
2505 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2506 scsi_low_revoke_ccb(slp, cb, 1);
2510 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2512 if (cb->ccb_omsgoutflag == 0)
2513 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2515 #endif /* SCSI_LOW_DEBUG */
2517 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2518 cb->ccb_flags &= ~CCB_DISCQ;
2519 slp->sl_Qnexus = cb;
2521 slp->sl_scp = cb->ccb_sscp;
2522 slp->sl_error |= cb->ccb_error;
2528 /* inform "ccb nexus established" to the host driver */
2529 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2532 if (cb->ccb_msgoutflag != 0)
2534 scsi_low_ccb_message_exec(slp, cb);
2541 scsi_low_reselected(slp, targ)
2542 struct scsi_low_softc *slp;
2545 struct targ_info *ti;
2550 * Check select vs reselected collision.
2553 if ((cb = slp->sl_selid) != NULL)
2555 scsi_low_arbit_fail(slp, cb);
2556 #ifdef SCSI_LOW_STATICS
2557 scsi_low_statics.nexus_conflict ++;
2558 #endif /* SCSI_LOW_STATICS */
2562 * Check if no current active nexus.
2564 if (slp->sl_Tnexus != NULL)
2571 * Check a valid target id asserted ?
2573 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2575 s = "scsi id illegal";
2580 * Check the target scsi status.
2582 ti = slp->sl_ti[targ];
2583 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2585 s = "phase mismatch";
2593 scsi_low_init_msgsys(slp, ti);
2596 * Establish our target nexus
2598 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2599 slp->sl_Tnexus = ti;
2600 #ifdef SCSI_LOW_STATICS
2601 scsi_low_statics.nexus_reselected ++;
2602 #endif /* SCSI_LOW_STATICS */
2606 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2607 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2608 "reselect: scsi world confused");
2612 /**************************************************************
2613 * cmd out pointer setup
2614 **************************************************************/
2616 scsi_low_cmd(slp, ti)
2617 struct scsi_low_softc *slp;
2618 struct targ_info *ti;
2620 struct slccb *cb = slp->sl_Qnexus;
2622 slp->sl_ph_count ++;
2628 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2629 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2630 slp->sl_scp.scp_datalen = 0;
2631 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2632 slp->sl_error |= FATALIO;
2633 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2634 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2639 #ifdef SCSI_LOW_DEBUG
2640 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2642 scsi_low_test_cmdlnk(slp, cb);
2644 #endif /* SCSI_LOW_DEBUG */
2649 /**************************************************************
2650 * data out pointer setup
2651 **************************************************************/
2653 scsi_low_data(slp, ti, bp, direction)
2654 struct scsi_low_softc *slp;
2655 struct targ_info *ti;
2659 struct slccb *cb = slp->sl_Qnexus;
2661 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2667 slp->sl_error |= (FATALIO | PDMAERR);
2668 slp->sl_scp.scp_datalen = 0;
2669 slp->sl_scp.scp_direction = direction;
2670 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2671 if (ti->ti_ophase != ti->ti_phase)
2676 s = "DATA PHASE: ccb nexus not found";
2678 s = "DATA PHASE: xfer direction mismatch";
2679 SCSI_LOW_INFO(slp, ti, s);
2686 /**************************************************************
2688 **************************************************************/
2689 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2690 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2691 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2692 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2693 #define MSGIN_DATA_LAST 0x30
2695 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2696 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2697 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2698 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2700 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2701 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2702 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2703 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2704 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2705 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2706 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2708 struct scsi_low_msgout_data {
2711 int (*md_msgfunc) (struct scsi_low_softc *);
2712 int (*md_errfunc) (struct scsi_low_softc *, u_int);
2713 #define MSG_RELEASE_ATN 0x0001
2717 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2718 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2719 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2720 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2721 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2722 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2723 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2724 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2725 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2726 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2727 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2728 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2729 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2730 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2731 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2732 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2733 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2736 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2737 static int scsi_low_synch (struct scsi_low_softc *);
2738 static int scsi_low_wide (struct scsi_low_softc *);
2739 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2740 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2741 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2742 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2743 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2744 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2745 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2746 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2747 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2748 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2749 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2751 struct scsi_low_msgin_data {
2753 int (*md_msgfunc) (struct scsi_low_softc *);
2756 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2757 /* 0 */ {1, scsi_low_msginfunc_cc},
2758 /* 1 */ {2, scsi_low_msginfunc_ext},
2759 /* 2 */ {1, scsi_low_msginfunc_sdp},
2760 /* 3 */ {1, scsi_low_msginfunc_rp},
2761 /* 4 */ {1, scsi_low_msginfunc_disc},
2762 /* 5 */ {1, scsi_low_msginfunc_rejop},
2763 /* 6 */ {1, scsi_low_msginfunc_rejop},
2764 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2765 /* 8 */ {1, scsi_low_msginfunc_noop},
2766 /* 9 */ {1, scsi_low_msginfunc_parity},
2767 /* a */ {1, scsi_low_msginfunc_lcc},
2768 /* b */ {1, scsi_low_msginfunc_lcc},
2769 /* c */ {1, scsi_low_msginfunc_rejop},
2770 /* d */ {2, scsi_low_msginfunc_rejop},
2771 /* e */ {1, scsi_low_msginfunc_rejop},
2772 /* f */ {1, scsi_low_msginfunc_rejop},
2773 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2774 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2775 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2776 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2777 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2778 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2779 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2780 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2781 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2782 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2783 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2784 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2785 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2786 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2787 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2788 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2789 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2790 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2791 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2792 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2793 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2794 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2795 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2796 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2797 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2798 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2799 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2800 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2801 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2802 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2803 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2804 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2805 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2808 /**************************************************************
2810 **************************************************************/
2812 scsi_low_msgfunc_synch(slp)
2813 struct scsi_low_softc *slp;
2815 struct targ_info *ti = slp->sl_Tnexus;
2816 int ptr = ti->ti_msgoutlen;
2818 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2819 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2820 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2821 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2822 return MSG_EXTEND_SYNCHLEN + 2;
2826 scsi_low_msgfunc_wide(slp)
2827 struct scsi_low_softc *slp;
2829 struct targ_info *ti = slp->sl_Tnexus;
2830 int ptr = ti->ti_msgoutlen;
2832 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2833 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2834 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2835 return MSG_EXTEND_WIDELEN + 2;
2839 scsi_low_msgfunc_identify(slp)
2840 struct scsi_low_softc *slp;
2842 struct targ_info *ti = slp->sl_Tnexus;
2843 struct lun_info *li = slp->sl_Lnexus;
2844 struct slccb *cb = slp->sl_Qnexus;
2845 int ptr = ti->ti_msgoutlen;
2851 slp->sl_error |= FATALIO;
2852 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2853 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2857 if (scsi_low_is_disconnect_ok(cb) != 0)
2858 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2862 if (ti->ti_phase == PH_MSGOUT)
2864 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2865 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2867 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2871 ti->ti_msgoutstr[ptr + 0] = msg;
2876 scsi_low_msgfunc_abort(slp)
2877 struct scsi_low_softc *slp;
2880 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2885 scsi_low_msgfunc_qabort(slp)
2886 struct scsi_low_softc *slp;
2889 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2894 scsi_low_msgfunc_reset(slp)
2895 struct scsi_low_softc *slp;
2898 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2903 scsi_low_msgfunc_qtag(slp)
2904 struct scsi_low_softc *slp;
2906 struct targ_info *ti = slp->sl_Tnexus;
2907 struct slccb *cb = slp->sl_Qnexus;
2908 int ptr = ti->ti_msgoutlen;
2910 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2912 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2917 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2918 if (ti->ti_phase == PH_MSGOUT)
2920 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2927 * The following functions are called when targets give unexpected
2928 * responces in msgin (after msgout).
2931 scsi_low_errfunc_identify(slp, msgflags)
2932 struct scsi_low_softc *slp;
2936 if (slp->sl_Lnexus != NULL)
2938 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2939 scsi_low_calcf_lun(slp->sl_Lnexus);
2945 scsi_low_errfunc_synch(slp, msgflags)
2946 struct scsi_low_softc *slp;
2949 struct targ_info *ti = slp->sl_Tnexus;
2951 MSGIN_PERIOD(ti) = 0;
2952 MSGIN_OFFSET(ti) = 0;
2953 scsi_low_synch(slp);
2958 scsi_low_errfunc_wide(slp, msgflags)
2959 struct scsi_low_softc *slp;
2962 struct targ_info *ti = slp->sl_Tnexus;
2964 MSGIN_WIDTHP(ti) = 0;
2970 scsi_low_errfunc_qtag(slp, msgflags)
2971 struct scsi_low_softc *slp;
2975 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2977 if (slp->sl_Qnexus != NULL)
2979 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2981 if (slp->sl_Lnexus != NULL)
2983 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2984 scsi_low_calcf_lun(slp->sl_Lnexus);
2986 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2993 scsi_low_msgout(slp, ti, fl)
2994 struct scsi_low_softc *slp;
2995 struct targ_info *ti;
2998 struct scsi_low_msgout_data *mdp;
3001 #ifdef SCSI_LOW_DIAGNOSTIC
3002 if (ti != slp->sl_Tnexus)
3004 scsi_low_print(slp, NULL);
3005 panic("scsi_low_msgout: Target nexus inconsistent");
3007 #endif /* SCSI_LOW_DIAGNOSTIC */
3009 slp->sl_ph_count ++;
3010 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3012 printf("%s: too many phase changes\n", slp->sl_xname);
3013 slp->sl_error |= FATALIO;
3014 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3018 * Scsi phase changes.
3019 * Previously msgs asserted are accepted by our target or
3020 * processed by scsi_low_msgin.
3021 * Thus clear all saved informations.
3023 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3025 ti->ti_omsgflags = 0;
3026 ti->ti_emsgflags = 0;
3028 else if (slp->sl_atten == 0)
3031 * We did not assert attention, however still our target required
3032 * msgs. Resend previous msgs.
3034 ti->ti_msgflags |= ti->ti_omsgflags;
3035 ti->ti_omsgflags = 0;
3036 #ifdef SCSI_LOW_DIAGNOSTIC
3037 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3038 #endif /* SCSI_LOW_DIAGNOSTIC */
3042 * We have no msgs. send MSG_NOOP (OK?)
3044 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3045 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3050 ti->ti_msgoutlen = 0;
3051 slp->sl_clear_atten = 0;
3052 mdp = &scsi_low_msgout_data[0];
3053 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3055 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3057 ti->ti_omsgflags |= mdp->md_flags;
3058 ti->ti_msgflags &= ~mdp->md_flags;
3059 ti->ti_emsgflags = mdp->md_flags;
3061 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3062 if (mdp->md_msgfunc != NULL)
3063 len = (*mdp->md_msgfunc) (slp);
3067 #ifdef SCSI_LOW_DIAGNOSTIC
3068 scsi_low_msg_log_write(&ti->ti_log_msgout,
3069 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3070 #endif /* SCSI_LOW_DIAGNOSTIC */
3072 ti->ti_msgoutlen += len;
3073 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3075 slp->sl_clear_atten = 1;
3079 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3080 ti->ti_msgflags == 0)
3083 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3088 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3089 slp->sl_clear_atten = 1;
3091 return ti->ti_msgoutlen;
3094 /**************************************************************
3096 **************************************************************/
3098 scsi_low_msginfunc_noop(slp)
3099 struct scsi_low_softc *slp;
3106 scsi_low_msginfunc_rejop(slp)
3107 struct scsi_low_softc *slp;
3109 struct targ_info *ti = slp->sl_Tnexus;
3110 u_int8_t msg = ti->ti_msgin[0];
3112 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3113 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3118 scsi_low_msginfunc_cc(slp)
3119 struct scsi_low_softc *slp;
3121 struct lun_info *li;
3123 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3125 /* validate status */
3126 if (slp->sl_Qnexus == NULL)
3129 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3130 li = slp->sl_Lnexus;
3131 switch (slp->sl_scp.scp_status)
3134 li->li_maxnqio = li->li_maxnexus;
3139 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3140 scsi_low_reset_nexus_lun(slp, li, 0);
3148 if (li->li_maxnexus >= li->li_nqio)
3149 li->li_maxnexus = li->li_nqio - 1;
3150 li->li_maxnqio = li->li_maxnexus;
3155 slp->sl_error |= MSGERR;
3165 scsi_low_msginfunc_lcc(slp)
3166 struct scsi_low_softc *slp;
3168 struct targ_info *ti;
3169 struct lun_info *li;
3170 struct slccb *ncb, *cb;
3172 ti = slp->sl_Tnexus;
3173 li = slp->sl_Lnexus;
3174 if ((cb = slp->sl_Qnexus) == NULL)
3177 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3178 switch (slp->sl_scp.scp_status)
3182 li->li_maxnqio = li->li_maxnexus;
3186 slp->sl_error |= MSGERR;
3190 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3193 cb->ccb_error |= slp->sl_error;
3194 if (cb->ccb_error != 0)
3197 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3198 ncb = TAILQ_NEXT(ncb, ccb_chain))
3201 goto cmd_link_start;
3206 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3207 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3211 ncb->ccb_flags &= ~CCB_STARTQ;
3212 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3214 scsi_low_dealloc_qtag(ncb);
3215 ncb->ccb_tag = cb->ccb_tag;
3216 ncb->ccb_otag = cb->ccb_otag;
3217 cb->ccb_tag = SCSI_LOW_UNKTAG;
3218 cb->ccb_otag = SCSI_LOW_UNKTAG;
3219 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3220 panic("%s: linked ccb retried", slp->sl_xname);
3222 slp->sl_Qnexus = ncb;
3223 slp->sl_ph_count = 0;
3226 ncb->ccb_datalen = -1;
3227 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3228 ncb->ccb_flags &= ~CCB_INTERNAL;
3230 scsi_low_init_msgsys(slp, ti);
3232 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3234 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3235 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3236 ncb->ccb_tc = ncb->ccb_tcmax;
3238 /* setup saved scsi data pointer */
3239 ncb->ccb_sscp = ncb->ccb_scp;
3240 slp->sl_scp = ncb->ccb_sscp;
3241 slp->sl_error = ncb->ccb_error;
3243 #ifdef SCSI_LOW_DIAGNOSTIC
3244 scsi_low_msg_log_init(&ti->ti_log_msgin);
3245 scsi_low_msg_log_init(&ti->ti_log_msgout);
3246 #endif /* SCSI_LOW_DIAGNOSTIC */
3251 scsi_low_msginfunc_disc(slp)
3252 struct scsi_low_softc *slp;
3255 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3260 scsi_low_msginfunc_sdp(slp)
3261 struct scsi_low_softc *slp;
3263 struct slccb *cb = slp->sl_Qnexus;
3267 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3268 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3271 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3276 scsi_low_msginfunc_rp(slp)
3277 struct scsi_low_softc *slp;
3280 if (slp->sl_Qnexus != NULL)
3281 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3283 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3289 struct scsi_low_softc *slp;
3291 struct targ_info *ti = slp->sl_Tnexus;
3292 u_int period = 0, offset = 0, speed;
3296 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3297 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3298 MSGIN_OFFSET(ti) == 0)
3300 if ((offset = MSGIN_OFFSET(ti)) != 0)
3301 period = MSGIN_PERIOD(ti);
3302 s = offset ? "synchronous" : "async";
3307 * Target seems to be brain damaged.
3308 * Force async transfer.
3310 ti->ti_maxsynch.period = 0;
3311 ti->ti_maxsynch.offset = 0;
3312 printf("%s: target brain damaged. async transfer\n",
3317 ti->ti_maxsynch.period = period;
3318 ti->ti_maxsynch.offset = offset;
3320 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3324 * Current period and offset are not acceptable
3326 * The adapter changes max synch and max offset.
3328 printf("%s: synch neg failed. retry synch msg neg ...\n",
3333 ti->ti_osynch = ti->ti_maxsynch;
3336 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3340 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3342 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3343 struct slccb *cb = slp->sl_Qnexus;
3345 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3347 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3349 printf("%s(%d:*): <%s> offset %d period %dns ",
3350 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3354 speed = 1000 * 10 / (period * 4);
3355 printf("%d.%d M/s", speed / 10, speed % 10);
3364 struct scsi_low_softc *slp;
3366 struct targ_info *ti = slp->sl_Tnexus;
3369 ti->ti_width = MSGIN_WIDTHP(ti);
3370 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3374 * Current width is not acceptable for our adapter.
3375 * The adapter changes max width.
3377 printf("%s: wide neg failed. retry wide msg neg ...\n",
3382 ti->ti_owidth = ti->ti_width;
3383 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3385 ti->ti_setup_msg_done |=
3386 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3390 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3392 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3393 struct slccb *cb = slp->sl_Qnexus;
3395 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3397 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3399 printf("%s(%d:*): transfer width %d bits\n",
3400 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3406 scsi_low_msginfunc_simple_qtag(slp)
3407 struct scsi_low_softc *slp;
3409 struct targ_info *ti = slp->sl_Tnexus;
3410 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3412 if (slp->sl_Qnexus != NULL)
3414 if (slp->sl_Qnexus->ccb_tag != etag)
3416 slp->sl_error |= FATALIO;
3417 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3418 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3421 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3423 #ifdef SCSI_LOW_DEBUG
3424 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3426 #endif /* SCSI_LOW_DEBUG */
3428 slp->sl_error |= FATALIO;
3429 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3430 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3436 scsi_low_msginfunc_i_wide_residue(slp)
3437 struct scsi_low_softc *slp;
3439 struct targ_info *ti = slp->sl_Tnexus;
3440 struct slccb *cb = slp->sl_Qnexus;
3441 int res = (int) ti->ti_msgin[1];
3443 if (cb == NULL || res <= 0 ||
3444 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3445 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3448 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3451 slp->sl_scp.scp_datalen += res;
3452 slp->sl_scp.scp_data -= res;
3453 scsi_low_data_finish(slp);
3458 scsi_low_msginfunc_ext(slp)
3459 struct scsi_low_softc *slp;
3461 struct slccb *cb = slp->sl_Qnexus;
3462 struct lun_info *li = slp->sl_Lnexus;
3463 struct targ_info *ti = slp->sl_Tnexus;
3467 if (ti->ti_msginptr == 2)
3469 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3473 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3475 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3479 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3480 count = (int) htonl((long) (*ptr));
3481 if(slp->sl_scp.scp_datalen - count < 0 ||
3482 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3485 slp->sl_scp.scp_datalen -= count;
3486 slp->sl_scp.scp_data += count;
3489 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3493 retry = scsi_low_synch(slp);
3494 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3495 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3497 #ifdef SCSI_LOW_DEBUG
3498 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3500 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3502 #endif /* SCSI_LOW_DEBUG */
3505 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3509 retry = scsi_low_wide(slp);
3510 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3511 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3519 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3524 scsi_low_msginfunc_parity(slp)
3525 struct scsi_low_softc *slp;
3527 struct targ_info *ti = slp->sl_Tnexus;
3529 /* only I -> T, invalid! */
3530 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3535 scsi_low_msginfunc_msg_reject(slp)
3536 struct scsi_low_softc *slp;
3538 struct targ_info *ti = slp->sl_Tnexus;
3539 struct scsi_low_msgout_data *mdp;
3542 if (ti->ti_emsgflags != 0)
3544 printf("%s: msg flags [0x%x] rejected\n",
3545 slp->sl_xname, ti->ti_emsgflags);
3546 msgflags = SCSI_LOW_MSG_REJECT;
3547 mdp = &scsi_low_msgout_data[0];
3548 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3550 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3552 ti->ti_emsgflags &= ~mdp->md_flags;
3553 if (mdp->md_errfunc != NULL)
3554 (*mdp->md_errfunc) (slp, msgflags);
3562 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3563 slp->sl_error |= MSGERR;
3569 scsi_low_msgin(slp, ti, c)
3570 struct scsi_low_softc *slp;
3571 struct targ_info *ti;
3574 struct scsi_low_msgin_data *sdp;
3575 struct lun_info *li;
3578 #ifdef SCSI_LOW_DIAGNOSTIC
3579 if (ti != slp->sl_Tnexus)
3581 scsi_low_print(slp, NULL);
3582 panic("scsi_low_msgin: Target nexus inconsistent");
3584 #endif /* SCSI_LOW_DIAGNOSTIC */
3587 * Phase changes, clear the pointer.
3589 if (ti->ti_ophase != ti->ti_phase)
3592 ti->ti_msgin_parity_error = 0;
3594 slp->sl_ph_count ++;
3595 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3597 printf("%s: too many phase changes\n", slp->sl_xname);
3598 slp->sl_error |= FATALIO;
3599 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3604 * Store a current messages byte into buffer and
3605 * wait for the completion of the current msg.
3607 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3608 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3610 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3611 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3615 * Check parity errors.
3617 if ((c & SCSI_LOW_DATA_PE) != 0)
3619 ti->ti_msgin_parity_error ++;
3620 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3624 if (ti->ti_msgin_parity_error != 0)
3628 * Calculate messages length.
3630 msg = ti->ti_msgin[0];
3631 if (msg < MSGIN_DATA_LAST)
3632 sdp = &scsi_low_msgin_data[msg];
3634 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3636 if (ti->ti_msginlen == 0)
3638 ti->ti_msginlen = sdp->md_len;
3644 if (ti->ti_msginptr < ti->ti_msginlen)
3650 if ((msg & MSG_IDENTIFY) == 0)
3652 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3657 li = slp->sl_Lnexus;
3660 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3663 slp->sl_Lnexus = li;
3664 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3668 if (MSGCMD_LUN(msg) != li->li_lun)
3672 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3674 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3676 #ifdef SCSI_LOW_DEBUG
3677 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3681 #endif /* SCSI_LOW_DEBUG */
3689 * Msg process completed, reset msgin pointer and assert ATN if desired.
3692 slp->sl_error |= FATALIO;
3693 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3694 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3697 if (ti->ti_msginptr < ti->ti_msginlen)
3700 #ifdef SCSI_LOW_DIAGNOSTIC
3701 scsi_low_msg_log_write(&ti->ti_log_msgin,
3702 &ti->ti_msgin[0], ti->ti_msginlen);
3703 #endif /* SCSI_LOW_DIAGNOSTIC */
3709 /**********************************************************
3711 **********************************************************/
3713 scsi_low_disconnected(slp, ti)
3714 struct scsi_low_softc *slp;
3715 struct targ_info *ti;
3717 struct slccb *cb = slp->sl_Qnexus;
3719 /* check phase completion */
3720 switch (slp->sl_msgphase)
3723 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3724 scsi_low_msginfunc_cc(slp);
3725 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3729 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3730 scsi_low_msginfunc_cc(slp);
3731 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3735 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3736 scsi_low_msginfunc_cc(slp);
3742 struct lun_info *li;
3745 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3746 cb->ccb_flags |= CCB_DISCQ;
3747 cb->ccb_error |= slp->sl_error;
3753 #ifdef SCSI_LOW_STATICS
3754 scsi_low_statics.nexus_disconnected ++;
3755 #endif /* SCSI_LOW_STATICS */
3757 #ifdef SCSI_LOW_DEBUG
3758 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3760 printf("## SCSI_LOW_DISCONNECTED ===============\n");
3761 scsi_low_print(slp, NULL);
3763 #endif /* SCSI_LOW_DEBUG */
3767 slp->sl_error |= FATALIO;
3768 if (ti->ti_phase == PH_SELSTART)
3769 slp->sl_error |= SELTIMEOUTIO;
3771 slp->sl_error |= UBFERR;
3780 #ifdef SCSI_LOW_DEBUG
3781 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3783 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3784 (cb->ccb_msgoutflag != 0 ||
3785 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3787 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3790 #endif /* SCSI_LOW_DEBUG */
3792 cb->ccb_error |= slp->sl_error;
3793 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3795 cb->ccb_flags |= CCB_STARTQ;
3796 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3801 scsi_low_bus_release(slp, ti);
3802 scsi_low_start(slp);
3806 /**********************************************************
3808 **********************************************************/
3810 scsi_low_alloc_qtag(cb)
3813 struct lun_info *li = cb->li;
3814 scsi_low_tag_t etag;
3816 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3819 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3820 etag = ffs(li->li_qtagbits);
3824 li->li_qtagbits &= ~(1 << (etag - 1));
3825 cb->ccb_otag = etag;
3828 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3829 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3830 if (li->li_qtagarray[li->li_qd] == 0)
3833 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3834 if (li->li_qtagarray[li->li_qd] == 0)
3840 li->li_qtagarray[li->li_qd] ++;
3841 cb->ccb_otag = (li->li_qd ++);
3843 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3847 scsi_low_dealloc_qtag(cb)
3850 struct lun_info *li = cb->li;
3851 scsi_low_tag_t etag;
3853 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3856 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3857 etag = cb->ccb_otag - 1;
3858 #ifdef SCSI_LOW_DIAGNOSTIC
3859 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3860 panic("scsi_low_dealloc_tag: illegal tag");
3861 #endif /* SCSI_LOW_DIAGNOSTIC */
3862 li->li_qtagbits |= (1 << etag);
3864 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3865 etag = cb->ccb_otag;
3866 #ifdef SCSI_LOW_DIAGNOSTIC
3867 if (etag >= SCSI_LOW_MAXNEXUS)
3868 panic("scsi_low_dealloc_tag: illegal tag");
3869 #endif /* SCSI_LOW_DIAGNOSTIC */
3870 li->li_qtagarray[etag] --;
3871 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3873 cb->ccb_otag = SCSI_LOW_UNKTAG;
3878 scsi_low_revoke_ccb(slp, cb, fdone)
3879 struct scsi_low_softc *slp;
3883 struct targ_info *ti = cb->ti;
3884 struct lun_info *li = cb->li;
3886 #ifdef SCSI_LOW_DIAGNOSTIC
3887 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3888 (CCB_STARTQ | CCB_DISCQ))
3890 panic("%s: ccb in both queue", slp->sl_xname);
3892 #endif /* SCSI_LOW_DIAGNOSTIC */
3894 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3896 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3899 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3901 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3907 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3908 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3911 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3912 (cb->ccb_flags & CCB_NORETRY) != 0))
3914 cb->ccb_error |= FATALIO;
3915 cb->ccb_flags &= ~CCB_AUTOSENSE;
3916 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3917 panic("%s: done ccb retried", slp->sl_xname);
3922 cb->ccb_error |= PENDINGIO;
3923 scsi_low_deactivate_qtag(cb);
3924 scsi_low_ccb_message_retry(cb);
3925 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3931 scsi_low_reset_nexus_lun(slp, li, fdone)
3932 struct scsi_low_softc *slp;
3933 struct lun_info *li;
3936 struct slccb *cb, *ncb, *ecb;
3942 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3944 ncb = TAILQ_NEXT(cb, ccb_chain);
3945 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3949 * presumely keep ordering of io
3951 cb->ccb_flags |= CCB_STARTQ;
3954 TAILQ_INSERT_HEAD(&slp->sl_start,\
3959 TAILQ_INSERT_AFTER(&slp->sl_start,\
3960 ecb, cb, ccb_chain);
3967 /**************************************************************
3969 **************************************************************/
3971 scsi_low_calcf_lun(li)
3972 struct lun_info *li;
3974 struct targ_info *ti = li->li_ti;
3975 struct scsi_low_softc *slp = ti->ti_sc;
3976 u_int cfgflags, diskflags;
3978 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3979 cfgflags = li->li_cfgflags;
3983 diskflags = li->li_diskflags & li->li_quirks;
3986 li->li_flags &= ~SCSI_LOW_DISC;
3987 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3988 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3989 (cfgflags & SCSI_LOW_DISC) != 0)
3990 li->li_flags |= SCSI_LOW_DISC;
3993 li->li_flags |= SCSI_LOW_NOPARITY;
3994 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3995 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3996 (cfgflags & SCSI_LOW_NOPARITY) == 0)
3997 li->li_flags &= ~SCSI_LOW_NOPARITY;
4000 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4001 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4002 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4004 li->li_flags |= SCSI_LOW_QTAG;
4005 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4006 li->li_maxnqio = li->li_maxnexus;
4010 li->li_flags &= ~SCSI_LOW_QTAG;
4011 li->li_maxnexus = 0;
4012 li->li_maxnqio = li->li_maxnexus;
4016 li->li_flags &= ~SCSI_LOW_LINK;
4017 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4018 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4019 li->li_flags |= SCSI_LOW_LINK;
4021 /* compatible flags */
4022 li->li_flags &= ~SCSI_LOW_SYNC;
4023 if (ti->ti_maxsynch.offset > 0)
4024 li->li_flags |= SCSI_LOW_SYNC;
4026 #ifdef SCSI_LOW_DEBUG
4027 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4029 scsi_low_calcf_show(li);
4031 #endif /* SCSI_LOW_DEBUG */
4035 scsi_low_calcf_target(ti)
4036 struct targ_info *ti;
4038 struct scsi_low_softc *slp = ti->ti_sc;
4039 u_int offset, period, diskflags;
4041 diskflags = ti->ti_diskflags & ti->ti_quirks;
4044 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4045 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4047 offset = ti->ti_maxsynch.offset;
4048 period = ti->ti_maxsynch.period;
4049 if (offset == 0 || period == 0)
4050 offset = period = 0;
4054 offset = period = 0;
4057 ti->ti_maxsynch.offset = offset;
4058 ti->ti_maxsynch.period = period;
4061 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4062 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4063 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4065 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4066 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4067 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4069 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4071 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4072 ti->ti_maxsynch.period != ti->ti_osynch.period)
4073 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4074 if (ti->ti_width != ti->ti_owidth)
4075 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4077 ti->ti_osynch = ti->ti_maxsynch;
4078 ti->ti_owidth = ti->ti_width;
4081 #ifdef SCSI_LOW_DEBUG
4082 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4084 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4085 slp->sl_xname, ti->ti_id,
4086 ti->ti_maxsynch.period * 4,
4087 ti->ti_maxsynch.offset,
4090 #endif /* SCSI_LOW_DEBUG */
4094 scsi_low_calcf_show(li)
4095 struct lun_info *li;
4097 struct targ_info *ti = li->li_ti;
4098 struct scsi_low_softc *slp = ti->ti_sc;
4100 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4101 slp->sl_xname, ti->ti_id, li->li_lun,
4102 ti->ti_maxsynch.period * 4,
4103 ti->ti_maxsynch.offset,
4105 li->li_flags, SCSI_LOW_BITS);
4108 #ifdef SCSI_LOW_START_UP_CHECK
4109 /**************************************************************
4110 * scsi world start up
4111 **************************************************************/
4112 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
4115 scsi_low_start_up(slp)
4116 struct scsi_low_softc *slp;
4118 struct targ_info *ti;
4119 struct lun_info *li;
4123 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4125 for (target = 0; target < slp->sl_ntargs; target ++)
4127 if (target == slp->sl_hostid)
4129 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4131 printf("%s: scsi_low: target %d (host card)\n",
4132 slp->sl_xname, target);
4137 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4139 printf("%s: scsi_low: target %d lun ",
4140 slp->sl_xname, target);
4143 ti = slp->sl_ti[target];
4144 for (lun = 0; lun < slp->sl_nluns; lun ++)
4146 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4152 li = scsi_low_alloc_li(ti, lun, 1);
4154 scsi_low_enqueue(slp, ti, li, cb,
4155 CCB_AUTOSENSE | CCB_POLLED, 0);
4157 scsi_low_poll(slp, cb);
4159 if (li->li_state != SCSI_LOW_LUN_OK)
4162 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4168 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4177 scsi_low_poll(slp, cb)
4178 struct scsi_low_softc *slp;
4184 while (slp->sl_nio > 0)
4186 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4188 (*slp->sl_funcs->scsi_low_poll) (slp);
4189 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4193 scsi_low_timeout_check(slp);
4198 #endif /* SCSI_LOW_START_UP_CHECK */
4200 /**********************************************************
4202 **********************************************************/
4203 #ifdef SCSI_LOW_DEBUG
4205 scsi_low_test_abort(slp, ti, li)
4206 struct scsi_low_softc *slp;
4207 struct targ_info *ti;
4208 struct lun_info *li;
4212 if (li->li_disc > 1)
4214 acb = TAILQ_FIRST(&li->li_discq);
4215 if (scsi_low_abort_ccb(slp, acb) == 0)
4217 printf("%s: aborting ccb(0x%lx) start\n",
4218 slp->sl_xname, (u_long) acb);
4224 scsi_low_test_atten(slp, ti, msg)
4225 struct scsi_low_softc *slp;
4226 struct targ_info *ti;
4230 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4231 scsi_low_assert_msg(slp, ti, msg, 0);
4233 printf("%s: atten check OK\n", slp->sl_xname);
4237 scsi_low_test_cmdlnk(slp, cb)
4238 struct scsi_low_softc *slp;
4241 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4243 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4246 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4247 slp->sl_scp.scp_cmdlen);
4248 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4249 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4251 #endif /* SCSI_LOW_DEBUG */
4254 scsi_low_info(slp, ti, s)
4255 struct scsi_low_softc *slp;
4256 struct targ_info *ti;
4261 slp = LIST_FIRST(&sl_tab);
4265 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4268 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4269 ti = TAILQ_NEXT(ti, ti_chain))
4271 scsi_low_print(slp, ti);
4276 scsi_low_print(slp, ti);
4280 static u_char *phase[] =
4282 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4283 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4287 scsi_low_print(slp, ti)
4288 struct scsi_low_softc *slp;
4289 struct targ_info *ti;
4291 struct lun_info *li;
4295 if (ti == NULL || ti == slp->sl_Tnexus)
4297 ti = slp->sl_Tnexus;
4298 li = slp->sl_Lnexus;
4299 cb = slp->sl_Qnexus;
4303 li = LIST_FIRST(&ti->ti_litab);
4304 cb = TAILQ_FIRST(&li->li_discq);
4308 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4309 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4315 u_int flags = 0, maxnqio = 0, nqio = 0;
4321 flags = li->li_flags;
4322 maxnqio = li->li_maxnqio;
4326 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4328 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4329 phase[(int) ti->ti_phase], ti->ti_disc,
4334 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4335 (u_int) cb->ccb_scp.scp_cmd[0],
4336 cb->ccb_scp.scp_cmdlen,
4338 cb->ccb_scp.scp_datalen,
4339 (u_int) cb->ccb_sscp.scp_status,
4340 cb->ccb_error, SCSI_LOW_ERRORBITS);
4343 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4344 (u_int) (ti->ti_msginptr),
4345 (u_int) (ti->ti_msgin[0]),
4346 (u_int) (ti->ti_msgin[1]),
4347 (u_int) (ti->ti_msgin[2]),
4348 (u_int) (ti->ti_msgin[3]),
4349 (u_int) (ti->ti_msgin[4]),
4352 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4353 (u_int) ti->ti_msgflags,
4354 (u_int) (ti->ti_msgoutstr[0]),
4355 (u_int) (ti->ti_msgoutstr[1]),
4356 (u_int) (ti->ti_msgoutstr[2]),
4357 (u_int) (ti->ti_msgoutstr[3]),
4358 (u_int) (ti->ti_msgoutstr[4]),
4360 flags, SCSI_LOW_BITS);
4362 #ifdef SCSI_LOW_DIAGNOSTIC
4363 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4364 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4365 #endif /* SCSI_LOW_DIAGNOSTIC */
4369 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4370 (u_long) sp->scp_data,
4372 (u_int) sp->scp_status,
4373 slp->sl_error, SCSI_LOW_ERRORBITS);