1 /* $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.4 2001/12/17 13:30:20 non Exp $ */
2 /* $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.2 2003/06/17 04:28:19 dillon Exp $ */
3 /* $NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ */
6 #define SCSI_LOW_STATICS
8 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
9 #define SCSI_LOW_START_UP_CHECK
11 /* #define SCSI_LOW_INFO_DETAIL */
12 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
13 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
16 #define SCSI_LOW_TARGET_OPEN
17 #endif /* __NetBSD__ */
20 #define SCSI_LOW_FLAGS_QUIRKS_OK
21 #endif /* __FreeBSD__ */
24 * [NetBSD for NEC PC-98 series]
25 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
26 * NetBSD/pc98 porting staff. All rights reserved.
27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
28 * Naofumi HONDA. All rights reserved.
30 * [Ported for FreeBSD CAM]
31 * Copyright (c) 2000, 2001
32 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. The name of the author may not be used to endorse or promote products
44 * derived from this software without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
48 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
49 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
50 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
52 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
55 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56 * POSSIBILITY OF SUCH DAMAGE.
59 /* <On the nexus establishment>
60 * When our host is reselected,
61 * nexus establish processes are little complicated.
62 * Normal steps are followings:
63 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
64 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
65 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
69 #include <sys/param.h>
70 #include <sys/systm.h>
71 #include <sys/kernel.h>
74 #if __FreeBSD_version >= 500001
77 #include <machine/clock.h>
79 #include <sys/devicestat.h>
80 #endif /* __FreeBSD__ */
83 #include <sys/queue.h>
84 #include <sys/malloc.h>
85 #include <sys/errno.h>
88 #include <sys/device.h>
91 #include <machine/bus.h>
92 #include <machine/intr.h>
93 #include <machine/dvcfg.h>
97 #include <dev/scsipi/scsipi_all.h>
98 #include <dev/scsipi/scsipiconf.h>
99 #include <dev/scsipi/scsipi_disk.h>
100 #include <dev/scsipi/scsi_all.h>
101 #include <dev/scsipi/scsiconf.h>
102 #include <sys/scsiio.h>
104 #include <i386/Cbus/dev/scsi_low.h>
105 #endif /* __NetBSD__ */
109 #include <cam/cam_ccb.h>
110 #include <cam/cam_sim.h>
111 #include <cam/cam_debug.h>
112 #include <cam/cam_periph.h>
114 #include <cam/scsi/scsi_all.h>
115 #include <cam/scsi/scsi_message.h>
117 #include <cam/scsi/scsi_low.h>
119 #include <sys/cons.h>
120 #endif /* __FreeBSD__ */
122 /**************************************************************
124 **************************************************************/
125 #define SCSI_LOW_POLL_HZ 1000
127 /* functions return values */
128 #define SCSI_LOW_START_NO_QTAG 0
129 #define SCSI_LOW_START_QTAG 1
131 #define SCSI_LOW_DONE_COMPLETE 0
132 #define SCSI_LOW_DONE_RETRY 1
134 /* internal disk flags */
135 #define SCSI_LOW_DISK_DISC 0x00000001
136 #define SCSI_LOW_DISK_QTAG 0x00000002
137 #define SCSI_LOW_DISK_LINK 0x00000004
138 #define SCSI_LOW_DISK_PARITY 0x00000008
139 #define SCSI_LOW_DISK_SYNC 0x00010000
140 #define SCSI_LOW_DISK_WIDE_16 0x00020000
141 #define SCSI_LOW_DISK_WIDE_32 0x00040000
142 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
143 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
144 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
146 /**************************************************************
148 **************************************************************/
149 /* static */ void scsi_low_info __P((struct scsi_low_softc *, struct targ_info *, u_char *));
150 static void scsi_low_engage __P((void *));
151 static struct slccb *scsi_low_establish_ccb __P((struct targ_info *, struct lun_info *, scsi_low_tag_t));
152 static int scsi_low_done __P((struct scsi_low_softc *, struct slccb *));
153 static int scsi_low_setup_done __P((struct scsi_low_softc *, struct slccb *));
154 static void scsi_low_bus_release __P((struct scsi_low_softc *, struct targ_info *));
155 static void scsi_low_twiddle_wait __P((void));
156 static struct lun_info *scsi_low_alloc_li __P((struct targ_info *, int, int));
157 static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int));
158 static void scsi_low_calcf_lun __P((struct lun_info *));
159 static void scsi_low_calcf_target __P((struct targ_info *));
160 static void scsi_low_calcf_show __P((struct lun_info *));
161 static void scsi_low_reset_nexus __P((struct scsi_low_softc *, int));
162 static void scsi_low_reset_nexus_target __P((struct scsi_low_softc *, struct targ_info *, int));
163 static void scsi_low_reset_nexus_lun __P((struct scsi_low_softc *, struct lun_info *, int));
164 static int scsi_low_init __P((struct scsi_low_softc *, u_int));
165 static void scsi_low_start __P((struct scsi_low_softc *));
166 static void scsi_low_free_ti __P((struct scsi_low_softc *));
168 static int scsi_low_alloc_qtag __P((struct slccb *));
169 static int scsi_low_dealloc_qtag __P((struct slccb *));
170 static int scsi_low_enqueue __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int));
171 static int scsi_low_message_enqueue __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int));
172 static void scsi_low_unit_ready_cmd __P((struct slccb *));
173 static void scsi_low_timeout __P((void *));
174 static int scsi_low_timeout_check __P((struct scsi_low_softc *));
175 #ifdef SCSI_LOW_START_UP_CHECK
176 static int scsi_low_start_up __P((struct scsi_low_softc *));
177 #endif /* SCSI_LOW_START_UP_CHECK */
178 static int scsi_low_abort_ccb __P((struct scsi_low_softc *, struct slccb *));
179 static struct slccb *scsi_low_revoke_ccb __P((struct scsi_low_softc *, struct slccb *, int));
181 int scsi_low_version_major = 2;
182 int scsi_low_version_minor = 17;
184 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
186 /**************************************************************
187 * Debug, Run test and Statics
188 **************************************************************/
189 #ifdef SCSI_LOW_INFO_DETAIL
190 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
191 #else /* !SCSI_LOW_INFO_DETAIL */
192 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
193 #endif /* !SCSI_LOW_INFO_DETAIL */
195 #ifdef SCSI_LOW_STATICS
196 struct scsi_low_statics {
199 int nexus_disconnected;
200 int nexus_reselected;
203 #endif /* SCSI_LOW_STATICS */
205 #ifdef SCSI_LOW_DEBUG
206 #define SCSI_LOW_DEBUG_DONE 0x00001
207 #define SCSI_LOW_DEBUG_DISC 0x00002
208 #define SCSI_LOW_DEBUG_SENSE 0x00004
209 #define SCSI_LOW_DEBUG_CALCF 0x00008
210 #define SCSI_LOW_DEBUG_ACTION 0x10000
211 int scsi_low_debug = 0;
213 #define SCSI_LOW_MAX_ATTEN_CHECK 32
214 #define SCSI_LOW_ATTEN_CHECK 0x0001
215 #define SCSI_LOW_CMDLNK_CHECK 0x0002
216 #define SCSI_LOW_ABORT_CHECK 0x0004
217 #define SCSI_LOW_NEXUS_CHECK 0x0008
218 int scsi_low_test = 0;
219 int scsi_low_test_id = 0;
221 static void scsi_low_test_abort __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *));
222 static void scsi_low_test_cmdlnk __P((struct scsi_low_softc *, struct slccb *));
223 static void scsi_low_test_atten __P((struct scsi_low_softc *, struct targ_info *, u_int));
224 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
225 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
226 #define SCSI_LOW_DEBUG_GO(fl, id) \
227 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
228 #endif /* SCSI_LOW_DEBUG */
230 /**************************************************************
232 **************************************************************/
233 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
234 GENERIC_CCB(scsi_low, slccb, ccb_chain)
236 /**************************************************************
238 **************************************************************/
239 #define SCSI_LOW_INLINE static __inline
240 SCSI_LOW_INLINE void scsi_low_activate_qtag __P((struct slccb *));
241 SCSI_LOW_INLINE void scsi_low_deactivate_qtag __P((struct slccb *));
242 SCSI_LOW_INLINE void scsi_low_ccb_message_assert __P((struct slccb *, u_int));
243 SCSI_LOW_INLINE void scsi_low_ccb_message_exec __P((struct scsi_low_softc *, struct slccb *));
244 SCSI_LOW_INLINE void scsi_low_ccb_message_retry __P((struct slccb *));
245 SCSI_LOW_INLINE void scsi_low_ccb_message_clear __P((struct slccb *));
246 SCSI_LOW_INLINE void scsi_low_init_msgsys __P((struct scsi_low_softc *, struct targ_info *));
249 scsi_low_activate_qtag(cb)
252 struct lun_info *li = cb->li;
254 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
258 cb->ccb_tag = cb->ccb_otag;
262 scsi_low_deactivate_qtag(cb)
265 struct lun_info *li = cb->li;
267 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
271 cb->ccb_tag = SCSI_LOW_UNKTAG;
275 scsi_low_ccb_message_exec(slp, cb)
276 struct scsi_low_softc *slp;
280 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
281 cb->ccb_msgoutflag = 0;
285 scsi_low_ccb_message_assert(cb, msg)
290 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
294 scsi_low_ccb_message_retry(cb)
297 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
301 scsi_low_ccb_message_clear(cb)
304 cb->ccb_msgoutflag = 0;
308 scsi_low_init_msgsys(slp, ti)
309 struct scsi_low_softc *slp;
310 struct targ_info *ti;
314 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
315 SCSI_LOW_DEASSERT_ATN(slp);
316 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
319 /*=============================================================
320 * START OF OS switch (All OS depend fucntions should be here)
321 =============================================================*/
322 /* common os depend utitlities */
323 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
324 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
325 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
327 static u_int8_t scsi_low_cmd_flags[256] = {
328 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
329 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
330 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
331 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
332 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
335 struct scsi_low_error_code {
340 static struct slccb *scsi_low_find_ccb __P((struct scsi_low_softc *, u_int, u_int, void *));
341 static int scsi_low_translate_error_code __P((struct slccb *, struct scsi_low_error_code *));
343 static struct slccb *
344 scsi_low_find_ccb(slp, target, lun, osdep)
345 struct scsi_low_softc *slp;
349 struct targ_info *ti;
353 ti = slp->sl_ti[target];
354 li = scsi_low_alloc_li(ti, lun, 0);
358 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
361 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
362 cb = TAILQ_NEXT(cb, ccb_chain))
364 if (cb->osdep == osdep)
368 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
369 cb = TAILQ_NEXT(cb, ccb_chain))
371 if (cb->osdep == osdep)
378 scsi_low_translate_error_code(cb, tp)
380 struct scsi_low_error_code *tp;
383 if (cb->ccb_error == 0)
384 return tp->error_code;
386 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
388 return tp->error_code;
391 #ifdef SCSI_LOW_INTERFACE_XS
392 /**************************************************************
393 * SCSI INTERFACE (XS)
394 **************************************************************/
395 #define SCSI_LOW_MINPHYS 0x10000
396 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
397 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
398 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
399 #define SCSI_LOW_XS_POLL_HZ 1000
401 static int scsi_low_poll_xs __P((struct scsi_low_softc *, struct slccb *));
402 static void scsi_low_scsi_minphys_xs __P((struct buf *));
403 #ifdef SCSI_LOW_TARGET_OPEN
404 static int scsi_low_target_open __P((struct scsipi_link *, struct cfdata *));
405 #endif /* SCSI_LOW_TARGET_OPEN */
406 static int scsi_low_scsi_cmd_xs __P((struct scsipi_xfer *));
407 static int scsi_low_enable_xs __P((void *, int));
408 static int scsi_low_ioctl_xs __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
410 static int scsi_low_attach_xs __P((struct scsi_low_softc *));
411 static int scsi_low_world_start_xs __P((struct scsi_low_softc *));
412 static int scsi_low_dettach_xs __P((struct scsi_low_softc *));
413 static int scsi_low_ccb_setup_xs __P((struct scsi_low_softc *, struct slccb *));
414 static int scsi_low_done_xs __P((struct scsi_low_softc *, struct slccb *));
415 static void scsi_low_timeout_xs __P((struct scsi_low_softc *, int, int));
416 static u_int scsi_low_translate_quirks_xs __P((u_int));
417 static void scsi_low_setup_quirks_xs __P((struct targ_info *, struct lun_info *, u_int));
419 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
421 scsi_low_world_start_xs,
423 scsi_low_ccb_setup_xs,
428 struct scsipi_device scsi_low_dev = {
429 NULL, /* Use default error handler */
430 NULL, /* have a queue, served by this */
431 NULL, /* have no async handler */
432 NULL, /* Use default 'done' routine */
435 struct scsi_low_error_code scsi_low_error_code_xs[] = {
439 {SELTIMEOUTIO, XS_SELTIMEOUT},
440 {TIMEOUTIO, XS_TIMEOUT},
441 {-1, XS_DRIVER_STUFFUP}
445 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
446 struct scsipi_link *link;
452 struct scsi_low_softc *slp;
453 int s, error = ENOTTY;
455 slp = (struct scsi_low_softc *) link->adapter_softc;
456 if ((slp->sl_flags & HW_INACTIVE) != 0)
459 if (cmd == SCBUSIORESET)
461 s = SCSI_LOW_SPLSCSI();
462 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
466 else if (slp->sl_funcs->scsi_low_ioctl != 0)
468 error = (*slp->sl_funcs->scsi_low_ioctl)
469 (slp, cmd, addr, flag, p);
476 scsi_low_enable_xs(arg, enable)
480 struct scsi_low_softc *slp = arg;
484 if ((slp->sl_flags & HW_INACTIVE) != 0)
489 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
490 (slp->sl_flags & HW_POWERCTRL) == 0)
493 slp->sl_flags |= HW_POWDOWN;
494 if (slp->sl_funcs->scsi_low_power != NULL)
496 (*slp->sl_funcs->scsi_low_power)
497 (slp, SCSI_LOW_POWDOWN);
504 scsi_low_scsi_minphys_xs(bp)
508 if (bp->b_bcount > SCSI_LOW_MINPHYS)
509 bp->b_bcount = SCSI_LOW_MINPHYS;
514 scsi_low_poll_xs(slp, cb)
515 struct scsi_low_softc *slp;
518 struct scsipi_xfer *xs = cb->osdep;
521 cb->ccb_flags |= CCB_NOSDONE;
524 while (slp->sl_nio > 0)
526 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
528 (*slp->sl_funcs->scsi_low_poll) (slp);
530 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
532 cb->ccb_flags |= CCB_NORETRY;
533 cb->ccb_error |= FATALIO;
534 (void) scsi_low_revoke_ccb(slp, cb, 1);
535 printf("%s: hardware inactive in poll mode\n",
539 if ((xs->flags & ITSDONE) != 0)
542 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
546 scsi_low_timeout_check(slp);
549 xs->flags |= ITSDONE;
555 scsi_low_scsi_cmd_xs(xs)
556 struct scsipi_xfer *xs;
558 struct scsipi_link *splp = xs->sc_link;
559 struct scsi_low_softc *slp = splp->adapter_softc;
560 struct targ_info *ti;
563 int s, targ, lun, flags, rv;
565 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
566 return TRY_AGAIN_LATER;
568 targ = splp->scsipi_scsi.target,
569 lun = splp->scsipi_scsi.lun;
570 ti = slp->sl_ti[targ];
575 if ((xs->flags & SCSI_POLL) == 0)
576 flags = CCB_AUTOSENSE;
578 flags = CCB_AUTOSENSE | CCB_POLLED;
581 s = SCSI_LOW_SPLSCSI();
582 li = scsi_low_alloc_li(ti, lun, 1);
583 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
585 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
588 if ((xs->flags & SCSI_RESET) != 0)
590 flags |= CCB_NORETRY | CCB_URGENT;
591 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
595 if (ti->ti_setup_msg != 0)
597 scsi_low_message_enqueue(slp, ti, li, flags);
601 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
604 #ifdef SCSI_LOW_DEBUG
605 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
607 scsi_low_test_abort(slp, ti, li);
609 #endif /* SCSI_LOW_DEBUG */
611 if ((cb->ccb_flags & CCB_POLLED) != 0)
613 rv = scsi_low_poll_xs(slp, cb);
617 rv = SUCCESSFULLY_QUEUED;
624 scsi_low_attach_xs(slp)
625 struct scsi_low_softc *slp;
627 struct scsipi_adapter *sap;
628 struct scsipi_link *splp;
630 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
632 sap = SCSI_LOW_MALLOC(sizeof(*sap));
635 splp = SCSI_LOW_MALLOC(sizeof(*splp));
639 SCSI_LOW_BZERO(sap, sizeof(*sap));
640 SCSI_LOW_BZERO(splp, sizeof(*splp));
642 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
643 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
644 sap->scsipi_enable = scsi_low_enable_xs;
645 sap->scsipi_ioctl = scsi_low_ioctl_xs;
646 #ifdef SCSI_LOW_TARGET_OPEN
647 sap->open_target_lu = scsi_low_target_open;
648 #endif /* SCSI_LOW_TARGET_OPEN */
650 splp->adapter_softc = slp;
651 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
652 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
653 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
654 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
655 splp->openings = slp->sl_openings;
656 splp->type = BUS_SCSI;
657 splp->adapter_softc = slp;
659 splp->device = &scsi_low_dev;
661 slp->sl_si.si_splp = splp;
662 slp->sl_show_result = SHOW_ALL_NEG;
667 scsi_low_world_start_xs(slp)
668 struct scsi_low_softc *slp;
675 scsi_low_dettach_xs(slp)
676 struct scsi_low_softc *slp;
680 * scsipi does not have dettach bus fucntion.
682 scsipi_dettach_scsibus(slp->sl_si.si_splp);
688 scsi_low_ccb_setup_xs(slp, cb)
689 struct scsi_low_softc *slp;
692 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
694 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
696 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
697 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
698 cb->ccb_scp.scp_data = xs->data;
699 cb->ccb_scp.scp_datalen = xs->datalen;
700 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
701 SCSI_LOW_WRITE : SCSI_LOW_READ;
702 cb->ccb_tcmax = xs->timeout / 1000;
706 scsi_low_unit_ready_cmd(cb);
708 return SCSI_LOW_START_QTAG;
712 scsi_low_done_xs(slp, cb)
713 struct scsi_low_softc *slp;
716 struct scsipi_xfer *xs;
718 xs = (struct scsipi_xfer *) cb->osdep;
719 if (cb->ccb_error == 0)
721 xs->error = XS_NOERROR;
726 if (cb->ccb_rcnt >= slp->sl_max_retry)
727 cb->ccb_error |= ABORTIO;
729 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
730 (cb->ccb_error & ABORTIO) == 0)
733 if ((cb->ccb_error & SENSEIO) != 0)
735 xs->sense.scsi_sense = cb->ccb_sense;
738 xs->error = scsi_low_translate_error_code(cb,
739 &scsi_low_error_code_xs[0]);
741 #ifdef SCSI_LOW_DIAGNOSTIC
742 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
743 cb->ccb_scp.scp_cmdlen > 0 &&
744 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
745 SCSI_LOW_CMD_ABORT_WARNING) != 0)
747 printf("%s: WARNING: scsi_low IO abort\n",
749 scsi_low_print(slp, NULL);
751 #endif /* SCSI_LOW_DIAGNOSTIC */
754 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
755 xs->status = 0; /* XXX */
757 xs->status = cb->ccb_scp.scp_status;
759 xs->flags |= ITSDONE;
760 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
767 scsi_low_timeout_xs(slp, ch, action)
768 struct scsi_low_softc *slp;
775 case SCSI_LOW_TIMEOUT_CH_IO:
778 case SCSI_LOW_TIMEOUT_START:
779 timeout(scsi_low_timeout, slp,
780 hz / SCSI_LOW_TIMEOUT_HZ);
782 case SCSI_LOW_TIMEOUT_STOP:
783 untimeout(scsi_low_timeout, slp);
788 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
791 case SCSI_LOW_TIMEOUT_START:
792 timeout(scsi_low_engage, slp, 1);
794 case SCSI_LOW_TIMEOUT_STOP:
795 untimeout(scsi_low_engage, slp);
800 case SCSI_LOW_TIMEOUT_CH_RECOVER:
806 scsi_low_translate_quirks_xs(quirks)
811 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
814 if (quirks & SDEV_NODISC)
815 flags &= ~SCSI_LOW_DISK_DISC;
816 #endif /* SDEV_NODISC */
818 if (quirks & SDEV_NOPARITY)
819 flags &= ~SCSI_LOW_DISK_PARITY;
820 #endif /* SDEV_NOPARITY */
822 if (quirks & SDEV_NOCMDLNK)
823 flags &= ~SCSI_LOW_DISK_LINK;
824 #endif /* SDEV_NOCMDLNK */
826 if (quirks & SDEV_NOTAG)
827 flags &= ~SCSI_LOW_DISK_QTAG;
828 #endif /* SDEV_NOTAG */
830 if (quirks & SDEV_NOSYNC)
831 flags &= ~SCSI_LOW_DISK_SYNC;
832 #endif /* SDEV_NOSYNC */
838 scsi_low_setup_quirks_xs(ti, li, flags)
839 struct targ_info *ti;
845 li->li_sloi.sloi_quirks = flags;
846 quirks = scsi_low_translate_quirks_xs(flags);
847 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
848 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
849 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
850 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
851 scsi_low_calcf_target(ti);
852 scsi_low_calcf_lun(li);
853 scsi_low_calcf_show(li);
856 #ifdef SCSI_LOW_TARGET_OPEN
858 scsi_low_target_open(link, cf)
859 struct scsipi_link *link;
862 u_int target = link->scsipi_scsi.target;
863 u_int lun = link->scsipi_scsi.lun;
864 struct scsi_low_softc *slp;
865 struct targ_info *ti;
868 slp = (struct scsi_low_softc *) link->adapter_softc;
869 ti = slp->sl_ti[target];
870 li = scsi_low_alloc_li(ti, lun, 0);
874 li->li_cfgflags = cf->cf_flags;
875 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
878 #endif /* SCSI_LOW_TARGET_OPEN */
880 #endif /* SCSI_LOW_INTERFACE_XS */
882 #ifdef SCSI_LOW_INTERFACE_CAM
883 /**************************************************************
884 * SCSI INTERFACE (CAM)
885 **************************************************************/
886 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
887 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
888 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
890 static void scsi_low_poll_cam __P((struct cam_sim *));
891 static void scsi_low_cam_rescan_callback __P((struct cam_periph *, union ccb *));
892 static void scsi_low_rescan_bus_cam __P((struct scsi_low_softc *));
893 void scsi_low_scsi_action_cam __P((struct cam_sim *, union ccb *));
895 static int scsi_low_attach_cam __P((struct scsi_low_softc *));
896 static int scsi_low_world_start_cam __P((struct scsi_low_softc *));
897 static int scsi_low_dettach_cam __P((struct scsi_low_softc *));
898 static int scsi_low_ccb_setup_cam __P((struct scsi_low_softc *, struct slccb *));
899 static int scsi_low_done_cam __P((struct scsi_low_softc *, struct slccb *));
900 static void scsi_low_timeout_cam __P((struct scsi_low_softc *, int, int));
902 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
904 scsi_low_world_start_cam,
905 scsi_low_dettach_cam,
906 scsi_low_ccb_setup_cam,
911 struct scsi_low_error_code scsi_low_error_code_cam[] = {
913 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
914 {SENSEERR, CAM_AUTOSENSE_FAIL},
915 {UACAERR, CAM_SCSI_STATUS_ERROR},
916 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
917 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
918 {TIMEOUTIO, CAM_CMD_TIMEOUT},
919 {PDMAERR, CAM_DATA_RUN_ERR},
920 {PARITYERR, CAM_UNCOR_PARITY},
921 {UBFERR, CAM_UNEXP_BUSFREE},
922 {ABORTIO, CAM_REQ_ABORTED},
923 {-1, CAM_UNREC_HBA_ERROR}
926 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
929 * Please check a polling hz, currently we assume scsi_low_poll() is
932 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
935 scsi_low_poll_cam(sim)
938 struct scsi_low_softc *slp = SIM2SLP(sim);
940 (*slp->sl_funcs->scsi_low_poll) (slp);
942 if (slp->sl_si.si_poll_count ++ >=
943 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
945 slp->sl_si.si_poll_count = 0;
946 scsi_low_timeout_check(slp);
951 scsi_low_cam_rescan_callback(periph, ccb)
952 struct cam_periph *periph;
956 xpt_free_path(ccb->ccb_h.path);
961 scsi_low_rescan_bus_cam(slp)
962 struct scsi_low_softc *slp;
964 struct cam_path *path;
965 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
968 bzero(ccb, sizeof(union ccb));
970 status = xpt_create_path(&path, xpt_periph,
971 cam_sim_path(slp->sl_si.sim), -1, 0);
972 if (status != CAM_REQ_CMP)
975 xpt_setup_ccb(&ccb->ccb_h, path, 5);
976 ccb->ccb_h.func_code = XPT_SCAN_BUS;
977 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
978 ccb->crcn.flags = CAM_FLAG_NONE;
983 scsi_low_scsi_action_cam(sim, ccb)
987 struct scsi_low_softc *slp = SIM2SLP(sim);
988 struct targ_info *ti;
991 u_int lun, flags, msg, target;
994 target = (u_int) (ccb->ccb_h.target_id);
995 lun = (u_int) ccb->ccb_h.target_lun;
997 #ifdef SCSI_LOW_DEBUG
998 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
1000 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
1001 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1003 #endif /* SCSI_LOW_DEBUG */
1005 switch (ccb->ccb_h.func_code) {
1006 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1007 #ifdef SCSI_LOW_DIAGNOSTIC
1008 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1010 printf("%s: invalid target/lun\n", slp->sl_xname);
1011 ccb->ccb_h.status = CAM_REQ_INVALID;
1015 #endif /* SCSI_LOW_DIAGNOSTIC */
1017 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1018 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1023 ti = slp->sl_ti[target];
1026 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1027 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1031 s = SCSI_LOW_SPLSCSI();
1032 li = scsi_low_alloc_li(ti, lun, 1);
1034 if (ti->ti_setup_msg != 0)
1036 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1039 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1041 #ifdef SCSI_LOW_DEBUG
1042 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1044 scsi_low_test_abort(slp, ti, li);
1046 #endif /* SCSI_LOW_DEBUG */
1050 case XPT_EN_LUN: /* Enable LUN as a target */
1051 case XPT_TARGET_IO: /* Execute target I/O request */
1052 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1053 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1055 ccb->ccb_h.status = CAM_REQ_INVALID;
1059 case XPT_ABORT: /* Abort the specified CCB */
1060 #ifdef SCSI_LOW_DIAGNOSTIC
1061 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1063 printf("%s: invalid target/lun\n", slp->sl_xname);
1064 ccb->ccb_h.status = CAM_REQ_INVALID;
1068 #endif /* SCSI_LOW_DIAGNOSTIC */
1070 s = SCSI_LOW_SPLSCSI();
1071 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1072 rv = scsi_low_abort_ccb(slp, cb);
1076 ccb->ccb_h.status = CAM_REQ_CMP;
1078 ccb->ccb_h.status = CAM_REQ_INVALID;
1082 case XPT_SET_TRAN_SETTINGS: {
1083 struct ccb_trans_settings *cts;
1086 #ifdef SCSI_LOW_DIAGNOSTIC
1087 if (target == CAM_TARGET_WILDCARD)
1089 printf("%s: invalid target\n", slp->sl_xname);
1090 ccb->ccb_h.status = CAM_REQ_INVALID;
1094 #endif /* SCSI_LOW_DIAGNOSTIC */
1096 ti = slp->sl_ti[target];
1097 if (lun == CAM_LUN_WILDCARD)
1100 s = SCSI_LOW_SPLSCSI();
1101 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
1102 CCB_TRANS_SYNC_RATE_VALID |
1103 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
1105 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
1106 val = cts->bus_width;
1107 if (val < ti->ti_width)
1110 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
1111 val = cts->sync_period;
1112 if (val == 0 || val > ti->ti_maxsynch.period)
1113 ti->ti_maxsynch.period = val;
1115 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
1116 val = cts->sync_offset;
1117 if (val < ti->ti_maxsynch.offset)
1118 ti->ti_maxsynch.offset = val;
1121 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1122 scsi_low_calcf_target(ti);
1125 if ((cts->valid & (CCB_TRANS_DISC_VALID |
1126 CCB_TRANS_TQ_VALID)) != 0)
1128 li = scsi_low_alloc_li(ti, lun, 1);
1129 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
1131 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
1132 li->li_quirks |= SCSI_LOW_DISK_DISC;
1134 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1136 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
1138 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
1139 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1141 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1144 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1145 scsi_low_calcf_target(ti);
1146 scsi_low_calcf_lun(li);
1147 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1148 scsi_low_calcf_show(li);
1152 ccb->ccb_h.status = CAM_REQ_CMP;
1157 case XPT_GET_TRAN_SETTINGS: {
1158 struct ccb_trans_settings *cts;
1162 #ifdef SCSI_LOW_DIAGNOSTIC
1163 if (target == CAM_TARGET_WILDCARD)
1165 printf("%s: invalid target\n", slp->sl_xname);
1166 ccb->ccb_h.status = CAM_REQ_INVALID;
1170 #endif /* SCSI_LOW_DIAGNOSTIC */
1171 ti = slp->sl_ti[target];
1172 if (lun == CAM_LUN_WILDCARD)
1175 s = SCSI_LOW_SPLSCSI();
1176 li = scsi_low_alloc_li(ti, lun, 1);
1177 #ifdef CAM_NEW_TRAN_CODE
1178 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1179 struct ccb_trans_settings_scsi *scsi =
1180 &cts->proto_specific.scsi;
1181 struct ccb_trans_settings_spi *spi =
1182 &cts->xport_specific.spi;
1183 #ifdef SCSI_LOW_DIAGNOSTIC
1184 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1186 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1187 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1191 #endif /* SCSI_LOW_DIAGNOSTIC */
1192 cts->protocol = PROTO_SCSI;
1193 cts->protocol_version = SCSI_REV_2;
1194 cts->transport = XPORT_SPI;
1195 cts->transport_version = 2;
1197 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1198 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1200 diskflags = li->li_diskflags & li->li_cfgflags;
1201 if (diskflags & SCSI_LOW_DISK_DISC)
1202 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1203 if (diskflags & SCSI_LOW_DISK_QTAG)
1204 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1206 spi->sync_period = ti->ti_maxsynch.period;
1207 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1208 spi->sync_offset = ti->ti_maxsynch.offset;
1209 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1211 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1212 spi->bus_width = ti->ti_width;
1214 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1215 scsi->valid = CTS_SCSI_VALID_TQ;
1216 spi->valid |= CTS_SPI_VALID_DISC;
1220 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1222 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
1224 #ifdef SCSI_LOW_DIAGNOSTIC
1225 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
1227 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1228 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
1232 #endif /* SCSI_LOW_DIAGNOSTIC */
1233 diskflags = li->li_diskflags & li->li_cfgflags;
1234 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
1235 cts->flags |= CCB_TRANS_DISC_ENB;
1237 cts->flags &= ~CCB_TRANS_DISC_ENB;
1238 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
1239 cts->flags |= CCB_TRANS_TAG_ENB;
1241 cts->flags &= ~CCB_TRANS_TAG_ENB;
1243 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1245 #ifdef SCSI_LOW_DIAGNOSTIC
1246 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1248 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1249 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1253 #endif /* SCSI_LOW_DIAGNOSTIC */
1254 if ((li->li_flags & SCSI_LOW_DISC) != 0)
1255 cts->flags |= CCB_TRANS_DISC_ENB;
1257 cts->flags &= ~CCB_TRANS_DISC_ENB;
1258 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
1259 cts->flags |= CCB_TRANS_TAG_ENB;
1261 cts->flags &= ~CCB_TRANS_TAG_ENB;
1265 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1269 cts->sync_period = ti->ti_maxsynch.period;
1270 cts->sync_offset = ti->ti_maxsynch.offset;
1271 cts->bus_width = ti->ti_width;
1273 cts->valid = CCB_TRANS_SYNC_RATE_VALID
1274 | CCB_TRANS_SYNC_OFFSET_VALID
1275 | CCB_TRANS_BUS_WIDTH_VALID
1276 | CCB_TRANS_DISC_VALID
1277 | CCB_TRANS_TQ_VALID;
1278 ccb->ccb_h.status = CAM_REQ_CMP;
1286 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1287 struct ccb_calc_geometry *ccg;
1289 u_int32_t secs_per_cylinder;
1294 size_mb = ccg->volume_size
1295 / ((1024L * 1024L) / ccg->block_size);
1297 if (size_mb > 1024 && extended) {
1299 ccg->secs_per_track = 63;
1302 ccg->secs_per_track = 32;
1304 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1305 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1306 ccb->ccb_h.status = CAM_REQ_CMP;
1311 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1312 s = SCSI_LOW_SPLSCSI();
1313 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1315 ccb->ccb_h.status = CAM_REQ_CMP;
1319 case XPT_TERM_IO: /* Terminate the I/O process */
1320 ccb->ccb_h.status = CAM_REQ_INVALID;
1324 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1325 #ifdef SCSI_LOW_DIAGNOSTIC
1326 if (target == CAM_TARGET_WILDCARD)
1328 printf("%s: invalid target\n", slp->sl_xname);
1329 ccb->ccb_h.status = CAM_REQ_INVALID;
1333 #endif /* SCSI_LOW_DIAGNOSTIC */
1335 msg = SCSI_LOW_MSG_RESET;
1336 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1338 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1343 ti = slp->sl_ti[target];
1344 if (lun == CAM_LUN_WILDCARD)
1348 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1349 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1351 flags = CCB_NORETRY | CCB_URGENT;
1353 s = SCSI_LOW_SPLSCSI();
1354 li = scsi_low_alloc_li(ti, lun, 1);
1355 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1359 case XPT_PATH_INQ: { /* Path routing inquiry */
1360 struct ccb_pathinq *cpi = &ccb->cpi;
1362 cpi->version_num = scsi_low_version_major;
1363 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1364 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1365 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1366 cpi->hba_inquiry |= PI_WIDE_16;
1367 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1368 cpi->hba_inquiry |= PI_WIDE_32;
1369 if (ti->ti_maxsynch.offset > 0)
1370 cpi->hba_inquiry |= PI_SDTR_ABLE;
1371 cpi->target_sprt = 0;
1373 cpi->hba_eng_cnt = 0;
1374 cpi->max_target = slp->sl_ntargs - 1;
1375 cpi->max_lun = slp->sl_nluns - 1;
1376 cpi->initiator_id = slp->sl_hostid;
1377 cpi->bus_id = cam_sim_bus(sim);
1378 cpi->base_transfer_speed = 3300;
1379 #ifdef CAM_NEW_TRAN_CODE
1380 cpi->transport = XPORT_SPI;
1381 cpi->transport_version = 2;
1382 cpi->protocol = PROTO_SCSI;
1383 cpi->protocol_version = SCSI_REV_2;
1385 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1386 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1387 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1388 cpi->unit_number = cam_sim_unit(sim);
1389 cpi->ccb_h.status = CAM_REQ_CMP;
1395 printf("scsi_low: non support func_code = %d ",
1396 ccb->ccb_h.func_code);
1397 ccb->ccb_h.status = CAM_REQ_INVALID;
1404 scsi_low_attach_cam(slp)
1405 struct scsi_low_softc *slp;
1407 struct cam_devq *devq;
1408 int tagged_openings;
1410 sprintf(slp->sl_xname, "%s%d",
1411 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1413 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1418 * ask the adapter what subunits are present
1420 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1421 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1423 DEVPORT_DEVNAME(slp->sl_dev), slp,
1424 DEVPORT_DEVUNIT(slp->sl_dev),
1425 slp->sl_openings, tagged_openings, devq);
1427 if (slp->sl_si.sim == NULL) {
1428 cam_simq_free(devq);
1432 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1433 free(slp->sl_si.sim, M_DEVBUF);
1437 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1438 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1439 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1440 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1441 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1442 free(slp->sl_si.sim, M_DEVBUF);
1446 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1451 scsi_low_world_start_cam(slp)
1452 struct scsi_low_softc *slp;
1456 scsi_low_rescan_bus_cam(slp);
1461 scsi_low_dettach_cam(slp)
1462 struct scsi_low_softc *slp;
1465 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1466 xpt_free_path(slp->sl_si.path);
1467 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1468 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1473 scsi_low_ccb_setup_cam(slp, cb)
1474 struct scsi_low_softc *slp;
1477 union ccb *ccb = (union ccb *) cb->osdep;
1479 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1481 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1482 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1483 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1484 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1485 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1486 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1487 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1488 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1489 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1493 scsi_low_unit_ready_cmd(cb);
1495 return SCSI_LOW_START_QTAG;
1499 scsi_low_done_cam(slp, cb)
1500 struct scsi_low_softc *slp;
1505 ccb = (union ccb *) cb->osdep;
1506 if (cb->ccb_error == 0)
1508 ccb->ccb_h.status = CAM_REQ_CMP;
1509 ccb->csio.resid = 0;
1513 if (cb->ccb_rcnt >= slp->sl_max_retry)
1514 cb->ccb_error |= ABORTIO;
1516 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1517 (cb->ccb_error & ABORTIO) == 0)
1520 if ((cb->ccb_error & SENSEIO) != 0)
1522 memcpy(&ccb->csio.sense_data,
1524 sizeof(ccb->csio.sense_data));
1527 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1528 &scsi_low_error_code_cam[0]);
1530 #ifdef SCSI_LOW_DIAGNOSTIC
1531 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1532 cb->ccb_scp.scp_cmdlen > 0 &&
1533 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1534 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1536 printf("%s: WARNING: scsi_low IO abort\n",
1538 scsi_low_print(slp, NULL);
1540 #endif /* SCSI_LOW_DIAGNOSTIC */
1543 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1544 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1546 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1547 ccb->csio.scsi_status = 0; /* XXX */
1549 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1551 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1557 scsi_low_timeout_cam(slp, ch, action)
1558 struct scsi_low_softc *slp;
1565 case SCSI_LOW_TIMEOUT_CH_IO:
1568 case SCSI_LOW_TIMEOUT_START:
1569 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1570 hz / SCSI_LOW_TIMEOUT_HZ);
1572 case SCSI_LOW_TIMEOUT_STOP:
1573 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1578 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1581 case SCSI_LOW_TIMEOUT_START:
1582 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1584 case SCSI_LOW_TIMEOUT_STOP:
1585 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1589 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1594 #endif /* SCSI_LOW_INTERFACE_CAM */
1596 /*=============================================================
1597 * END OF OS switch (All OS depend fucntions should be above)
1598 =============================================================*/
1600 /**************************************************************
1601 * scsi low deactivate and activate
1602 **************************************************************/
1604 scsi_low_is_busy(slp)
1605 struct scsi_low_softc *slp;
1608 if (slp->sl_nio > 0)
1614 scsi_low_deactivate(slp)
1615 struct scsi_low_softc *slp;
1619 s = SCSI_LOW_SPLSCSI();
1620 slp->sl_flags |= HW_INACTIVE;
1621 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1622 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1623 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1624 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1630 scsi_low_activate(slp)
1631 struct scsi_low_softc *slp;
1635 s = SCSI_LOW_SPLSCSI();
1636 slp->sl_flags &= ~HW_INACTIVE;
1637 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1639 slp->sl_flags |= HW_INACTIVE;
1644 slp->sl_timeout_count = 0;
1645 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1646 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1651 /**************************************************************
1653 **************************************************************/
1654 #ifdef SCSI_LOW_DIAGNOSTIC
1655 static void scsi_low_msg_log_init __P((struct scsi_low_msg_log *));
1656 static void scsi_low_msg_log_write __P((struct scsi_low_msg_log *, u_int8_t *,
1658 static void scsi_low_msg_log_show __P((struct scsi_low_msg_log *, char *, int));
1661 scsi_low_msg_log_init(slmlp)
1662 struct scsi_low_msg_log *slmlp;
1665 slmlp->slml_ptr = 0;
1669 scsi_low_msg_log_write(slmlp, datap, len)
1670 struct scsi_low_msg_log *slmlp;
1676 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1679 ptr = slmlp->slml_ptr ++;
1680 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1681 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1682 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1683 slmlp->slml_msg[ptr].msg[ind] = 0;
1687 scsi_low_msg_log_show(slmlp, s, len)
1688 struct scsi_low_msg_log *slmlp;
1694 printf("%s: (%d) ", s, slmlp->slml_ptr);
1695 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1697 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1700 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1706 #endif /* SCSI_LOW_DIAGNOSTIC */
1708 /**************************************************************
1710 **************************************************************/
1712 scsi_low_engage(arg)
1715 struct scsi_low_softc *slp = arg;
1716 int s = SCSI_LOW_SPLSCSI();
1718 switch (slp->sl_rstep)
1722 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1723 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1724 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1729 slp->sl_flags &= ~HW_RESUME;
1730 scsi_low_start(slp);
1740 scsi_low_init(slp, flags)
1741 struct scsi_low_softc *slp;
1746 slp->sl_flags |= HW_INITIALIZING;
1748 /* clear power control timeout */
1749 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1751 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1752 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1753 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1755 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1758 /* reset current nexus */
1759 scsi_low_reset_nexus(slp, flags);
1760 if ((slp->sl_flags & HW_INACTIVE) != 0)
1766 if (flags != SCSI_LOW_RESTART_SOFT)
1768 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1772 slp->sl_flags &= ~HW_INITIALIZING;
1776 /**************************************************************
1778 **************************************************************/
1779 static struct lun_info *
1780 scsi_low_alloc_li(ti, lun, alloc)
1781 struct targ_info *ti;
1785 struct scsi_low_softc *slp = ti->ti_sc;
1786 struct lun_info *li;
1788 li = LIST_FIRST(&ti->ti_litab);
1791 if (li->li_lun == lun)
1794 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1796 if (li->li_lun == lun)
1798 LIST_REMOVE(li, lun_chain);
1799 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1808 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1810 panic("no lun info mem\n");
1812 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1816 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1818 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1819 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1820 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1821 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1822 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1824 li->li_qtagbits = (u_int) -1;
1826 TAILQ_INIT(&li->li_discq);
1827 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1829 /* host specific structure initialization per lun */
1830 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1831 (*slp->sl_funcs->scsi_low_lun_init)
1832 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1833 scsi_low_calcf_lun(li);
1837 /**************************************************************
1838 * allocate targ_info
1839 **************************************************************/
1840 static struct targ_info *
1841 scsi_low_alloc_ti(slp, targ)
1842 struct scsi_low_softc *slp;
1845 struct targ_info *ti;
1847 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1848 TAILQ_INIT(&slp->sl_titab);
1850 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1852 panic("%s short of memory\n", slp->sl_xname);
1854 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1858 slp->sl_ti[targ] = ti;
1859 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1860 LIST_INIT(&ti->ti_litab);
1862 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1863 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1864 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1865 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1866 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1867 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1869 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1871 (*slp->sl_funcs->scsi_low_targ_init)
1872 (slp, ti, SCSI_LOW_INFO_ALLOC);
1874 scsi_low_calcf_target(ti);
1879 scsi_low_free_ti(slp)
1880 struct scsi_low_softc *slp;
1882 struct targ_info *ti, *tib;
1883 struct lun_info *li, *nli;
1885 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1887 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1889 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1891 (*slp->sl_funcs->scsi_low_lun_init)
1892 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1894 nli = LIST_NEXT(li, lun_chain);
1898 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1900 (*slp->sl_funcs->scsi_low_targ_init)
1901 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1903 tib = TAILQ_NEXT(ti, ti_chain);
1908 /**************************************************************
1910 **************************************************************/
1912 scsi_low_bus_idle(slp)
1913 struct scsi_low_softc *slp;
1916 slp->sl_retry_sel = 0;
1917 if (slp->sl_Tnexus == NULL)
1918 scsi_low_start(slp);
1922 scsi_low_timeout(arg)
1925 struct scsi_low_softc *slp = arg;
1928 s = SCSI_LOW_SPLSCSI();
1929 (void) scsi_low_timeout_check(slp);
1930 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1931 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1936 scsi_low_timeout_check(slp)
1937 struct scsi_low_softc *slp;
1939 struct targ_info *ti;
1940 struct lun_info *li;
1941 struct slccb *cb = NULL; /* XXX */
1943 /* selection restart */
1944 if (slp->sl_retry_sel != 0)
1946 slp->sl_retry_sel = 0;
1947 if (slp->sl_Tnexus != NULL)
1950 cb = TAILQ_FIRST(&slp->sl_start);
1954 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1956 cb->ccb_flags |= CCB_NORETRY;
1957 cb->ccb_error |= SELTIMEOUTIO;
1958 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1959 panic("%s: ccb not finished\n", slp->sl_xname);
1962 if (slp->sl_Tnexus == NULL)
1963 scsi_low_start(slp);
1966 /* call hardware timeout */
1968 if (slp->sl_funcs->scsi_low_timeout != NULL)
1970 (*slp->sl_funcs->scsi_low_timeout) (slp);
1973 if (slp->sl_timeout_count ++ <
1974 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1977 slp->sl_timeout_count = 0;
1978 if (slp->sl_nio > 0)
1980 if ((cb = slp->sl_Qnexus) != NULL)
1982 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1986 else if (slp->sl_disc == 0)
1988 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1991 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1995 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1996 ti = TAILQ_NEXT(ti, ti_chain))
1998 if (ti->ti_disc == 0)
2001 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2002 li = LIST_NEXT(li, lun_chain))
2004 for (cb = TAILQ_FIRST(&li->li_discq);
2006 cb = TAILQ_NEXT(cb, ccb_chain))
2009 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
2017 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
2019 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2022 if (slp->sl_active != 0)
2024 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2030 if (slp->sl_powc < 0)
2032 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2033 slp->sl_flags |= HW_POWDOWN;
2034 (*slp->sl_funcs->scsi_low_power)
2035 (slp, SCSI_LOW_POWDOWN);
2041 cb->ccb_error |= TIMEOUTIO;
2042 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2043 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2044 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2045 scsi_low_start(slp);
2051 scsi_low_abort_ccb(slp, cb)
2052 struct scsi_low_softc *slp;
2055 struct targ_info *ti;
2056 struct lun_info *li;
2061 if ((cb->ccb_omsgoutflag &
2062 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2067 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2068 msg = SCSI_LOW_MSG_ABORT;
2070 msg = SCSI_LOW_MSG_ABORT_QTAG;
2072 cb->ccb_error |= ABORTIO;
2073 cb->ccb_flags |= CCB_NORETRY;
2074 scsi_low_ccb_message_assert(cb, msg);
2076 if (cb == slp->sl_Qnexus)
2078 scsi_low_assert_msg(slp, ti, msg, 1);
2080 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2082 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2083 panic("%s: revoked ccb done\n", slp->sl_xname);
2085 cb->ccb_flags |= CCB_STARTQ;
2086 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2088 if (slp->sl_Tnexus == NULL)
2089 scsi_low_start(slp);
2093 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2094 panic("%s: revoked ccb retried\n", slp->sl_xname);
2099 /**************************************************************
2100 * Generic SCSI INTERFACE
2101 **************************************************************/
2103 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2104 struct scsi_low_softc *slp;
2105 int openings, ntargs, nluns, targsize, lunsize;
2107 struct targ_info *ti;
2108 struct lun_info *li;
2111 #ifdef SCSI_LOW_INTERFACE_XS
2112 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2113 #endif /* SCSI_LOW_INTERFACE_XS */
2114 #ifdef SCSI_LOW_INTERFACE_CAM
2115 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2116 #endif /* SCSI_LOW_INTERFACE_CAM */
2118 if (slp->sl_osdep_fp == NULL)
2119 panic("scsi_low: interface not spcified\n");
2121 if (ntargs > SCSI_LOW_NTARGETS)
2123 printf("scsi_low: %d targets are too large\n", ntargs);
2124 printf("change kernel options SCSI_LOW_NTARGETS");
2129 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2131 slp->sl_openings = openings;
2132 slp->sl_ntargs = ntargs;
2133 slp->sl_nluns = nluns;
2134 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2136 if (lunsize < sizeof(struct lun_info))
2137 lunsize = sizeof(struct lun_info);
2139 if (targsize < sizeof(struct targ_info))
2140 targsize = sizeof(struct targ_info);
2142 slp->sl_targsize = targsize;
2143 for (i = 0; i < ntargs; i ++)
2145 ti = scsi_low_alloc_ti(slp, i);
2146 ti->ti_lunsize = lunsize;
2147 li = scsi_low_alloc_li(ti, 0, 1);
2150 /* initialize queue */
2151 nccb = openings * ntargs;
2152 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2153 nccb = SCSI_LOW_NCCB;
2154 scsi_low_init_ccbque(nccb);
2155 TAILQ_INIT(&slp->sl_start);
2157 /* call os depend attach */
2158 s = SCSI_LOW_SPLSCSI();
2159 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2163 printf("%s: scsi_low_attach: osdep attach failed\n",
2168 /* check hardware */
2169 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2170 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2173 printf("%s: scsi_low_attach: initialization failed\n",
2178 /* start watch dog */
2179 slp->sl_timeout_count = 0;
2180 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2181 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2182 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2185 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2187 #ifdef SCSI_LOW_START_UP_CHECK
2188 /* probing devices */
2189 scsi_low_start_up(slp);
2190 #endif /* SCSI_LOW_START_UP_CHECK */
2192 /* call os depend attach done*/
2193 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2199 scsi_low_dettach(slp)
2200 struct scsi_low_softc *slp;
2204 s = SCSI_LOW_SPLSCSI();
2205 if (scsi_low_is_busy(slp) != 0)
2211 scsi_low_deactivate(slp);
2213 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2220 scsi_low_free_ti(slp);
2221 LIST_REMOVE(slp, sl_chain);
2226 /**************************************************************
2228 **************************************************************/
2230 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2231 struct scsi_low_softc *slp;
2232 struct targ_info *ti;
2233 struct lun_info *li;
2241 scsi_low_ccb_message_assert(cb, msg);
2243 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2244 scsi_low_alloc_qtag(cb);
2246 cb->ccb_flags = flags | CCB_STARTQ;
2247 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2248 cb->ccb_error |= PENDINGIO;
2250 if ((flags & CCB_URGENT) != 0)
2252 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2256 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2261 if (slp->sl_Tnexus == NULL)
2262 scsi_low_start(slp);
2267 scsi_low_message_enqueue(slp, ti, li, flags)
2268 struct scsi_low_softc *slp;
2269 struct targ_info *ti;
2270 struct lun_info *li;
2276 tmsgflags = ti->ti_setup_msg;
2277 ti->ti_setup_msg = 0;
2279 flags |= CCB_NORETRY;
2280 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2285 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2289 /**************************************************************
2290 * Generic Start & Done
2291 **************************************************************/
2292 #define SLSC_MODE_SENSE_SHORT 0x1a
2293 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2294 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2295 sizeof(struct scsi_low_mode_sense_data), 0};
2296 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2297 sizeof(struct scsi_low_inq_data), 0};
2298 static u_int8_t unit_ready_cmd[6];
2299 static int scsi_low_setup_start __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *));
2300 static int scsi_low_sense_abort_start __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *));
2301 static int scsi_low_resume __P((struct scsi_low_softc *));
2304 scsi_low_unit_ready_cmd(cb)
2308 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2309 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2310 cb->ccb_scp.scp_datalen = 0;
2311 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2316 scsi_low_sense_abort_start(slp, ti, li, cb)
2317 struct scsi_low_softc *slp;
2318 struct targ_info *ti;
2319 struct lun_info *li;
2323 cb->ccb_scp.scp_cmdlen = 6;
2324 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2325 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2326 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2327 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2328 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2329 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2330 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2332 scsi_low_ccb_message_clear(cb);
2333 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2335 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2339 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2340 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2341 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2342 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2345 return SCSI_LOW_START_NO_QTAG;
2349 scsi_low_setup_start(slp, ti, li, cb)
2350 struct scsi_low_softc *slp;
2351 struct targ_info *ti;
2352 struct lun_info *li;
2356 switch(li->li_state)
2358 case SCSI_LOW_LUN_SLEEP:
2359 scsi_low_unit_ready_cmd(cb);
2362 case SCSI_LOW_LUN_START:
2363 cb->ccb_scp.scp_cmd = ss_cmd;
2364 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2365 cb->ccb_scp.scp_datalen = 0;
2366 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2370 case SCSI_LOW_LUN_INQ:
2371 cb->ccb_scp.scp_cmd = inq_cmd;
2372 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2373 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2374 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2375 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2379 case SCSI_LOW_LUN_MODEQ:
2380 cb->ccb_scp.scp_cmd = sms_cmd;
2381 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2382 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2383 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2384 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2386 return SCSI_LOW_START_QTAG;
2389 panic("%s: no setup phase\n", slp->sl_xname);
2392 return SCSI_LOW_START_NO_QTAG;
2396 scsi_low_resume(slp)
2397 struct scsi_low_softc *slp;
2400 if (slp->sl_flags & HW_RESUME)
2402 slp->sl_flags &= ~HW_POWDOWN;
2403 if (slp->sl_funcs->scsi_low_power != NULL)
2405 slp->sl_flags |= HW_RESUME;
2407 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2408 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2409 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2410 SCSI_LOW_TIMEOUT_START);
2418 struct scsi_low_softc *slp;
2420 struct targ_info *ti;
2421 struct lun_info *li;
2425 /* check hardware exists or under initializations ? */
2426 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2429 /* check hardware power up ? */
2430 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2433 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2435 if (scsi_low_resume(slp) == EJUSTRETURN)
2441 #ifdef SCSI_LOW_DIAGNOSTIC
2442 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2444 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2445 panic("%s: inconsistent\n", slp->sl_xname);
2447 #endif /* SCSI_LOW_DIAGNOSTIC */
2449 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2450 cb = TAILQ_NEXT(cb, ccb_chain))
2454 if (li->li_disc == 0)
2456 goto scsi_low_cmd_start;
2458 else if (li->li_nqio > 0)
2460 if (li->li_nqio < li->li_maxnqio ||
2461 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2462 goto scsi_low_cmd_start;
2468 cb->ccb_flags &= ~CCB_STARTQ;
2469 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2472 /* clear all error flag bits (for restart) */
2474 cb->ccb_datalen = -1;
2475 cb->ccb_scp.scp_status = ST_UNKNOWN;
2477 /* setup nexus pointer */
2478 slp->sl_Qnexus = cb;
2479 slp->sl_Lnexus = li;
2480 slp->sl_Tnexus = ti;
2482 /* initialize msgsys */
2483 scsi_low_init_msgsys(slp, ti);
2486 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2488 /* CA state or forced abort */
2489 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2491 else if (li->li_state >= SCSI_LOW_LUN_OK)
2493 cb->ccb_flags &= ~CCB_INTERNAL;
2494 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2495 if (cb->ccb_msgoutflag != 0)
2497 scsi_low_ccb_message_exec(slp, cb);
2502 cb->ccb_flags |= CCB_INTERNAL;
2503 rv = scsi_low_setup_start(slp, ti, li, cb);
2507 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2509 if (rv == SCSI_LOW_START_QTAG &&
2510 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2515 scsi_low_activate_qtag(cb);
2516 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2517 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2518 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2519 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2520 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2522 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2523 scsi_low_assert_msg(slp, ti, qmsg, 0);
2527 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2528 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2529 cb->ccb_tc = cb->ccb_tcmax;
2531 /* setup saved scsi data pointer */
2532 cb->ccb_sscp = cb->ccb_scp;
2534 /* setup current scsi pointer */
2535 slp->sl_scp = cb->ccb_sscp;
2536 slp->sl_error = cb->ccb_error;
2538 /* assert always an identify msg */
2539 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2542 #ifdef SCSI_LOW_DIAGNOSTIC
2543 scsi_low_msg_log_init(&ti->ti_log_msgin);
2544 scsi_low_msg_log_init(&ti->ti_log_msgout);
2545 #endif /* SCSI_LOW_DIAGNOSTIC */
2547 /* selection start */
2549 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2550 if (rv == SCSI_LOW_START_OK)
2552 #ifdef SCSI_LOW_STATICS
2553 scsi_low_statics.nexus_win ++;
2554 #endif /* SCSI_LOW_STATICS */
2558 scsi_low_arbit_fail(slp, cb);
2559 #ifdef SCSI_LOW_STATICS
2560 scsi_low_statics.nexus_fail ++;
2561 #endif /* SCSI_LOW_STATICS */
2565 scsi_low_arbit_fail(slp, cb)
2566 struct scsi_low_softc *slp;
2569 struct targ_info *ti = cb->ti;
2571 scsi_low_deactivate_qtag(cb);
2572 scsi_low_ccb_message_retry(cb);
2573 cb->ccb_flags |= CCB_STARTQ;
2574 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2576 scsi_low_bus_release(slp, ti);
2579 if (slp->sl_disc == 0)
2581 #ifdef SCSI_LOW_DIAGNOSTIC
2582 printf("%s: try selection again\n", slp->sl_xname);
2583 #endif /* SCSI_LOW_DIAGNOSTIC */
2584 slp->sl_retry_sel = 1;
2589 scsi_low_bus_release(slp, ti)
2590 struct scsi_low_softc *slp;
2591 struct targ_info *ti;
2594 if (ti->ti_disc > 0)
2596 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2600 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2603 /* clear all nexus pointer */
2604 slp->sl_Qnexus = NULL;
2605 slp->sl_Lnexus = NULL;
2606 slp->sl_Tnexus = NULL;
2608 /* clear selection assert */
2609 slp->sl_selid = NULL;
2611 /* clear nexus data */
2612 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2614 /* clear phase change counter */
2615 slp->sl_ph_count = 0;
2619 scsi_low_setup_done(slp, cb)
2620 struct scsi_low_softc *slp;
2623 struct targ_info *ti;
2624 struct lun_info *li;
2629 if (cb->ccb_rcnt >= slp->sl_max_retry)
2631 cb->ccb_error |= ABORTIO;
2632 return SCSI_LOW_DONE_COMPLETE;
2635 /* XXX: special huck for selection timeout */
2636 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2637 (cb->ccb_error & SELTIMEOUTIO) != 0)
2639 cb->ccb_error |= ABORTIO;
2640 return SCSI_LOW_DONE_COMPLETE;
2643 switch(li->li_state)
2645 case SCSI_LOW_LUN_INQ:
2646 if (cb->ccb_error != 0)
2649 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2653 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2655 else if ((li->li_inq.sd_version & 7) >= 2 ||
2656 (li->li_inq.sd_len >= 4))
2658 if ((li->li_inq.sd_support & 0x2) == 0)
2659 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2660 if ((li->li_inq.sd_support & 0x8) == 0)
2661 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2664 if ((li->li_inq.sd_support & 0x10) == 0)
2665 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2666 if ((li->li_inq.sd_support & 0x20) == 0)
2667 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2668 if ((li->li_inq.sd_support & 0x40) == 0)
2669 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2674 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2677 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2679 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2681 scsi_low_calcf_target(ti);
2682 scsi_low_calcf_lun(li);
2685 case SCSI_LOW_LUN_MODEQ:
2686 if (cb->ccb_error != 0)
2688 if (cb->ccb_error & SENSEIO)
2690 #ifdef SCSI_LOW_DEBUG
2691 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2693 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2694 (u_int) cb->ccb_sense.error_code,
2695 (u_int) cb->ccb_sense.segment,
2696 (u_int) cb->ccb_sense.flags,
2697 (u_int) cb->ccb_sense.add_sense_code,
2698 (u_int) cb->ccb_sense.add_sense_code_qual);
2700 #endif /* SCSI_LOW_DEBUG */
2704 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2707 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2709 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2710 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2712 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2713 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2714 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2716 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2717 scsi_low_calcf_lun(li);
2725 if (li->li_state == SCSI_LOW_LUN_OK)
2727 scsi_low_calcf_target(ti);
2728 scsi_low_calcf_lun(li);
2729 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2730 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2732 scsi_low_calcf_show(li);
2737 return SCSI_LOW_DONE_RETRY;
2741 scsi_low_done(slp, cb)
2742 struct scsi_low_softc *slp;
2747 if (cb->ccb_error == 0)
2749 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2751 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2753 * SCSI-2 draft suggests
2754 * page 0x0a QErr bit determins if
2755 * the target aborts or continues
2756 * the queueing io's after CA state resolved.
2757 * However many targets seem not to support
2758 * the page 0x0a. Thus we should manually clear the
2759 * queuing io's after CA state.
2761 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2764 cb->ccb_flags |= CCB_CLEARQ;
2767 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2769 if ((cb->ccb_flags & CCB_SENSE) != 0)
2770 cb->ccb_error |= (SENSEIO | ABORTIO);
2771 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2773 else switch (cb->ccb_sscp.scp_status)
2779 if (cb->ccb_datalen == 0 ||
2780 cb->ccb_scp.scp_datalen == 0)
2783 if (cb->ccb_scp.scp_cmdlen > 0 &&
2784 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2785 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2788 cb->ccb_error |= PDMAERR;
2793 cb->ccb_error |= (BUSYERR | STATERR);
2797 cb->ccb_error |= (STATERR | ABORTIO);
2802 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2805 cb->ccb_flags |= CCB_SENSE;
2808 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2813 cb->ccb_error |= FATALIO;
2819 if (cb->ccb_flags & CCB_SENSE)
2821 cb->ccb_error |= (SENSEERR | ABORTIO);
2823 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2827 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2829 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2833 /* check a ccb msgout flag */
2834 if (cb->ccb_omsgoutflag != 0)
2836 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2837 SCSI_LOW_MSG_ABORT_QTAG | \
2838 SCSI_LOW_MSG_CLEAR_QTAG | \
2839 SCSI_LOW_MSG_TERMIO)
2841 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2843 cb->ccb_error |= ABORTIO;
2847 /* call OS depend done */
2848 if (cb->osdep != NULL)
2850 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2851 if (rv == EJUSTRETURN)
2854 else if (cb->ccb_error != 0)
2856 if (cb->ccb_rcnt >= slp->sl_max_retry)
2857 cb->ccb_error |= ABORTIO;
2859 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2860 (cb->ccb_error & ABORTIO) == 0)
2864 /* free our target */
2865 #ifdef SCSI_LOW_DEBUG
2866 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2868 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2869 scsi_low_print(slp, NULL);
2871 #endif /* SCSI_LOW_DEBUG */
2873 scsi_low_deactivate_qtag(cb);
2874 scsi_low_dealloc_qtag(cb);
2875 scsi_low_free_ccb(cb);
2877 return SCSI_LOW_DONE_COMPLETE;
2880 #ifdef SCSI_LOW_DEBUG
2881 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2883 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2884 scsi_low_print(slp, NULL);
2886 #endif /* SCSI_LOW_DEBUG */
2889 scsi_low_deactivate_qtag(cb);
2890 scsi_low_ccb_message_retry(cb);
2891 return SCSI_LOW_DONE_RETRY;
2894 /**************************************************************
2896 **************************************************************/
2898 scsi_low_reset_nexus_target(slp, ti, fdone)
2899 struct scsi_low_softc *slp;
2900 struct targ_info *ti;
2903 struct lun_info *li;
2905 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2906 li = LIST_NEXT(li, lun_chain))
2908 scsi_low_reset_nexus_lun(slp, li, fdone);
2909 li->li_state = SCSI_LOW_LUN_SLEEP;
2914 ti->ti_setup_msg = 0;
2915 ti->ti_setup_msg_done = 0;
2917 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2918 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2920 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2921 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2923 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2925 ((*slp->sl_funcs->scsi_low_targ_init)
2926 (slp, ti, SCSI_LOW_INFO_REVOKE));
2928 scsi_low_calcf_target(ti);
2930 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2931 li = LIST_NEXT(li, lun_chain))
2935 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2936 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2938 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2940 ((*slp->sl_funcs->scsi_low_lun_init)
2941 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2943 scsi_low_calcf_lun(li);
2948 scsi_low_reset_nexus(slp, fdone)
2949 struct scsi_low_softc *slp;
2952 struct targ_info *ti;
2953 struct slccb *cb, *topcb;
2955 if ((cb = slp->sl_Qnexus) != NULL)
2957 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2964 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2965 ti = TAILQ_NEXT(ti, ti_chain))
2967 scsi_low_reset_nexus_target(slp, ti, fdone);
2968 scsi_low_bus_release(slp, ti);
2969 scsi_low_init_msgsys(slp, ti);
2974 topcb->ccb_flags |= CCB_STARTQ;
2975 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2979 slp->sl_retry_sel = 0;
2980 slp->sl_flags &= ~HW_PDMASTART;
2985 static char tw_chars[] = "|/-\\";
2986 #define TWIDDLEWAIT 10000
2989 scsi_low_twiddle_wait(void)
2993 cnputc(tw_chars[tw_pos++]);
2994 tw_pos %= (sizeof(tw_chars) - 1);
2995 SCSI_LOW_DELAY(TWIDDLEWAIT);
2999 scsi_low_bus_reset(slp)
3000 struct scsi_low_softc *slp;
3004 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
3006 printf("%s: try to reset scsi bus ", slp->sl_xname);
3007 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
3008 scsi_low_twiddle_wait();
3014 scsi_low_restart(slp, flags, s)
3015 struct scsi_low_softc *slp;
3022 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3024 if ((error = scsi_low_init(slp, flags)) != 0)
3027 scsi_low_start(slp);
3031 /**************************************************************
3032 * disconnect and reselect
3033 **************************************************************/
3034 #define MSGCMD_LUN(msg) (msg & 0x07)
3036 static struct slccb *
3037 scsi_low_establish_ccb(ti, li, tag)
3038 struct targ_info *ti;
3039 struct lun_info *li;
3042 struct scsi_low_softc *slp = ti->ti_sc;
3048 cb = TAILQ_FIRST(&li->li_discq);
3049 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3050 if (cb->ccb_tag == tag)
3055 * establish our ccb nexus
3058 #ifdef SCSI_LOW_DEBUG
3059 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3061 printf("%s: nexus(0x%lx) abort check start\n",
3062 slp->sl_xname, (u_long) cb);
3063 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3064 scsi_low_revoke_ccb(slp, cb, 1);
3068 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3070 if (cb->ccb_omsgoutflag == 0)
3071 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3073 #endif /* SCSI_LOW_DEBUG */
3075 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3076 cb->ccb_flags &= ~CCB_DISCQ;
3077 slp->sl_Qnexus = cb;
3079 slp->sl_scp = cb->ccb_sscp;
3080 slp->sl_error |= cb->ccb_error;
3086 /* inform "ccb nexus established" to the host driver */
3087 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3090 if (cb->ccb_msgoutflag != 0)
3092 scsi_low_ccb_message_exec(slp, cb);
3099 scsi_low_reselected(slp, targ)
3100 struct scsi_low_softc *slp;
3103 struct targ_info *ti;
3108 * Check select vs reselected collision.
3111 if ((cb = slp->sl_selid) != NULL)
3113 scsi_low_arbit_fail(slp, cb);
3114 #ifdef SCSI_LOW_STATICS
3115 scsi_low_statics.nexus_conflict ++;
3116 #endif /* SCSI_LOW_STATICS */
3120 * Check if no current active nexus.
3122 if (slp->sl_Tnexus != NULL)
3129 * Check a valid target id asserted ?
3131 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3133 s = "scsi id illegal";
3138 * Check the target scsi status.
3140 ti = slp->sl_ti[targ];
3141 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3143 s = "phase mismatch";
3151 scsi_low_init_msgsys(slp, ti);
3154 * Establish our target nexus
3156 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3157 slp->sl_Tnexus = ti;
3158 #ifdef SCSI_LOW_STATICS
3159 scsi_low_statics.nexus_reselected ++;
3160 #endif /* SCSI_LOW_STATICS */
3164 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3165 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3166 "reselect: scsi world confused");
3170 /**************************************************************
3171 * cmd out pointer setup
3172 **************************************************************/
3174 scsi_low_cmd(slp, ti)
3175 struct scsi_low_softc *slp;
3176 struct targ_info *ti;
3178 struct slccb *cb = slp->sl_Qnexus;
3180 slp->sl_ph_count ++;
3186 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3187 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3188 slp->sl_scp.scp_datalen = 0;
3189 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3190 slp->sl_error |= FATALIO;
3191 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3192 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3197 #ifdef SCSI_LOW_DEBUG
3198 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3200 scsi_low_test_cmdlnk(slp, cb);
3202 #endif /* SCSI_LOW_DEBUG */
3207 /**************************************************************
3208 * data out pointer setup
3209 **************************************************************/
3211 scsi_low_data(slp, ti, bp, direction)
3212 struct scsi_low_softc *slp;
3213 struct targ_info *ti;
3217 struct slccb *cb = slp->sl_Qnexus;
3219 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3225 slp->sl_error |= (FATALIO | PDMAERR);
3226 slp->sl_scp.scp_datalen = 0;
3227 slp->sl_scp.scp_direction = direction;
3228 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3229 if (ti->ti_ophase != ti->ti_phase)
3234 s = "DATA PHASE: ccb nexus not found";
3236 s = "DATA PHASE: xfer direction mismatch";
3237 SCSI_LOW_INFO(slp, ti, s);
3244 /**************************************************************
3246 **************************************************************/
3247 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3248 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3249 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3250 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3251 #define MSGIN_DATA_LAST 0x30
3253 static int scsi_low_errfunc_synch __P((struct scsi_low_softc *, u_int));
3254 static int scsi_low_errfunc_wide __P((struct scsi_low_softc *, u_int));
3255 static int scsi_low_errfunc_identify __P((struct scsi_low_softc *, u_int));
3256 static int scsi_low_errfunc_qtag __P((struct scsi_low_softc *, u_int));
3258 static int scsi_low_msgfunc_synch __P((struct scsi_low_softc *));
3259 static int scsi_low_msgfunc_wide __P((struct scsi_low_softc *));
3260 static int scsi_low_msgfunc_identify __P((struct scsi_low_softc *));
3261 static int scsi_low_msgfunc_abort __P((struct scsi_low_softc *));
3262 static int scsi_low_msgfunc_qabort __P((struct scsi_low_softc *));
3263 static int scsi_low_msgfunc_qtag __P((struct scsi_low_softc *));
3264 static int scsi_low_msgfunc_reset __P((struct scsi_low_softc *));
3266 struct scsi_low_msgout_data {
3269 int (*md_msgfunc) __P((struct scsi_low_softc *));
3270 int (*md_errfunc) __P((struct scsi_low_softc *, u_int));
3271 #define MSG_RELEASE_ATN 0x0001
3275 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3276 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3277 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3278 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3279 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3280 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3281 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3282 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3283 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3284 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3285 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3286 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3287 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3288 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3289 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3290 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3291 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3294 static int scsi_low_msginfunc_ext __P((struct scsi_low_softc *));
3295 static int scsi_low_synch __P((struct scsi_low_softc *));
3296 static int scsi_low_wide __P((struct scsi_low_softc *));
3297 static int scsi_low_msginfunc_msg_reject __P((struct scsi_low_softc *));
3298 static int scsi_low_msginfunc_rejop __P((struct scsi_low_softc *));
3299 static int scsi_low_msginfunc_rp __P((struct scsi_low_softc *));
3300 static int scsi_low_msginfunc_sdp __P((struct scsi_low_softc *));
3301 static int scsi_low_msginfunc_disc __P((struct scsi_low_softc *));
3302 static int scsi_low_msginfunc_cc __P((struct scsi_low_softc *));
3303 static int scsi_low_msginfunc_lcc __P((struct scsi_low_softc *));
3304 static int scsi_low_msginfunc_parity __P((struct scsi_low_softc *));
3305 static int scsi_low_msginfunc_noop __P((struct scsi_low_softc *));
3306 static int scsi_low_msginfunc_simple_qtag __P((struct scsi_low_softc *));
3307 static int scsi_low_msginfunc_i_wide_residue __P((struct scsi_low_softc *));
3309 struct scsi_low_msgin_data {
3311 int (*md_msgfunc) __P((struct scsi_low_softc *));
3314 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3315 /* 0 */ {1, scsi_low_msginfunc_cc},
3316 /* 1 */ {2, scsi_low_msginfunc_ext},
3317 /* 2 */ {1, scsi_low_msginfunc_sdp},
3318 /* 3 */ {1, scsi_low_msginfunc_rp},
3319 /* 4 */ {1, scsi_low_msginfunc_disc},
3320 /* 5 */ {1, scsi_low_msginfunc_rejop},
3321 /* 6 */ {1, scsi_low_msginfunc_rejop},
3322 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
3323 /* 8 */ {1, scsi_low_msginfunc_noop},
3324 /* 9 */ {1, scsi_low_msginfunc_parity},
3325 /* a */ {1, scsi_low_msginfunc_lcc},
3326 /* b */ {1, scsi_low_msginfunc_lcc},
3327 /* c */ {1, scsi_low_msginfunc_rejop},
3328 /* d */ {2, scsi_low_msginfunc_rejop},
3329 /* e */ {1, scsi_low_msginfunc_rejop},
3330 /* f */ {1, scsi_low_msginfunc_rejop},
3331 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
3332 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
3333 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
3334 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
3335 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
3336 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
3337 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
3338 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
3339 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
3340 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
3341 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
3342 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
3343 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
3344 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
3345 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
3346 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
3347 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3348 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
3349 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
3350 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3351 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
3352 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
3353 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
3354 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
3355 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
3356 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
3357 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
3358 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
3359 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
3360 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
3361 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
3362 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
3363 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3366 /**************************************************************
3368 **************************************************************/
3370 scsi_low_msgfunc_synch(slp)
3371 struct scsi_low_softc *slp;
3373 struct targ_info *ti = slp->sl_Tnexus;
3374 int ptr = ti->ti_msgoutlen;
3376 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3377 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3378 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3379 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3380 return MSG_EXTEND_SYNCHLEN + 2;
3384 scsi_low_msgfunc_wide(slp)
3385 struct scsi_low_softc *slp;
3387 struct targ_info *ti = slp->sl_Tnexus;
3388 int ptr = ti->ti_msgoutlen;
3390 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3391 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3392 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3393 return MSG_EXTEND_WIDELEN + 2;
3397 scsi_low_msgfunc_identify(slp)
3398 struct scsi_low_softc *slp;
3400 struct targ_info *ti = slp->sl_Tnexus;
3401 struct lun_info *li = slp->sl_Lnexus;
3402 struct slccb *cb = slp->sl_Qnexus;
3403 int ptr = ti->ti_msgoutlen;
3409 slp->sl_error |= FATALIO;
3410 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3411 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3415 if (scsi_low_is_disconnect_ok(cb) != 0)
3416 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3420 if (ti->ti_phase == PH_MSGOUT)
3422 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3423 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3425 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3429 ti->ti_msgoutstr[ptr + 0] = msg;
3434 scsi_low_msgfunc_abort(slp)
3435 struct scsi_low_softc *slp;
3438 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3443 scsi_low_msgfunc_qabort(slp)
3444 struct scsi_low_softc *slp;
3447 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3452 scsi_low_msgfunc_reset(slp)
3453 struct scsi_low_softc *slp;
3456 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3461 scsi_low_msgfunc_qtag(slp)
3462 struct scsi_low_softc *slp;
3464 struct targ_info *ti = slp->sl_Tnexus;
3465 struct slccb *cb = slp->sl_Qnexus;
3466 int ptr = ti->ti_msgoutlen;
3468 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3470 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3475 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3476 if (ti->ti_phase == PH_MSGOUT)
3478 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3485 * The following functions are called when targets give unexpected
3486 * responces in msgin (after msgout).
3489 scsi_low_errfunc_identify(slp, msgflags)
3490 struct scsi_low_softc *slp;
3494 if (slp->sl_Lnexus != NULL)
3496 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3497 scsi_low_calcf_lun(slp->sl_Lnexus);
3503 scsi_low_errfunc_synch(slp, msgflags)
3504 struct scsi_low_softc *slp;
3507 struct targ_info *ti = slp->sl_Tnexus;
3509 MSGIN_PERIOD(ti) = 0;
3510 MSGIN_OFFSET(ti) = 0;
3511 scsi_low_synch(slp);
3516 scsi_low_errfunc_wide(slp, msgflags)
3517 struct scsi_low_softc *slp;
3520 struct targ_info *ti = slp->sl_Tnexus;
3522 MSGIN_WIDTHP(ti) = 0;
3528 scsi_low_errfunc_qtag(slp, msgflags)
3529 struct scsi_low_softc *slp;
3533 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3535 if (slp->sl_Qnexus != NULL)
3537 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3539 if (slp->sl_Lnexus != NULL)
3541 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3542 scsi_low_calcf_lun(slp->sl_Lnexus);
3544 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3551 scsi_low_msgout(slp, ti, fl)
3552 struct scsi_low_softc *slp;
3553 struct targ_info *ti;
3556 struct scsi_low_msgout_data *mdp;
3559 #ifdef SCSI_LOW_DIAGNOSTIC
3560 if (ti != slp->sl_Tnexus)
3562 scsi_low_print(slp, NULL);
3563 panic("scsi_low_msgout: Target nexus inconsistent");
3565 #endif /* SCSI_LOW_DIAGNOSTIC */
3567 slp->sl_ph_count ++;
3568 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3570 printf("%s: too many phase changes\n", slp->sl_xname);
3571 slp->sl_error |= FATALIO;
3572 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3576 * Scsi phase changes.
3577 * Previously msgs asserted are accepted by our target or
3578 * processed by scsi_low_msgin.
3579 * Thus clear all saved informations.
3581 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3583 ti->ti_omsgflags = 0;
3584 ti->ti_emsgflags = 0;
3586 else if (slp->sl_atten == 0)
3589 * We did not assert attention, however still our target required
3590 * msgs. Resend previous msgs.
3592 ti->ti_msgflags |= ti->ti_omsgflags;
3593 ti->ti_omsgflags = 0;
3594 #ifdef SCSI_LOW_DIAGNOSTIC
3595 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3596 #endif /* SCSI_LOW_DIAGNOSTIC */
3600 * We have no msgs. send MSG_NOOP (OK?)
3602 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3603 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3608 ti->ti_msgoutlen = 0;
3609 slp->sl_clear_atten = 0;
3610 mdp = &scsi_low_msgout_data[0];
3611 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3613 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3615 ti->ti_omsgflags |= mdp->md_flags;
3616 ti->ti_msgflags &= ~mdp->md_flags;
3617 ti->ti_emsgflags = mdp->md_flags;
3619 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3620 if (mdp->md_msgfunc != NULL)
3621 len = (*mdp->md_msgfunc) (slp);
3625 #ifdef SCSI_LOW_DIAGNOSTIC
3626 scsi_low_msg_log_write(&ti->ti_log_msgout,
3627 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3628 #endif /* SCSI_LOW_DIAGNOSTIC */
3630 ti->ti_msgoutlen += len;
3631 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3633 slp->sl_clear_atten = 1;
3637 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3638 ti->ti_msgflags == 0)
3641 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3646 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3647 slp->sl_clear_atten = 1;
3649 return ti->ti_msgoutlen;
3652 /**************************************************************
3654 **************************************************************/
3656 scsi_low_msginfunc_noop(slp)
3657 struct scsi_low_softc *slp;
3664 scsi_low_msginfunc_rejop(slp)
3665 struct scsi_low_softc *slp;
3667 struct targ_info *ti = slp->sl_Tnexus;
3668 u_int8_t msg = ti->ti_msgin[0];
3670 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3671 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3676 scsi_low_msginfunc_cc(slp)
3677 struct scsi_low_softc *slp;
3679 struct lun_info *li;
3681 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3683 /* validate status */
3684 if (slp->sl_Qnexus == NULL)
3687 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3688 li = slp->sl_Lnexus;
3689 switch (slp->sl_scp.scp_status)
3692 li->li_maxnqio = li->li_maxnexus;
3697 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3698 scsi_low_reset_nexus_lun(slp, li, 0);
3706 if (li->li_maxnexus >= li->li_nqio)
3707 li->li_maxnexus = li->li_nqio - 1;
3708 li->li_maxnqio = li->li_maxnexus;
3713 slp->sl_error |= MSGERR;
3723 scsi_low_msginfunc_lcc(slp)
3724 struct scsi_low_softc *slp;
3726 struct targ_info *ti;
3727 struct lun_info *li;
3728 struct slccb *ncb, *cb;
3730 ti = slp->sl_Tnexus;
3731 li = slp->sl_Lnexus;
3732 if ((cb = slp->sl_Qnexus) == NULL)
3735 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3736 switch (slp->sl_scp.scp_status)
3740 li->li_maxnqio = li->li_maxnexus;
3744 slp->sl_error |= MSGERR;
3748 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3751 cb->ccb_error |= slp->sl_error;
3752 if (cb->ccb_error != 0)
3755 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3756 ncb = TAILQ_NEXT(ncb, ccb_chain))
3759 goto cmd_link_start;
3764 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3765 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3769 ncb->ccb_flags &= ~CCB_STARTQ;
3770 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3772 scsi_low_dealloc_qtag(ncb);
3773 ncb->ccb_tag = cb->ccb_tag;
3774 ncb->ccb_otag = cb->ccb_otag;
3775 cb->ccb_tag = SCSI_LOW_UNKTAG;
3776 cb->ccb_otag = SCSI_LOW_UNKTAG;
3777 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3778 panic("%s: linked ccb retried\n", slp->sl_xname);
3780 slp->sl_Qnexus = ncb;
3781 slp->sl_ph_count = 0;
3784 ncb->ccb_datalen = -1;
3785 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3786 ncb->ccb_flags &= ~CCB_INTERNAL;
3788 scsi_low_init_msgsys(slp, ti);
3790 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3792 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3793 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3794 ncb->ccb_tc = ncb->ccb_tcmax;
3796 /* setup saved scsi data pointer */
3797 ncb->ccb_sscp = ncb->ccb_scp;
3798 slp->sl_scp = ncb->ccb_sscp;
3799 slp->sl_error = ncb->ccb_error;
3801 #ifdef SCSI_LOW_DIAGNOSTIC
3802 scsi_low_msg_log_init(&ti->ti_log_msgin);
3803 scsi_low_msg_log_init(&ti->ti_log_msgout);
3804 #endif /* SCSI_LOW_DIAGNOSTIC */
3809 scsi_low_msginfunc_disc(slp)
3810 struct scsi_low_softc *slp;
3813 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3818 scsi_low_msginfunc_sdp(slp)
3819 struct scsi_low_softc *slp;
3821 struct slccb *cb = slp->sl_Qnexus;
3825 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3826 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3829 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3834 scsi_low_msginfunc_rp(slp)
3835 struct scsi_low_softc *slp;
3838 if (slp->sl_Qnexus != NULL)
3839 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3841 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3847 struct scsi_low_softc *slp;
3849 struct targ_info *ti = slp->sl_Tnexus;
3850 u_int period = 0, offset = 0, speed;
3854 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3855 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3856 MSGIN_OFFSET(ti) == 0)
3858 if ((offset = MSGIN_OFFSET(ti)) != 0)
3859 period = MSGIN_PERIOD(ti);
3860 s = offset ? "synchronous" : "async";
3865 * Target seems to be brain damaged.
3866 * Force async transfer.
3868 ti->ti_maxsynch.period = 0;
3869 ti->ti_maxsynch.offset = 0;
3870 printf("%s: target brain damaged. async transfer\n",
3875 ti->ti_maxsynch.period = period;
3876 ti->ti_maxsynch.offset = offset;
3878 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3882 * Current period and offset are not acceptable
3884 * The adapter changes max synch and max offset.
3886 printf("%s: synch neg failed. retry synch msg neg ...\n",
3891 ti->ti_osynch = ti->ti_maxsynch;
3894 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3898 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3900 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3901 struct slccb *cb = slp->sl_Qnexus;
3903 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3905 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3907 printf("%s(%d:*): <%s> offset %d period %dns ",
3908 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3912 speed = 1000 * 10 / (period * 4);
3913 printf("%d.%d M/s", speed / 10, speed % 10);
3922 struct scsi_low_softc *slp;
3924 struct targ_info *ti = slp->sl_Tnexus;
3927 ti->ti_width = MSGIN_WIDTHP(ti);
3928 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3932 * Current width is not acceptable for our adapter.
3933 * The adapter changes max width.
3935 printf("%s: wide neg failed. retry wide msg neg ...\n",
3940 ti->ti_owidth = ti->ti_width;
3941 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3943 ti->ti_setup_msg_done |=
3944 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3948 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3950 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3951 struct slccb *cb = slp->sl_Qnexus;
3953 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3955 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3957 printf("%s(%d:*): transfer width %d bits\n",
3958 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3964 scsi_low_msginfunc_simple_qtag(slp)
3965 struct scsi_low_softc *slp;
3967 struct targ_info *ti = slp->sl_Tnexus;
3968 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3970 if (slp->sl_Qnexus != NULL)
3972 if (slp->sl_Qnexus->ccb_tag != etag)
3974 slp->sl_error |= FATALIO;
3975 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3976 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3979 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3981 #ifdef SCSI_LOW_DEBUG
3982 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3984 #endif /* SCSI_LOW_DEBUG */
3986 slp->sl_error |= FATALIO;
3987 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3988 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3994 scsi_low_msginfunc_i_wide_residue(slp)
3995 struct scsi_low_softc *slp;
3997 struct targ_info *ti = slp->sl_Tnexus;
3998 struct slccb *cb = slp->sl_Qnexus;
3999 int res = (int) ti->ti_msgin[1];
4001 if (cb == NULL || res <= 0 ||
4002 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
4003 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
4006 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
4009 slp->sl_scp.scp_datalen += res;
4010 slp->sl_scp.scp_data -= res;
4011 scsi_low_data_finish(slp);
4016 scsi_low_msginfunc_ext(slp)
4017 struct scsi_low_softc *slp;
4019 struct slccb *cb = slp->sl_Qnexus;
4020 struct lun_info *li = slp->sl_Lnexus;
4021 struct targ_info *ti = slp->sl_Tnexus;
4025 if (ti->ti_msginptr == 2)
4027 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4031 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4033 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4037 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4038 count = (int) htonl((long) (*ptr));
4039 if(slp->sl_scp.scp_datalen - count < 0 ||
4040 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4043 slp->sl_scp.scp_datalen -= count;
4044 slp->sl_scp.scp_data += count;
4047 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4051 retry = scsi_low_synch(slp);
4052 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4053 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4055 #ifdef SCSI_LOW_DEBUG
4056 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4058 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4060 #endif /* SCSI_LOW_DEBUG */
4063 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4067 retry = scsi_low_wide(slp);
4068 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4069 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4077 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4082 scsi_low_msginfunc_parity(slp)
4083 struct scsi_low_softc *slp;
4085 struct targ_info *ti = slp->sl_Tnexus;
4087 /* only I -> T, invalid! */
4088 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4093 scsi_low_msginfunc_msg_reject(slp)
4094 struct scsi_low_softc *slp;
4096 struct targ_info *ti = slp->sl_Tnexus;
4097 struct scsi_low_msgout_data *mdp;
4100 if (ti->ti_emsgflags != 0)
4102 printf("%s: msg flags [0x%x] rejected\n",
4103 slp->sl_xname, ti->ti_emsgflags);
4104 msgflags = SCSI_LOW_MSG_REJECT;
4105 mdp = &scsi_low_msgout_data[0];
4106 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4108 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4110 ti->ti_emsgflags &= ~mdp->md_flags;
4111 if (mdp->md_errfunc != NULL)
4112 (*mdp->md_errfunc) (slp, msgflags);
4120 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4121 slp->sl_error |= MSGERR;
4127 scsi_low_msgin(slp, ti, c)
4128 struct scsi_low_softc *slp;
4129 struct targ_info *ti;
4132 struct scsi_low_msgin_data *sdp;
4133 struct lun_info *li;
4136 #ifdef SCSI_LOW_DIAGNOSTIC
4137 if (ti != slp->sl_Tnexus)
4139 scsi_low_print(slp, NULL);
4140 panic("scsi_low_msgin: Target nexus inconsistent");
4142 #endif /* SCSI_LOW_DIAGNOSTIC */
4145 * Phase changes, clear the pointer.
4147 if (ti->ti_ophase != ti->ti_phase)
4150 ti->ti_msgin_parity_error = 0;
4152 slp->sl_ph_count ++;
4153 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4155 printf("%s: too many phase changes\n", slp->sl_xname);
4156 slp->sl_error |= FATALIO;
4157 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4162 * Store a current messages byte into buffer and
4163 * wait for the completion of the current msg.
4165 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4166 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4168 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4169 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4173 * Check parity errors.
4175 if ((c & SCSI_LOW_DATA_PE) != 0)
4177 ti->ti_msgin_parity_error ++;
4178 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4182 if (ti->ti_msgin_parity_error != 0)
4186 * Calculate messages length.
4188 msg = ti->ti_msgin[0];
4189 if (msg < MSGIN_DATA_LAST)
4190 sdp = &scsi_low_msgin_data[msg];
4192 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4194 if (ti->ti_msginlen == 0)
4196 ti->ti_msginlen = sdp->md_len;
4202 if (ti->ti_msginptr < ti->ti_msginlen)
4208 if ((msg & MSG_IDENTIFY) == 0)
4210 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4215 li = slp->sl_Lnexus;
4218 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4221 slp->sl_Lnexus = li;
4222 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4226 if (MSGCMD_LUN(msg) != li->li_lun)
4230 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4232 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4234 #ifdef SCSI_LOW_DEBUG
4235 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4239 #endif /* SCSI_LOW_DEBUG */
4247 * Msg process completed, reset msgin pointer and assert ATN if desired.
4250 slp->sl_error |= FATALIO;
4251 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4252 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4255 if (ti->ti_msginptr < ti->ti_msginlen)
4258 #ifdef SCSI_LOW_DIAGNOSTIC
4259 scsi_low_msg_log_write(&ti->ti_log_msgin,
4260 &ti->ti_msgin[0], ti->ti_msginlen);
4261 #endif /* SCSI_LOW_DIAGNOSTIC */
4267 /**********************************************************
4269 **********************************************************/
4271 scsi_low_disconnected(slp, ti)
4272 struct scsi_low_softc *slp;
4273 struct targ_info *ti;
4275 struct slccb *cb = slp->sl_Qnexus;
4277 /* check phase completion */
4278 switch (slp->sl_msgphase)
4281 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4282 scsi_low_msginfunc_cc(slp);
4283 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4287 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4288 scsi_low_msginfunc_cc(slp);
4289 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4293 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4294 scsi_low_msginfunc_cc(slp);
4300 struct lun_info *li;
4303 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4304 cb->ccb_flags |= CCB_DISCQ;
4305 cb->ccb_error |= slp->sl_error;
4311 #ifdef SCSI_LOW_STATICS
4312 scsi_low_statics.nexus_disconnected ++;
4313 #endif /* SCSI_LOW_STATICS */
4315 #ifdef SCSI_LOW_DEBUG
4316 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4318 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4319 scsi_low_print(slp, NULL);
4321 #endif /* SCSI_LOW_DEBUG */
4325 slp->sl_error |= FATALIO;
4326 if (ti->ti_phase == PH_SELSTART)
4327 slp->sl_error |= SELTIMEOUTIO;
4329 slp->sl_error |= UBFERR;
4338 #ifdef SCSI_LOW_DEBUG
4339 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4341 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4342 (cb->ccb_msgoutflag != 0 ||
4343 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4345 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4348 #endif /* SCSI_LOW_DEBUG */
4350 cb->ccb_error |= slp->sl_error;
4351 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4353 cb->ccb_flags |= CCB_STARTQ;
4354 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4359 scsi_low_bus_release(slp, ti);
4360 scsi_low_start(slp);
4364 /**********************************************************
4366 **********************************************************/
4368 scsi_low_alloc_qtag(cb)
4371 struct lun_info *li = cb->li;
4372 scsi_low_tag_t etag;
4374 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4377 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4378 etag = ffs(li->li_qtagbits);
4382 li->li_qtagbits &= ~(1 << (etag - 1));
4383 cb->ccb_otag = etag;
4386 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4387 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4388 if (li->li_qtagarray[li->li_qd] == 0)
4391 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4392 if (li->li_qtagarray[li->li_qd] == 0)
4398 li->li_qtagarray[li->li_qd] ++;
4399 cb->ccb_otag = (li->li_qd ++);
4401 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4405 scsi_low_dealloc_qtag(cb)
4408 struct lun_info *li = cb->li;
4409 scsi_low_tag_t etag;
4411 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4414 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4415 etag = cb->ccb_otag - 1;
4416 #ifdef SCSI_LOW_DIAGNOSTIC
4417 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4418 panic("scsi_low_dealloc_tag: illegal tag");
4419 #endif /* SCSI_LOW_DIAGNOSTIC */
4420 li->li_qtagbits |= (1 << etag);
4422 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4423 etag = cb->ccb_otag;
4424 #ifdef SCSI_LOW_DIAGNOSTIC
4425 if (etag >= SCSI_LOW_MAXNEXUS)
4426 panic("scsi_low_dealloc_tag: illegal tag");
4427 #endif /* SCSI_LOW_DIAGNOSTIC */
4428 li->li_qtagarray[etag] --;
4429 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4431 cb->ccb_otag = SCSI_LOW_UNKTAG;
4436 scsi_low_revoke_ccb(slp, cb, fdone)
4437 struct scsi_low_softc *slp;
4441 struct targ_info *ti = cb->ti;
4442 struct lun_info *li = cb->li;
4444 #ifdef SCSI_LOW_DIAGNOSTIC
4445 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4446 (CCB_STARTQ | CCB_DISCQ))
4448 panic("%s: ccb in both queue\n", slp->sl_xname);
4450 #endif /* SCSI_LOW_DIAGNOSTIC */
4452 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4454 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4457 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4459 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4465 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4466 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4469 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4470 (cb->ccb_flags & CCB_NORETRY) != 0))
4472 cb->ccb_error |= FATALIO;
4473 cb->ccb_flags &= ~CCB_AUTOSENSE;
4474 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4475 panic("%s: done ccb retried\n", slp->sl_xname);
4480 cb->ccb_error |= PENDINGIO;
4481 scsi_low_deactivate_qtag(cb);
4482 scsi_low_ccb_message_retry(cb);
4483 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4489 scsi_low_reset_nexus_lun(slp, li, fdone)
4490 struct scsi_low_softc *slp;
4491 struct lun_info *li;
4494 struct slccb *cb, *ncb, *ecb;
4500 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4502 ncb = TAILQ_NEXT(cb, ccb_chain);
4503 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4507 * presumely keep ordering of io
4509 cb->ccb_flags |= CCB_STARTQ;
4512 TAILQ_INSERT_HEAD(&slp->sl_start,\
4517 TAILQ_INSERT_AFTER(&slp->sl_start,\
4518 ecb, cb, ccb_chain);
4525 /**************************************************************
4527 **************************************************************/
4529 scsi_low_calcf_lun(li)
4530 struct lun_info *li;
4532 struct targ_info *ti = li->li_ti;
4533 struct scsi_low_softc *slp = ti->ti_sc;
4534 u_int cfgflags, diskflags;
4536 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4537 cfgflags = li->li_cfgflags;
4541 diskflags = li->li_diskflags & li->li_quirks;
4544 li->li_flags &= ~SCSI_LOW_DISC;
4545 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4546 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4547 (cfgflags & SCSI_LOW_DISC) != 0)
4548 li->li_flags |= SCSI_LOW_DISC;
4551 li->li_flags |= SCSI_LOW_NOPARITY;
4552 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4553 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4554 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4555 li->li_flags &= ~SCSI_LOW_NOPARITY;
4558 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4559 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4560 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4562 li->li_flags |= SCSI_LOW_QTAG;
4563 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4564 li->li_maxnqio = li->li_maxnexus;
4568 li->li_flags &= ~SCSI_LOW_QTAG;
4569 li->li_maxnexus = 0;
4570 li->li_maxnqio = li->li_maxnexus;
4574 li->li_flags &= ~SCSI_LOW_LINK;
4575 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4576 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4577 li->li_flags |= SCSI_LOW_LINK;
4579 /* compatible flags */
4580 li->li_flags &= ~SCSI_LOW_SYNC;
4581 if (ti->ti_maxsynch.offset > 0)
4582 li->li_flags |= SCSI_LOW_SYNC;
4584 #ifdef SCSI_LOW_DEBUG
4585 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4587 scsi_low_calcf_show(li);
4589 #endif /* SCSI_LOW_DEBUG */
4593 scsi_low_calcf_target(ti)
4594 struct targ_info *ti;
4596 struct scsi_low_softc *slp = ti->ti_sc;
4597 u_int offset, period, diskflags;
4599 diskflags = ti->ti_diskflags & ti->ti_quirks;
4602 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4603 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4605 offset = ti->ti_maxsynch.offset;
4606 period = ti->ti_maxsynch.period;
4607 if (offset == 0 || period == 0)
4608 offset = period = 0;
4612 offset = period = 0;
4615 ti->ti_maxsynch.offset = offset;
4616 ti->ti_maxsynch.period = period;
4619 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4620 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4621 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4623 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4624 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4625 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4627 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4629 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4630 ti->ti_maxsynch.period != ti->ti_osynch.period)
4631 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4632 if (ti->ti_width != ti->ti_owidth)
4633 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4635 ti->ti_osynch = ti->ti_maxsynch;
4636 ti->ti_owidth = ti->ti_width;
4639 #ifdef SCSI_LOW_DEBUG
4640 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4642 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4643 slp->sl_xname, ti->ti_id,
4644 ti->ti_maxsynch.period * 4,
4645 ti->ti_maxsynch.offset,
4648 #endif /* SCSI_LOW_DEBUG */
4652 scsi_low_calcf_show(li)
4653 struct lun_info *li;
4655 struct targ_info *ti = li->li_ti;
4656 struct scsi_low_softc *slp = ti->ti_sc;
4658 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4659 slp->sl_xname, ti->ti_id, li->li_lun,
4660 ti->ti_maxsynch.period * 4,
4661 ti->ti_maxsynch.offset,
4663 li->li_flags, SCSI_LOW_BITS);
4666 #ifdef SCSI_LOW_START_UP_CHECK
4667 /**************************************************************
4668 * scsi world start up
4669 **************************************************************/
4670 static int scsi_low_poll __P((struct scsi_low_softc *, struct slccb *));
4673 scsi_low_start_up(slp)
4674 struct scsi_low_softc *slp;
4676 struct targ_info *ti;
4677 struct lun_info *li;
4681 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4683 for (target = 0; target < slp->sl_ntargs; target ++)
4685 if (target == slp->sl_hostid)
4687 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4689 printf("%s: scsi_low: target %d (host card)\n",
4690 slp->sl_xname, target);
4695 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4697 printf("%s: scsi_low: target %d lun ",
4698 slp->sl_xname, target);
4701 ti = slp->sl_ti[target];
4702 for (lun = 0; lun < slp->sl_nluns; lun ++)
4704 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4710 li = scsi_low_alloc_li(ti, lun, 1);
4712 scsi_low_enqueue(slp, ti, li, cb,
4713 CCB_AUTOSENSE | CCB_POLLED, 0);
4715 scsi_low_poll(slp, cb);
4717 if (li->li_state != SCSI_LOW_LUN_OK)
4720 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4726 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4735 scsi_low_poll(slp, cb)
4736 struct scsi_low_softc *slp;
4742 while (slp->sl_nio > 0)
4744 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4746 (*slp->sl_funcs->scsi_low_poll) (slp);
4747 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4751 scsi_low_timeout_check(slp);
4756 #endif /* SCSI_LOW_START_UP_CHECK */
4758 /**********************************************************
4760 **********************************************************/
4761 #ifdef SCSI_LOW_DEBUG
4763 scsi_low_test_abort(slp, ti, li)
4764 struct scsi_low_softc *slp;
4765 struct targ_info *ti;
4766 struct lun_info *li;
4770 if (li->li_disc > 1)
4772 acb = TAILQ_FIRST(&li->li_discq);
4773 if (scsi_low_abort_ccb(slp, acb) == 0)
4775 printf("%s: aborting ccb(0x%lx) start\n",
4776 slp->sl_xname, (u_long) acb);
4782 scsi_low_test_atten(slp, ti, msg)
4783 struct scsi_low_softc *slp;
4784 struct targ_info *ti;
4788 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4789 scsi_low_assert_msg(slp, ti, msg, 0);
4791 printf("%s: atten check OK\n", slp->sl_xname);
4795 scsi_low_test_cmdlnk(slp, cb)
4796 struct scsi_low_softc *slp;
4799 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4801 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4804 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4805 slp->sl_scp.scp_cmdlen);
4806 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4807 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4809 #endif /* SCSI_LOW_DEBUG */
4812 scsi_low_info(slp, ti, s)
4813 struct scsi_low_softc *slp;
4814 struct targ_info *ti;
4819 slp = LIST_FIRST(&sl_tab);
4823 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4826 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4827 ti = TAILQ_NEXT(ti, ti_chain))
4829 scsi_low_print(slp, ti);
4834 scsi_low_print(slp, ti);
4838 static u_char *phase[] =
4840 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4841 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4845 scsi_low_print(slp, ti)
4846 struct scsi_low_softc *slp;
4847 struct targ_info *ti;
4849 struct lun_info *li;
4853 if (ti == NULL || ti == slp->sl_Tnexus)
4855 ti = slp->sl_Tnexus;
4856 li = slp->sl_Lnexus;
4857 cb = slp->sl_Qnexus;
4861 li = LIST_FIRST(&ti->ti_litab);
4862 cb = TAILQ_FIRST(&li->li_discq);
4866 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4867 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4873 u_int flags = 0, maxnqio = 0, nqio = 0;
4879 flags = li->li_flags;
4880 maxnqio = li->li_maxnqio;
4884 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4886 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4887 phase[(int) ti->ti_phase], ti->ti_disc,
4892 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4893 (u_int) cb->ccb_scp.scp_cmd[0],
4894 cb->ccb_scp.scp_cmdlen,
4896 cb->ccb_scp.scp_datalen,
4897 (u_int) cb->ccb_sscp.scp_status,
4898 cb->ccb_error, SCSI_LOW_ERRORBITS);
4901 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4902 (u_int) (ti->ti_msginptr),
4903 (u_int) (ti->ti_msgin[0]),
4904 (u_int) (ti->ti_msgin[1]),
4905 (u_int) (ti->ti_msgin[2]),
4906 (u_int) (ti->ti_msgin[3]),
4907 (u_int) (ti->ti_msgin[4]),
4910 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4911 (u_int) ti->ti_msgflags,
4912 (u_int) (ti->ti_msgoutstr[0]),
4913 (u_int) (ti->ti_msgoutstr[1]),
4914 (u_int) (ti->ti_msgoutstr[2]),
4915 (u_int) (ti->ti_msgoutstr[3]),
4916 (u_int) (ti->ti_msgoutstr[4]),
4918 flags, SCSI_LOW_BITS);
4920 #ifdef SCSI_LOW_DIAGNOSTIC
4921 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4922 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4923 #endif /* SCSI_LOW_DIAGNOSTIC */
4927 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4928 (u_long) sp->scp_data,
4930 (u_int) sp->scp_status,
4931 slp->sl_error, SCSI_LOW_ERRORBITS);