2 * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $
3 * $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.6 2003/12/29 23:31:00 dillon Exp $
4 * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $
7 #define SCSI_LOW_STATICS
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define SCSI_LOW_START_UP_CHECK
12 /* #define SCSI_LOW_INFO_DETAIL */
13 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
14 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
17 #define SCSI_LOW_TARGET_OPEN
18 #endif /* __NetBSD__ */
21 #define SCSI_LOW_FLAGS_QUIRKS_OK
22 #endif /* __FreeBSD__ */
25 * [NetBSD for NEC PC-98 series]
26 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
27 * NetBSD/pc98 porting staff. All rights reserved.
28 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
29 * Naofumi HONDA. All rights reserved.
31 * [Ported for FreeBSD CAM]
32 * Copyright (c) 2000, 2001
33 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. The name of the author may not be used to endorse or promote products
45 * derived from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
49 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
50 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
51 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
53 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
55 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
56 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
57 * POSSIBILITY OF SUCH DAMAGE.
60 /* <On the nexus establishment>
61 * When our host is reselected,
62 * nexus establish processes are little complicated.
63 * Normal steps are followings:
64 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
65 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
66 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
70 #include <sys/param.h>
71 #include <sys/systm.h>
72 #include <sys/kernel.h>
75 #if __FreeBSD_version >= 500001
78 #include <machine/clock.h>
80 #include <sys/devicestat.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_ccb.h"
111 #include "../cam_sim.h"
112 #include "../cam_debug.h"
113 #include "../cam_periph.h"
115 #include "scsi_all.h"
116 #include "scsi_message.h"
118 #include "scsi_low.h"
120 #include <sys/cons.h>
121 #endif /* __FreeBSD__ */
123 /**************************************************************
125 **************************************************************/
126 #define SCSI_LOW_POLL_HZ 1000
128 /* functions return values */
129 #define SCSI_LOW_START_NO_QTAG 0
130 #define SCSI_LOW_START_QTAG 1
132 #define SCSI_LOW_DONE_COMPLETE 0
133 #define SCSI_LOW_DONE_RETRY 1
135 /* internal disk flags */
136 #define SCSI_LOW_DISK_DISC 0x00000001
137 #define SCSI_LOW_DISK_QTAG 0x00000002
138 #define SCSI_LOW_DISK_LINK 0x00000004
139 #define SCSI_LOW_DISK_PARITY 0x00000008
140 #define SCSI_LOW_DISK_SYNC 0x00010000
141 #define SCSI_LOW_DISK_WIDE_16 0x00020000
142 #define SCSI_LOW_DISK_WIDE_32 0x00040000
143 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
144 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
145 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
147 /**************************************************************
149 **************************************************************/
150 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
151 static void scsi_low_engage (void *);
152 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
153 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
154 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
155 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
156 static void scsi_low_twiddle_wait (void);
157 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
158 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
159 static void scsi_low_calcf_lun (struct lun_info *);
160 static void scsi_low_calcf_target (struct targ_info *);
161 static void scsi_low_calcf_show (struct lun_info *);
162 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
163 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
164 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
165 static int scsi_low_init (struct scsi_low_softc *, u_int);
166 static void scsi_low_start (struct scsi_low_softc *);
167 static void scsi_low_free_ti (struct scsi_low_softc *);
169 static int scsi_low_alloc_qtag (struct slccb *);
170 static int scsi_low_dealloc_qtag (struct slccb *);
171 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
172 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
173 static void scsi_low_unit_ready_cmd (struct slccb *);
174 static void scsi_low_timeout (void *);
175 static int scsi_low_timeout_check (struct scsi_low_softc *);
176 #ifdef SCSI_LOW_START_UP_CHECK
177 static int scsi_low_start_up (struct scsi_low_softc *);
178 #endif /* SCSI_LOW_START_UP_CHECK */
179 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
180 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
182 int scsi_low_version_major = 2;
183 int scsi_low_version_minor = 17;
185 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
187 /**************************************************************
188 * Debug, Run test and Statics
189 **************************************************************/
190 #ifdef SCSI_LOW_INFO_DETAIL
191 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
192 #else /* !SCSI_LOW_INFO_DETAIL */
193 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
194 #endif /* !SCSI_LOW_INFO_DETAIL */
196 #ifdef SCSI_LOW_STATICS
197 struct scsi_low_statics {
200 int nexus_disconnected;
201 int nexus_reselected;
204 #endif /* SCSI_LOW_STATICS */
206 #ifdef SCSI_LOW_DEBUG
207 #define SCSI_LOW_DEBUG_DONE 0x00001
208 #define SCSI_LOW_DEBUG_DISC 0x00002
209 #define SCSI_LOW_DEBUG_SENSE 0x00004
210 #define SCSI_LOW_DEBUG_CALCF 0x00008
211 #define SCSI_LOW_DEBUG_ACTION 0x10000
212 int scsi_low_debug = 0;
214 #define SCSI_LOW_MAX_ATTEN_CHECK 32
215 #define SCSI_LOW_ATTEN_CHECK 0x0001
216 #define SCSI_LOW_CMDLNK_CHECK 0x0002
217 #define SCSI_LOW_ABORT_CHECK 0x0004
218 #define SCSI_LOW_NEXUS_CHECK 0x0008
219 int scsi_low_test = 0;
220 int scsi_low_test_id = 0;
222 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
223 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
224 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
225 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
226 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
227 #define SCSI_LOW_DEBUG_GO(fl, id) \
228 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
229 #endif /* SCSI_LOW_DEBUG */
231 /**************************************************************
233 **************************************************************/
234 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
235 GENERIC_CCB(scsi_low, slccb, ccb_chain)
237 /**************************************************************
239 **************************************************************/
240 #define SCSI_LOW_INLINE static __inline
241 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
242 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
243 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
244 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
245 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
246 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
247 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
250 scsi_low_activate_qtag(cb)
253 struct lun_info *li = cb->li;
255 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
259 cb->ccb_tag = cb->ccb_otag;
263 scsi_low_deactivate_qtag(cb)
266 struct lun_info *li = cb->li;
268 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
272 cb->ccb_tag = SCSI_LOW_UNKTAG;
276 scsi_low_ccb_message_exec(slp, cb)
277 struct scsi_low_softc *slp;
281 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
282 cb->ccb_msgoutflag = 0;
286 scsi_low_ccb_message_assert(cb, msg)
291 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
295 scsi_low_ccb_message_retry(cb)
298 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
302 scsi_low_ccb_message_clear(cb)
305 cb->ccb_msgoutflag = 0;
309 scsi_low_init_msgsys(slp, ti)
310 struct scsi_low_softc *slp;
311 struct targ_info *ti;
315 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
316 SCSI_LOW_DEASSERT_ATN(slp);
317 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
320 /*=============================================================
321 * START OF OS switch (All OS depend fucntions should be here)
322 =============================================================*/
323 /* common os depend utitlities */
324 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
325 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
326 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
328 static u_int8_t scsi_low_cmd_flags[256] = {
329 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
330 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
331 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
332 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
333 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
336 struct scsi_low_error_code {
341 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
342 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
344 static struct slccb *
345 scsi_low_find_ccb(slp, target, lun, osdep)
346 struct scsi_low_softc *slp;
350 struct targ_info *ti;
354 ti = slp->sl_ti[target];
355 li = scsi_low_alloc_li(ti, lun, 0);
359 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
362 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
363 cb = TAILQ_NEXT(cb, ccb_chain))
365 if (cb->osdep == osdep)
369 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
370 cb = TAILQ_NEXT(cb, ccb_chain))
372 if (cb->osdep == osdep)
379 scsi_low_translate_error_code(cb, tp)
381 struct scsi_low_error_code *tp;
384 if (cb->ccb_error == 0)
385 return tp->error_code;
387 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
389 return tp->error_code;
392 #ifdef SCSI_LOW_INTERFACE_XS
393 /**************************************************************
394 * SCSI INTERFACE (XS)
395 **************************************************************/
396 #define SCSI_LOW_MINPHYS 0x10000
397 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
398 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
399 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
400 #define SCSI_LOW_XS_POLL_HZ 1000
402 static int scsi_low_poll_xs (struct scsi_low_softc *, struct slccb *));
403 static void scsi_low_scsi_minphys_xs (struct buf *);
404 #ifdef SCSI_LOW_TARGET_OPEN
405 static int scsi_low_target_open (struct scsipi_link *, struct cfdata *);
406 #endif /* SCSI_LOW_TARGET_OPEN */
407 static int scsi_low_scsi_cmd_xs (struct scsipi_xfer *);
408 static int scsi_low_enable_xs (void *, int);
409 static int scsi_low_ioctl_xs (struct scsipi_link *, u_long, caddr_t, int, struct proc *);
411 static int scsi_low_attach_xs (struct scsi_low_softc *);
412 static int scsi_low_world_start_xs (struct scsi_low_softc *);
413 static int scsi_low_dettach_xs (struct scsi_low_softc *);
414 static int scsi_low_ccb_setup_xs (struct scsi_low_softc *, struct slccb *);
415 static int scsi_low_done_xs (struct scsi_low_softc *, struct slccb *);
416 static void scsi_low_timeout_xs (struct scsi_low_softc *, int, int);
417 static u_int scsi_low_translate_quirks_xs (u_int);
418 static void scsi_low_setup_quirks_xs (struct targ_info *, struct lun_info *, u_int);
420 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
422 scsi_low_world_start_xs,
424 scsi_low_ccb_setup_xs,
429 struct scsipi_device scsi_low_dev = {
430 NULL, /* Use default error handler */
431 NULL, /* have a queue, served by this */
432 NULL, /* have no async handler */
433 NULL, /* Use default 'done' routine */
436 struct scsi_low_error_code scsi_low_error_code_xs[] = {
440 {SELTIMEOUTIO, XS_SELTIMEOUT},
441 {TIMEOUTIO, XS_TIMEOUT},
442 {-1, XS_DRIVER_STUFFUP}
446 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
447 struct scsipi_link *link;
453 struct scsi_low_softc *slp;
454 int s, error = ENOTTY;
456 slp = (struct scsi_low_softc *) link->adapter_softc;
457 if ((slp->sl_flags & HW_INACTIVE) != 0)
460 if (cmd == SCBUSIORESET)
462 s = SCSI_LOW_SPLSCSI();
463 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
467 else if (slp->sl_funcs->scsi_low_ioctl != 0)
469 error = (*slp->sl_funcs->scsi_low_ioctl)
470 (slp, cmd, addr, flag, p);
477 scsi_low_enable_xs(arg, enable)
481 struct scsi_low_softc *slp = arg;
485 if ((slp->sl_flags & HW_INACTIVE) != 0)
490 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
491 (slp->sl_flags & HW_POWERCTRL) == 0)
494 slp->sl_flags |= HW_POWDOWN;
495 if (slp->sl_funcs->scsi_low_power != NULL)
497 (*slp->sl_funcs->scsi_low_power)
498 (slp, SCSI_LOW_POWDOWN);
505 scsi_low_scsi_minphys_xs(bp)
509 if (bp->b_bcount > SCSI_LOW_MINPHYS)
510 bp->b_bcount = SCSI_LOW_MINPHYS;
515 scsi_low_poll_xs(slp, cb)
516 struct scsi_low_softc *slp;
519 struct scsipi_xfer *xs = cb->osdep;
522 cb->ccb_flags |= CCB_NOSDONE;
525 while (slp->sl_nio > 0)
527 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
529 (*slp->sl_funcs->scsi_low_poll) (slp);
531 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
533 cb->ccb_flags |= CCB_NORETRY;
534 cb->ccb_error |= FATALIO;
535 (void) scsi_low_revoke_ccb(slp, cb, 1);
536 printf("%s: hardware inactive in poll mode\n",
540 if ((xs->flags & ITSDONE) != 0)
543 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
547 scsi_low_timeout_check(slp);
550 xs->flags |= ITSDONE;
556 scsi_low_scsi_cmd_xs(xs)
557 struct scsipi_xfer *xs;
559 struct scsipi_link *splp = xs->sc_link;
560 struct scsi_low_softc *slp = splp->adapter_softc;
561 struct targ_info *ti;
564 int s, targ, lun, flags, rv;
566 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
567 return TRY_AGAIN_LATER;
569 targ = splp->scsipi_scsi.target,
570 lun = splp->scsipi_scsi.lun;
571 ti = slp->sl_ti[targ];
576 if ((xs->flags & SCSI_POLL) == 0)
577 flags = CCB_AUTOSENSE;
579 flags = CCB_AUTOSENSE | CCB_POLLED;
582 s = SCSI_LOW_SPLSCSI();
583 li = scsi_low_alloc_li(ti, lun, 1);
584 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
586 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
589 if ((xs->flags & SCSI_RESET) != 0)
591 flags |= CCB_NORETRY | CCB_URGENT;
592 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
596 if (ti->ti_setup_msg != 0)
598 scsi_low_message_enqueue(slp, ti, li, flags);
602 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
605 #ifdef SCSI_LOW_DEBUG
606 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
608 scsi_low_test_abort(slp, ti, li);
610 #endif /* SCSI_LOW_DEBUG */
612 if ((cb->ccb_flags & CCB_POLLED) != 0)
614 rv = scsi_low_poll_xs(slp, cb);
618 rv = SUCCESSFULLY_QUEUED;
625 scsi_low_attach_xs(slp)
626 struct scsi_low_softc *slp;
628 struct scsipi_adapter *sap;
629 struct scsipi_link *splp;
631 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
633 sap = SCSI_LOW_MALLOC(sizeof(*sap));
636 splp = SCSI_LOW_MALLOC(sizeof(*splp));
640 SCSI_LOW_BZERO(sap, sizeof(*sap));
641 SCSI_LOW_BZERO(splp, sizeof(*splp));
643 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
644 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
645 sap->scsipi_enable = scsi_low_enable_xs;
646 sap->scsipi_ioctl = scsi_low_ioctl_xs;
647 #ifdef SCSI_LOW_TARGET_OPEN
648 sap->open_target_lu = scsi_low_target_open;
649 #endif /* SCSI_LOW_TARGET_OPEN */
651 splp->adapter_softc = slp;
652 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
653 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
654 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
655 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
656 splp->openings = slp->sl_openings;
657 splp->type = BUS_SCSI;
658 splp->adapter_softc = slp;
660 splp->device = &scsi_low_dev;
662 slp->sl_si.si_splp = splp;
663 slp->sl_show_result = SHOW_ALL_NEG;
668 scsi_low_world_start_xs(slp)
669 struct scsi_low_softc *slp;
676 scsi_low_dettach_xs(slp)
677 struct scsi_low_softc *slp;
681 * scsipi does not have dettach bus fucntion.
683 scsipi_dettach_scsibus(slp->sl_si.si_splp);
689 scsi_low_ccb_setup_xs(slp, cb)
690 struct scsi_low_softc *slp;
693 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
695 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
697 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
698 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
699 cb->ccb_scp.scp_data = xs->data;
700 cb->ccb_scp.scp_datalen = xs->datalen;
701 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
702 SCSI_LOW_WRITE : SCSI_LOW_READ;
703 cb->ccb_tcmax = xs->timeout / 1000;
707 scsi_low_unit_ready_cmd(cb);
709 return SCSI_LOW_START_QTAG;
713 scsi_low_done_xs(slp, cb)
714 struct scsi_low_softc *slp;
717 struct scsipi_xfer *xs;
719 xs = (struct scsipi_xfer *) cb->osdep;
720 if (cb->ccb_error == 0)
722 xs->error = XS_NOERROR;
727 if (cb->ccb_rcnt >= slp->sl_max_retry)
728 cb->ccb_error |= ABORTIO;
730 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
731 (cb->ccb_error & ABORTIO) == 0)
734 if ((cb->ccb_error & SENSEIO) != 0)
736 xs->sense.scsi_sense = cb->ccb_sense;
739 xs->error = scsi_low_translate_error_code(cb,
740 &scsi_low_error_code_xs[0]);
742 #ifdef SCSI_LOW_DIAGNOSTIC
743 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
744 cb->ccb_scp.scp_cmdlen > 0 &&
745 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
746 SCSI_LOW_CMD_ABORT_WARNING) != 0)
748 printf("%s: WARNING: scsi_low IO abort\n",
750 scsi_low_print(slp, NULL);
752 #endif /* SCSI_LOW_DIAGNOSTIC */
755 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
756 xs->status = 0; /* XXX */
758 xs->status = cb->ccb_scp.scp_status;
760 xs->flags |= ITSDONE;
761 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
768 scsi_low_timeout_xs(slp, ch, action)
769 struct scsi_low_softc *slp;
776 case SCSI_LOW_TIMEOUT_CH_IO:
779 case SCSI_LOW_TIMEOUT_START:
780 timeout(scsi_low_timeout, slp,
781 hz / SCSI_LOW_TIMEOUT_HZ);
783 case SCSI_LOW_TIMEOUT_STOP:
784 untimeout(scsi_low_timeout, slp);
789 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
792 case SCSI_LOW_TIMEOUT_START:
793 timeout(scsi_low_engage, slp, 1);
795 case SCSI_LOW_TIMEOUT_STOP:
796 untimeout(scsi_low_engage, slp);
801 case SCSI_LOW_TIMEOUT_CH_RECOVER:
807 scsi_low_translate_quirks_xs(quirks)
812 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
815 if (quirks & SDEV_NODISC)
816 flags &= ~SCSI_LOW_DISK_DISC;
817 #endif /* SDEV_NODISC */
819 if (quirks & SDEV_NOPARITY)
820 flags &= ~SCSI_LOW_DISK_PARITY;
821 #endif /* SDEV_NOPARITY */
823 if (quirks & SDEV_NOCMDLNK)
824 flags &= ~SCSI_LOW_DISK_LINK;
825 #endif /* SDEV_NOCMDLNK */
827 if (quirks & SDEV_NOTAG)
828 flags &= ~SCSI_LOW_DISK_QTAG;
829 #endif /* SDEV_NOTAG */
831 if (quirks & SDEV_NOSYNC)
832 flags &= ~SCSI_LOW_DISK_SYNC;
833 #endif /* SDEV_NOSYNC */
839 scsi_low_setup_quirks_xs(ti, li, flags)
840 struct targ_info *ti;
846 li->li_sloi.sloi_quirks = flags;
847 quirks = scsi_low_translate_quirks_xs(flags);
848 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
849 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
850 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
851 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
852 scsi_low_calcf_target(ti);
853 scsi_low_calcf_lun(li);
854 scsi_low_calcf_show(li);
857 #ifdef SCSI_LOW_TARGET_OPEN
859 scsi_low_target_open(link, cf)
860 struct scsipi_link *link;
863 u_int target = link->scsipi_scsi.target;
864 u_int lun = link->scsipi_scsi.lun;
865 struct scsi_low_softc *slp;
866 struct targ_info *ti;
869 slp = (struct scsi_low_softc *) link->adapter_softc;
870 ti = slp->sl_ti[target];
871 li = scsi_low_alloc_li(ti, lun, 0);
875 li->li_cfgflags = cf->cf_flags;
876 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
879 #endif /* SCSI_LOW_TARGET_OPEN */
881 #endif /* SCSI_LOW_INTERFACE_XS */
883 #ifdef SCSI_LOW_INTERFACE_CAM
884 /**************************************************************
885 * SCSI INTERFACE (CAM)
886 **************************************************************/
887 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
888 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
889 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
891 static void scsi_low_poll_cam (struct cam_sim *);
892 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
893 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
894 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
896 static int scsi_low_attach_cam (struct scsi_low_softc *);
897 static int scsi_low_world_start_cam (struct scsi_low_softc *);
898 static int scsi_low_dettach_cam (struct scsi_low_softc *);
899 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
900 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
901 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
903 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
905 scsi_low_world_start_cam,
906 scsi_low_dettach_cam,
907 scsi_low_ccb_setup_cam,
912 struct scsi_low_error_code scsi_low_error_code_cam[] = {
914 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
915 {SENSEERR, CAM_AUTOSENSE_FAIL},
916 {UACAERR, CAM_SCSI_STATUS_ERROR},
917 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
918 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
919 {TIMEOUTIO, CAM_CMD_TIMEOUT},
920 {PDMAERR, CAM_DATA_RUN_ERR},
921 {PARITYERR, CAM_UNCOR_PARITY},
922 {UBFERR, CAM_UNEXP_BUSFREE},
923 {ABORTIO, CAM_REQ_ABORTED},
924 {-1, CAM_UNREC_HBA_ERROR}
927 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
930 * Please check a polling hz, currently we assume scsi_low_poll() is
933 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
936 scsi_low_poll_cam(sim)
939 struct scsi_low_softc *slp = SIM2SLP(sim);
941 (*slp->sl_funcs->scsi_low_poll) (slp);
943 if (slp->sl_si.si_poll_count ++ >=
944 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
946 slp->sl_si.si_poll_count = 0;
947 scsi_low_timeout_check(slp);
952 scsi_low_cam_rescan_callback(periph, ccb)
953 struct cam_periph *periph;
957 xpt_free_path(ccb->ccb_h.path);
962 scsi_low_rescan_bus_cam(slp)
963 struct scsi_low_softc *slp;
965 struct cam_path *path;
966 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
969 bzero(ccb, sizeof(union ccb));
971 status = xpt_create_path(&path, xpt_periph,
972 cam_sim_path(slp->sl_si.sim), -1, 0);
973 if (status != CAM_REQ_CMP)
976 xpt_setup_ccb(&ccb->ccb_h, path, 5);
977 ccb->ccb_h.func_code = XPT_SCAN_BUS;
978 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
979 ccb->crcn.flags = CAM_FLAG_NONE;
984 scsi_low_scsi_action_cam(sim, ccb)
988 struct scsi_low_softc *slp = SIM2SLP(sim);
989 struct targ_info *ti;
992 u_int lun, flags, msg, target;
995 target = (u_int) (ccb->ccb_h.target_id);
996 lun = (u_int) ccb->ccb_h.target_lun;
998 #ifdef SCSI_LOW_DEBUG
999 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
1001 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
1002 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1004 #endif /* SCSI_LOW_DEBUG */
1006 switch (ccb->ccb_h.func_code) {
1007 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1008 #ifdef SCSI_LOW_DIAGNOSTIC
1009 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1011 printf("%s: invalid target/lun\n", slp->sl_xname);
1012 ccb->ccb_h.status = CAM_REQ_INVALID;
1016 #endif /* SCSI_LOW_DIAGNOSTIC */
1018 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1019 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1024 ti = slp->sl_ti[target];
1027 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1028 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1032 s = SCSI_LOW_SPLSCSI();
1033 li = scsi_low_alloc_li(ti, lun, 1);
1035 if (ti->ti_setup_msg != 0)
1037 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1040 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1042 #ifdef SCSI_LOW_DEBUG
1043 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1045 scsi_low_test_abort(slp, ti, li);
1047 #endif /* SCSI_LOW_DEBUG */
1051 case XPT_EN_LUN: /* Enable LUN as a target */
1052 case XPT_TARGET_IO: /* Execute target I/O request */
1053 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1054 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1056 ccb->ccb_h.status = CAM_REQ_INVALID;
1060 case XPT_ABORT: /* Abort the specified CCB */
1061 #ifdef SCSI_LOW_DIAGNOSTIC
1062 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1064 printf("%s: invalid target/lun\n", slp->sl_xname);
1065 ccb->ccb_h.status = CAM_REQ_INVALID;
1069 #endif /* SCSI_LOW_DIAGNOSTIC */
1071 s = SCSI_LOW_SPLSCSI();
1072 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1073 rv = scsi_low_abort_ccb(slp, cb);
1077 ccb->ccb_h.status = CAM_REQ_CMP;
1079 ccb->ccb_h.status = CAM_REQ_INVALID;
1083 case XPT_SET_TRAN_SETTINGS: {
1084 struct ccb_trans_settings *cts;
1087 #ifdef SCSI_LOW_DIAGNOSTIC
1088 if (target == CAM_TARGET_WILDCARD)
1090 printf("%s: invalid target\n", slp->sl_xname);
1091 ccb->ccb_h.status = CAM_REQ_INVALID;
1095 #endif /* SCSI_LOW_DIAGNOSTIC */
1097 ti = slp->sl_ti[target];
1098 if (lun == CAM_LUN_WILDCARD)
1101 s = SCSI_LOW_SPLSCSI();
1102 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
1103 CCB_TRANS_SYNC_RATE_VALID |
1104 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
1106 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
1107 val = cts->bus_width;
1108 if (val < ti->ti_width)
1111 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
1112 val = cts->sync_period;
1113 if (val == 0 || val > ti->ti_maxsynch.period)
1114 ti->ti_maxsynch.period = val;
1116 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
1117 val = cts->sync_offset;
1118 if (val < ti->ti_maxsynch.offset)
1119 ti->ti_maxsynch.offset = val;
1122 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1123 scsi_low_calcf_target(ti);
1126 if ((cts->valid & (CCB_TRANS_DISC_VALID |
1127 CCB_TRANS_TQ_VALID)) != 0)
1129 li = scsi_low_alloc_li(ti, lun, 1);
1130 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
1132 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
1133 li->li_quirks |= SCSI_LOW_DISK_DISC;
1135 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1137 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
1139 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
1140 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1142 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1145 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1146 scsi_low_calcf_target(ti);
1147 scsi_low_calcf_lun(li);
1148 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1149 scsi_low_calcf_show(li);
1153 ccb->ccb_h.status = CAM_REQ_CMP;
1158 case XPT_GET_TRAN_SETTINGS: {
1159 struct ccb_trans_settings *cts;
1163 #ifdef SCSI_LOW_DIAGNOSTIC
1164 if (target == CAM_TARGET_WILDCARD)
1166 printf("%s: invalid target\n", slp->sl_xname);
1167 ccb->ccb_h.status = CAM_REQ_INVALID;
1171 #endif /* SCSI_LOW_DIAGNOSTIC */
1172 ti = slp->sl_ti[target];
1173 if (lun == CAM_LUN_WILDCARD)
1176 s = SCSI_LOW_SPLSCSI();
1177 li = scsi_low_alloc_li(ti, lun, 1);
1178 #ifdef CAM_NEW_TRAN_CODE
1179 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1180 struct ccb_trans_settings_scsi *scsi =
1181 &cts->proto_specific.scsi;
1182 struct ccb_trans_settings_spi *spi =
1183 &cts->xport_specific.spi;
1184 #ifdef SCSI_LOW_DIAGNOSTIC
1185 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1187 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1188 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1192 #endif /* SCSI_LOW_DIAGNOSTIC */
1193 cts->protocol = PROTO_SCSI;
1194 cts->protocol_version = SCSI_REV_2;
1195 cts->transport = XPORT_SPI;
1196 cts->transport_version = 2;
1198 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1199 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1201 diskflags = li->li_diskflags & li->li_cfgflags;
1202 if (diskflags & SCSI_LOW_DISK_DISC)
1203 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1204 if (diskflags & SCSI_LOW_DISK_QTAG)
1205 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1207 spi->sync_period = ti->ti_maxsynch.period;
1208 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1209 spi->sync_offset = ti->ti_maxsynch.offset;
1210 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1212 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1213 spi->bus_width = ti->ti_width;
1215 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1216 scsi->valid = CTS_SCSI_VALID_TQ;
1217 spi->valid |= CTS_SPI_VALID_DISC;
1221 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1223 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
1225 #ifdef SCSI_LOW_DIAGNOSTIC
1226 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
1228 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1229 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
1233 #endif /* SCSI_LOW_DIAGNOSTIC */
1234 diskflags = li->li_diskflags & li->li_cfgflags;
1235 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
1236 cts->flags |= CCB_TRANS_DISC_ENB;
1238 cts->flags &= ~CCB_TRANS_DISC_ENB;
1239 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
1240 cts->flags |= CCB_TRANS_TAG_ENB;
1242 cts->flags &= ~CCB_TRANS_TAG_ENB;
1244 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1246 #ifdef SCSI_LOW_DIAGNOSTIC
1247 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1249 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1250 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1254 #endif /* SCSI_LOW_DIAGNOSTIC */
1255 if ((li->li_flags & SCSI_LOW_DISC) != 0)
1256 cts->flags |= CCB_TRANS_DISC_ENB;
1258 cts->flags &= ~CCB_TRANS_DISC_ENB;
1259 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
1260 cts->flags |= CCB_TRANS_TAG_ENB;
1262 cts->flags &= ~CCB_TRANS_TAG_ENB;
1266 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1270 cts->sync_period = ti->ti_maxsynch.period;
1271 cts->sync_offset = ti->ti_maxsynch.offset;
1272 cts->bus_width = ti->ti_width;
1274 cts->valid = CCB_TRANS_SYNC_RATE_VALID
1275 | CCB_TRANS_SYNC_OFFSET_VALID
1276 | CCB_TRANS_BUS_WIDTH_VALID
1277 | CCB_TRANS_DISC_VALID
1278 | CCB_TRANS_TQ_VALID;
1279 ccb->ccb_h.status = CAM_REQ_CMP;
1287 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1288 cam_calc_geometry(&ccb->ccg, /*extended*/1);
1293 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1294 s = SCSI_LOW_SPLSCSI();
1295 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1297 ccb->ccb_h.status = CAM_REQ_CMP;
1301 case XPT_TERM_IO: /* Terminate the I/O process */
1302 ccb->ccb_h.status = CAM_REQ_INVALID;
1306 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1307 #ifdef SCSI_LOW_DIAGNOSTIC
1308 if (target == CAM_TARGET_WILDCARD)
1310 printf("%s: invalid target\n", slp->sl_xname);
1311 ccb->ccb_h.status = CAM_REQ_INVALID;
1315 #endif /* SCSI_LOW_DIAGNOSTIC */
1317 msg = SCSI_LOW_MSG_RESET;
1318 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1320 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1325 ti = slp->sl_ti[target];
1326 if (lun == CAM_LUN_WILDCARD)
1330 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1331 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1333 flags = CCB_NORETRY | CCB_URGENT;
1335 s = SCSI_LOW_SPLSCSI();
1336 li = scsi_low_alloc_li(ti, lun, 1);
1337 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1341 case XPT_PATH_INQ: { /* Path routing inquiry */
1342 struct ccb_pathinq *cpi = &ccb->cpi;
1344 cpi->version_num = scsi_low_version_major;
1345 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1346 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1347 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1348 cpi->hba_inquiry |= PI_WIDE_16;
1349 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1350 cpi->hba_inquiry |= PI_WIDE_32;
1351 if (ti->ti_maxsynch.offset > 0)
1352 cpi->hba_inquiry |= PI_SDTR_ABLE;
1353 cpi->target_sprt = 0;
1355 cpi->hba_eng_cnt = 0;
1356 cpi->max_target = slp->sl_ntargs - 1;
1357 cpi->max_lun = slp->sl_nluns - 1;
1358 cpi->initiator_id = slp->sl_hostid;
1359 cpi->bus_id = cam_sim_bus(sim);
1360 cpi->base_transfer_speed = 3300;
1361 #ifdef CAM_NEW_TRAN_CODE
1362 cpi->transport = XPORT_SPI;
1363 cpi->transport_version = 2;
1364 cpi->protocol = PROTO_SCSI;
1365 cpi->protocol_version = SCSI_REV_2;
1367 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1368 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1369 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1370 cpi->unit_number = cam_sim_unit(sim);
1371 cpi->ccb_h.status = CAM_REQ_CMP;
1377 printf("scsi_low: non support func_code = %d ",
1378 ccb->ccb_h.func_code);
1379 ccb->ccb_h.status = CAM_REQ_INVALID;
1386 scsi_low_attach_cam(slp)
1387 struct scsi_low_softc *slp;
1389 struct cam_devq *devq;
1390 int tagged_openings;
1392 sprintf(slp->sl_xname, "%s%d",
1393 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1395 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1400 * ask the adapter what subunits are present
1402 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1403 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1405 DEVPORT_DEVNAME(slp->sl_dev), slp,
1406 DEVPORT_DEVUNIT(slp->sl_dev),
1407 slp->sl_openings, tagged_openings, devq);
1409 if (slp->sl_si.sim == NULL) {
1410 cam_simq_free(devq);
1414 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1415 free(slp->sl_si.sim, M_DEVBUF);
1419 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1420 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1421 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1422 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1423 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1424 free(slp->sl_si.sim, M_DEVBUF);
1428 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1433 scsi_low_world_start_cam(slp)
1434 struct scsi_low_softc *slp;
1438 scsi_low_rescan_bus_cam(slp);
1443 scsi_low_dettach_cam(slp)
1444 struct scsi_low_softc *slp;
1447 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1448 xpt_free_path(slp->sl_si.path);
1449 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1450 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1455 scsi_low_ccb_setup_cam(slp, cb)
1456 struct scsi_low_softc *slp;
1459 union ccb *ccb = (union ccb *) cb->osdep;
1461 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1463 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1464 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1465 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1466 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1467 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1468 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1469 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1470 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1471 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1475 scsi_low_unit_ready_cmd(cb);
1477 return SCSI_LOW_START_QTAG;
1481 scsi_low_done_cam(slp, cb)
1482 struct scsi_low_softc *slp;
1487 ccb = (union ccb *) cb->osdep;
1488 if (cb->ccb_error == 0)
1490 ccb->ccb_h.status = CAM_REQ_CMP;
1491 ccb->csio.resid = 0;
1495 if (cb->ccb_rcnt >= slp->sl_max_retry)
1496 cb->ccb_error |= ABORTIO;
1498 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1499 (cb->ccb_error & ABORTIO) == 0)
1502 if ((cb->ccb_error & SENSEIO) != 0)
1504 memcpy(&ccb->csio.sense_data,
1506 sizeof(ccb->csio.sense_data));
1509 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1510 &scsi_low_error_code_cam[0]);
1512 #ifdef SCSI_LOW_DIAGNOSTIC
1513 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1514 cb->ccb_scp.scp_cmdlen > 0 &&
1515 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1516 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1518 printf("%s: WARNING: scsi_low IO abort\n",
1520 scsi_low_print(slp, NULL);
1522 #endif /* SCSI_LOW_DIAGNOSTIC */
1525 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1526 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1528 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1529 ccb->csio.scsi_status = 0; /* XXX */
1531 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1533 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1539 scsi_low_timeout_cam(slp, ch, action)
1540 struct scsi_low_softc *slp;
1547 case SCSI_LOW_TIMEOUT_CH_IO:
1550 case SCSI_LOW_TIMEOUT_START:
1551 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1552 hz / SCSI_LOW_TIMEOUT_HZ);
1554 case SCSI_LOW_TIMEOUT_STOP:
1555 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1560 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1563 case SCSI_LOW_TIMEOUT_START:
1564 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1566 case SCSI_LOW_TIMEOUT_STOP:
1567 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1571 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1576 #endif /* SCSI_LOW_INTERFACE_CAM */
1578 /*=============================================================
1579 * END OF OS switch (All OS depend fucntions should be above)
1580 =============================================================*/
1582 /**************************************************************
1583 * scsi low deactivate and activate
1584 **************************************************************/
1586 scsi_low_is_busy(slp)
1587 struct scsi_low_softc *slp;
1590 if (slp->sl_nio > 0)
1596 scsi_low_deactivate(slp)
1597 struct scsi_low_softc *slp;
1601 s = SCSI_LOW_SPLSCSI();
1602 slp->sl_flags |= HW_INACTIVE;
1603 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1604 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1605 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1606 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1612 scsi_low_activate(slp)
1613 struct scsi_low_softc *slp;
1617 s = SCSI_LOW_SPLSCSI();
1618 slp->sl_flags &= ~HW_INACTIVE;
1619 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1621 slp->sl_flags |= HW_INACTIVE;
1626 slp->sl_timeout_count = 0;
1627 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1628 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1633 /**************************************************************
1635 **************************************************************/
1636 #ifdef SCSI_LOW_DIAGNOSTIC
1637 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1638 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1640 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1643 scsi_low_msg_log_init(slmlp)
1644 struct scsi_low_msg_log *slmlp;
1647 slmlp->slml_ptr = 0;
1651 scsi_low_msg_log_write(slmlp, datap, len)
1652 struct scsi_low_msg_log *slmlp;
1658 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1661 ptr = slmlp->slml_ptr ++;
1662 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1663 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1664 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1665 slmlp->slml_msg[ptr].msg[ind] = 0;
1669 scsi_low_msg_log_show(slmlp, s, len)
1670 struct scsi_low_msg_log *slmlp;
1676 printf("%s: (%d) ", s, slmlp->slml_ptr);
1677 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1679 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1682 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1688 #endif /* SCSI_LOW_DIAGNOSTIC */
1690 /**************************************************************
1692 **************************************************************/
1694 scsi_low_engage(arg)
1697 struct scsi_low_softc *slp = arg;
1698 int s = SCSI_LOW_SPLSCSI();
1700 switch (slp->sl_rstep)
1704 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1705 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1706 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1711 slp->sl_flags &= ~HW_RESUME;
1712 scsi_low_start(slp);
1722 scsi_low_init(slp, flags)
1723 struct scsi_low_softc *slp;
1728 slp->sl_flags |= HW_INITIALIZING;
1730 /* clear power control timeout */
1731 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1733 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1734 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1735 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1737 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1740 /* reset current nexus */
1741 scsi_low_reset_nexus(slp, flags);
1742 if ((slp->sl_flags & HW_INACTIVE) != 0)
1748 if (flags != SCSI_LOW_RESTART_SOFT)
1750 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1754 slp->sl_flags &= ~HW_INITIALIZING;
1758 /**************************************************************
1760 **************************************************************/
1761 static struct lun_info *
1762 scsi_low_alloc_li(ti, lun, alloc)
1763 struct targ_info *ti;
1767 struct scsi_low_softc *slp = ti->ti_sc;
1768 struct lun_info *li;
1770 li = LIST_FIRST(&ti->ti_litab);
1773 if (li->li_lun == lun)
1776 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1778 if (li->li_lun == lun)
1780 LIST_REMOVE(li, lun_chain);
1781 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1790 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1792 panic("no lun info mem");
1794 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1798 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1800 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1801 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1802 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1803 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1804 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1806 li->li_qtagbits = (u_int) -1;
1808 TAILQ_INIT(&li->li_discq);
1809 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1811 /* host specific structure initialization per lun */
1812 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1813 (*slp->sl_funcs->scsi_low_lun_init)
1814 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1815 scsi_low_calcf_lun(li);
1819 /**************************************************************
1820 * allocate targ_info
1821 **************************************************************/
1822 static struct targ_info *
1823 scsi_low_alloc_ti(slp, targ)
1824 struct scsi_low_softc *slp;
1827 struct targ_info *ti;
1829 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1830 TAILQ_INIT(&slp->sl_titab);
1832 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1834 panic("%s short of memory", slp->sl_xname);
1836 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1840 slp->sl_ti[targ] = ti;
1841 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1842 LIST_INIT(&ti->ti_litab);
1844 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1845 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1846 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1847 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1848 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1849 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1851 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1853 (*slp->sl_funcs->scsi_low_targ_init)
1854 (slp, ti, SCSI_LOW_INFO_ALLOC);
1856 scsi_low_calcf_target(ti);
1861 scsi_low_free_ti(slp)
1862 struct scsi_low_softc *slp;
1864 struct targ_info *ti, *tib;
1865 struct lun_info *li, *nli;
1867 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1869 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1871 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1873 (*slp->sl_funcs->scsi_low_lun_init)
1874 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1876 nli = LIST_NEXT(li, lun_chain);
1880 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1882 (*slp->sl_funcs->scsi_low_targ_init)
1883 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1885 tib = TAILQ_NEXT(ti, ti_chain);
1890 /**************************************************************
1892 **************************************************************/
1894 scsi_low_bus_idle(slp)
1895 struct scsi_low_softc *slp;
1898 slp->sl_retry_sel = 0;
1899 if (slp->sl_Tnexus == NULL)
1900 scsi_low_start(slp);
1904 scsi_low_timeout(arg)
1907 struct scsi_low_softc *slp = arg;
1910 s = SCSI_LOW_SPLSCSI();
1911 (void) scsi_low_timeout_check(slp);
1912 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1913 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1918 scsi_low_timeout_check(slp)
1919 struct scsi_low_softc *slp;
1921 struct targ_info *ti;
1922 struct lun_info *li;
1923 struct slccb *cb = NULL; /* XXX */
1925 /* selection restart */
1926 if (slp->sl_retry_sel != 0)
1928 slp->sl_retry_sel = 0;
1929 if (slp->sl_Tnexus != NULL)
1932 cb = TAILQ_FIRST(&slp->sl_start);
1936 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1938 cb->ccb_flags |= CCB_NORETRY;
1939 cb->ccb_error |= SELTIMEOUTIO;
1940 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1941 panic("%s: ccb not finished", slp->sl_xname);
1944 if (slp->sl_Tnexus == NULL)
1945 scsi_low_start(slp);
1948 /* call hardware timeout */
1950 if (slp->sl_funcs->scsi_low_timeout != NULL)
1952 (*slp->sl_funcs->scsi_low_timeout) (slp);
1955 if (slp->sl_timeout_count ++ <
1956 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1959 slp->sl_timeout_count = 0;
1960 if (slp->sl_nio > 0)
1962 if ((cb = slp->sl_Qnexus) != NULL)
1964 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1968 else if (slp->sl_disc == 0)
1970 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1973 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1977 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1978 ti = TAILQ_NEXT(ti, ti_chain))
1980 if (ti->ti_disc == 0)
1983 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1984 li = LIST_NEXT(li, lun_chain))
1986 for (cb = TAILQ_FIRST(&li->li_discq);
1988 cb = TAILQ_NEXT(cb, ccb_chain))
1991 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1999 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
2001 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2004 if (slp->sl_active != 0)
2006 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2012 if (slp->sl_powc < 0)
2014 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2015 slp->sl_flags |= HW_POWDOWN;
2016 (*slp->sl_funcs->scsi_low_power)
2017 (slp, SCSI_LOW_POWDOWN);
2023 cb->ccb_error |= TIMEOUTIO;
2024 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2025 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2026 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2027 scsi_low_start(slp);
2033 scsi_low_abort_ccb(slp, cb)
2034 struct scsi_low_softc *slp;
2037 struct targ_info *ti;
2038 struct lun_info *li;
2043 if ((cb->ccb_omsgoutflag &
2044 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2049 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2050 msg = SCSI_LOW_MSG_ABORT;
2052 msg = SCSI_LOW_MSG_ABORT_QTAG;
2054 cb->ccb_error |= ABORTIO;
2055 cb->ccb_flags |= CCB_NORETRY;
2056 scsi_low_ccb_message_assert(cb, msg);
2058 if (cb == slp->sl_Qnexus)
2060 scsi_low_assert_msg(slp, ti, msg, 1);
2062 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2064 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2065 panic("%s: revoked ccb done", slp->sl_xname);
2067 cb->ccb_flags |= CCB_STARTQ;
2068 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2070 if (slp->sl_Tnexus == NULL)
2071 scsi_low_start(slp);
2075 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2076 panic("%s: revoked ccb retried", slp->sl_xname);
2081 /**************************************************************
2082 * Generic SCSI INTERFACE
2083 **************************************************************/
2085 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2086 struct scsi_low_softc *slp;
2087 int openings, ntargs, nluns, targsize, lunsize;
2089 struct targ_info *ti;
2090 struct lun_info *li;
2093 #ifdef SCSI_LOW_INTERFACE_XS
2094 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2095 #endif /* SCSI_LOW_INTERFACE_XS */
2096 #ifdef SCSI_LOW_INTERFACE_CAM
2097 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2098 #endif /* SCSI_LOW_INTERFACE_CAM */
2100 if (slp->sl_osdep_fp == NULL)
2101 panic("scsi_low: interface not spcified");
2103 if (ntargs > SCSI_LOW_NTARGETS)
2105 printf("scsi_low: %d targets are too large\n", ntargs);
2106 printf("change kernel options SCSI_LOW_NTARGETS");
2111 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2113 slp->sl_openings = openings;
2114 slp->sl_ntargs = ntargs;
2115 slp->sl_nluns = nluns;
2116 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2118 if (lunsize < sizeof(struct lun_info))
2119 lunsize = sizeof(struct lun_info);
2121 if (targsize < sizeof(struct targ_info))
2122 targsize = sizeof(struct targ_info);
2124 slp->sl_targsize = targsize;
2125 for (i = 0; i < ntargs; i ++)
2127 ti = scsi_low_alloc_ti(slp, i);
2128 ti->ti_lunsize = lunsize;
2129 li = scsi_low_alloc_li(ti, 0, 1);
2132 /* initialize queue */
2133 nccb = openings * ntargs;
2134 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2135 nccb = SCSI_LOW_NCCB;
2136 scsi_low_init_ccbque(nccb);
2137 TAILQ_INIT(&slp->sl_start);
2139 /* call os depend attach */
2140 s = SCSI_LOW_SPLSCSI();
2141 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2145 printf("%s: scsi_low_attach: osdep attach failed\n",
2150 /* check hardware */
2151 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2152 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2155 printf("%s: scsi_low_attach: initialization failed\n",
2160 /* start watch dog */
2161 slp->sl_timeout_count = 0;
2162 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2163 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2164 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2167 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2169 #ifdef SCSI_LOW_START_UP_CHECK
2170 /* probing devices */
2171 scsi_low_start_up(slp);
2172 #endif /* SCSI_LOW_START_UP_CHECK */
2174 /* call os depend attach done*/
2175 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2181 scsi_low_dettach(slp)
2182 struct scsi_low_softc *slp;
2186 s = SCSI_LOW_SPLSCSI();
2187 if (scsi_low_is_busy(slp) != 0)
2193 scsi_low_deactivate(slp);
2195 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2202 scsi_low_free_ti(slp);
2203 LIST_REMOVE(slp, sl_chain);
2208 /**************************************************************
2210 **************************************************************/
2212 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2213 struct scsi_low_softc *slp;
2214 struct targ_info *ti;
2215 struct lun_info *li;
2223 scsi_low_ccb_message_assert(cb, msg);
2225 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2226 scsi_low_alloc_qtag(cb);
2228 cb->ccb_flags = flags | CCB_STARTQ;
2229 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2230 cb->ccb_error |= PENDINGIO;
2232 if ((flags & CCB_URGENT) != 0)
2234 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2238 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2243 if (slp->sl_Tnexus == NULL)
2244 scsi_low_start(slp);
2249 scsi_low_message_enqueue(slp, ti, li, flags)
2250 struct scsi_low_softc *slp;
2251 struct targ_info *ti;
2252 struct lun_info *li;
2258 tmsgflags = ti->ti_setup_msg;
2259 ti->ti_setup_msg = 0;
2261 flags |= CCB_NORETRY;
2262 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2267 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2271 /**************************************************************
2272 * Generic Start & Done
2273 **************************************************************/
2274 #define SLSC_MODE_SENSE_SHORT 0x1a
2275 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2276 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2277 sizeof(struct scsi_low_mode_sense_data), 0};
2278 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2279 sizeof(struct scsi_low_inq_data), 0};
2280 static u_int8_t unit_ready_cmd[6];
2281 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2282 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2283 static int scsi_low_resume (struct scsi_low_softc *);
2286 scsi_low_unit_ready_cmd(cb)
2290 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2291 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2292 cb->ccb_scp.scp_datalen = 0;
2293 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2298 scsi_low_sense_abort_start(slp, ti, li, cb)
2299 struct scsi_low_softc *slp;
2300 struct targ_info *ti;
2301 struct lun_info *li;
2305 cb->ccb_scp.scp_cmdlen = 6;
2306 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2307 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2308 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2309 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2310 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2311 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2312 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2314 scsi_low_ccb_message_clear(cb);
2315 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2317 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2321 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2322 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2323 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2324 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2327 return SCSI_LOW_START_NO_QTAG;
2331 scsi_low_setup_start(slp, ti, li, cb)
2332 struct scsi_low_softc *slp;
2333 struct targ_info *ti;
2334 struct lun_info *li;
2338 switch(li->li_state)
2340 case SCSI_LOW_LUN_SLEEP:
2341 scsi_low_unit_ready_cmd(cb);
2344 case SCSI_LOW_LUN_START:
2345 cb->ccb_scp.scp_cmd = ss_cmd;
2346 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2347 cb->ccb_scp.scp_datalen = 0;
2348 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2352 case SCSI_LOW_LUN_INQ:
2353 cb->ccb_scp.scp_cmd = inq_cmd;
2354 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2355 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2356 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2357 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2361 case SCSI_LOW_LUN_MODEQ:
2362 cb->ccb_scp.scp_cmd = sms_cmd;
2363 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2364 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2365 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2366 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2368 return SCSI_LOW_START_QTAG;
2371 panic("%s: no setup phase", slp->sl_xname);
2374 return SCSI_LOW_START_NO_QTAG;
2378 scsi_low_resume(slp)
2379 struct scsi_low_softc *slp;
2382 if (slp->sl_flags & HW_RESUME)
2384 slp->sl_flags &= ~HW_POWDOWN;
2385 if (slp->sl_funcs->scsi_low_power != NULL)
2387 slp->sl_flags |= HW_RESUME;
2389 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2390 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2391 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2392 SCSI_LOW_TIMEOUT_START);
2400 struct scsi_low_softc *slp;
2402 struct targ_info *ti;
2403 struct lun_info *li;
2407 /* check hardware exists or under initializations ? */
2408 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2411 /* check hardware power up ? */
2412 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2415 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2417 if (scsi_low_resume(slp) == EJUSTRETURN)
2423 #ifdef SCSI_LOW_DIAGNOSTIC
2424 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2426 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2427 panic("%s: inconsistent", slp->sl_xname);
2429 #endif /* SCSI_LOW_DIAGNOSTIC */
2431 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2432 cb = TAILQ_NEXT(cb, ccb_chain))
2436 if (li->li_disc == 0)
2438 goto scsi_low_cmd_start;
2440 else if (li->li_nqio > 0)
2442 if (li->li_nqio < li->li_maxnqio ||
2443 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2444 goto scsi_low_cmd_start;
2450 cb->ccb_flags &= ~CCB_STARTQ;
2451 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2454 /* clear all error flag bits (for restart) */
2456 cb->ccb_datalen = -1;
2457 cb->ccb_scp.scp_status = ST_UNKNOWN;
2459 /* setup nexus pointer */
2460 slp->sl_Qnexus = cb;
2461 slp->sl_Lnexus = li;
2462 slp->sl_Tnexus = ti;
2464 /* initialize msgsys */
2465 scsi_low_init_msgsys(slp, ti);
2468 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2470 /* CA state or forced abort */
2471 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2473 else if (li->li_state >= SCSI_LOW_LUN_OK)
2475 cb->ccb_flags &= ~CCB_INTERNAL;
2476 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2477 if (cb->ccb_msgoutflag != 0)
2479 scsi_low_ccb_message_exec(slp, cb);
2484 cb->ccb_flags |= CCB_INTERNAL;
2485 rv = scsi_low_setup_start(slp, ti, li, cb);
2489 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2491 if (rv == SCSI_LOW_START_QTAG &&
2492 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2497 scsi_low_activate_qtag(cb);
2498 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2499 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2500 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2501 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2502 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2504 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2505 scsi_low_assert_msg(slp, ti, qmsg, 0);
2509 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2510 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2511 cb->ccb_tc = cb->ccb_tcmax;
2513 /* setup saved scsi data pointer */
2514 cb->ccb_sscp = cb->ccb_scp;
2516 /* setup current scsi pointer */
2517 slp->sl_scp = cb->ccb_sscp;
2518 slp->sl_error = cb->ccb_error;
2520 /* assert always an identify msg */
2521 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2524 #ifdef SCSI_LOW_DIAGNOSTIC
2525 scsi_low_msg_log_init(&ti->ti_log_msgin);
2526 scsi_low_msg_log_init(&ti->ti_log_msgout);
2527 #endif /* SCSI_LOW_DIAGNOSTIC */
2529 /* selection start */
2531 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2532 if (rv == SCSI_LOW_START_OK)
2534 #ifdef SCSI_LOW_STATICS
2535 scsi_low_statics.nexus_win ++;
2536 #endif /* SCSI_LOW_STATICS */
2540 scsi_low_arbit_fail(slp, cb);
2541 #ifdef SCSI_LOW_STATICS
2542 scsi_low_statics.nexus_fail ++;
2543 #endif /* SCSI_LOW_STATICS */
2547 scsi_low_arbit_fail(slp, cb)
2548 struct scsi_low_softc *slp;
2551 struct targ_info *ti = cb->ti;
2553 scsi_low_deactivate_qtag(cb);
2554 scsi_low_ccb_message_retry(cb);
2555 cb->ccb_flags |= CCB_STARTQ;
2556 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2558 scsi_low_bus_release(slp, ti);
2561 if (slp->sl_disc == 0)
2563 #ifdef SCSI_LOW_DIAGNOSTIC
2564 printf("%s: try selection again\n", slp->sl_xname);
2565 #endif /* SCSI_LOW_DIAGNOSTIC */
2566 slp->sl_retry_sel = 1;
2571 scsi_low_bus_release(slp, ti)
2572 struct scsi_low_softc *slp;
2573 struct targ_info *ti;
2576 if (ti->ti_disc > 0)
2578 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2582 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2585 /* clear all nexus pointer */
2586 slp->sl_Qnexus = NULL;
2587 slp->sl_Lnexus = NULL;
2588 slp->sl_Tnexus = NULL;
2590 /* clear selection assert */
2591 slp->sl_selid = NULL;
2593 /* clear nexus data */
2594 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2596 /* clear phase change counter */
2597 slp->sl_ph_count = 0;
2601 scsi_low_setup_done(slp, cb)
2602 struct scsi_low_softc *slp;
2605 struct targ_info *ti;
2606 struct lun_info *li;
2611 if (cb->ccb_rcnt >= slp->sl_max_retry)
2613 cb->ccb_error |= ABORTIO;
2614 return SCSI_LOW_DONE_COMPLETE;
2617 /* XXX: special huck for selection timeout */
2618 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2619 (cb->ccb_error & SELTIMEOUTIO) != 0)
2621 cb->ccb_error |= ABORTIO;
2622 return SCSI_LOW_DONE_COMPLETE;
2625 switch(li->li_state)
2627 case SCSI_LOW_LUN_INQ:
2628 if (cb->ccb_error != 0)
2631 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2635 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2637 else if ((li->li_inq.sd_version & 7) >= 2 ||
2638 (li->li_inq.sd_len >= 4))
2640 if ((li->li_inq.sd_support & 0x2) == 0)
2641 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2642 if ((li->li_inq.sd_support & 0x8) == 0)
2643 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2646 if ((li->li_inq.sd_support & 0x10) == 0)
2647 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2648 if ((li->li_inq.sd_support & 0x20) == 0)
2649 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2650 if ((li->li_inq.sd_support & 0x40) == 0)
2651 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2656 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2659 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2661 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2663 scsi_low_calcf_target(ti);
2664 scsi_low_calcf_lun(li);
2667 case SCSI_LOW_LUN_MODEQ:
2668 if (cb->ccb_error != 0)
2670 if (cb->ccb_error & SENSEIO)
2672 #ifdef SCSI_LOW_DEBUG
2673 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2675 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2676 (u_int) cb->ccb_sense.error_code,
2677 (u_int) cb->ccb_sense.segment,
2678 (u_int) cb->ccb_sense.flags,
2679 (u_int) cb->ccb_sense.add_sense_code,
2680 (u_int) cb->ccb_sense.add_sense_code_qual);
2682 #endif /* SCSI_LOW_DEBUG */
2686 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2689 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2691 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2692 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2694 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2695 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2696 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2698 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2699 scsi_low_calcf_lun(li);
2707 if (li->li_state == SCSI_LOW_LUN_OK)
2709 scsi_low_calcf_target(ti);
2710 scsi_low_calcf_lun(li);
2711 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2712 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2714 scsi_low_calcf_show(li);
2719 return SCSI_LOW_DONE_RETRY;
2723 scsi_low_done(slp, cb)
2724 struct scsi_low_softc *slp;
2729 if (cb->ccb_error == 0)
2731 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2733 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2735 * SCSI-2 draft suggests
2736 * page 0x0a QErr bit determins if
2737 * the target aborts or continues
2738 * the queueing io's after CA state resolved.
2739 * However many targets seem not to support
2740 * the page 0x0a. Thus we should manually clear the
2741 * queuing io's after CA state.
2743 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2746 cb->ccb_flags |= CCB_CLEARQ;
2749 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2751 if ((cb->ccb_flags & CCB_SENSE) != 0)
2752 cb->ccb_error |= (SENSEIO | ABORTIO);
2753 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2755 else switch (cb->ccb_sscp.scp_status)
2761 if (cb->ccb_datalen == 0 ||
2762 cb->ccb_scp.scp_datalen == 0)
2765 if (cb->ccb_scp.scp_cmdlen > 0 &&
2766 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2767 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2770 cb->ccb_error |= PDMAERR;
2775 cb->ccb_error |= (BUSYERR | STATERR);
2779 cb->ccb_error |= (STATERR | ABORTIO);
2784 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2787 cb->ccb_flags |= CCB_SENSE;
2790 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2795 cb->ccb_error |= FATALIO;
2801 if (cb->ccb_flags & CCB_SENSE)
2803 cb->ccb_error |= (SENSEERR | ABORTIO);
2805 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2809 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2811 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2815 /* check a ccb msgout flag */
2816 if (cb->ccb_omsgoutflag != 0)
2818 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2819 SCSI_LOW_MSG_ABORT_QTAG | \
2820 SCSI_LOW_MSG_CLEAR_QTAG | \
2821 SCSI_LOW_MSG_TERMIO)
2823 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2825 cb->ccb_error |= ABORTIO;
2829 /* call OS depend done */
2830 if (cb->osdep != NULL)
2832 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2833 if (rv == EJUSTRETURN)
2836 else if (cb->ccb_error != 0)
2838 if (cb->ccb_rcnt >= slp->sl_max_retry)
2839 cb->ccb_error |= ABORTIO;
2841 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2842 (cb->ccb_error & ABORTIO) == 0)
2846 /* free our target */
2847 #ifdef SCSI_LOW_DEBUG
2848 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2850 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2851 scsi_low_print(slp, NULL);
2853 #endif /* SCSI_LOW_DEBUG */
2855 scsi_low_deactivate_qtag(cb);
2856 scsi_low_dealloc_qtag(cb);
2857 scsi_low_free_ccb(cb);
2859 return SCSI_LOW_DONE_COMPLETE;
2862 #ifdef SCSI_LOW_DEBUG
2863 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2865 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2866 scsi_low_print(slp, NULL);
2868 #endif /* SCSI_LOW_DEBUG */
2871 scsi_low_deactivate_qtag(cb);
2872 scsi_low_ccb_message_retry(cb);
2873 return SCSI_LOW_DONE_RETRY;
2876 /**************************************************************
2878 **************************************************************/
2880 scsi_low_reset_nexus_target(slp, ti, fdone)
2881 struct scsi_low_softc *slp;
2882 struct targ_info *ti;
2885 struct lun_info *li;
2887 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2888 li = LIST_NEXT(li, lun_chain))
2890 scsi_low_reset_nexus_lun(slp, li, fdone);
2891 li->li_state = SCSI_LOW_LUN_SLEEP;
2896 ti->ti_setup_msg = 0;
2897 ti->ti_setup_msg_done = 0;
2899 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2900 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2902 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2903 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2905 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2907 ((*slp->sl_funcs->scsi_low_targ_init)
2908 (slp, ti, SCSI_LOW_INFO_REVOKE));
2910 scsi_low_calcf_target(ti);
2912 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2913 li = LIST_NEXT(li, lun_chain))
2917 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2918 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2920 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2922 ((*slp->sl_funcs->scsi_low_lun_init)
2923 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2925 scsi_low_calcf_lun(li);
2930 scsi_low_reset_nexus(slp, fdone)
2931 struct scsi_low_softc *slp;
2934 struct targ_info *ti;
2935 struct slccb *cb, *topcb;
2937 if ((cb = slp->sl_Qnexus) != NULL)
2939 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2946 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2947 ti = TAILQ_NEXT(ti, ti_chain))
2949 scsi_low_reset_nexus_target(slp, ti, fdone);
2950 scsi_low_bus_release(slp, ti);
2951 scsi_low_init_msgsys(slp, ti);
2956 topcb->ccb_flags |= CCB_STARTQ;
2957 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2961 slp->sl_retry_sel = 0;
2962 slp->sl_flags &= ~HW_PDMASTART;
2967 static char tw_chars[] = "|/-\\";
2968 #define TWIDDLEWAIT 10000
2971 scsi_low_twiddle_wait(void)
2975 cnputc(tw_chars[tw_pos++]);
2976 tw_pos %= (sizeof(tw_chars) - 1);
2977 SCSI_LOW_DELAY(TWIDDLEWAIT);
2981 scsi_low_bus_reset(slp)
2982 struct scsi_low_softc *slp;
2986 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2988 printf("%s: try to reset scsi bus ", slp->sl_xname);
2989 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2990 scsi_low_twiddle_wait();
2996 scsi_low_restart(slp, flags, s)
2997 struct scsi_low_softc *slp;
3004 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3006 if ((error = scsi_low_init(slp, flags)) != 0)
3009 scsi_low_start(slp);
3013 /**************************************************************
3014 * disconnect and reselect
3015 **************************************************************/
3016 #define MSGCMD_LUN(msg) (msg & 0x07)
3018 static struct slccb *
3019 scsi_low_establish_ccb(ti, li, tag)
3020 struct targ_info *ti;
3021 struct lun_info *li;
3024 struct scsi_low_softc *slp = ti->ti_sc;
3030 cb = TAILQ_FIRST(&li->li_discq);
3031 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3032 if (cb->ccb_tag == tag)
3037 * establish our ccb nexus
3040 #ifdef SCSI_LOW_DEBUG
3041 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3043 printf("%s: nexus(0x%lx) abort check start\n",
3044 slp->sl_xname, (u_long) cb);
3045 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3046 scsi_low_revoke_ccb(slp, cb, 1);
3050 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3052 if (cb->ccb_omsgoutflag == 0)
3053 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3055 #endif /* SCSI_LOW_DEBUG */
3057 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3058 cb->ccb_flags &= ~CCB_DISCQ;
3059 slp->sl_Qnexus = cb;
3061 slp->sl_scp = cb->ccb_sscp;
3062 slp->sl_error |= cb->ccb_error;
3068 /* inform "ccb nexus established" to the host driver */
3069 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3072 if (cb->ccb_msgoutflag != 0)
3074 scsi_low_ccb_message_exec(slp, cb);
3081 scsi_low_reselected(slp, targ)
3082 struct scsi_low_softc *slp;
3085 struct targ_info *ti;
3090 * Check select vs reselected collision.
3093 if ((cb = slp->sl_selid) != NULL)
3095 scsi_low_arbit_fail(slp, cb);
3096 #ifdef SCSI_LOW_STATICS
3097 scsi_low_statics.nexus_conflict ++;
3098 #endif /* SCSI_LOW_STATICS */
3102 * Check if no current active nexus.
3104 if (slp->sl_Tnexus != NULL)
3111 * Check a valid target id asserted ?
3113 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3115 s = "scsi id illegal";
3120 * Check the target scsi status.
3122 ti = slp->sl_ti[targ];
3123 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3125 s = "phase mismatch";
3133 scsi_low_init_msgsys(slp, ti);
3136 * Establish our target nexus
3138 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3139 slp->sl_Tnexus = ti;
3140 #ifdef SCSI_LOW_STATICS
3141 scsi_low_statics.nexus_reselected ++;
3142 #endif /* SCSI_LOW_STATICS */
3146 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3147 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3148 "reselect: scsi world confused");
3152 /**************************************************************
3153 * cmd out pointer setup
3154 **************************************************************/
3156 scsi_low_cmd(slp, ti)
3157 struct scsi_low_softc *slp;
3158 struct targ_info *ti;
3160 struct slccb *cb = slp->sl_Qnexus;
3162 slp->sl_ph_count ++;
3168 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3169 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3170 slp->sl_scp.scp_datalen = 0;
3171 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3172 slp->sl_error |= FATALIO;
3173 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3174 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3179 #ifdef SCSI_LOW_DEBUG
3180 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3182 scsi_low_test_cmdlnk(slp, cb);
3184 #endif /* SCSI_LOW_DEBUG */
3189 /**************************************************************
3190 * data out pointer setup
3191 **************************************************************/
3193 scsi_low_data(slp, ti, bp, direction)
3194 struct scsi_low_softc *slp;
3195 struct targ_info *ti;
3199 struct slccb *cb = slp->sl_Qnexus;
3201 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3207 slp->sl_error |= (FATALIO | PDMAERR);
3208 slp->sl_scp.scp_datalen = 0;
3209 slp->sl_scp.scp_direction = direction;
3210 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3211 if (ti->ti_ophase != ti->ti_phase)
3216 s = "DATA PHASE: ccb nexus not found";
3218 s = "DATA PHASE: xfer direction mismatch";
3219 SCSI_LOW_INFO(slp, ti, s);
3226 /**************************************************************
3228 **************************************************************/
3229 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3230 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3231 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3232 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3233 #define MSGIN_DATA_LAST 0x30
3235 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
3236 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
3237 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
3238 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
3240 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
3241 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
3242 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
3243 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
3244 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
3245 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
3246 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
3248 struct scsi_low_msgout_data {
3251 int (*md_msgfunc) (struct scsi_low_softc *);
3252 int (*md_errfunc) (struct scsi_low_softc *, u_int);
3253 #define MSG_RELEASE_ATN 0x0001
3257 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3258 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3259 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3260 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3261 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3262 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3263 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3264 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3265 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3266 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3267 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3268 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3269 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3270 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3271 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3272 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3273 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3276 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
3277 static int scsi_low_synch (struct scsi_low_softc *);
3278 static int scsi_low_wide (struct scsi_low_softc *);
3279 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
3280 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
3281 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
3282 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
3283 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
3284 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
3285 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
3286 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
3287 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
3288 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
3289 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
3291 struct scsi_low_msgin_data {
3293 int (*md_msgfunc) (struct scsi_low_softc *);
3296 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3297 /* 0 */ {1, scsi_low_msginfunc_cc},
3298 /* 1 */ {2, scsi_low_msginfunc_ext},
3299 /* 2 */ {1, scsi_low_msginfunc_sdp},
3300 /* 3 */ {1, scsi_low_msginfunc_rp},
3301 /* 4 */ {1, scsi_low_msginfunc_disc},
3302 /* 5 */ {1, scsi_low_msginfunc_rejop},
3303 /* 6 */ {1, scsi_low_msginfunc_rejop},
3304 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
3305 /* 8 */ {1, scsi_low_msginfunc_noop},
3306 /* 9 */ {1, scsi_low_msginfunc_parity},
3307 /* a */ {1, scsi_low_msginfunc_lcc},
3308 /* b */ {1, scsi_low_msginfunc_lcc},
3309 /* c */ {1, scsi_low_msginfunc_rejop},
3310 /* d */ {2, scsi_low_msginfunc_rejop},
3311 /* e */ {1, scsi_low_msginfunc_rejop},
3312 /* f */ {1, scsi_low_msginfunc_rejop},
3313 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
3314 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
3315 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
3316 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
3317 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
3318 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
3319 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
3320 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
3321 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
3322 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
3323 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
3324 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
3325 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
3326 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
3327 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
3328 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
3329 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3330 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
3331 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
3332 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3333 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
3334 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
3335 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
3336 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
3337 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
3338 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
3339 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
3340 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
3341 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
3342 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
3343 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
3344 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
3345 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3348 /**************************************************************
3350 **************************************************************/
3352 scsi_low_msgfunc_synch(slp)
3353 struct scsi_low_softc *slp;
3355 struct targ_info *ti = slp->sl_Tnexus;
3356 int ptr = ti->ti_msgoutlen;
3358 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3359 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3360 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3361 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3362 return MSG_EXTEND_SYNCHLEN + 2;
3366 scsi_low_msgfunc_wide(slp)
3367 struct scsi_low_softc *slp;
3369 struct targ_info *ti = slp->sl_Tnexus;
3370 int ptr = ti->ti_msgoutlen;
3372 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3373 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3374 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3375 return MSG_EXTEND_WIDELEN + 2;
3379 scsi_low_msgfunc_identify(slp)
3380 struct scsi_low_softc *slp;
3382 struct targ_info *ti = slp->sl_Tnexus;
3383 struct lun_info *li = slp->sl_Lnexus;
3384 struct slccb *cb = slp->sl_Qnexus;
3385 int ptr = ti->ti_msgoutlen;
3391 slp->sl_error |= FATALIO;
3392 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3393 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3397 if (scsi_low_is_disconnect_ok(cb) != 0)
3398 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3402 if (ti->ti_phase == PH_MSGOUT)
3404 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3405 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3407 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3411 ti->ti_msgoutstr[ptr + 0] = msg;
3416 scsi_low_msgfunc_abort(slp)
3417 struct scsi_low_softc *slp;
3420 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3425 scsi_low_msgfunc_qabort(slp)
3426 struct scsi_low_softc *slp;
3429 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3434 scsi_low_msgfunc_reset(slp)
3435 struct scsi_low_softc *slp;
3438 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3443 scsi_low_msgfunc_qtag(slp)
3444 struct scsi_low_softc *slp;
3446 struct targ_info *ti = slp->sl_Tnexus;
3447 struct slccb *cb = slp->sl_Qnexus;
3448 int ptr = ti->ti_msgoutlen;
3450 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3452 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3457 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3458 if (ti->ti_phase == PH_MSGOUT)
3460 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3467 * The following functions are called when targets give unexpected
3468 * responces in msgin (after msgout).
3471 scsi_low_errfunc_identify(slp, msgflags)
3472 struct scsi_low_softc *slp;
3476 if (slp->sl_Lnexus != NULL)
3478 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3479 scsi_low_calcf_lun(slp->sl_Lnexus);
3485 scsi_low_errfunc_synch(slp, msgflags)
3486 struct scsi_low_softc *slp;
3489 struct targ_info *ti = slp->sl_Tnexus;
3491 MSGIN_PERIOD(ti) = 0;
3492 MSGIN_OFFSET(ti) = 0;
3493 scsi_low_synch(slp);
3498 scsi_low_errfunc_wide(slp, msgflags)
3499 struct scsi_low_softc *slp;
3502 struct targ_info *ti = slp->sl_Tnexus;
3504 MSGIN_WIDTHP(ti) = 0;
3510 scsi_low_errfunc_qtag(slp, msgflags)
3511 struct scsi_low_softc *slp;
3515 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3517 if (slp->sl_Qnexus != NULL)
3519 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3521 if (slp->sl_Lnexus != NULL)
3523 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3524 scsi_low_calcf_lun(slp->sl_Lnexus);
3526 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3533 scsi_low_msgout(slp, ti, fl)
3534 struct scsi_low_softc *slp;
3535 struct targ_info *ti;
3538 struct scsi_low_msgout_data *mdp;
3541 #ifdef SCSI_LOW_DIAGNOSTIC
3542 if (ti != slp->sl_Tnexus)
3544 scsi_low_print(slp, NULL);
3545 panic("scsi_low_msgout: Target nexus inconsistent");
3547 #endif /* SCSI_LOW_DIAGNOSTIC */
3549 slp->sl_ph_count ++;
3550 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3552 printf("%s: too many phase changes\n", slp->sl_xname);
3553 slp->sl_error |= FATALIO;
3554 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3558 * Scsi phase changes.
3559 * Previously msgs asserted are accepted by our target or
3560 * processed by scsi_low_msgin.
3561 * Thus clear all saved informations.
3563 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3565 ti->ti_omsgflags = 0;
3566 ti->ti_emsgflags = 0;
3568 else if (slp->sl_atten == 0)
3571 * We did not assert attention, however still our target required
3572 * msgs. Resend previous msgs.
3574 ti->ti_msgflags |= ti->ti_omsgflags;
3575 ti->ti_omsgflags = 0;
3576 #ifdef SCSI_LOW_DIAGNOSTIC
3577 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3578 #endif /* SCSI_LOW_DIAGNOSTIC */
3582 * We have no msgs. send MSG_NOOP (OK?)
3584 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3585 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3590 ti->ti_msgoutlen = 0;
3591 slp->sl_clear_atten = 0;
3592 mdp = &scsi_low_msgout_data[0];
3593 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3595 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3597 ti->ti_omsgflags |= mdp->md_flags;
3598 ti->ti_msgflags &= ~mdp->md_flags;
3599 ti->ti_emsgflags = mdp->md_flags;
3601 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3602 if (mdp->md_msgfunc != NULL)
3603 len = (*mdp->md_msgfunc) (slp);
3607 #ifdef SCSI_LOW_DIAGNOSTIC
3608 scsi_low_msg_log_write(&ti->ti_log_msgout,
3609 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3610 #endif /* SCSI_LOW_DIAGNOSTIC */
3612 ti->ti_msgoutlen += len;
3613 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3615 slp->sl_clear_atten = 1;
3619 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3620 ti->ti_msgflags == 0)
3623 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3628 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3629 slp->sl_clear_atten = 1;
3631 return ti->ti_msgoutlen;
3634 /**************************************************************
3636 **************************************************************/
3638 scsi_low_msginfunc_noop(slp)
3639 struct scsi_low_softc *slp;
3646 scsi_low_msginfunc_rejop(slp)
3647 struct scsi_low_softc *slp;
3649 struct targ_info *ti = slp->sl_Tnexus;
3650 u_int8_t msg = ti->ti_msgin[0];
3652 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3653 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3658 scsi_low_msginfunc_cc(slp)
3659 struct scsi_low_softc *slp;
3661 struct lun_info *li;
3663 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3665 /* validate status */
3666 if (slp->sl_Qnexus == NULL)
3669 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3670 li = slp->sl_Lnexus;
3671 switch (slp->sl_scp.scp_status)
3674 li->li_maxnqio = li->li_maxnexus;
3679 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3680 scsi_low_reset_nexus_lun(slp, li, 0);
3688 if (li->li_maxnexus >= li->li_nqio)
3689 li->li_maxnexus = li->li_nqio - 1;
3690 li->li_maxnqio = li->li_maxnexus;
3695 slp->sl_error |= MSGERR;
3705 scsi_low_msginfunc_lcc(slp)
3706 struct scsi_low_softc *slp;
3708 struct targ_info *ti;
3709 struct lun_info *li;
3710 struct slccb *ncb, *cb;
3712 ti = slp->sl_Tnexus;
3713 li = slp->sl_Lnexus;
3714 if ((cb = slp->sl_Qnexus) == NULL)
3717 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3718 switch (slp->sl_scp.scp_status)
3722 li->li_maxnqio = li->li_maxnexus;
3726 slp->sl_error |= MSGERR;
3730 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3733 cb->ccb_error |= slp->sl_error;
3734 if (cb->ccb_error != 0)
3737 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3738 ncb = TAILQ_NEXT(ncb, ccb_chain))
3741 goto cmd_link_start;
3746 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3747 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3751 ncb->ccb_flags &= ~CCB_STARTQ;
3752 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3754 scsi_low_dealloc_qtag(ncb);
3755 ncb->ccb_tag = cb->ccb_tag;
3756 ncb->ccb_otag = cb->ccb_otag;
3757 cb->ccb_tag = SCSI_LOW_UNKTAG;
3758 cb->ccb_otag = SCSI_LOW_UNKTAG;
3759 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3760 panic("%s: linked ccb retried", slp->sl_xname);
3762 slp->sl_Qnexus = ncb;
3763 slp->sl_ph_count = 0;
3766 ncb->ccb_datalen = -1;
3767 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3768 ncb->ccb_flags &= ~CCB_INTERNAL;
3770 scsi_low_init_msgsys(slp, ti);
3772 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3774 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3775 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3776 ncb->ccb_tc = ncb->ccb_tcmax;
3778 /* setup saved scsi data pointer */
3779 ncb->ccb_sscp = ncb->ccb_scp;
3780 slp->sl_scp = ncb->ccb_sscp;
3781 slp->sl_error = ncb->ccb_error;
3783 #ifdef SCSI_LOW_DIAGNOSTIC
3784 scsi_low_msg_log_init(&ti->ti_log_msgin);
3785 scsi_low_msg_log_init(&ti->ti_log_msgout);
3786 #endif /* SCSI_LOW_DIAGNOSTIC */
3791 scsi_low_msginfunc_disc(slp)
3792 struct scsi_low_softc *slp;
3795 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3800 scsi_low_msginfunc_sdp(slp)
3801 struct scsi_low_softc *slp;
3803 struct slccb *cb = slp->sl_Qnexus;
3807 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3808 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3811 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3816 scsi_low_msginfunc_rp(slp)
3817 struct scsi_low_softc *slp;
3820 if (slp->sl_Qnexus != NULL)
3821 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3823 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3829 struct scsi_low_softc *slp;
3831 struct targ_info *ti = slp->sl_Tnexus;
3832 u_int period = 0, offset = 0, speed;
3836 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3837 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3838 MSGIN_OFFSET(ti) == 0)
3840 if ((offset = MSGIN_OFFSET(ti)) != 0)
3841 period = MSGIN_PERIOD(ti);
3842 s = offset ? "synchronous" : "async";
3847 * Target seems to be brain damaged.
3848 * Force async transfer.
3850 ti->ti_maxsynch.period = 0;
3851 ti->ti_maxsynch.offset = 0;
3852 printf("%s: target brain damaged. async transfer\n",
3857 ti->ti_maxsynch.period = period;
3858 ti->ti_maxsynch.offset = offset;
3860 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3864 * Current period and offset are not acceptable
3866 * The adapter changes max synch and max offset.
3868 printf("%s: synch neg failed. retry synch msg neg ...\n",
3873 ti->ti_osynch = ti->ti_maxsynch;
3876 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3880 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3882 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3883 struct slccb *cb = slp->sl_Qnexus;
3885 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3887 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3889 printf("%s(%d:*): <%s> offset %d period %dns ",
3890 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3894 speed = 1000 * 10 / (period * 4);
3895 printf("%d.%d M/s", speed / 10, speed % 10);
3904 struct scsi_low_softc *slp;
3906 struct targ_info *ti = slp->sl_Tnexus;
3909 ti->ti_width = MSGIN_WIDTHP(ti);
3910 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3914 * Current width is not acceptable for our adapter.
3915 * The adapter changes max width.
3917 printf("%s: wide neg failed. retry wide msg neg ...\n",
3922 ti->ti_owidth = ti->ti_width;
3923 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3925 ti->ti_setup_msg_done |=
3926 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3930 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3932 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3933 struct slccb *cb = slp->sl_Qnexus;
3935 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3937 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3939 printf("%s(%d:*): transfer width %d bits\n",
3940 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3946 scsi_low_msginfunc_simple_qtag(slp)
3947 struct scsi_low_softc *slp;
3949 struct targ_info *ti = slp->sl_Tnexus;
3950 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3952 if (slp->sl_Qnexus != NULL)
3954 if (slp->sl_Qnexus->ccb_tag != etag)
3956 slp->sl_error |= FATALIO;
3957 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3958 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3961 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3963 #ifdef SCSI_LOW_DEBUG
3964 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3966 #endif /* SCSI_LOW_DEBUG */
3968 slp->sl_error |= FATALIO;
3969 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3970 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3976 scsi_low_msginfunc_i_wide_residue(slp)
3977 struct scsi_low_softc *slp;
3979 struct targ_info *ti = slp->sl_Tnexus;
3980 struct slccb *cb = slp->sl_Qnexus;
3981 int res = (int) ti->ti_msgin[1];
3983 if (cb == NULL || res <= 0 ||
3984 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3985 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3988 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3991 slp->sl_scp.scp_datalen += res;
3992 slp->sl_scp.scp_data -= res;
3993 scsi_low_data_finish(slp);
3998 scsi_low_msginfunc_ext(slp)
3999 struct scsi_low_softc *slp;
4001 struct slccb *cb = slp->sl_Qnexus;
4002 struct lun_info *li = slp->sl_Lnexus;
4003 struct targ_info *ti = slp->sl_Tnexus;
4007 if (ti->ti_msginptr == 2)
4009 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4013 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4015 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4019 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4020 count = (int) htonl((long) (*ptr));
4021 if(slp->sl_scp.scp_datalen - count < 0 ||
4022 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4025 slp->sl_scp.scp_datalen -= count;
4026 slp->sl_scp.scp_data += count;
4029 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4033 retry = scsi_low_synch(slp);
4034 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4035 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4037 #ifdef SCSI_LOW_DEBUG
4038 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4040 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4042 #endif /* SCSI_LOW_DEBUG */
4045 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4049 retry = scsi_low_wide(slp);
4050 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4051 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4059 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4064 scsi_low_msginfunc_parity(slp)
4065 struct scsi_low_softc *slp;
4067 struct targ_info *ti = slp->sl_Tnexus;
4069 /* only I -> T, invalid! */
4070 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4075 scsi_low_msginfunc_msg_reject(slp)
4076 struct scsi_low_softc *slp;
4078 struct targ_info *ti = slp->sl_Tnexus;
4079 struct scsi_low_msgout_data *mdp;
4082 if (ti->ti_emsgflags != 0)
4084 printf("%s: msg flags [0x%x] rejected\n",
4085 slp->sl_xname, ti->ti_emsgflags);
4086 msgflags = SCSI_LOW_MSG_REJECT;
4087 mdp = &scsi_low_msgout_data[0];
4088 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4090 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4092 ti->ti_emsgflags &= ~mdp->md_flags;
4093 if (mdp->md_errfunc != NULL)
4094 (*mdp->md_errfunc) (slp, msgflags);
4102 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4103 slp->sl_error |= MSGERR;
4109 scsi_low_msgin(slp, ti, c)
4110 struct scsi_low_softc *slp;
4111 struct targ_info *ti;
4114 struct scsi_low_msgin_data *sdp;
4115 struct lun_info *li;
4118 #ifdef SCSI_LOW_DIAGNOSTIC
4119 if (ti != slp->sl_Tnexus)
4121 scsi_low_print(slp, NULL);
4122 panic("scsi_low_msgin: Target nexus inconsistent");
4124 #endif /* SCSI_LOW_DIAGNOSTIC */
4127 * Phase changes, clear the pointer.
4129 if (ti->ti_ophase != ti->ti_phase)
4132 ti->ti_msgin_parity_error = 0;
4134 slp->sl_ph_count ++;
4135 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4137 printf("%s: too many phase changes\n", slp->sl_xname);
4138 slp->sl_error |= FATALIO;
4139 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4144 * Store a current messages byte into buffer and
4145 * wait for the completion of the current msg.
4147 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4148 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4150 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4151 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4155 * Check parity errors.
4157 if ((c & SCSI_LOW_DATA_PE) != 0)
4159 ti->ti_msgin_parity_error ++;
4160 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4164 if (ti->ti_msgin_parity_error != 0)
4168 * Calculate messages length.
4170 msg = ti->ti_msgin[0];
4171 if (msg < MSGIN_DATA_LAST)
4172 sdp = &scsi_low_msgin_data[msg];
4174 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4176 if (ti->ti_msginlen == 0)
4178 ti->ti_msginlen = sdp->md_len;
4184 if (ti->ti_msginptr < ti->ti_msginlen)
4190 if ((msg & MSG_IDENTIFY) == 0)
4192 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4197 li = slp->sl_Lnexus;
4200 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4203 slp->sl_Lnexus = li;
4204 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4208 if (MSGCMD_LUN(msg) != li->li_lun)
4212 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4214 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4216 #ifdef SCSI_LOW_DEBUG
4217 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4221 #endif /* SCSI_LOW_DEBUG */
4229 * Msg process completed, reset msgin pointer and assert ATN if desired.
4232 slp->sl_error |= FATALIO;
4233 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4234 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4237 if (ti->ti_msginptr < ti->ti_msginlen)
4240 #ifdef SCSI_LOW_DIAGNOSTIC
4241 scsi_low_msg_log_write(&ti->ti_log_msgin,
4242 &ti->ti_msgin[0], ti->ti_msginlen);
4243 #endif /* SCSI_LOW_DIAGNOSTIC */
4249 /**********************************************************
4251 **********************************************************/
4253 scsi_low_disconnected(slp, ti)
4254 struct scsi_low_softc *slp;
4255 struct targ_info *ti;
4257 struct slccb *cb = slp->sl_Qnexus;
4259 /* check phase completion */
4260 switch (slp->sl_msgphase)
4263 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4264 scsi_low_msginfunc_cc(slp);
4265 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4269 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4270 scsi_low_msginfunc_cc(slp);
4271 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4275 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4276 scsi_low_msginfunc_cc(slp);
4282 struct lun_info *li;
4285 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4286 cb->ccb_flags |= CCB_DISCQ;
4287 cb->ccb_error |= slp->sl_error;
4293 #ifdef SCSI_LOW_STATICS
4294 scsi_low_statics.nexus_disconnected ++;
4295 #endif /* SCSI_LOW_STATICS */
4297 #ifdef SCSI_LOW_DEBUG
4298 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4300 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4301 scsi_low_print(slp, NULL);
4303 #endif /* SCSI_LOW_DEBUG */
4307 slp->sl_error |= FATALIO;
4308 if (ti->ti_phase == PH_SELSTART)
4309 slp->sl_error |= SELTIMEOUTIO;
4311 slp->sl_error |= UBFERR;
4320 #ifdef SCSI_LOW_DEBUG
4321 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4323 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4324 (cb->ccb_msgoutflag != 0 ||
4325 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4327 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4330 #endif /* SCSI_LOW_DEBUG */
4332 cb->ccb_error |= slp->sl_error;
4333 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4335 cb->ccb_flags |= CCB_STARTQ;
4336 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4341 scsi_low_bus_release(slp, ti);
4342 scsi_low_start(slp);
4346 /**********************************************************
4348 **********************************************************/
4350 scsi_low_alloc_qtag(cb)
4353 struct lun_info *li = cb->li;
4354 scsi_low_tag_t etag;
4356 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4359 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4360 etag = ffs(li->li_qtagbits);
4364 li->li_qtagbits &= ~(1 << (etag - 1));
4365 cb->ccb_otag = etag;
4368 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4369 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4370 if (li->li_qtagarray[li->li_qd] == 0)
4373 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4374 if (li->li_qtagarray[li->li_qd] == 0)
4380 li->li_qtagarray[li->li_qd] ++;
4381 cb->ccb_otag = (li->li_qd ++);
4383 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4387 scsi_low_dealloc_qtag(cb)
4390 struct lun_info *li = cb->li;
4391 scsi_low_tag_t etag;
4393 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4396 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4397 etag = cb->ccb_otag - 1;
4398 #ifdef SCSI_LOW_DIAGNOSTIC
4399 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4400 panic("scsi_low_dealloc_tag: illegal tag");
4401 #endif /* SCSI_LOW_DIAGNOSTIC */
4402 li->li_qtagbits |= (1 << etag);
4404 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4405 etag = cb->ccb_otag;
4406 #ifdef SCSI_LOW_DIAGNOSTIC
4407 if (etag >= SCSI_LOW_MAXNEXUS)
4408 panic("scsi_low_dealloc_tag: illegal tag");
4409 #endif /* SCSI_LOW_DIAGNOSTIC */
4410 li->li_qtagarray[etag] --;
4411 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4413 cb->ccb_otag = SCSI_LOW_UNKTAG;
4418 scsi_low_revoke_ccb(slp, cb, fdone)
4419 struct scsi_low_softc *slp;
4423 struct targ_info *ti = cb->ti;
4424 struct lun_info *li = cb->li;
4426 #ifdef SCSI_LOW_DIAGNOSTIC
4427 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4428 (CCB_STARTQ | CCB_DISCQ))
4430 panic("%s: ccb in both queue", slp->sl_xname);
4432 #endif /* SCSI_LOW_DIAGNOSTIC */
4434 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4436 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4439 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4441 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4447 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4448 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4451 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4452 (cb->ccb_flags & CCB_NORETRY) != 0))
4454 cb->ccb_error |= FATALIO;
4455 cb->ccb_flags &= ~CCB_AUTOSENSE;
4456 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4457 panic("%s: done ccb retried", slp->sl_xname);
4462 cb->ccb_error |= PENDINGIO;
4463 scsi_low_deactivate_qtag(cb);
4464 scsi_low_ccb_message_retry(cb);
4465 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4471 scsi_low_reset_nexus_lun(slp, li, fdone)
4472 struct scsi_low_softc *slp;
4473 struct lun_info *li;
4476 struct slccb *cb, *ncb, *ecb;
4482 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4484 ncb = TAILQ_NEXT(cb, ccb_chain);
4485 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4489 * presumely keep ordering of io
4491 cb->ccb_flags |= CCB_STARTQ;
4494 TAILQ_INSERT_HEAD(&slp->sl_start,\
4499 TAILQ_INSERT_AFTER(&slp->sl_start,\
4500 ecb, cb, ccb_chain);
4507 /**************************************************************
4509 **************************************************************/
4511 scsi_low_calcf_lun(li)
4512 struct lun_info *li;
4514 struct targ_info *ti = li->li_ti;
4515 struct scsi_low_softc *slp = ti->ti_sc;
4516 u_int cfgflags, diskflags;
4518 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4519 cfgflags = li->li_cfgflags;
4523 diskflags = li->li_diskflags & li->li_quirks;
4526 li->li_flags &= ~SCSI_LOW_DISC;
4527 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4528 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4529 (cfgflags & SCSI_LOW_DISC) != 0)
4530 li->li_flags |= SCSI_LOW_DISC;
4533 li->li_flags |= SCSI_LOW_NOPARITY;
4534 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4535 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4536 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4537 li->li_flags &= ~SCSI_LOW_NOPARITY;
4540 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4541 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4542 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4544 li->li_flags |= SCSI_LOW_QTAG;
4545 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4546 li->li_maxnqio = li->li_maxnexus;
4550 li->li_flags &= ~SCSI_LOW_QTAG;
4551 li->li_maxnexus = 0;
4552 li->li_maxnqio = li->li_maxnexus;
4556 li->li_flags &= ~SCSI_LOW_LINK;
4557 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4558 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4559 li->li_flags |= SCSI_LOW_LINK;
4561 /* compatible flags */
4562 li->li_flags &= ~SCSI_LOW_SYNC;
4563 if (ti->ti_maxsynch.offset > 0)
4564 li->li_flags |= SCSI_LOW_SYNC;
4566 #ifdef SCSI_LOW_DEBUG
4567 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4569 scsi_low_calcf_show(li);
4571 #endif /* SCSI_LOW_DEBUG */
4575 scsi_low_calcf_target(ti)
4576 struct targ_info *ti;
4578 struct scsi_low_softc *slp = ti->ti_sc;
4579 u_int offset, period, diskflags;
4581 diskflags = ti->ti_diskflags & ti->ti_quirks;
4584 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4585 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4587 offset = ti->ti_maxsynch.offset;
4588 period = ti->ti_maxsynch.period;
4589 if (offset == 0 || period == 0)
4590 offset = period = 0;
4594 offset = period = 0;
4597 ti->ti_maxsynch.offset = offset;
4598 ti->ti_maxsynch.period = period;
4601 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4602 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4603 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4605 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4606 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4607 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4609 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4611 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4612 ti->ti_maxsynch.period != ti->ti_osynch.period)
4613 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4614 if (ti->ti_width != ti->ti_owidth)
4615 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4617 ti->ti_osynch = ti->ti_maxsynch;
4618 ti->ti_owidth = ti->ti_width;
4621 #ifdef SCSI_LOW_DEBUG
4622 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4624 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4625 slp->sl_xname, ti->ti_id,
4626 ti->ti_maxsynch.period * 4,
4627 ti->ti_maxsynch.offset,
4630 #endif /* SCSI_LOW_DEBUG */
4634 scsi_low_calcf_show(li)
4635 struct lun_info *li;
4637 struct targ_info *ti = li->li_ti;
4638 struct scsi_low_softc *slp = ti->ti_sc;
4640 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4641 slp->sl_xname, ti->ti_id, li->li_lun,
4642 ti->ti_maxsynch.period * 4,
4643 ti->ti_maxsynch.offset,
4645 li->li_flags, SCSI_LOW_BITS);
4648 #ifdef SCSI_LOW_START_UP_CHECK
4649 /**************************************************************
4650 * scsi world start up
4651 **************************************************************/
4652 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
4655 scsi_low_start_up(slp)
4656 struct scsi_low_softc *slp;
4658 struct targ_info *ti;
4659 struct lun_info *li;
4663 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4665 for (target = 0; target < slp->sl_ntargs; target ++)
4667 if (target == slp->sl_hostid)
4669 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4671 printf("%s: scsi_low: target %d (host card)\n",
4672 slp->sl_xname, target);
4677 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4679 printf("%s: scsi_low: target %d lun ",
4680 slp->sl_xname, target);
4683 ti = slp->sl_ti[target];
4684 for (lun = 0; lun < slp->sl_nluns; lun ++)
4686 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4692 li = scsi_low_alloc_li(ti, lun, 1);
4694 scsi_low_enqueue(slp, ti, li, cb,
4695 CCB_AUTOSENSE | CCB_POLLED, 0);
4697 scsi_low_poll(slp, cb);
4699 if (li->li_state != SCSI_LOW_LUN_OK)
4702 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4708 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4717 scsi_low_poll(slp, cb)
4718 struct scsi_low_softc *slp;
4724 while (slp->sl_nio > 0)
4726 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4728 (*slp->sl_funcs->scsi_low_poll) (slp);
4729 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4733 scsi_low_timeout_check(slp);
4738 #endif /* SCSI_LOW_START_UP_CHECK */
4740 /**********************************************************
4742 **********************************************************/
4743 #ifdef SCSI_LOW_DEBUG
4745 scsi_low_test_abort(slp, ti, li)
4746 struct scsi_low_softc *slp;
4747 struct targ_info *ti;
4748 struct lun_info *li;
4752 if (li->li_disc > 1)
4754 acb = TAILQ_FIRST(&li->li_discq);
4755 if (scsi_low_abort_ccb(slp, acb) == 0)
4757 printf("%s: aborting ccb(0x%lx) start\n",
4758 slp->sl_xname, (u_long) acb);
4764 scsi_low_test_atten(slp, ti, msg)
4765 struct scsi_low_softc *slp;
4766 struct targ_info *ti;
4770 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4771 scsi_low_assert_msg(slp, ti, msg, 0);
4773 printf("%s: atten check OK\n", slp->sl_xname);
4777 scsi_low_test_cmdlnk(slp, cb)
4778 struct scsi_low_softc *slp;
4781 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4783 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4786 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4787 slp->sl_scp.scp_cmdlen);
4788 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4789 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4791 #endif /* SCSI_LOW_DEBUG */
4794 scsi_low_info(slp, ti, s)
4795 struct scsi_low_softc *slp;
4796 struct targ_info *ti;
4801 slp = LIST_FIRST(&sl_tab);
4805 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4808 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4809 ti = TAILQ_NEXT(ti, ti_chain))
4811 scsi_low_print(slp, ti);
4816 scsi_low_print(slp, ti);
4820 static u_char *phase[] =
4822 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4823 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4827 scsi_low_print(slp, ti)
4828 struct scsi_low_softc *slp;
4829 struct targ_info *ti;
4831 struct lun_info *li;
4835 if (ti == NULL || ti == slp->sl_Tnexus)
4837 ti = slp->sl_Tnexus;
4838 li = slp->sl_Lnexus;
4839 cb = slp->sl_Qnexus;
4843 li = LIST_FIRST(&ti->ti_litab);
4844 cb = TAILQ_FIRST(&li->li_discq);
4848 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4849 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4855 u_int flags = 0, maxnqio = 0, nqio = 0;
4861 flags = li->li_flags;
4862 maxnqio = li->li_maxnqio;
4866 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4868 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4869 phase[(int) ti->ti_phase], ti->ti_disc,
4874 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4875 (u_int) cb->ccb_scp.scp_cmd[0],
4876 cb->ccb_scp.scp_cmdlen,
4878 cb->ccb_scp.scp_datalen,
4879 (u_int) cb->ccb_sscp.scp_status,
4880 cb->ccb_error, SCSI_LOW_ERRORBITS);
4883 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4884 (u_int) (ti->ti_msginptr),
4885 (u_int) (ti->ti_msgin[0]),
4886 (u_int) (ti->ti_msgin[1]),
4887 (u_int) (ti->ti_msgin[2]),
4888 (u_int) (ti->ti_msgin[3]),
4889 (u_int) (ti->ti_msgin[4]),
4892 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4893 (u_int) ti->ti_msgflags,
4894 (u_int) (ti->ti_msgoutstr[0]),
4895 (u_int) (ti->ti_msgoutstr[1]),
4896 (u_int) (ti->ti_msgoutstr[2]),
4897 (u_int) (ti->ti_msgoutstr[3]),
4898 (u_int) (ti->ti_msgoutstr[4]),
4900 flags, SCSI_LOW_BITS);
4902 #ifdef SCSI_LOW_DIAGNOSTIC
4903 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4904 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4905 #endif /* SCSI_LOW_DIAGNOSTIC */
4909 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4910 (u_long) sp->scp_data,
4912 (u_int) sp->scp_status,
4913 slp->sl_error, SCSI_LOW_ERRORBITS);