1 /* $NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ */
7 #define SCSI_LOW_STATICS
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define SCSI_LOW_START_UP_CHECK
12 /* #define SCSI_LOW_INFO_DETAIL */
14 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
15 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
18 #define SCSI_LOW_TARGET_OPEN
19 #endif /* __NetBSD__ */
22 #define SCSI_LOW_FLAGS_QUIRKS_OK
23 #endif /* __FreeBSD__ */
26 * [NetBSD for NEC PC-98 series]
27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
28 * NetBSD/pc98 porting staff. All rights reserved.
29 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
30 * Naofumi HONDA. All rights reserved.
32 * [Ported for FreeBSD CAM]
33 * Copyright (c) 2000, 2001
34 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
35 * All rights reserved.
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. The name of the author may not be used to endorse or promote products
46 * derived from this software without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 * POSSIBILITY OF SUCH DAMAGE.
61 /* <On the nexus establishment>
62 * When our host is reselected,
63 * nexus establish processes are little complicated.
64 * Normal steps are followings:
65 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
66 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
67 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
76 #if __FreeBSD_version >= 500001
79 #include <machine/clock.h>
81 #endif /* __FreeBSD__ */
84 #include <sys/queue.h>
85 #include <sys/malloc.h>
86 #include <sys/errno.h>
89 #include <sys/device.h>
92 #include <machine/bus.h>
93 #include <machine/intr.h>
94 #include <machine/dvcfg.h>
98 #include <dev/scsipi/scsipi_all.h>
99 #include <dev/scsipi/scsipiconf.h>
100 #include <dev/scsipi/scsipi_disk.h>
101 #include <dev/scsipi/scsi_all.h>
102 #include <dev/scsipi/scsiconf.h>
103 #include <sys/scsiio.h>
105 #include <i386/Cbus/dev/scsi_low.h>
106 #endif /* __NetBSD__ */
110 #include <cam/cam_ccb.h>
111 #include <cam/cam_sim.h>
112 #include <cam/cam_debug.h>
113 #include <cam/cam_periph.h>
114 #include <cam/cam_xpt_periph.h>
116 #include <cam/scsi/scsi_all.h>
117 #include <cam/scsi/scsi_message.h>
119 #include <cam/scsi/scsi_low.h>
121 #include <sys/cons.h>
122 #endif /* __FreeBSD__ */
124 /**************************************************************
126 **************************************************************/
127 #define SCSI_LOW_POLL_HZ 1000
129 /* functions return values */
130 #define SCSI_LOW_START_NO_QTAG 0
131 #define SCSI_LOW_START_QTAG 1
133 #define SCSI_LOW_DONE_COMPLETE 0
134 #define SCSI_LOW_DONE_RETRY 1
136 /* internal disk flags */
137 #define SCSI_LOW_DISK_DISC 0x00000001
138 #define SCSI_LOW_DISK_QTAG 0x00000002
139 #define SCSI_LOW_DISK_LINK 0x00000004
140 #define SCSI_LOW_DISK_PARITY 0x00000008
141 #define SCSI_LOW_DISK_SYNC 0x00010000
142 #define SCSI_LOW_DISK_WIDE_16 0x00020000
143 #define SCSI_LOW_DISK_WIDE_32 0x00040000
144 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
145 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
146 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
148 MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
150 /**************************************************************
152 **************************************************************/
153 /* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *);
154 static void scsi_low_engage(void *);
155 static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
156 static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
157 static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
158 static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
159 static void scsi_low_twiddle_wait(void);
160 static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
161 static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
162 static void scsi_low_calcf_lun(struct lun_info *);
163 static void scsi_low_calcf_target(struct targ_info *);
164 static void scsi_low_calcf_show(struct lun_info *);
165 static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
166 static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
167 static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
168 static int scsi_low_init(struct scsi_low_softc *, u_int);
169 static void scsi_low_start(struct scsi_low_softc *);
170 static void scsi_low_free_ti(struct scsi_low_softc *);
172 static int scsi_low_alloc_qtag(struct slccb *);
173 static int scsi_low_dealloc_qtag(struct slccb *);
174 static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
175 static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
176 static void scsi_low_unit_ready_cmd(struct slccb *);
177 static void scsi_low_timeout(void *);
178 static int scsi_low_timeout_check(struct scsi_low_softc *);
179 #ifdef SCSI_LOW_START_UP_CHECK
180 static int scsi_low_start_up(struct scsi_low_softc *);
181 #endif /* SCSI_LOW_START_UP_CHECK */
182 static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
183 static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
185 int scsi_low_version_major = 2;
186 int scsi_low_version_minor = 17;
188 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
190 /**************************************************************
191 * Debug, Run test and Statics
192 **************************************************************/
193 #ifdef SCSI_LOW_INFO_DETAIL
194 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
195 #else /* !SCSI_LOW_INFO_DETAIL */
196 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
197 #endif /* !SCSI_LOW_INFO_DETAIL */
199 #ifdef SCSI_LOW_STATICS
200 static struct scsi_low_statics {
203 int nexus_disconnected;
204 int nexus_reselected;
207 #endif /* SCSI_LOW_STATICS */
209 #ifdef SCSI_LOW_DEBUG
210 #define SCSI_LOW_DEBUG_DONE 0x00001
211 #define SCSI_LOW_DEBUG_DISC 0x00002
212 #define SCSI_LOW_DEBUG_SENSE 0x00004
213 #define SCSI_LOW_DEBUG_CALCF 0x00008
214 #define SCSI_LOW_DEBUG_ACTION 0x10000
215 int scsi_low_debug = 0;
217 #define SCSI_LOW_MAX_ATTEN_CHECK 32
218 #define SCSI_LOW_ATTEN_CHECK 0x0001
219 #define SCSI_LOW_CMDLNK_CHECK 0x0002
220 #define SCSI_LOW_ABORT_CHECK 0x0004
221 #define SCSI_LOW_NEXUS_CHECK 0x0008
222 int scsi_low_test = 0;
223 int scsi_low_test_id = 0;
225 static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
226 static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
227 static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int);
228 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
229 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
230 #define SCSI_LOW_DEBUG_GO(fl, id) \
231 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
232 #endif /* SCSI_LOW_DEBUG */
234 /**************************************************************
236 **************************************************************/
237 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
238 GENERIC_CCB(scsi_low, slccb, ccb_chain)
240 /**************************************************************
242 **************************************************************/
243 #define SCSI_LOW_INLINE static __inline
244 SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
245 SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
246 SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
247 SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
248 SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
249 SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
250 SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
253 scsi_low_activate_qtag(cb)
256 struct lun_info *li = cb->li;
258 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
262 cb->ccb_tag = cb->ccb_otag;
266 scsi_low_deactivate_qtag(cb)
269 struct lun_info *li = cb->li;
271 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
275 cb->ccb_tag = SCSI_LOW_UNKTAG;
279 scsi_low_ccb_message_exec(slp, cb)
280 struct scsi_low_softc *slp;
284 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
285 cb->ccb_msgoutflag = 0;
289 scsi_low_ccb_message_assert(cb, msg)
294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
298 scsi_low_ccb_message_retry(cb)
301 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
305 scsi_low_ccb_message_clear(cb)
308 cb->ccb_msgoutflag = 0;
312 scsi_low_init_msgsys(slp, ti)
313 struct scsi_low_softc *slp;
314 struct targ_info *ti;
318 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
319 SCSI_LOW_DEASSERT_ATN(slp);
320 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
323 /*=============================================================
324 * START OF OS switch (All OS depend fucntions should be here)
325 =============================================================*/
326 /* common os depend utitlities */
327 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
328 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
329 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
331 static u_int8_t scsi_low_cmd_flags[256] = {
332 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
333 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
334 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
335 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
336 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
339 struct scsi_low_error_code {
344 static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
345 static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
347 static struct slccb *
348 scsi_low_find_ccb(slp, target, lun, osdep)
349 struct scsi_low_softc *slp;
353 struct targ_info *ti;
357 ti = slp->sl_ti[target];
358 li = scsi_low_alloc_li(ti, lun, 0);
362 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
365 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
366 cb = TAILQ_NEXT(cb, ccb_chain))
368 if (cb->osdep == osdep)
372 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
373 cb = TAILQ_NEXT(cb, ccb_chain))
375 if (cb->osdep == osdep)
382 scsi_low_translate_error_code(cb, tp)
384 struct scsi_low_error_code *tp;
387 if (cb->ccb_error == 0)
388 return tp->error_code;
390 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
392 return tp->error_code;
395 #ifdef SCSI_LOW_INTERFACE_XS
396 /**************************************************************
397 * SCSI INTERFACE (XS)
398 **************************************************************/
399 #define SCSI_LOW_MINPHYS 0x10000
400 #define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
401 #define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
402 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
403 #define SCSI_LOW_XS_POLL_HZ 1000
405 static int scsi_low_poll_xs(struct scsi_low_softc *, struct slccb *);
406 static void scsi_low_scsi_minphys_xs(struct buf *);
407 #ifdef SCSI_LOW_TARGET_OPEN
408 static int scsi_low_target_open(struct scsipi_link *, struct cfdata *);
409 #endif /* SCSI_LOW_TARGET_OPEN */
410 static int scsi_low_scsi_cmd_xs(struct scsipi_xfer *);
411 static int scsi_low_enable_xs(void *, int);
412 static int scsi_low_ioctl_xs(struct scsipi_link *, u_long, caddr_t, int, struct proc *);
414 static int scsi_low_attach_xs(struct scsi_low_softc *);
415 static int scsi_low_world_start_xs(struct scsi_low_softc *);
416 static int scsi_low_dettach_xs(struct scsi_low_softc *);
417 static int scsi_low_ccb_setup_xs(struct scsi_low_softc *, struct slccb *);
418 static int scsi_low_done_xs(struct scsi_low_softc *, struct slccb *);
419 static void scsi_low_timeout_xs(struct scsi_low_softc *, int, int);
420 static u_int scsi_low_translate_quirks_xs(u_int);
421 static void scsi_low_setup_quirks_xs(struct targ_info *, struct lun_info *, u_int);
423 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
425 scsi_low_world_start_xs,
427 scsi_low_ccb_setup_xs,
432 struct scsipi_device scsi_low_dev = {
433 NULL, /* Use default error handler */
434 NULL, /* have a queue, served by this */
435 NULL, /* have no async handler */
436 NULL, /* Use default 'done' routine */
439 struct scsi_low_error_code scsi_low_error_code_xs[] = {
443 {SELTIMEOUTIO, XS_SELTIMEOUT},
444 {TIMEOUTIO, XS_TIMEOUT},
445 {-1, XS_DRIVER_STUFFUP}
449 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
450 struct scsipi_link *link;
456 struct scsi_low_softc *slp;
457 int s, error = ENOTTY;
459 slp = (struct scsi_low_softc *) link->adapter_softc;
460 if ((slp->sl_flags & HW_INACTIVE) != 0)
463 if (cmd == SCBUSIORESET)
465 s = SCSI_LOW_SPLSCSI();
466 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
470 else if (slp->sl_funcs->scsi_low_ioctl != 0)
472 error = (*slp->sl_funcs->scsi_low_ioctl)
473 (slp, cmd, addr, flag, p);
480 scsi_low_enable_xs(arg, enable)
484 struct scsi_low_softc *slp = arg;
488 if ((slp->sl_flags & HW_INACTIVE) != 0)
493 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
494 (slp->sl_flags & HW_POWERCTRL) == 0)
497 slp->sl_flags |= HW_POWDOWN;
498 if (slp->sl_funcs->scsi_low_power != NULL)
500 (*slp->sl_funcs->scsi_low_power)
501 (slp, SCSI_LOW_POWDOWN);
508 scsi_low_scsi_minphys_xs(bp)
512 if (bp->b_bcount > SCSI_LOW_MINPHYS)
513 bp->b_bcount = SCSI_LOW_MINPHYS;
518 scsi_low_poll_xs(slp, cb)
519 struct scsi_low_softc *slp;
522 struct scsipi_xfer *xs = cb->osdep;
525 cb->ccb_flags |= CCB_NOSDONE;
528 while (slp->sl_nio > 0)
530 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
532 (*slp->sl_funcs->scsi_low_poll) (slp);
534 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
536 cb->ccb_flags |= CCB_NORETRY;
537 cb->ccb_error |= FATALIO;
538 (void) scsi_low_revoke_ccb(slp, cb, 1);
539 printf("%s: hardware inactive in poll mode\n",
543 if ((xs->flags & ITSDONE) != 0)
546 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
550 scsi_low_timeout_check(slp);
553 xs->flags |= ITSDONE;
559 scsi_low_scsi_cmd_xs(xs)
560 struct scsipi_xfer *xs;
562 struct scsipi_link *splp = xs->sc_link;
563 struct scsi_low_softc *slp = splp->adapter_softc;
564 struct targ_info *ti;
567 int s, targ, lun, flags, rv;
569 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
570 return TRY_AGAIN_LATER;
572 targ = splp->scsipi_scsi.target,
573 lun = splp->scsipi_scsi.lun;
574 ti = slp->sl_ti[targ];
579 if ((xs->flags & SCSI_POLL) == 0)
580 flags = CCB_AUTOSENSE;
582 flags = CCB_AUTOSENSE | CCB_POLLED;
585 s = SCSI_LOW_SPLSCSI();
586 li = scsi_low_alloc_li(ti, lun, 1);
587 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
589 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
592 if ((xs->flags & SCSI_RESET) != 0)
594 flags |= CCB_NORETRY | CCB_URGENT;
595 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
599 if (ti->ti_setup_msg != 0)
601 scsi_low_message_enqueue(slp, ti, li, flags);
605 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
608 #ifdef SCSI_LOW_DEBUG
609 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
611 scsi_low_test_abort(slp, ti, li);
613 #endif /* SCSI_LOW_DEBUG */
615 if ((cb->ccb_flags & CCB_POLLED) != 0)
617 rv = scsi_low_poll_xs(slp, cb);
621 rv = SUCCESSFULLY_QUEUED;
628 scsi_low_attach_xs(slp)
629 struct scsi_low_softc *slp;
631 struct scsipi_adapter *sap;
632 struct scsipi_link *splp;
634 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
636 sap = SCSI_LOW_MALLOC(sizeof(*sap));
639 splp = SCSI_LOW_MALLOC(sizeof(*splp));
643 SCSI_LOW_BZERO(sap, sizeof(*sap));
644 SCSI_LOW_BZERO(splp, sizeof(*splp));
646 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
647 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
648 sap->scsipi_enable = scsi_low_enable_xs;
649 sap->scsipi_ioctl = scsi_low_ioctl_xs;
650 #ifdef SCSI_LOW_TARGET_OPEN
651 sap->open_target_lu = scsi_low_target_open;
652 #endif /* SCSI_LOW_TARGET_OPEN */
654 splp->adapter_softc = slp;
655 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
656 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
657 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
658 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
659 splp->openings = slp->sl_openings;
660 splp->type = BUS_SCSI;
661 splp->adapter_softc = slp;
663 splp->device = &scsi_low_dev;
665 slp->sl_si.si_splp = splp;
666 slp->sl_show_result = SHOW_ALL_NEG;
671 scsi_low_world_start_xs(slp)
672 struct scsi_low_softc *slp;
679 scsi_low_dettach_xs(slp)
680 struct scsi_low_softc *slp;
684 * scsipi does not have dettach bus fucntion.
686 scsipi_dettach_scsibus(slp->sl_si.si_splp);
692 scsi_low_ccb_setup_xs(slp, cb)
693 struct scsi_low_softc *slp;
696 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
698 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
700 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
701 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
702 cb->ccb_scp.scp_data = xs->data;
703 cb->ccb_scp.scp_datalen = xs->datalen;
704 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
705 SCSI_LOW_WRITE : SCSI_LOW_READ;
706 cb->ccb_tcmax = xs->timeout / 1000;
710 scsi_low_unit_ready_cmd(cb);
712 return SCSI_LOW_START_QTAG;
716 scsi_low_done_xs(slp, cb)
717 struct scsi_low_softc *slp;
720 struct scsipi_xfer *xs;
722 xs = (struct scsipi_xfer *) cb->osdep;
723 if (cb->ccb_error == 0)
725 xs->error = XS_NOERROR;
730 if (cb->ccb_rcnt >= slp->sl_max_retry)
731 cb->ccb_error |= ABORTIO;
733 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
734 (cb->ccb_error & ABORTIO) == 0)
737 if ((cb->ccb_error & SENSEIO) != 0)
739 xs->sense.scsi_sense = cb->ccb_sense;
742 xs->error = scsi_low_translate_error_code(cb,
743 &scsi_low_error_code_xs[0]);
745 #ifdef SCSI_LOW_DIAGNOSTIC
746 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
747 cb->ccb_scp.scp_cmdlen > 0 &&
748 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
749 SCSI_LOW_CMD_ABORT_WARNING) != 0)
751 printf("%s: WARNING: scsi_low IO abort\n",
753 scsi_low_print(slp, NULL);
755 #endif /* SCSI_LOW_DIAGNOSTIC */
758 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
759 xs->status = 0; /* XXX */
761 xs->status = cb->ccb_scp.scp_status;
763 xs->flags |= ITSDONE;
764 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
771 scsi_low_timeout_xs(slp, ch, action)
772 struct scsi_low_softc *slp;
779 case SCSI_LOW_TIMEOUT_CH_IO:
782 case SCSI_LOW_TIMEOUT_START:
783 timeout(scsi_low_timeout, slp,
784 hz / SCSI_LOW_TIMEOUT_HZ);
786 case SCSI_LOW_TIMEOUT_STOP:
787 untimeout(scsi_low_timeout, slp);
792 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
795 case SCSI_LOW_TIMEOUT_START:
796 timeout(scsi_low_engage, slp, 1);
798 case SCSI_LOW_TIMEOUT_STOP:
799 untimeout(scsi_low_engage, slp);
804 case SCSI_LOW_TIMEOUT_CH_RECOVER:
810 scsi_low_translate_quirks_xs(quirks)
815 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
818 if (quirks & SDEV_NODISC)
819 flags &= ~SCSI_LOW_DISK_DISC;
820 #endif /* SDEV_NODISC */
822 if (quirks & SDEV_NOPARITY)
823 flags &= ~SCSI_LOW_DISK_PARITY;
824 #endif /* SDEV_NOPARITY */
826 if (quirks & SDEV_NOCMDLNK)
827 flags &= ~SCSI_LOW_DISK_LINK;
828 #endif /* SDEV_NOCMDLNK */
830 if (quirks & SDEV_NOTAG)
831 flags &= ~SCSI_LOW_DISK_QTAG;
832 #endif /* SDEV_NOTAG */
834 if (quirks & SDEV_NOSYNC)
835 flags &= ~SCSI_LOW_DISK_SYNC;
836 #endif /* SDEV_NOSYNC */
842 scsi_low_setup_quirks_xs(ti, li, flags)
843 struct targ_info *ti;
849 li->li_sloi.sloi_quirks = flags;
850 quirks = scsi_low_translate_quirks_xs(flags);
851 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
852 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
853 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
854 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
855 scsi_low_calcf_target(ti);
856 scsi_low_calcf_lun(li);
857 scsi_low_calcf_show(li);
860 #ifdef SCSI_LOW_TARGET_OPEN
862 scsi_low_target_open(link, cf)
863 struct scsipi_link *link;
866 u_int target = link->scsipi_scsi.target;
867 u_int lun = link->scsipi_scsi.lun;
868 struct scsi_low_softc *slp;
869 struct targ_info *ti;
872 slp = (struct scsi_low_softc *) link->adapter_softc;
873 ti = slp->sl_ti[target];
874 li = scsi_low_alloc_li(ti, lun, 0);
878 li->li_cfgflags = cf->cf_flags;
879 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
882 #endif /* SCSI_LOW_TARGET_OPEN */
884 #endif /* SCSI_LOW_INTERFACE_XS */
886 #ifdef SCSI_LOW_INTERFACE_CAM
887 /**************************************************************
888 * SCSI INTERFACE (CAM)
889 **************************************************************/
890 #define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
891 #define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
892 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
894 static void scsi_low_poll_cam(struct cam_sim *);
895 static void scsi_low_cam_rescan_callback(struct cam_periph *, union ccb *);
896 static void scsi_low_rescan_bus_cam(struct scsi_low_softc *);
897 void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
899 static int scsi_low_attach_cam(struct scsi_low_softc *);
900 static int scsi_low_world_start_cam(struct scsi_low_softc *);
901 static int scsi_low_dettach_cam(struct scsi_low_softc *);
902 static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
903 static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
904 static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int);
906 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
908 scsi_low_world_start_cam,
909 scsi_low_dettach_cam,
910 scsi_low_ccb_setup_cam,
915 struct scsi_low_error_code scsi_low_error_code_cam[] = {
917 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
918 {SENSEERR, CAM_AUTOSENSE_FAIL},
919 {UACAERR, CAM_SCSI_STATUS_ERROR},
920 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
921 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
922 {TIMEOUTIO, CAM_CMD_TIMEOUT},
923 {PDMAERR, CAM_DATA_RUN_ERR},
924 {PARITYERR, CAM_UNCOR_PARITY},
925 {UBFERR, CAM_UNEXP_BUSFREE},
926 {ABORTIO, CAM_REQ_ABORTED},
927 {-1, CAM_UNREC_HBA_ERROR}
930 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
933 * Please check a polling hz, currently we assume scsi_low_poll() is
936 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
939 scsi_low_poll_cam(sim)
942 struct scsi_low_softc *slp = SIM2SLP(sim);
944 (*slp->sl_funcs->scsi_low_poll) (slp);
946 if (slp->sl_si.si_poll_count ++ >=
947 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
949 slp->sl_si.si_poll_count = 0;
950 scsi_low_timeout_check(slp);
955 scsi_low_cam_rescan_callback(periph, ccb)
956 struct cam_periph *periph;
960 xpt_free_path(ccb->ccb_h.path);
965 scsi_low_rescan_bus_cam(slp)
966 struct scsi_low_softc *slp;
968 struct cam_path *path;
972 status = xpt_create_path(&path, xpt_periph,
973 cam_sim_path(slp->sl_si.sim), -1, 0);
974 if (status != CAM_REQ_CMP)
977 ccb = xpt_alloc_ccb();
978 bzero(ccb, sizeof(union ccb));
979 xpt_setup_ccb(&ccb->ccb_h, path, 5);
980 ccb->ccb_h.func_code = XPT_SCAN_BUS;
981 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
982 ccb->crcn.flags = CAM_FLAG_NONE;
987 scsi_low_scsi_action_cam(sim, ccb)
991 struct scsi_low_softc *slp = SIM2SLP(sim);
992 struct targ_info *ti;
995 u_int lun, flags, msg, target;
998 target = (u_int) (ccb->ccb_h.target_id);
999 lun = (u_int) ccb->ccb_h.target_lun;
1001 #ifdef SCSI_LOW_DEBUG
1002 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
1004 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
1005 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1007 #endif /* SCSI_LOW_DEBUG */
1009 switch (ccb->ccb_h.func_code) {
1010 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1011 #ifdef SCSI_LOW_DIAGNOSTIC
1012 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1014 printf("%s: invalid target/lun\n", slp->sl_xname);
1015 ccb->ccb_h.status = CAM_REQ_INVALID;
1019 #endif /* SCSI_LOW_DIAGNOSTIC */
1021 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1022 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1027 ti = slp->sl_ti[target];
1030 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1031 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1035 s = SCSI_LOW_SPLSCSI();
1036 li = scsi_low_alloc_li(ti, lun, 1);
1038 if (ti->ti_setup_msg != 0)
1040 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1043 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1045 #ifdef SCSI_LOW_DEBUG
1046 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1048 scsi_low_test_abort(slp, ti, li);
1050 #endif /* SCSI_LOW_DEBUG */
1054 case XPT_EN_LUN: /* Enable LUN as a target */
1055 case XPT_TARGET_IO: /* Execute target I/O request */
1056 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1057 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1059 ccb->ccb_h.status = CAM_REQ_INVALID;
1063 case XPT_ABORT: /* Abort the specified CCB */
1064 #ifdef SCSI_LOW_DIAGNOSTIC
1065 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1067 printf("%s: invalid target/lun\n", slp->sl_xname);
1068 ccb->ccb_h.status = CAM_REQ_INVALID;
1072 #endif /* SCSI_LOW_DIAGNOSTIC */
1074 s = SCSI_LOW_SPLSCSI();
1075 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1076 rv = scsi_low_abort_ccb(slp, cb);
1080 ccb->ccb_h.status = CAM_REQ_CMP;
1082 ccb->ccb_h.status = CAM_REQ_INVALID;
1086 case XPT_SET_TRAN_SETTINGS: {
1087 struct ccb_trans_settings_scsi *scsi;
1088 struct ccb_trans_settings_spi *spi;
1089 struct ccb_trans_settings *cts;
1092 #ifdef SCSI_LOW_DIAGNOSTIC
1093 if (target == CAM_TARGET_WILDCARD)
1095 printf("%s: invalid target\n", slp->sl_xname);
1096 ccb->ccb_h.status = CAM_REQ_INVALID;
1100 #endif /* SCSI_LOW_DIAGNOSTIC */
1102 ti = slp->sl_ti[target];
1103 if (lun == CAM_LUN_WILDCARD)
1106 s = SCSI_LOW_SPLSCSI();
1107 scsi = &cts->proto_specific.scsi;
1108 spi = &cts->xport_specific.spi;
1109 if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH |
1110 CTS_SPI_VALID_SYNC_RATE |
1111 CTS_SPI_VALID_SYNC_OFFSET)) != 0)
1113 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
1114 val = spi->bus_width;
1115 if (val < ti->ti_width)
1118 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
1119 val = spi->sync_period;
1120 if (val == 0 || val > ti->ti_maxsynch.period)
1121 ti->ti_maxsynch.period = val;
1123 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
1124 val = spi->sync_offset;
1125 if (val < ti->ti_maxsynch.offset)
1126 ti->ti_maxsynch.offset = val;
1128 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1129 scsi_low_calcf_target(ti);
1132 if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 ||
1133 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
1135 li = scsi_low_alloc_li(ti, lun, 1);
1136 if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) {
1137 li->li_quirks |= SCSI_LOW_DISK_DISC;
1139 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1142 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
1143 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1145 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1147 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1148 scsi_low_calcf_target(ti);
1149 scsi_low_calcf_lun(li);
1150 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1151 scsi_low_calcf_show(li);
1155 ccb->ccb_h.status = CAM_REQ_CMP;
1160 case XPT_GET_TRAN_SETTINGS: {
1161 struct ccb_trans_settings *cts;
1165 #ifdef SCSI_LOW_DIAGNOSTIC
1166 if (target == CAM_TARGET_WILDCARD)
1168 printf("%s: invalid target\n", slp->sl_xname);
1169 ccb->ccb_h.status = CAM_REQ_INVALID;
1173 #endif /* SCSI_LOW_DIAGNOSTIC */
1174 ti = slp->sl_ti[target];
1175 if (lun == CAM_LUN_WILDCARD)
1178 s = SCSI_LOW_SPLSCSI();
1179 li = scsi_low_alloc_li(ti, lun, 1);
1180 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1181 struct ccb_trans_settings_scsi *scsi =
1182 &cts->proto_specific.scsi;
1183 struct ccb_trans_settings_spi *spi =
1184 &cts->xport_specific.spi;
1185 #ifdef SCSI_LOW_DIAGNOSTIC
1186 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1188 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1189 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1193 #endif /* SCSI_LOW_DIAGNOSTIC */
1194 cts->protocol = PROTO_SCSI;
1195 cts->protocol_version = SCSI_REV_2;
1196 cts->transport = XPORT_SPI;
1197 cts->transport_version = 2;
1199 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1200 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1202 diskflags = li->li_diskflags & li->li_cfgflags;
1203 if (diskflags & SCSI_LOW_DISK_DISC)
1204 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1205 if (diskflags & SCSI_LOW_DISK_QTAG)
1206 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1208 spi->sync_period = ti->ti_maxsynch.period;
1209 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1210 spi->sync_offset = ti->ti_maxsynch.offset;
1211 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1213 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1214 spi->bus_width = ti->ti_width;
1216 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1217 scsi->valid = CTS_SCSI_VALID_TQ;
1218 spi->valid |= CTS_SPI_VALID_DISC;
1222 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1229 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1230 cam_calc_geometry(&ccb->ccg, /*extended*/1);
1235 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1236 s = SCSI_LOW_SPLSCSI();
1237 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1239 ccb->ccb_h.status = CAM_REQ_CMP;
1243 case XPT_TERM_IO: /* Terminate the I/O process */
1244 ccb->ccb_h.status = CAM_REQ_INVALID;
1248 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1249 #ifdef SCSI_LOW_DIAGNOSTIC
1250 if (target == CAM_TARGET_WILDCARD)
1252 printf("%s: invalid target\n", slp->sl_xname);
1253 ccb->ccb_h.status = CAM_REQ_INVALID;
1257 #endif /* SCSI_LOW_DIAGNOSTIC */
1259 msg = SCSI_LOW_MSG_RESET;
1260 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1262 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1267 ti = slp->sl_ti[target];
1268 if (lun == CAM_LUN_WILDCARD)
1272 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1273 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1275 flags = CCB_NORETRY | CCB_URGENT;
1277 s = SCSI_LOW_SPLSCSI();
1278 li = scsi_low_alloc_li(ti, lun, 1);
1279 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1283 case XPT_PATH_INQ: { /* Path routing inquiry */
1284 struct ccb_pathinq *cpi = &ccb->cpi;
1286 cpi->version_num = scsi_low_version_major;
1287 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1288 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1289 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1290 cpi->hba_inquiry |= PI_WIDE_16;
1291 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1292 cpi->hba_inquiry |= PI_WIDE_32;
1293 if (ti->ti_maxsynch.offset > 0)
1294 cpi->hba_inquiry |= PI_SDTR_ABLE;
1295 cpi->target_sprt = 0;
1297 cpi->hba_eng_cnt = 0;
1298 cpi->max_target = slp->sl_ntargs - 1;
1299 cpi->max_lun = slp->sl_nluns - 1;
1300 cpi->initiator_id = slp->sl_hostid;
1301 cpi->bus_id = cam_sim_bus(sim);
1302 cpi->base_transfer_speed = 3300;
1303 cpi->transport = XPORT_SPI;
1304 cpi->transport_version = 2;
1305 cpi->protocol = PROTO_SCSI;
1306 cpi->protocol_version = SCSI_REV_2;
1307 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1308 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1309 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1310 cpi->unit_number = cam_sim_unit(sim);
1311 cpi->ccb_h.status = CAM_REQ_CMP;
1317 printf("scsi_low: non support func_code = %d ",
1318 ccb->ccb_h.func_code);
1319 ccb->ccb_h.status = CAM_REQ_INVALID;
1326 scsi_low_attach_cam(slp)
1327 struct scsi_low_softc *slp;
1329 struct cam_devq *devq;
1330 int tagged_openings;
1332 sprintf(slp->sl_xname, "%s%d",
1333 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1335 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1340 * ask the adapter what subunits are present
1342 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1343 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1345 DEVPORT_DEVNAME(slp->sl_dev), slp,
1346 DEVPORT_DEVUNIT(slp->sl_dev), &Giant,
1347 slp->sl_openings, tagged_openings, devq);
1349 if (slp->sl_si.sim == NULL) {
1350 cam_simq_free(devq);
1354 if (xpt_bus_register(slp->sl_si.sim, NULL, 0) != CAM_SUCCESS) {
1355 free(slp->sl_si.sim, M_SCSILOW);
1359 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1360 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1361 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1362 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1363 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1367 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1372 scsi_low_world_start_cam(slp)
1373 struct scsi_low_softc *slp;
1377 scsi_low_rescan_bus_cam(slp);
1382 scsi_low_dettach_cam(slp)
1383 struct scsi_low_softc *slp;
1386 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1387 xpt_free_path(slp->sl_si.path);
1388 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1389 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1394 scsi_low_ccb_setup_cam(slp, cb)
1395 struct scsi_low_softc *slp;
1398 union ccb *ccb = (union ccb *) cb->osdep;
1400 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1402 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1403 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1404 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1405 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1406 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1407 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1408 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1409 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1410 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1414 scsi_low_unit_ready_cmd(cb);
1416 return SCSI_LOW_START_QTAG;
1420 scsi_low_done_cam(slp, cb)
1421 struct scsi_low_softc *slp;
1426 ccb = (union ccb *) cb->osdep;
1427 if (cb->ccb_error == 0)
1429 ccb->ccb_h.status = CAM_REQ_CMP;
1430 ccb->csio.resid = 0;
1434 if (cb->ccb_rcnt >= slp->sl_max_retry)
1435 cb->ccb_error |= ABORTIO;
1437 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1438 (cb->ccb_error & ABORTIO) == 0)
1441 if ((cb->ccb_error & SENSEIO) != 0)
1443 memcpy(&ccb->csio.sense_data,
1445 sizeof(ccb->csio.sense_data));
1448 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1449 &scsi_low_error_code_cam[0]);
1451 #ifdef SCSI_LOW_DIAGNOSTIC
1452 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1453 cb->ccb_scp.scp_cmdlen > 0 &&
1454 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1455 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1457 printf("%s: WARNING: scsi_low IO abort\n",
1459 scsi_low_print(slp, NULL);
1461 #endif /* SCSI_LOW_DIAGNOSTIC */
1464 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1465 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1467 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1468 ccb->csio.scsi_status = 0; /* XXX */
1470 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1472 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1478 scsi_low_timeout_cam(slp, ch, action)
1479 struct scsi_low_softc *slp;
1486 case SCSI_LOW_TIMEOUT_CH_IO:
1489 case SCSI_LOW_TIMEOUT_START:
1490 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1491 hz / SCSI_LOW_TIMEOUT_HZ);
1493 case SCSI_LOW_TIMEOUT_STOP:
1494 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1499 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1502 case SCSI_LOW_TIMEOUT_START:
1503 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1505 case SCSI_LOW_TIMEOUT_STOP:
1506 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1510 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1515 #endif /* SCSI_LOW_INTERFACE_CAM */
1517 /*=============================================================
1518 * END OF OS switch (All OS depend fucntions should be above)
1519 =============================================================*/
1521 /**************************************************************
1522 * scsi low deactivate and activate
1523 **************************************************************/
1525 scsi_low_is_busy(slp)
1526 struct scsi_low_softc *slp;
1529 if (slp->sl_nio > 0)
1535 scsi_low_deactivate(slp)
1536 struct scsi_low_softc *slp;
1540 s = SCSI_LOW_SPLSCSI();
1541 slp->sl_flags |= HW_INACTIVE;
1542 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1543 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1544 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1545 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1551 scsi_low_activate(slp)
1552 struct scsi_low_softc *slp;
1556 s = SCSI_LOW_SPLSCSI();
1557 slp->sl_flags &= ~HW_INACTIVE;
1558 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1560 slp->sl_flags |= HW_INACTIVE;
1565 slp->sl_timeout_count = 0;
1566 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1567 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1572 /**************************************************************
1574 **************************************************************/
1575 #ifdef SCSI_LOW_DIAGNOSTIC
1576 static void scsi_low_msg_log_init(struct scsi_low_msg_log *);
1577 static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int);
1578 static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int);
1581 scsi_low_msg_log_init(slmlp)
1582 struct scsi_low_msg_log *slmlp;
1585 slmlp->slml_ptr = 0;
1589 scsi_low_msg_log_write(slmlp, datap, len)
1590 struct scsi_low_msg_log *slmlp;
1596 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1599 ptr = slmlp->slml_ptr ++;
1600 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1601 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1602 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1603 slmlp->slml_msg[ptr].msg[ind] = 0;
1607 scsi_low_msg_log_show(slmlp, s, len)
1608 struct scsi_low_msg_log *slmlp;
1614 printf("%s: (%d) ", s, slmlp->slml_ptr);
1615 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1617 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1620 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1626 #endif /* SCSI_LOW_DIAGNOSTIC */
1628 /**************************************************************
1630 **************************************************************/
1632 scsi_low_engage(arg)
1635 struct scsi_low_softc *slp = arg;
1636 int s = SCSI_LOW_SPLSCSI();
1638 switch (slp->sl_rstep)
1642 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1643 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1644 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1649 slp->sl_flags &= ~HW_RESUME;
1650 scsi_low_start(slp);
1660 scsi_low_init(slp, flags)
1661 struct scsi_low_softc *slp;
1666 slp->sl_flags |= HW_INITIALIZING;
1668 /* clear power control timeout */
1669 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1671 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1672 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1673 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1675 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1678 /* reset current nexus */
1679 scsi_low_reset_nexus(slp, flags);
1680 if ((slp->sl_flags & HW_INACTIVE) != 0)
1686 if (flags != SCSI_LOW_RESTART_SOFT)
1688 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1692 slp->sl_flags &= ~HW_INITIALIZING;
1696 /**************************************************************
1698 **************************************************************/
1699 static struct lun_info *
1700 scsi_low_alloc_li(ti, lun, alloc)
1701 struct targ_info *ti;
1705 struct scsi_low_softc *slp = ti->ti_sc;
1706 struct lun_info *li;
1708 li = LIST_FIRST(&ti->ti_litab);
1711 if (li->li_lun == lun)
1714 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1716 if (li->li_lun == lun)
1718 LIST_REMOVE(li, lun_chain);
1719 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1728 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1730 panic("no lun info mem");
1732 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1736 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1738 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1739 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1740 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1741 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1742 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1744 li->li_qtagbits = (u_int) -1;
1746 TAILQ_INIT(&li->li_discq);
1747 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1749 /* host specific structure initialization per lun */
1750 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1751 (*slp->sl_funcs->scsi_low_lun_init)
1752 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1753 scsi_low_calcf_lun(li);
1757 /**************************************************************
1758 * allocate targ_info
1759 **************************************************************/
1760 static struct targ_info *
1761 scsi_low_alloc_ti(slp, targ)
1762 struct scsi_low_softc *slp;
1765 struct targ_info *ti;
1767 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1768 TAILQ_INIT(&slp->sl_titab);
1770 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1772 panic("%s short of memory", slp->sl_xname);
1774 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1778 slp->sl_ti[targ] = ti;
1779 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1780 LIST_INIT(&ti->ti_litab);
1782 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1783 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1784 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1785 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1786 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1787 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1789 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1791 (*slp->sl_funcs->scsi_low_targ_init)
1792 (slp, ti, SCSI_LOW_INFO_ALLOC);
1794 scsi_low_calcf_target(ti);
1799 scsi_low_free_ti(slp)
1800 struct scsi_low_softc *slp;
1802 struct targ_info *ti, *tib;
1803 struct lun_info *li, *nli;
1805 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1807 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1809 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1811 (*slp->sl_funcs->scsi_low_lun_init)
1812 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1814 nli = LIST_NEXT(li, lun_chain);
1818 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1820 (*slp->sl_funcs->scsi_low_targ_init)
1821 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1823 tib = TAILQ_NEXT(ti, ti_chain);
1828 /**************************************************************
1830 **************************************************************/
1832 scsi_low_bus_idle(slp)
1833 struct scsi_low_softc *slp;
1836 slp->sl_retry_sel = 0;
1837 if (slp->sl_Tnexus == NULL)
1838 scsi_low_start(slp);
1842 scsi_low_timeout(arg)
1845 struct scsi_low_softc *slp = arg;
1848 s = SCSI_LOW_SPLSCSI();
1849 (void) scsi_low_timeout_check(slp);
1850 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1851 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1856 scsi_low_timeout_check(slp)
1857 struct scsi_low_softc *slp;
1859 struct targ_info *ti;
1860 struct lun_info *li;
1861 struct slccb *cb = NULL; /* XXX */
1863 /* selection restart */
1864 if (slp->sl_retry_sel != 0)
1866 slp->sl_retry_sel = 0;
1867 if (slp->sl_Tnexus != NULL)
1870 cb = TAILQ_FIRST(&slp->sl_start);
1874 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1876 cb->ccb_flags |= CCB_NORETRY;
1877 cb->ccb_error |= SELTIMEOUTIO;
1878 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1879 panic("%s: ccb not finished", slp->sl_xname);
1882 if (slp->sl_Tnexus == NULL)
1883 scsi_low_start(slp);
1886 /* call hardware timeout */
1888 if (slp->sl_funcs->scsi_low_timeout != NULL)
1890 (*slp->sl_funcs->scsi_low_timeout) (slp);
1893 if (slp->sl_timeout_count ++ <
1894 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1897 slp->sl_timeout_count = 0;
1898 if (slp->sl_nio > 0)
1900 if ((cb = slp->sl_Qnexus) != NULL)
1902 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1906 else if (slp->sl_disc == 0)
1908 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1911 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1915 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1916 ti = TAILQ_NEXT(ti, ti_chain))
1918 if (ti->ti_disc == 0)
1921 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1922 li = LIST_NEXT(li, lun_chain))
1924 for (cb = TAILQ_FIRST(&li->li_discq);
1926 cb = TAILQ_NEXT(cb, ccb_chain))
1929 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1937 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1939 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1942 if (slp->sl_active != 0)
1944 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1950 if (slp->sl_powc < 0)
1952 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1953 slp->sl_flags |= HW_POWDOWN;
1954 (*slp->sl_funcs->scsi_low_power)
1955 (slp, SCSI_LOW_POWDOWN);
1961 cb->ccb_error |= TIMEOUTIO;
1962 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1963 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1964 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1965 scsi_low_start(slp);
1971 scsi_low_abort_ccb(slp, cb)
1972 struct scsi_low_softc *slp;
1975 struct targ_info *ti;
1976 struct lun_info *li;
1981 if ((cb->ccb_omsgoutflag &
1982 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1987 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1988 msg = SCSI_LOW_MSG_ABORT;
1990 msg = SCSI_LOW_MSG_ABORT_QTAG;
1992 cb->ccb_error |= ABORTIO;
1993 cb->ccb_flags |= CCB_NORETRY;
1994 scsi_low_ccb_message_assert(cb, msg);
1996 if (cb == slp->sl_Qnexus)
1998 scsi_low_assert_msg(slp, ti, msg, 1);
2000 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2002 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2003 panic("%s: revoked ccb done", slp->sl_xname);
2005 cb->ccb_flags |= CCB_STARTQ;
2006 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2008 if (slp->sl_Tnexus == NULL)
2009 scsi_low_start(slp);
2013 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2014 panic("%s: revoked ccb retried", slp->sl_xname);
2019 /**************************************************************
2020 * Generic SCSI INTERFACE
2021 **************************************************************/
2023 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2024 struct scsi_low_softc *slp;
2025 int openings, ntargs, nluns, targsize, lunsize;
2027 struct targ_info *ti;
2028 struct lun_info *li;
2031 #ifdef SCSI_LOW_INTERFACE_XS
2032 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2033 #endif /* SCSI_LOW_INTERFACE_XS */
2034 #ifdef SCSI_LOW_INTERFACE_CAM
2035 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2036 #endif /* SCSI_LOW_INTERFACE_CAM */
2038 if (slp->sl_osdep_fp == NULL)
2039 panic("scsi_low: interface not spcified");
2041 if (ntargs > SCSI_LOW_NTARGETS)
2043 printf("scsi_low: %d targets are too large\n", ntargs);
2044 printf("change kernel options SCSI_LOW_NTARGETS");
2049 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2051 slp->sl_openings = openings;
2052 slp->sl_ntargs = ntargs;
2053 slp->sl_nluns = nluns;
2054 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2056 if (lunsize < sizeof(struct lun_info))
2057 lunsize = sizeof(struct lun_info);
2059 if (targsize < sizeof(struct targ_info))
2060 targsize = sizeof(struct targ_info);
2062 slp->sl_targsize = targsize;
2063 for (i = 0; i < ntargs; i ++)
2065 ti = scsi_low_alloc_ti(slp, i);
2066 ti->ti_lunsize = lunsize;
2067 li = scsi_low_alloc_li(ti, 0, 1);
2070 /* initialize queue */
2071 nccb = openings * ntargs;
2072 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2073 nccb = SCSI_LOW_NCCB;
2074 scsi_low_init_ccbque(nccb);
2075 TAILQ_INIT(&slp->sl_start);
2077 /* call os depend attach */
2078 s = SCSI_LOW_SPLSCSI();
2079 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2083 printf("%s: scsi_low_attach: osdep attach failed\n",
2088 /* check hardware */
2089 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2090 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2093 printf("%s: scsi_low_attach: initialization failed\n",
2098 /* start watch dog */
2099 slp->sl_timeout_count = 0;
2100 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2101 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2102 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2105 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2107 #ifdef SCSI_LOW_START_UP_CHECK
2108 /* probing devices */
2109 scsi_low_start_up(slp);
2110 #endif /* SCSI_LOW_START_UP_CHECK */
2112 /* call os depend attach done*/
2113 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2119 scsi_low_dettach(slp)
2120 struct scsi_low_softc *slp;
2124 s = SCSI_LOW_SPLSCSI();
2125 if (scsi_low_is_busy(slp) != 0)
2131 scsi_low_deactivate(slp);
2133 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2140 scsi_low_free_ti(slp);
2141 LIST_REMOVE(slp, sl_chain);
2146 /**************************************************************
2148 **************************************************************/
2150 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2151 struct scsi_low_softc *slp;
2152 struct targ_info *ti;
2153 struct lun_info *li;
2161 scsi_low_ccb_message_assert(cb, msg);
2163 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2164 scsi_low_alloc_qtag(cb);
2166 cb->ccb_flags = flags | CCB_STARTQ;
2167 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2168 cb->ccb_error |= PENDINGIO;
2170 if ((flags & CCB_URGENT) != 0)
2172 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2176 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2181 if (slp->sl_Tnexus == NULL)
2182 scsi_low_start(slp);
2187 scsi_low_message_enqueue(slp, ti, li, flags)
2188 struct scsi_low_softc *slp;
2189 struct targ_info *ti;
2190 struct lun_info *li;
2196 tmsgflags = ti->ti_setup_msg;
2197 ti->ti_setup_msg = 0;
2199 flags |= CCB_NORETRY;
2200 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2205 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2209 /**************************************************************
2210 * Generic Start & Done
2211 **************************************************************/
2212 #define SLSC_MODE_SENSE_SHORT 0x1a
2213 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2214 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2215 sizeof(struct scsi_low_mode_sense_data), 0};
2216 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2217 sizeof(struct scsi_low_inq_data), 0};
2218 static u_int8_t unit_ready_cmd[6];
2219 static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2220 static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2221 static int scsi_low_resume(struct scsi_low_softc *);
2224 scsi_low_unit_ready_cmd(cb)
2228 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2229 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2230 cb->ccb_scp.scp_datalen = 0;
2231 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2236 scsi_low_sense_abort_start(slp, ti, li, cb)
2237 struct scsi_low_softc *slp;
2238 struct targ_info *ti;
2239 struct lun_info *li;
2243 cb->ccb_scp.scp_cmdlen = 6;
2244 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2245 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2246 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2247 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2248 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2249 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2250 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2252 scsi_low_ccb_message_clear(cb);
2253 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2255 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2259 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2260 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2261 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2262 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2265 return SCSI_LOW_START_NO_QTAG;
2269 scsi_low_setup_start(slp, ti, li, cb)
2270 struct scsi_low_softc *slp;
2271 struct targ_info *ti;
2272 struct lun_info *li;
2276 switch(li->li_state)
2278 case SCSI_LOW_LUN_SLEEP:
2279 scsi_low_unit_ready_cmd(cb);
2282 case SCSI_LOW_LUN_START:
2283 cb->ccb_scp.scp_cmd = ss_cmd;
2284 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2285 cb->ccb_scp.scp_datalen = 0;
2286 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2290 case SCSI_LOW_LUN_INQ:
2291 cb->ccb_scp.scp_cmd = inq_cmd;
2292 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2293 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2294 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2295 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2299 case SCSI_LOW_LUN_MODEQ:
2300 cb->ccb_scp.scp_cmd = sms_cmd;
2301 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2302 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2303 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2304 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2306 return SCSI_LOW_START_QTAG;
2309 panic("%s: no setup phase", slp->sl_xname);
2312 return SCSI_LOW_START_NO_QTAG;
2316 scsi_low_resume(slp)
2317 struct scsi_low_softc *slp;
2320 if (slp->sl_flags & HW_RESUME)
2322 slp->sl_flags &= ~HW_POWDOWN;
2323 if (slp->sl_funcs->scsi_low_power != NULL)
2325 slp->sl_flags |= HW_RESUME;
2327 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2328 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2329 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2330 SCSI_LOW_TIMEOUT_START);
2338 struct scsi_low_softc *slp;
2340 struct targ_info *ti;
2341 struct lun_info *li;
2345 /* check hardware exists or under initializations ? */
2346 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2349 /* check hardware power up ? */
2350 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2353 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2355 if (scsi_low_resume(slp) == EJUSTRETURN)
2361 #ifdef SCSI_LOW_DIAGNOSTIC
2362 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2364 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2365 panic("%s: inconsistent", slp->sl_xname);
2367 #endif /* SCSI_LOW_DIAGNOSTIC */
2369 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2370 cb = TAILQ_NEXT(cb, ccb_chain))
2374 if (li->li_disc == 0)
2376 goto scsi_low_cmd_start;
2378 else if (li->li_nqio > 0)
2380 if (li->li_nqio < li->li_maxnqio ||
2381 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2382 goto scsi_low_cmd_start;
2388 cb->ccb_flags &= ~CCB_STARTQ;
2389 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2392 /* clear all error flag bits (for restart) */
2394 cb->ccb_datalen = -1;
2395 cb->ccb_scp.scp_status = ST_UNKNOWN;
2397 /* setup nexus pointer */
2398 slp->sl_Qnexus = cb;
2399 slp->sl_Lnexus = li;
2400 slp->sl_Tnexus = ti;
2402 /* initialize msgsys */
2403 scsi_low_init_msgsys(slp, ti);
2406 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2408 /* CA state or forced abort */
2409 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2411 else if (li->li_state >= SCSI_LOW_LUN_OK)
2413 cb->ccb_flags &= ~CCB_INTERNAL;
2414 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2415 if (cb->ccb_msgoutflag != 0)
2417 scsi_low_ccb_message_exec(slp, cb);
2422 cb->ccb_flags |= CCB_INTERNAL;
2423 rv = scsi_low_setup_start(slp, ti, li, cb);
2427 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2429 if (rv == SCSI_LOW_START_QTAG &&
2430 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2435 scsi_low_activate_qtag(cb);
2436 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2437 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2438 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2439 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2440 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2442 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2443 scsi_low_assert_msg(slp, ti, qmsg, 0);
2447 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2448 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2449 cb->ccb_tc = cb->ccb_tcmax;
2451 /* setup saved scsi data pointer */
2452 cb->ccb_sscp = cb->ccb_scp;
2454 /* setup current scsi pointer */
2455 slp->sl_scp = cb->ccb_sscp;
2456 slp->sl_error = cb->ccb_error;
2458 /* assert always an identify msg */
2459 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2462 #ifdef SCSI_LOW_DIAGNOSTIC
2463 scsi_low_msg_log_init(&ti->ti_log_msgin);
2464 scsi_low_msg_log_init(&ti->ti_log_msgout);
2465 #endif /* SCSI_LOW_DIAGNOSTIC */
2467 /* selection start */
2469 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2470 if (rv == SCSI_LOW_START_OK)
2472 #ifdef SCSI_LOW_STATICS
2473 scsi_low_statics.nexus_win ++;
2474 #endif /* SCSI_LOW_STATICS */
2478 scsi_low_arbit_fail(slp, cb);
2479 #ifdef SCSI_LOW_STATICS
2480 scsi_low_statics.nexus_fail ++;
2481 #endif /* SCSI_LOW_STATICS */
2485 scsi_low_arbit_fail(slp, cb)
2486 struct scsi_low_softc *slp;
2489 struct targ_info *ti = cb->ti;
2491 scsi_low_deactivate_qtag(cb);
2492 scsi_low_ccb_message_retry(cb);
2493 cb->ccb_flags |= CCB_STARTQ;
2494 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2496 scsi_low_bus_release(slp, ti);
2499 if (slp->sl_disc == 0)
2501 #ifdef SCSI_LOW_DIAGNOSTIC
2502 printf("%s: try selection again\n", slp->sl_xname);
2503 #endif /* SCSI_LOW_DIAGNOSTIC */
2504 slp->sl_retry_sel = 1;
2509 scsi_low_bus_release(slp, ti)
2510 struct scsi_low_softc *slp;
2511 struct targ_info *ti;
2514 if (ti->ti_disc > 0)
2516 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2520 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2523 /* clear all nexus pointer */
2524 slp->sl_Qnexus = NULL;
2525 slp->sl_Lnexus = NULL;
2526 slp->sl_Tnexus = NULL;
2528 /* clear selection assert */
2529 slp->sl_selid = NULL;
2531 /* clear nexus data */
2532 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2534 /* clear phase change counter */
2535 slp->sl_ph_count = 0;
2539 scsi_low_setup_done(slp, cb)
2540 struct scsi_low_softc *slp;
2543 struct targ_info *ti;
2544 struct lun_info *li;
2549 if (cb->ccb_rcnt >= slp->sl_max_retry)
2551 cb->ccb_error |= ABORTIO;
2552 return SCSI_LOW_DONE_COMPLETE;
2555 /* XXX: special huck for selection timeout */
2556 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2557 (cb->ccb_error & SELTIMEOUTIO) != 0)
2559 cb->ccb_error |= ABORTIO;
2560 return SCSI_LOW_DONE_COMPLETE;
2563 switch(li->li_state)
2565 case SCSI_LOW_LUN_INQ:
2566 if (cb->ccb_error != 0)
2569 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2573 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2575 else if ((li->li_inq.sd_version & 7) >= 2 ||
2576 (li->li_inq.sd_len >= 4))
2578 if ((li->li_inq.sd_support & 0x2) == 0)
2579 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2580 if ((li->li_inq.sd_support & 0x8) == 0)
2581 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2584 if ((li->li_inq.sd_support & 0x10) == 0)
2585 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2586 if ((li->li_inq.sd_support & 0x20) == 0)
2587 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2588 if ((li->li_inq.sd_support & 0x40) == 0)
2589 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2594 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2597 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2599 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2601 scsi_low_calcf_target(ti);
2602 scsi_low_calcf_lun(li);
2605 case SCSI_LOW_LUN_MODEQ:
2606 if (cb->ccb_error != 0)
2608 if (cb->ccb_error & SENSEIO)
2610 #ifdef SCSI_LOW_DEBUG
2611 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2613 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2614 (u_int) cb->ccb_sense.error_code,
2615 (u_int) cb->ccb_sense.segment,
2616 (u_int) cb->ccb_sense.flags,
2617 (u_int) cb->ccb_sense.add_sense_code,
2618 (u_int) cb->ccb_sense.add_sense_code_qual);
2620 #endif /* SCSI_LOW_DEBUG */
2624 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2627 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2629 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2630 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2632 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2633 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2634 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2636 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2637 scsi_low_calcf_lun(li);
2645 if (li->li_state == SCSI_LOW_LUN_OK)
2647 scsi_low_calcf_target(ti);
2648 scsi_low_calcf_lun(li);
2649 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2650 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2652 scsi_low_calcf_show(li);
2657 return SCSI_LOW_DONE_RETRY;
2661 scsi_low_done(slp, cb)
2662 struct scsi_low_softc *slp;
2667 if (cb->ccb_error == 0)
2669 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2671 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2673 * SCSI-2 draft suggests
2674 * page 0x0a QErr bit determins if
2675 * the target aborts or continues
2676 * the queueing io's after CA state resolved.
2677 * However many targets seem not to support
2678 * the page 0x0a. Thus we should manually clear the
2679 * queuing io's after CA state.
2681 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2684 cb->ccb_flags |= CCB_CLEARQ;
2687 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2689 if ((cb->ccb_flags & CCB_SENSE) != 0)
2690 cb->ccb_error |= (SENSEIO | ABORTIO);
2691 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2693 else switch (cb->ccb_sscp.scp_status)
2699 if (cb->ccb_datalen == 0 ||
2700 cb->ccb_scp.scp_datalen == 0)
2703 if (cb->ccb_scp.scp_cmdlen > 0 &&
2704 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2705 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2708 cb->ccb_error |= PDMAERR;
2713 cb->ccb_error |= (BUSYERR | STATERR);
2717 cb->ccb_error |= (STATERR | ABORTIO);
2722 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2725 cb->ccb_flags |= CCB_SENSE;
2728 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2733 cb->ccb_error |= FATALIO;
2739 if (cb->ccb_flags & CCB_SENSE)
2741 cb->ccb_error |= (SENSEERR | ABORTIO);
2743 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2747 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2749 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2753 /* check a ccb msgout flag */
2754 if (cb->ccb_omsgoutflag != 0)
2756 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2757 SCSI_LOW_MSG_ABORT_QTAG | \
2758 SCSI_LOW_MSG_CLEAR_QTAG | \
2759 SCSI_LOW_MSG_TERMIO)
2761 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2763 cb->ccb_error |= ABORTIO;
2767 /* call OS depend done */
2768 if (cb->osdep != NULL)
2770 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2771 if (rv == EJUSTRETURN)
2774 else if (cb->ccb_error != 0)
2776 if (cb->ccb_rcnt >= slp->sl_max_retry)
2777 cb->ccb_error |= ABORTIO;
2779 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2780 (cb->ccb_error & ABORTIO) == 0)
2784 /* free our target */
2785 #ifdef SCSI_LOW_DEBUG
2786 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2788 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2789 scsi_low_print(slp, NULL);
2791 #endif /* SCSI_LOW_DEBUG */
2793 scsi_low_deactivate_qtag(cb);
2794 scsi_low_dealloc_qtag(cb);
2795 scsi_low_free_ccb(cb);
2797 return SCSI_LOW_DONE_COMPLETE;
2800 #ifdef SCSI_LOW_DEBUG
2801 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2803 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2804 scsi_low_print(slp, NULL);
2806 #endif /* SCSI_LOW_DEBUG */
2809 scsi_low_deactivate_qtag(cb);
2810 scsi_low_ccb_message_retry(cb);
2811 return SCSI_LOW_DONE_RETRY;
2814 /**************************************************************
2816 **************************************************************/
2818 scsi_low_reset_nexus_target(slp, ti, fdone)
2819 struct scsi_low_softc *slp;
2820 struct targ_info *ti;
2823 struct lun_info *li;
2825 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2826 li = LIST_NEXT(li, lun_chain))
2828 scsi_low_reset_nexus_lun(slp, li, fdone);
2829 li->li_state = SCSI_LOW_LUN_SLEEP;
2834 ti->ti_setup_msg = 0;
2835 ti->ti_setup_msg_done = 0;
2837 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2838 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2840 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2841 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2843 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2845 ((*slp->sl_funcs->scsi_low_targ_init)
2846 (slp, ti, SCSI_LOW_INFO_REVOKE));
2848 scsi_low_calcf_target(ti);
2850 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2851 li = LIST_NEXT(li, lun_chain))
2855 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2856 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2858 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2860 ((*slp->sl_funcs->scsi_low_lun_init)
2861 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2863 scsi_low_calcf_lun(li);
2868 scsi_low_reset_nexus(slp, fdone)
2869 struct scsi_low_softc *slp;
2872 struct targ_info *ti;
2873 struct slccb *cb, *topcb;
2875 if ((cb = slp->sl_Qnexus) != NULL)
2877 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2884 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2885 ti = TAILQ_NEXT(ti, ti_chain))
2887 scsi_low_reset_nexus_target(slp, ti, fdone);
2888 scsi_low_bus_release(slp, ti);
2889 scsi_low_init_msgsys(slp, ti);
2894 topcb->ccb_flags |= CCB_STARTQ;
2895 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2899 slp->sl_retry_sel = 0;
2900 slp->sl_flags &= ~HW_PDMASTART;
2905 static char tw_chars[] = "|/-\\";
2906 #define TWIDDLEWAIT 10000
2909 scsi_low_twiddle_wait(void)
2913 cnputc(tw_chars[tw_pos++]);
2914 tw_pos %= (sizeof(tw_chars) - 1);
2915 SCSI_LOW_DELAY(TWIDDLEWAIT);
2919 scsi_low_bus_reset(slp)
2920 struct scsi_low_softc *slp;
2924 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2926 printf("%s: try to reset scsi bus ", slp->sl_xname);
2927 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2928 scsi_low_twiddle_wait();
2934 scsi_low_restart(slp, flags, s)
2935 struct scsi_low_softc *slp;
2942 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2944 if ((error = scsi_low_init(slp, flags)) != 0)
2947 scsi_low_start(slp);
2951 /**************************************************************
2952 * disconnect and reselect
2953 **************************************************************/
2954 #define MSGCMD_LUN(msg) (msg & 0x07)
2956 static struct slccb *
2957 scsi_low_establish_ccb(ti, li, tag)
2958 struct targ_info *ti;
2959 struct lun_info *li;
2962 struct scsi_low_softc *slp = ti->ti_sc;
2968 cb = TAILQ_FIRST(&li->li_discq);
2969 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2970 if (cb->ccb_tag == tag)
2975 * establish our ccb nexus
2978 #ifdef SCSI_LOW_DEBUG
2979 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2981 printf("%s: nexus(0x%lx) abort check start\n",
2982 slp->sl_xname, (u_long) cb);
2983 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2984 scsi_low_revoke_ccb(slp, cb, 1);
2988 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2990 if (cb->ccb_omsgoutflag == 0)
2991 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2993 #endif /* SCSI_LOW_DEBUG */
2995 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2996 cb->ccb_flags &= ~CCB_DISCQ;
2997 slp->sl_Qnexus = cb;
2999 slp->sl_scp = cb->ccb_sscp;
3000 slp->sl_error |= cb->ccb_error;
3006 /* inform "ccb nexus established" to the host driver */
3007 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3010 if (cb->ccb_msgoutflag != 0)
3012 scsi_low_ccb_message_exec(slp, cb);
3019 scsi_low_reselected(slp, targ)
3020 struct scsi_low_softc *slp;
3023 struct targ_info *ti;
3028 * Check select vs reselected collision.
3031 if ((cb = slp->sl_selid) != NULL)
3033 scsi_low_arbit_fail(slp, cb);
3034 #ifdef SCSI_LOW_STATICS
3035 scsi_low_statics.nexus_conflict ++;
3036 #endif /* SCSI_LOW_STATICS */
3040 * Check if no current active nexus.
3042 if (slp->sl_Tnexus != NULL)
3049 * Check a valid target id asserted ?
3051 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3053 s = "scsi id illegal";
3058 * Check the target scsi status.
3060 ti = slp->sl_ti[targ];
3061 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3063 s = "phase mismatch";
3071 scsi_low_init_msgsys(slp, ti);
3074 * Establish our target nexus
3076 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3077 slp->sl_Tnexus = ti;
3078 #ifdef SCSI_LOW_STATICS
3079 scsi_low_statics.nexus_reselected ++;
3080 #endif /* SCSI_LOW_STATICS */
3084 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3085 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3086 "reselect: scsi world confused");
3090 /**************************************************************
3091 * cmd out pointer setup
3092 **************************************************************/
3094 scsi_low_cmd(slp, ti)
3095 struct scsi_low_softc *slp;
3096 struct targ_info *ti;
3098 struct slccb *cb = slp->sl_Qnexus;
3100 slp->sl_ph_count ++;
3106 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3107 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3108 slp->sl_scp.scp_datalen = 0;
3109 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3110 slp->sl_error |= FATALIO;
3111 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3112 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3117 #ifdef SCSI_LOW_DEBUG
3118 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3120 scsi_low_test_cmdlnk(slp, cb);
3122 #endif /* SCSI_LOW_DEBUG */
3127 /**************************************************************
3128 * data out pointer setup
3129 **************************************************************/
3131 scsi_low_data(slp, ti, bp, direction)
3132 struct scsi_low_softc *slp;
3133 struct targ_info *ti;
3137 struct slccb *cb = slp->sl_Qnexus;
3139 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3145 slp->sl_error |= (FATALIO | PDMAERR);
3146 slp->sl_scp.scp_datalen = 0;
3147 slp->sl_scp.scp_direction = direction;
3148 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3149 if (ti->ti_ophase != ti->ti_phase)
3154 s = "DATA PHASE: ccb nexus not found";
3156 s = "DATA PHASE: xfer direction mismatch";
3157 SCSI_LOW_INFO(slp, ti, s);
3164 /**************************************************************
3166 **************************************************************/
3167 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3168 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3169 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3170 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3171 #define MSGIN_DATA_LAST 0x30
3173 static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int);
3174 static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int);
3175 static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int);
3176 static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int);
3178 static int scsi_low_msgfunc_synch(struct scsi_low_softc *);
3179 static int scsi_low_msgfunc_wide(struct scsi_low_softc *);
3180 static int scsi_low_msgfunc_identify(struct scsi_low_softc *);
3181 static int scsi_low_msgfunc_abort(struct scsi_low_softc *);
3182 static int scsi_low_msgfunc_qabort(struct scsi_low_softc *);
3183 static int scsi_low_msgfunc_qtag(struct scsi_low_softc *);
3184 static int scsi_low_msgfunc_reset(struct scsi_low_softc *);
3186 struct scsi_low_msgout_data {
3189 int (*md_msgfunc)(struct scsi_low_softc *);
3190 int (*md_errfunc)(struct scsi_low_softc *, u_int);
3191 #define MSG_RELEASE_ATN 0x0001
3195 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3196 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3197 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3198 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3199 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3200 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3201 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3202 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3203 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3204 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3205 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3206 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3207 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3208 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3209 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3210 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3211 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3214 static int scsi_low_msginfunc_ext(struct scsi_low_softc *);
3215 static int scsi_low_synch(struct scsi_low_softc *);
3216 static int scsi_low_wide(struct scsi_low_softc *);
3217 static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *);
3218 static int scsi_low_msginfunc_rejop(struct scsi_low_softc *);
3219 static int scsi_low_msginfunc_rp(struct scsi_low_softc *);
3220 static int scsi_low_msginfunc_sdp(struct scsi_low_softc *);
3221 static int scsi_low_msginfunc_disc(struct scsi_low_softc *);
3222 static int scsi_low_msginfunc_cc(struct scsi_low_softc *);
3223 static int scsi_low_msginfunc_lcc(struct scsi_low_softc *);
3224 static int scsi_low_msginfunc_parity(struct scsi_low_softc *);
3225 static int scsi_low_msginfunc_noop(struct scsi_low_softc *);
3226 static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *);
3227 static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *);
3229 struct scsi_low_msgin_data {
3231 int (*md_msgfunc)(struct scsi_low_softc *);
3234 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3235 /* 0 */ {1, scsi_low_msginfunc_cc},
3236 /* 1 */ {2, scsi_low_msginfunc_ext},
3237 /* 2 */ {1, scsi_low_msginfunc_sdp},
3238 /* 3 */ {1, scsi_low_msginfunc_rp},
3239 /* 4 */ {1, scsi_low_msginfunc_disc},
3240 /* 5 */ {1, scsi_low_msginfunc_rejop},
3241 /* 6 */ {1, scsi_low_msginfunc_rejop},
3242 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
3243 /* 8 */ {1, scsi_low_msginfunc_noop},
3244 /* 9 */ {1, scsi_low_msginfunc_parity},
3245 /* a */ {1, scsi_low_msginfunc_lcc},
3246 /* b */ {1, scsi_low_msginfunc_lcc},
3247 /* c */ {1, scsi_low_msginfunc_rejop},
3248 /* d */ {2, scsi_low_msginfunc_rejop},
3249 /* e */ {1, scsi_low_msginfunc_rejop},
3250 /* f */ {1, scsi_low_msginfunc_rejop},
3251 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
3252 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
3253 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
3254 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
3255 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
3256 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
3257 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
3258 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
3259 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
3260 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
3261 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
3262 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
3263 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
3264 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
3265 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
3266 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
3267 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3268 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
3269 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
3270 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3271 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
3272 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
3273 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
3274 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
3275 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
3276 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
3277 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
3278 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
3279 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
3280 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
3281 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
3282 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
3283 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3286 /**************************************************************
3288 **************************************************************/
3290 scsi_low_msgfunc_synch(slp)
3291 struct scsi_low_softc *slp;
3293 struct targ_info *ti = slp->sl_Tnexus;
3294 int ptr = ti->ti_msgoutlen;
3296 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3297 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3298 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3299 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3300 return MSG_EXTEND_SYNCHLEN + 2;
3304 scsi_low_msgfunc_wide(slp)
3305 struct scsi_low_softc *slp;
3307 struct targ_info *ti = slp->sl_Tnexus;
3308 int ptr = ti->ti_msgoutlen;
3310 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3311 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3312 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3313 return MSG_EXTEND_WIDELEN + 2;
3317 scsi_low_msgfunc_identify(slp)
3318 struct scsi_low_softc *slp;
3320 struct targ_info *ti = slp->sl_Tnexus;
3321 struct lun_info *li = slp->sl_Lnexus;
3322 struct slccb *cb = slp->sl_Qnexus;
3323 int ptr = ti->ti_msgoutlen;
3329 slp->sl_error |= FATALIO;
3330 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3331 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3335 if (scsi_low_is_disconnect_ok(cb) != 0)
3336 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3340 if (ti->ti_phase == PH_MSGOUT)
3342 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3343 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3345 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3349 ti->ti_msgoutstr[ptr + 0] = msg;
3354 scsi_low_msgfunc_abort(slp)
3355 struct scsi_low_softc *slp;
3358 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3363 scsi_low_msgfunc_qabort(slp)
3364 struct scsi_low_softc *slp;
3367 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3372 scsi_low_msgfunc_reset(slp)
3373 struct scsi_low_softc *slp;
3376 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3381 scsi_low_msgfunc_qtag(slp)
3382 struct scsi_low_softc *slp;
3384 struct targ_info *ti = slp->sl_Tnexus;
3385 struct slccb *cb = slp->sl_Qnexus;
3386 int ptr = ti->ti_msgoutlen;
3388 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3390 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3395 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3396 if (ti->ti_phase == PH_MSGOUT)
3398 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3405 * The following functions are called when targets give unexpected
3406 * responces in msgin (after msgout).
3409 scsi_low_errfunc_identify(slp, msgflags)
3410 struct scsi_low_softc *slp;
3414 if (slp->sl_Lnexus != NULL)
3416 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3417 scsi_low_calcf_lun(slp->sl_Lnexus);
3423 scsi_low_errfunc_synch(slp, msgflags)
3424 struct scsi_low_softc *slp;
3427 struct targ_info *ti = slp->sl_Tnexus;
3429 MSGIN_PERIOD(ti) = 0;
3430 MSGIN_OFFSET(ti) = 0;
3431 scsi_low_synch(slp);
3436 scsi_low_errfunc_wide(slp, msgflags)
3437 struct scsi_low_softc *slp;
3440 struct targ_info *ti = slp->sl_Tnexus;
3442 MSGIN_WIDTHP(ti) = 0;
3448 scsi_low_errfunc_qtag(slp, msgflags)
3449 struct scsi_low_softc *slp;
3453 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3455 if (slp->sl_Qnexus != NULL)
3457 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3459 if (slp->sl_Lnexus != NULL)
3461 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3462 scsi_low_calcf_lun(slp->sl_Lnexus);
3464 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3471 scsi_low_msgout(slp, ti, fl)
3472 struct scsi_low_softc *slp;
3473 struct targ_info *ti;
3476 struct scsi_low_msgout_data *mdp;
3479 #ifdef SCSI_LOW_DIAGNOSTIC
3480 if (ti != slp->sl_Tnexus)
3482 scsi_low_print(slp, NULL);
3483 panic("scsi_low_msgout: Target nexus inconsistent");
3485 #endif /* SCSI_LOW_DIAGNOSTIC */
3487 slp->sl_ph_count ++;
3488 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3490 printf("%s: too many phase changes\n", slp->sl_xname);
3491 slp->sl_error |= FATALIO;
3492 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3496 * Scsi phase changes.
3497 * Previously msgs asserted are accepted by our target or
3498 * processed by scsi_low_msgin.
3499 * Thus clear all saved informations.
3501 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3503 ti->ti_omsgflags = 0;
3504 ti->ti_emsgflags = 0;
3506 else if (slp->sl_atten == 0)
3509 * We did not assert attention, however still our target required
3510 * msgs. Resend previous msgs.
3512 ti->ti_msgflags |= ti->ti_omsgflags;
3513 ti->ti_omsgflags = 0;
3514 #ifdef SCSI_LOW_DIAGNOSTIC
3515 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3516 #endif /* SCSI_LOW_DIAGNOSTIC */
3520 * We have no msgs. send MSG_NOOP (OK?)
3522 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3523 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3528 ti->ti_msgoutlen = 0;
3529 slp->sl_clear_atten = 0;
3530 mdp = &scsi_low_msgout_data[0];
3531 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3533 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3535 ti->ti_omsgflags |= mdp->md_flags;
3536 ti->ti_msgflags &= ~mdp->md_flags;
3537 ti->ti_emsgflags = mdp->md_flags;
3539 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3540 if (mdp->md_msgfunc != NULL)
3541 len = (*mdp->md_msgfunc) (slp);
3545 #ifdef SCSI_LOW_DIAGNOSTIC
3546 scsi_low_msg_log_write(&ti->ti_log_msgout,
3547 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3548 #endif /* SCSI_LOW_DIAGNOSTIC */
3550 ti->ti_msgoutlen += len;
3551 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3553 slp->sl_clear_atten = 1;
3557 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3558 ti->ti_msgflags == 0)
3561 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3566 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3567 slp->sl_clear_atten = 1;
3569 return ti->ti_msgoutlen;
3572 /**************************************************************
3574 **************************************************************/
3576 scsi_low_msginfunc_noop(slp)
3577 struct scsi_low_softc *slp;
3584 scsi_low_msginfunc_rejop(slp)
3585 struct scsi_low_softc *slp;
3587 struct targ_info *ti = slp->sl_Tnexus;
3588 u_int8_t msg = ti->ti_msgin[0];
3590 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3591 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3596 scsi_low_msginfunc_cc(slp)
3597 struct scsi_low_softc *slp;
3599 struct lun_info *li;
3601 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3603 /* validate status */
3604 if (slp->sl_Qnexus == NULL)
3607 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3608 li = slp->sl_Lnexus;
3609 switch (slp->sl_scp.scp_status)
3612 li->li_maxnqio = li->li_maxnexus;
3617 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3618 scsi_low_reset_nexus_lun(slp, li, 0);
3626 if (li->li_maxnexus >= li->li_nqio)
3627 li->li_maxnexus = li->li_nqio - 1;
3628 li->li_maxnqio = li->li_maxnexus;
3633 slp->sl_error |= MSGERR;
3643 scsi_low_msginfunc_lcc(slp)
3644 struct scsi_low_softc *slp;
3646 struct targ_info *ti;
3647 struct lun_info *li;
3648 struct slccb *ncb, *cb;
3650 ti = slp->sl_Tnexus;
3651 li = slp->sl_Lnexus;
3652 if ((cb = slp->sl_Qnexus) == NULL)
3655 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3656 switch (slp->sl_scp.scp_status)
3660 li->li_maxnqio = li->li_maxnexus;
3664 slp->sl_error |= MSGERR;
3668 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3671 cb->ccb_error |= slp->sl_error;
3672 if (cb->ccb_error != 0)
3675 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3676 ncb = TAILQ_NEXT(ncb, ccb_chain))
3679 goto cmd_link_start;
3684 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3685 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3689 ncb->ccb_flags &= ~CCB_STARTQ;
3690 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3692 scsi_low_dealloc_qtag(ncb);
3693 ncb->ccb_tag = cb->ccb_tag;
3694 ncb->ccb_otag = cb->ccb_otag;
3695 cb->ccb_tag = SCSI_LOW_UNKTAG;
3696 cb->ccb_otag = SCSI_LOW_UNKTAG;
3697 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3698 panic("%s: linked ccb retried", slp->sl_xname);
3700 slp->sl_Qnexus = ncb;
3701 slp->sl_ph_count = 0;
3704 ncb->ccb_datalen = -1;
3705 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3706 ncb->ccb_flags &= ~CCB_INTERNAL;
3708 scsi_low_init_msgsys(slp, ti);
3710 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3712 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3713 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3714 ncb->ccb_tc = ncb->ccb_tcmax;
3716 /* setup saved scsi data pointer */
3717 ncb->ccb_sscp = ncb->ccb_scp;
3718 slp->sl_scp = ncb->ccb_sscp;
3719 slp->sl_error = ncb->ccb_error;
3721 #ifdef SCSI_LOW_DIAGNOSTIC
3722 scsi_low_msg_log_init(&ti->ti_log_msgin);
3723 scsi_low_msg_log_init(&ti->ti_log_msgout);
3724 #endif /* SCSI_LOW_DIAGNOSTIC */
3729 scsi_low_msginfunc_disc(slp)
3730 struct scsi_low_softc *slp;
3733 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3738 scsi_low_msginfunc_sdp(slp)
3739 struct scsi_low_softc *slp;
3741 struct slccb *cb = slp->sl_Qnexus;
3745 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3746 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3749 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3754 scsi_low_msginfunc_rp(slp)
3755 struct scsi_low_softc *slp;
3758 if (slp->sl_Qnexus != NULL)
3759 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3761 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3767 struct scsi_low_softc *slp;
3769 struct targ_info *ti = slp->sl_Tnexus;
3770 u_int period = 0, offset = 0, speed;
3774 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3775 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3776 MSGIN_OFFSET(ti) == 0)
3778 if ((offset = MSGIN_OFFSET(ti)) != 0)
3779 period = MSGIN_PERIOD(ti);
3780 s = offset ? "synchronous" : "async";
3785 * Target seems to be brain damaged.
3786 * Force async transfer.
3788 ti->ti_maxsynch.period = 0;
3789 ti->ti_maxsynch.offset = 0;
3790 printf("%s: target brain damaged. async transfer\n",
3795 ti->ti_maxsynch.period = period;
3796 ti->ti_maxsynch.offset = offset;
3798 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3802 * Current period and offset are not acceptable
3804 * The adapter changes max synch and max offset.
3806 printf("%s: synch neg failed. retry synch msg neg ...\n",
3811 ti->ti_osynch = ti->ti_maxsynch;
3814 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3818 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3820 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3821 struct slccb *cb = slp->sl_Qnexus;
3823 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3825 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3827 printf("%s(%d:*): <%s> offset %d period %dns ",
3828 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3832 speed = 1000 * 10 / (period * 4);
3833 printf("%d.%d M/s", speed / 10, speed % 10);
3842 struct scsi_low_softc *slp;
3844 struct targ_info *ti = slp->sl_Tnexus;
3847 ti->ti_width = MSGIN_WIDTHP(ti);
3848 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3852 * Current width is not acceptable for our adapter.
3853 * The adapter changes max width.
3855 printf("%s: wide neg failed. retry wide msg neg ...\n",
3860 ti->ti_owidth = ti->ti_width;
3861 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3863 ti->ti_setup_msg_done |=
3864 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3868 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3870 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3871 struct slccb *cb = slp->sl_Qnexus;
3873 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3875 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3877 printf("%s(%d:*): transfer width %d bits\n",
3878 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3884 scsi_low_msginfunc_simple_qtag(slp)
3885 struct scsi_low_softc *slp;
3887 struct targ_info *ti = slp->sl_Tnexus;
3888 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3890 if (slp->sl_Qnexus != NULL)
3892 if (slp->sl_Qnexus->ccb_tag != etag)
3894 slp->sl_error |= FATALIO;
3895 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3896 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3899 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3901 #ifdef SCSI_LOW_DEBUG
3902 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3904 #endif /* SCSI_LOW_DEBUG */
3906 slp->sl_error |= FATALIO;
3907 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3908 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3914 scsi_low_msginfunc_i_wide_residue(slp)
3915 struct scsi_low_softc *slp;
3917 struct targ_info *ti = slp->sl_Tnexus;
3918 struct slccb *cb = slp->sl_Qnexus;
3919 int res = (int) ti->ti_msgin[1];
3921 if (cb == NULL || res <= 0 ||
3922 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3923 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3926 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3929 slp->sl_scp.scp_datalen += res;
3930 slp->sl_scp.scp_data -= res;
3931 scsi_low_data_finish(slp);
3936 scsi_low_msginfunc_ext(slp)
3937 struct scsi_low_softc *slp;
3939 struct slccb *cb = slp->sl_Qnexus;
3940 struct lun_info *li = slp->sl_Lnexus;
3941 struct targ_info *ti = slp->sl_Tnexus;
3945 if (ti->ti_msginptr == 2)
3947 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3951 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3953 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3957 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3958 count = (int) htonl((long) (*ptr));
3959 if(slp->sl_scp.scp_datalen - count < 0 ||
3960 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3963 slp->sl_scp.scp_datalen -= count;
3964 slp->sl_scp.scp_data += count;
3967 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3971 retry = scsi_low_synch(slp);
3972 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3973 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3975 #ifdef SCSI_LOW_DEBUG
3976 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3978 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3980 #endif /* SCSI_LOW_DEBUG */
3983 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3987 retry = scsi_low_wide(slp);
3988 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3989 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3997 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4002 scsi_low_msginfunc_parity(slp)
4003 struct scsi_low_softc *slp;
4005 struct targ_info *ti = slp->sl_Tnexus;
4007 /* only I -> T, invalid! */
4008 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4013 scsi_low_msginfunc_msg_reject(slp)
4014 struct scsi_low_softc *slp;
4016 struct targ_info *ti = slp->sl_Tnexus;
4017 struct scsi_low_msgout_data *mdp;
4020 if (ti->ti_emsgflags != 0)
4022 printf("%s: msg flags [0x%x] rejected\n",
4023 slp->sl_xname, ti->ti_emsgflags);
4024 msgflags = SCSI_LOW_MSG_REJECT;
4025 mdp = &scsi_low_msgout_data[0];
4026 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4028 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4030 ti->ti_emsgflags &= ~mdp->md_flags;
4031 if (mdp->md_errfunc != NULL)
4032 (*mdp->md_errfunc) (slp, msgflags);
4040 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4041 slp->sl_error |= MSGERR;
4047 scsi_low_msgin(slp, ti, c)
4048 struct scsi_low_softc *slp;
4049 struct targ_info *ti;
4052 struct scsi_low_msgin_data *sdp;
4053 struct lun_info *li;
4056 #ifdef SCSI_LOW_DIAGNOSTIC
4057 if (ti != slp->sl_Tnexus)
4059 scsi_low_print(slp, NULL);
4060 panic("scsi_low_msgin: Target nexus inconsistent");
4062 #endif /* SCSI_LOW_DIAGNOSTIC */
4065 * Phase changes, clear the pointer.
4067 if (ti->ti_ophase != ti->ti_phase)
4070 ti->ti_msgin_parity_error = 0;
4072 slp->sl_ph_count ++;
4073 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4075 printf("%s: too many phase changes\n", slp->sl_xname);
4076 slp->sl_error |= FATALIO;
4077 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4082 * Store a current messages byte into buffer and
4083 * wait for the completion of the current msg.
4085 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4086 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4088 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4089 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4093 * Check parity errors.
4095 if ((c & SCSI_LOW_DATA_PE) != 0)
4097 ti->ti_msgin_parity_error ++;
4098 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4102 if (ti->ti_msgin_parity_error != 0)
4106 * Calculate messages length.
4108 msg = ti->ti_msgin[0];
4109 if (msg < MSGIN_DATA_LAST)
4110 sdp = &scsi_low_msgin_data[msg];
4112 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4114 if (ti->ti_msginlen == 0)
4116 ti->ti_msginlen = sdp->md_len;
4122 if (ti->ti_msginptr < ti->ti_msginlen)
4128 if ((msg & MSG_IDENTIFY) == 0)
4130 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4135 li = slp->sl_Lnexus;
4138 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4141 slp->sl_Lnexus = li;
4142 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4146 if (MSGCMD_LUN(msg) != li->li_lun)
4150 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4152 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4154 #ifdef SCSI_LOW_DEBUG
4155 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4159 #endif /* SCSI_LOW_DEBUG */
4167 * Msg process completed, reset msgin pointer and assert ATN if desired.
4170 slp->sl_error |= FATALIO;
4171 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4172 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4175 if (ti->ti_msginptr < ti->ti_msginlen)
4178 #ifdef SCSI_LOW_DIAGNOSTIC
4179 scsi_low_msg_log_write(&ti->ti_log_msgin,
4180 &ti->ti_msgin[0], ti->ti_msginlen);
4181 #endif /* SCSI_LOW_DIAGNOSTIC */
4187 /**********************************************************
4189 **********************************************************/
4191 scsi_low_disconnected(slp, ti)
4192 struct scsi_low_softc *slp;
4193 struct targ_info *ti;
4195 struct slccb *cb = slp->sl_Qnexus;
4197 /* check phase completion */
4198 switch (slp->sl_msgphase)
4201 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4202 scsi_low_msginfunc_cc(slp);
4203 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4207 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4208 scsi_low_msginfunc_cc(slp);
4209 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4213 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4214 scsi_low_msginfunc_cc(slp);
4220 struct lun_info *li;
4223 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4224 cb->ccb_flags |= CCB_DISCQ;
4225 cb->ccb_error |= slp->sl_error;
4231 #ifdef SCSI_LOW_STATICS
4232 scsi_low_statics.nexus_disconnected ++;
4233 #endif /* SCSI_LOW_STATICS */
4235 #ifdef SCSI_LOW_DEBUG
4236 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4238 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4239 scsi_low_print(slp, NULL);
4241 #endif /* SCSI_LOW_DEBUG */
4245 slp->sl_error |= FATALIO;
4246 if (ti->ti_phase == PH_SELSTART)
4247 slp->sl_error |= SELTIMEOUTIO;
4249 slp->sl_error |= UBFERR;
4258 #ifdef SCSI_LOW_DEBUG
4259 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4261 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4262 (cb->ccb_msgoutflag != 0 ||
4263 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4265 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4268 #endif /* SCSI_LOW_DEBUG */
4270 cb->ccb_error |= slp->sl_error;
4271 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4273 cb->ccb_flags |= CCB_STARTQ;
4274 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4279 scsi_low_bus_release(slp, ti);
4280 scsi_low_start(slp);
4284 /**********************************************************
4286 **********************************************************/
4288 scsi_low_alloc_qtag(cb)
4291 struct lun_info *li = cb->li;
4292 scsi_low_tag_t etag;
4294 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4297 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4298 etag = ffs(li->li_qtagbits);
4302 li->li_qtagbits &= ~(1 << (etag - 1));
4303 cb->ccb_otag = etag;
4306 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4307 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4308 if (li->li_qtagarray[li->li_qd] == 0)
4311 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4312 if (li->li_qtagarray[li->li_qd] == 0)
4318 li->li_qtagarray[li->li_qd] ++;
4319 cb->ccb_otag = (li->li_qd ++);
4321 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4325 scsi_low_dealloc_qtag(cb)
4328 struct lun_info *li = cb->li;
4329 scsi_low_tag_t etag;
4331 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4334 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4335 etag = cb->ccb_otag - 1;
4336 #ifdef SCSI_LOW_DIAGNOSTIC
4337 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4338 panic("scsi_low_dealloc_tag: illegal tag");
4339 #endif /* SCSI_LOW_DIAGNOSTIC */
4340 li->li_qtagbits |= (1 << etag);
4342 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4343 etag = cb->ccb_otag;
4344 #ifdef SCSI_LOW_DIAGNOSTIC
4345 if (etag >= SCSI_LOW_MAXNEXUS)
4346 panic("scsi_low_dealloc_tag: illegal tag");
4347 #endif /* SCSI_LOW_DIAGNOSTIC */
4348 li->li_qtagarray[etag] --;
4349 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4351 cb->ccb_otag = SCSI_LOW_UNKTAG;
4355 static struct slccb *
4356 scsi_low_revoke_ccb(slp, cb, fdone)
4357 struct scsi_low_softc *slp;
4361 struct targ_info *ti = cb->ti;
4362 struct lun_info *li = cb->li;
4364 #ifdef SCSI_LOW_DIAGNOSTIC
4365 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4366 (CCB_STARTQ | CCB_DISCQ))
4368 panic("%s: ccb in both queue", slp->sl_xname);
4370 #endif /* SCSI_LOW_DIAGNOSTIC */
4372 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4374 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4377 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4379 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4385 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4386 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4389 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4390 (cb->ccb_flags & CCB_NORETRY) != 0))
4392 cb->ccb_error |= FATALIO;
4393 cb->ccb_flags &= ~CCB_AUTOSENSE;
4394 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4395 panic("%s: done ccb retried", slp->sl_xname);
4400 cb->ccb_error |= PENDINGIO;
4401 scsi_low_deactivate_qtag(cb);
4402 scsi_low_ccb_message_retry(cb);
4403 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4409 scsi_low_reset_nexus_lun(slp, li, fdone)
4410 struct scsi_low_softc *slp;
4411 struct lun_info *li;
4414 struct slccb *cb, *ncb, *ecb;
4420 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4422 ncb = TAILQ_NEXT(cb, ccb_chain);
4423 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4427 * presumely keep ordering of io
4429 cb->ccb_flags |= CCB_STARTQ;
4432 TAILQ_INSERT_HEAD(&slp->sl_start,\
4437 TAILQ_INSERT_AFTER(&slp->sl_start,\
4438 ecb, cb, ccb_chain);
4445 /**************************************************************
4447 **************************************************************/
4449 scsi_low_calcf_lun(li)
4450 struct lun_info *li;
4452 struct targ_info *ti = li->li_ti;
4453 struct scsi_low_softc *slp = ti->ti_sc;
4454 u_int cfgflags, diskflags;
4456 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4457 cfgflags = li->li_cfgflags;
4461 diskflags = li->li_diskflags & li->li_quirks;
4464 li->li_flags &= ~SCSI_LOW_DISC;
4465 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4466 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4467 (cfgflags & SCSI_LOW_DISC) != 0)
4468 li->li_flags |= SCSI_LOW_DISC;
4471 li->li_flags |= SCSI_LOW_NOPARITY;
4472 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4473 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4474 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4475 li->li_flags &= ~SCSI_LOW_NOPARITY;
4478 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4479 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4480 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4482 li->li_flags |= SCSI_LOW_QTAG;
4483 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4484 li->li_maxnqio = li->li_maxnexus;
4488 li->li_flags &= ~SCSI_LOW_QTAG;
4489 li->li_maxnexus = 0;
4490 li->li_maxnqio = li->li_maxnexus;
4494 li->li_flags &= ~SCSI_LOW_LINK;
4495 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4496 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4497 li->li_flags |= SCSI_LOW_LINK;
4499 /* compatible flags */
4500 li->li_flags &= ~SCSI_LOW_SYNC;
4501 if (ti->ti_maxsynch.offset > 0)
4502 li->li_flags |= SCSI_LOW_SYNC;
4504 #ifdef SCSI_LOW_DEBUG
4505 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4507 scsi_low_calcf_show(li);
4509 #endif /* SCSI_LOW_DEBUG */
4513 scsi_low_calcf_target(ti)
4514 struct targ_info *ti;
4516 struct scsi_low_softc *slp = ti->ti_sc;
4517 u_int offset, period, diskflags;
4519 diskflags = ti->ti_diskflags & ti->ti_quirks;
4522 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4523 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4525 offset = ti->ti_maxsynch.offset;
4526 period = ti->ti_maxsynch.period;
4527 if (offset == 0 || period == 0)
4528 offset = period = 0;
4532 offset = period = 0;
4535 ti->ti_maxsynch.offset = offset;
4536 ti->ti_maxsynch.period = period;
4539 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4540 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4541 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4543 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4544 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4545 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4547 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4549 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4550 ti->ti_maxsynch.period != ti->ti_osynch.period)
4551 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4552 if (ti->ti_width != ti->ti_owidth)
4553 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4555 ti->ti_osynch = ti->ti_maxsynch;
4556 ti->ti_owidth = ti->ti_width;
4559 #ifdef SCSI_LOW_DEBUG
4560 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4562 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4563 slp->sl_xname, ti->ti_id,
4564 ti->ti_maxsynch.period * 4,
4565 ti->ti_maxsynch.offset,
4568 #endif /* SCSI_LOW_DEBUG */
4572 scsi_low_calcf_show(li)
4573 struct lun_info *li;
4575 struct targ_info *ti = li->li_ti;
4576 struct scsi_low_softc *slp = ti->ti_sc;
4578 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4579 slp->sl_xname, ti->ti_id, li->li_lun,
4580 ti->ti_maxsynch.period * 4,
4581 ti->ti_maxsynch.offset,
4583 li->li_flags, SCSI_LOW_BITS);
4586 #ifdef SCSI_LOW_START_UP_CHECK
4587 /**************************************************************
4588 * scsi world start up
4589 **************************************************************/
4590 static int scsi_low_poll(struct scsi_low_softc *, struct slccb *);
4593 scsi_low_start_up(slp)
4594 struct scsi_low_softc *slp;
4596 struct targ_info *ti;
4597 struct lun_info *li;
4601 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4603 for (target = 0; target < slp->sl_ntargs; target ++)
4605 if (target == slp->sl_hostid)
4607 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4609 printf("%s: scsi_low: target %d (host card)\n",
4610 slp->sl_xname, target);
4615 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4617 printf("%s: scsi_low: target %d lun ",
4618 slp->sl_xname, target);
4621 ti = slp->sl_ti[target];
4622 for (lun = 0; lun < slp->sl_nluns; lun ++)
4624 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4630 li = scsi_low_alloc_li(ti, lun, 1);
4632 scsi_low_enqueue(slp, ti, li, cb,
4633 CCB_AUTOSENSE | CCB_POLLED, 0);
4635 scsi_low_poll(slp, cb);
4637 if (li->li_state != SCSI_LOW_LUN_OK)
4640 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4646 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4655 scsi_low_poll(slp, cb)
4656 struct scsi_low_softc *slp;
4662 while (slp->sl_nio > 0)
4664 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4666 (*slp->sl_funcs->scsi_low_poll) (slp);
4667 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4671 scsi_low_timeout_check(slp);
4676 #endif /* SCSI_LOW_START_UP_CHECK */
4678 /**********************************************************
4680 **********************************************************/
4681 #ifdef SCSI_LOW_DEBUG
4683 scsi_low_test_abort(slp, ti, li)
4684 struct scsi_low_softc *slp;
4685 struct targ_info *ti;
4686 struct lun_info *li;
4690 if (li->li_disc > 1)
4692 acb = TAILQ_FIRST(&li->li_discq);
4693 if (scsi_low_abort_ccb(slp, acb) == 0)
4695 printf("%s: aborting ccb(0x%lx) start\n",
4696 slp->sl_xname, (u_long) acb);
4702 scsi_low_test_atten(slp, ti, msg)
4703 struct scsi_low_softc *slp;
4704 struct targ_info *ti;
4708 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4709 scsi_low_assert_msg(slp, ti, msg, 0);
4711 printf("%s: atten check OK\n", slp->sl_xname);
4715 scsi_low_test_cmdlnk(slp, cb)
4716 struct scsi_low_softc *slp;
4719 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4721 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4724 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4725 slp->sl_scp.scp_cmdlen);
4726 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4727 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4729 #endif /* SCSI_LOW_DEBUG */
4732 scsi_low_info(slp, ti, s)
4733 struct scsi_low_softc *slp;
4734 struct targ_info *ti;
4739 slp = LIST_FIRST(&sl_tab);
4743 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4746 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4747 ti = TAILQ_NEXT(ti, ti_chain))
4749 scsi_low_print(slp, ti);
4754 scsi_low_print(slp, ti);
4758 static u_char *phase[] =
4760 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4761 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4765 scsi_low_print(slp, ti)
4766 struct scsi_low_softc *slp;
4767 struct targ_info *ti;
4769 struct lun_info *li;
4773 if (ti == NULL || ti == slp->sl_Tnexus)
4775 ti = slp->sl_Tnexus;
4776 li = slp->sl_Lnexus;
4777 cb = slp->sl_Qnexus;
4781 li = LIST_FIRST(&ti->ti_litab);
4782 cb = TAILQ_FIRST(&li->li_discq);
4786 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4787 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4793 u_int flags = 0, maxnqio = 0, nqio = 0;
4799 flags = li->li_flags;
4800 maxnqio = li->li_maxnqio;
4804 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4806 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4807 phase[(int) ti->ti_phase], ti->ti_disc,
4812 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4813 (u_int) cb->ccb_scp.scp_cmd[0],
4814 cb->ccb_scp.scp_cmdlen,
4816 cb->ccb_scp.scp_datalen,
4817 (u_int) cb->ccb_sscp.scp_status,
4818 cb->ccb_error, SCSI_LOW_ERRORBITS);
4821 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4822 (u_int) (ti->ti_msginptr),
4823 (u_int) (ti->ti_msgin[0]),
4824 (u_int) (ti->ti_msgin[1]),
4825 (u_int) (ti->ti_msgin[2]),
4826 (u_int) (ti->ti_msgin[3]),
4827 (u_int) (ti->ti_msgin[4]),
4830 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4831 (u_int) ti->ti_msgflags,
4832 (u_int) (ti->ti_msgoutstr[0]),
4833 (u_int) (ti->ti_msgoutstr[1]),
4834 (u_int) (ti->ti_msgoutstr[2]),
4835 (u_int) (ti->ti_msgoutstr[3]),
4836 (u_int) (ti->ti_msgoutstr[4]),
4838 flags, SCSI_LOW_BITS);
4840 #ifdef SCSI_LOW_DIAGNOSTIC
4841 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4842 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4843 #endif /* SCSI_LOW_DIAGNOSTIC */
4847 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4848 (u_long) sp->scp_data,
4850 (u_int) sp->scp_status,
4851 slp->sl_error, SCSI_LOW_ERRORBITS);