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.20 2007/05/13 18:33:56 swildner 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) kprintf("%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(struct slccb *cb)
214 struct lun_info *li = cb->li;
216 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
220 cb->ccb_tag = cb->ccb_otag;
224 scsi_low_deactivate_qtag(struct slccb *cb)
226 struct lun_info *li = cb->li;
228 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
232 cb->ccb_tag = SCSI_LOW_UNKTAG;
236 scsi_low_ccb_message_exec(struct scsi_low_softc *slp, struct slccb *cb)
238 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
239 cb->ccb_msgoutflag = 0;
243 scsi_low_ccb_message_assert(struct slccb *cb, u_int msg)
245 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
249 scsi_low_ccb_message_retry(struct slccb *cb)
251 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
255 scsi_low_ccb_message_clear(struct slccb *cb)
257 cb->ccb_msgoutflag = 0;
261 scsi_low_init_msgsys(struct scsi_low_softc *slp, struct targ_info *ti)
264 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
265 SCSI_LOW_DEASSERT_ATN(slp);
266 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
269 /*=============================================================
270 * START OF OS switch (All OS depend fucntions should be here)
271 =============================================================*/
272 /* common os depend utitlities */
273 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
274 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
275 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
277 static u_int8_t scsi_low_cmd_flags[256] = {
278 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
279 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
280 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
281 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
282 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
285 struct scsi_low_error_code {
290 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
291 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
293 static struct slccb *
294 scsi_low_find_ccb(struct scsi_low_softc *slp, u_int target, u_int lun, void *osdep)
296 struct targ_info *ti;
300 ti = slp->sl_ti[target];
301 li = scsi_low_alloc_li(ti, lun, 0);
305 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
308 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
309 cb = TAILQ_NEXT(cb, ccb_chain))
311 if (cb->osdep == osdep)
315 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
316 cb = TAILQ_NEXT(cb, ccb_chain))
318 if (cb->osdep == osdep)
325 scsi_low_translate_error_code(struct slccb *cb, struct scsi_low_error_code *tp)
327 if (cb->ccb_error == 0)
328 return tp->error_code;
330 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
332 return tp->error_code;
335 /**************************************************************
336 * SCSI INTERFACE (CAM)
337 **************************************************************/
338 #define SCSI_LOW_MALLOC(size) kmalloc((size), M_DEVBUF, M_INTWAIT)
339 #define SCSI_LOW_FREE(pt) kfree((pt), M_DEVBUF)
340 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
342 static void scsi_low_poll_cam (struct cam_sim *);
343 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
344 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
345 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
347 static int scsi_low_attach_cam (struct scsi_low_softc *);
348 static int scsi_low_world_start_cam (struct scsi_low_softc *);
349 static int scsi_low_dettach_cam (struct scsi_low_softc *);
350 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
351 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
352 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
354 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
356 scsi_low_world_start_cam,
357 scsi_low_dettach_cam,
358 scsi_low_ccb_setup_cam,
363 struct scsi_low_error_code scsi_low_error_code_cam[] = {
365 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
366 {SENSEERR, CAM_AUTOSENSE_FAIL},
367 {UACAERR, CAM_SCSI_STATUS_ERROR},
368 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
369 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
370 {TIMEOUTIO, CAM_CMD_TIMEOUT},
371 {PDMAERR, CAM_DATA_RUN_ERR},
372 {PARITYERR, CAM_UNCOR_PARITY},
373 {UBFERR, CAM_UNEXP_BUSFREE},
374 {ABORTIO, CAM_REQ_ABORTED},
375 {-1, CAM_UNREC_HBA_ERROR}
378 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
381 * Please check a polling hz, currently we assume scsi_low_poll() is
384 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
387 scsi_low_poll_cam(struct cam_sim *sim)
389 struct scsi_low_softc *slp = SIM2SLP(sim);
391 (*slp->sl_funcs->scsi_low_poll) (slp);
393 if (slp->sl_si.si_poll_count ++ >=
394 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
396 slp->sl_si.si_poll_count = 0;
397 scsi_low_timeout_check(slp);
402 scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
404 xpt_free_path(ccb->ccb_h.path);
405 kfree(ccb, M_DEVBUF);
409 scsi_low_rescan_bus_cam(struct scsi_low_softc *slp)
411 struct cam_path *path;
412 union ccb *ccb = kmalloc(sizeof(union ccb), M_DEVBUF, M_INTWAIT | M_ZERO);
415 status = xpt_create_path(&path, xpt_periph,
416 cam_sim_path(slp->sl_si.sim), -1, 0);
417 if (status != CAM_REQ_CMP)
420 xpt_setup_ccb(&ccb->ccb_h, path, 5);
421 ccb->ccb_h.func_code = XPT_SCAN_BUS;
422 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
423 ccb->crcn.flags = CAM_FLAG_NONE;
428 scsi_low_scsi_action_cam(struct cam_sim *sim, union ccb *ccb)
430 struct scsi_low_softc *slp = SIM2SLP(sim);
431 struct targ_info *ti;
434 u_int lun, flags, msg, target;
437 target = (u_int) (ccb->ccb_h.target_id);
438 lun = (u_int) ccb->ccb_h.target_lun;
440 #ifdef SCSI_LOW_DEBUG
441 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
443 kprintf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
444 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
446 #endif /* SCSI_LOW_DEBUG */
448 switch (ccb->ccb_h.func_code) {
449 case XPT_SCSI_IO: /* Execute the requested I/O operation */
450 #ifdef SCSI_LOW_DIAGNOSTIC
451 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
453 kprintf("%s: invalid target/lun\n", slp->sl_xname);
454 ccb->ccb_h.status = CAM_REQ_INVALID;
458 #endif /* SCSI_LOW_DIAGNOSTIC */
460 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
461 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
466 ti = slp->sl_ti[target];
469 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
470 flags = CCB_AUTOSENSE | CCB_SCSIIO;
475 li = scsi_low_alloc_li(ti, lun, 1);
477 if (ti->ti_setup_msg != 0)
479 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
482 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
484 #ifdef SCSI_LOW_DEBUG
485 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
487 scsi_low_test_abort(slp, ti, li);
489 #endif /* SCSI_LOW_DEBUG */
493 case XPT_EN_LUN: /* Enable LUN as a target */
494 case XPT_TARGET_IO: /* Execute target I/O request */
495 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
496 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
498 ccb->ccb_h.status = CAM_REQ_INVALID;
502 case XPT_ABORT: /* Abort the specified CCB */
503 #ifdef SCSI_LOW_DIAGNOSTIC
504 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
506 kprintf("%s: invalid target/lun\n", slp->sl_xname);
507 ccb->ccb_h.status = CAM_REQ_INVALID;
511 #endif /* SCSI_LOW_DIAGNOSTIC */
514 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
515 rv = scsi_low_abort_ccb(slp, cb);
519 ccb->ccb_h.status = CAM_REQ_CMP;
521 ccb->ccb_h.status = CAM_REQ_INVALID;
525 case XPT_SET_TRAN_SETTINGS: {
526 struct ccb_trans_settings *cts;
529 #ifdef SCSI_LOW_DIAGNOSTIC
530 if (target == CAM_TARGET_WILDCARD)
532 kprintf("%s: invalid target\n", slp->sl_xname);
533 ccb->ccb_h.status = CAM_REQ_INVALID;
537 #endif /* SCSI_LOW_DIAGNOSTIC */
539 ti = slp->sl_ti[target];
540 if (lun == CAM_LUN_WILDCARD)
544 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
545 CCB_TRANS_SYNC_RATE_VALID |
546 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
548 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
549 val = cts->bus_width;
550 if (val < ti->ti_width)
553 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
554 val = cts->sync_period;
555 if (val == 0 || val > ti->ti_maxsynch.period)
556 ti->ti_maxsynch.period = val;
558 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
559 val = cts->sync_offset;
560 if (val < ti->ti_maxsynch.offset)
561 ti->ti_maxsynch.offset = val;
564 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
565 scsi_low_calcf_target(ti);
568 if ((cts->valid & (CCB_TRANS_DISC_VALID |
569 CCB_TRANS_TQ_VALID)) != 0)
571 li = scsi_low_alloc_li(ti, lun, 1);
572 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
574 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
575 li->li_quirks |= SCSI_LOW_DISK_DISC;
577 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
579 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
581 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
582 li->li_quirks |= SCSI_LOW_DISK_QTAG;
584 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
587 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
588 scsi_low_calcf_target(ti);
589 scsi_low_calcf_lun(li);
590 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
591 scsi_low_calcf_show(li);
595 ccb->ccb_h.status = CAM_REQ_CMP;
600 case XPT_GET_TRAN_SETTINGS: {
601 struct ccb_trans_settings *cts;
605 #ifdef SCSI_LOW_DIAGNOSTIC
606 if (target == CAM_TARGET_WILDCARD)
608 kprintf("%s: invalid target\n", slp->sl_xname);
609 ccb->ccb_h.status = CAM_REQ_INVALID;
613 #endif /* SCSI_LOW_DIAGNOSTIC */
614 ti = slp->sl_ti[target];
615 if (lun == CAM_LUN_WILDCARD)
619 li = scsi_low_alloc_li(ti, lun, 1);
620 #ifdef CAM_NEW_TRAN_CODE
621 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
622 struct ccb_trans_settings_scsi *scsi =
623 &cts->proto_specific.scsi;
624 struct ccb_trans_settings_spi *spi =
625 &cts->xport_specific.spi;
626 #ifdef SCSI_LOW_DIAGNOSTIC
627 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
629 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
630 kprintf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
634 #endif /* SCSI_LOW_DIAGNOSTIC */
635 cts->protocol = PROTO_SCSI;
636 cts->protocol_version = SCSI_REV_2;
637 cts->transport = XPORT_SPI;
638 cts->transport_version = 2;
640 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
641 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
643 diskflags = li->li_diskflags & li->li_cfgflags;
644 if (diskflags & SCSI_LOW_DISK_DISC)
645 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
646 if (diskflags & SCSI_LOW_DISK_QTAG)
647 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
649 spi->sync_period = ti->ti_maxsynch.period;
650 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
651 spi->sync_offset = ti->ti_maxsynch.offset;
652 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
654 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
655 spi->bus_width = ti->ti_width;
657 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
658 scsi->valid = CTS_SCSI_VALID_TQ;
659 spi->valid |= CTS_SPI_VALID_DISC;
663 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
665 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
667 #ifdef SCSI_LOW_DIAGNOSTIC
668 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
670 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
671 kprintf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
675 #endif /* SCSI_LOW_DIAGNOSTIC */
676 diskflags = li->li_diskflags & li->li_cfgflags;
677 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
678 cts->flags |= CCB_TRANS_DISC_ENB;
680 cts->flags &= ~CCB_TRANS_DISC_ENB;
681 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
682 cts->flags |= CCB_TRANS_TAG_ENB;
684 cts->flags &= ~CCB_TRANS_TAG_ENB;
686 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
688 #ifdef SCSI_LOW_DIAGNOSTIC
689 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
691 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
692 kprintf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
696 #endif /* SCSI_LOW_DIAGNOSTIC */
697 if ((li->li_flags & SCSI_LOW_DISC) != 0)
698 cts->flags |= CCB_TRANS_DISC_ENB;
700 cts->flags &= ~CCB_TRANS_DISC_ENB;
701 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
702 cts->flags |= CCB_TRANS_TAG_ENB;
704 cts->flags &= ~CCB_TRANS_TAG_ENB;
708 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
712 cts->sync_period = ti->ti_maxsynch.period;
713 cts->sync_offset = ti->ti_maxsynch.offset;
714 cts->bus_width = ti->ti_width;
716 cts->valid = CCB_TRANS_SYNC_RATE_VALID
717 | CCB_TRANS_SYNC_OFFSET_VALID
718 | CCB_TRANS_BUS_WIDTH_VALID
719 | CCB_TRANS_DISC_VALID
720 | CCB_TRANS_TQ_VALID;
721 ccb->ccb_h.status = CAM_REQ_CMP;
729 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
730 cam_calc_geometry(&ccb->ccg, /*extended*/1);
735 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
737 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
739 ccb->ccb_h.status = CAM_REQ_CMP;
743 case XPT_TERM_IO: /* Terminate the I/O process */
744 ccb->ccb_h.status = CAM_REQ_INVALID;
748 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
749 #ifdef SCSI_LOW_DIAGNOSTIC
750 if (target == CAM_TARGET_WILDCARD)
752 kprintf("%s: invalid target\n", slp->sl_xname);
753 ccb->ccb_h.status = CAM_REQ_INVALID;
757 #endif /* SCSI_LOW_DIAGNOSTIC */
759 msg = SCSI_LOW_MSG_RESET;
760 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
762 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
767 ti = slp->sl_ti[target];
768 if (lun == CAM_LUN_WILDCARD)
772 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
773 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
775 flags = CCB_NORETRY | CCB_URGENT;
778 li = scsi_low_alloc_li(ti, lun, 1);
779 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
783 case XPT_PATH_INQ: { /* Path routing inquiry */
784 struct ccb_pathinq *cpi = &ccb->cpi;
786 cpi->version_num = scsi_low_version_major;
787 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
788 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
789 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
790 cpi->hba_inquiry |= PI_WIDE_16;
791 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
792 cpi->hba_inquiry |= PI_WIDE_32;
793 if (ti->ti_maxsynch.offset > 0)
794 cpi->hba_inquiry |= PI_SDTR_ABLE;
795 cpi->target_sprt = 0;
797 cpi->hba_eng_cnt = 0;
798 cpi->max_target = slp->sl_ntargs - 1;
799 cpi->max_lun = slp->sl_nluns - 1;
800 cpi->initiator_id = slp->sl_hostid;
801 cpi->bus_id = cam_sim_bus(sim);
802 cpi->base_transfer_speed = 3300;
803 #ifdef CAM_NEW_TRAN_CODE
804 cpi->transport = XPORT_SPI;
805 cpi->transport_version = 2;
806 cpi->protocol = PROTO_SCSI;
807 cpi->protocol_version = SCSI_REV_2;
809 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
810 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
811 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
812 cpi->unit_number = cam_sim_unit(sim);
813 cpi->ccb_h.status = CAM_REQ_CMP;
819 kprintf("scsi_low: non support func_code = %d ",
820 ccb->ccb_h.func_code);
821 ccb->ccb_h.status = CAM_REQ_INVALID;
828 scsi_low_attach_cam(struct scsi_low_softc *slp)
830 struct cam_devq *devq;
833 ksprintf(slp->sl_xname, "%s%d",
834 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
836 devq = cam_simq_alloc(SCSI_LOW_NCCB);
841 * ask the adapter what subunits are present
843 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
844 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
846 DEVPORT_DEVNAME(slp->sl_dev), slp,
847 DEVPORT_DEVUNIT(slp->sl_dev),
848 slp->sl_openings, tagged_openings, devq);
849 cam_simq_release(devq);
850 if (slp->sl_si.sim == NULL) {
854 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
855 cam_sim_free(slp->sl_si.sim);
856 slp->sl_si.sim = NULL;
860 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
861 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
862 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
863 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
864 cam_sim_free(slp->sl_si.sim);
865 slp->sl_si.sim = NULL;
869 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
874 scsi_low_world_start_cam(struct scsi_low_softc *slp)
878 scsi_low_rescan_bus_cam(slp);
880 scsi_low_rescan_bus_cam(slp);
885 scsi_low_dettach_cam(struct scsi_low_softc *slp)
887 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
888 xpt_free_path(slp->sl_si.path);
889 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
890 cam_sim_free(slp->sl_si.sim);
891 slp->sl_si.sim = NULL;
896 scsi_low_ccb_setup_cam(struct scsi_low_softc *slp, struct slccb *cb)
898 union ccb *ccb = (union ccb *) cb->osdep;
900 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
902 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
903 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
904 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
905 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
906 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
907 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
908 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
909 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
910 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
914 scsi_low_unit_ready_cmd(cb);
916 return SCSI_LOW_START_QTAG;
920 scsi_low_done_cam(struct scsi_low_softc *slp, struct slccb *cb)
924 ccb = (union ccb *) cb->osdep;
925 if (cb->ccb_error == 0)
927 ccb->ccb_h.status = CAM_REQ_CMP;
932 if (cb->ccb_rcnt >= slp->sl_max_retry)
933 cb->ccb_error |= ABORTIO;
935 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
936 (cb->ccb_error & ABORTIO) == 0)
939 if ((cb->ccb_error & SENSEIO) != 0)
941 memcpy(&ccb->csio.sense_data,
943 sizeof(ccb->csio.sense_data));
946 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
947 &scsi_low_error_code_cam[0]);
949 #ifdef SCSI_LOW_DIAGNOSTIC
950 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
951 cb->ccb_scp.scp_cmdlen > 0 &&
952 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
953 SCSI_LOW_CMD_ABORT_WARNING) != 0)
955 kprintf("%s: WARNING: scsi_low IO abort\n",
957 scsi_low_print(slp, NULL);
959 #endif /* SCSI_LOW_DIAGNOSTIC */
962 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
963 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
965 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
966 ccb->csio.scsi_status = 0; /* XXX */
968 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
970 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
976 scsi_low_timeout_cam(struct scsi_low_softc *slp, int ch, int action)
980 case SCSI_LOW_TIMEOUT_CH_IO:
983 case SCSI_LOW_TIMEOUT_START:
984 callout_reset(&slp->sl_si.timeout_ch,
985 hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
987 case SCSI_LOW_TIMEOUT_STOP:
988 callout_stop(&slp->sl_si.timeout_ch);
993 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
996 case SCSI_LOW_TIMEOUT_START:
997 callout_reset(&slp->sl_si.engage_ch, 1,
998 scsi_low_engage, slp);
1000 case SCSI_LOW_TIMEOUT_STOP:
1001 callout_stop(&slp->sl_si.engage_ch);
1005 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1010 /**************************************************************
1011 * scsi low deactivate and activate
1012 **************************************************************/
1014 scsi_low_is_busy(struct scsi_low_softc *slp)
1016 if (slp->sl_nio > 0)
1022 scsi_low_deactivate(struct scsi_low_softc *slp)
1025 slp->sl_flags |= HW_INACTIVE;
1026 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1027 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1028 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1029 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1035 scsi_low_activate(struct scsi_low_softc *slp)
1040 slp->sl_flags &= ~HW_INACTIVE;
1041 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1043 slp->sl_flags |= HW_INACTIVE;
1048 slp->sl_timeout_count = 0;
1049 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1050 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1055 /**************************************************************
1057 **************************************************************/
1058 #ifdef SCSI_LOW_DIAGNOSTIC
1059 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1060 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1062 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1065 scsi_low_msg_log_init(struct scsi_low_msg_log *slmlp)
1067 slmlp->slml_ptr = 0;
1071 scsi_low_msg_log_write(struct scsi_low_msg_log *slmlp, u_int8_t *datap, int len)
1075 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1078 ptr = slmlp->slml_ptr ++;
1079 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1080 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1081 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1082 slmlp->slml_msg[ptr].msg[ind] = 0;
1086 scsi_low_msg_log_show(struct scsi_low_msg_log *slmlp, char *s, int len)
1090 kprintf("%s: (%d) ", s, slmlp->slml_ptr);
1091 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1093 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1096 kprintf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1102 #endif /* SCSI_LOW_DIAGNOSTIC */
1104 /**************************************************************
1106 **************************************************************/
1108 scsi_low_engage(void *arg)
1110 struct scsi_low_softc *slp = arg;
1114 switch (slp->sl_rstep)
1118 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1119 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1120 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1125 slp->sl_flags &= ~HW_RESUME;
1126 scsi_low_start(slp);
1136 scsi_low_init(struct scsi_low_softc *slp, u_int flags)
1140 slp->sl_flags |= HW_INITIALIZING;
1142 /* clear power control timeout */
1143 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1145 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1146 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1147 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1149 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1152 /* reset current nexus */
1153 scsi_low_reset_nexus(slp, flags);
1154 if ((slp->sl_flags & HW_INACTIVE) != 0)
1160 if (flags != SCSI_LOW_RESTART_SOFT)
1162 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1166 slp->sl_flags &= ~HW_INITIALIZING;
1170 /**************************************************************
1172 **************************************************************/
1173 static struct lun_info *
1174 scsi_low_alloc_li(struct targ_info *ti, int lun, int alloc)
1176 struct scsi_low_softc *slp = ti->ti_sc;
1177 struct lun_info *li;
1179 li = LIST_FIRST(&ti->ti_litab);
1182 if (li->li_lun == lun)
1185 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1187 if (li->li_lun == lun)
1189 LIST_REMOVE(li, lun_chain);
1190 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1199 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1201 panic("no lun info mem");
1203 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1207 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1209 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1210 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1211 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1212 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1213 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1215 li->li_qtagbits = (u_int) -1;
1217 TAILQ_INIT(&li->li_discq);
1218 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1220 /* host specific structure initialization per lun */
1221 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1222 (*slp->sl_funcs->scsi_low_lun_init)
1223 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1224 scsi_low_calcf_lun(li);
1228 /**************************************************************
1229 * allocate targ_info
1230 **************************************************************/
1231 static struct targ_info *
1232 scsi_low_alloc_ti(struct scsi_low_softc *slp, int targ)
1234 struct targ_info *ti;
1236 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1237 TAILQ_INIT(&slp->sl_titab);
1239 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1241 panic("%s short of memory", slp->sl_xname);
1243 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1247 slp->sl_ti[targ] = ti;
1248 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1249 LIST_INIT(&ti->ti_litab);
1251 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1252 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1253 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1254 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1255 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1256 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1258 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1260 (*slp->sl_funcs->scsi_low_targ_init)
1261 (slp, ti, SCSI_LOW_INFO_ALLOC);
1263 scsi_low_calcf_target(ti);
1268 scsi_low_free_ti(struct scsi_low_softc *slp)
1270 struct targ_info *ti, *tib;
1271 struct lun_info *li, *nli;
1273 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1275 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1277 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1279 (*slp->sl_funcs->scsi_low_lun_init)
1280 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1282 nli = LIST_NEXT(li, lun_chain);
1286 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1288 (*slp->sl_funcs->scsi_low_targ_init)
1289 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1291 tib = TAILQ_NEXT(ti, ti_chain);
1296 /**************************************************************
1298 **************************************************************/
1300 scsi_low_bus_idle(struct scsi_low_softc *slp)
1302 slp->sl_retry_sel = 0;
1303 if (slp->sl_Tnexus == NULL)
1304 scsi_low_start(slp);
1308 scsi_low_timeout(void *arg)
1310 struct scsi_low_softc *slp = arg;
1313 scsi_low_timeout_check(slp);
1314 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1315 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1320 scsi_low_timeout_check(struct scsi_low_softc *slp)
1322 struct targ_info *ti;
1323 struct lun_info *li;
1324 struct slccb *cb = NULL; /* XXX */
1326 /* selection restart */
1327 if (slp->sl_retry_sel != 0)
1329 slp->sl_retry_sel = 0;
1330 if (slp->sl_Tnexus != NULL)
1333 cb = TAILQ_FIRST(&slp->sl_start);
1337 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1339 cb->ccb_flags |= CCB_NORETRY;
1340 cb->ccb_error |= SELTIMEOUTIO;
1341 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1342 panic("%s: ccb not finished", slp->sl_xname);
1345 if (slp->sl_Tnexus == NULL)
1346 scsi_low_start(slp);
1349 /* call hardware timeout */
1351 if (slp->sl_funcs->scsi_low_timeout != NULL)
1353 (*slp->sl_funcs->scsi_low_timeout) (slp);
1356 if (slp->sl_timeout_count ++ <
1357 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1360 slp->sl_timeout_count = 0;
1361 if (slp->sl_nio > 0)
1363 if ((cb = slp->sl_Qnexus) != NULL)
1365 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1369 else if (slp->sl_disc == 0)
1371 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1374 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1378 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1379 ti = TAILQ_NEXT(ti, ti_chain))
1381 if (ti->ti_disc == 0)
1384 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1385 li = LIST_NEXT(li, lun_chain))
1387 for (cb = TAILQ_FIRST(&li->li_discq);
1389 cb = TAILQ_NEXT(cb, ccb_chain))
1392 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1400 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1402 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1405 if (slp->sl_active != 0)
1407 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1413 if (slp->sl_powc < 0)
1415 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1416 slp->sl_flags |= HW_POWDOWN;
1417 (*slp->sl_funcs->scsi_low_power)
1418 (slp, SCSI_LOW_POWDOWN);
1424 cb->ccb_error |= TIMEOUTIO;
1425 kprintf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1426 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1427 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1428 scsi_low_start(slp);
1434 scsi_low_abort_ccb(struct scsi_low_softc *slp, struct slccb *cb)
1436 struct targ_info *ti;
1437 struct lun_info *li;
1442 if ((cb->ccb_omsgoutflag &
1443 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1448 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1449 msg = SCSI_LOW_MSG_ABORT;
1451 msg = SCSI_LOW_MSG_ABORT_QTAG;
1453 cb->ccb_error |= ABORTIO;
1454 cb->ccb_flags |= CCB_NORETRY;
1455 scsi_low_ccb_message_assert(cb, msg);
1457 if (cb == slp->sl_Qnexus)
1459 scsi_low_assert_msg(slp, ti, msg, 1);
1461 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1463 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1464 panic("%s: revoked ccb done", slp->sl_xname);
1466 cb->ccb_flags |= CCB_STARTQ;
1467 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1469 if (slp->sl_Tnexus == NULL)
1470 scsi_low_start(slp);
1474 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1475 panic("%s: revoked ccb retried", slp->sl_xname);
1480 /**************************************************************
1481 * Generic SCSI INTERFACE
1482 **************************************************************/
1484 scsi_low_attach(struct scsi_low_softc *slp, int openings, int ntargs, int nluns,
1485 int targsize, int lunsize)
1487 struct targ_info *ti;
1488 struct lun_info *li;
1491 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1493 if (slp->sl_osdep_fp == NULL)
1494 panic("scsi_low: interface not spcified");
1496 if (ntargs > SCSI_LOW_NTARGETS)
1498 kprintf("scsi_low: %d targets are too large\n", ntargs);
1499 kprintf("change kernel options SCSI_LOW_NTARGETS");
1504 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1506 slp->sl_openings = openings;
1507 slp->sl_ntargs = ntargs;
1508 slp->sl_nluns = nluns;
1509 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1511 if (lunsize < sizeof(struct lun_info))
1512 lunsize = sizeof(struct lun_info);
1514 if (targsize < sizeof(struct targ_info))
1515 targsize = sizeof(struct targ_info);
1517 slp->sl_targsize = targsize;
1518 for (i = 0; i < ntargs; i ++)
1520 ti = scsi_low_alloc_ti(slp, i);
1521 ti->ti_lunsize = lunsize;
1522 li = scsi_low_alloc_li(ti, 0, 1);
1525 /* initialize queue */
1526 nccb = openings * ntargs;
1527 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1528 nccb = SCSI_LOW_NCCB;
1529 scsi_low_init_ccbque(nccb);
1530 TAILQ_INIT(&slp->sl_start);
1532 /* call os depend attach */
1533 callout_init(&slp->sl_si.timeout_ch);
1534 callout_init(&slp->sl_si.engage_ch);
1537 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1541 kprintf("%s: scsi_low_attach: osdep attach failed\n",
1546 /* check hardware */
1547 SCSI_LOW_DELAY(1000); /* wait for 1ms */
1548 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1551 kprintf("%s: scsi_low_attach: initialization failed\n",
1556 /* start watch dog */
1557 slp->sl_timeout_count = 0;
1558 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1559 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1560 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1563 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1565 #ifdef SCSI_LOW_START_UP_CHECK
1566 /* probing devices */
1567 scsi_low_start_up(slp);
1568 #endif /* SCSI_LOW_START_UP_CHECK */
1570 /* call os depend attach done*/
1571 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1577 scsi_low_dettach(struct scsi_low_softc *slp)
1582 if (scsi_low_is_busy(slp) != 0)
1588 scsi_low_deactivate(slp);
1590 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1597 scsi_low_free_ti(slp);
1598 LIST_REMOVE(slp, sl_chain);
1603 /**************************************************************
1605 **************************************************************/
1607 scsi_low_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1608 struct lun_info *li, struct slccb *cb, u_int flags,
1615 scsi_low_ccb_message_assert(cb, msg);
1617 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1618 scsi_low_alloc_qtag(cb);
1620 cb->ccb_flags = flags | CCB_STARTQ;
1621 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1622 cb->ccb_error |= PENDINGIO;
1624 if ((flags & CCB_URGENT) != 0)
1626 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1630 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1635 if (slp->sl_Tnexus == NULL)
1636 scsi_low_start(slp);
1641 scsi_low_message_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1642 struct lun_info *li, u_int flags)
1647 tmsgflags = ti->ti_setup_msg;
1648 ti->ti_setup_msg = 0;
1650 flags |= CCB_NORETRY;
1651 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1656 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1660 /**************************************************************
1661 * Generic Start & Done
1662 **************************************************************/
1663 #define SLSC_MODE_SENSE_SHORT 0x1a
1664 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1665 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1666 sizeof(struct scsi_low_mode_sense_data), 0};
1667 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1668 sizeof(struct scsi_low_inq_data), 0};
1669 static u_int8_t unit_ready_cmd[6];
1670 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1671 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1672 static int scsi_low_resume (struct scsi_low_softc *);
1675 scsi_low_unit_ready_cmd(struct slccb *cb)
1677 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1678 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1679 cb->ccb_scp.scp_datalen = 0;
1680 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1685 scsi_low_sense_abort_start(struct scsi_low_softc *slp, struct targ_info *ti,
1686 struct lun_info *li, struct slccb *cb)
1688 cb->ccb_scp.scp_cmdlen = 6;
1689 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1690 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1691 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1692 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1693 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1694 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1695 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1697 scsi_low_ccb_message_clear(cb);
1698 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1700 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1704 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1705 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1706 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1707 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1710 return SCSI_LOW_START_NO_QTAG;
1714 scsi_low_setup_start(struct scsi_low_softc *slp, struct targ_info *ti,
1715 struct lun_info *li, struct slccb *cb)
1717 switch(li->li_state)
1719 case SCSI_LOW_LUN_SLEEP:
1720 scsi_low_unit_ready_cmd(cb);
1723 case SCSI_LOW_LUN_START:
1724 cb->ccb_scp.scp_cmd = ss_cmd;
1725 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1726 cb->ccb_scp.scp_datalen = 0;
1727 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1731 case SCSI_LOW_LUN_INQ:
1732 cb->ccb_scp.scp_cmd = inq_cmd;
1733 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1734 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1735 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1736 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1740 case SCSI_LOW_LUN_MODEQ:
1741 cb->ccb_scp.scp_cmd = sms_cmd;
1742 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1743 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1744 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1745 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1747 return SCSI_LOW_START_QTAG;
1750 panic("%s: no setup phase", slp->sl_xname);
1753 return SCSI_LOW_START_NO_QTAG;
1757 scsi_low_resume(struct scsi_low_softc *slp)
1759 if (slp->sl_flags & HW_RESUME)
1761 slp->sl_flags &= ~HW_POWDOWN;
1762 if (slp->sl_funcs->scsi_low_power != NULL)
1764 slp->sl_flags |= HW_RESUME;
1766 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1767 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1768 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1769 SCSI_LOW_TIMEOUT_START);
1776 scsi_low_start(struct scsi_low_softc *slp)
1778 struct targ_info *ti;
1779 struct lun_info *li;
1783 /* check hardware exists or under initializations ? */
1784 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1787 /* check hardware power up ? */
1788 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1791 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1793 if (scsi_low_resume(slp) == EJUSTRETURN)
1799 #ifdef SCSI_LOW_DIAGNOSTIC
1800 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1802 scsi_low_info(slp, NULL, "NEXUS INCONSISTENT");
1803 panic("%s: inconsistent", slp->sl_xname);
1805 #endif /* SCSI_LOW_DIAGNOSTIC */
1807 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1808 cb = TAILQ_NEXT(cb, ccb_chain))
1812 if (li->li_disc == 0)
1814 goto scsi_low_cmd_start;
1816 else if (li->li_nqio > 0)
1818 if (li->li_nqio < li->li_maxnqio ||
1819 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1820 goto scsi_low_cmd_start;
1826 cb->ccb_flags &= ~CCB_STARTQ;
1827 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1830 /* clear all error flag bits (for restart) */
1832 cb->ccb_datalen = -1;
1833 cb->ccb_scp.scp_status = ST_UNKNOWN;
1835 /* setup nexus pointer */
1836 slp->sl_Qnexus = cb;
1837 slp->sl_Lnexus = li;
1838 slp->sl_Tnexus = ti;
1840 /* initialize msgsys */
1841 scsi_low_init_msgsys(slp, ti);
1844 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1846 /* CA state or forced abort */
1847 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1849 else if (li->li_state >= SCSI_LOW_LUN_OK)
1851 cb->ccb_flags &= ~CCB_INTERNAL;
1852 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1853 if (cb->ccb_msgoutflag != 0)
1855 scsi_low_ccb_message_exec(slp, cb);
1860 cb->ccb_flags |= CCB_INTERNAL;
1861 rv = scsi_low_setup_start(slp, ti, li, cb);
1865 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1867 if (rv == SCSI_LOW_START_QTAG &&
1868 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1873 scsi_low_activate_qtag(cb);
1874 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1875 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1876 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1877 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1878 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1880 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1881 scsi_low_assert_msg(slp, ti, qmsg, 0);
1885 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1886 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1887 cb->ccb_tc = cb->ccb_tcmax;
1889 /* setup saved scsi data pointer */
1890 cb->ccb_sscp = cb->ccb_scp;
1892 /* setup current scsi pointer */
1893 slp->sl_scp = cb->ccb_sscp;
1894 slp->sl_error = cb->ccb_error;
1896 /* assert always an identify msg */
1897 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1900 #ifdef SCSI_LOW_DIAGNOSTIC
1901 scsi_low_msg_log_init(&ti->ti_log_msgin);
1902 scsi_low_msg_log_init(&ti->ti_log_msgout);
1903 #endif /* SCSI_LOW_DIAGNOSTIC */
1905 /* selection start */
1907 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1908 if (rv == SCSI_LOW_START_OK)
1910 #ifdef SCSI_LOW_STATICS
1911 scsi_low_statics.nexus_win ++;
1912 #endif /* SCSI_LOW_STATICS */
1916 scsi_low_arbit_fail(slp, cb);
1917 #ifdef SCSI_LOW_STATICS
1918 scsi_low_statics.nexus_fail ++;
1919 #endif /* SCSI_LOW_STATICS */
1923 scsi_low_arbit_fail(struct scsi_low_softc *slp, struct slccb *cb)
1925 struct targ_info *ti = cb->ti;
1927 scsi_low_deactivate_qtag(cb);
1928 scsi_low_ccb_message_retry(cb);
1929 cb->ccb_flags |= CCB_STARTQ;
1930 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1932 scsi_low_bus_release(slp, ti);
1935 if (slp->sl_disc == 0)
1937 #ifdef SCSI_LOW_DIAGNOSTIC
1938 kprintf("%s: try selection again\n", slp->sl_xname);
1939 #endif /* SCSI_LOW_DIAGNOSTIC */
1940 slp->sl_retry_sel = 1;
1945 scsi_low_bus_release(struct scsi_low_softc *slp, struct targ_info *ti)
1947 if (ti->ti_disc > 0)
1949 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1953 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1956 /* clear all nexus pointer */
1957 slp->sl_Qnexus = NULL;
1958 slp->sl_Lnexus = NULL;
1959 slp->sl_Tnexus = NULL;
1961 /* clear selection assert */
1962 slp->sl_selid = NULL;
1964 /* clear nexus data */
1965 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1967 /* clear phase change counter */
1968 slp->sl_ph_count = 0;
1972 scsi_low_setup_done(struct scsi_low_softc *slp, struct slccb *cb)
1974 struct targ_info *ti;
1975 struct lun_info *li;
1980 if (cb->ccb_rcnt >= slp->sl_max_retry)
1982 cb->ccb_error |= ABORTIO;
1983 return SCSI_LOW_DONE_COMPLETE;
1986 /* XXX: special huck for selection timeout */
1987 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1988 (cb->ccb_error & SELTIMEOUTIO) != 0)
1990 cb->ccb_error |= ABORTIO;
1991 return SCSI_LOW_DONE_COMPLETE;
1994 switch(li->li_state)
1996 case SCSI_LOW_LUN_INQ:
1997 if (cb->ccb_error != 0)
2000 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2004 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2006 else if ((li->li_inq.sd_version & 7) >= 2 ||
2007 (li->li_inq.sd_len >= 4))
2009 if ((li->li_inq.sd_support & 0x2) == 0)
2010 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2011 if ((li->li_inq.sd_support & 0x8) == 0)
2012 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2015 if ((li->li_inq.sd_support & 0x10) == 0)
2016 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2017 if ((li->li_inq.sd_support & 0x20) == 0)
2018 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2019 if ((li->li_inq.sd_support & 0x40) == 0)
2020 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2025 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2028 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2030 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2032 scsi_low_calcf_target(ti);
2033 scsi_low_calcf_lun(li);
2036 case SCSI_LOW_LUN_MODEQ:
2037 if (cb->ccb_error != 0)
2039 if (cb->ccb_error & SENSEIO)
2041 #ifdef SCSI_LOW_DEBUG
2042 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2044 kprintf("SENSE: [%x][%x][%x][%x][%x]\n",
2045 (u_int) cb->ccb_sense.error_code,
2046 (u_int) cb->ccb_sense.segment,
2047 (u_int) cb->ccb_sense.flags,
2048 (u_int) cb->ccb_sense.add_sense_code,
2049 (u_int) cb->ccb_sense.add_sense_code_qual);
2051 #endif /* SCSI_LOW_DEBUG */
2055 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2058 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2060 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2061 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2063 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2064 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2065 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2067 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2068 scsi_low_calcf_lun(li);
2076 if (li->li_state == SCSI_LOW_LUN_OK)
2078 scsi_low_calcf_target(ti);
2079 scsi_low_calcf_lun(li);
2080 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2081 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2083 scsi_low_calcf_show(li);
2088 return SCSI_LOW_DONE_RETRY;
2092 scsi_low_done(struct scsi_low_softc *slp, struct slccb *cb)
2096 if (cb->ccb_error == 0)
2098 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2100 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2102 * SCSI-2 draft suggests
2103 * page 0x0a QErr bit determins if
2104 * the target aborts or continues
2105 * the queueing io's after CA state resolved.
2106 * However many targets seem not to support
2107 * the page 0x0a. Thus we should manually clear the
2108 * queuing io's after CA state.
2110 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2113 cb->ccb_flags |= CCB_CLEARQ;
2116 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2118 if ((cb->ccb_flags & CCB_SENSE) != 0)
2119 cb->ccb_error |= (SENSEIO | ABORTIO);
2120 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2122 else switch (cb->ccb_sscp.scp_status)
2128 if (cb->ccb_datalen == 0 ||
2129 cb->ccb_scp.scp_datalen == 0)
2132 if (cb->ccb_scp.scp_cmdlen > 0 &&
2133 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2134 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2137 cb->ccb_error |= PDMAERR;
2142 cb->ccb_error |= (BUSYERR | STATERR);
2146 cb->ccb_error |= (STATERR | ABORTIO);
2151 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2154 cb->ccb_flags |= CCB_SENSE;
2157 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2162 cb->ccb_error |= FATALIO;
2168 if (cb->ccb_flags & CCB_SENSE)
2170 cb->ccb_error |= (SENSEERR | ABORTIO);
2172 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2176 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2178 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2182 /* check a ccb msgout flag */
2183 if (cb->ccb_omsgoutflag != 0)
2185 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2186 SCSI_LOW_MSG_ABORT_QTAG | \
2187 SCSI_LOW_MSG_CLEAR_QTAG | \
2188 SCSI_LOW_MSG_TERMIO)
2190 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2192 cb->ccb_error |= ABORTIO;
2196 /* call OS depend done */
2197 if (cb->osdep != NULL)
2199 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2200 if (rv == EJUSTRETURN)
2203 else if (cb->ccb_error != 0)
2205 if (cb->ccb_rcnt >= slp->sl_max_retry)
2206 cb->ccb_error |= ABORTIO;
2208 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2209 (cb->ccb_error & ABORTIO) == 0)
2213 /* free our target */
2214 #ifdef SCSI_LOW_DEBUG
2215 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2217 kprintf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2218 scsi_low_print(slp, NULL);
2220 #endif /* SCSI_LOW_DEBUG */
2222 scsi_low_deactivate_qtag(cb);
2223 scsi_low_dealloc_qtag(cb);
2224 scsi_low_free_ccb(cb);
2226 return SCSI_LOW_DONE_COMPLETE;
2229 #ifdef SCSI_LOW_DEBUG
2230 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2232 kprintf("** SCSI_LOW_DONE_RETRY ===============\n");
2233 scsi_low_print(slp, NULL);
2235 #endif /* SCSI_LOW_DEBUG */
2238 scsi_low_deactivate_qtag(cb);
2239 scsi_low_ccb_message_retry(cb);
2240 return SCSI_LOW_DONE_RETRY;
2243 /**************************************************************
2245 **************************************************************/
2247 scsi_low_reset_nexus_target(struct scsi_low_softc *slp, struct targ_info *ti,
2250 struct lun_info *li;
2252 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2253 li = LIST_NEXT(li, lun_chain))
2255 scsi_low_reset_nexus_lun(slp, li, fdone);
2256 li->li_state = SCSI_LOW_LUN_SLEEP;
2261 ti->ti_setup_msg = 0;
2262 ti->ti_setup_msg_done = 0;
2264 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2265 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2267 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2268 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2270 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2272 ((*slp->sl_funcs->scsi_low_targ_init)
2273 (slp, ti, SCSI_LOW_INFO_REVOKE));
2275 scsi_low_calcf_target(ti);
2277 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2278 li = LIST_NEXT(li, lun_chain))
2282 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2283 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2285 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2287 ((*slp->sl_funcs->scsi_low_lun_init)
2288 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2290 scsi_low_calcf_lun(li);
2295 scsi_low_reset_nexus(struct scsi_low_softc *slp, int fdone)
2297 struct targ_info *ti;
2298 struct slccb *cb, *topcb;
2300 if ((cb = slp->sl_Qnexus) != NULL)
2302 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2309 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2310 ti = TAILQ_NEXT(ti, ti_chain))
2312 scsi_low_reset_nexus_target(slp, ti, fdone);
2313 scsi_low_bus_release(slp, ti);
2314 scsi_low_init_msgsys(slp, ti);
2319 topcb->ccb_flags |= CCB_STARTQ;
2320 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2324 slp->sl_retry_sel = 0;
2325 slp->sl_flags &= ~HW_PDMASTART;
2330 static char tw_chars[] = "|/-\\";
2331 #define TWIDDLEWAIT 10000
2334 scsi_low_twiddle_wait(void)
2337 cnputc(tw_chars[tw_pos++]);
2338 tw_pos %= (sizeof(tw_chars) - 1);
2339 SCSI_LOW_DELAY(TWIDDLEWAIT);
2343 scsi_low_bus_reset(struct scsi_low_softc *slp)
2347 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2349 kprintf("%s: try to reset scsi bus ", slp->sl_xname);
2350 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2351 scsi_low_twiddle_wait();
2357 scsi_low_restart(struct scsi_low_softc *slp, int flags, u_char *s)
2362 kprintf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2364 if ((error = scsi_low_init(slp, flags)) != 0)
2367 scsi_low_start(slp);
2371 /**************************************************************
2372 * disconnect and reselect
2373 **************************************************************/
2374 #define MSGCMD_LUN(msg) (msg & 0x07)
2376 static struct slccb *
2377 scsi_low_establish_ccb(struct targ_info *ti, struct lun_info *li, scsi_low_tag_t tag)
2379 struct scsi_low_softc *slp = ti->ti_sc;
2385 cb = TAILQ_FIRST(&li->li_discq);
2386 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2387 if (cb->ccb_tag == tag)
2392 * establish our ccb nexus
2395 #ifdef SCSI_LOW_DEBUG
2396 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2398 kprintf("%s: nexus(0x%lx) abort check start\n",
2399 slp->sl_xname, (u_long) cb);
2400 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2401 scsi_low_revoke_ccb(slp, cb, 1);
2405 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2407 if (cb->ccb_omsgoutflag == 0)
2408 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2410 #endif /* SCSI_LOW_DEBUG */
2412 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2413 cb->ccb_flags &= ~CCB_DISCQ;
2414 slp->sl_Qnexus = cb;
2416 slp->sl_scp = cb->ccb_sscp;
2417 slp->sl_error |= cb->ccb_error;
2423 /* inform "ccb nexus established" to the host driver */
2424 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2427 if (cb->ccb_msgoutflag != 0)
2429 scsi_low_ccb_message_exec(slp, cb);
2436 scsi_low_reselected(struct scsi_low_softc *slp, u_int targ)
2438 struct targ_info *ti;
2443 * Check select vs reselected collision.
2446 if ((cb = slp->sl_selid) != NULL)
2448 scsi_low_arbit_fail(slp, cb);
2449 #ifdef SCSI_LOW_STATICS
2450 scsi_low_statics.nexus_conflict ++;
2451 #endif /* SCSI_LOW_STATICS */
2455 * Check if no current active nexus.
2457 if (slp->sl_Tnexus != NULL)
2464 * Check a valid target id asserted ?
2466 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2468 s = "scsi id illegal";
2473 * Check the target scsi status.
2475 ti = slp->sl_ti[targ];
2476 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2478 s = "phase mismatch";
2486 scsi_low_init_msgsys(slp, ti);
2489 * Establish our target nexus
2491 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2492 slp->sl_Tnexus = ti;
2493 #ifdef SCSI_LOW_STATICS
2494 scsi_low_statics.nexus_reselected ++;
2495 #endif /* SCSI_LOW_STATICS */
2499 kprintf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2500 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2501 "reselect: scsi world confused");
2505 /**************************************************************
2506 * cmd out pointer setup
2507 **************************************************************/
2509 scsi_low_cmd(struct scsi_low_softc *slp, struct targ_info *ti)
2511 struct slccb *cb = slp->sl_Qnexus;
2513 slp->sl_ph_count ++;
2519 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2520 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2521 slp->sl_scp.scp_datalen = 0;
2522 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2523 slp->sl_error |= FATALIO;
2524 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2525 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2530 #ifdef SCSI_LOW_DEBUG
2531 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2533 scsi_low_test_cmdlnk(slp, cb);
2535 #endif /* SCSI_LOW_DEBUG */
2540 /**************************************************************
2541 * data out pointer setup
2542 **************************************************************/
2544 scsi_low_data(struct scsi_low_softc *slp, struct targ_info *ti,
2545 struct buf **bp, int direction)
2547 struct slccb *cb = slp->sl_Qnexus;
2549 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2555 slp->sl_error |= (FATALIO | PDMAERR);
2556 slp->sl_scp.scp_datalen = 0;
2557 slp->sl_scp.scp_direction = direction;
2558 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2559 if (ti->ti_ophase != ti->ti_phase)
2564 s = "DATA PHASE: ccb nexus not found";
2566 s = "DATA PHASE: xfer direction mismatch";
2567 SCSI_LOW_INFO(slp, ti, s);
2574 /**************************************************************
2576 **************************************************************/
2577 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2578 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2579 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2580 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2581 #define MSGIN_DATA_LAST 0x30
2583 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2584 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2585 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2586 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2588 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2589 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2590 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2591 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2592 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2593 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2594 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2596 struct scsi_low_msgout_data {
2599 int (*md_msgfunc) (struct scsi_low_softc *);
2600 int (*md_errfunc) (struct scsi_low_softc *, u_int);
2601 #define MSG_RELEASE_ATN 0x0001
2605 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2606 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2607 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2608 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2609 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2610 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2611 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2612 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2613 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2614 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2615 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2616 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2617 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2618 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2619 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2620 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2621 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2624 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2625 static int scsi_low_synch (struct scsi_low_softc *);
2626 static int scsi_low_wide (struct scsi_low_softc *);
2627 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2628 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2629 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2630 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2631 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2632 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2633 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2634 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2635 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2636 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2637 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2639 struct scsi_low_msgin_data {
2641 int (*md_msgfunc) (struct scsi_low_softc *);
2644 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2645 /* 0 */ {1, scsi_low_msginfunc_cc},
2646 /* 1 */ {2, scsi_low_msginfunc_ext},
2647 /* 2 */ {1, scsi_low_msginfunc_sdp},
2648 /* 3 */ {1, scsi_low_msginfunc_rp},
2649 /* 4 */ {1, scsi_low_msginfunc_disc},
2650 /* 5 */ {1, scsi_low_msginfunc_rejop},
2651 /* 6 */ {1, scsi_low_msginfunc_rejop},
2652 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2653 /* 8 */ {1, scsi_low_msginfunc_noop},
2654 /* 9 */ {1, scsi_low_msginfunc_parity},
2655 /* a */ {1, scsi_low_msginfunc_lcc},
2656 /* b */ {1, scsi_low_msginfunc_lcc},
2657 /* c */ {1, scsi_low_msginfunc_rejop},
2658 /* d */ {2, scsi_low_msginfunc_rejop},
2659 /* e */ {1, scsi_low_msginfunc_rejop},
2660 /* f */ {1, scsi_low_msginfunc_rejop},
2661 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2662 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2663 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2664 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2665 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2666 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2667 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2668 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2669 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2670 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2671 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2672 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2673 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2674 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2675 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2676 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2677 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2678 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2679 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2680 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2681 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2682 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2683 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2684 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2685 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2686 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2687 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2688 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2689 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2690 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2691 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2692 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2693 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2696 /**************************************************************
2698 **************************************************************/
2700 scsi_low_msgfunc_synch(struct scsi_low_softc *slp)
2702 struct targ_info *ti = slp->sl_Tnexus;
2703 int ptr = ti->ti_msgoutlen;
2705 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2706 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2707 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2708 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2709 return MSG_EXTEND_SYNCHLEN + 2;
2713 scsi_low_msgfunc_wide(struct scsi_low_softc *slp)
2715 struct targ_info *ti = slp->sl_Tnexus;
2716 int ptr = ti->ti_msgoutlen;
2718 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2719 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2720 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2721 return MSG_EXTEND_WIDELEN + 2;
2725 scsi_low_msgfunc_identify(struct scsi_low_softc *slp)
2727 struct targ_info *ti = slp->sl_Tnexus;
2728 struct lun_info *li = slp->sl_Lnexus;
2729 struct slccb *cb = slp->sl_Qnexus;
2730 int ptr = ti->ti_msgoutlen;
2736 slp->sl_error |= FATALIO;
2737 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2738 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2742 if (scsi_low_is_disconnect_ok(cb) != 0)
2743 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2747 if (ti->ti_phase == PH_MSGOUT)
2749 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2750 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2752 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2756 ti->ti_msgoutstr[ptr + 0] = msg;
2761 scsi_low_msgfunc_abort(struct scsi_low_softc *slp)
2763 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2768 scsi_low_msgfunc_qabort(struct scsi_low_softc *slp)
2770 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2775 scsi_low_msgfunc_reset(struct scsi_low_softc *slp)
2777 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2782 scsi_low_msgfunc_qtag(struct scsi_low_softc *slp)
2784 struct targ_info *ti = slp->sl_Tnexus;
2785 struct slccb *cb = slp->sl_Qnexus;
2786 int ptr = ti->ti_msgoutlen;
2788 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2790 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2795 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2796 if (ti->ti_phase == PH_MSGOUT)
2798 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2805 * The following functions are called when targets give unexpected
2806 * responces in msgin (after msgout).
2809 scsi_low_errfunc_identify(struct scsi_low_softc *slp, u_int msgflags)
2811 if (slp->sl_Lnexus != NULL)
2813 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2814 scsi_low_calcf_lun(slp->sl_Lnexus);
2820 scsi_low_errfunc_synch(struct scsi_low_softc *slp, u_int msgflags)
2822 struct targ_info *ti = slp->sl_Tnexus;
2824 MSGIN_PERIOD(ti) = 0;
2825 MSGIN_OFFSET(ti) = 0;
2826 scsi_low_synch(slp);
2831 scsi_low_errfunc_wide(struct scsi_low_softc *slp, u_int msgflags)
2833 struct targ_info *ti = slp->sl_Tnexus;
2835 MSGIN_WIDTHP(ti) = 0;
2841 scsi_low_errfunc_qtag(struct scsi_low_softc *slp, u_int msgflags)
2843 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2845 if (slp->sl_Qnexus != NULL)
2847 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2849 if (slp->sl_Lnexus != NULL)
2851 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2852 scsi_low_calcf_lun(slp->sl_Lnexus);
2854 kprintf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2861 scsi_low_msgout(struct scsi_low_softc *slp, struct targ_info *ti, u_int fl)
2863 struct scsi_low_msgout_data *mdp;
2866 #ifdef SCSI_LOW_DIAGNOSTIC
2867 if (ti != slp->sl_Tnexus)
2869 scsi_low_print(slp, NULL);
2870 panic("scsi_low_msgout: Target nexus inconsistent");
2872 #endif /* SCSI_LOW_DIAGNOSTIC */
2874 slp->sl_ph_count ++;
2875 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2877 kprintf("%s: too many phase changes\n", slp->sl_xname);
2878 slp->sl_error |= FATALIO;
2879 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2883 * Scsi phase changes.
2884 * Previously msgs asserted are accepted by our target or
2885 * processed by scsi_low_msgin.
2886 * Thus clear all saved informations.
2888 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2890 ti->ti_omsgflags = 0;
2891 ti->ti_emsgflags = 0;
2893 else if (slp->sl_atten == 0)
2896 * We did not assert attention, however still our target required
2897 * msgs. Resend previous msgs.
2899 ti->ti_msgflags |= ti->ti_omsgflags;
2900 ti->ti_omsgflags = 0;
2901 #ifdef SCSI_LOW_DIAGNOSTIC
2902 kprintf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
2903 #endif /* SCSI_LOW_DIAGNOSTIC */
2907 * We have no msgs. send MSG_NOOP (OK?)
2909 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2910 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2915 ti->ti_msgoutlen = 0;
2916 slp->sl_clear_atten = 0;
2917 mdp = &scsi_low_msgout_data[0];
2918 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2920 if ((ti->ti_msgflags & mdp->md_flags) != 0)
2922 ti->ti_omsgflags |= mdp->md_flags;
2923 ti->ti_msgflags &= ~mdp->md_flags;
2924 ti->ti_emsgflags = mdp->md_flags;
2926 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2927 if (mdp->md_msgfunc != NULL)
2928 len = (*mdp->md_msgfunc) (slp);
2932 #ifdef SCSI_LOW_DIAGNOSTIC
2933 scsi_low_msg_log_write(&ti->ti_log_msgout,
2934 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2935 #endif /* SCSI_LOW_DIAGNOSTIC */
2937 ti->ti_msgoutlen += len;
2938 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2940 slp->sl_clear_atten = 1;
2944 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2945 ti->ti_msgflags == 0)
2948 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2953 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2954 slp->sl_clear_atten = 1;
2956 return ti->ti_msgoutlen;
2959 /**************************************************************
2961 **************************************************************/
2963 scsi_low_msginfunc_noop(struct scsi_low_softc *slp)
2969 scsi_low_msginfunc_rejop(struct scsi_low_softc *slp)
2971 struct targ_info *ti = slp->sl_Tnexus;
2972 u_int8_t msg = ti->ti_msgin[0];
2974 kprintf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
2975 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2980 scsi_low_msginfunc_cc(struct scsi_low_softc *slp)
2982 struct lun_info *li;
2984 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2986 /* validate status */
2987 if (slp->sl_Qnexus == NULL)
2990 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2991 li = slp->sl_Lnexus;
2992 switch (slp->sl_scp.scp_status)
2995 li->li_maxnqio = li->li_maxnexus;
3000 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3001 scsi_low_reset_nexus_lun(slp, li, 0);
3009 if (li->li_maxnexus >= li->li_nqio)
3010 li->li_maxnexus = li->li_nqio - 1;
3011 li->li_maxnqio = li->li_maxnexus;
3016 slp->sl_error |= MSGERR;
3026 scsi_low_msginfunc_lcc(struct scsi_low_softc *slp)
3028 struct targ_info *ti;
3029 struct lun_info *li;
3030 struct slccb *ncb, *cb;
3032 ti = slp->sl_Tnexus;
3033 li = slp->sl_Lnexus;
3034 if ((cb = slp->sl_Qnexus) == NULL)
3037 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3038 switch (slp->sl_scp.scp_status)
3042 li->li_maxnqio = li->li_maxnexus;
3046 slp->sl_error |= MSGERR;
3050 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3053 cb->ccb_error |= slp->sl_error;
3054 if (cb->ccb_error != 0)
3057 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3058 ncb = TAILQ_NEXT(ncb, ccb_chain))
3061 goto cmd_link_start;
3066 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3067 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3071 ncb->ccb_flags &= ~CCB_STARTQ;
3072 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3074 scsi_low_dealloc_qtag(ncb);
3075 ncb->ccb_tag = cb->ccb_tag;
3076 ncb->ccb_otag = cb->ccb_otag;
3077 cb->ccb_tag = SCSI_LOW_UNKTAG;
3078 cb->ccb_otag = SCSI_LOW_UNKTAG;
3079 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3080 panic("%s: linked ccb retried", slp->sl_xname);
3082 slp->sl_Qnexus = ncb;
3083 slp->sl_ph_count = 0;
3086 ncb->ccb_datalen = -1;
3087 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3088 ncb->ccb_flags &= ~CCB_INTERNAL;
3090 scsi_low_init_msgsys(slp, ti);
3092 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3094 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3095 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3096 ncb->ccb_tc = ncb->ccb_tcmax;
3098 /* setup saved scsi data pointer */
3099 ncb->ccb_sscp = ncb->ccb_scp;
3100 slp->sl_scp = ncb->ccb_sscp;
3101 slp->sl_error = ncb->ccb_error;
3103 #ifdef SCSI_LOW_DIAGNOSTIC
3104 scsi_low_msg_log_init(&ti->ti_log_msgin);
3105 scsi_low_msg_log_init(&ti->ti_log_msgout);
3106 #endif /* SCSI_LOW_DIAGNOSTIC */
3111 scsi_low_msginfunc_disc(struct scsi_low_softc *slp)
3113 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3118 scsi_low_msginfunc_sdp(struct scsi_low_softc *slp)
3120 struct slccb *cb = slp->sl_Qnexus;
3124 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3125 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3128 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3133 scsi_low_msginfunc_rp(struct scsi_low_softc *slp)
3135 if (slp->sl_Qnexus != NULL)
3136 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3138 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3143 scsi_low_synch(struct scsi_low_softc *slp)
3145 struct targ_info *ti = slp->sl_Tnexus;
3146 u_int period = 0, offset = 0, speed;
3150 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3151 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3152 MSGIN_OFFSET(ti) == 0)
3154 if ((offset = MSGIN_OFFSET(ti)) != 0)
3155 period = MSGIN_PERIOD(ti);
3156 s = offset ? "synchronous" : "async";
3161 * Target seems to be brain damaged.
3162 * Force async transfer.
3164 ti->ti_maxsynch.period = 0;
3165 ti->ti_maxsynch.offset = 0;
3166 kprintf("%s: target brain damaged. async transfer\n",
3171 ti->ti_maxsynch.period = period;
3172 ti->ti_maxsynch.offset = offset;
3174 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3178 * Current period and offset are not acceptable
3180 * The adapter changes max synch and max offset.
3182 kprintf("%s: synch neg failed. retry synch msg neg ...\n",
3187 ti->ti_osynch = ti->ti_maxsynch;
3190 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3194 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3196 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3197 struct slccb *cb = slp->sl_Qnexus;
3199 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3201 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3203 kprintf("%s(%d:*): <%s> offset %d period %dns ",
3204 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3208 speed = 1000 * 10 / (period * 4);
3209 kprintf("%d.%d M/s", speed / 10, speed % 10);
3217 scsi_low_wide(struct scsi_low_softc *slp)
3219 struct targ_info *ti = slp->sl_Tnexus;
3222 ti->ti_width = MSGIN_WIDTHP(ti);
3223 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3227 * Current width is not acceptable for our adapter.
3228 * The adapter changes max width.
3230 kprintf("%s: wide neg failed. retry wide msg neg ...\n",
3235 ti->ti_owidth = ti->ti_width;
3236 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3238 ti->ti_setup_msg_done |=
3239 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3243 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3245 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3246 struct slccb *cb = slp->sl_Qnexus;
3248 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3250 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3252 kprintf("%s(%d:*): transfer width %d bits\n",
3253 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3259 scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *slp)
3261 struct targ_info *ti = slp->sl_Tnexus;
3262 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3264 if (slp->sl_Qnexus != NULL)
3266 if (slp->sl_Qnexus->ccb_tag != etag)
3268 slp->sl_error |= FATALIO;
3269 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3270 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3273 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3275 #ifdef SCSI_LOW_DEBUG
3276 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3278 #endif /* SCSI_LOW_DEBUG */
3280 slp->sl_error |= FATALIO;
3281 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3282 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3288 scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *slp)
3290 struct targ_info *ti = slp->sl_Tnexus;
3291 struct slccb *cb = slp->sl_Qnexus;
3292 int res = (int) ti->ti_msgin[1];
3294 if (cb == NULL || res <= 0 ||
3295 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3296 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3299 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3302 slp->sl_scp.scp_datalen += res;
3303 slp->sl_scp.scp_data -= res;
3304 scsi_low_data_finish(slp);
3309 scsi_low_msginfunc_ext(struct scsi_low_softc *slp)
3311 struct slccb *cb = slp->sl_Qnexus;
3312 struct lun_info *li = slp->sl_Lnexus;
3313 struct targ_info *ti = slp->sl_Tnexus;
3317 if (ti->ti_msginptr == 2)
3319 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3323 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3325 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3329 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3330 count = (int) htonl((long) (*ptr));
3331 if(slp->sl_scp.scp_datalen - count < 0 ||
3332 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3335 slp->sl_scp.scp_datalen -= count;
3336 slp->sl_scp.scp_data += count;
3339 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3343 retry = scsi_low_synch(slp);
3344 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3345 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3347 #ifdef SCSI_LOW_DEBUG
3348 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3350 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3352 #endif /* SCSI_LOW_DEBUG */
3355 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3359 retry = scsi_low_wide(slp);
3360 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3361 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3369 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3374 scsi_low_msginfunc_parity(struct scsi_low_softc *slp)
3376 struct targ_info *ti = slp->sl_Tnexus;
3378 /* only I -> T, invalid! */
3379 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3384 scsi_low_msginfunc_msg_reject(struct scsi_low_softc *slp)
3386 struct targ_info *ti = slp->sl_Tnexus;
3387 struct scsi_low_msgout_data *mdp;
3390 if (ti->ti_emsgflags != 0)
3392 kprintf("%s: msg flags [0x%x] rejected\n",
3393 slp->sl_xname, ti->ti_emsgflags);
3394 msgflags = SCSI_LOW_MSG_REJECT;
3395 mdp = &scsi_low_msgout_data[0];
3396 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3398 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3400 ti->ti_emsgflags &= ~mdp->md_flags;
3401 if (mdp->md_errfunc != NULL)
3402 (*mdp->md_errfunc) (slp, msgflags);
3410 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3411 slp->sl_error |= MSGERR;
3417 scsi_low_msgin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c)
3419 struct scsi_low_msgin_data *sdp;
3420 struct lun_info *li;
3423 #ifdef SCSI_LOW_DIAGNOSTIC
3424 if (ti != slp->sl_Tnexus)
3426 scsi_low_print(slp, NULL);
3427 panic("scsi_low_msgin: Target nexus inconsistent");
3429 #endif /* SCSI_LOW_DIAGNOSTIC */
3432 * Phase changes, clear the pointer.
3434 if (ti->ti_ophase != ti->ti_phase)
3437 ti->ti_msgin_parity_error = 0;
3439 slp->sl_ph_count ++;
3440 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3442 kprintf("%s: too many phase changes\n", slp->sl_xname);
3443 slp->sl_error |= FATALIO;
3444 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3449 * Store a current messages byte into buffer and
3450 * wait for the completion of the current msg.
3452 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3453 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3455 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3456 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3460 * Check parity errors.
3462 if ((c & SCSI_LOW_DATA_PE) != 0)
3464 ti->ti_msgin_parity_error ++;
3465 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3469 if (ti->ti_msgin_parity_error != 0)
3473 * Calculate messages length.
3475 msg = ti->ti_msgin[0];
3476 if (msg < MSGIN_DATA_LAST)
3477 sdp = &scsi_low_msgin_data[msg];
3479 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3481 if (ti->ti_msginlen == 0)
3483 ti->ti_msginlen = sdp->md_len;
3489 if (ti->ti_msginptr < ti->ti_msginlen)
3495 if ((msg & MSG_IDENTIFY) == 0)
3497 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3502 li = slp->sl_Lnexus;
3505 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3508 slp->sl_Lnexus = li;
3509 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3513 if (MSGCMD_LUN(msg) != li->li_lun)
3517 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3519 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3521 #ifdef SCSI_LOW_DEBUG
3522 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3526 #endif /* SCSI_LOW_DEBUG */
3534 * Msg process completed, reset msgin pointer and assert ATN if desired.
3537 slp->sl_error |= FATALIO;
3538 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3539 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3542 if (ti->ti_msginptr < ti->ti_msginlen)
3545 #ifdef SCSI_LOW_DIAGNOSTIC
3546 scsi_low_msg_log_write(&ti->ti_log_msgin,
3547 &ti->ti_msgin[0], ti->ti_msginlen);
3548 #endif /* SCSI_LOW_DIAGNOSTIC */
3554 /**********************************************************
3556 **********************************************************/
3558 scsi_low_disconnected(struct scsi_low_softc *slp, struct targ_info *ti)
3560 struct slccb *cb = slp->sl_Qnexus;
3562 /* check phase completion */
3563 switch (slp->sl_msgphase)
3566 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3567 scsi_low_msginfunc_cc(slp);
3568 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3572 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3573 scsi_low_msginfunc_cc(slp);
3574 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3578 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3579 scsi_low_msginfunc_cc(slp);
3585 struct lun_info *li;
3588 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3589 cb->ccb_flags |= CCB_DISCQ;
3590 cb->ccb_error |= slp->sl_error;
3596 #ifdef SCSI_LOW_STATICS
3597 scsi_low_statics.nexus_disconnected ++;
3598 #endif /* SCSI_LOW_STATICS */
3600 #ifdef SCSI_LOW_DEBUG
3601 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3603 kprintf("## SCSI_LOW_DISCONNECTED ===============\n");
3604 scsi_low_print(slp, NULL);
3606 #endif /* SCSI_LOW_DEBUG */
3610 slp->sl_error |= FATALIO;
3611 if (ti->ti_phase == PH_SELSTART)
3612 slp->sl_error |= SELTIMEOUTIO;
3614 slp->sl_error |= UBFERR;
3623 #ifdef SCSI_LOW_DEBUG
3624 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3626 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3627 (cb->ccb_msgoutflag != 0 ||
3628 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3630 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3633 #endif /* SCSI_LOW_DEBUG */
3635 cb->ccb_error |= slp->sl_error;
3636 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3638 cb->ccb_flags |= CCB_STARTQ;
3639 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3644 scsi_low_bus_release(slp, ti);
3645 scsi_low_start(slp);
3649 /**********************************************************
3651 **********************************************************/
3653 scsi_low_alloc_qtag(struct slccb *cb)
3655 struct lun_info *li = cb->li;
3656 scsi_low_tag_t etag;
3658 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3661 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3662 etag = ffs(li->li_qtagbits);
3666 li->li_qtagbits &= ~(1 << (etag - 1));
3667 cb->ccb_otag = etag;
3670 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3671 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3672 if (li->li_qtagarray[li->li_qd] == 0)
3675 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3676 if (li->li_qtagarray[li->li_qd] == 0)
3682 li->li_qtagarray[li->li_qd] ++;
3683 cb->ccb_otag = (li->li_qd ++);
3685 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3689 scsi_low_dealloc_qtag(struct slccb *cb)
3691 struct lun_info *li = cb->li;
3692 scsi_low_tag_t etag;
3694 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3697 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3698 etag = cb->ccb_otag - 1;
3699 #ifdef SCSI_LOW_DIAGNOSTIC
3700 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3701 panic("scsi_low_dealloc_tag: illegal tag");
3702 #endif /* SCSI_LOW_DIAGNOSTIC */
3703 li->li_qtagbits |= (1 << etag);
3705 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3706 etag = cb->ccb_otag;
3707 #ifdef SCSI_LOW_DIAGNOSTIC
3708 if (etag >= SCSI_LOW_MAXNEXUS)
3709 panic("scsi_low_dealloc_tag: illegal tag");
3710 #endif /* SCSI_LOW_DIAGNOSTIC */
3711 li->li_qtagarray[etag] --;
3712 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3714 cb->ccb_otag = SCSI_LOW_UNKTAG;
3719 scsi_low_revoke_ccb(struct scsi_low_softc *slp, struct slccb *cb, int fdone)
3721 struct targ_info *ti = cb->ti;
3722 struct lun_info *li = cb->li;
3724 #ifdef SCSI_LOW_DIAGNOSTIC
3725 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3726 (CCB_STARTQ | CCB_DISCQ))
3728 panic("%s: ccb in both queue", slp->sl_xname);
3730 #endif /* SCSI_LOW_DIAGNOSTIC */
3732 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3734 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3737 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3739 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3745 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3746 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3749 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3750 (cb->ccb_flags & CCB_NORETRY) != 0))
3752 cb->ccb_error |= FATALIO;
3753 cb->ccb_flags &= ~CCB_AUTOSENSE;
3754 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3755 panic("%s: done ccb retried", slp->sl_xname);
3760 cb->ccb_error |= PENDINGIO;
3761 scsi_low_deactivate_qtag(cb);
3762 scsi_low_ccb_message_retry(cb);
3763 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3769 scsi_low_reset_nexus_lun(struct scsi_low_softc *slp, struct lun_info *li, int fdone)
3771 struct slccb *cb, *ncb, *ecb;
3777 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3779 ncb = TAILQ_NEXT(cb, ccb_chain);
3780 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3784 * presumely keep ordering of io
3786 cb->ccb_flags |= CCB_STARTQ;
3789 TAILQ_INSERT_HEAD(&slp->sl_start,\
3794 TAILQ_INSERT_AFTER(&slp->sl_start,\
3795 ecb, cb, ccb_chain);
3802 /**************************************************************
3804 **************************************************************/
3806 scsi_low_calcf_lun(struct lun_info *li)
3808 struct targ_info *ti = li->li_ti;
3809 struct scsi_low_softc *slp = ti->ti_sc;
3810 u_int cfgflags, diskflags;
3812 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3813 cfgflags = li->li_cfgflags;
3817 diskflags = li->li_diskflags & li->li_quirks;
3820 li->li_flags &= ~SCSI_LOW_DISC;
3821 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3822 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3823 (cfgflags & SCSI_LOW_DISC) != 0)
3824 li->li_flags |= SCSI_LOW_DISC;
3827 li->li_flags |= SCSI_LOW_NOPARITY;
3828 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3829 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3830 (cfgflags & SCSI_LOW_NOPARITY) == 0)
3831 li->li_flags &= ~SCSI_LOW_NOPARITY;
3834 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3835 (cfgflags & SCSI_LOW_QTAG) != 0 &&
3836 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3838 li->li_flags |= SCSI_LOW_QTAG;
3839 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3840 li->li_maxnqio = li->li_maxnexus;
3844 li->li_flags &= ~SCSI_LOW_QTAG;
3845 li->li_maxnexus = 0;
3846 li->li_maxnqio = li->li_maxnexus;
3850 li->li_flags &= ~SCSI_LOW_LINK;
3851 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3852 (diskflags & SCSI_LOW_DISK_LINK) != 0)
3853 li->li_flags |= SCSI_LOW_LINK;
3855 /* compatible flags */
3856 li->li_flags &= ~SCSI_LOW_SYNC;
3857 if (ti->ti_maxsynch.offset > 0)
3858 li->li_flags |= SCSI_LOW_SYNC;
3860 #ifdef SCSI_LOW_DEBUG
3861 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3863 scsi_low_calcf_show(li);
3865 #endif /* SCSI_LOW_DEBUG */
3869 scsi_low_calcf_target(struct targ_info *ti)
3871 struct scsi_low_softc *slp = ti->ti_sc;
3872 u_int offset, period, diskflags;
3874 diskflags = ti->ti_diskflags & ti->ti_quirks;
3877 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
3878 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
3880 offset = ti->ti_maxsynch.offset;
3881 period = ti->ti_maxsynch.period;
3882 if (offset == 0 || period == 0)
3883 offset = period = 0;
3887 offset = period = 0;
3890 ti->ti_maxsynch.offset = offset;
3891 ti->ti_maxsynch.period = period;
3894 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
3895 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
3896 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
3898 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
3899 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3900 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
3902 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
3904 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
3905 ti->ti_maxsynch.period != ti->ti_osynch.period)
3906 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
3907 if (ti->ti_width != ti->ti_owidth)
3908 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
3910 ti->ti_osynch = ti->ti_maxsynch;
3911 ti->ti_owidth = ti->ti_width;
3914 #ifdef SCSI_LOW_DEBUG
3915 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3917 kprintf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
3918 slp->sl_xname, ti->ti_id,
3919 ti->ti_maxsynch.period * 4,
3920 ti->ti_maxsynch.offset,
3923 #endif /* SCSI_LOW_DEBUG */
3927 scsi_low_calcf_show(struct lun_info *li)
3929 struct targ_info *ti = li->li_ti;
3930 struct scsi_low_softc *slp = ti->ti_sc;
3932 kprintf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
3933 slp->sl_xname, ti->ti_id, li->li_lun,
3934 ti->ti_maxsynch.period * 4,
3935 ti->ti_maxsynch.offset,
3937 li->li_flags, SCSI_LOW_BITS);
3940 #ifdef SCSI_LOW_START_UP_CHECK
3941 /**************************************************************
3942 * scsi world start up
3943 **************************************************************/
3944 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
3947 scsi_low_start_up(struct scsi_low_softc *slp)
3949 struct targ_info *ti;
3950 struct lun_info *li;
3954 kprintf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
3956 for (target = 0; target < slp->sl_ntargs; target ++)
3958 if (target == slp->sl_hostid)
3960 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3962 kprintf("%s: scsi_low: target %d (host card)\n",
3963 slp->sl_xname, target);
3968 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3970 kprintf("%s: scsi_low: target %d lun ",
3971 slp->sl_xname, target);
3974 ti = slp->sl_ti[target];
3975 for (lun = 0; lun < slp->sl_nluns; lun ++)
3977 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
3983 li = scsi_low_alloc_li(ti, lun, 1);
3985 scsi_low_enqueue(slp, ti, li, cb,
3986 CCB_AUTOSENSE | CCB_POLLED, 0);
3988 scsi_low_poll(slp, cb);
3990 if (li->li_state != SCSI_LOW_LUN_OK)
3993 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3995 kprintf("%d ", lun);
3999 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4008 scsi_low_poll(struct scsi_low_softc *slp, struct slccb *cb)
4013 while (slp->sl_nio > 0)
4015 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4017 (*slp->sl_funcs->scsi_low_poll) (slp);
4018 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4022 scsi_low_timeout_check(slp);
4027 #endif /* SCSI_LOW_START_UP_CHECK */
4029 /**********************************************************
4031 **********************************************************/
4032 #ifdef SCSI_LOW_DEBUG
4034 scsi_low_test_abort(struct scsi_low_softc *slp, struct targ_info *ti,
4035 struct lun_info *li)
4039 if (li->li_disc > 1)
4041 acb = TAILQ_FIRST(&li->li_discq);
4042 if (scsi_low_abort_ccb(slp, acb) == 0)
4044 kprintf("%s: aborting ccb(0x%lx) start\n",
4045 slp->sl_xname, (u_long) acb);
4051 scsi_low_test_atten(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg)
4053 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4054 scsi_low_assert_msg(slp, ti, msg, 0);
4056 kprintf("%s: atten check OK\n", slp->sl_xname);
4060 scsi_low_test_cmdlnk(struct scsi_low_softc *slp, struct slccb *cb)
4062 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4064 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4067 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4068 slp->sl_scp.scp_cmdlen);
4069 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4070 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4072 #endif /* SCSI_LOW_DEBUG */
4075 scsi_low_info(struct scsi_low_softc *slp, struct targ_info *ti, u_char *s)
4078 slp = LIST_FIRST(&sl_tab);
4082 kprintf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4085 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4086 ti = TAILQ_NEXT(ti, ti_chain))
4088 scsi_low_print(slp, ti);
4093 scsi_low_print(slp, ti);
4097 static u_char *phase[] =
4099 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4100 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4104 scsi_low_print(struct scsi_low_softc *slp, struct targ_info *ti)
4106 struct lun_info *li;
4110 if (ti == NULL || ti == slp->sl_Tnexus)
4112 ti = slp->sl_Tnexus;
4113 li = slp->sl_Lnexus;
4114 cb = slp->sl_Qnexus;
4118 li = LIST_FIRST(&ti->ti_litab);
4119 cb = TAILQ_FIRST(&li->li_discq);
4123 kprintf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4124 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4130 u_int flags = 0, maxnqio = 0, nqio = 0;
4136 flags = li->li_flags;
4137 maxnqio = li->li_maxnqio;
4141 kprintf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4143 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4144 phase[(int) ti->ti_phase], ti->ti_disc,
4149 kprintf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4150 (u_int) cb->ccb_scp.scp_cmd[0],
4151 cb->ccb_scp.scp_cmdlen,
4153 cb->ccb_scp.scp_datalen,
4154 (u_int) cb->ccb_sscp.scp_status,
4155 cb->ccb_error, SCSI_LOW_ERRORBITS);
4158 kprintf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4159 (u_int) (ti->ti_msginptr),
4160 (u_int) (ti->ti_msgin[0]),
4161 (u_int) (ti->ti_msgin[1]),
4162 (u_int) (ti->ti_msgin[2]),
4163 (u_int) (ti->ti_msgin[3]),
4164 (u_int) (ti->ti_msgin[4]),
4167 kprintf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4168 (u_int) ti->ti_msgflags,
4169 (u_int) (ti->ti_msgoutstr[0]),
4170 (u_int) (ti->ti_msgoutstr[1]),
4171 (u_int) (ti->ti_msgoutstr[2]),
4172 (u_int) (ti->ti_msgoutstr[3]),
4173 (u_int) (ti->ti_msgoutstr[4]),
4175 flags, SCSI_LOW_BITS);
4177 #ifdef SCSI_LOW_DIAGNOSTIC
4178 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4179 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4180 #endif /* SCSI_LOW_DIAGNOSTIC */
4184 kprintf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4185 (u_long) sp->scp_data,
4187 (u_int) sp->scp_status,
4188 slp->sl_error, SCSI_LOW_ERRORBITS);