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.9 2004/03/15 01:10:31 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 /* __DragonFly__ */
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 #include <machine/clock.h>
76 #include <sys/devicestat.h>
77 #endif /* __DragonFly__ */
80 #include <sys/queue.h>
81 #include <sys/malloc.h>
82 #include <sys/errno.h>
85 #include <sys/device.h>
88 #include <machine/bus.h>
89 #include <machine/intr.h>
90 #include <machine/dvcfg.h>
94 #include <dev/scsipi/scsipi_all.h>
95 #include <dev/scsipi/scsipiconf.h>
96 #include <dev/scsipi/scsipi_disk.h>
97 #include <dev/scsipi/scsi_all.h>
98 #include <dev/scsipi/scsiconf.h>
99 #include <sys/scsiio.h>
101 #include <i386/Cbus/dev/scsi_low.h>
102 #endif /* __NetBSD__ */
105 #include <bus/cam/cam.h>
106 #include <bus/cam/cam_ccb.h>
107 #include <bus/cam/cam_sim.h>
108 #include <bus/cam/cam_debug.h>
109 #include <bus/cam/cam_periph.h>
111 #include "scsi_all.h"
112 #include "scsi_message.h"
114 #include "scsi_low.h"
116 #include <sys/cons.h>
117 #endif /* __DragonFly__ */
119 /**************************************************************
121 **************************************************************/
122 #define SCSI_LOW_POLL_HZ 1000
124 /* functions return values */
125 #define SCSI_LOW_START_NO_QTAG 0
126 #define SCSI_LOW_START_QTAG 1
128 #define SCSI_LOW_DONE_COMPLETE 0
129 #define SCSI_LOW_DONE_RETRY 1
131 /* internal disk flags */
132 #define SCSI_LOW_DISK_DISC 0x00000001
133 #define SCSI_LOW_DISK_QTAG 0x00000002
134 #define SCSI_LOW_DISK_LINK 0x00000004
135 #define SCSI_LOW_DISK_PARITY 0x00000008
136 #define SCSI_LOW_DISK_SYNC 0x00010000
137 #define SCSI_LOW_DISK_WIDE_16 0x00020000
138 #define SCSI_LOW_DISK_WIDE_32 0x00040000
139 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
140 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
141 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
143 /**************************************************************
145 **************************************************************/
146 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
147 static void scsi_low_engage (void *);
148 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
149 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
150 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
151 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
152 static void scsi_low_twiddle_wait (void);
153 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
154 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
155 static void scsi_low_calcf_lun (struct lun_info *);
156 static void scsi_low_calcf_target (struct targ_info *);
157 static void scsi_low_calcf_show (struct lun_info *);
158 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
159 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
160 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
161 static int scsi_low_init (struct scsi_low_softc *, u_int);
162 static void scsi_low_start (struct scsi_low_softc *);
163 static void scsi_low_free_ti (struct scsi_low_softc *);
165 static int scsi_low_alloc_qtag (struct slccb *);
166 static int scsi_low_dealloc_qtag (struct slccb *);
167 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
168 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
169 static void scsi_low_unit_ready_cmd (struct slccb *);
170 static void scsi_low_timeout (void *);
171 static int scsi_low_timeout_check (struct scsi_low_softc *);
172 #ifdef SCSI_LOW_START_UP_CHECK
173 static int scsi_low_start_up (struct scsi_low_softc *);
174 #endif /* SCSI_LOW_START_UP_CHECK */
175 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
176 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
178 int scsi_low_version_major = 2;
179 int scsi_low_version_minor = 17;
181 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
183 /**************************************************************
184 * Debug, Run test and Statics
185 **************************************************************/
186 #ifdef SCSI_LOW_INFO_DETAIL
187 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
188 #else /* !SCSI_LOW_INFO_DETAIL */
189 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
190 #endif /* !SCSI_LOW_INFO_DETAIL */
192 #ifdef SCSI_LOW_STATICS
193 struct scsi_low_statics {
196 int nexus_disconnected;
197 int nexus_reselected;
200 #endif /* SCSI_LOW_STATICS */
202 #ifdef SCSI_LOW_DEBUG
203 #define SCSI_LOW_DEBUG_DONE 0x00001
204 #define SCSI_LOW_DEBUG_DISC 0x00002
205 #define SCSI_LOW_DEBUG_SENSE 0x00004
206 #define SCSI_LOW_DEBUG_CALCF 0x00008
207 #define SCSI_LOW_DEBUG_ACTION 0x10000
208 int scsi_low_debug = 0;
210 #define SCSI_LOW_MAX_ATTEN_CHECK 32
211 #define SCSI_LOW_ATTEN_CHECK 0x0001
212 #define SCSI_LOW_CMDLNK_CHECK 0x0002
213 #define SCSI_LOW_ABORT_CHECK 0x0004
214 #define SCSI_LOW_NEXUS_CHECK 0x0008
215 int scsi_low_test = 0;
216 int scsi_low_test_id = 0;
218 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
219 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
220 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
221 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
222 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
223 #define SCSI_LOW_DEBUG_GO(fl, id) \
224 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
225 #endif /* SCSI_LOW_DEBUG */
227 /**************************************************************
229 **************************************************************/
230 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
231 GENERIC_CCB(scsi_low, slccb, ccb_chain)
233 /**************************************************************
235 **************************************************************/
236 #define SCSI_LOW_INLINE static __inline
237 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
238 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
239 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
240 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
241 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
242 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
243 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
246 scsi_low_activate_qtag(cb)
249 struct lun_info *li = cb->li;
251 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
255 cb->ccb_tag = cb->ccb_otag;
259 scsi_low_deactivate_qtag(cb)
262 struct lun_info *li = cb->li;
264 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
268 cb->ccb_tag = SCSI_LOW_UNKTAG;
272 scsi_low_ccb_message_exec(slp, cb)
273 struct scsi_low_softc *slp;
277 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
278 cb->ccb_msgoutflag = 0;
282 scsi_low_ccb_message_assert(cb, msg)
287 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
291 scsi_low_ccb_message_retry(cb)
294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
298 scsi_low_ccb_message_clear(cb)
301 cb->ccb_msgoutflag = 0;
305 scsi_low_init_msgsys(slp, ti)
306 struct scsi_low_softc *slp;
307 struct targ_info *ti;
311 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
312 SCSI_LOW_DEASSERT_ATN(slp);
313 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
316 /*=============================================================
317 * START OF OS switch (All OS depend fucntions should be here)
318 =============================================================*/
319 /* common os depend utitlities */
320 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
321 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
322 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
324 static u_int8_t scsi_low_cmd_flags[256] = {
325 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
326 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
327 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
328 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
329 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
332 struct scsi_low_error_code {
337 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
338 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
340 static struct slccb *
341 scsi_low_find_ccb(slp, target, lun, osdep)
342 struct scsi_low_softc *slp;
346 struct targ_info *ti;
350 ti = slp->sl_ti[target];
351 li = scsi_low_alloc_li(ti, lun, 0);
355 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
358 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
359 cb = TAILQ_NEXT(cb, ccb_chain))
361 if (cb->osdep == osdep)
365 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
366 cb = TAILQ_NEXT(cb, ccb_chain))
368 if (cb->osdep == osdep)
375 scsi_low_translate_error_code(cb, tp)
377 struct scsi_low_error_code *tp;
380 if (cb->ccb_error == 0)
381 return tp->error_code;
383 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
385 return tp->error_code;
388 #ifdef SCSI_LOW_INTERFACE_XS
389 /**************************************************************
390 * SCSI INTERFACE (XS)
391 **************************************************************/
392 #define SCSI_LOW_MINPHYS 0x10000
393 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_INTWAIT)
394 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
395 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
396 #define SCSI_LOW_XS_POLL_HZ 1000
398 static int scsi_low_poll_xs (struct scsi_low_softc *, struct slccb *));
399 static void scsi_low_scsi_minphys_xs (struct buf *);
400 #ifdef SCSI_LOW_TARGET_OPEN
401 static int scsi_low_target_open (struct scsipi_link *, struct cfdata *);
402 #endif /* SCSI_LOW_TARGET_OPEN */
403 static int scsi_low_scsi_cmd_xs (struct scsipi_xfer *);
404 static int scsi_low_enable_xs (void *, int);
405 static int scsi_low_ioctl_xs (struct scsipi_link *, u_long, caddr_t, int, struct proc *);
407 static int scsi_low_attach_xs (struct scsi_low_softc *);
408 static int scsi_low_world_start_xs (struct scsi_low_softc *);
409 static int scsi_low_dettach_xs (struct scsi_low_softc *);
410 static int scsi_low_ccb_setup_xs (struct scsi_low_softc *, struct slccb *);
411 static int scsi_low_done_xs (struct scsi_low_softc *, struct slccb *);
412 static void scsi_low_timeout_xs (struct scsi_low_softc *, int, int);
413 static u_int scsi_low_translate_quirks_xs (u_int);
414 static void scsi_low_setup_quirks_xs (struct targ_info *, struct lun_info *, u_int);
416 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
418 scsi_low_world_start_xs,
420 scsi_low_ccb_setup_xs,
425 struct scsipi_device scsi_low_dev = {
426 NULL, /* Use default error handler */
427 NULL, /* have a queue, served by this */
428 NULL, /* have no async handler */
429 NULL, /* Use default 'done' routine */
432 struct scsi_low_error_code scsi_low_error_code_xs[] = {
436 {SELTIMEOUTIO, XS_SELTIMEOUT},
437 {TIMEOUTIO, XS_TIMEOUT},
438 {-1, XS_DRIVER_STUFFUP}
442 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
443 struct scsipi_link *link;
449 struct scsi_low_softc *slp;
450 int s, error = ENOTTY;
452 slp = (struct scsi_low_softc *) link->adapter_softc;
453 if ((slp->sl_flags & HW_INACTIVE) != 0)
456 if (cmd == SCBUSIORESET)
458 s = SCSI_LOW_SPLSCSI();
459 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
463 else if (slp->sl_funcs->scsi_low_ioctl != 0)
465 error = (*slp->sl_funcs->scsi_low_ioctl)
466 (slp, cmd, addr, flag, p);
473 scsi_low_enable_xs(arg, enable)
477 struct scsi_low_softc *slp = arg;
481 if ((slp->sl_flags & HW_INACTIVE) != 0)
486 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
487 (slp->sl_flags & HW_POWERCTRL) == 0)
490 slp->sl_flags |= HW_POWDOWN;
491 if (slp->sl_funcs->scsi_low_power != NULL)
493 (*slp->sl_funcs->scsi_low_power)
494 (slp, SCSI_LOW_POWDOWN);
501 scsi_low_scsi_minphys_xs(bp)
505 if (bp->b_bcount > SCSI_LOW_MINPHYS)
506 bp->b_bcount = SCSI_LOW_MINPHYS;
511 scsi_low_poll_xs(slp, cb)
512 struct scsi_low_softc *slp;
515 struct scsipi_xfer *xs = cb->osdep;
518 cb->ccb_flags |= CCB_NOSDONE;
521 while (slp->sl_nio > 0)
523 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
525 (*slp->sl_funcs->scsi_low_poll) (slp);
527 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
529 cb->ccb_flags |= CCB_NORETRY;
530 cb->ccb_error |= FATALIO;
531 (void) scsi_low_revoke_ccb(slp, cb, 1);
532 printf("%s: hardware inactive in poll mode\n",
536 if ((xs->flags & ITSDONE) != 0)
539 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
543 scsi_low_timeout_check(slp);
546 xs->flags |= ITSDONE;
552 scsi_low_scsi_cmd_xs(xs)
553 struct scsipi_xfer *xs;
555 struct scsipi_link *splp = xs->sc_link;
556 struct scsi_low_softc *slp = splp->adapter_softc;
557 struct targ_info *ti;
560 int s, targ, lun, flags, rv;
562 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
563 return TRY_AGAIN_LATER;
565 targ = splp->scsipi_scsi.target,
566 lun = splp->scsipi_scsi.lun;
567 ti = slp->sl_ti[targ];
572 if ((xs->flags & SCSI_POLL) == 0)
573 flags = CCB_AUTOSENSE;
575 flags = CCB_AUTOSENSE | CCB_POLLED;
578 s = SCSI_LOW_SPLSCSI();
579 li = scsi_low_alloc_li(ti, lun, 1);
580 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
582 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
585 if ((xs->flags & SCSI_RESET) != 0)
587 flags |= CCB_NORETRY | CCB_URGENT;
588 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
592 if (ti->ti_setup_msg != 0)
594 scsi_low_message_enqueue(slp, ti, li, flags);
598 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
601 #ifdef SCSI_LOW_DEBUG
602 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
604 scsi_low_test_abort(slp, ti, li);
606 #endif /* SCSI_LOW_DEBUG */
608 if ((cb->ccb_flags & CCB_POLLED) != 0)
610 rv = scsi_low_poll_xs(slp, cb);
614 rv = SUCCESSFULLY_QUEUED;
621 scsi_low_attach_xs(slp)
622 struct scsi_low_softc *slp;
624 struct scsipi_adapter *sap;
625 struct scsipi_link *splp;
627 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
629 sap = SCSI_LOW_MALLOC(sizeof(*sap));
632 splp = SCSI_LOW_MALLOC(sizeof(*splp));
636 SCSI_LOW_BZERO(sap, sizeof(*sap));
637 SCSI_LOW_BZERO(splp, sizeof(*splp));
639 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
640 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
641 sap->scsipi_enable = scsi_low_enable_xs;
642 sap->scsipi_ioctl = scsi_low_ioctl_xs;
643 #ifdef SCSI_LOW_TARGET_OPEN
644 sap->open_target_lu = scsi_low_target_open;
645 #endif /* SCSI_LOW_TARGET_OPEN */
647 splp->adapter_softc = slp;
648 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
649 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
650 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
651 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
652 splp->openings = slp->sl_openings;
653 splp->type = BUS_SCSI;
654 splp->adapter_softc = slp;
656 splp->device = &scsi_low_dev;
658 slp->sl_si.si_splp = splp;
659 slp->sl_show_result = SHOW_ALL_NEG;
664 scsi_low_world_start_xs(slp)
665 struct scsi_low_softc *slp;
672 scsi_low_dettach_xs(slp)
673 struct scsi_low_softc *slp;
677 * scsipi does not have dettach bus fucntion.
679 scsipi_dettach_scsibus(slp->sl_si.si_splp);
685 scsi_low_ccb_setup_xs(slp, cb)
686 struct scsi_low_softc *slp;
689 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
691 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
693 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
694 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
695 cb->ccb_scp.scp_data = xs->data;
696 cb->ccb_scp.scp_datalen = xs->datalen;
697 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
698 SCSI_LOW_WRITE : SCSI_LOW_READ;
699 cb->ccb_tcmax = xs->timeout / 1000;
703 scsi_low_unit_ready_cmd(cb);
705 return SCSI_LOW_START_QTAG;
709 scsi_low_done_xs(slp, cb)
710 struct scsi_low_softc *slp;
713 struct scsipi_xfer *xs;
715 xs = (struct scsipi_xfer *) cb->osdep;
716 if (cb->ccb_error == 0)
718 xs->error = XS_NOERROR;
723 if (cb->ccb_rcnt >= slp->sl_max_retry)
724 cb->ccb_error |= ABORTIO;
726 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
727 (cb->ccb_error & ABORTIO) == 0)
730 if ((cb->ccb_error & SENSEIO) != 0)
732 xs->sense.scsi_sense = cb->ccb_sense;
735 xs->error = scsi_low_translate_error_code(cb,
736 &scsi_low_error_code_xs[0]);
738 #ifdef SCSI_LOW_DIAGNOSTIC
739 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
740 cb->ccb_scp.scp_cmdlen > 0 &&
741 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
742 SCSI_LOW_CMD_ABORT_WARNING) != 0)
744 printf("%s: WARNING: scsi_low IO abort\n",
746 scsi_low_print(slp, NULL);
748 #endif /* SCSI_LOW_DIAGNOSTIC */
751 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
752 xs->status = 0; /* XXX */
754 xs->status = cb->ccb_scp.scp_status;
756 xs->flags |= ITSDONE;
757 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
764 scsi_low_timeout_xs(slp, ch, action)
765 struct scsi_low_softc *slp;
772 case SCSI_LOW_TIMEOUT_CH_IO:
775 case SCSI_LOW_TIMEOUT_START:
776 timeout(scsi_low_timeout, slp,
777 hz / SCSI_LOW_TIMEOUT_HZ);
779 case SCSI_LOW_TIMEOUT_STOP:
780 untimeout(scsi_low_timeout, slp);
785 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
788 case SCSI_LOW_TIMEOUT_START:
789 timeout(scsi_low_engage, slp, 1);
791 case SCSI_LOW_TIMEOUT_STOP:
792 untimeout(scsi_low_engage, slp);
797 case SCSI_LOW_TIMEOUT_CH_RECOVER:
803 scsi_low_translate_quirks_xs(quirks)
808 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
811 if (quirks & SDEV_NODISC)
812 flags &= ~SCSI_LOW_DISK_DISC;
813 #endif /* SDEV_NODISC */
815 if (quirks & SDEV_NOPARITY)
816 flags &= ~SCSI_LOW_DISK_PARITY;
817 #endif /* SDEV_NOPARITY */
819 if (quirks & SDEV_NOCMDLNK)
820 flags &= ~SCSI_LOW_DISK_LINK;
821 #endif /* SDEV_NOCMDLNK */
823 if (quirks & SDEV_NOTAG)
824 flags &= ~SCSI_LOW_DISK_QTAG;
825 #endif /* SDEV_NOTAG */
827 if (quirks & SDEV_NOSYNC)
828 flags &= ~SCSI_LOW_DISK_SYNC;
829 #endif /* SDEV_NOSYNC */
835 scsi_low_setup_quirks_xs(ti, li, flags)
836 struct targ_info *ti;
842 li->li_sloi.sloi_quirks = flags;
843 quirks = scsi_low_translate_quirks_xs(flags);
844 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
845 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
846 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
847 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
848 scsi_low_calcf_target(ti);
849 scsi_low_calcf_lun(li);
850 scsi_low_calcf_show(li);
853 #ifdef SCSI_LOW_TARGET_OPEN
855 scsi_low_target_open(link, cf)
856 struct scsipi_link *link;
859 u_int target = link->scsipi_scsi.target;
860 u_int lun = link->scsipi_scsi.lun;
861 struct scsi_low_softc *slp;
862 struct targ_info *ti;
865 slp = (struct scsi_low_softc *) link->adapter_softc;
866 ti = slp->sl_ti[target];
867 li = scsi_low_alloc_li(ti, lun, 0);
871 li->li_cfgflags = cf->cf_flags;
872 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
875 #endif /* SCSI_LOW_TARGET_OPEN */
877 #endif /* SCSI_LOW_INTERFACE_XS */
879 #ifdef SCSI_LOW_INTERFACE_CAM
880 /**************************************************************
881 * SCSI INTERFACE (CAM)
882 **************************************************************/
883 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_INTWAIT)
884 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
885 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
887 static void scsi_low_poll_cam (struct cam_sim *);
888 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
889 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
890 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
892 static int scsi_low_attach_cam (struct scsi_low_softc *);
893 static int scsi_low_world_start_cam (struct scsi_low_softc *);
894 static int scsi_low_dettach_cam (struct scsi_low_softc *);
895 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
896 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
897 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
899 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
901 scsi_low_world_start_cam,
902 scsi_low_dettach_cam,
903 scsi_low_ccb_setup_cam,
908 struct scsi_low_error_code scsi_low_error_code_cam[] = {
910 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
911 {SENSEERR, CAM_AUTOSENSE_FAIL},
912 {UACAERR, CAM_SCSI_STATUS_ERROR},
913 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
914 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
915 {TIMEOUTIO, CAM_CMD_TIMEOUT},
916 {PDMAERR, CAM_DATA_RUN_ERR},
917 {PARITYERR, CAM_UNCOR_PARITY},
918 {UBFERR, CAM_UNEXP_BUSFREE},
919 {ABORTIO, CAM_REQ_ABORTED},
920 {-1, CAM_UNREC_HBA_ERROR}
923 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
926 * Please check a polling hz, currently we assume scsi_low_poll() is
929 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
932 scsi_low_poll_cam(sim)
935 struct scsi_low_softc *slp = SIM2SLP(sim);
937 (*slp->sl_funcs->scsi_low_poll) (slp);
939 if (slp->sl_si.si_poll_count ++ >=
940 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
942 slp->sl_si.si_poll_count = 0;
943 scsi_low_timeout_check(slp);
948 scsi_low_cam_rescan_callback(periph, ccb)
949 struct cam_periph *periph;
953 xpt_free_path(ccb->ccb_h.path);
958 scsi_low_rescan_bus_cam(slp)
959 struct scsi_low_softc *slp;
961 struct cam_path *path;
962 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_INTWAIT);
965 bzero(ccb, sizeof(union ccb));
967 status = xpt_create_path(&path, xpt_periph,
968 cam_sim_path(slp->sl_si.sim), -1, 0);
969 if (status != CAM_REQ_CMP)
972 xpt_setup_ccb(&ccb->ccb_h, path, 5);
973 ccb->ccb_h.func_code = XPT_SCAN_BUS;
974 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
975 ccb->crcn.flags = CAM_FLAG_NONE;
980 scsi_low_scsi_action_cam(sim, ccb)
984 struct scsi_low_softc *slp = SIM2SLP(sim);
985 struct targ_info *ti;
988 u_int lun, flags, msg, target;
991 target = (u_int) (ccb->ccb_h.target_id);
992 lun = (u_int) ccb->ccb_h.target_lun;
994 #ifdef SCSI_LOW_DEBUG
995 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
997 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
998 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1000 #endif /* SCSI_LOW_DEBUG */
1002 switch (ccb->ccb_h.func_code) {
1003 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1004 #ifdef SCSI_LOW_DIAGNOSTIC
1005 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1007 printf("%s: invalid target/lun\n", slp->sl_xname);
1008 ccb->ccb_h.status = CAM_REQ_INVALID;
1012 #endif /* SCSI_LOW_DIAGNOSTIC */
1014 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1015 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1020 ti = slp->sl_ti[target];
1023 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1024 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1028 s = SCSI_LOW_SPLSCSI();
1029 li = scsi_low_alloc_li(ti, lun, 1);
1031 if (ti->ti_setup_msg != 0)
1033 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1036 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1038 #ifdef SCSI_LOW_DEBUG
1039 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1041 scsi_low_test_abort(slp, ti, li);
1043 #endif /* SCSI_LOW_DEBUG */
1047 case XPT_EN_LUN: /* Enable LUN as a target */
1048 case XPT_TARGET_IO: /* Execute target I/O request */
1049 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1050 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1052 ccb->ccb_h.status = CAM_REQ_INVALID;
1056 case XPT_ABORT: /* Abort the specified CCB */
1057 #ifdef SCSI_LOW_DIAGNOSTIC
1058 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1060 printf("%s: invalid target/lun\n", slp->sl_xname);
1061 ccb->ccb_h.status = CAM_REQ_INVALID;
1065 #endif /* SCSI_LOW_DIAGNOSTIC */
1067 s = SCSI_LOW_SPLSCSI();
1068 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1069 rv = scsi_low_abort_ccb(slp, cb);
1073 ccb->ccb_h.status = CAM_REQ_CMP;
1075 ccb->ccb_h.status = CAM_REQ_INVALID;
1079 case XPT_SET_TRAN_SETTINGS: {
1080 struct ccb_trans_settings *cts;
1083 #ifdef SCSI_LOW_DIAGNOSTIC
1084 if (target == CAM_TARGET_WILDCARD)
1086 printf("%s: invalid target\n", slp->sl_xname);
1087 ccb->ccb_h.status = CAM_REQ_INVALID;
1091 #endif /* SCSI_LOW_DIAGNOSTIC */
1093 ti = slp->sl_ti[target];
1094 if (lun == CAM_LUN_WILDCARD)
1097 s = SCSI_LOW_SPLSCSI();
1098 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
1099 CCB_TRANS_SYNC_RATE_VALID |
1100 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
1102 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
1103 val = cts->bus_width;
1104 if (val < ti->ti_width)
1107 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
1108 val = cts->sync_period;
1109 if (val == 0 || val > ti->ti_maxsynch.period)
1110 ti->ti_maxsynch.period = val;
1112 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
1113 val = cts->sync_offset;
1114 if (val < ti->ti_maxsynch.offset)
1115 ti->ti_maxsynch.offset = val;
1118 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1119 scsi_low_calcf_target(ti);
1122 if ((cts->valid & (CCB_TRANS_DISC_VALID |
1123 CCB_TRANS_TQ_VALID)) != 0)
1125 li = scsi_low_alloc_li(ti, lun, 1);
1126 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
1128 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
1129 li->li_quirks |= SCSI_LOW_DISK_DISC;
1131 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1133 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
1135 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
1136 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1138 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1141 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1142 scsi_low_calcf_target(ti);
1143 scsi_low_calcf_lun(li);
1144 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1145 scsi_low_calcf_show(li);
1149 ccb->ccb_h.status = CAM_REQ_CMP;
1154 case XPT_GET_TRAN_SETTINGS: {
1155 struct ccb_trans_settings *cts;
1159 #ifdef SCSI_LOW_DIAGNOSTIC
1160 if (target == CAM_TARGET_WILDCARD)
1162 printf("%s: invalid target\n", slp->sl_xname);
1163 ccb->ccb_h.status = CAM_REQ_INVALID;
1167 #endif /* SCSI_LOW_DIAGNOSTIC */
1168 ti = slp->sl_ti[target];
1169 if (lun == CAM_LUN_WILDCARD)
1172 s = SCSI_LOW_SPLSCSI();
1173 li = scsi_low_alloc_li(ti, lun, 1);
1174 #ifdef CAM_NEW_TRAN_CODE
1175 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1176 struct ccb_trans_settings_scsi *scsi =
1177 &cts->proto_specific.scsi;
1178 struct ccb_trans_settings_spi *spi =
1179 &cts->xport_specific.spi;
1180 #ifdef SCSI_LOW_DIAGNOSTIC
1181 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1183 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1184 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1188 #endif /* SCSI_LOW_DIAGNOSTIC */
1189 cts->protocol = PROTO_SCSI;
1190 cts->protocol_version = SCSI_REV_2;
1191 cts->transport = XPORT_SPI;
1192 cts->transport_version = 2;
1194 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1195 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1197 diskflags = li->li_diskflags & li->li_cfgflags;
1198 if (diskflags & SCSI_LOW_DISK_DISC)
1199 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1200 if (diskflags & SCSI_LOW_DISK_QTAG)
1201 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1203 spi->sync_period = ti->ti_maxsynch.period;
1204 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1205 spi->sync_offset = ti->ti_maxsynch.offset;
1206 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1208 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1209 spi->bus_width = ti->ti_width;
1211 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1212 scsi->valid = CTS_SCSI_VALID_TQ;
1213 spi->valid |= CTS_SPI_VALID_DISC;
1217 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1219 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
1221 #ifdef SCSI_LOW_DIAGNOSTIC
1222 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
1224 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1225 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
1229 #endif /* SCSI_LOW_DIAGNOSTIC */
1230 diskflags = li->li_diskflags & li->li_cfgflags;
1231 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
1232 cts->flags |= CCB_TRANS_DISC_ENB;
1234 cts->flags &= ~CCB_TRANS_DISC_ENB;
1235 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
1236 cts->flags |= CCB_TRANS_TAG_ENB;
1238 cts->flags &= ~CCB_TRANS_TAG_ENB;
1240 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1242 #ifdef SCSI_LOW_DIAGNOSTIC
1243 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1245 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1246 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1250 #endif /* SCSI_LOW_DIAGNOSTIC */
1251 if ((li->li_flags & SCSI_LOW_DISC) != 0)
1252 cts->flags |= CCB_TRANS_DISC_ENB;
1254 cts->flags &= ~CCB_TRANS_DISC_ENB;
1255 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
1256 cts->flags |= CCB_TRANS_TAG_ENB;
1258 cts->flags &= ~CCB_TRANS_TAG_ENB;
1262 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1266 cts->sync_period = ti->ti_maxsynch.period;
1267 cts->sync_offset = ti->ti_maxsynch.offset;
1268 cts->bus_width = ti->ti_width;
1270 cts->valid = CCB_TRANS_SYNC_RATE_VALID
1271 | CCB_TRANS_SYNC_OFFSET_VALID
1272 | CCB_TRANS_BUS_WIDTH_VALID
1273 | CCB_TRANS_DISC_VALID
1274 | CCB_TRANS_TQ_VALID;
1275 ccb->ccb_h.status = CAM_REQ_CMP;
1283 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1284 cam_calc_geometry(&ccb->ccg, /*extended*/1);
1289 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1290 s = SCSI_LOW_SPLSCSI();
1291 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1293 ccb->ccb_h.status = CAM_REQ_CMP;
1297 case XPT_TERM_IO: /* Terminate the I/O process */
1298 ccb->ccb_h.status = CAM_REQ_INVALID;
1302 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1303 #ifdef SCSI_LOW_DIAGNOSTIC
1304 if (target == CAM_TARGET_WILDCARD)
1306 printf("%s: invalid target\n", slp->sl_xname);
1307 ccb->ccb_h.status = CAM_REQ_INVALID;
1311 #endif /* SCSI_LOW_DIAGNOSTIC */
1313 msg = SCSI_LOW_MSG_RESET;
1314 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1316 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1321 ti = slp->sl_ti[target];
1322 if (lun == CAM_LUN_WILDCARD)
1326 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1327 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1329 flags = CCB_NORETRY | CCB_URGENT;
1331 s = SCSI_LOW_SPLSCSI();
1332 li = scsi_low_alloc_li(ti, lun, 1);
1333 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1337 case XPT_PATH_INQ: { /* Path routing inquiry */
1338 struct ccb_pathinq *cpi = &ccb->cpi;
1340 cpi->version_num = scsi_low_version_major;
1341 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1342 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1343 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1344 cpi->hba_inquiry |= PI_WIDE_16;
1345 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1346 cpi->hba_inquiry |= PI_WIDE_32;
1347 if (ti->ti_maxsynch.offset > 0)
1348 cpi->hba_inquiry |= PI_SDTR_ABLE;
1349 cpi->target_sprt = 0;
1351 cpi->hba_eng_cnt = 0;
1352 cpi->max_target = slp->sl_ntargs - 1;
1353 cpi->max_lun = slp->sl_nluns - 1;
1354 cpi->initiator_id = slp->sl_hostid;
1355 cpi->bus_id = cam_sim_bus(sim);
1356 cpi->base_transfer_speed = 3300;
1357 #ifdef CAM_NEW_TRAN_CODE
1358 cpi->transport = XPORT_SPI;
1359 cpi->transport_version = 2;
1360 cpi->protocol = PROTO_SCSI;
1361 cpi->protocol_version = SCSI_REV_2;
1363 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1364 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1365 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1366 cpi->unit_number = cam_sim_unit(sim);
1367 cpi->ccb_h.status = CAM_REQ_CMP;
1373 printf("scsi_low: non support func_code = %d ",
1374 ccb->ccb_h.func_code);
1375 ccb->ccb_h.status = CAM_REQ_INVALID;
1382 scsi_low_attach_cam(slp)
1383 struct scsi_low_softc *slp;
1385 struct cam_devq *devq;
1386 int tagged_openings;
1388 sprintf(slp->sl_xname, "%s%d",
1389 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1391 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1396 * ask the adapter what subunits are present
1398 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1399 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1401 DEVPORT_DEVNAME(slp->sl_dev), slp,
1402 DEVPORT_DEVUNIT(slp->sl_dev),
1403 slp->sl_openings, tagged_openings, devq);
1404 cam_simq_release(devq);
1405 if (slp->sl_si.sim == NULL) {
1409 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1410 cam_sim_free(slp->sl_si.sim);
1411 slp->sl_si.sim = NULL;
1415 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1416 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1417 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1418 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1419 cam_sim_free(slp->sl_si.sim);
1420 slp->sl_si.sim = NULL;
1424 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1429 scsi_low_world_start_cam(slp)
1430 struct scsi_low_softc *slp;
1434 scsi_low_rescan_bus_cam(slp);
1439 scsi_low_dettach_cam(slp)
1440 struct scsi_low_softc *slp;
1443 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1444 xpt_free_path(slp->sl_si.path);
1445 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1446 cam_sim_free(slp->sl_si.sim);
1447 slp->sl_si.sim = NULL;
1452 scsi_low_ccb_setup_cam(slp, cb)
1453 struct scsi_low_softc *slp;
1456 union ccb *ccb = (union ccb *) cb->osdep;
1458 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1460 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1461 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1462 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1463 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1464 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1465 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1466 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1467 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1468 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1472 scsi_low_unit_ready_cmd(cb);
1474 return SCSI_LOW_START_QTAG;
1478 scsi_low_done_cam(slp, cb)
1479 struct scsi_low_softc *slp;
1484 ccb = (union ccb *) cb->osdep;
1485 if (cb->ccb_error == 0)
1487 ccb->ccb_h.status = CAM_REQ_CMP;
1488 ccb->csio.resid = 0;
1492 if (cb->ccb_rcnt >= slp->sl_max_retry)
1493 cb->ccb_error |= ABORTIO;
1495 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1496 (cb->ccb_error & ABORTIO) == 0)
1499 if ((cb->ccb_error & SENSEIO) != 0)
1501 memcpy(&ccb->csio.sense_data,
1503 sizeof(ccb->csio.sense_data));
1506 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1507 &scsi_low_error_code_cam[0]);
1509 #ifdef SCSI_LOW_DIAGNOSTIC
1510 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1511 cb->ccb_scp.scp_cmdlen > 0 &&
1512 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1513 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1515 printf("%s: WARNING: scsi_low IO abort\n",
1517 scsi_low_print(slp, NULL);
1519 #endif /* SCSI_LOW_DIAGNOSTIC */
1522 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1523 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1525 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1526 ccb->csio.scsi_status = 0; /* XXX */
1528 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1530 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1536 scsi_low_timeout_cam(slp, ch, action)
1537 struct scsi_low_softc *slp;
1544 case SCSI_LOW_TIMEOUT_CH_IO:
1547 case SCSI_LOW_TIMEOUT_START:
1548 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1549 hz / SCSI_LOW_TIMEOUT_HZ);
1551 case SCSI_LOW_TIMEOUT_STOP:
1552 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1557 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1560 case SCSI_LOW_TIMEOUT_START:
1561 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1563 case SCSI_LOW_TIMEOUT_STOP:
1564 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1568 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1573 #endif /* SCSI_LOW_INTERFACE_CAM */
1575 /*=============================================================
1576 * END OF OS switch (All OS depend fucntions should be above)
1577 =============================================================*/
1579 /**************************************************************
1580 * scsi low deactivate and activate
1581 **************************************************************/
1583 scsi_low_is_busy(slp)
1584 struct scsi_low_softc *slp;
1587 if (slp->sl_nio > 0)
1593 scsi_low_deactivate(slp)
1594 struct scsi_low_softc *slp;
1598 s = SCSI_LOW_SPLSCSI();
1599 slp->sl_flags |= HW_INACTIVE;
1600 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1601 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1602 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1603 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1609 scsi_low_activate(slp)
1610 struct scsi_low_softc *slp;
1614 s = SCSI_LOW_SPLSCSI();
1615 slp->sl_flags &= ~HW_INACTIVE;
1616 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1618 slp->sl_flags |= HW_INACTIVE;
1623 slp->sl_timeout_count = 0;
1624 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1625 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1630 /**************************************************************
1632 **************************************************************/
1633 #ifdef SCSI_LOW_DIAGNOSTIC
1634 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1635 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1637 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1640 scsi_low_msg_log_init(slmlp)
1641 struct scsi_low_msg_log *slmlp;
1644 slmlp->slml_ptr = 0;
1648 scsi_low_msg_log_write(slmlp, datap, len)
1649 struct scsi_low_msg_log *slmlp;
1655 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1658 ptr = slmlp->slml_ptr ++;
1659 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1660 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1661 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1662 slmlp->slml_msg[ptr].msg[ind] = 0;
1666 scsi_low_msg_log_show(slmlp, s, len)
1667 struct scsi_low_msg_log *slmlp;
1673 printf("%s: (%d) ", s, slmlp->slml_ptr);
1674 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1676 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1679 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1685 #endif /* SCSI_LOW_DIAGNOSTIC */
1687 /**************************************************************
1689 **************************************************************/
1691 scsi_low_engage(arg)
1694 struct scsi_low_softc *slp = arg;
1695 int s = SCSI_LOW_SPLSCSI();
1697 switch (slp->sl_rstep)
1701 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1702 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1703 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1708 slp->sl_flags &= ~HW_RESUME;
1709 scsi_low_start(slp);
1719 scsi_low_init(slp, flags)
1720 struct scsi_low_softc *slp;
1725 slp->sl_flags |= HW_INITIALIZING;
1727 /* clear power control timeout */
1728 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1730 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1731 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1732 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1734 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1737 /* reset current nexus */
1738 scsi_low_reset_nexus(slp, flags);
1739 if ((slp->sl_flags & HW_INACTIVE) != 0)
1745 if (flags != SCSI_LOW_RESTART_SOFT)
1747 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1751 slp->sl_flags &= ~HW_INITIALIZING;
1755 /**************************************************************
1757 **************************************************************/
1758 static struct lun_info *
1759 scsi_low_alloc_li(ti, lun, alloc)
1760 struct targ_info *ti;
1764 struct scsi_low_softc *slp = ti->ti_sc;
1765 struct lun_info *li;
1767 li = LIST_FIRST(&ti->ti_litab);
1770 if (li->li_lun == lun)
1773 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1775 if (li->li_lun == lun)
1777 LIST_REMOVE(li, lun_chain);
1778 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1787 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1789 panic("no lun info mem");
1791 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1795 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1797 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1798 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1799 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1800 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1801 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1803 li->li_qtagbits = (u_int) -1;
1805 TAILQ_INIT(&li->li_discq);
1806 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1808 /* host specific structure initialization per lun */
1809 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1810 (*slp->sl_funcs->scsi_low_lun_init)
1811 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1812 scsi_low_calcf_lun(li);
1816 /**************************************************************
1817 * allocate targ_info
1818 **************************************************************/
1819 static struct targ_info *
1820 scsi_low_alloc_ti(slp, targ)
1821 struct scsi_low_softc *slp;
1824 struct targ_info *ti;
1826 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1827 TAILQ_INIT(&slp->sl_titab);
1829 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1831 panic("%s short of memory", slp->sl_xname);
1833 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1837 slp->sl_ti[targ] = ti;
1838 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1839 LIST_INIT(&ti->ti_litab);
1841 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1842 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1843 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1844 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1845 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1846 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1848 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1850 (*slp->sl_funcs->scsi_low_targ_init)
1851 (slp, ti, SCSI_LOW_INFO_ALLOC);
1853 scsi_low_calcf_target(ti);
1858 scsi_low_free_ti(slp)
1859 struct scsi_low_softc *slp;
1861 struct targ_info *ti, *tib;
1862 struct lun_info *li, *nli;
1864 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1866 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1868 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1870 (*slp->sl_funcs->scsi_low_lun_init)
1871 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1873 nli = LIST_NEXT(li, lun_chain);
1877 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1879 (*slp->sl_funcs->scsi_low_targ_init)
1880 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1882 tib = TAILQ_NEXT(ti, ti_chain);
1887 /**************************************************************
1889 **************************************************************/
1891 scsi_low_bus_idle(slp)
1892 struct scsi_low_softc *slp;
1895 slp->sl_retry_sel = 0;
1896 if (slp->sl_Tnexus == NULL)
1897 scsi_low_start(slp);
1901 scsi_low_timeout(arg)
1904 struct scsi_low_softc *slp = arg;
1907 s = SCSI_LOW_SPLSCSI();
1908 (void) scsi_low_timeout_check(slp);
1909 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1910 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1915 scsi_low_timeout_check(slp)
1916 struct scsi_low_softc *slp;
1918 struct targ_info *ti;
1919 struct lun_info *li;
1920 struct slccb *cb = NULL; /* XXX */
1922 /* selection restart */
1923 if (slp->sl_retry_sel != 0)
1925 slp->sl_retry_sel = 0;
1926 if (slp->sl_Tnexus != NULL)
1929 cb = TAILQ_FIRST(&slp->sl_start);
1933 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1935 cb->ccb_flags |= CCB_NORETRY;
1936 cb->ccb_error |= SELTIMEOUTIO;
1937 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1938 panic("%s: ccb not finished", slp->sl_xname);
1941 if (slp->sl_Tnexus == NULL)
1942 scsi_low_start(slp);
1945 /* call hardware timeout */
1947 if (slp->sl_funcs->scsi_low_timeout != NULL)
1949 (*slp->sl_funcs->scsi_low_timeout) (slp);
1952 if (slp->sl_timeout_count ++ <
1953 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1956 slp->sl_timeout_count = 0;
1957 if (slp->sl_nio > 0)
1959 if ((cb = slp->sl_Qnexus) != NULL)
1961 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1965 else if (slp->sl_disc == 0)
1967 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1970 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1974 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1975 ti = TAILQ_NEXT(ti, ti_chain))
1977 if (ti->ti_disc == 0)
1980 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1981 li = LIST_NEXT(li, lun_chain))
1983 for (cb = TAILQ_FIRST(&li->li_discq);
1985 cb = TAILQ_NEXT(cb, ccb_chain))
1988 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1996 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1998 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2001 if (slp->sl_active != 0)
2003 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2009 if (slp->sl_powc < 0)
2011 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2012 slp->sl_flags |= HW_POWDOWN;
2013 (*slp->sl_funcs->scsi_low_power)
2014 (slp, SCSI_LOW_POWDOWN);
2020 cb->ccb_error |= TIMEOUTIO;
2021 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2022 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2023 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2024 scsi_low_start(slp);
2030 scsi_low_abort_ccb(slp, cb)
2031 struct scsi_low_softc *slp;
2034 struct targ_info *ti;
2035 struct lun_info *li;
2040 if ((cb->ccb_omsgoutflag &
2041 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2046 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2047 msg = SCSI_LOW_MSG_ABORT;
2049 msg = SCSI_LOW_MSG_ABORT_QTAG;
2051 cb->ccb_error |= ABORTIO;
2052 cb->ccb_flags |= CCB_NORETRY;
2053 scsi_low_ccb_message_assert(cb, msg);
2055 if (cb == slp->sl_Qnexus)
2057 scsi_low_assert_msg(slp, ti, msg, 1);
2059 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2061 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2062 panic("%s: revoked ccb done", slp->sl_xname);
2064 cb->ccb_flags |= CCB_STARTQ;
2065 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2067 if (slp->sl_Tnexus == NULL)
2068 scsi_low_start(slp);
2072 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2073 panic("%s: revoked ccb retried", slp->sl_xname);
2078 /**************************************************************
2079 * Generic SCSI INTERFACE
2080 **************************************************************/
2082 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2083 struct scsi_low_softc *slp;
2084 int openings, ntargs, nluns, targsize, lunsize;
2086 struct targ_info *ti;
2087 struct lun_info *li;
2090 #ifdef SCSI_LOW_INTERFACE_XS
2091 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2092 #endif /* SCSI_LOW_INTERFACE_XS */
2093 #ifdef SCSI_LOW_INTERFACE_CAM
2094 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2095 #endif /* SCSI_LOW_INTERFACE_CAM */
2097 if (slp->sl_osdep_fp == NULL)
2098 panic("scsi_low: interface not spcified");
2100 if (ntargs > SCSI_LOW_NTARGETS)
2102 printf("scsi_low: %d targets are too large\n", ntargs);
2103 printf("change kernel options SCSI_LOW_NTARGETS");
2108 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2110 slp->sl_openings = openings;
2111 slp->sl_ntargs = ntargs;
2112 slp->sl_nluns = nluns;
2113 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2115 if (lunsize < sizeof(struct lun_info))
2116 lunsize = sizeof(struct lun_info);
2118 if (targsize < sizeof(struct targ_info))
2119 targsize = sizeof(struct targ_info);
2121 slp->sl_targsize = targsize;
2122 for (i = 0; i < ntargs; i ++)
2124 ti = scsi_low_alloc_ti(slp, i);
2125 ti->ti_lunsize = lunsize;
2126 li = scsi_low_alloc_li(ti, 0, 1);
2129 /* initialize queue */
2130 nccb = openings * ntargs;
2131 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2132 nccb = SCSI_LOW_NCCB;
2133 scsi_low_init_ccbque(nccb);
2134 TAILQ_INIT(&slp->sl_start);
2136 /* call os depend attach */
2137 s = SCSI_LOW_SPLSCSI();
2138 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2142 printf("%s: scsi_low_attach: osdep attach failed\n",
2147 /* check hardware */
2148 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2149 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2152 printf("%s: scsi_low_attach: initialization failed\n",
2157 /* start watch dog */
2158 slp->sl_timeout_count = 0;
2159 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2160 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2161 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2164 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2166 #ifdef SCSI_LOW_START_UP_CHECK
2167 /* probing devices */
2168 scsi_low_start_up(slp);
2169 #endif /* SCSI_LOW_START_UP_CHECK */
2171 /* call os depend attach done*/
2172 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2178 scsi_low_dettach(slp)
2179 struct scsi_low_softc *slp;
2183 s = SCSI_LOW_SPLSCSI();
2184 if (scsi_low_is_busy(slp) != 0)
2190 scsi_low_deactivate(slp);
2192 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2199 scsi_low_free_ti(slp);
2200 LIST_REMOVE(slp, sl_chain);
2205 /**************************************************************
2207 **************************************************************/
2209 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2210 struct scsi_low_softc *slp;
2211 struct targ_info *ti;
2212 struct lun_info *li;
2220 scsi_low_ccb_message_assert(cb, msg);
2222 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2223 scsi_low_alloc_qtag(cb);
2225 cb->ccb_flags = flags | CCB_STARTQ;
2226 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2227 cb->ccb_error |= PENDINGIO;
2229 if ((flags & CCB_URGENT) != 0)
2231 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2235 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2240 if (slp->sl_Tnexus == NULL)
2241 scsi_low_start(slp);
2246 scsi_low_message_enqueue(slp, ti, li, flags)
2247 struct scsi_low_softc *slp;
2248 struct targ_info *ti;
2249 struct lun_info *li;
2255 tmsgflags = ti->ti_setup_msg;
2256 ti->ti_setup_msg = 0;
2258 flags |= CCB_NORETRY;
2259 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2264 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2268 /**************************************************************
2269 * Generic Start & Done
2270 **************************************************************/
2271 #define SLSC_MODE_SENSE_SHORT 0x1a
2272 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2273 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2274 sizeof(struct scsi_low_mode_sense_data), 0};
2275 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2276 sizeof(struct scsi_low_inq_data), 0};
2277 static u_int8_t unit_ready_cmd[6];
2278 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2279 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2280 static int scsi_low_resume (struct scsi_low_softc *);
2283 scsi_low_unit_ready_cmd(cb)
2287 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2288 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2289 cb->ccb_scp.scp_datalen = 0;
2290 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2295 scsi_low_sense_abort_start(slp, ti, li, cb)
2296 struct scsi_low_softc *slp;
2297 struct targ_info *ti;
2298 struct lun_info *li;
2302 cb->ccb_scp.scp_cmdlen = 6;
2303 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2304 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2305 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2306 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2307 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2308 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2309 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2311 scsi_low_ccb_message_clear(cb);
2312 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2314 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2318 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2319 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2320 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2321 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2324 return SCSI_LOW_START_NO_QTAG;
2328 scsi_low_setup_start(slp, ti, li, cb)
2329 struct scsi_low_softc *slp;
2330 struct targ_info *ti;
2331 struct lun_info *li;
2335 switch(li->li_state)
2337 case SCSI_LOW_LUN_SLEEP:
2338 scsi_low_unit_ready_cmd(cb);
2341 case SCSI_LOW_LUN_START:
2342 cb->ccb_scp.scp_cmd = ss_cmd;
2343 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2344 cb->ccb_scp.scp_datalen = 0;
2345 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2349 case SCSI_LOW_LUN_INQ:
2350 cb->ccb_scp.scp_cmd = inq_cmd;
2351 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2352 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2353 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2354 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2358 case SCSI_LOW_LUN_MODEQ:
2359 cb->ccb_scp.scp_cmd = sms_cmd;
2360 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2361 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2362 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2363 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2365 return SCSI_LOW_START_QTAG;
2368 panic("%s: no setup phase", slp->sl_xname);
2371 return SCSI_LOW_START_NO_QTAG;
2375 scsi_low_resume(slp)
2376 struct scsi_low_softc *slp;
2379 if (slp->sl_flags & HW_RESUME)
2381 slp->sl_flags &= ~HW_POWDOWN;
2382 if (slp->sl_funcs->scsi_low_power != NULL)
2384 slp->sl_flags |= HW_RESUME;
2386 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2387 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2388 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2389 SCSI_LOW_TIMEOUT_START);
2397 struct scsi_low_softc *slp;
2399 struct targ_info *ti;
2400 struct lun_info *li;
2404 /* check hardware exists or under initializations ? */
2405 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2408 /* check hardware power up ? */
2409 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2412 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2414 if (scsi_low_resume(slp) == EJUSTRETURN)
2420 #ifdef SCSI_LOW_DIAGNOSTIC
2421 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2423 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2424 panic("%s: inconsistent", slp->sl_xname);
2426 #endif /* SCSI_LOW_DIAGNOSTIC */
2428 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2429 cb = TAILQ_NEXT(cb, ccb_chain))
2433 if (li->li_disc == 0)
2435 goto scsi_low_cmd_start;
2437 else if (li->li_nqio > 0)
2439 if (li->li_nqio < li->li_maxnqio ||
2440 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2441 goto scsi_low_cmd_start;
2447 cb->ccb_flags &= ~CCB_STARTQ;
2448 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2451 /* clear all error flag bits (for restart) */
2453 cb->ccb_datalen = -1;
2454 cb->ccb_scp.scp_status = ST_UNKNOWN;
2456 /* setup nexus pointer */
2457 slp->sl_Qnexus = cb;
2458 slp->sl_Lnexus = li;
2459 slp->sl_Tnexus = ti;
2461 /* initialize msgsys */
2462 scsi_low_init_msgsys(slp, ti);
2465 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2467 /* CA state or forced abort */
2468 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2470 else if (li->li_state >= SCSI_LOW_LUN_OK)
2472 cb->ccb_flags &= ~CCB_INTERNAL;
2473 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2474 if (cb->ccb_msgoutflag != 0)
2476 scsi_low_ccb_message_exec(slp, cb);
2481 cb->ccb_flags |= CCB_INTERNAL;
2482 rv = scsi_low_setup_start(slp, ti, li, cb);
2486 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2488 if (rv == SCSI_LOW_START_QTAG &&
2489 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2494 scsi_low_activate_qtag(cb);
2495 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2496 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2497 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2498 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2499 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2501 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2502 scsi_low_assert_msg(slp, ti, qmsg, 0);
2506 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2507 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2508 cb->ccb_tc = cb->ccb_tcmax;
2510 /* setup saved scsi data pointer */
2511 cb->ccb_sscp = cb->ccb_scp;
2513 /* setup current scsi pointer */
2514 slp->sl_scp = cb->ccb_sscp;
2515 slp->sl_error = cb->ccb_error;
2517 /* assert always an identify msg */
2518 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2521 #ifdef SCSI_LOW_DIAGNOSTIC
2522 scsi_low_msg_log_init(&ti->ti_log_msgin);
2523 scsi_low_msg_log_init(&ti->ti_log_msgout);
2524 #endif /* SCSI_LOW_DIAGNOSTIC */
2526 /* selection start */
2528 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2529 if (rv == SCSI_LOW_START_OK)
2531 #ifdef SCSI_LOW_STATICS
2532 scsi_low_statics.nexus_win ++;
2533 #endif /* SCSI_LOW_STATICS */
2537 scsi_low_arbit_fail(slp, cb);
2538 #ifdef SCSI_LOW_STATICS
2539 scsi_low_statics.nexus_fail ++;
2540 #endif /* SCSI_LOW_STATICS */
2544 scsi_low_arbit_fail(slp, cb)
2545 struct scsi_low_softc *slp;
2548 struct targ_info *ti = cb->ti;
2550 scsi_low_deactivate_qtag(cb);
2551 scsi_low_ccb_message_retry(cb);
2552 cb->ccb_flags |= CCB_STARTQ;
2553 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2555 scsi_low_bus_release(slp, ti);
2558 if (slp->sl_disc == 0)
2560 #ifdef SCSI_LOW_DIAGNOSTIC
2561 printf("%s: try selection again\n", slp->sl_xname);
2562 #endif /* SCSI_LOW_DIAGNOSTIC */
2563 slp->sl_retry_sel = 1;
2568 scsi_low_bus_release(slp, ti)
2569 struct scsi_low_softc *slp;
2570 struct targ_info *ti;
2573 if (ti->ti_disc > 0)
2575 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2579 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2582 /* clear all nexus pointer */
2583 slp->sl_Qnexus = NULL;
2584 slp->sl_Lnexus = NULL;
2585 slp->sl_Tnexus = NULL;
2587 /* clear selection assert */
2588 slp->sl_selid = NULL;
2590 /* clear nexus data */
2591 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2593 /* clear phase change counter */
2594 slp->sl_ph_count = 0;
2598 scsi_low_setup_done(slp, cb)
2599 struct scsi_low_softc *slp;
2602 struct targ_info *ti;
2603 struct lun_info *li;
2608 if (cb->ccb_rcnt >= slp->sl_max_retry)
2610 cb->ccb_error |= ABORTIO;
2611 return SCSI_LOW_DONE_COMPLETE;
2614 /* XXX: special huck for selection timeout */
2615 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2616 (cb->ccb_error & SELTIMEOUTIO) != 0)
2618 cb->ccb_error |= ABORTIO;
2619 return SCSI_LOW_DONE_COMPLETE;
2622 switch(li->li_state)
2624 case SCSI_LOW_LUN_INQ:
2625 if (cb->ccb_error != 0)
2628 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2632 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2634 else if ((li->li_inq.sd_version & 7) >= 2 ||
2635 (li->li_inq.sd_len >= 4))
2637 if ((li->li_inq.sd_support & 0x2) == 0)
2638 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2639 if ((li->li_inq.sd_support & 0x8) == 0)
2640 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2643 if ((li->li_inq.sd_support & 0x10) == 0)
2644 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2645 if ((li->li_inq.sd_support & 0x20) == 0)
2646 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2647 if ((li->li_inq.sd_support & 0x40) == 0)
2648 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2653 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2656 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2658 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2660 scsi_low_calcf_target(ti);
2661 scsi_low_calcf_lun(li);
2664 case SCSI_LOW_LUN_MODEQ:
2665 if (cb->ccb_error != 0)
2667 if (cb->ccb_error & SENSEIO)
2669 #ifdef SCSI_LOW_DEBUG
2670 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2672 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2673 (u_int) cb->ccb_sense.error_code,
2674 (u_int) cb->ccb_sense.segment,
2675 (u_int) cb->ccb_sense.flags,
2676 (u_int) cb->ccb_sense.add_sense_code,
2677 (u_int) cb->ccb_sense.add_sense_code_qual);
2679 #endif /* SCSI_LOW_DEBUG */
2683 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2686 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2688 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2689 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2691 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2692 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2693 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2695 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2696 scsi_low_calcf_lun(li);
2704 if (li->li_state == SCSI_LOW_LUN_OK)
2706 scsi_low_calcf_target(ti);
2707 scsi_low_calcf_lun(li);
2708 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2709 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2711 scsi_low_calcf_show(li);
2716 return SCSI_LOW_DONE_RETRY;
2720 scsi_low_done(slp, cb)
2721 struct scsi_low_softc *slp;
2726 if (cb->ccb_error == 0)
2728 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2730 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2732 * SCSI-2 draft suggests
2733 * page 0x0a QErr bit determins if
2734 * the target aborts or continues
2735 * the queueing io's after CA state resolved.
2736 * However many targets seem not to support
2737 * the page 0x0a. Thus we should manually clear the
2738 * queuing io's after CA state.
2740 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2743 cb->ccb_flags |= CCB_CLEARQ;
2746 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2748 if ((cb->ccb_flags & CCB_SENSE) != 0)
2749 cb->ccb_error |= (SENSEIO | ABORTIO);
2750 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2752 else switch (cb->ccb_sscp.scp_status)
2758 if (cb->ccb_datalen == 0 ||
2759 cb->ccb_scp.scp_datalen == 0)
2762 if (cb->ccb_scp.scp_cmdlen > 0 &&
2763 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2764 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2767 cb->ccb_error |= PDMAERR;
2772 cb->ccb_error |= (BUSYERR | STATERR);
2776 cb->ccb_error |= (STATERR | ABORTIO);
2781 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2784 cb->ccb_flags |= CCB_SENSE;
2787 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2792 cb->ccb_error |= FATALIO;
2798 if (cb->ccb_flags & CCB_SENSE)
2800 cb->ccb_error |= (SENSEERR | ABORTIO);
2802 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2806 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2808 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2812 /* check a ccb msgout flag */
2813 if (cb->ccb_omsgoutflag != 0)
2815 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2816 SCSI_LOW_MSG_ABORT_QTAG | \
2817 SCSI_LOW_MSG_CLEAR_QTAG | \
2818 SCSI_LOW_MSG_TERMIO)
2820 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2822 cb->ccb_error |= ABORTIO;
2826 /* call OS depend done */
2827 if (cb->osdep != NULL)
2829 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2830 if (rv == EJUSTRETURN)
2833 else if (cb->ccb_error != 0)
2835 if (cb->ccb_rcnt >= slp->sl_max_retry)
2836 cb->ccb_error |= ABORTIO;
2838 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2839 (cb->ccb_error & ABORTIO) == 0)
2843 /* free our target */
2844 #ifdef SCSI_LOW_DEBUG
2845 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2847 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2848 scsi_low_print(slp, NULL);
2850 #endif /* SCSI_LOW_DEBUG */
2852 scsi_low_deactivate_qtag(cb);
2853 scsi_low_dealloc_qtag(cb);
2854 scsi_low_free_ccb(cb);
2856 return SCSI_LOW_DONE_COMPLETE;
2859 #ifdef SCSI_LOW_DEBUG
2860 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2862 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2863 scsi_low_print(slp, NULL);
2865 #endif /* SCSI_LOW_DEBUG */
2868 scsi_low_deactivate_qtag(cb);
2869 scsi_low_ccb_message_retry(cb);
2870 return SCSI_LOW_DONE_RETRY;
2873 /**************************************************************
2875 **************************************************************/
2877 scsi_low_reset_nexus_target(slp, ti, fdone)
2878 struct scsi_low_softc *slp;
2879 struct targ_info *ti;
2882 struct lun_info *li;
2884 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2885 li = LIST_NEXT(li, lun_chain))
2887 scsi_low_reset_nexus_lun(slp, li, fdone);
2888 li->li_state = SCSI_LOW_LUN_SLEEP;
2893 ti->ti_setup_msg = 0;
2894 ti->ti_setup_msg_done = 0;
2896 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2897 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2899 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2900 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2902 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2904 ((*slp->sl_funcs->scsi_low_targ_init)
2905 (slp, ti, SCSI_LOW_INFO_REVOKE));
2907 scsi_low_calcf_target(ti);
2909 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2910 li = LIST_NEXT(li, lun_chain))
2914 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2915 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2917 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2919 ((*slp->sl_funcs->scsi_low_lun_init)
2920 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2922 scsi_low_calcf_lun(li);
2927 scsi_low_reset_nexus(slp, fdone)
2928 struct scsi_low_softc *slp;
2931 struct targ_info *ti;
2932 struct slccb *cb, *topcb;
2934 if ((cb = slp->sl_Qnexus) != NULL)
2936 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2943 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2944 ti = TAILQ_NEXT(ti, ti_chain))
2946 scsi_low_reset_nexus_target(slp, ti, fdone);
2947 scsi_low_bus_release(slp, ti);
2948 scsi_low_init_msgsys(slp, ti);
2953 topcb->ccb_flags |= CCB_STARTQ;
2954 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2958 slp->sl_retry_sel = 0;
2959 slp->sl_flags &= ~HW_PDMASTART;
2964 static char tw_chars[] = "|/-\\";
2965 #define TWIDDLEWAIT 10000
2968 scsi_low_twiddle_wait(void)
2972 cnputc(tw_chars[tw_pos++]);
2973 tw_pos %= (sizeof(tw_chars) - 1);
2974 SCSI_LOW_DELAY(TWIDDLEWAIT);
2978 scsi_low_bus_reset(slp)
2979 struct scsi_low_softc *slp;
2983 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2985 printf("%s: try to reset scsi bus ", slp->sl_xname);
2986 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2987 scsi_low_twiddle_wait();
2993 scsi_low_restart(slp, flags, s)
2994 struct scsi_low_softc *slp;
3001 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3003 if ((error = scsi_low_init(slp, flags)) != 0)
3006 scsi_low_start(slp);
3010 /**************************************************************
3011 * disconnect and reselect
3012 **************************************************************/
3013 #define MSGCMD_LUN(msg) (msg & 0x07)
3015 static struct slccb *
3016 scsi_low_establish_ccb(ti, li, tag)
3017 struct targ_info *ti;
3018 struct lun_info *li;
3021 struct scsi_low_softc *slp = ti->ti_sc;
3027 cb = TAILQ_FIRST(&li->li_discq);
3028 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3029 if (cb->ccb_tag == tag)
3034 * establish our ccb nexus
3037 #ifdef SCSI_LOW_DEBUG
3038 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3040 printf("%s: nexus(0x%lx) abort check start\n",
3041 slp->sl_xname, (u_long) cb);
3042 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3043 scsi_low_revoke_ccb(slp, cb, 1);
3047 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3049 if (cb->ccb_omsgoutflag == 0)
3050 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3052 #endif /* SCSI_LOW_DEBUG */
3054 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3055 cb->ccb_flags &= ~CCB_DISCQ;
3056 slp->sl_Qnexus = cb;
3058 slp->sl_scp = cb->ccb_sscp;
3059 slp->sl_error |= cb->ccb_error;
3065 /* inform "ccb nexus established" to the host driver */
3066 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3069 if (cb->ccb_msgoutflag != 0)
3071 scsi_low_ccb_message_exec(slp, cb);
3078 scsi_low_reselected(slp, targ)
3079 struct scsi_low_softc *slp;
3082 struct targ_info *ti;
3087 * Check select vs reselected collision.
3090 if ((cb = slp->sl_selid) != NULL)
3092 scsi_low_arbit_fail(slp, cb);
3093 #ifdef SCSI_LOW_STATICS
3094 scsi_low_statics.nexus_conflict ++;
3095 #endif /* SCSI_LOW_STATICS */
3099 * Check if no current active nexus.
3101 if (slp->sl_Tnexus != NULL)
3108 * Check a valid target id asserted ?
3110 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3112 s = "scsi id illegal";
3117 * Check the target scsi status.
3119 ti = slp->sl_ti[targ];
3120 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3122 s = "phase mismatch";
3130 scsi_low_init_msgsys(slp, ti);
3133 * Establish our target nexus
3135 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3136 slp->sl_Tnexus = ti;
3137 #ifdef SCSI_LOW_STATICS
3138 scsi_low_statics.nexus_reselected ++;
3139 #endif /* SCSI_LOW_STATICS */
3143 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3144 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3145 "reselect: scsi world confused");
3149 /**************************************************************
3150 * cmd out pointer setup
3151 **************************************************************/
3153 scsi_low_cmd(slp, ti)
3154 struct scsi_low_softc *slp;
3155 struct targ_info *ti;
3157 struct slccb *cb = slp->sl_Qnexus;
3159 slp->sl_ph_count ++;
3165 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3166 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3167 slp->sl_scp.scp_datalen = 0;
3168 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3169 slp->sl_error |= FATALIO;
3170 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3171 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3176 #ifdef SCSI_LOW_DEBUG
3177 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3179 scsi_low_test_cmdlnk(slp, cb);
3181 #endif /* SCSI_LOW_DEBUG */
3186 /**************************************************************
3187 * data out pointer setup
3188 **************************************************************/
3190 scsi_low_data(slp, ti, bp, direction)
3191 struct scsi_low_softc *slp;
3192 struct targ_info *ti;
3196 struct slccb *cb = slp->sl_Qnexus;
3198 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3204 slp->sl_error |= (FATALIO | PDMAERR);
3205 slp->sl_scp.scp_datalen = 0;
3206 slp->sl_scp.scp_direction = direction;
3207 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3208 if (ti->ti_ophase != ti->ti_phase)
3213 s = "DATA PHASE: ccb nexus not found";
3215 s = "DATA PHASE: xfer direction mismatch";
3216 SCSI_LOW_INFO(slp, ti, s);
3223 /**************************************************************
3225 **************************************************************/
3226 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3227 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3228 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3229 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3230 #define MSGIN_DATA_LAST 0x30
3232 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
3233 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
3234 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
3235 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
3237 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
3238 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
3239 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
3240 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
3241 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
3242 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
3243 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
3245 struct scsi_low_msgout_data {
3248 int (*md_msgfunc) (struct scsi_low_softc *);
3249 int (*md_errfunc) (struct scsi_low_softc *, u_int);
3250 #define MSG_RELEASE_ATN 0x0001
3254 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3255 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3256 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3257 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3258 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3259 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3260 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3261 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3262 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3263 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3264 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3265 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3266 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3267 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3268 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3269 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3270 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3273 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
3274 static int scsi_low_synch (struct scsi_low_softc *);
3275 static int scsi_low_wide (struct scsi_low_softc *);
3276 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
3277 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
3278 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
3279 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
3280 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
3281 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
3282 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
3283 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
3284 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
3285 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
3286 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
3288 struct scsi_low_msgin_data {
3290 int (*md_msgfunc) (struct scsi_low_softc *);
3293 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3294 /* 0 */ {1, scsi_low_msginfunc_cc},
3295 /* 1 */ {2, scsi_low_msginfunc_ext},
3296 /* 2 */ {1, scsi_low_msginfunc_sdp},
3297 /* 3 */ {1, scsi_low_msginfunc_rp},
3298 /* 4 */ {1, scsi_low_msginfunc_disc},
3299 /* 5 */ {1, scsi_low_msginfunc_rejop},
3300 /* 6 */ {1, scsi_low_msginfunc_rejop},
3301 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
3302 /* 8 */ {1, scsi_low_msginfunc_noop},
3303 /* 9 */ {1, scsi_low_msginfunc_parity},
3304 /* a */ {1, scsi_low_msginfunc_lcc},
3305 /* b */ {1, scsi_low_msginfunc_lcc},
3306 /* c */ {1, scsi_low_msginfunc_rejop},
3307 /* d */ {2, scsi_low_msginfunc_rejop},
3308 /* e */ {1, scsi_low_msginfunc_rejop},
3309 /* f */ {1, scsi_low_msginfunc_rejop},
3310 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
3311 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
3312 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
3313 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
3314 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
3315 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
3316 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
3317 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
3318 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
3319 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
3320 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
3321 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
3322 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
3323 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
3324 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
3325 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
3326 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3327 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
3328 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
3329 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3330 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
3331 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
3332 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
3333 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
3334 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
3335 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
3336 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
3337 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
3338 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
3339 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
3340 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
3341 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
3342 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3345 /**************************************************************
3347 **************************************************************/
3349 scsi_low_msgfunc_synch(slp)
3350 struct scsi_low_softc *slp;
3352 struct targ_info *ti = slp->sl_Tnexus;
3353 int ptr = ti->ti_msgoutlen;
3355 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3356 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3357 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3358 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3359 return MSG_EXTEND_SYNCHLEN + 2;
3363 scsi_low_msgfunc_wide(slp)
3364 struct scsi_low_softc *slp;
3366 struct targ_info *ti = slp->sl_Tnexus;
3367 int ptr = ti->ti_msgoutlen;
3369 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3370 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3371 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3372 return MSG_EXTEND_WIDELEN + 2;
3376 scsi_low_msgfunc_identify(slp)
3377 struct scsi_low_softc *slp;
3379 struct targ_info *ti = slp->sl_Tnexus;
3380 struct lun_info *li = slp->sl_Lnexus;
3381 struct slccb *cb = slp->sl_Qnexus;
3382 int ptr = ti->ti_msgoutlen;
3388 slp->sl_error |= FATALIO;
3389 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3390 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3394 if (scsi_low_is_disconnect_ok(cb) != 0)
3395 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3399 if (ti->ti_phase == PH_MSGOUT)
3401 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3402 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3404 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3408 ti->ti_msgoutstr[ptr + 0] = msg;
3413 scsi_low_msgfunc_abort(slp)
3414 struct scsi_low_softc *slp;
3417 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3422 scsi_low_msgfunc_qabort(slp)
3423 struct scsi_low_softc *slp;
3426 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3431 scsi_low_msgfunc_reset(slp)
3432 struct scsi_low_softc *slp;
3435 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3440 scsi_low_msgfunc_qtag(slp)
3441 struct scsi_low_softc *slp;
3443 struct targ_info *ti = slp->sl_Tnexus;
3444 struct slccb *cb = slp->sl_Qnexus;
3445 int ptr = ti->ti_msgoutlen;
3447 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3449 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3454 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3455 if (ti->ti_phase == PH_MSGOUT)
3457 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3464 * The following functions are called when targets give unexpected
3465 * responces in msgin (after msgout).
3468 scsi_low_errfunc_identify(slp, msgflags)
3469 struct scsi_low_softc *slp;
3473 if (slp->sl_Lnexus != NULL)
3475 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3476 scsi_low_calcf_lun(slp->sl_Lnexus);
3482 scsi_low_errfunc_synch(slp, msgflags)
3483 struct scsi_low_softc *slp;
3486 struct targ_info *ti = slp->sl_Tnexus;
3488 MSGIN_PERIOD(ti) = 0;
3489 MSGIN_OFFSET(ti) = 0;
3490 scsi_low_synch(slp);
3495 scsi_low_errfunc_wide(slp, msgflags)
3496 struct scsi_low_softc *slp;
3499 struct targ_info *ti = slp->sl_Tnexus;
3501 MSGIN_WIDTHP(ti) = 0;
3507 scsi_low_errfunc_qtag(slp, msgflags)
3508 struct scsi_low_softc *slp;
3512 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3514 if (slp->sl_Qnexus != NULL)
3516 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3518 if (slp->sl_Lnexus != NULL)
3520 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3521 scsi_low_calcf_lun(slp->sl_Lnexus);
3523 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3530 scsi_low_msgout(slp, ti, fl)
3531 struct scsi_low_softc *slp;
3532 struct targ_info *ti;
3535 struct scsi_low_msgout_data *mdp;
3538 #ifdef SCSI_LOW_DIAGNOSTIC
3539 if (ti != slp->sl_Tnexus)
3541 scsi_low_print(slp, NULL);
3542 panic("scsi_low_msgout: Target nexus inconsistent");
3544 #endif /* SCSI_LOW_DIAGNOSTIC */
3546 slp->sl_ph_count ++;
3547 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3549 printf("%s: too many phase changes\n", slp->sl_xname);
3550 slp->sl_error |= FATALIO;
3551 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3555 * Scsi phase changes.
3556 * Previously msgs asserted are accepted by our target or
3557 * processed by scsi_low_msgin.
3558 * Thus clear all saved informations.
3560 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3562 ti->ti_omsgflags = 0;
3563 ti->ti_emsgflags = 0;
3565 else if (slp->sl_atten == 0)
3568 * We did not assert attention, however still our target required
3569 * msgs. Resend previous msgs.
3571 ti->ti_msgflags |= ti->ti_omsgflags;
3572 ti->ti_omsgflags = 0;
3573 #ifdef SCSI_LOW_DIAGNOSTIC
3574 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3575 #endif /* SCSI_LOW_DIAGNOSTIC */
3579 * We have no msgs. send MSG_NOOP (OK?)
3581 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3582 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3587 ti->ti_msgoutlen = 0;
3588 slp->sl_clear_atten = 0;
3589 mdp = &scsi_low_msgout_data[0];
3590 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3592 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3594 ti->ti_omsgflags |= mdp->md_flags;
3595 ti->ti_msgflags &= ~mdp->md_flags;
3596 ti->ti_emsgflags = mdp->md_flags;
3598 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3599 if (mdp->md_msgfunc != NULL)
3600 len = (*mdp->md_msgfunc) (slp);
3604 #ifdef SCSI_LOW_DIAGNOSTIC
3605 scsi_low_msg_log_write(&ti->ti_log_msgout,
3606 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3607 #endif /* SCSI_LOW_DIAGNOSTIC */
3609 ti->ti_msgoutlen += len;
3610 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3612 slp->sl_clear_atten = 1;
3616 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3617 ti->ti_msgflags == 0)
3620 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3625 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3626 slp->sl_clear_atten = 1;
3628 return ti->ti_msgoutlen;
3631 /**************************************************************
3633 **************************************************************/
3635 scsi_low_msginfunc_noop(slp)
3636 struct scsi_low_softc *slp;
3643 scsi_low_msginfunc_rejop(slp)
3644 struct scsi_low_softc *slp;
3646 struct targ_info *ti = slp->sl_Tnexus;
3647 u_int8_t msg = ti->ti_msgin[0];
3649 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3650 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3655 scsi_low_msginfunc_cc(slp)
3656 struct scsi_low_softc *slp;
3658 struct lun_info *li;
3660 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3662 /* validate status */
3663 if (slp->sl_Qnexus == NULL)
3666 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3667 li = slp->sl_Lnexus;
3668 switch (slp->sl_scp.scp_status)
3671 li->li_maxnqio = li->li_maxnexus;
3676 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3677 scsi_low_reset_nexus_lun(slp, li, 0);
3685 if (li->li_maxnexus >= li->li_nqio)
3686 li->li_maxnexus = li->li_nqio - 1;
3687 li->li_maxnqio = li->li_maxnexus;
3692 slp->sl_error |= MSGERR;
3702 scsi_low_msginfunc_lcc(slp)
3703 struct scsi_low_softc *slp;
3705 struct targ_info *ti;
3706 struct lun_info *li;
3707 struct slccb *ncb, *cb;
3709 ti = slp->sl_Tnexus;
3710 li = slp->sl_Lnexus;
3711 if ((cb = slp->sl_Qnexus) == NULL)
3714 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3715 switch (slp->sl_scp.scp_status)
3719 li->li_maxnqio = li->li_maxnexus;
3723 slp->sl_error |= MSGERR;
3727 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3730 cb->ccb_error |= slp->sl_error;
3731 if (cb->ccb_error != 0)
3734 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3735 ncb = TAILQ_NEXT(ncb, ccb_chain))
3738 goto cmd_link_start;
3743 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3744 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3748 ncb->ccb_flags &= ~CCB_STARTQ;
3749 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3751 scsi_low_dealloc_qtag(ncb);
3752 ncb->ccb_tag = cb->ccb_tag;
3753 ncb->ccb_otag = cb->ccb_otag;
3754 cb->ccb_tag = SCSI_LOW_UNKTAG;
3755 cb->ccb_otag = SCSI_LOW_UNKTAG;
3756 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3757 panic("%s: linked ccb retried", slp->sl_xname);
3759 slp->sl_Qnexus = ncb;
3760 slp->sl_ph_count = 0;
3763 ncb->ccb_datalen = -1;
3764 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3765 ncb->ccb_flags &= ~CCB_INTERNAL;
3767 scsi_low_init_msgsys(slp, ti);
3769 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3771 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3772 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3773 ncb->ccb_tc = ncb->ccb_tcmax;
3775 /* setup saved scsi data pointer */
3776 ncb->ccb_sscp = ncb->ccb_scp;
3777 slp->sl_scp = ncb->ccb_sscp;
3778 slp->sl_error = ncb->ccb_error;
3780 #ifdef SCSI_LOW_DIAGNOSTIC
3781 scsi_low_msg_log_init(&ti->ti_log_msgin);
3782 scsi_low_msg_log_init(&ti->ti_log_msgout);
3783 #endif /* SCSI_LOW_DIAGNOSTIC */
3788 scsi_low_msginfunc_disc(slp)
3789 struct scsi_low_softc *slp;
3792 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3797 scsi_low_msginfunc_sdp(slp)
3798 struct scsi_low_softc *slp;
3800 struct slccb *cb = slp->sl_Qnexus;
3804 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3805 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3808 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3813 scsi_low_msginfunc_rp(slp)
3814 struct scsi_low_softc *slp;
3817 if (slp->sl_Qnexus != NULL)
3818 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3820 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3826 struct scsi_low_softc *slp;
3828 struct targ_info *ti = slp->sl_Tnexus;
3829 u_int period = 0, offset = 0, speed;
3833 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3834 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3835 MSGIN_OFFSET(ti) == 0)
3837 if ((offset = MSGIN_OFFSET(ti)) != 0)
3838 period = MSGIN_PERIOD(ti);
3839 s = offset ? "synchronous" : "async";
3844 * Target seems to be brain damaged.
3845 * Force async transfer.
3847 ti->ti_maxsynch.period = 0;
3848 ti->ti_maxsynch.offset = 0;
3849 printf("%s: target brain damaged. async transfer\n",
3854 ti->ti_maxsynch.period = period;
3855 ti->ti_maxsynch.offset = offset;
3857 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3861 * Current period and offset are not acceptable
3863 * The adapter changes max synch and max offset.
3865 printf("%s: synch neg failed. retry synch msg neg ...\n",
3870 ti->ti_osynch = ti->ti_maxsynch;
3873 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3877 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3879 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3880 struct slccb *cb = slp->sl_Qnexus;
3882 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3884 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3886 printf("%s(%d:*): <%s> offset %d period %dns ",
3887 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3891 speed = 1000 * 10 / (period * 4);
3892 printf("%d.%d M/s", speed / 10, speed % 10);
3901 struct scsi_low_softc *slp;
3903 struct targ_info *ti = slp->sl_Tnexus;
3906 ti->ti_width = MSGIN_WIDTHP(ti);
3907 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3911 * Current width is not acceptable for our adapter.
3912 * The adapter changes max width.
3914 printf("%s: wide neg failed. retry wide msg neg ...\n",
3919 ti->ti_owidth = ti->ti_width;
3920 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3922 ti->ti_setup_msg_done |=
3923 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3927 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3929 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3930 struct slccb *cb = slp->sl_Qnexus;
3932 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3934 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3936 printf("%s(%d:*): transfer width %d bits\n",
3937 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3943 scsi_low_msginfunc_simple_qtag(slp)
3944 struct scsi_low_softc *slp;
3946 struct targ_info *ti = slp->sl_Tnexus;
3947 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3949 if (slp->sl_Qnexus != NULL)
3951 if (slp->sl_Qnexus->ccb_tag != etag)
3953 slp->sl_error |= FATALIO;
3954 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3955 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3958 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3960 #ifdef SCSI_LOW_DEBUG
3961 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3963 #endif /* SCSI_LOW_DEBUG */
3965 slp->sl_error |= FATALIO;
3966 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3967 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3973 scsi_low_msginfunc_i_wide_residue(slp)
3974 struct scsi_low_softc *slp;
3976 struct targ_info *ti = slp->sl_Tnexus;
3977 struct slccb *cb = slp->sl_Qnexus;
3978 int res = (int) ti->ti_msgin[1];
3980 if (cb == NULL || res <= 0 ||
3981 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3982 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3985 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3988 slp->sl_scp.scp_datalen += res;
3989 slp->sl_scp.scp_data -= res;
3990 scsi_low_data_finish(slp);
3995 scsi_low_msginfunc_ext(slp)
3996 struct scsi_low_softc *slp;
3998 struct slccb *cb = slp->sl_Qnexus;
3999 struct lun_info *li = slp->sl_Lnexus;
4000 struct targ_info *ti = slp->sl_Tnexus;
4004 if (ti->ti_msginptr == 2)
4006 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4010 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4012 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4016 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4017 count = (int) htonl((long) (*ptr));
4018 if(slp->sl_scp.scp_datalen - count < 0 ||
4019 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4022 slp->sl_scp.scp_datalen -= count;
4023 slp->sl_scp.scp_data += count;
4026 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4030 retry = scsi_low_synch(slp);
4031 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4032 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4034 #ifdef SCSI_LOW_DEBUG
4035 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4037 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4039 #endif /* SCSI_LOW_DEBUG */
4042 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4046 retry = scsi_low_wide(slp);
4047 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4048 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4056 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4061 scsi_low_msginfunc_parity(slp)
4062 struct scsi_low_softc *slp;
4064 struct targ_info *ti = slp->sl_Tnexus;
4066 /* only I -> T, invalid! */
4067 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4072 scsi_low_msginfunc_msg_reject(slp)
4073 struct scsi_low_softc *slp;
4075 struct targ_info *ti = slp->sl_Tnexus;
4076 struct scsi_low_msgout_data *mdp;
4079 if (ti->ti_emsgflags != 0)
4081 printf("%s: msg flags [0x%x] rejected\n",
4082 slp->sl_xname, ti->ti_emsgflags);
4083 msgflags = SCSI_LOW_MSG_REJECT;
4084 mdp = &scsi_low_msgout_data[0];
4085 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4087 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4089 ti->ti_emsgflags &= ~mdp->md_flags;
4090 if (mdp->md_errfunc != NULL)
4091 (*mdp->md_errfunc) (slp, msgflags);
4099 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4100 slp->sl_error |= MSGERR;
4106 scsi_low_msgin(slp, ti, c)
4107 struct scsi_low_softc *slp;
4108 struct targ_info *ti;
4111 struct scsi_low_msgin_data *sdp;
4112 struct lun_info *li;
4115 #ifdef SCSI_LOW_DIAGNOSTIC
4116 if (ti != slp->sl_Tnexus)
4118 scsi_low_print(slp, NULL);
4119 panic("scsi_low_msgin: Target nexus inconsistent");
4121 #endif /* SCSI_LOW_DIAGNOSTIC */
4124 * Phase changes, clear the pointer.
4126 if (ti->ti_ophase != ti->ti_phase)
4129 ti->ti_msgin_parity_error = 0;
4131 slp->sl_ph_count ++;
4132 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4134 printf("%s: too many phase changes\n", slp->sl_xname);
4135 slp->sl_error |= FATALIO;
4136 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4141 * Store a current messages byte into buffer and
4142 * wait for the completion of the current msg.
4144 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4145 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4147 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4148 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4152 * Check parity errors.
4154 if ((c & SCSI_LOW_DATA_PE) != 0)
4156 ti->ti_msgin_parity_error ++;
4157 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4161 if (ti->ti_msgin_parity_error != 0)
4165 * Calculate messages length.
4167 msg = ti->ti_msgin[0];
4168 if (msg < MSGIN_DATA_LAST)
4169 sdp = &scsi_low_msgin_data[msg];
4171 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4173 if (ti->ti_msginlen == 0)
4175 ti->ti_msginlen = sdp->md_len;
4181 if (ti->ti_msginptr < ti->ti_msginlen)
4187 if ((msg & MSG_IDENTIFY) == 0)
4189 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4194 li = slp->sl_Lnexus;
4197 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4200 slp->sl_Lnexus = li;
4201 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4205 if (MSGCMD_LUN(msg) != li->li_lun)
4209 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4211 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4213 #ifdef SCSI_LOW_DEBUG
4214 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4218 #endif /* SCSI_LOW_DEBUG */
4226 * Msg process completed, reset msgin pointer and assert ATN if desired.
4229 slp->sl_error |= FATALIO;
4230 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4231 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4234 if (ti->ti_msginptr < ti->ti_msginlen)
4237 #ifdef SCSI_LOW_DIAGNOSTIC
4238 scsi_low_msg_log_write(&ti->ti_log_msgin,
4239 &ti->ti_msgin[0], ti->ti_msginlen);
4240 #endif /* SCSI_LOW_DIAGNOSTIC */
4246 /**********************************************************
4248 **********************************************************/
4250 scsi_low_disconnected(slp, ti)
4251 struct scsi_low_softc *slp;
4252 struct targ_info *ti;
4254 struct slccb *cb = slp->sl_Qnexus;
4256 /* check phase completion */
4257 switch (slp->sl_msgphase)
4260 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4261 scsi_low_msginfunc_cc(slp);
4262 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4266 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4267 scsi_low_msginfunc_cc(slp);
4268 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4272 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4273 scsi_low_msginfunc_cc(slp);
4279 struct lun_info *li;
4282 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4283 cb->ccb_flags |= CCB_DISCQ;
4284 cb->ccb_error |= slp->sl_error;
4290 #ifdef SCSI_LOW_STATICS
4291 scsi_low_statics.nexus_disconnected ++;
4292 #endif /* SCSI_LOW_STATICS */
4294 #ifdef SCSI_LOW_DEBUG
4295 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4297 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4298 scsi_low_print(slp, NULL);
4300 #endif /* SCSI_LOW_DEBUG */
4304 slp->sl_error |= FATALIO;
4305 if (ti->ti_phase == PH_SELSTART)
4306 slp->sl_error |= SELTIMEOUTIO;
4308 slp->sl_error |= UBFERR;
4317 #ifdef SCSI_LOW_DEBUG
4318 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4320 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4321 (cb->ccb_msgoutflag != 0 ||
4322 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4324 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4327 #endif /* SCSI_LOW_DEBUG */
4329 cb->ccb_error |= slp->sl_error;
4330 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4332 cb->ccb_flags |= CCB_STARTQ;
4333 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4338 scsi_low_bus_release(slp, ti);
4339 scsi_low_start(slp);
4343 /**********************************************************
4345 **********************************************************/
4347 scsi_low_alloc_qtag(cb)
4350 struct lun_info *li = cb->li;
4351 scsi_low_tag_t etag;
4353 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4356 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4357 etag = ffs(li->li_qtagbits);
4361 li->li_qtagbits &= ~(1 << (etag - 1));
4362 cb->ccb_otag = etag;
4365 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4366 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4367 if (li->li_qtagarray[li->li_qd] == 0)
4370 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4371 if (li->li_qtagarray[li->li_qd] == 0)
4377 li->li_qtagarray[li->li_qd] ++;
4378 cb->ccb_otag = (li->li_qd ++);
4380 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4384 scsi_low_dealloc_qtag(cb)
4387 struct lun_info *li = cb->li;
4388 scsi_low_tag_t etag;
4390 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4393 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4394 etag = cb->ccb_otag - 1;
4395 #ifdef SCSI_LOW_DIAGNOSTIC
4396 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4397 panic("scsi_low_dealloc_tag: illegal tag");
4398 #endif /* SCSI_LOW_DIAGNOSTIC */
4399 li->li_qtagbits |= (1 << etag);
4401 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4402 etag = cb->ccb_otag;
4403 #ifdef SCSI_LOW_DIAGNOSTIC
4404 if (etag >= SCSI_LOW_MAXNEXUS)
4405 panic("scsi_low_dealloc_tag: illegal tag");
4406 #endif /* SCSI_LOW_DIAGNOSTIC */
4407 li->li_qtagarray[etag] --;
4408 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4410 cb->ccb_otag = SCSI_LOW_UNKTAG;
4415 scsi_low_revoke_ccb(slp, cb, fdone)
4416 struct scsi_low_softc *slp;
4420 struct targ_info *ti = cb->ti;
4421 struct lun_info *li = cb->li;
4423 #ifdef SCSI_LOW_DIAGNOSTIC
4424 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4425 (CCB_STARTQ | CCB_DISCQ))
4427 panic("%s: ccb in both queue", slp->sl_xname);
4429 #endif /* SCSI_LOW_DIAGNOSTIC */
4431 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4433 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4436 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4438 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4444 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4445 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4448 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4449 (cb->ccb_flags & CCB_NORETRY) != 0))
4451 cb->ccb_error |= FATALIO;
4452 cb->ccb_flags &= ~CCB_AUTOSENSE;
4453 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4454 panic("%s: done ccb retried", slp->sl_xname);
4459 cb->ccb_error |= PENDINGIO;
4460 scsi_low_deactivate_qtag(cb);
4461 scsi_low_ccb_message_retry(cb);
4462 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4468 scsi_low_reset_nexus_lun(slp, li, fdone)
4469 struct scsi_low_softc *slp;
4470 struct lun_info *li;
4473 struct slccb *cb, *ncb, *ecb;
4479 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4481 ncb = TAILQ_NEXT(cb, ccb_chain);
4482 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4486 * presumely keep ordering of io
4488 cb->ccb_flags |= CCB_STARTQ;
4491 TAILQ_INSERT_HEAD(&slp->sl_start,\
4496 TAILQ_INSERT_AFTER(&slp->sl_start,\
4497 ecb, cb, ccb_chain);
4504 /**************************************************************
4506 **************************************************************/
4508 scsi_low_calcf_lun(li)
4509 struct lun_info *li;
4511 struct targ_info *ti = li->li_ti;
4512 struct scsi_low_softc *slp = ti->ti_sc;
4513 u_int cfgflags, diskflags;
4515 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4516 cfgflags = li->li_cfgflags;
4520 diskflags = li->li_diskflags & li->li_quirks;
4523 li->li_flags &= ~SCSI_LOW_DISC;
4524 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4525 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4526 (cfgflags & SCSI_LOW_DISC) != 0)
4527 li->li_flags |= SCSI_LOW_DISC;
4530 li->li_flags |= SCSI_LOW_NOPARITY;
4531 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4532 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4533 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4534 li->li_flags &= ~SCSI_LOW_NOPARITY;
4537 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4538 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4539 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4541 li->li_flags |= SCSI_LOW_QTAG;
4542 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4543 li->li_maxnqio = li->li_maxnexus;
4547 li->li_flags &= ~SCSI_LOW_QTAG;
4548 li->li_maxnexus = 0;
4549 li->li_maxnqio = li->li_maxnexus;
4553 li->li_flags &= ~SCSI_LOW_LINK;
4554 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4555 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4556 li->li_flags |= SCSI_LOW_LINK;
4558 /* compatible flags */
4559 li->li_flags &= ~SCSI_LOW_SYNC;
4560 if (ti->ti_maxsynch.offset > 0)
4561 li->li_flags |= SCSI_LOW_SYNC;
4563 #ifdef SCSI_LOW_DEBUG
4564 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4566 scsi_low_calcf_show(li);
4568 #endif /* SCSI_LOW_DEBUG */
4572 scsi_low_calcf_target(ti)
4573 struct targ_info *ti;
4575 struct scsi_low_softc *slp = ti->ti_sc;
4576 u_int offset, period, diskflags;
4578 diskflags = ti->ti_diskflags & ti->ti_quirks;
4581 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4582 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4584 offset = ti->ti_maxsynch.offset;
4585 period = ti->ti_maxsynch.period;
4586 if (offset == 0 || period == 0)
4587 offset = period = 0;
4591 offset = period = 0;
4594 ti->ti_maxsynch.offset = offset;
4595 ti->ti_maxsynch.period = period;
4598 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4599 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4600 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4602 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4603 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4604 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4606 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4608 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4609 ti->ti_maxsynch.period != ti->ti_osynch.period)
4610 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4611 if (ti->ti_width != ti->ti_owidth)
4612 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4614 ti->ti_osynch = ti->ti_maxsynch;
4615 ti->ti_owidth = ti->ti_width;
4618 #ifdef SCSI_LOW_DEBUG
4619 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4621 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4622 slp->sl_xname, ti->ti_id,
4623 ti->ti_maxsynch.period * 4,
4624 ti->ti_maxsynch.offset,
4627 #endif /* SCSI_LOW_DEBUG */
4631 scsi_low_calcf_show(li)
4632 struct lun_info *li;
4634 struct targ_info *ti = li->li_ti;
4635 struct scsi_low_softc *slp = ti->ti_sc;
4637 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4638 slp->sl_xname, ti->ti_id, li->li_lun,
4639 ti->ti_maxsynch.period * 4,
4640 ti->ti_maxsynch.offset,
4642 li->li_flags, SCSI_LOW_BITS);
4645 #ifdef SCSI_LOW_START_UP_CHECK
4646 /**************************************************************
4647 * scsi world start up
4648 **************************************************************/
4649 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
4652 scsi_low_start_up(slp)
4653 struct scsi_low_softc *slp;
4655 struct targ_info *ti;
4656 struct lun_info *li;
4660 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4662 for (target = 0; target < slp->sl_ntargs; target ++)
4664 if (target == slp->sl_hostid)
4666 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4668 printf("%s: scsi_low: target %d (host card)\n",
4669 slp->sl_xname, target);
4674 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4676 printf("%s: scsi_low: target %d lun ",
4677 slp->sl_xname, target);
4680 ti = slp->sl_ti[target];
4681 for (lun = 0; lun < slp->sl_nluns; lun ++)
4683 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4689 li = scsi_low_alloc_li(ti, lun, 1);
4691 scsi_low_enqueue(slp, ti, li, cb,
4692 CCB_AUTOSENSE | CCB_POLLED, 0);
4694 scsi_low_poll(slp, cb);
4696 if (li->li_state != SCSI_LOW_LUN_OK)
4699 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4705 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4714 scsi_low_poll(slp, cb)
4715 struct scsi_low_softc *slp;
4721 while (slp->sl_nio > 0)
4723 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4725 (*slp->sl_funcs->scsi_low_poll) (slp);
4726 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4730 scsi_low_timeout_check(slp);
4735 #endif /* SCSI_LOW_START_UP_CHECK */
4737 /**********************************************************
4739 **********************************************************/
4740 #ifdef SCSI_LOW_DEBUG
4742 scsi_low_test_abort(slp, ti, li)
4743 struct scsi_low_softc *slp;
4744 struct targ_info *ti;
4745 struct lun_info *li;
4749 if (li->li_disc > 1)
4751 acb = TAILQ_FIRST(&li->li_discq);
4752 if (scsi_low_abort_ccb(slp, acb) == 0)
4754 printf("%s: aborting ccb(0x%lx) start\n",
4755 slp->sl_xname, (u_long) acb);
4761 scsi_low_test_atten(slp, ti, msg)
4762 struct scsi_low_softc *slp;
4763 struct targ_info *ti;
4767 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4768 scsi_low_assert_msg(slp, ti, msg, 0);
4770 printf("%s: atten check OK\n", slp->sl_xname);
4774 scsi_low_test_cmdlnk(slp, cb)
4775 struct scsi_low_softc *slp;
4778 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4780 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4783 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4784 slp->sl_scp.scp_cmdlen);
4785 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4786 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4788 #endif /* SCSI_LOW_DEBUG */
4791 scsi_low_info(slp, ti, s)
4792 struct scsi_low_softc *slp;
4793 struct targ_info *ti;
4798 slp = LIST_FIRST(&sl_tab);
4802 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4805 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4806 ti = TAILQ_NEXT(ti, ti_chain))
4808 scsi_low_print(slp, ti);
4813 scsi_low_print(slp, ti);
4817 static u_char *phase[] =
4819 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4820 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4824 scsi_low_print(slp, ti)
4825 struct scsi_low_softc *slp;
4826 struct targ_info *ti;
4828 struct lun_info *li;
4832 if (ti == NULL || ti == slp->sl_Tnexus)
4834 ti = slp->sl_Tnexus;
4835 li = slp->sl_Lnexus;
4836 cb = slp->sl_Qnexus;
4840 li = LIST_FIRST(&ti->ti_litab);
4841 cb = TAILQ_FIRST(&li->li_discq);
4845 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4846 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4852 u_int flags = 0, maxnqio = 0, nqio = 0;
4858 flags = li->li_flags;
4859 maxnqio = li->li_maxnqio;
4863 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4865 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4866 phase[(int) ti->ti_phase], ti->ti_disc,
4871 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4872 (u_int) cb->ccb_scp.scp_cmd[0],
4873 cb->ccb_scp.scp_cmdlen,
4875 cb->ccb_scp.scp_datalen,
4876 (u_int) cb->ccb_sscp.scp_status,
4877 cb->ccb_error, SCSI_LOW_ERRORBITS);
4880 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4881 (u_int) (ti->ti_msginptr),
4882 (u_int) (ti->ti_msgin[0]),
4883 (u_int) (ti->ti_msgin[1]),
4884 (u_int) (ti->ti_msgin[2]),
4885 (u_int) (ti->ti_msgin[3]),
4886 (u_int) (ti->ti_msgin[4]),
4889 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4890 (u_int) ti->ti_msgflags,
4891 (u_int) (ti->ti_msgoutstr[0]),
4892 (u_int) (ti->ti_msgoutstr[1]),
4893 (u_int) (ti->ti_msgoutstr[2]),
4894 (u_int) (ti->ti_msgoutstr[3]),
4895 (u_int) (ti->ti_msgoutstr[4]),
4897 flags, SCSI_LOW_BITS);
4899 #ifdef SCSI_LOW_DIAGNOSTIC
4900 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4901 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4902 #endif /* SCSI_LOW_DIAGNOSTIC */
4906 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4907 (u_long) sp->scp_data,
4909 (u_int) sp->scp_status,
4910 slp->sl_error, SCSI_LOW_ERRORBITS);