1 /* $NecBSD: 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 */
14 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
15 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
17 #define SCSI_LOW_FLAGS_QUIRKS_OK
20 * [NetBSD for NEC PC-98 series]
21 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
22 * NetBSD/pc98 porting staff. All rights reserved.
23 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
24 * Naofumi HONDA. All rights reserved.
26 * [Ported for FreeBSD CAM]
27 * Copyright (c) 2000, 2001
28 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
34 * 1. Redistributions of source code must retain the above copyright
35 * notice, this list of conditions and the following disclaimer.
36 * 2. Redistributions in binary form must reproduce the above copyright
37 * notice, this list of conditions and the following disclaimer in the
38 * documentation and/or other materials provided with the distribution.
39 * 3. The name of the author may not be used to endorse or promote products
40 * derived from this software without specific prior written permission.
42 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
43 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
44 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
45 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
46 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
47 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
51 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
52 * POSSIBILITY OF SUCH DAMAGE.
55 /* <On the nexus establishment>
56 * When our host is reselected,
57 * nexus establish processes are little complicated.
58 * Normal steps are followings:
59 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
60 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
61 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
70 #include <sys/queue.h>
71 #include <sys/malloc.h>
72 #include <sys/errno.h>
75 #include <cam/cam_ccb.h>
76 #include <cam/cam_sim.h>
77 #include <cam/cam_debug.h>
78 #include <cam/cam_periph.h>
79 #include <cam/cam_xpt_periph.h>
81 #include <cam/scsi/scsi_all.h>
82 #include <cam/scsi/scsi_message.h>
84 #include <cam/scsi/scsi_low.h>
88 /**************************************************************
90 **************************************************************/
91 #define SCSI_LOW_POLL_HZ 1000
93 /* functions return values */
94 #define SCSI_LOW_START_NO_QTAG 0
95 #define SCSI_LOW_START_QTAG 1
97 #define SCSI_LOW_DONE_COMPLETE 0
98 #define SCSI_LOW_DONE_RETRY 1
100 /* internal disk flags */
101 #define SCSI_LOW_DISK_DISC 0x00000001
102 #define SCSI_LOW_DISK_QTAG 0x00000002
103 #define SCSI_LOW_DISK_LINK 0x00000004
104 #define SCSI_LOW_DISK_PARITY 0x00000008
105 #define SCSI_LOW_DISK_SYNC 0x00010000
106 #define SCSI_LOW_DISK_WIDE_16 0x00020000
107 #define SCSI_LOW_DISK_WIDE_32 0x00040000
108 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
109 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
110 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
112 static MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
114 /**************************************************************
116 **************************************************************/
117 /* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *);
118 static void scsi_low_engage(void *);
119 static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
120 static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
121 static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
122 static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
123 static void scsi_low_twiddle_wait(void);
124 static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
125 static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
126 static void scsi_low_calcf_lun(struct lun_info *);
127 static void scsi_low_calcf_target(struct targ_info *);
128 static void scsi_low_calcf_show(struct lun_info *);
129 static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
130 static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
131 static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
132 static int scsi_low_init(struct scsi_low_softc *, u_int);
133 static void scsi_low_start(struct scsi_low_softc *);
134 static void scsi_low_free_ti(struct scsi_low_softc *);
136 static int scsi_low_alloc_qtag(struct slccb *);
137 static int scsi_low_dealloc_qtag(struct slccb *);
138 static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
139 static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
140 static void scsi_low_unit_ready_cmd(struct slccb *);
141 static void scsi_low_timeout(void *);
142 static int scsi_low_timeout_check(struct scsi_low_softc *);
143 #ifdef SCSI_LOW_START_UP_CHECK
144 static int scsi_low_start_up(struct scsi_low_softc *);
145 #endif /* SCSI_LOW_START_UP_CHECK */
146 static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
147 static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
149 int scsi_low_version_major = 2;
150 int scsi_low_version_minor = 17;
152 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
153 static struct mtx sl_tab_lock;
154 MTX_SYSINIT(sl_tab_lock, &sl_tab_lock, "scsi low table", MTX_DEF);
156 /**************************************************************
157 * Debug, Run test and Statics
158 **************************************************************/
159 #ifdef SCSI_LOW_INFO_DETAIL
160 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
161 #else /* !SCSI_LOW_INFO_DETAIL */
162 #define SCSI_LOW_INFO(slp, ti, s) device_printf((slp)->sl_dev, "%s\n", (s))
163 #endif /* !SCSI_LOW_INFO_DETAIL */
165 #ifdef SCSI_LOW_STATICS
166 static struct scsi_low_statics {
169 int nexus_disconnected;
170 int nexus_reselected;
173 #endif /* SCSI_LOW_STATICS */
175 #ifdef SCSI_LOW_DEBUG
176 #define SCSI_LOW_DEBUG_DONE 0x00001
177 #define SCSI_LOW_DEBUG_DISC 0x00002
178 #define SCSI_LOW_DEBUG_SENSE 0x00004
179 #define SCSI_LOW_DEBUG_CALCF 0x00008
180 #define SCSI_LOW_DEBUG_ACTION 0x10000
181 int scsi_low_debug = 0;
183 #define SCSI_LOW_MAX_ATTEN_CHECK 32
184 #define SCSI_LOW_ATTEN_CHECK 0x0001
185 #define SCSI_LOW_CMDLNK_CHECK 0x0002
186 #define SCSI_LOW_ABORT_CHECK 0x0004
187 #define SCSI_LOW_NEXUS_CHECK 0x0008
188 int scsi_low_test = 0;
189 int scsi_low_test_id = 0;
191 static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
192 static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
193 static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int);
194 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
195 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
196 #define SCSI_LOW_DEBUG_GO(fl, id) \
197 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
198 #endif /* SCSI_LOW_DEBUG */
200 /**************************************************************
202 **************************************************************/
203 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
204 GENERIC_CCB(scsi_low, slccb, ccb_chain)
206 /**************************************************************
208 **************************************************************/
209 #define SCSI_LOW_INLINE static __inline
210 SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
211 SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
212 SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
213 SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
214 SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
215 SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
216 SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
219 scsi_low_activate_qtag(cb)
222 struct lun_info *li = cb->li;
224 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
228 cb->ccb_tag = cb->ccb_otag;
232 scsi_low_deactivate_qtag(cb)
235 struct lun_info *li = cb->li;
237 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
241 cb->ccb_tag = SCSI_LOW_UNKTAG;
245 scsi_low_ccb_message_exec(slp, cb)
246 struct scsi_low_softc *slp;
250 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
251 cb->ccb_msgoutflag = 0;
255 scsi_low_ccb_message_assert(cb, msg)
260 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
264 scsi_low_ccb_message_retry(cb)
267 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
271 scsi_low_ccb_message_clear(cb)
274 cb->ccb_msgoutflag = 0;
278 scsi_low_init_msgsys(slp, ti)
279 struct scsi_low_softc *slp;
280 struct targ_info *ti;
284 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
285 SCSI_LOW_DEASSERT_ATN(slp);
286 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
289 /*=============================================================
290 * START OF OS switch (All OS depend fucntions should be here)
291 =============================================================*/
292 /* common os depend utitlities */
293 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
294 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
295 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
297 static u_int8_t scsi_low_cmd_flags[256] = {
298 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
299 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
300 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
301 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
302 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
305 struct scsi_low_error_code {
310 static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
311 static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
313 static struct slccb *
314 scsi_low_find_ccb(slp, target, lun, osdep)
315 struct scsi_low_softc *slp;
319 struct targ_info *ti;
323 ti = slp->sl_ti[target];
324 li = scsi_low_alloc_li(ti, lun, 0);
328 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
331 TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
333 if (cb->osdep == osdep)
337 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
339 if (cb->osdep == osdep)
346 scsi_low_translate_error_code(cb, tp)
348 struct scsi_low_error_code *tp;
351 if (cb->ccb_error == 0)
352 return tp->error_code;
354 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
356 return tp->error_code;
359 /**************************************************************
360 * SCSI INTERFACE (CAM)
361 **************************************************************/
362 #define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
363 #define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
364 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
366 static void scsi_low_poll_cam(struct cam_sim *);
367 void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
369 static int scsi_low_attach_cam(struct scsi_low_softc *);
370 static int scsi_low_detach_cam(struct scsi_low_softc *);
371 static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
372 static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
374 struct scsi_low_error_code scsi_low_error_code_cam[] = {
376 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
377 {SENSEERR, CAM_AUTOSENSE_FAIL},
378 {UACAERR, CAM_SCSI_STATUS_ERROR},
379 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
380 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
381 {TIMEOUTIO, CAM_CMD_TIMEOUT},
382 {PDMAERR, CAM_DATA_RUN_ERR},
383 {PARITYERR, CAM_UNCOR_PARITY},
384 {UBFERR, CAM_UNEXP_BUSFREE},
385 {ABORTIO, CAM_REQ_ABORTED},
386 {-1, CAM_UNREC_HBA_ERROR}
389 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
392 * Please check a polling hz, currently we assume scsi_low_poll() is
395 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
398 scsi_low_poll_cam(sim)
401 struct scsi_low_softc *slp = SIM2SLP(sim);
403 SCSI_LOW_ASSERT_LOCKED(slp);
404 (*slp->sl_funcs->scsi_low_poll) (slp);
406 if (slp->sl_poll_count ++ >=
407 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
409 slp->sl_poll_count = 0;
410 scsi_low_timeout_check(slp);
415 scsi_low_scsi_action_cam(sim, ccb)
419 struct scsi_low_softc *slp = SIM2SLP(sim);
420 struct targ_info *ti;
423 u_int lun, flags, msg, target;
426 SCSI_LOW_ASSERT_LOCKED(slp);
427 target = (u_int) (ccb->ccb_h.target_id);
428 lun = (u_int) ccb->ccb_h.target_lun;
430 #ifdef SCSI_LOW_DEBUG
431 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
433 device_printf(slp->sl_dev,
434 "cam_action: func code 0x%x target: %d, lun: %d\n",
435 ccb->ccb_h.func_code, target, lun);
437 #endif /* SCSI_LOW_DEBUG */
439 switch (ccb->ccb_h.func_code) {
440 case XPT_SCSI_IO: /* Execute the requested I/O operation */
441 #ifdef SCSI_LOW_DIAGNOSTIC
442 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
444 device_printf(slp->sl_dev, "invalid target/lun\n");
445 ccb->ccb_h.status = CAM_REQ_INVALID;
449 #endif /* SCSI_LOW_DIAGNOSTIC */
451 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
452 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
457 ti = slp->sl_ti[target];
460 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
461 flags = CCB_AUTOSENSE | CCB_SCSIIO;
465 li = scsi_low_alloc_li(ti, lun, 1);
467 if (ti->ti_setup_msg != 0)
469 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
472 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
474 #ifdef SCSI_LOW_DEBUG
475 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
477 scsi_low_test_abort(slp, ti, li);
479 #endif /* SCSI_LOW_DEBUG */
482 case XPT_EN_LUN: /* Enable LUN as a target */
483 case XPT_TARGET_IO: /* Execute target I/O request */
484 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
485 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
487 ccb->ccb_h.status = CAM_REQ_INVALID;
491 case XPT_ABORT: /* Abort the specified CCB */
492 #ifdef SCSI_LOW_DIAGNOSTIC
493 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
495 device_printf(slp->sl_dev, "invalid target/lun\n");
496 ccb->ccb_h.status = CAM_REQ_INVALID;
500 #endif /* SCSI_LOW_DIAGNOSTIC */
502 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
503 rv = scsi_low_abort_ccb(slp, cb);
506 ccb->ccb_h.status = CAM_REQ_CMP;
508 ccb->ccb_h.status = CAM_REQ_INVALID;
512 case XPT_SET_TRAN_SETTINGS: {
513 struct ccb_trans_settings_scsi *scsi;
514 struct ccb_trans_settings_spi *spi;
515 struct ccb_trans_settings *cts;
518 #ifdef SCSI_LOW_DIAGNOSTIC
519 if (target == CAM_TARGET_WILDCARD)
521 device_printf(slp->sl_dev, "invalid target\n");
522 ccb->ccb_h.status = CAM_REQ_INVALID;
526 #endif /* SCSI_LOW_DIAGNOSTIC */
528 ti = slp->sl_ti[target];
529 if (lun == CAM_LUN_WILDCARD)
532 scsi = &cts->proto_specific.scsi;
533 spi = &cts->xport_specific.spi;
534 if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH |
535 CTS_SPI_VALID_SYNC_RATE |
536 CTS_SPI_VALID_SYNC_OFFSET)) != 0)
538 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
539 val = spi->bus_width;
540 if (val < ti->ti_width)
543 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
544 val = spi->sync_period;
545 if (val == 0 || val > ti->ti_maxsynch.period)
546 ti->ti_maxsynch.period = val;
548 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
549 val = spi->sync_offset;
550 if (val < ti->ti_maxsynch.offset)
551 ti->ti_maxsynch.offset = val;
553 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
554 scsi_low_calcf_target(ti);
557 if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 ||
558 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
560 li = scsi_low_alloc_li(ti, lun, 1);
561 if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) {
562 li->li_quirks |= SCSI_LOW_DISK_DISC;
564 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
567 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
568 li->li_quirks |= SCSI_LOW_DISK_QTAG;
570 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
572 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
573 scsi_low_calcf_target(ti);
574 scsi_low_calcf_lun(li);
575 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
576 scsi_low_calcf_show(li);
579 ccb->ccb_h.status = CAM_REQ_CMP;
584 case XPT_GET_TRAN_SETTINGS: {
585 struct ccb_trans_settings *cts;
589 #ifdef SCSI_LOW_DIAGNOSTIC
590 if (target == CAM_TARGET_WILDCARD)
592 device_printf(slp->sl_dev, "invalid target\n");
593 ccb->ccb_h.status = CAM_REQ_INVALID;
597 #endif /* SCSI_LOW_DIAGNOSTIC */
598 ti = slp->sl_ti[target];
599 if (lun == CAM_LUN_WILDCARD)
602 li = scsi_low_alloc_li(ti, lun, 1);
603 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
604 struct ccb_trans_settings_scsi *scsi =
605 &cts->proto_specific.scsi;
606 struct ccb_trans_settings_spi *spi =
607 &cts->xport_specific.spi;
608 #ifdef SCSI_LOW_DIAGNOSTIC
609 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
611 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
612 device_printf(slp->sl_dev,
613 "invalid GET_TRANS_CURRENT_SETTINGS call\n");
616 #endif /* SCSI_LOW_DIAGNOSTIC */
617 cts->protocol = PROTO_SCSI;
618 cts->protocol_version = SCSI_REV_2;
619 cts->transport = XPORT_SPI;
620 cts->transport_version = 2;
622 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
623 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
625 diskflags = li->li_diskflags & li->li_cfgflags;
626 if (diskflags & SCSI_LOW_DISK_DISC)
627 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
628 if (diskflags & SCSI_LOW_DISK_QTAG)
629 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
631 spi->sync_period = ti->ti_maxsynch.period;
632 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
633 spi->sync_offset = ti->ti_maxsynch.offset;
634 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
636 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
637 spi->bus_width = ti->ti_width;
639 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
640 scsi->valid = CTS_SCSI_VALID_TQ;
641 spi->valid |= CTS_SPI_VALID_DISC;
645 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
651 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
652 cam_calc_geometry(&ccb->ccg, /*extended*/1);
657 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
658 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
659 ccb->ccb_h.status = CAM_REQ_CMP;
663 case XPT_TERM_IO: /* Terminate the I/O process */
664 ccb->ccb_h.status = CAM_REQ_INVALID;
668 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
669 #ifdef SCSI_LOW_DIAGNOSTIC
670 if (target == CAM_TARGET_WILDCARD)
672 device_printf(slp->sl_dev, "invalid target\n");
673 ccb->ccb_h.status = CAM_REQ_INVALID;
677 #endif /* SCSI_LOW_DIAGNOSTIC */
679 msg = SCSI_LOW_MSG_RESET;
680 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
682 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
687 ti = slp->sl_ti[target];
688 if (lun == CAM_LUN_WILDCARD)
692 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
693 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
695 flags = CCB_NORETRY | CCB_URGENT;
697 li = scsi_low_alloc_li(ti, lun, 1);
698 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
701 case XPT_PATH_INQ: { /* Path routing inquiry */
702 struct ccb_pathinq *cpi = &ccb->cpi;
704 cpi->version_num = scsi_low_version_major;
705 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
706 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
707 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
708 cpi->hba_inquiry |= PI_WIDE_16;
709 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
710 cpi->hba_inquiry |= PI_WIDE_32;
711 if (ti->ti_maxsynch.offset > 0)
712 cpi->hba_inquiry |= PI_SDTR_ABLE;
713 cpi->target_sprt = 0;
715 cpi->hba_eng_cnt = 0;
716 cpi->max_target = slp->sl_ntargs - 1;
717 cpi->max_lun = slp->sl_nluns - 1;
718 cpi->initiator_id = slp->sl_hostid;
719 cpi->bus_id = cam_sim_bus(sim);
720 cpi->base_transfer_speed = 3300;
721 cpi->transport = XPORT_SPI;
722 cpi->transport_version = 2;
723 cpi->protocol = PROTO_SCSI;
724 cpi->protocol_version = SCSI_REV_2;
725 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
726 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
727 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
728 cpi->unit_number = cam_sim_unit(sim);
729 cpi->ccb_h.status = CAM_REQ_CMP;
735 printf("scsi_low: non support func_code = %d ",
736 ccb->ccb_h.func_code);
737 ccb->ccb_h.status = CAM_REQ_INVALID;
744 scsi_low_attach_cam(slp)
745 struct scsi_low_softc *slp;
747 struct cam_devq *devq;
750 devq = cam_simq_alloc(SCSI_LOW_NCCB);
755 * ask the adapter what subunits are present
757 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
758 slp->sl_sim = cam_sim_alloc(scsi_low_scsi_action_cam,
760 device_get_name(slp->sl_dev), slp,
761 device_get_unit(slp->sl_dev), &slp->sl_lock,
762 slp->sl_openings, tagged_openings, devq);
764 if (slp->sl_sim == NULL) {
770 if (xpt_bus_register(slp->sl_sim, slp->sl_dev, 0) != CAM_SUCCESS) {
771 cam_sim_free(slp->sl_sim, TRUE);
772 SCSI_LOW_UNLOCK(slp);
776 if (xpt_create_path(&slp->sl_path, /*periph*/NULL,
777 cam_sim_path(slp->sl_sim), CAM_TARGET_WILDCARD,
778 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
779 xpt_bus_deregister(cam_sim_path(slp->sl_sim));
780 cam_sim_free(slp->sl_sim, /*free_simq*/TRUE);
781 SCSI_LOW_UNLOCK(slp);
785 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
786 SCSI_LOW_UNLOCK(slp);
791 scsi_low_detach_cam(slp)
792 struct scsi_low_softc *slp;
795 xpt_async(AC_LOST_DEVICE, slp->sl_path, NULL);
796 xpt_free_path(slp->sl_path);
797 xpt_bus_deregister(cam_sim_path(slp->sl_sim));
798 cam_sim_free(slp->sl_sim, /* free_devq */ TRUE);
803 scsi_low_ccb_setup_cam(slp, cb)
804 struct scsi_low_softc *slp;
807 union ccb *ccb = (union ccb *) cb->osdep;
809 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
811 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
812 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
813 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
814 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
815 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
816 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
817 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
818 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
819 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
823 scsi_low_unit_ready_cmd(cb);
825 return SCSI_LOW_START_QTAG;
829 scsi_low_done_cam(slp, cb)
830 struct scsi_low_softc *slp;
835 ccb = (union ccb *) cb->osdep;
836 if (cb->ccb_error == 0)
838 ccb->ccb_h.status = CAM_REQ_CMP;
843 if (cb->ccb_rcnt >= slp->sl_max_retry)
844 cb->ccb_error |= ABORTIO;
846 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
847 (cb->ccb_error & ABORTIO) == 0)
850 if ((cb->ccb_error & SENSEIO) != 0)
852 memcpy(&ccb->csio.sense_data,
854 sizeof(ccb->csio.sense_data));
857 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
858 &scsi_low_error_code_cam[0]);
860 #ifdef SCSI_LOW_DIAGNOSTIC
861 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
862 cb->ccb_scp.scp_cmdlen > 0 &&
863 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
864 SCSI_LOW_CMD_ABORT_WARNING) != 0)
866 device_printf(slp->sl_dev,
867 "WARNING: scsi_low IO abort\n");
868 scsi_low_print(slp, NULL);
870 #endif /* SCSI_LOW_DIAGNOSTIC */
873 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
874 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
876 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
877 ccb->csio.scsi_status = 0; /* XXX */
879 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
881 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
886 /**************************************************************
887 * scsi low deactivate and activate
888 **************************************************************/
890 scsi_low_is_busy(slp)
891 struct scsi_low_softc *slp;
900 scsi_low_deactivate(slp)
901 struct scsi_low_softc *slp;
904 slp->sl_flags |= HW_INACTIVE;
905 callout_stop(&slp->sl_timeout_timer);
906 callout_stop(&slp->sl_engage_timer);
911 scsi_low_activate(slp)
912 struct scsi_low_softc *slp;
916 slp->sl_flags &= ~HW_INACTIVE;
917 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
919 slp->sl_flags |= HW_INACTIVE;
923 slp->sl_timeout_count = 0;
924 callout_reset(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ,
925 scsi_low_timeout, slp);
929 /**************************************************************
931 **************************************************************/
932 #ifdef SCSI_LOW_DIAGNOSTIC
933 static void scsi_low_msg_log_init(struct scsi_low_msg_log *);
934 static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int);
935 static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int);
938 scsi_low_msg_log_init(slmlp)
939 struct scsi_low_msg_log *slmlp;
946 scsi_low_msg_log_write(slmlp, datap, len)
947 struct scsi_low_msg_log *slmlp;
953 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
956 ptr = slmlp->slml_ptr ++;
957 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
958 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
959 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
960 slmlp->slml_msg[ptr].msg[ind] = 0;
964 scsi_low_msg_log_show(slmlp, s, len)
965 struct scsi_low_msg_log *slmlp;
971 printf("%s: (%d) ", s, slmlp->slml_ptr);
972 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
974 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
977 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
983 #endif /* SCSI_LOW_DIAGNOSTIC */
985 /**************************************************************
987 **************************************************************/
992 struct scsi_low_softc *slp = arg;
994 SCSI_LOW_ASSERT_LOCKED(slp);
995 switch (slp->sl_rstep)
999 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1000 callout_reset(&slp->sl_engage_timer, hz / 1000,
1001 scsi_low_engage, slp);
1006 slp->sl_flags &= ~HW_RESUME;
1007 scsi_low_start(slp);
1016 scsi_low_init(slp, flags)
1017 struct scsi_low_softc *slp;
1022 slp->sl_flags |= HW_INITIALIZING;
1024 /* clear power control timeout */
1025 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1027 callout_stop(&slp->sl_engage_timer);
1028 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1030 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1033 /* reset current nexus */
1034 scsi_low_reset_nexus(slp, flags);
1035 if ((slp->sl_flags & HW_INACTIVE) != 0)
1041 if (flags != SCSI_LOW_RESTART_SOFT)
1043 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1047 slp->sl_flags &= ~HW_INITIALIZING;
1051 /**************************************************************
1053 **************************************************************/
1054 static struct lun_info *
1055 scsi_low_alloc_li(ti, lun, alloc)
1056 struct targ_info *ti;
1060 struct scsi_low_softc *slp = ti->ti_sc;
1061 struct lun_info *li;
1063 li = LIST_FIRST(&ti->ti_litab);
1066 if (li->li_lun == lun)
1069 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1071 if (li->li_lun == lun)
1073 LIST_REMOVE(li, lun_chain);
1074 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1083 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1085 panic("no lun info mem");
1087 bzero(li, ti->ti_lunsize);
1091 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1093 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1094 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1095 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1096 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1097 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1099 li->li_qtagbits = (u_int) -1;
1101 TAILQ_INIT(&li->li_discq);
1102 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1104 /* host specific structure initialization per lun */
1105 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1106 (*slp->sl_funcs->scsi_low_lun_init)
1107 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1108 scsi_low_calcf_lun(li);
1112 /**************************************************************
1113 * allocate targ_info
1114 **************************************************************/
1115 static struct targ_info *
1116 scsi_low_alloc_ti(slp, targ)
1117 struct scsi_low_softc *slp;
1120 struct targ_info *ti;
1122 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1123 TAILQ_INIT(&slp->sl_titab);
1125 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1127 panic("%s short of memory", device_get_nameunit(slp->sl_dev));
1129 bzero(ti, slp->sl_targsize);
1133 slp->sl_ti[targ] = ti;
1134 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1135 LIST_INIT(&ti->ti_litab);
1137 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1138 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1139 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1140 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1141 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1142 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1144 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1146 (*slp->sl_funcs->scsi_low_targ_init)
1147 (slp, ti, SCSI_LOW_INFO_ALLOC);
1149 scsi_low_calcf_target(ti);
1154 scsi_low_free_ti(slp)
1155 struct scsi_low_softc *slp;
1157 struct targ_info *ti, *tib;
1158 struct lun_info *li, *nli;
1160 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1162 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1164 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1166 (*slp->sl_funcs->scsi_low_lun_init)
1167 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1169 nli = LIST_NEXT(li, lun_chain);
1173 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1175 (*slp->sl_funcs->scsi_low_targ_init)
1176 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1178 tib = TAILQ_NEXT(ti, ti_chain);
1183 /**************************************************************
1185 **************************************************************/
1187 scsi_low_bus_idle(slp)
1188 struct scsi_low_softc *slp;
1191 slp->sl_retry_sel = 0;
1192 if (slp->sl_Tnexus == NULL)
1193 scsi_low_start(slp);
1197 scsi_low_timeout(arg)
1200 struct scsi_low_softc *slp = arg;
1202 SCSI_LOW_ASSERT_LOCKED(slp);
1203 (void) scsi_low_timeout_check(slp);
1204 callout_schedule(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ);
1208 scsi_low_timeout_check(slp)
1209 struct scsi_low_softc *slp;
1211 struct targ_info *ti;
1212 struct lun_info *li;
1213 struct slccb *cb = NULL; /* XXX */
1215 /* selection restart */
1216 if (slp->sl_retry_sel != 0)
1218 slp->sl_retry_sel = 0;
1219 if (slp->sl_Tnexus != NULL)
1222 cb = TAILQ_FIRST(&slp->sl_start);
1226 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1228 cb->ccb_flags |= CCB_NORETRY;
1229 cb->ccb_error |= SELTIMEOUTIO;
1230 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1231 panic("%s: ccb not finished",
1232 device_get_nameunit(slp->sl_dev));
1235 if (slp->sl_Tnexus == NULL)
1236 scsi_low_start(slp);
1239 /* call hardware timeout */
1241 if (slp->sl_funcs->scsi_low_timeout != NULL)
1243 (*slp->sl_funcs->scsi_low_timeout) (slp);
1246 if (slp->sl_timeout_count ++ <
1247 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1250 slp->sl_timeout_count = 0;
1251 if (slp->sl_nio > 0)
1253 if ((cb = slp->sl_Qnexus) != NULL)
1255 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1259 else if (slp->sl_disc == 0)
1261 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1264 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1268 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1269 ti = TAILQ_NEXT(ti, ti_chain))
1271 if (ti->ti_disc == 0)
1274 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1275 li = LIST_NEXT(li, lun_chain))
1277 for (cb = TAILQ_FIRST(&li->li_discq);
1279 cb = TAILQ_NEXT(cb, ccb_chain))
1282 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1290 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1292 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1295 if (slp->sl_active != 0)
1297 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1303 if (slp->sl_powc < 0)
1305 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1306 slp->sl_flags |= HW_POWDOWN;
1307 (*slp->sl_funcs->scsi_low_power)
1308 (slp, SCSI_LOW_POWDOWN);
1314 cb->ccb_error |= TIMEOUTIO;
1315 device_printf(slp->sl_dev, "slccb (0x%lx) timeout!\n", (u_long) cb);
1316 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1317 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1318 scsi_low_start(slp);
1324 scsi_low_abort_ccb(slp, cb)
1325 struct scsi_low_softc *slp;
1328 struct targ_info *ti;
1329 struct lun_info *li;
1334 if ((cb->ccb_omsgoutflag &
1335 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1340 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1341 msg = SCSI_LOW_MSG_ABORT;
1343 msg = SCSI_LOW_MSG_ABORT_QTAG;
1345 cb->ccb_error |= ABORTIO;
1346 cb->ccb_flags |= CCB_NORETRY;
1347 scsi_low_ccb_message_assert(cb, msg);
1349 if (cb == slp->sl_Qnexus)
1351 scsi_low_assert_msg(slp, ti, msg, 1);
1353 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1355 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1356 panic("%s: revoked ccb done",
1357 device_get_nameunit(slp->sl_dev));
1359 cb->ccb_flags |= CCB_STARTQ;
1360 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1362 if (slp->sl_Tnexus == NULL)
1363 scsi_low_start(slp);
1367 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1368 panic("%s: revoked ccb retried",
1369 device_get_nameunit(slp->sl_dev));
1374 /**************************************************************
1375 * Generic SCSI INTERFACE
1376 **************************************************************/
1378 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
1379 struct scsi_low_softc *slp;
1380 int openings, ntargs, nluns, targsize, lunsize;
1382 struct targ_info *ti;
1383 struct lun_info *li;
1386 if (ntargs > SCSI_LOW_NTARGETS)
1388 printf("scsi_low: %d targets are too large\n", ntargs);
1389 printf("change kernel options SCSI_LOW_NTARGETS");
1394 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1396 slp->sl_openings = openings;
1397 slp->sl_ntargs = ntargs;
1398 slp->sl_nluns = nluns;
1399 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1401 if (lunsize < sizeof(struct lun_info))
1402 lunsize = sizeof(struct lun_info);
1404 if (targsize < sizeof(struct targ_info))
1405 targsize = sizeof(struct targ_info);
1407 slp->sl_targsize = targsize;
1408 for (i = 0; i < ntargs; i ++)
1410 ti = scsi_low_alloc_ti(slp, i);
1411 ti->ti_lunsize = lunsize;
1412 li = scsi_low_alloc_li(ti, 0, 1);
1415 /* initialize queue */
1416 nccb = openings * ntargs;
1417 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1418 nccb = SCSI_LOW_NCCB;
1419 scsi_low_init_ccbque(nccb);
1420 TAILQ_INIT(&slp->sl_start);
1422 /* call os depend attach */
1423 rv = scsi_low_attach_cam(slp);
1426 device_printf(slp->sl_dev,
1427 "scsi_low_attach: osdep attach failed\n");
1431 /* check hardware */
1432 DELAY(1000); /* wait for 1ms */
1434 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1436 device_printf(slp->sl_dev,
1437 "scsi_low_attach: initialization failed\n");
1438 SCSI_LOW_UNLOCK(slp);
1442 /* start watch dog */
1443 slp->sl_timeout_count = 0;
1444 callout_reset(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ,
1445 scsi_low_timeout, slp);
1446 mtx_lock(&sl_tab_lock);
1447 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1448 mtx_unlock(&sl_tab_lock);
1451 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1453 #ifdef SCSI_LOW_START_UP_CHECK
1454 /* probing devices */
1455 scsi_low_start_up(slp);
1456 #endif /* SCSI_LOW_START_UP_CHECK */
1457 SCSI_LOW_UNLOCK(slp);
1463 scsi_low_detach(slp)
1464 struct scsi_low_softc *slp;
1469 if (scsi_low_is_busy(slp) != 0)
1471 SCSI_LOW_UNLOCK(slp);
1475 scsi_low_deactivate(slp);
1477 rv = scsi_low_detach_cam(slp);
1480 SCSI_LOW_UNLOCK(slp);
1484 scsi_low_free_ti(slp);
1485 SCSI_LOW_UNLOCK(slp);
1486 callout_drain(&slp->sl_timeout_timer);
1487 callout_drain(&slp->sl_engage_timer);
1488 mtx_lock(&sl_tab_lock);
1489 LIST_REMOVE(slp, sl_chain);
1490 mtx_unlock(&sl_tab_lock);
1494 /**************************************************************
1496 **************************************************************/
1498 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
1499 struct scsi_low_softc *slp;
1500 struct targ_info *ti;
1501 struct lun_info *li;
1509 scsi_low_ccb_message_assert(cb, msg);
1511 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1512 scsi_low_alloc_qtag(cb);
1514 cb->ccb_flags = flags | CCB_STARTQ;
1515 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1516 cb->ccb_error |= PENDINGIO;
1518 if ((flags & CCB_URGENT) != 0)
1520 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1524 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1529 if (slp->sl_Tnexus == NULL)
1530 scsi_low_start(slp);
1535 scsi_low_message_enqueue(slp, ti, li, flags)
1536 struct scsi_low_softc *slp;
1537 struct targ_info *ti;
1538 struct lun_info *li;
1544 tmsgflags = ti->ti_setup_msg;
1545 ti->ti_setup_msg = 0;
1547 flags |= CCB_NORETRY;
1548 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1553 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1557 /**************************************************************
1558 * Generic Start & Done
1559 **************************************************************/
1560 #define SLSC_MODE_SENSE_SHORT 0x1a
1561 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1562 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1563 sizeof(struct scsi_low_mode_sense_data), 0};
1564 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1565 sizeof(struct scsi_low_inq_data), 0};
1566 static u_int8_t unit_ready_cmd[6];
1567 static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1568 static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1569 static int scsi_low_resume(struct scsi_low_softc *);
1572 scsi_low_unit_ready_cmd(cb)
1576 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1577 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1578 cb->ccb_scp.scp_datalen = 0;
1579 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1584 scsi_low_sense_abort_start(slp, ti, li, cb)
1585 struct scsi_low_softc *slp;
1586 struct targ_info *ti;
1587 struct lun_info *li;
1591 cb->ccb_scp.scp_cmdlen = 6;
1592 bzero(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1593 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1594 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1595 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1596 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1597 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1598 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1600 scsi_low_ccb_message_clear(cb);
1601 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1603 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1607 bzero(&cb->ccb_sense, sizeof(cb->ccb_sense));
1608 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1609 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1610 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1613 return SCSI_LOW_START_NO_QTAG;
1617 scsi_low_setup_start(slp, ti, li, cb)
1618 struct scsi_low_softc *slp;
1619 struct targ_info *ti;
1620 struct lun_info *li;
1624 switch(li->li_state)
1626 case SCSI_LOW_LUN_SLEEP:
1627 scsi_low_unit_ready_cmd(cb);
1630 case SCSI_LOW_LUN_START:
1631 cb->ccb_scp.scp_cmd = ss_cmd;
1632 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1633 cb->ccb_scp.scp_datalen = 0;
1634 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1638 case SCSI_LOW_LUN_INQ:
1639 cb->ccb_scp.scp_cmd = inq_cmd;
1640 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1641 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1642 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1643 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1647 case SCSI_LOW_LUN_MODEQ:
1648 cb->ccb_scp.scp_cmd = sms_cmd;
1649 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1650 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1651 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1652 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1654 return SCSI_LOW_START_QTAG;
1657 panic("%s: no setup phase", device_get_nameunit(slp->sl_dev));
1660 return SCSI_LOW_START_NO_QTAG;
1664 scsi_low_resume(slp)
1665 struct scsi_low_softc *slp;
1668 if (slp->sl_flags & HW_RESUME)
1670 slp->sl_flags &= ~HW_POWDOWN;
1671 if (slp->sl_funcs->scsi_low_power != NULL)
1673 slp->sl_flags |= HW_RESUME;
1675 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1676 callout_reset(&slp->sl_engage_timer, hz / 1000,
1677 scsi_low_engage, slp);
1685 struct scsi_low_softc *slp;
1687 struct targ_info *ti;
1688 struct lun_info *li;
1692 /* check hardware exists or under initializations ? */
1693 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1696 /* check hardware power up ? */
1697 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1700 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1702 if (scsi_low_resume(slp) == EJUSTRETURN)
1708 #ifdef SCSI_LOW_DIAGNOSTIC
1709 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1711 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
1712 panic("%s: inconsistent", device_get_nameunit(slp->sl_dev));
1714 #endif /* SCSI_LOW_DIAGNOSTIC */
1716 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1717 cb = TAILQ_NEXT(cb, ccb_chain))
1721 if (li->li_disc == 0)
1723 goto scsi_low_cmd_start;
1725 else if (li->li_nqio > 0)
1727 if (li->li_nqio < li->li_maxnqio ||
1728 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1729 goto scsi_low_cmd_start;
1735 cb->ccb_flags &= ~CCB_STARTQ;
1736 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1739 /* clear all error flag bits (for restart) */
1741 cb->ccb_datalen = -1;
1742 cb->ccb_scp.scp_status = ST_UNKNOWN;
1744 /* setup nexus pointer */
1745 slp->sl_Qnexus = cb;
1746 slp->sl_Lnexus = li;
1747 slp->sl_Tnexus = ti;
1749 /* initialize msgsys */
1750 scsi_low_init_msgsys(slp, ti);
1753 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1755 /* CA state or forced abort */
1756 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1758 else if (li->li_state >= SCSI_LOW_LUN_OK)
1760 cb->ccb_flags &= ~CCB_INTERNAL;
1761 rv = scsi_low_ccb_setup_cam(slp, cb);
1762 if (cb->ccb_msgoutflag != 0)
1764 scsi_low_ccb_message_exec(slp, cb);
1769 cb->ccb_flags |= CCB_INTERNAL;
1770 rv = scsi_low_setup_start(slp, ti, li, cb);
1774 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1776 if (rv == SCSI_LOW_START_QTAG &&
1777 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1782 scsi_low_activate_qtag(cb);
1783 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1784 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1785 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1786 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1787 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1789 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1790 scsi_low_assert_msg(slp, ti, qmsg, 0);
1794 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1795 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1796 cb->ccb_tc = cb->ccb_tcmax;
1798 /* setup saved scsi data pointer */
1799 cb->ccb_sscp = cb->ccb_scp;
1801 /* setup current scsi pointer */
1802 slp->sl_scp = cb->ccb_sscp;
1803 slp->sl_error = cb->ccb_error;
1805 /* assert always an identify msg */
1806 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1809 #ifdef SCSI_LOW_DIAGNOSTIC
1810 scsi_low_msg_log_init(&ti->ti_log_msgin);
1811 scsi_low_msg_log_init(&ti->ti_log_msgout);
1812 #endif /* SCSI_LOW_DIAGNOSTIC */
1814 /* selection start */
1816 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1817 if (rv == SCSI_LOW_START_OK)
1819 #ifdef SCSI_LOW_STATICS
1820 scsi_low_statics.nexus_win ++;
1821 #endif /* SCSI_LOW_STATICS */
1825 scsi_low_arbit_fail(slp, cb);
1826 #ifdef SCSI_LOW_STATICS
1827 scsi_low_statics.nexus_fail ++;
1828 #endif /* SCSI_LOW_STATICS */
1832 scsi_low_arbit_fail(slp, cb)
1833 struct scsi_low_softc *slp;
1836 struct targ_info *ti = cb->ti;
1838 scsi_low_deactivate_qtag(cb);
1839 scsi_low_ccb_message_retry(cb);
1840 cb->ccb_flags |= CCB_STARTQ;
1841 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1843 scsi_low_bus_release(slp, ti);
1846 if (slp->sl_disc == 0)
1848 #ifdef SCSI_LOW_DIAGNOSTIC
1849 device_printf(slp->sl_dev, "try selection again\n");
1850 #endif /* SCSI_LOW_DIAGNOSTIC */
1851 slp->sl_retry_sel = 1;
1856 scsi_low_bus_release(slp, ti)
1857 struct scsi_low_softc *slp;
1858 struct targ_info *ti;
1861 if (ti->ti_disc > 0)
1863 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1867 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1870 /* clear all nexus pointer */
1871 slp->sl_Qnexus = NULL;
1872 slp->sl_Lnexus = NULL;
1873 slp->sl_Tnexus = NULL;
1875 /* clear selection assert */
1876 slp->sl_selid = NULL;
1878 /* clear nexus data */
1879 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1881 /* clear phase change counter */
1882 slp->sl_ph_count = 0;
1886 scsi_low_setup_done(slp, cb)
1887 struct scsi_low_softc *slp;
1890 struct targ_info *ti;
1891 struct lun_info *li;
1896 if (cb->ccb_rcnt >= slp->sl_max_retry)
1898 cb->ccb_error |= ABORTIO;
1899 return SCSI_LOW_DONE_COMPLETE;
1902 /* XXX: special huck for selection timeout */
1903 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1904 (cb->ccb_error & SELTIMEOUTIO) != 0)
1906 cb->ccb_error |= ABORTIO;
1907 return SCSI_LOW_DONE_COMPLETE;
1910 switch(li->li_state)
1912 case SCSI_LOW_LUN_INQ:
1913 if (cb->ccb_error != 0)
1916 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
1920 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
1922 else if ((li->li_inq.sd_version & 7) >= 2 ||
1923 (li->li_inq.sd_len >= 4))
1925 if ((li->li_inq.sd_support & 0x2) == 0)
1926 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1927 if ((li->li_inq.sd_support & 0x8) == 0)
1928 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
1931 if ((li->li_inq.sd_support & 0x10) == 0)
1932 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
1933 if ((li->li_inq.sd_support & 0x20) == 0)
1934 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
1935 if ((li->li_inq.sd_support & 0x40) == 0)
1936 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
1941 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
1944 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
1946 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
1948 scsi_low_calcf_target(ti);
1949 scsi_low_calcf_lun(li);
1952 case SCSI_LOW_LUN_MODEQ:
1953 if (cb->ccb_error != 0)
1955 if (cb->ccb_error & SENSEIO)
1957 #ifdef SCSI_LOW_DEBUG
1958 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
1960 int error_code, sense_key, asc, ascq;
1962 scsi_extract_sense(&cb->ccb_sense,
1967 printf("SENSE: [%x][%x][%x][%x]\n",
1968 error_code, sense_key, asc,
1971 #endif /* SCSI_LOW_DEBUG */
1975 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1978 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
1980 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
1981 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
1983 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
1984 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
1985 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1987 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
1988 scsi_low_calcf_lun(li);
1996 if (li->li_state == SCSI_LOW_LUN_OK)
1998 scsi_low_calcf_target(ti);
1999 scsi_low_calcf_lun(li);
2000 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2001 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2003 scsi_low_calcf_show(li);
2008 return SCSI_LOW_DONE_RETRY;
2012 scsi_low_done(slp, cb)
2013 struct scsi_low_softc *slp;
2018 if (cb->ccb_error == 0)
2020 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2022 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2024 * SCSI-2 draft suggests
2025 * page 0x0a QErr bit determins if
2026 * the target aborts or continues
2027 * the queueing io's after CA state resolved.
2028 * However many targets seem not to support
2029 * the page 0x0a. Thus we should manually clear the
2030 * queuing io's after CA state.
2032 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2035 cb->ccb_flags |= CCB_CLEARQ;
2038 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2040 if ((cb->ccb_flags & CCB_SENSE) != 0)
2041 cb->ccb_error |= (SENSEIO | ABORTIO);
2042 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2044 else switch (cb->ccb_sscp.scp_status)
2050 if (cb->ccb_datalen == 0 ||
2051 cb->ccb_scp.scp_datalen == 0)
2054 if (cb->ccb_scp.scp_cmdlen > 0 &&
2055 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2056 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2059 cb->ccb_error |= PDMAERR;
2064 cb->ccb_error |= (BUSYERR | STATERR);
2068 cb->ccb_error |= (STATERR | ABORTIO);
2073 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2076 cb->ccb_flags |= CCB_SENSE;
2079 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2084 cb->ccb_error |= FATALIO;
2090 if (cb->ccb_flags & CCB_SENSE)
2092 cb->ccb_error |= (SENSEERR | ABORTIO);
2094 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2098 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2100 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2104 /* check a ccb msgout flag */
2105 if (cb->ccb_omsgoutflag != 0)
2107 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2108 SCSI_LOW_MSG_ABORT_QTAG | \
2109 SCSI_LOW_MSG_CLEAR_QTAG | \
2110 SCSI_LOW_MSG_TERMIO)
2112 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2114 cb->ccb_error |= ABORTIO;
2118 /* call OS depend done */
2119 if (cb->osdep != NULL)
2121 rv = scsi_low_done_cam(slp, cb);
2122 if (rv == EJUSTRETURN)
2125 else if (cb->ccb_error != 0)
2127 if (cb->ccb_rcnt >= slp->sl_max_retry)
2128 cb->ccb_error |= ABORTIO;
2130 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2131 (cb->ccb_error & ABORTIO) == 0)
2135 /* free our target */
2136 #ifdef SCSI_LOW_DEBUG
2137 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2139 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2140 scsi_low_print(slp, NULL);
2142 #endif /* SCSI_LOW_DEBUG */
2144 scsi_low_deactivate_qtag(cb);
2145 scsi_low_dealloc_qtag(cb);
2146 scsi_low_free_ccb(cb);
2148 return SCSI_LOW_DONE_COMPLETE;
2151 #ifdef SCSI_LOW_DEBUG
2152 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2154 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2155 scsi_low_print(slp, NULL);
2157 #endif /* SCSI_LOW_DEBUG */
2160 scsi_low_deactivate_qtag(cb);
2161 scsi_low_ccb_message_retry(cb);
2162 return SCSI_LOW_DONE_RETRY;
2165 /**************************************************************
2167 **************************************************************/
2169 scsi_low_reset_nexus_target(slp, ti, fdone)
2170 struct scsi_low_softc *slp;
2171 struct targ_info *ti;
2174 struct lun_info *li;
2176 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2177 li = LIST_NEXT(li, lun_chain))
2179 scsi_low_reset_nexus_lun(slp, li, fdone);
2180 li->li_state = SCSI_LOW_LUN_SLEEP;
2185 ti->ti_setup_msg = 0;
2186 ti->ti_setup_msg_done = 0;
2188 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2189 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2191 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2192 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2194 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2196 ((*slp->sl_funcs->scsi_low_targ_init)
2197 (slp, ti, SCSI_LOW_INFO_REVOKE));
2199 scsi_low_calcf_target(ti);
2201 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2202 li = LIST_NEXT(li, lun_chain))
2206 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2207 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2209 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2211 ((*slp->sl_funcs->scsi_low_lun_init)
2212 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2214 scsi_low_calcf_lun(li);
2219 scsi_low_reset_nexus(slp, fdone)
2220 struct scsi_low_softc *slp;
2223 struct targ_info *ti;
2224 struct slccb *cb, *topcb;
2226 if ((cb = slp->sl_Qnexus) != NULL)
2228 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2235 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2236 ti = TAILQ_NEXT(ti, ti_chain))
2238 scsi_low_reset_nexus_target(slp, ti, fdone);
2239 scsi_low_bus_release(slp, ti);
2240 scsi_low_init_msgsys(slp, ti);
2245 topcb->ccb_flags |= CCB_STARTQ;
2246 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2250 slp->sl_retry_sel = 0;
2251 slp->sl_flags &= ~HW_PDMASTART;
2256 static char tw_chars[] = "|/-\\";
2257 #define TWIDDLEWAIT 10000
2260 scsi_low_twiddle_wait(void)
2264 cnputc(tw_chars[tw_pos++]);
2265 tw_pos %= (sizeof(tw_chars) - 1);
2270 scsi_low_bus_reset(slp)
2271 struct scsi_low_softc *slp;
2275 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2277 device_printf(slp->sl_dev, "try to reset scsi bus ");
2278 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2279 scsi_low_twiddle_wait();
2285 scsi_low_restart(slp, flags, s)
2286 struct scsi_low_softc *slp;
2293 device_printf(slp->sl_dev, "scsi bus restart. reason: %s\n", s);
2295 if ((error = scsi_low_init(slp, flags)) != 0)
2298 scsi_low_start(slp);
2302 /**************************************************************
2303 * disconnect and reselect
2304 **************************************************************/
2305 #define MSGCMD_LUN(msg) (msg & 0x07)
2307 static struct slccb *
2308 scsi_low_establish_ccb(ti, li, tag)
2309 struct targ_info *ti;
2310 struct lun_info *li;
2313 struct scsi_low_softc *slp = ti->ti_sc;
2319 cb = TAILQ_FIRST(&li->li_discq);
2320 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2321 if (cb->ccb_tag == tag)
2326 * establish our ccb nexus
2329 #ifdef SCSI_LOW_DEBUG
2330 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2332 device_printf(slp->sl_dev, "nexus(0x%lx) abort check start\n",
2334 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2335 scsi_low_revoke_ccb(slp, cb, 1);
2339 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2341 if (cb->ccb_omsgoutflag == 0)
2342 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2344 #endif /* SCSI_LOW_DEBUG */
2346 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2347 cb->ccb_flags &= ~CCB_DISCQ;
2348 slp->sl_Qnexus = cb;
2350 slp->sl_scp = cb->ccb_sscp;
2351 slp->sl_error |= cb->ccb_error;
2357 /* inform "ccb nexus established" to the host driver */
2358 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2361 if (cb->ccb_msgoutflag != 0)
2363 scsi_low_ccb_message_exec(slp, cb);
2370 scsi_low_reselected(slp, targ)
2371 struct scsi_low_softc *slp;
2374 struct targ_info *ti;
2379 * Check select vs reselected collision.
2382 if ((cb = slp->sl_selid) != NULL)
2384 scsi_low_arbit_fail(slp, cb);
2385 #ifdef SCSI_LOW_STATICS
2386 scsi_low_statics.nexus_conflict ++;
2387 #endif /* SCSI_LOW_STATICS */
2391 * Check if no current active nexus.
2393 if (slp->sl_Tnexus != NULL)
2400 * Check a valid target id asserted ?
2402 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2404 s = "scsi id illegal";
2409 * Check the target scsi status.
2411 ti = slp->sl_ti[targ];
2412 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2414 s = "phase mismatch";
2422 scsi_low_init_msgsys(slp, ti);
2425 * Establish our target nexus
2427 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2428 slp->sl_Tnexus = ti;
2429 #ifdef SCSI_LOW_STATICS
2430 scsi_low_statics.nexus_reselected ++;
2431 #endif /* SCSI_LOW_STATICS */
2435 device_printf(slp->sl_dev, "reselect(%x:unknown) %s\n", targ, s);
2436 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2437 "reselect: scsi world confused");
2441 /**************************************************************
2442 * cmd out pointer setup
2443 **************************************************************/
2445 scsi_low_cmd(slp, ti)
2446 struct scsi_low_softc *slp;
2447 struct targ_info *ti;
2449 struct slccb *cb = slp->sl_Qnexus;
2451 slp->sl_ph_count ++;
2457 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2458 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2459 slp->sl_scp.scp_datalen = 0;
2460 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2461 slp->sl_error |= FATALIO;
2462 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2463 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2468 #ifdef SCSI_LOW_DEBUG
2469 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2471 scsi_low_test_cmdlnk(slp, cb);
2473 #endif /* SCSI_LOW_DEBUG */
2478 /**************************************************************
2479 * data out pointer setup
2480 **************************************************************/
2482 scsi_low_data(slp, ti, bp, direction)
2483 struct scsi_low_softc *slp;
2484 struct targ_info *ti;
2488 struct slccb *cb = slp->sl_Qnexus;
2490 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2496 slp->sl_error |= (FATALIO | PDMAERR);
2497 slp->sl_scp.scp_datalen = 0;
2498 slp->sl_scp.scp_direction = direction;
2499 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2500 if (ti->ti_ophase != ti->ti_phase)
2505 s = "DATA PHASE: ccb nexus not found";
2507 s = "DATA PHASE: xfer direction mismatch";
2508 SCSI_LOW_INFO(slp, ti, s);
2515 /**************************************************************
2517 **************************************************************/
2518 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2519 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2520 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2521 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2522 #define MSGIN_DATA_LAST 0x30
2524 static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int);
2525 static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int);
2526 static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int);
2527 static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int);
2529 static int scsi_low_msgfunc_synch(struct scsi_low_softc *);
2530 static int scsi_low_msgfunc_wide(struct scsi_low_softc *);
2531 static int scsi_low_msgfunc_identify(struct scsi_low_softc *);
2532 static int scsi_low_msgfunc_abort(struct scsi_low_softc *);
2533 static int scsi_low_msgfunc_qabort(struct scsi_low_softc *);
2534 static int scsi_low_msgfunc_qtag(struct scsi_low_softc *);
2535 static int scsi_low_msgfunc_reset(struct scsi_low_softc *);
2537 struct scsi_low_msgout_data {
2540 int (*md_msgfunc)(struct scsi_low_softc *);
2541 int (*md_errfunc)(struct scsi_low_softc *, u_int);
2542 #define MSG_RELEASE_ATN 0x0001
2546 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2547 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2548 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2549 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2550 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2551 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2552 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2553 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2554 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2555 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2556 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2557 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2558 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2559 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2560 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2561 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2562 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2565 static int scsi_low_msginfunc_ext(struct scsi_low_softc *);
2566 static int scsi_low_synch(struct scsi_low_softc *);
2567 static int scsi_low_wide(struct scsi_low_softc *);
2568 static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *);
2569 static int scsi_low_msginfunc_rejop(struct scsi_low_softc *);
2570 static int scsi_low_msginfunc_rp(struct scsi_low_softc *);
2571 static int scsi_low_msginfunc_sdp(struct scsi_low_softc *);
2572 static int scsi_low_msginfunc_disc(struct scsi_low_softc *);
2573 static int scsi_low_msginfunc_cc(struct scsi_low_softc *);
2574 static int scsi_low_msginfunc_lcc(struct scsi_low_softc *);
2575 static int scsi_low_msginfunc_parity(struct scsi_low_softc *);
2576 static int scsi_low_msginfunc_noop(struct scsi_low_softc *);
2577 static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *);
2578 static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *);
2580 struct scsi_low_msgin_data {
2582 int (*md_msgfunc)(struct scsi_low_softc *);
2585 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2586 /* 0 */ {1, scsi_low_msginfunc_cc},
2587 /* 1 */ {2, scsi_low_msginfunc_ext},
2588 /* 2 */ {1, scsi_low_msginfunc_sdp},
2589 /* 3 */ {1, scsi_low_msginfunc_rp},
2590 /* 4 */ {1, scsi_low_msginfunc_disc},
2591 /* 5 */ {1, scsi_low_msginfunc_rejop},
2592 /* 6 */ {1, scsi_low_msginfunc_rejop},
2593 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2594 /* 8 */ {1, scsi_low_msginfunc_noop},
2595 /* 9 */ {1, scsi_low_msginfunc_parity},
2596 /* a */ {1, scsi_low_msginfunc_lcc},
2597 /* b */ {1, scsi_low_msginfunc_lcc},
2598 /* c */ {1, scsi_low_msginfunc_rejop},
2599 /* d */ {2, scsi_low_msginfunc_rejop},
2600 /* e */ {1, scsi_low_msginfunc_rejop},
2601 /* f */ {1, scsi_low_msginfunc_rejop},
2602 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2603 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2604 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2605 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2606 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2607 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2608 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2609 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2610 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2611 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2612 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2613 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2614 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2615 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2616 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2617 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2618 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2619 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2620 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2621 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2622 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2623 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2624 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2625 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2626 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2627 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2628 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2629 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2630 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2631 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2632 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2633 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2634 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2637 /**************************************************************
2639 **************************************************************/
2641 scsi_low_msgfunc_synch(slp)
2642 struct scsi_low_softc *slp;
2644 struct targ_info *ti = slp->sl_Tnexus;
2645 int ptr = ti->ti_msgoutlen;
2647 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2648 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2649 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2650 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2651 return MSG_EXTEND_SYNCHLEN + 2;
2655 scsi_low_msgfunc_wide(slp)
2656 struct scsi_low_softc *slp;
2658 struct targ_info *ti = slp->sl_Tnexus;
2659 int ptr = ti->ti_msgoutlen;
2661 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2662 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2663 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2664 return MSG_EXTEND_WIDELEN + 2;
2668 scsi_low_msgfunc_identify(slp)
2669 struct scsi_low_softc *slp;
2671 struct targ_info *ti = slp->sl_Tnexus;
2672 struct lun_info *li = slp->sl_Lnexus;
2673 struct slccb *cb = slp->sl_Qnexus;
2674 int ptr = ti->ti_msgoutlen;
2680 slp->sl_error |= FATALIO;
2681 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2682 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2686 if (scsi_low_is_disconnect_ok(cb) != 0)
2687 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2691 if (ti->ti_phase == PH_MSGOUT)
2693 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2694 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2696 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2700 ti->ti_msgoutstr[ptr + 0] = msg;
2705 scsi_low_msgfunc_abort(slp)
2706 struct scsi_low_softc *slp;
2709 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2714 scsi_low_msgfunc_qabort(slp)
2715 struct scsi_low_softc *slp;
2718 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2723 scsi_low_msgfunc_reset(slp)
2724 struct scsi_low_softc *slp;
2727 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2732 scsi_low_msgfunc_qtag(slp)
2733 struct scsi_low_softc *slp;
2735 struct targ_info *ti = slp->sl_Tnexus;
2736 struct slccb *cb = slp->sl_Qnexus;
2737 int ptr = ti->ti_msgoutlen;
2739 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2741 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2746 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2747 if (ti->ti_phase == PH_MSGOUT)
2749 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2756 * The following functions are called when targets give unexpected
2757 * responces in msgin (after msgout).
2760 scsi_low_errfunc_identify(slp, msgflags)
2761 struct scsi_low_softc *slp;
2765 if (slp->sl_Lnexus != NULL)
2767 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2768 scsi_low_calcf_lun(slp->sl_Lnexus);
2774 scsi_low_errfunc_synch(slp, msgflags)
2775 struct scsi_low_softc *slp;
2778 struct targ_info *ti = slp->sl_Tnexus;
2780 MSGIN_PERIOD(ti) = 0;
2781 MSGIN_OFFSET(ti) = 0;
2782 scsi_low_synch(slp);
2787 scsi_low_errfunc_wide(slp, msgflags)
2788 struct scsi_low_softc *slp;
2791 struct targ_info *ti = slp->sl_Tnexus;
2793 MSGIN_WIDTHP(ti) = 0;
2799 scsi_low_errfunc_qtag(slp, msgflags)
2800 struct scsi_low_softc *slp;
2804 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2806 if (slp->sl_Qnexus != NULL)
2808 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2810 if (slp->sl_Lnexus != NULL)
2812 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2813 scsi_low_calcf_lun(slp->sl_Lnexus);
2815 device_printf(slp->sl_dev, "scsi_low: qtag msg rejected\n");
2822 scsi_low_msgout(slp, ti, fl)
2823 struct scsi_low_softc *slp;
2824 struct targ_info *ti;
2827 struct scsi_low_msgout_data *mdp;
2830 #ifdef SCSI_LOW_DIAGNOSTIC
2831 if (ti != slp->sl_Tnexus)
2833 scsi_low_print(slp, NULL);
2834 panic("scsi_low_msgout: Target nexus inconsistent");
2836 #endif /* SCSI_LOW_DIAGNOSTIC */
2838 slp->sl_ph_count ++;
2839 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2841 device_printf(slp->sl_dev, "too many phase changes\n");
2842 slp->sl_error |= FATALIO;
2843 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2847 * Scsi phase changes.
2848 * Previously msgs asserted are accepted by our target or
2849 * processed by scsi_low_msgin.
2850 * Thus clear all saved informations.
2852 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2854 ti->ti_omsgflags = 0;
2855 ti->ti_emsgflags = 0;
2857 else if (slp->sl_atten == 0)
2860 * We did not assert attention, however still our target required
2861 * msgs. Resend previous msgs.
2863 ti->ti_msgflags |= ti->ti_omsgflags;
2864 ti->ti_omsgflags = 0;
2865 #ifdef SCSI_LOW_DIAGNOSTIC
2866 device_printf(slp->sl_dev, "scsi_low_msgout: retry msgout\n");
2867 #endif /* SCSI_LOW_DIAGNOSTIC */
2871 * We have no msgs. send MSG_NOOP (OK?)
2873 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2874 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2879 ti->ti_msgoutlen = 0;
2880 slp->sl_clear_atten = 0;
2881 mdp = &scsi_low_msgout_data[0];
2882 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2884 if ((ti->ti_msgflags & mdp->md_flags) != 0)
2886 ti->ti_omsgflags |= mdp->md_flags;
2887 ti->ti_msgflags &= ~mdp->md_flags;
2888 ti->ti_emsgflags = mdp->md_flags;
2890 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2891 if (mdp->md_msgfunc != NULL)
2892 len = (*mdp->md_msgfunc) (slp);
2896 #ifdef SCSI_LOW_DIAGNOSTIC
2897 scsi_low_msg_log_write(&ti->ti_log_msgout,
2898 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2899 #endif /* SCSI_LOW_DIAGNOSTIC */
2901 ti->ti_msgoutlen += len;
2902 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2904 slp->sl_clear_atten = 1;
2908 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2909 ti->ti_msgflags == 0)
2912 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2917 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2918 slp->sl_clear_atten = 1;
2920 return ti->ti_msgoutlen;
2923 /**************************************************************
2925 **************************************************************/
2927 scsi_low_msginfunc_noop(slp)
2928 struct scsi_low_softc *slp;
2935 scsi_low_msginfunc_rejop(slp)
2936 struct scsi_low_softc *slp;
2938 struct targ_info *ti = slp->sl_Tnexus;
2939 u_int8_t msg = ti->ti_msgin[0];
2941 device_printf(slp->sl_dev, "MSGIN: msg 0x%x rejected\n", (u_int) msg);
2942 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2947 scsi_low_msginfunc_cc(slp)
2948 struct scsi_low_softc *slp;
2950 struct lun_info *li;
2952 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2954 /* validate status */
2955 if (slp->sl_Qnexus == NULL)
2958 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2959 li = slp->sl_Lnexus;
2960 switch (slp->sl_scp.scp_status)
2963 li->li_maxnqio = li->li_maxnexus;
2968 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
2969 scsi_low_reset_nexus_lun(slp, li, 0);
2977 if (li->li_maxnexus >= li->li_nqio)
2978 li->li_maxnexus = li->li_nqio - 1;
2979 li->li_maxnqio = li->li_maxnexus;
2984 slp->sl_error |= MSGERR;
2994 scsi_low_msginfunc_lcc(slp)
2995 struct scsi_low_softc *slp;
2997 struct targ_info *ti;
2998 struct lun_info *li;
2999 struct slccb *ncb, *cb;
3001 ti = slp->sl_Tnexus;
3002 li = slp->sl_Lnexus;
3003 if ((cb = slp->sl_Qnexus) == NULL)
3006 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3007 switch (slp->sl_scp.scp_status)
3011 li->li_maxnqio = li->li_maxnexus;
3015 slp->sl_error |= MSGERR;
3019 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3022 cb->ccb_error |= slp->sl_error;
3023 if (cb->ccb_error != 0)
3026 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3027 ncb = TAILQ_NEXT(ncb, ccb_chain))
3030 goto cmd_link_start;
3035 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3036 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3040 ncb->ccb_flags &= ~CCB_STARTQ;
3041 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3043 scsi_low_dealloc_qtag(ncb);
3044 ncb->ccb_tag = cb->ccb_tag;
3045 ncb->ccb_otag = cb->ccb_otag;
3046 cb->ccb_tag = SCSI_LOW_UNKTAG;
3047 cb->ccb_otag = SCSI_LOW_UNKTAG;
3048 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3049 panic("%s: linked ccb retried",
3050 device_get_nameunit(slp->sl_dev));
3052 slp->sl_Qnexus = ncb;
3053 slp->sl_ph_count = 0;
3056 ncb->ccb_datalen = -1;
3057 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3058 ncb->ccb_flags &= ~CCB_INTERNAL;
3060 scsi_low_init_msgsys(slp, ti);
3062 scsi_low_ccb_setup_cam(slp, ncb);
3064 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3065 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3066 ncb->ccb_tc = ncb->ccb_tcmax;
3068 /* setup saved scsi data pointer */
3069 ncb->ccb_sscp = ncb->ccb_scp;
3070 slp->sl_scp = ncb->ccb_sscp;
3071 slp->sl_error = ncb->ccb_error;
3073 #ifdef SCSI_LOW_DIAGNOSTIC
3074 scsi_low_msg_log_init(&ti->ti_log_msgin);
3075 scsi_low_msg_log_init(&ti->ti_log_msgout);
3076 #endif /* SCSI_LOW_DIAGNOSTIC */
3081 scsi_low_msginfunc_disc(slp)
3082 struct scsi_low_softc *slp;
3085 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3090 scsi_low_msginfunc_sdp(slp)
3091 struct scsi_low_softc *slp;
3093 struct slccb *cb = slp->sl_Qnexus;
3097 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3098 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3101 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3106 scsi_low_msginfunc_rp(slp)
3107 struct scsi_low_softc *slp;
3110 if (slp->sl_Qnexus != NULL)
3111 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3113 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3119 struct scsi_low_softc *slp;
3121 struct targ_info *ti = slp->sl_Tnexus;
3122 u_int period = 0, offset = 0, speed;
3126 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3127 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3128 MSGIN_OFFSET(ti) == 0)
3130 if ((offset = MSGIN_OFFSET(ti)) != 0)
3131 period = MSGIN_PERIOD(ti);
3132 s = offset ? "synchronous" : "async";
3137 * Target seems to be brain damaged.
3138 * Force async transfer.
3140 ti->ti_maxsynch.period = 0;
3141 ti->ti_maxsynch.offset = 0;
3142 device_printf(slp->sl_dev,
3143 "target brain damaged. async transfer\n");
3147 ti->ti_maxsynch.period = period;
3148 ti->ti_maxsynch.offset = offset;
3150 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3154 * Current period and offset are not acceptable
3156 * The adapter changes max synch and max offset.
3158 device_printf(slp->sl_dev,
3159 "synch neg failed. retry synch msg neg ...\n");
3163 ti->ti_osynch = ti->ti_maxsynch;
3166 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3170 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3172 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3173 struct slccb *cb = slp->sl_Qnexus;
3175 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3177 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3179 device_printf(slp->sl_dev,
3180 "(%d:*): <%s> offset %d period %dns ",
3181 ti->ti_id, s, offset, period * 4);
3185 speed = 1000 * 10 / (period * 4);
3186 printf("%d.%d M/s", speed / 10, speed % 10);
3195 struct scsi_low_softc *slp;
3197 struct targ_info *ti = slp->sl_Tnexus;
3200 ti->ti_width = MSGIN_WIDTHP(ti);
3201 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3205 * Current width is not acceptable for our adapter.
3206 * The adapter changes max width.
3208 device_printf(slp->sl_dev,
3209 "wide neg failed. retry wide msg neg ...\n");
3213 ti->ti_owidth = ti->ti_width;
3214 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3216 ti->ti_setup_msg_done |=
3217 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3221 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3223 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3224 struct slccb *cb = slp->sl_Qnexus;
3226 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3228 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3230 device_printf(slp->sl_dev, "(%d:*): transfer width %d bits\n",
3231 ti->ti_id, 1 << (3 + ti->ti_width));
3237 scsi_low_msginfunc_simple_qtag(slp)
3238 struct scsi_low_softc *slp;
3240 struct targ_info *ti = slp->sl_Tnexus;
3241 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3243 if (slp->sl_Qnexus != NULL)
3245 if (slp->sl_Qnexus->ccb_tag != etag)
3247 slp->sl_error |= FATALIO;
3248 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3249 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3252 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3254 #ifdef SCSI_LOW_DEBUG
3255 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3257 #endif /* SCSI_LOW_DEBUG */
3259 slp->sl_error |= FATALIO;
3260 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3261 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3267 scsi_low_msginfunc_i_wide_residue(slp)
3268 struct scsi_low_softc *slp;
3270 struct targ_info *ti = slp->sl_Tnexus;
3271 struct slccb *cb = slp->sl_Qnexus;
3272 int res = (int) ti->ti_msgin[1];
3274 if (cb == NULL || res <= 0 ||
3275 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3276 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3279 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3282 slp->sl_scp.scp_datalen += res;
3283 slp->sl_scp.scp_data -= res;
3284 scsi_low_data_finish(slp);
3289 scsi_low_msginfunc_ext(slp)
3290 struct scsi_low_softc *slp;
3292 struct slccb *cb = slp->sl_Qnexus;
3293 struct lun_info *li = slp->sl_Lnexus;
3294 struct targ_info *ti = slp->sl_Tnexus;
3298 if (ti->ti_msginptr == 2)
3300 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3304 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3306 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3310 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3311 count = (int) htonl((long) (*ptr));
3312 if(slp->sl_scp.scp_datalen - count < 0 ||
3313 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3316 slp->sl_scp.scp_datalen -= count;
3317 slp->sl_scp.scp_data += count;
3320 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3324 retry = scsi_low_synch(slp);
3325 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3326 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3328 #ifdef SCSI_LOW_DEBUG
3329 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3331 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3333 #endif /* SCSI_LOW_DEBUG */
3336 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3340 retry = scsi_low_wide(slp);
3341 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3342 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3350 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3355 scsi_low_msginfunc_parity(slp)
3356 struct scsi_low_softc *slp;
3358 struct targ_info *ti = slp->sl_Tnexus;
3360 /* only I -> T, invalid! */
3361 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3366 scsi_low_msginfunc_msg_reject(slp)
3367 struct scsi_low_softc *slp;
3369 struct targ_info *ti = slp->sl_Tnexus;
3370 struct scsi_low_msgout_data *mdp;
3373 if (ti->ti_emsgflags != 0)
3375 device_printf(slp->sl_dev, "msg flags [0x%x] rejected\n",
3377 msgflags = SCSI_LOW_MSG_REJECT;
3378 mdp = &scsi_low_msgout_data[0];
3379 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3381 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3383 ti->ti_emsgflags &= ~mdp->md_flags;
3384 if (mdp->md_errfunc != NULL)
3385 (*mdp->md_errfunc) (slp, msgflags);
3393 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3394 slp->sl_error |= MSGERR;
3400 scsi_low_msgin(slp, ti, c)
3401 struct scsi_low_softc *slp;
3402 struct targ_info *ti;
3405 struct scsi_low_msgin_data *sdp;
3406 struct lun_info *li;
3409 #ifdef SCSI_LOW_DIAGNOSTIC
3410 if (ti != slp->sl_Tnexus)
3412 scsi_low_print(slp, NULL);
3413 panic("scsi_low_msgin: Target nexus inconsistent");
3415 #endif /* SCSI_LOW_DIAGNOSTIC */
3418 * Phase changes, clear the pointer.
3420 if (ti->ti_ophase != ti->ti_phase)
3423 ti->ti_msgin_parity_error = 0;
3425 slp->sl_ph_count ++;
3426 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3428 device_printf(slp->sl_dev, "too many phase changes\n");
3429 slp->sl_error |= FATALIO;
3430 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3435 * Store a current messages byte into buffer and
3436 * wait for the completion of the current msg.
3438 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3439 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3441 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3442 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3446 * Check parity errors.
3448 if ((c & SCSI_LOW_DATA_PE) != 0)
3450 ti->ti_msgin_parity_error ++;
3451 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3455 if (ti->ti_msgin_parity_error != 0)
3459 * Calculate messages length.
3461 msg = ti->ti_msgin[0];
3462 if (msg < MSGIN_DATA_LAST)
3463 sdp = &scsi_low_msgin_data[msg];
3465 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3467 if (ti->ti_msginlen == 0)
3469 ti->ti_msginlen = sdp->md_len;
3475 if (ti->ti_msginptr < ti->ti_msginlen)
3481 if ((msg & MSG_IDENTIFY) == 0)
3483 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3488 li = slp->sl_Lnexus;
3491 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3494 slp->sl_Lnexus = li;
3495 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3499 if (MSGCMD_LUN(msg) != li->li_lun)
3503 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3505 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3507 #ifdef SCSI_LOW_DEBUG
3508 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3512 #endif /* SCSI_LOW_DEBUG */
3520 * Msg process completed, reset msgin pointer and assert ATN if desired.
3523 slp->sl_error |= FATALIO;
3524 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3525 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3528 if (ti->ti_msginptr < ti->ti_msginlen)
3531 #ifdef SCSI_LOW_DIAGNOSTIC
3532 scsi_low_msg_log_write(&ti->ti_log_msgin,
3533 &ti->ti_msgin[0], ti->ti_msginlen);
3534 #endif /* SCSI_LOW_DIAGNOSTIC */
3540 /**********************************************************
3542 **********************************************************/
3544 scsi_low_disconnected(slp, ti)
3545 struct scsi_low_softc *slp;
3546 struct targ_info *ti;
3548 struct slccb *cb = slp->sl_Qnexus;
3550 /* check phase completion */
3551 switch (slp->sl_msgphase)
3554 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3555 scsi_low_msginfunc_cc(slp);
3556 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3560 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3561 scsi_low_msginfunc_cc(slp);
3562 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3566 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3567 scsi_low_msginfunc_cc(slp);
3573 struct lun_info *li;
3576 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3577 cb->ccb_flags |= CCB_DISCQ;
3578 cb->ccb_error |= slp->sl_error;
3584 #ifdef SCSI_LOW_STATICS
3585 scsi_low_statics.nexus_disconnected ++;
3586 #endif /* SCSI_LOW_STATICS */
3588 #ifdef SCSI_LOW_DEBUG
3589 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3591 printf("## SCSI_LOW_DISCONNECTED ===============\n");
3592 scsi_low_print(slp, NULL);
3594 #endif /* SCSI_LOW_DEBUG */
3598 slp->sl_error |= FATALIO;
3599 if (ti->ti_phase == PH_SELSTART)
3600 slp->sl_error |= SELTIMEOUTIO;
3602 slp->sl_error |= UBFERR;
3611 #ifdef SCSI_LOW_DEBUG
3612 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3614 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3615 (cb->ccb_msgoutflag != 0 ||
3616 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3618 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3621 #endif /* SCSI_LOW_DEBUG */
3623 cb->ccb_error |= slp->sl_error;
3624 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3626 cb->ccb_flags |= CCB_STARTQ;
3627 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3632 scsi_low_bus_release(slp, ti);
3633 scsi_low_start(slp);
3637 /**********************************************************
3639 **********************************************************/
3641 scsi_low_alloc_qtag(cb)
3644 struct lun_info *li = cb->li;
3645 scsi_low_tag_t etag;
3647 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3650 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3651 etag = ffs(li->li_qtagbits);
3655 li->li_qtagbits &= ~(1 << (etag - 1));
3656 cb->ccb_otag = etag;
3659 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3660 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3661 if (li->li_qtagarray[li->li_qd] == 0)
3664 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3665 if (li->li_qtagarray[li->li_qd] == 0)
3671 li->li_qtagarray[li->li_qd] ++;
3672 cb->ccb_otag = (li->li_qd ++);
3674 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3678 scsi_low_dealloc_qtag(cb)
3681 struct lun_info *li = cb->li;
3682 scsi_low_tag_t etag;
3684 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3687 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3688 etag = cb->ccb_otag - 1;
3689 #ifdef SCSI_LOW_DIAGNOSTIC
3690 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3691 panic("scsi_low_dealloc_tag: illegal tag");
3692 #endif /* SCSI_LOW_DIAGNOSTIC */
3693 li->li_qtagbits |= (1 << etag);
3695 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3696 etag = cb->ccb_otag;
3697 #ifdef SCSI_LOW_DIAGNOSTIC
3698 if (etag >= SCSI_LOW_MAXNEXUS)
3699 panic("scsi_low_dealloc_tag: illegal tag");
3700 #endif /* SCSI_LOW_DIAGNOSTIC */
3701 li->li_qtagarray[etag] --;
3702 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3704 cb->ccb_otag = SCSI_LOW_UNKTAG;
3708 static struct slccb *
3709 scsi_low_revoke_ccb(slp, cb, fdone)
3710 struct scsi_low_softc *slp;
3714 struct targ_info *ti = cb->ti;
3715 struct lun_info *li = cb->li;
3717 #ifdef SCSI_LOW_DIAGNOSTIC
3718 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3719 (CCB_STARTQ | CCB_DISCQ))
3721 panic("%s: ccb in both queue",
3722 device_get_nameunit(slp->sl_dev));
3724 #endif /* SCSI_LOW_DIAGNOSTIC */
3726 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3728 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3731 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3733 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3739 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3740 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3743 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3744 (cb->ccb_flags & CCB_NORETRY) != 0))
3746 cb->ccb_error |= FATALIO;
3747 cb->ccb_flags &= ~CCB_AUTOSENSE;
3748 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3749 panic("%s: done ccb retried",
3750 device_get_nameunit(slp->sl_dev));
3755 cb->ccb_error |= PENDINGIO;
3756 scsi_low_deactivate_qtag(cb);
3757 scsi_low_ccb_message_retry(cb);
3758 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3764 scsi_low_reset_nexus_lun(slp, li, fdone)
3765 struct scsi_low_softc *slp;
3766 struct lun_info *li;
3769 struct slccb *cb, *ncb, *ecb;
3775 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3777 ncb = TAILQ_NEXT(cb, ccb_chain);
3778 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3782 * presumely keep ordering of io
3784 cb->ccb_flags |= CCB_STARTQ;
3787 TAILQ_INSERT_HEAD(&slp->sl_start,\
3792 TAILQ_INSERT_AFTER(&slp->sl_start,\
3793 ecb, cb, ccb_chain);
3800 /**************************************************************
3802 **************************************************************/
3804 scsi_low_calcf_lun(li)
3805 struct lun_info *li;
3807 struct targ_info *ti = li->li_ti;
3808 struct scsi_low_softc *slp = ti->ti_sc;
3809 u_int cfgflags, diskflags;
3811 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3812 cfgflags = li->li_cfgflags;
3816 diskflags = li->li_diskflags & li->li_quirks;
3819 li->li_flags &= ~SCSI_LOW_DISC;
3820 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3821 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3822 (cfgflags & SCSI_LOW_DISC) != 0)
3823 li->li_flags |= SCSI_LOW_DISC;
3826 li->li_flags |= SCSI_LOW_NOPARITY;
3827 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3828 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3829 (cfgflags & SCSI_LOW_NOPARITY) == 0)
3830 li->li_flags &= ~SCSI_LOW_NOPARITY;
3833 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3834 (cfgflags & SCSI_LOW_QTAG) != 0 &&
3835 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3837 li->li_flags |= SCSI_LOW_QTAG;
3838 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3839 li->li_maxnqio = li->li_maxnexus;
3843 li->li_flags &= ~SCSI_LOW_QTAG;
3844 li->li_maxnexus = 0;
3845 li->li_maxnqio = li->li_maxnexus;
3849 li->li_flags &= ~SCSI_LOW_LINK;
3850 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3851 (diskflags & SCSI_LOW_DISK_LINK) != 0)
3852 li->li_flags |= SCSI_LOW_LINK;
3854 /* compatible flags */
3855 li->li_flags &= ~SCSI_LOW_SYNC;
3856 if (ti->ti_maxsynch.offset > 0)
3857 li->li_flags |= SCSI_LOW_SYNC;
3859 #ifdef SCSI_LOW_DEBUG
3860 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3862 scsi_low_calcf_show(li);
3864 #endif /* SCSI_LOW_DEBUG */
3868 scsi_low_calcf_target(ti)
3869 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 device_printf(slp->sl_dev,
3918 "(%d:*): max period(%dns) offset(%d) width(%d)\n",
3920 ti->ti_maxsynch.period * 4,
3921 ti->ti_maxsynch.offset,
3924 #endif /* SCSI_LOW_DEBUG */
3928 scsi_low_calcf_show(li)
3929 struct lun_info *li;
3931 struct targ_info *ti = li->li_ti;
3932 struct scsi_low_softc *slp = ti->ti_sc;
3934 device_printf(slp->sl_dev,
3935 "(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
3936 ti->ti_id, li->li_lun,
3937 ti->ti_maxsynch.period * 4,
3938 ti->ti_maxsynch.offset,
3940 li->li_flags, SCSI_LOW_BITS);
3943 #ifdef SCSI_LOW_START_UP_CHECK
3944 /**************************************************************
3945 * scsi world start up
3946 **************************************************************/
3947 static int scsi_low_poll(struct scsi_low_softc *, struct slccb *);
3950 scsi_low_start_up(slp)
3951 struct scsi_low_softc *slp;
3953 struct targ_info *ti;
3954 struct lun_info *li;
3958 device_printf(slp->sl_dev, "scsi_low: probing all devices ....\n");
3960 for (target = 0; target < slp->sl_ntargs; target ++)
3962 if (target == slp->sl_hostid)
3964 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3966 device_printf(slp->sl_dev,
3967 "scsi_low: target %d (host card)\n",
3973 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3975 device_printf(slp->sl_dev, "scsi_low: target %d lun ",
3979 ti = slp->sl_ti[target];
3980 for (lun = 0; lun < slp->sl_nluns; lun ++)
3982 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
3988 li = scsi_low_alloc_li(ti, lun, 1);
3990 scsi_low_enqueue(slp, ti, li, cb,
3991 CCB_AUTOSENSE | CCB_POLLED, 0);
3993 scsi_low_poll(slp, cb);
3995 if (li->li_state != SCSI_LOW_LUN_OK)
3998 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4004 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4013 scsi_low_poll(slp, cb)
4014 struct scsi_low_softc *slp;
4020 while (slp->sl_nio > 0)
4022 DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4024 (*slp->sl_funcs->scsi_low_poll) (slp);
4025 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4029 scsi_low_timeout_check(slp);
4034 #endif /* SCSI_LOW_START_UP_CHECK */
4036 /**********************************************************
4038 **********************************************************/
4039 #ifdef SCSI_LOW_DEBUG
4041 scsi_low_test_abort(slp, ti, li)
4042 struct scsi_low_softc *slp;
4043 struct targ_info *ti;
4044 struct lun_info *li;
4048 if (li->li_disc > 1)
4050 acb = TAILQ_FIRST(&li->li_discq);
4051 if (scsi_low_abort_ccb(slp, acb) == 0)
4053 device_printf(slp->sl_dev,
4054 "aborting ccb(0x%lx) start\n", (u_long) acb);
4060 scsi_low_test_atten(slp, ti, msg)
4061 struct scsi_low_softc *slp;
4062 struct targ_info *ti;
4066 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4067 scsi_low_assert_msg(slp, ti, msg, 0);
4069 device_printf(slp->sl_dev, "atten check OK\n");
4073 scsi_low_test_cmdlnk(slp, cb)
4074 struct scsi_low_softc *slp;
4077 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4079 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4082 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4083 slp->sl_scp.scp_cmdlen);
4084 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4085 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4087 #endif /* SCSI_LOW_DEBUG */
4090 scsi_low_info(slp, ti, s)
4091 struct scsi_low_softc *slp;
4092 struct targ_info *ti;
4097 slp = LIST_FIRST(&sl_tab);
4101 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4104 TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
4106 scsi_low_print(slp, ti);
4111 scsi_low_print(slp, ti);
4115 static u_char *phase[] =
4117 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4118 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4122 scsi_low_print(slp, ti)
4123 struct scsi_low_softc *slp;
4124 struct targ_info *ti;
4126 struct lun_info *li;
4130 if (ti == NULL || ti == slp->sl_Tnexus)
4132 ti = slp->sl_Tnexus;
4133 li = slp->sl_Lnexus;
4134 cb = slp->sl_Qnexus;
4138 li = LIST_FIRST(&ti->ti_litab);
4139 cb = TAILQ_FIRST(&li->li_discq);
4143 device_printf(slp->sl_dev,
4144 "=== NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4145 (u_long) ti, (u_long) li, (u_long) cb, slp->sl_nio);
4150 u_int flags = 0, maxnqio = 0, nqio = 0;
4151 int lun = CAM_LUN_WILDCARD;
4156 flags = li->li_flags;
4157 maxnqio = li->li_maxnqio;
4161 device_printf(slp->sl_dev,
4162 "(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4163 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4164 phase[(int) ti->ti_phase], ti->ti_disc,
4169 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4170 (u_int) cb->ccb_scp.scp_cmd[0],
4171 cb->ccb_scp.scp_cmdlen,
4173 cb->ccb_scp.scp_datalen,
4174 (u_int) cb->ccb_sscp.scp_status,
4175 cb->ccb_error, SCSI_LOW_ERRORBITS);
4178 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4179 (u_int) (ti->ti_msginptr),
4180 (u_int) (ti->ti_msgin[0]),
4181 (u_int) (ti->ti_msgin[1]),
4182 (u_int) (ti->ti_msgin[2]),
4183 (u_int) (ti->ti_msgin[3]),
4184 (u_int) (ti->ti_msgin[4]),
4187 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4188 (u_int) ti->ti_msgflags,
4189 (u_int) (ti->ti_msgoutstr[0]),
4190 (u_int) (ti->ti_msgoutstr[1]),
4191 (u_int) (ti->ti_msgoutstr[2]),
4192 (u_int) (ti->ti_msgoutstr[3]),
4193 (u_int) (ti->ti_msgoutstr[4]),
4195 flags, SCSI_LOW_BITS);
4197 #ifdef SCSI_LOW_DIAGNOSTIC
4198 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4199 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4200 #endif /* SCSI_LOW_DIAGNOSTIC */
4204 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4205 (u_long) sp->scp_data,
4207 (u_int) sp->scp_status,
4208 slp->sl_error, SCSI_LOW_ERRORBITS);