1 /* $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.4 2001/12/17 13:30:20 non Exp $ */
2 /* $NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ */
5 #define SCSI_LOW_STATICS
7 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
8 #define SCSI_LOW_START_UP_CHECK
10 /* #define SCSI_LOW_INFO_DETAIL */
11 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
12 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
15 #define SCSI_LOW_TARGET_OPEN
16 #endif /* __NetBSD__ */
19 #define SCSI_LOW_FLAGS_QUIRKS_OK
20 #endif /* __FreeBSD__ */
23 * [NetBSD for NEC PC-98 series]
24 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
25 * NetBSD/pc98 porting staff. All rights reserved.
26 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
27 * Naofumi HONDA. All rights reserved.
29 * [Ported for FreeBSD CAM]
30 * Copyright (c) 2000, 2001
31 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
32 * All rights reserved.
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
37 * 1. Redistributions of source code must retain the above copyright
38 * notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 * notice, this list of conditions and the following disclaimer in the
41 * documentation and/or other materials provided with the distribution.
42 * 3. The name of the author may not be used to endorse or promote products
43 * derived from this software without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
49 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
54 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE.
58 /* <On the nexus establishment>
59 * When our host is reselected,
60 * nexus establish processes are little complicated.
61 * Normal steps are followings:
62 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
63 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
64 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
73 #if __FreeBSD_version >= 500001
76 #include <machine/clock.h>
78 #include <sys/devicestat.h>
79 #endif /* __FreeBSD__ */
82 #include <sys/queue.h>
83 #include <sys/malloc.h>
84 #include <sys/errno.h>
87 #include <sys/device.h>
90 #include <machine/bus.h>
91 #include <machine/intr.h>
92 #include <machine/dvcfg.h>
96 #include <dev/scsipi/scsipi_all.h>
97 #include <dev/scsipi/scsipiconf.h>
98 #include <dev/scsipi/scsipi_disk.h>
99 #include <dev/scsipi/scsi_all.h>
100 #include <dev/scsipi/scsiconf.h>
101 #include <sys/scsiio.h>
103 #include <i386/Cbus/dev/scsi_low.h>
104 #endif /* __NetBSD__ */
108 #include <cam/cam_ccb.h>
109 #include <cam/cam_sim.h>
110 #include <cam/cam_debug.h>
111 #include <cam/cam_periph.h>
113 #include <cam/scsi/scsi_all.h>
114 #include <cam/scsi/scsi_message.h>
116 #include <cam/scsi/scsi_low.h>
118 #include <sys/cons.h>
119 #endif /* __FreeBSD__ */
121 /**************************************************************
123 **************************************************************/
124 #define SCSI_LOW_POLL_HZ 1000
126 /* functions return values */
127 #define SCSI_LOW_START_NO_QTAG 0
128 #define SCSI_LOW_START_QTAG 1
130 #define SCSI_LOW_DONE_COMPLETE 0
131 #define SCSI_LOW_DONE_RETRY 1
133 /* internal disk flags */
134 #define SCSI_LOW_DISK_DISC 0x00000001
135 #define SCSI_LOW_DISK_QTAG 0x00000002
136 #define SCSI_LOW_DISK_LINK 0x00000004
137 #define SCSI_LOW_DISK_PARITY 0x00000008
138 #define SCSI_LOW_DISK_SYNC 0x00010000
139 #define SCSI_LOW_DISK_WIDE_16 0x00020000
140 #define SCSI_LOW_DISK_WIDE_32 0x00040000
141 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
142 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
143 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
145 /**************************************************************
147 **************************************************************/
148 /* static */ void scsi_low_info __P((struct scsi_low_softc *, struct targ_info *, u_char *));
149 static void scsi_low_engage __P((void *));
150 static struct slccb *scsi_low_establish_ccb __P((struct targ_info *, struct lun_info *, scsi_low_tag_t));
151 static int scsi_low_done __P((struct scsi_low_softc *, struct slccb *));
152 static int scsi_low_setup_done __P((struct scsi_low_softc *, struct slccb *));
153 static void scsi_low_bus_release __P((struct scsi_low_softc *, struct targ_info *));
154 static void scsi_low_twiddle_wait __P((void));
155 static struct lun_info *scsi_low_alloc_li __P((struct targ_info *, int, int));
156 static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int));
157 static void scsi_low_calcf_lun __P((struct lun_info *));
158 static void scsi_low_calcf_target __P((struct targ_info *));
159 static void scsi_low_calcf_show __P((struct lun_info *));
160 static void scsi_low_reset_nexus __P((struct scsi_low_softc *, int));
161 static void scsi_low_reset_nexus_target __P((struct scsi_low_softc *, struct targ_info *, int));
162 static void scsi_low_reset_nexus_lun __P((struct scsi_low_softc *, struct lun_info *, int));
163 static int scsi_low_init __P((struct scsi_low_softc *, u_int));
164 static void scsi_low_start __P((struct scsi_low_softc *));
165 static void scsi_low_free_ti __P((struct scsi_low_softc *));
167 static int scsi_low_alloc_qtag __P((struct slccb *));
168 static int scsi_low_dealloc_qtag __P((struct slccb *));
169 static int scsi_low_enqueue __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int));
170 static int scsi_low_message_enqueue __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int));
171 static void scsi_low_unit_ready_cmd __P((struct slccb *));
172 static void scsi_low_timeout __P((void *));
173 static int scsi_low_timeout_check __P((struct scsi_low_softc *));
174 #ifdef SCSI_LOW_START_UP_CHECK
175 static int scsi_low_start_up __P((struct scsi_low_softc *));
176 #endif /* SCSI_LOW_START_UP_CHECK */
177 static int scsi_low_abort_ccb __P((struct scsi_low_softc *, struct slccb *));
178 static struct slccb *scsi_low_revoke_ccb __P((struct scsi_low_softc *, struct slccb *, int));
180 int scsi_low_version_major = 2;
181 int scsi_low_version_minor = 17;
183 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
185 /**************************************************************
186 * Debug, Run test and Statics
187 **************************************************************/
188 #ifdef SCSI_LOW_INFO_DETAIL
189 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
190 #else /* !SCSI_LOW_INFO_DETAIL */
191 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
192 #endif /* !SCSI_LOW_INFO_DETAIL */
194 #ifdef SCSI_LOW_STATICS
195 struct scsi_low_statics {
198 int nexus_disconnected;
199 int nexus_reselected;
202 #endif /* SCSI_LOW_STATICS */
204 #ifdef SCSI_LOW_DEBUG
205 #define SCSI_LOW_DEBUG_DONE 0x00001
206 #define SCSI_LOW_DEBUG_DISC 0x00002
207 #define SCSI_LOW_DEBUG_SENSE 0x00004
208 #define SCSI_LOW_DEBUG_CALCF 0x00008
209 #define SCSI_LOW_DEBUG_ACTION 0x10000
210 int scsi_low_debug = 0;
212 #define SCSI_LOW_MAX_ATTEN_CHECK 32
213 #define SCSI_LOW_ATTEN_CHECK 0x0001
214 #define SCSI_LOW_CMDLNK_CHECK 0x0002
215 #define SCSI_LOW_ABORT_CHECK 0x0004
216 #define SCSI_LOW_NEXUS_CHECK 0x0008
217 int scsi_low_test = 0;
218 int scsi_low_test_id = 0;
220 static void scsi_low_test_abort __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *));
221 static void scsi_low_test_cmdlnk __P((struct scsi_low_softc *, struct slccb *));
222 static void scsi_low_test_atten __P((struct scsi_low_softc *, struct targ_info *, u_int));
223 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
224 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
225 #define SCSI_LOW_DEBUG_GO(fl, id) \
226 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
227 #endif /* SCSI_LOW_DEBUG */
229 /**************************************************************
231 **************************************************************/
232 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
233 GENERIC_CCB(scsi_low, slccb, ccb_chain)
235 /**************************************************************
237 **************************************************************/
238 #define SCSI_LOW_INLINE static __inline
239 SCSI_LOW_INLINE void scsi_low_activate_qtag __P((struct slccb *));
240 SCSI_LOW_INLINE void scsi_low_deactivate_qtag __P((struct slccb *));
241 SCSI_LOW_INLINE void scsi_low_ccb_message_assert __P((struct slccb *, u_int));
242 SCSI_LOW_INLINE void scsi_low_ccb_message_exec __P((struct scsi_low_softc *, struct slccb *));
243 SCSI_LOW_INLINE void scsi_low_ccb_message_retry __P((struct slccb *));
244 SCSI_LOW_INLINE void scsi_low_ccb_message_clear __P((struct slccb *));
245 SCSI_LOW_INLINE void scsi_low_init_msgsys __P((struct scsi_low_softc *, struct targ_info *));
248 scsi_low_activate_qtag(cb)
251 struct lun_info *li = cb->li;
253 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
257 cb->ccb_tag = cb->ccb_otag;
261 scsi_low_deactivate_qtag(cb)
264 struct lun_info *li = cb->li;
266 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
270 cb->ccb_tag = SCSI_LOW_UNKTAG;
274 scsi_low_ccb_message_exec(slp, cb)
275 struct scsi_low_softc *slp;
279 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
280 cb->ccb_msgoutflag = 0;
284 scsi_low_ccb_message_assert(cb, msg)
289 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
293 scsi_low_ccb_message_retry(cb)
296 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
300 scsi_low_ccb_message_clear(cb)
303 cb->ccb_msgoutflag = 0;
307 scsi_low_init_msgsys(slp, ti)
308 struct scsi_low_softc *slp;
309 struct targ_info *ti;
313 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
314 SCSI_LOW_DEASSERT_ATN(slp);
315 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
318 /*=============================================================
319 * START OF OS switch (All OS depend fucntions should be here)
320 =============================================================*/
321 /* common os depend utitlities */
322 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
323 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
324 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
326 static u_int8_t scsi_low_cmd_flags[256] = {
327 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
328 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
329 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
330 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
331 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
334 struct scsi_low_error_code {
339 static struct slccb *scsi_low_find_ccb __P((struct scsi_low_softc *, u_int, u_int, void *));
340 static int scsi_low_translate_error_code __P((struct slccb *, struct scsi_low_error_code *));
342 static struct slccb *
343 scsi_low_find_ccb(slp, target, lun, osdep)
344 struct scsi_low_softc *slp;
348 struct targ_info *ti;
352 ti = slp->sl_ti[target];
353 li = scsi_low_alloc_li(ti, lun, 0);
357 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
360 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
361 cb = TAILQ_NEXT(cb, ccb_chain))
363 if (cb->osdep == osdep)
367 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
368 cb = TAILQ_NEXT(cb, ccb_chain))
370 if (cb->osdep == osdep)
377 scsi_low_translate_error_code(cb, tp)
379 struct scsi_low_error_code *tp;
382 if (cb->ccb_error == 0)
383 return tp->error_code;
385 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
387 return tp->error_code;
390 #ifdef SCSI_LOW_INTERFACE_XS
391 /**************************************************************
392 * SCSI INTERFACE (XS)
393 **************************************************************/
394 #define SCSI_LOW_MINPHYS 0x10000
395 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
396 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
397 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
398 #define SCSI_LOW_XS_POLL_HZ 1000
400 static int scsi_low_poll_xs __P((struct scsi_low_softc *, struct slccb *));
401 static void scsi_low_scsi_minphys_xs __P((struct buf *));
402 #ifdef SCSI_LOW_TARGET_OPEN
403 static int scsi_low_target_open __P((struct scsipi_link *, struct cfdata *));
404 #endif /* SCSI_LOW_TARGET_OPEN */
405 static int scsi_low_scsi_cmd_xs __P((struct scsipi_xfer *));
406 static int scsi_low_enable_xs __P((void *, int));
407 static int scsi_low_ioctl_xs __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
409 static int scsi_low_attach_xs __P((struct scsi_low_softc *));
410 static int scsi_low_world_start_xs __P((struct scsi_low_softc *));
411 static int scsi_low_dettach_xs __P((struct scsi_low_softc *));
412 static int scsi_low_ccb_setup_xs __P((struct scsi_low_softc *, struct slccb *));
413 static int scsi_low_done_xs __P((struct scsi_low_softc *, struct slccb *));
414 static void scsi_low_timeout_xs __P((struct scsi_low_softc *, int, int));
415 static u_int scsi_low_translate_quirks_xs __P((u_int));
416 static void scsi_low_setup_quirks_xs __P((struct targ_info *, struct lun_info *, u_int));
418 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
420 scsi_low_world_start_xs,
422 scsi_low_ccb_setup_xs,
427 struct scsipi_device scsi_low_dev = {
428 NULL, /* Use default error handler */
429 NULL, /* have a queue, served by this */
430 NULL, /* have no async handler */
431 NULL, /* Use default 'done' routine */
434 struct scsi_low_error_code scsi_low_error_code_xs[] = {
438 {SELTIMEOUTIO, XS_SELTIMEOUT},
439 {TIMEOUTIO, XS_TIMEOUT},
440 {-1, XS_DRIVER_STUFFUP}
444 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
445 struct scsipi_link *link;
451 struct scsi_low_softc *slp;
452 int s, error = ENOTTY;
454 slp = (struct scsi_low_softc *) link->adapter_softc;
455 if ((slp->sl_flags & HW_INACTIVE) != 0)
458 if (cmd == SCBUSIORESET)
460 s = SCSI_LOW_SPLSCSI();
461 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
465 else if (slp->sl_funcs->scsi_low_ioctl != 0)
467 error = (*slp->sl_funcs->scsi_low_ioctl)
468 (slp, cmd, addr, flag, p);
475 scsi_low_enable_xs(arg, enable)
479 struct scsi_low_softc *slp = arg;
483 if ((slp->sl_flags & HW_INACTIVE) != 0)
488 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
489 (slp->sl_flags & HW_POWERCTRL) == 0)
492 slp->sl_flags |= HW_POWDOWN;
493 if (slp->sl_funcs->scsi_low_power != NULL)
495 (*slp->sl_funcs->scsi_low_power)
496 (slp, SCSI_LOW_POWDOWN);
503 scsi_low_scsi_minphys_xs(bp)
507 if (bp->b_bcount > SCSI_LOW_MINPHYS)
508 bp->b_bcount = SCSI_LOW_MINPHYS;
513 scsi_low_poll_xs(slp, cb)
514 struct scsi_low_softc *slp;
517 struct scsipi_xfer *xs = cb->osdep;
520 cb->ccb_flags |= CCB_NOSDONE;
523 while (slp->sl_nio > 0)
525 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
527 (*slp->sl_funcs->scsi_low_poll) (slp);
529 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
531 cb->ccb_flags |= CCB_NORETRY;
532 cb->ccb_error |= FATALIO;
533 (void) scsi_low_revoke_ccb(slp, cb, 1);
534 printf("%s: hardware inactive in poll mode\n",
538 if ((xs->flags & ITSDONE) != 0)
541 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
545 scsi_low_timeout_check(slp);
548 xs->flags |= ITSDONE;
554 scsi_low_scsi_cmd_xs(xs)
555 struct scsipi_xfer *xs;
557 struct scsipi_link *splp = xs->sc_link;
558 struct scsi_low_softc *slp = splp->adapter_softc;
559 struct targ_info *ti;
562 int s, targ, lun, flags, rv;
564 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
565 return TRY_AGAIN_LATER;
567 targ = splp->scsipi_scsi.target,
568 lun = splp->scsipi_scsi.lun;
569 ti = slp->sl_ti[targ];
574 if ((xs->flags & SCSI_POLL) == 0)
575 flags = CCB_AUTOSENSE;
577 flags = CCB_AUTOSENSE | CCB_POLLED;
580 s = SCSI_LOW_SPLSCSI();
581 li = scsi_low_alloc_li(ti, lun, 1);
582 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
584 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
587 if ((xs->flags & SCSI_RESET) != 0)
589 flags |= CCB_NORETRY | CCB_URGENT;
590 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
594 if (ti->ti_setup_msg != 0)
596 scsi_low_message_enqueue(slp, ti, li, flags);
600 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
603 #ifdef SCSI_LOW_DEBUG
604 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
606 scsi_low_test_abort(slp, ti, li);
608 #endif /* SCSI_LOW_DEBUG */
610 if ((cb->ccb_flags & CCB_POLLED) != 0)
612 rv = scsi_low_poll_xs(slp, cb);
616 rv = SUCCESSFULLY_QUEUED;
623 scsi_low_attach_xs(slp)
624 struct scsi_low_softc *slp;
626 struct scsipi_adapter *sap;
627 struct scsipi_link *splp;
629 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
631 sap = SCSI_LOW_MALLOC(sizeof(*sap));
634 splp = SCSI_LOW_MALLOC(sizeof(*splp));
638 SCSI_LOW_BZERO(sap, sizeof(*sap));
639 SCSI_LOW_BZERO(splp, sizeof(*splp));
641 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
642 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
643 sap->scsipi_enable = scsi_low_enable_xs;
644 sap->scsipi_ioctl = scsi_low_ioctl_xs;
645 #ifdef SCSI_LOW_TARGET_OPEN
646 sap->open_target_lu = scsi_low_target_open;
647 #endif /* SCSI_LOW_TARGET_OPEN */
649 splp->adapter_softc = slp;
650 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
651 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
652 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
653 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
654 splp->openings = slp->sl_openings;
655 splp->type = BUS_SCSI;
656 splp->adapter_softc = slp;
658 splp->device = &scsi_low_dev;
660 slp->sl_si.si_splp = splp;
661 slp->sl_show_result = SHOW_ALL_NEG;
666 scsi_low_world_start_xs(slp)
667 struct scsi_low_softc *slp;
674 scsi_low_dettach_xs(slp)
675 struct scsi_low_softc *slp;
679 * scsipi does not have dettach bus fucntion.
681 scsipi_dettach_scsibus(slp->sl_si.si_splp);
687 scsi_low_ccb_setup_xs(slp, cb)
688 struct scsi_low_softc *slp;
691 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
693 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
695 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
696 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
697 cb->ccb_scp.scp_data = xs->data;
698 cb->ccb_scp.scp_datalen = xs->datalen;
699 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
700 SCSI_LOW_WRITE : SCSI_LOW_READ;
701 cb->ccb_tcmax = xs->timeout / 1000;
705 scsi_low_unit_ready_cmd(cb);
707 return SCSI_LOW_START_QTAG;
711 scsi_low_done_xs(slp, cb)
712 struct scsi_low_softc *slp;
715 struct scsipi_xfer *xs;
717 xs = (struct scsipi_xfer *) cb->osdep;
718 if (cb->ccb_error == 0)
720 xs->error = XS_NOERROR;
725 if (cb->ccb_rcnt >= slp->sl_max_retry)
726 cb->ccb_error |= ABORTIO;
728 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
729 (cb->ccb_error & ABORTIO) == 0)
732 if ((cb->ccb_error & SENSEIO) != 0)
734 xs->sense.scsi_sense = cb->ccb_sense;
737 xs->error = scsi_low_translate_error_code(cb,
738 &scsi_low_error_code_xs[0]);
740 #ifdef SCSI_LOW_DIAGNOSTIC
741 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
742 cb->ccb_scp.scp_cmdlen > 0 &&
743 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
744 SCSI_LOW_CMD_ABORT_WARNING) != 0)
746 printf("%s: WARNING: scsi_low IO abort\n",
748 scsi_low_print(slp, NULL);
750 #endif /* SCSI_LOW_DIAGNOSTIC */
753 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
754 xs->status = 0; /* XXX */
756 xs->status = cb->ccb_scp.scp_status;
758 xs->flags |= ITSDONE;
759 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
766 scsi_low_timeout_xs(slp, ch, action)
767 struct scsi_low_softc *slp;
774 case SCSI_LOW_TIMEOUT_CH_IO:
777 case SCSI_LOW_TIMEOUT_START:
778 timeout(scsi_low_timeout, slp,
779 hz / SCSI_LOW_TIMEOUT_HZ);
781 case SCSI_LOW_TIMEOUT_STOP:
782 untimeout(scsi_low_timeout, slp);
787 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
790 case SCSI_LOW_TIMEOUT_START:
791 timeout(scsi_low_engage, slp, 1);
793 case SCSI_LOW_TIMEOUT_STOP:
794 untimeout(scsi_low_engage, slp);
799 case SCSI_LOW_TIMEOUT_CH_RECOVER:
805 scsi_low_translate_quirks_xs(quirks)
810 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
813 if (quirks & SDEV_NODISC)
814 flags &= ~SCSI_LOW_DISK_DISC;
815 #endif /* SDEV_NODISC */
817 if (quirks & SDEV_NOPARITY)
818 flags &= ~SCSI_LOW_DISK_PARITY;
819 #endif /* SDEV_NOPARITY */
821 if (quirks & SDEV_NOCMDLNK)
822 flags &= ~SCSI_LOW_DISK_LINK;
823 #endif /* SDEV_NOCMDLNK */
825 if (quirks & SDEV_NOTAG)
826 flags &= ~SCSI_LOW_DISK_QTAG;
827 #endif /* SDEV_NOTAG */
829 if (quirks & SDEV_NOSYNC)
830 flags &= ~SCSI_LOW_DISK_SYNC;
831 #endif /* SDEV_NOSYNC */
837 scsi_low_setup_quirks_xs(ti, li, flags)
838 struct targ_info *ti;
844 li->li_sloi.sloi_quirks = flags;
845 quirks = scsi_low_translate_quirks_xs(flags);
846 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
847 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
848 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
849 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
850 scsi_low_calcf_target(ti);
851 scsi_low_calcf_lun(li);
852 scsi_low_calcf_show(li);
855 #ifdef SCSI_LOW_TARGET_OPEN
857 scsi_low_target_open(link, cf)
858 struct scsipi_link *link;
861 u_int target = link->scsipi_scsi.target;
862 u_int lun = link->scsipi_scsi.lun;
863 struct scsi_low_softc *slp;
864 struct targ_info *ti;
867 slp = (struct scsi_low_softc *) link->adapter_softc;
868 ti = slp->sl_ti[target];
869 li = scsi_low_alloc_li(ti, lun, 0);
873 li->li_cfgflags = cf->cf_flags;
874 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
877 #endif /* SCSI_LOW_TARGET_OPEN */
879 #endif /* SCSI_LOW_INTERFACE_XS */
881 #ifdef SCSI_LOW_INTERFACE_CAM
882 /**************************************************************
883 * SCSI INTERFACE (CAM)
884 **************************************************************/
885 #define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
886 #define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
887 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
889 static void scsi_low_poll_cam __P((struct cam_sim *));
890 static void scsi_low_cam_rescan_callback __P((struct cam_periph *, union ccb *));
891 static void scsi_low_rescan_bus_cam __P((struct scsi_low_softc *));
892 void scsi_low_scsi_action_cam __P((struct cam_sim *, union ccb *));
894 static int scsi_low_attach_cam __P((struct scsi_low_softc *));
895 static int scsi_low_world_start_cam __P((struct scsi_low_softc *));
896 static int scsi_low_dettach_cam __P((struct scsi_low_softc *));
897 static int scsi_low_ccb_setup_cam __P((struct scsi_low_softc *, struct slccb *));
898 static int scsi_low_done_cam __P((struct scsi_low_softc *, struct slccb *));
899 static void scsi_low_timeout_cam __P((struct scsi_low_softc *, int, int));
901 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
903 scsi_low_world_start_cam,
904 scsi_low_dettach_cam,
905 scsi_low_ccb_setup_cam,
910 struct scsi_low_error_code scsi_low_error_code_cam[] = {
912 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
913 {SENSEERR, CAM_AUTOSENSE_FAIL},
914 {UACAERR, CAM_SCSI_STATUS_ERROR},
915 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
916 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
917 {TIMEOUTIO, CAM_CMD_TIMEOUT},
918 {PDMAERR, CAM_DATA_RUN_ERR},
919 {PARITYERR, CAM_UNCOR_PARITY},
920 {UBFERR, CAM_UNEXP_BUSFREE},
921 {ABORTIO, CAM_REQ_ABORTED},
922 {-1, CAM_UNREC_HBA_ERROR}
925 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
928 * Please check a polling hz, currently we assume scsi_low_poll() is
931 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
934 scsi_low_poll_cam(sim)
937 struct scsi_low_softc *slp = SIM2SLP(sim);
939 (*slp->sl_funcs->scsi_low_poll) (slp);
941 if (slp->sl_si.si_poll_count ++ >=
942 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
944 slp->sl_si.si_poll_count = 0;
945 scsi_low_timeout_check(slp);
950 scsi_low_cam_rescan_callback(periph, ccb)
951 struct cam_periph *periph;
955 xpt_free_path(ccb->ccb_h.path);
960 scsi_low_rescan_bus_cam(slp)
961 struct scsi_low_softc *slp;
963 struct cam_path *path;
964 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
967 bzero(ccb, sizeof(union ccb));
969 status = xpt_create_path(&path, xpt_periph,
970 cam_sim_path(slp->sl_si.sim), -1, 0);
971 if (status != CAM_REQ_CMP)
974 xpt_setup_ccb(&ccb->ccb_h, path, 5);
975 ccb->ccb_h.func_code = XPT_SCAN_BUS;
976 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
977 ccb->crcn.flags = CAM_FLAG_NONE;
982 scsi_low_scsi_action_cam(sim, ccb)
986 struct scsi_low_softc *slp = SIM2SLP(sim);
987 struct targ_info *ti;
990 u_int lun, flags, msg, target;
993 target = (u_int) (ccb->ccb_h.target_id);
994 lun = (u_int) ccb->ccb_h.target_lun;
996 #ifdef SCSI_LOW_DEBUG
997 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
999 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
1000 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1002 #endif /* SCSI_LOW_DEBUG */
1004 switch (ccb->ccb_h.func_code) {
1005 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1006 #ifdef SCSI_LOW_DIAGNOSTIC
1007 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1009 printf("%s: invalid target/lun\n", slp->sl_xname);
1010 ccb->ccb_h.status = CAM_REQ_INVALID;
1014 #endif /* SCSI_LOW_DIAGNOSTIC */
1016 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1017 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1022 ti = slp->sl_ti[target];
1025 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1026 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1030 s = SCSI_LOW_SPLSCSI();
1031 li = scsi_low_alloc_li(ti, lun, 1);
1033 if (ti->ti_setup_msg != 0)
1035 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1038 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1040 #ifdef SCSI_LOW_DEBUG
1041 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1043 scsi_low_test_abort(slp, ti, li);
1045 #endif /* SCSI_LOW_DEBUG */
1049 case XPT_EN_LUN: /* Enable LUN as a target */
1050 case XPT_TARGET_IO: /* Execute target I/O request */
1051 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1052 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1054 ccb->ccb_h.status = CAM_REQ_INVALID;
1058 case XPT_ABORT: /* Abort the specified CCB */
1059 #ifdef SCSI_LOW_DIAGNOSTIC
1060 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1062 printf("%s: invalid target/lun\n", slp->sl_xname);
1063 ccb->ccb_h.status = CAM_REQ_INVALID;
1067 #endif /* SCSI_LOW_DIAGNOSTIC */
1069 s = SCSI_LOW_SPLSCSI();
1070 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1071 rv = scsi_low_abort_ccb(slp, cb);
1075 ccb->ccb_h.status = CAM_REQ_CMP;
1077 ccb->ccb_h.status = CAM_REQ_INVALID;
1081 case XPT_SET_TRAN_SETTINGS: {
1082 struct ccb_trans_settings *cts;
1085 #ifdef SCSI_LOW_DIAGNOSTIC
1086 if (target == CAM_TARGET_WILDCARD)
1088 printf("%s: invalid target\n", slp->sl_xname);
1089 ccb->ccb_h.status = CAM_REQ_INVALID;
1093 #endif /* SCSI_LOW_DIAGNOSTIC */
1095 ti = slp->sl_ti[target];
1096 if (lun == CAM_LUN_WILDCARD)
1099 s = SCSI_LOW_SPLSCSI();
1100 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
1101 CCB_TRANS_SYNC_RATE_VALID |
1102 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
1104 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
1105 val = cts->bus_width;
1106 if (val < ti->ti_width)
1109 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
1110 val = cts->sync_period;
1111 if (val == 0 || val > ti->ti_maxsynch.period)
1112 ti->ti_maxsynch.period = val;
1114 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
1115 val = cts->sync_offset;
1116 if (val < ti->ti_maxsynch.offset)
1117 ti->ti_maxsynch.offset = val;
1120 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1121 scsi_low_calcf_target(ti);
1124 if ((cts->valid & (CCB_TRANS_DISC_VALID |
1125 CCB_TRANS_TQ_VALID)) != 0)
1127 li = scsi_low_alloc_li(ti, lun, 1);
1128 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
1130 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
1131 li->li_quirks |= SCSI_LOW_DISK_DISC;
1133 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1135 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
1137 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
1138 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1140 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1143 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1144 scsi_low_calcf_target(ti);
1145 scsi_low_calcf_lun(li);
1146 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1147 scsi_low_calcf_show(li);
1151 ccb->ccb_h.status = CAM_REQ_CMP;
1156 case XPT_GET_TRAN_SETTINGS: {
1157 struct ccb_trans_settings *cts;
1161 #ifdef SCSI_LOW_DIAGNOSTIC
1162 if (target == CAM_TARGET_WILDCARD)
1164 printf("%s: invalid target\n", slp->sl_xname);
1165 ccb->ccb_h.status = CAM_REQ_INVALID;
1169 #endif /* SCSI_LOW_DIAGNOSTIC */
1170 ti = slp->sl_ti[target];
1171 if (lun == CAM_LUN_WILDCARD)
1174 s = SCSI_LOW_SPLSCSI();
1175 li = scsi_low_alloc_li(ti, lun, 1);
1176 #ifdef CAM_NEW_TRAN_CODE
1177 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1178 struct ccb_trans_settings_scsi *scsi =
1179 &cts->proto_specific.scsi;
1180 struct ccb_trans_settings_spi *spi =
1181 &cts->xport_specific.spi;
1182 #ifdef SCSI_LOW_DIAGNOSTIC
1183 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1185 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1186 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1190 #endif /* SCSI_LOW_DIAGNOSTIC */
1191 cts->protocol = PROTO_SCSI;
1192 cts->protocol_version = SCSI_REV_2;
1193 cts->transport = XPORT_SPI;
1194 cts->transport_version = 2;
1196 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1197 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1199 diskflags = li->li_diskflags & li->li_cfgflags;
1200 if (diskflags & SCSI_LOW_DISK_DISC)
1201 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1202 if (diskflags & SCSI_LOW_DISK_QTAG)
1203 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1205 spi->sync_period = ti->ti_maxsynch.period;
1206 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1207 spi->sync_offset = ti->ti_maxsynch.offset;
1208 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1210 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1211 spi->bus_width = ti->ti_width;
1213 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1214 scsi->valid = CTS_SCSI_VALID_TQ;
1215 spi->valid |= CTS_SPI_VALID_DISC;
1219 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1221 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
1223 #ifdef SCSI_LOW_DIAGNOSTIC
1224 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
1226 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1227 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
1231 #endif /* SCSI_LOW_DIAGNOSTIC */
1232 diskflags = li->li_diskflags & li->li_cfgflags;
1233 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
1234 cts->flags |= CCB_TRANS_DISC_ENB;
1236 cts->flags &= ~CCB_TRANS_DISC_ENB;
1237 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
1238 cts->flags |= CCB_TRANS_TAG_ENB;
1240 cts->flags &= ~CCB_TRANS_TAG_ENB;
1242 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1244 #ifdef SCSI_LOW_DIAGNOSTIC
1245 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1247 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1248 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1252 #endif /* SCSI_LOW_DIAGNOSTIC */
1253 if ((li->li_flags & SCSI_LOW_DISC) != 0)
1254 cts->flags |= CCB_TRANS_DISC_ENB;
1256 cts->flags &= ~CCB_TRANS_DISC_ENB;
1257 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
1258 cts->flags |= CCB_TRANS_TAG_ENB;
1260 cts->flags &= ~CCB_TRANS_TAG_ENB;
1264 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1268 cts->sync_period = ti->ti_maxsynch.period;
1269 cts->sync_offset = ti->ti_maxsynch.offset;
1270 cts->bus_width = ti->ti_width;
1272 cts->valid = CCB_TRANS_SYNC_RATE_VALID
1273 | CCB_TRANS_SYNC_OFFSET_VALID
1274 | CCB_TRANS_BUS_WIDTH_VALID
1275 | CCB_TRANS_DISC_VALID
1276 | CCB_TRANS_TQ_VALID;
1277 ccb->ccb_h.status = CAM_REQ_CMP;
1285 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1286 struct ccb_calc_geometry *ccg;
1288 u_int32_t secs_per_cylinder;
1293 size_mb = ccg->volume_size
1294 / ((1024L * 1024L) / ccg->block_size);
1296 if (size_mb > 1024 && extended) {
1298 ccg->secs_per_track = 63;
1301 ccg->secs_per_track = 32;
1303 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
1304 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
1305 ccb->ccb_h.status = CAM_REQ_CMP;
1310 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1311 s = SCSI_LOW_SPLSCSI();
1312 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1314 ccb->ccb_h.status = CAM_REQ_CMP;
1318 case XPT_TERM_IO: /* Terminate the I/O process */
1319 ccb->ccb_h.status = CAM_REQ_INVALID;
1323 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1324 #ifdef SCSI_LOW_DIAGNOSTIC
1325 if (target == CAM_TARGET_WILDCARD)
1327 printf("%s: invalid target\n", slp->sl_xname);
1328 ccb->ccb_h.status = CAM_REQ_INVALID;
1332 #endif /* SCSI_LOW_DIAGNOSTIC */
1334 msg = SCSI_LOW_MSG_RESET;
1335 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1337 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1342 ti = slp->sl_ti[target];
1343 if (lun == CAM_LUN_WILDCARD)
1347 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1348 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1350 flags = CCB_NORETRY | CCB_URGENT;
1352 s = SCSI_LOW_SPLSCSI();
1353 li = scsi_low_alloc_li(ti, lun, 1);
1354 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1358 case XPT_PATH_INQ: { /* Path routing inquiry */
1359 struct ccb_pathinq *cpi = &ccb->cpi;
1361 cpi->version_num = scsi_low_version_major;
1362 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1363 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1364 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1365 cpi->hba_inquiry |= PI_WIDE_16;
1366 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1367 cpi->hba_inquiry |= PI_WIDE_32;
1368 if (ti->ti_maxsynch.offset > 0)
1369 cpi->hba_inquiry |= PI_SDTR_ABLE;
1370 cpi->target_sprt = 0;
1372 cpi->hba_eng_cnt = 0;
1373 cpi->max_target = slp->sl_ntargs - 1;
1374 cpi->max_lun = slp->sl_nluns - 1;
1375 cpi->initiator_id = slp->sl_hostid;
1376 cpi->bus_id = cam_sim_bus(sim);
1377 cpi->base_transfer_speed = 3300;
1378 #ifdef CAM_NEW_TRAN_CODE
1379 cpi->transport = XPORT_SPI;
1380 cpi->transport_version = 2;
1381 cpi->protocol = PROTO_SCSI;
1382 cpi->protocol_version = SCSI_REV_2;
1384 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1385 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1386 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1387 cpi->unit_number = cam_sim_unit(sim);
1388 cpi->ccb_h.status = CAM_REQ_CMP;
1394 printf("scsi_low: non support func_code = %d ",
1395 ccb->ccb_h.func_code);
1396 ccb->ccb_h.status = CAM_REQ_INVALID;
1403 scsi_low_attach_cam(slp)
1404 struct scsi_low_softc *slp;
1406 struct cam_devq *devq;
1407 int tagged_openings;
1409 sprintf(slp->sl_xname, "%s%d",
1410 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1412 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1417 * ask the adapter what subunits are present
1419 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1420 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1422 DEVPORT_DEVNAME(slp->sl_dev), slp,
1423 DEVPORT_DEVUNIT(slp->sl_dev),
1424 slp->sl_openings, tagged_openings, devq);
1426 if (slp->sl_si.sim == NULL) {
1427 cam_simq_free(devq);
1431 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1432 free(slp->sl_si.sim, M_DEVBUF);
1436 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1437 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1438 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1439 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1440 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1441 free(slp->sl_si.sim, M_DEVBUF);
1445 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1450 scsi_low_world_start_cam(slp)
1451 struct scsi_low_softc *slp;
1455 scsi_low_rescan_bus_cam(slp);
1460 scsi_low_dettach_cam(slp)
1461 struct scsi_low_softc *slp;
1464 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1465 xpt_free_path(slp->sl_si.path);
1466 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1467 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1472 scsi_low_ccb_setup_cam(slp, cb)
1473 struct scsi_low_softc *slp;
1476 union ccb *ccb = (union ccb *) cb->osdep;
1478 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1480 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1481 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1482 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1483 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1484 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1485 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1486 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1487 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1488 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1492 scsi_low_unit_ready_cmd(cb);
1494 return SCSI_LOW_START_QTAG;
1498 scsi_low_done_cam(slp, cb)
1499 struct scsi_low_softc *slp;
1504 ccb = (union ccb *) cb->osdep;
1505 if (cb->ccb_error == 0)
1507 ccb->ccb_h.status = CAM_REQ_CMP;
1508 ccb->csio.resid = 0;
1512 if (cb->ccb_rcnt >= slp->sl_max_retry)
1513 cb->ccb_error |= ABORTIO;
1515 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1516 (cb->ccb_error & ABORTIO) == 0)
1519 if ((cb->ccb_error & SENSEIO) != 0)
1521 memcpy(&ccb->csio.sense_data,
1523 sizeof(ccb->csio.sense_data));
1526 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1527 &scsi_low_error_code_cam[0]);
1529 #ifdef SCSI_LOW_DIAGNOSTIC
1530 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1531 cb->ccb_scp.scp_cmdlen > 0 &&
1532 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1533 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1535 printf("%s: WARNING: scsi_low IO abort\n",
1537 scsi_low_print(slp, NULL);
1539 #endif /* SCSI_LOW_DIAGNOSTIC */
1542 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1543 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1545 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1546 ccb->csio.scsi_status = 0; /* XXX */
1548 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1550 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1556 scsi_low_timeout_cam(slp, ch, action)
1557 struct scsi_low_softc *slp;
1564 case SCSI_LOW_TIMEOUT_CH_IO:
1567 case SCSI_LOW_TIMEOUT_START:
1568 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1569 hz / SCSI_LOW_TIMEOUT_HZ);
1571 case SCSI_LOW_TIMEOUT_STOP:
1572 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1577 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1580 case SCSI_LOW_TIMEOUT_START:
1581 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1583 case SCSI_LOW_TIMEOUT_STOP:
1584 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1588 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1593 #endif /* SCSI_LOW_INTERFACE_CAM */
1595 /*=============================================================
1596 * END OF OS switch (All OS depend fucntions should be above)
1597 =============================================================*/
1599 /**************************************************************
1600 * scsi low deactivate and activate
1601 **************************************************************/
1603 scsi_low_is_busy(slp)
1604 struct scsi_low_softc *slp;
1607 if (slp->sl_nio > 0)
1613 scsi_low_deactivate(slp)
1614 struct scsi_low_softc *slp;
1618 s = SCSI_LOW_SPLSCSI();
1619 slp->sl_flags |= HW_INACTIVE;
1620 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1621 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1622 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1623 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1629 scsi_low_activate(slp)
1630 struct scsi_low_softc *slp;
1634 s = SCSI_LOW_SPLSCSI();
1635 slp->sl_flags &= ~HW_INACTIVE;
1636 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1638 slp->sl_flags |= HW_INACTIVE;
1643 slp->sl_timeout_count = 0;
1644 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1645 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1650 /**************************************************************
1652 **************************************************************/
1653 #ifdef SCSI_LOW_DIAGNOSTIC
1654 static void scsi_low_msg_log_init __P((struct scsi_low_msg_log *));
1655 static void scsi_low_msg_log_write __P((struct scsi_low_msg_log *, u_int8_t *,
1657 static void scsi_low_msg_log_show __P((struct scsi_low_msg_log *, char *, int));
1660 scsi_low_msg_log_init(slmlp)
1661 struct scsi_low_msg_log *slmlp;
1664 slmlp->slml_ptr = 0;
1668 scsi_low_msg_log_write(slmlp, datap, len)
1669 struct scsi_low_msg_log *slmlp;
1675 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1678 ptr = slmlp->slml_ptr ++;
1679 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1680 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1681 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1682 slmlp->slml_msg[ptr].msg[ind] = 0;
1686 scsi_low_msg_log_show(slmlp, s, len)
1687 struct scsi_low_msg_log *slmlp;
1693 printf("%s: (%d) ", s, slmlp->slml_ptr);
1694 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1696 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1699 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1705 #endif /* SCSI_LOW_DIAGNOSTIC */
1707 /**************************************************************
1709 **************************************************************/
1711 scsi_low_engage(arg)
1714 struct scsi_low_softc *slp = arg;
1715 int s = SCSI_LOW_SPLSCSI();
1717 switch (slp->sl_rstep)
1721 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1722 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1723 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1728 slp->sl_flags &= ~HW_RESUME;
1729 scsi_low_start(slp);
1739 scsi_low_init(slp, flags)
1740 struct scsi_low_softc *slp;
1745 slp->sl_flags |= HW_INITIALIZING;
1747 /* clear power control timeout */
1748 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1750 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1751 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1752 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1754 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1757 /* reset current nexus */
1758 scsi_low_reset_nexus(slp, flags);
1759 if ((slp->sl_flags & HW_INACTIVE) != 0)
1765 if (flags != SCSI_LOW_RESTART_SOFT)
1767 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1771 slp->sl_flags &= ~HW_INITIALIZING;
1775 /**************************************************************
1777 **************************************************************/
1778 static struct lun_info *
1779 scsi_low_alloc_li(ti, lun, alloc)
1780 struct targ_info *ti;
1784 struct scsi_low_softc *slp = ti->ti_sc;
1785 struct lun_info *li;
1787 li = LIST_FIRST(&ti->ti_litab);
1790 if (li->li_lun == lun)
1793 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1795 if (li->li_lun == lun)
1797 LIST_REMOVE(li, lun_chain);
1798 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1807 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1809 panic("no lun info mem\n");
1811 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1815 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1817 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1818 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1819 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1820 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1821 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1823 li->li_qtagbits = (u_int) -1;
1825 TAILQ_INIT(&li->li_discq);
1826 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1828 /* host specific structure initialization per lun */
1829 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1830 (*slp->sl_funcs->scsi_low_lun_init)
1831 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1832 scsi_low_calcf_lun(li);
1836 /**************************************************************
1837 * allocate targ_info
1838 **************************************************************/
1839 static struct targ_info *
1840 scsi_low_alloc_ti(slp, targ)
1841 struct scsi_low_softc *slp;
1844 struct targ_info *ti;
1846 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1847 TAILQ_INIT(&slp->sl_titab);
1849 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1851 panic("%s short of memory\n", slp->sl_xname);
1853 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1857 slp->sl_ti[targ] = ti;
1858 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1859 LIST_INIT(&ti->ti_litab);
1861 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1862 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1863 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1864 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1865 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1866 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1868 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1870 (*slp->sl_funcs->scsi_low_targ_init)
1871 (slp, ti, SCSI_LOW_INFO_ALLOC);
1873 scsi_low_calcf_target(ti);
1878 scsi_low_free_ti(slp)
1879 struct scsi_low_softc *slp;
1881 struct targ_info *ti, *tib;
1882 struct lun_info *li, *nli;
1884 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1886 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1888 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1890 (*slp->sl_funcs->scsi_low_lun_init)
1891 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1893 nli = LIST_NEXT(li, lun_chain);
1897 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1899 (*slp->sl_funcs->scsi_low_targ_init)
1900 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1902 tib = TAILQ_NEXT(ti, ti_chain);
1907 /**************************************************************
1909 **************************************************************/
1911 scsi_low_bus_idle(slp)
1912 struct scsi_low_softc *slp;
1915 slp->sl_retry_sel = 0;
1916 if (slp->sl_Tnexus == NULL)
1917 scsi_low_start(slp);
1921 scsi_low_timeout(arg)
1924 struct scsi_low_softc *slp = arg;
1927 s = SCSI_LOW_SPLSCSI();
1928 (void) scsi_low_timeout_check(slp);
1929 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1930 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1935 scsi_low_timeout_check(slp)
1936 struct scsi_low_softc *slp;
1938 struct targ_info *ti;
1939 struct lun_info *li;
1940 struct slccb *cb = NULL; /* XXX */
1942 /* selection restart */
1943 if (slp->sl_retry_sel != 0)
1945 slp->sl_retry_sel = 0;
1946 if (slp->sl_Tnexus != NULL)
1949 cb = TAILQ_FIRST(&slp->sl_start);
1953 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1955 cb->ccb_flags |= CCB_NORETRY;
1956 cb->ccb_error |= SELTIMEOUTIO;
1957 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1958 panic("%s: ccb not finished\n", slp->sl_xname);
1961 if (slp->sl_Tnexus == NULL)
1962 scsi_low_start(slp);
1965 /* call hardware timeout */
1967 if (slp->sl_funcs->scsi_low_timeout != NULL)
1969 (*slp->sl_funcs->scsi_low_timeout) (slp);
1972 if (slp->sl_timeout_count ++ <
1973 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1976 slp->sl_timeout_count = 0;
1977 if (slp->sl_nio > 0)
1979 if ((cb = slp->sl_Qnexus) != NULL)
1981 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1985 else if (slp->sl_disc == 0)
1987 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1990 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1994 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1995 ti = TAILQ_NEXT(ti, ti_chain))
1997 if (ti->ti_disc == 0)
2000 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2001 li = LIST_NEXT(li, lun_chain))
2003 for (cb = TAILQ_FIRST(&li->li_discq);
2005 cb = TAILQ_NEXT(cb, ccb_chain))
2008 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
2016 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
2018 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2021 if (slp->sl_active != 0)
2023 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2029 if (slp->sl_powc < 0)
2031 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2032 slp->sl_flags |= HW_POWDOWN;
2033 (*slp->sl_funcs->scsi_low_power)
2034 (slp, SCSI_LOW_POWDOWN);
2040 cb->ccb_error |= TIMEOUTIO;
2041 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2042 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2043 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2044 scsi_low_start(slp);
2050 scsi_low_abort_ccb(slp, cb)
2051 struct scsi_low_softc *slp;
2054 struct targ_info *ti;
2055 struct lun_info *li;
2060 if ((cb->ccb_omsgoutflag &
2061 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2066 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2067 msg = SCSI_LOW_MSG_ABORT;
2069 msg = SCSI_LOW_MSG_ABORT_QTAG;
2071 cb->ccb_error |= ABORTIO;
2072 cb->ccb_flags |= CCB_NORETRY;
2073 scsi_low_ccb_message_assert(cb, msg);
2075 if (cb == slp->sl_Qnexus)
2077 scsi_low_assert_msg(slp, ti, msg, 1);
2079 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2081 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2082 panic("%s: revoked ccb done\n", slp->sl_xname);
2084 cb->ccb_flags |= CCB_STARTQ;
2085 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2087 if (slp->sl_Tnexus == NULL)
2088 scsi_low_start(slp);
2092 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2093 panic("%s: revoked ccb retried\n", slp->sl_xname);
2098 /**************************************************************
2099 * Generic SCSI INTERFACE
2100 **************************************************************/
2102 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2103 struct scsi_low_softc *slp;
2104 int openings, ntargs, nluns, targsize, lunsize;
2106 struct targ_info *ti;
2107 struct lun_info *li;
2110 #ifdef SCSI_LOW_INTERFACE_XS
2111 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2112 #endif /* SCSI_LOW_INTERFACE_XS */
2113 #ifdef SCSI_LOW_INTERFACE_CAM
2114 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2115 #endif /* SCSI_LOW_INTERFACE_CAM */
2117 if (slp->sl_osdep_fp == NULL)
2118 panic("scsi_low: interface not spcified\n");
2120 if (ntargs > SCSI_LOW_NTARGETS)
2122 printf("scsi_low: %d targets are too large\n", ntargs);
2123 printf("change kernel options SCSI_LOW_NTARGETS");
2128 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2130 slp->sl_openings = openings;
2131 slp->sl_ntargs = ntargs;
2132 slp->sl_nluns = nluns;
2133 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2135 if (lunsize < sizeof(struct lun_info))
2136 lunsize = sizeof(struct lun_info);
2138 if (targsize < sizeof(struct targ_info))
2139 targsize = sizeof(struct targ_info);
2141 slp->sl_targsize = targsize;
2142 for (i = 0; i < ntargs; i ++)
2144 ti = scsi_low_alloc_ti(slp, i);
2145 ti->ti_lunsize = lunsize;
2146 li = scsi_low_alloc_li(ti, 0, 1);
2149 /* initialize queue */
2150 nccb = openings * ntargs;
2151 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2152 nccb = SCSI_LOW_NCCB;
2153 scsi_low_init_ccbque(nccb);
2154 TAILQ_INIT(&slp->sl_start);
2156 /* call os depend attach */
2157 s = SCSI_LOW_SPLSCSI();
2158 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2162 printf("%s: scsi_low_attach: osdep attach failed\n",
2167 /* check hardware */
2168 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2169 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2172 printf("%s: scsi_low_attach: initialization failed\n",
2177 /* start watch dog */
2178 slp->sl_timeout_count = 0;
2179 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2180 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2181 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2184 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2186 #ifdef SCSI_LOW_START_UP_CHECK
2187 /* probing devices */
2188 scsi_low_start_up(slp);
2189 #endif /* SCSI_LOW_START_UP_CHECK */
2191 /* call os depend attach done*/
2192 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2198 scsi_low_dettach(slp)
2199 struct scsi_low_softc *slp;
2203 s = SCSI_LOW_SPLSCSI();
2204 if (scsi_low_is_busy(slp) != 0)
2210 scsi_low_deactivate(slp);
2212 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2219 scsi_low_free_ti(slp);
2220 LIST_REMOVE(slp, sl_chain);
2225 /**************************************************************
2227 **************************************************************/
2229 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2230 struct scsi_low_softc *slp;
2231 struct targ_info *ti;
2232 struct lun_info *li;
2240 scsi_low_ccb_message_assert(cb, msg);
2242 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2243 scsi_low_alloc_qtag(cb);
2245 cb->ccb_flags = flags | CCB_STARTQ;
2246 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2247 cb->ccb_error |= PENDINGIO;
2249 if ((flags & CCB_URGENT) != 0)
2251 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2255 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2260 if (slp->sl_Tnexus == NULL)
2261 scsi_low_start(slp);
2266 scsi_low_message_enqueue(slp, ti, li, flags)
2267 struct scsi_low_softc *slp;
2268 struct targ_info *ti;
2269 struct lun_info *li;
2275 tmsgflags = ti->ti_setup_msg;
2276 ti->ti_setup_msg = 0;
2278 flags |= CCB_NORETRY;
2279 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2284 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2288 /**************************************************************
2289 * Generic Start & Done
2290 **************************************************************/
2291 #define SLSC_MODE_SENSE_SHORT 0x1a
2292 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2293 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2294 sizeof(struct scsi_low_mode_sense_data), 0};
2295 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2296 sizeof(struct scsi_low_inq_data), 0};
2297 static u_int8_t unit_ready_cmd[6];
2298 static int scsi_low_setup_start __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *));
2299 static int scsi_low_sense_abort_start __P((struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *));
2300 static int scsi_low_resume __P((struct scsi_low_softc *));
2303 scsi_low_unit_ready_cmd(cb)
2307 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2308 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2309 cb->ccb_scp.scp_datalen = 0;
2310 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2315 scsi_low_sense_abort_start(slp, ti, li, cb)
2316 struct scsi_low_softc *slp;
2317 struct targ_info *ti;
2318 struct lun_info *li;
2322 cb->ccb_scp.scp_cmdlen = 6;
2323 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2324 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2325 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2326 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2327 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2328 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2329 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2331 scsi_low_ccb_message_clear(cb);
2332 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2334 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2338 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2339 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2340 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2341 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2344 return SCSI_LOW_START_NO_QTAG;
2348 scsi_low_setup_start(slp, ti, li, cb)
2349 struct scsi_low_softc *slp;
2350 struct targ_info *ti;
2351 struct lun_info *li;
2355 switch(li->li_state)
2357 case SCSI_LOW_LUN_SLEEP:
2358 scsi_low_unit_ready_cmd(cb);
2361 case SCSI_LOW_LUN_START:
2362 cb->ccb_scp.scp_cmd = ss_cmd;
2363 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2364 cb->ccb_scp.scp_datalen = 0;
2365 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2369 case SCSI_LOW_LUN_INQ:
2370 cb->ccb_scp.scp_cmd = inq_cmd;
2371 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2372 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2373 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2374 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2378 case SCSI_LOW_LUN_MODEQ:
2379 cb->ccb_scp.scp_cmd = sms_cmd;
2380 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2381 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2382 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2383 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2385 return SCSI_LOW_START_QTAG;
2388 panic("%s: no setup phase\n", slp->sl_xname);
2391 return SCSI_LOW_START_NO_QTAG;
2395 scsi_low_resume(slp)
2396 struct scsi_low_softc *slp;
2399 if (slp->sl_flags & HW_RESUME)
2401 slp->sl_flags &= ~HW_POWDOWN;
2402 if (slp->sl_funcs->scsi_low_power != NULL)
2404 slp->sl_flags |= HW_RESUME;
2406 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2407 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2408 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2409 SCSI_LOW_TIMEOUT_START);
2417 struct scsi_low_softc *slp;
2419 struct targ_info *ti;
2420 struct lun_info *li;
2424 /* check hardware exists or under initializations ? */
2425 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2428 /* check hardware power up ? */
2429 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2432 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2434 if (scsi_low_resume(slp) == EJUSTRETURN)
2440 #ifdef SCSI_LOW_DIAGNOSTIC
2441 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2443 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2444 panic("%s: inconsistent\n", slp->sl_xname);
2446 #endif /* SCSI_LOW_DIAGNOSTIC */
2448 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2449 cb = TAILQ_NEXT(cb, ccb_chain))
2453 if (li->li_disc == 0)
2455 goto scsi_low_cmd_start;
2457 else if (li->li_nqio > 0)
2459 if (li->li_nqio < li->li_maxnqio ||
2460 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2461 goto scsi_low_cmd_start;
2467 cb->ccb_flags &= ~CCB_STARTQ;
2468 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2471 /* clear all error flag bits (for restart) */
2473 cb->ccb_datalen = -1;
2474 cb->ccb_scp.scp_status = ST_UNKNOWN;
2476 /* setup nexus pointer */
2477 slp->sl_Qnexus = cb;
2478 slp->sl_Lnexus = li;
2479 slp->sl_Tnexus = ti;
2481 /* initialize msgsys */
2482 scsi_low_init_msgsys(slp, ti);
2485 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2487 /* CA state or forced abort */
2488 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2490 else if (li->li_state >= SCSI_LOW_LUN_OK)
2492 cb->ccb_flags &= ~CCB_INTERNAL;
2493 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2494 if (cb->ccb_msgoutflag != 0)
2496 scsi_low_ccb_message_exec(slp, cb);
2501 cb->ccb_flags |= CCB_INTERNAL;
2502 rv = scsi_low_setup_start(slp, ti, li, cb);
2506 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2508 if (rv == SCSI_LOW_START_QTAG &&
2509 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2514 scsi_low_activate_qtag(cb);
2515 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2516 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2517 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2518 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2519 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2521 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2522 scsi_low_assert_msg(slp, ti, qmsg, 0);
2526 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2527 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2528 cb->ccb_tc = cb->ccb_tcmax;
2530 /* setup saved scsi data pointer */
2531 cb->ccb_sscp = cb->ccb_scp;
2533 /* setup current scsi pointer */
2534 slp->sl_scp = cb->ccb_sscp;
2535 slp->sl_error = cb->ccb_error;
2537 /* assert always an identify msg */
2538 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2541 #ifdef SCSI_LOW_DIAGNOSTIC
2542 scsi_low_msg_log_init(&ti->ti_log_msgin);
2543 scsi_low_msg_log_init(&ti->ti_log_msgout);
2544 #endif /* SCSI_LOW_DIAGNOSTIC */
2546 /* selection start */
2548 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2549 if (rv == SCSI_LOW_START_OK)
2551 #ifdef SCSI_LOW_STATICS
2552 scsi_low_statics.nexus_win ++;
2553 #endif /* SCSI_LOW_STATICS */
2557 scsi_low_arbit_fail(slp, cb);
2558 #ifdef SCSI_LOW_STATICS
2559 scsi_low_statics.nexus_fail ++;
2560 #endif /* SCSI_LOW_STATICS */
2564 scsi_low_arbit_fail(slp, cb)
2565 struct scsi_low_softc *slp;
2568 struct targ_info *ti = cb->ti;
2570 scsi_low_deactivate_qtag(cb);
2571 scsi_low_ccb_message_retry(cb);
2572 cb->ccb_flags |= CCB_STARTQ;
2573 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2575 scsi_low_bus_release(slp, ti);
2578 if (slp->sl_disc == 0)
2580 #ifdef SCSI_LOW_DIAGNOSTIC
2581 printf("%s: try selection again\n", slp->sl_xname);
2582 #endif /* SCSI_LOW_DIAGNOSTIC */
2583 slp->sl_retry_sel = 1;
2588 scsi_low_bus_release(slp, ti)
2589 struct scsi_low_softc *slp;
2590 struct targ_info *ti;
2593 if (ti->ti_disc > 0)
2595 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2599 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2602 /* clear all nexus pointer */
2603 slp->sl_Qnexus = NULL;
2604 slp->sl_Lnexus = NULL;
2605 slp->sl_Tnexus = NULL;
2607 /* clear selection assert */
2608 slp->sl_selid = NULL;
2610 /* clear nexus data */
2611 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2613 /* clear phase change counter */
2614 slp->sl_ph_count = 0;
2618 scsi_low_setup_done(slp, cb)
2619 struct scsi_low_softc *slp;
2622 struct targ_info *ti;
2623 struct lun_info *li;
2628 if (cb->ccb_rcnt >= slp->sl_max_retry)
2630 cb->ccb_error |= ABORTIO;
2631 return SCSI_LOW_DONE_COMPLETE;
2634 /* XXX: special huck for selection timeout */
2635 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2636 (cb->ccb_error & SELTIMEOUTIO) != 0)
2638 cb->ccb_error |= ABORTIO;
2639 return SCSI_LOW_DONE_COMPLETE;
2642 switch(li->li_state)
2644 case SCSI_LOW_LUN_INQ:
2645 if (cb->ccb_error != 0)
2648 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2652 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2654 else if ((li->li_inq.sd_version & 7) >= 2 ||
2655 (li->li_inq.sd_len >= 4))
2657 if ((li->li_inq.sd_support & 0x2) == 0)
2658 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2659 if ((li->li_inq.sd_support & 0x8) == 0)
2660 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2663 if ((li->li_inq.sd_support & 0x10) == 0)
2664 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2665 if ((li->li_inq.sd_support & 0x20) == 0)
2666 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2667 if ((li->li_inq.sd_support & 0x40) == 0)
2668 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2673 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2676 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2678 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2680 scsi_low_calcf_target(ti);
2681 scsi_low_calcf_lun(li);
2684 case SCSI_LOW_LUN_MODEQ:
2685 if (cb->ccb_error != 0)
2687 if (cb->ccb_error & SENSEIO)
2689 #ifdef SCSI_LOW_DEBUG
2690 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2692 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2693 (u_int) cb->ccb_sense.error_code,
2694 (u_int) cb->ccb_sense.segment,
2695 (u_int) cb->ccb_sense.flags,
2696 (u_int) cb->ccb_sense.add_sense_code,
2697 (u_int) cb->ccb_sense.add_sense_code_qual);
2699 #endif /* SCSI_LOW_DEBUG */
2703 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2706 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2708 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2709 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2711 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2712 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2713 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2715 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2716 scsi_low_calcf_lun(li);
2724 if (li->li_state == SCSI_LOW_LUN_OK)
2726 scsi_low_calcf_target(ti);
2727 scsi_low_calcf_lun(li);
2728 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2729 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2731 scsi_low_calcf_show(li);
2736 return SCSI_LOW_DONE_RETRY;
2740 scsi_low_done(slp, cb)
2741 struct scsi_low_softc *slp;
2746 if (cb->ccb_error == 0)
2748 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2750 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2752 * SCSI-2 draft suggests
2753 * page 0x0a QErr bit determins if
2754 * the target aborts or continues
2755 * the queueing io's after CA state resolved.
2756 * However many targets seem not to support
2757 * the page 0x0a. Thus we should manually clear the
2758 * queuing io's after CA state.
2760 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2763 cb->ccb_flags |= CCB_CLEARQ;
2766 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2768 if ((cb->ccb_flags & CCB_SENSE) != 0)
2769 cb->ccb_error |= (SENSEIO | ABORTIO);
2770 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2772 else switch (cb->ccb_sscp.scp_status)
2778 if (cb->ccb_datalen == 0 ||
2779 cb->ccb_scp.scp_datalen == 0)
2782 if (cb->ccb_scp.scp_cmdlen > 0 &&
2783 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2784 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2787 cb->ccb_error |= PDMAERR;
2792 cb->ccb_error |= (BUSYERR | STATERR);
2796 cb->ccb_error |= (STATERR | ABORTIO);
2801 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2804 cb->ccb_flags |= CCB_SENSE;
2807 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2812 cb->ccb_error |= FATALIO;
2818 if (cb->ccb_flags & CCB_SENSE)
2820 cb->ccb_error |= (SENSEERR | ABORTIO);
2822 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2826 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2828 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2832 /* check a ccb msgout flag */
2833 if (cb->ccb_omsgoutflag != 0)
2835 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2836 SCSI_LOW_MSG_ABORT_QTAG | \
2837 SCSI_LOW_MSG_CLEAR_QTAG | \
2838 SCSI_LOW_MSG_TERMIO)
2840 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2842 cb->ccb_error |= ABORTIO;
2846 /* call OS depend done */
2847 if (cb->osdep != NULL)
2849 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2850 if (rv == EJUSTRETURN)
2853 else if (cb->ccb_error != 0)
2855 if (cb->ccb_rcnt >= slp->sl_max_retry)
2856 cb->ccb_error |= ABORTIO;
2858 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2859 (cb->ccb_error & ABORTIO) == 0)
2863 /* free our target */
2864 #ifdef SCSI_LOW_DEBUG
2865 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2867 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2868 scsi_low_print(slp, NULL);
2870 #endif /* SCSI_LOW_DEBUG */
2872 scsi_low_deactivate_qtag(cb);
2873 scsi_low_dealloc_qtag(cb);
2874 scsi_low_free_ccb(cb);
2876 return SCSI_LOW_DONE_COMPLETE;
2879 #ifdef SCSI_LOW_DEBUG
2880 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2882 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2883 scsi_low_print(slp, NULL);
2885 #endif /* SCSI_LOW_DEBUG */
2888 scsi_low_deactivate_qtag(cb);
2889 scsi_low_ccb_message_retry(cb);
2890 return SCSI_LOW_DONE_RETRY;
2893 /**************************************************************
2895 **************************************************************/
2897 scsi_low_reset_nexus_target(slp, ti, fdone)
2898 struct scsi_low_softc *slp;
2899 struct targ_info *ti;
2902 struct lun_info *li;
2904 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2905 li = LIST_NEXT(li, lun_chain))
2907 scsi_low_reset_nexus_lun(slp, li, fdone);
2908 li->li_state = SCSI_LOW_LUN_SLEEP;
2913 ti->ti_setup_msg = 0;
2914 ti->ti_setup_msg_done = 0;
2916 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2917 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2919 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2920 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2922 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2924 ((*slp->sl_funcs->scsi_low_targ_init)
2925 (slp, ti, SCSI_LOW_INFO_REVOKE));
2927 scsi_low_calcf_target(ti);
2929 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2930 li = LIST_NEXT(li, lun_chain))
2934 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2935 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2937 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2939 ((*slp->sl_funcs->scsi_low_lun_init)
2940 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2942 scsi_low_calcf_lun(li);
2947 scsi_low_reset_nexus(slp, fdone)
2948 struct scsi_low_softc *slp;
2951 struct targ_info *ti;
2952 struct slccb *cb, *topcb;
2954 if ((cb = slp->sl_Qnexus) != NULL)
2956 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2963 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2964 ti = TAILQ_NEXT(ti, ti_chain))
2966 scsi_low_reset_nexus_target(slp, ti, fdone);
2967 scsi_low_bus_release(slp, ti);
2968 scsi_low_init_msgsys(slp, ti);
2973 topcb->ccb_flags |= CCB_STARTQ;
2974 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2978 slp->sl_retry_sel = 0;
2979 slp->sl_flags &= ~HW_PDMASTART;
2984 static char tw_chars[] = "|/-\\";
2985 #define TWIDDLEWAIT 10000
2988 scsi_low_twiddle_wait(void)
2992 cnputc(tw_chars[tw_pos++]);
2993 tw_pos %= (sizeof(tw_chars) - 1);
2994 SCSI_LOW_DELAY(TWIDDLEWAIT);
2998 scsi_low_bus_reset(slp)
2999 struct scsi_low_softc *slp;
3003 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
3005 printf("%s: try to reset scsi bus ", slp->sl_xname);
3006 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
3007 scsi_low_twiddle_wait();
3013 scsi_low_restart(slp, flags, s)
3014 struct scsi_low_softc *slp;
3021 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3023 if ((error = scsi_low_init(slp, flags)) != 0)
3026 scsi_low_start(slp);
3030 /**************************************************************
3031 * disconnect and reselect
3032 **************************************************************/
3033 #define MSGCMD_LUN(msg) (msg & 0x07)
3035 static struct slccb *
3036 scsi_low_establish_ccb(ti, li, tag)
3037 struct targ_info *ti;
3038 struct lun_info *li;
3041 struct scsi_low_softc *slp = ti->ti_sc;
3047 cb = TAILQ_FIRST(&li->li_discq);
3048 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3049 if (cb->ccb_tag == tag)
3054 * establish our ccb nexus
3057 #ifdef SCSI_LOW_DEBUG
3058 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3060 printf("%s: nexus(0x%lx) abort check start\n",
3061 slp->sl_xname, (u_long) cb);
3062 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3063 scsi_low_revoke_ccb(slp, cb, 1);
3067 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3069 if (cb->ccb_omsgoutflag == 0)
3070 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3072 #endif /* SCSI_LOW_DEBUG */
3074 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3075 cb->ccb_flags &= ~CCB_DISCQ;
3076 slp->sl_Qnexus = cb;
3078 slp->sl_scp = cb->ccb_sscp;
3079 slp->sl_error |= cb->ccb_error;
3085 /* inform "ccb nexus established" to the host driver */
3086 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3089 if (cb->ccb_msgoutflag != 0)
3091 scsi_low_ccb_message_exec(slp, cb);
3098 scsi_low_reselected(slp, targ)
3099 struct scsi_low_softc *slp;
3102 struct targ_info *ti;
3107 * Check select vs reselected collision.
3110 if ((cb = slp->sl_selid) != NULL)
3112 scsi_low_arbit_fail(slp, cb);
3113 #ifdef SCSI_LOW_STATICS
3114 scsi_low_statics.nexus_conflict ++;
3115 #endif /* SCSI_LOW_STATICS */
3119 * Check if no current active nexus.
3121 if (slp->sl_Tnexus != NULL)
3128 * Check a valid target id asserted ?
3130 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3132 s = "scsi id illegal";
3137 * Check the target scsi status.
3139 ti = slp->sl_ti[targ];
3140 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3142 s = "phase mismatch";
3150 scsi_low_init_msgsys(slp, ti);
3153 * Establish our target nexus
3155 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3156 slp->sl_Tnexus = ti;
3157 #ifdef SCSI_LOW_STATICS
3158 scsi_low_statics.nexus_reselected ++;
3159 #endif /* SCSI_LOW_STATICS */
3163 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3164 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3165 "reselect: scsi world confused");
3169 /**************************************************************
3170 * cmd out pointer setup
3171 **************************************************************/
3173 scsi_low_cmd(slp, ti)
3174 struct scsi_low_softc *slp;
3175 struct targ_info *ti;
3177 struct slccb *cb = slp->sl_Qnexus;
3179 slp->sl_ph_count ++;
3185 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3186 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3187 slp->sl_scp.scp_datalen = 0;
3188 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3189 slp->sl_error |= FATALIO;
3190 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3191 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3196 #ifdef SCSI_LOW_DEBUG
3197 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3199 scsi_low_test_cmdlnk(slp, cb);
3201 #endif /* SCSI_LOW_DEBUG */
3206 /**************************************************************
3207 * data out pointer setup
3208 **************************************************************/
3210 scsi_low_data(slp, ti, bp, direction)
3211 struct scsi_low_softc *slp;
3212 struct targ_info *ti;
3216 struct slccb *cb = slp->sl_Qnexus;
3218 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3224 slp->sl_error |= (FATALIO | PDMAERR);
3225 slp->sl_scp.scp_datalen = 0;
3226 slp->sl_scp.scp_direction = direction;
3227 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3228 if (ti->ti_ophase != ti->ti_phase)
3233 s = "DATA PHASE: ccb nexus not found";
3235 s = "DATA PHASE: xfer direction mismatch";
3236 SCSI_LOW_INFO(slp, ti, s);
3243 /**************************************************************
3245 **************************************************************/
3246 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3247 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3248 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3249 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3250 #define MSGIN_DATA_LAST 0x30
3252 static int scsi_low_errfunc_synch __P((struct scsi_low_softc *, u_int));
3253 static int scsi_low_errfunc_wide __P((struct scsi_low_softc *, u_int));
3254 static int scsi_low_errfunc_identify __P((struct scsi_low_softc *, u_int));
3255 static int scsi_low_errfunc_qtag __P((struct scsi_low_softc *, u_int));
3257 static int scsi_low_msgfunc_synch __P((struct scsi_low_softc *));
3258 static int scsi_low_msgfunc_wide __P((struct scsi_low_softc *));
3259 static int scsi_low_msgfunc_identify __P((struct scsi_low_softc *));
3260 static int scsi_low_msgfunc_abort __P((struct scsi_low_softc *));
3261 static int scsi_low_msgfunc_qabort __P((struct scsi_low_softc *));
3262 static int scsi_low_msgfunc_qtag __P((struct scsi_low_softc *));
3263 static int scsi_low_msgfunc_reset __P((struct scsi_low_softc *));
3265 struct scsi_low_msgout_data {
3268 int (*md_msgfunc) __P((struct scsi_low_softc *));
3269 int (*md_errfunc) __P((struct scsi_low_softc *, u_int));
3270 #define MSG_RELEASE_ATN 0x0001
3274 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3275 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3276 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3277 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3278 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3279 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3280 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3281 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3282 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3283 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3284 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3285 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3286 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3287 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3288 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3289 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3290 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3293 static int scsi_low_msginfunc_ext __P((struct scsi_low_softc *));
3294 static int scsi_low_synch __P((struct scsi_low_softc *));
3295 static int scsi_low_wide __P((struct scsi_low_softc *));
3296 static int scsi_low_msginfunc_msg_reject __P((struct scsi_low_softc *));
3297 static int scsi_low_msginfunc_rejop __P((struct scsi_low_softc *));
3298 static int scsi_low_msginfunc_rp __P((struct scsi_low_softc *));
3299 static int scsi_low_msginfunc_sdp __P((struct scsi_low_softc *));
3300 static int scsi_low_msginfunc_disc __P((struct scsi_low_softc *));
3301 static int scsi_low_msginfunc_cc __P((struct scsi_low_softc *));
3302 static int scsi_low_msginfunc_lcc __P((struct scsi_low_softc *));
3303 static int scsi_low_msginfunc_parity __P((struct scsi_low_softc *));
3304 static int scsi_low_msginfunc_noop __P((struct scsi_low_softc *));
3305 static int scsi_low_msginfunc_simple_qtag __P((struct scsi_low_softc *));
3306 static int scsi_low_msginfunc_i_wide_residue __P((struct scsi_low_softc *));
3308 struct scsi_low_msgin_data {
3310 int (*md_msgfunc) __P((struct scsi_low_softc *));
3313 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3314 /* 0 */ {1, scsi_low_msginfunc_cc},
3315 /* 1 */ {2, scsi_low_msginfunc_ext},
3316 /* 2 */ {1, scsi_low_msginfunc_sdp},
3317 /* 3 */ {1, scsi_low_msginfunc_rp},
3318 /* 4 */ {1, scsi_low_msginfunc_disc},
3319 /* 5 */ {1, scsi_low_msginfunc_rejop},
3320 /* 6 */ {1, scsi_low_msginfunc_rejop},
3321 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
3322 /* 8 */ {1, scsi_low_msginfunc_noop},
3323 /* 9 */ {1, scsi_low_msginfunc_parity},
3324 /* a */ {1, scsi_low_msginfunc_lcc},
3325 /* b */ {1, scsi_low_msginfunc_lcc},
3326 /* c */ {1, scsi_low_msginfunc_rejop},
3327 /* d */ {2, scsi_low_msginfunc_rejop},
3328 /* e */ {1, scsi_low_msginfunc_rejop},
3329 /* f */ {1, scsi_low_msginfunc_rejop},
3330 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
3331 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
3332 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
3333 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
3334 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
3335 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
3336 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
3337 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
3338 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
3339 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
3340 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
3341 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
3342 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
3343 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
3344 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
3345 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
3346 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3347 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
3348 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
3349 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3350 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
3351 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
3352 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
3353 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
3354 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
3355 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
3356 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
3357 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
3358 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
3359 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
3360 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
3361 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
3362 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3365 /**************************************************************
3367 **************************************************************/
3369 scsi_low_msgfunc_synch(slp)
3370 struct scsi_low_softc *slp;
3372 struct targ_info *ti = slp->sl_Tnexus;
3373 int ptr = ti->ti_msgoutlen;
3375 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3376 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3377 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3378 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3379 return MSG_EXTEND_SYNCHLEN + 2;
3383 scsi_low_msgfunc_wide(slp)
3384 struct scsi_low_softc *slp;
3386 struct targ_info *ti = slp->sl_Tnexus;
3387 int ptr = ti->ti_msgoutlen;
3389 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3390 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3391 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3392 return MSG_EXTEND_WIDELEN + 2;
3396 scsi_low_msgfunc_identify(slp)
3397 struct scsi_low_softc *slp;
3399 struct targ_info *ti = slp->sl_Tnexus;
3400 struct lun_info *li = slp->sl_Lnexus;
3401 struct slccb *cb = slp->sl_Qnexus;
3402 int ptr = ti->ti_msgoutlen;
3408 slp->sl_error |= FATALIO;
3409 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3410 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3414 if (scsi_low_is_disconnect_ok(cb) != 0)
3415 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3419 if (ti->ti_phase == PH_MSGOUT)
3421 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3422 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3424 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3428 ti->ti_msgoutstr[ptr + 0] = msg;
3433 scsi_low_msgfunc_abort(slp)
3434 struct scsi_low_softc *slp;
3437 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3442 scsi_low_msgfunc_qabort(slp)
3443 struct scsi_low_softc *slp;
3446 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3451 scsi_low_msgfunc_reset(slp)
3452 struct scsi_low_softc *slp;
3455 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3460 scsi_low_msgfunc_qtag(slp)
3461 struct scsi_low_softc *slp;
3463 struct targ_info *ti = slp->sl_Tnexus;
3464 struct slccb *cb = slp->sl_Qnexus;
3465 int ptr = ti->ti_msgoutlen;
3467 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3469 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3474 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3475 if (ti->ti_phase == PH_MSGOUT)
3477 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3484 * The following functions are called when targets give unexpected
3485 * responces in msgin (after msgout).
3488 scsi_low_errfunc_identify(slp, msgflags)
3489 struct scsi_low_softc *slp;
3493 if (slp->sl_Lnexus != NULL)
3495 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3496 scsi_low_calcf_lun(slp->sl_Lnexus);
3502 scsi_low_errfunc_synch(slp, msgflags)
3503 struct scsi_low_softc *slp;
3506 struct targ_info *ti = slp->sl_Tnexus;
3508 MSGIN_PERIOD(ti) = 0;
3509 MSGIN_OFFSET(ti) = 0;
3510 scsi_low_synch(slp);
3515 scsi_low_errfunc_wide(slp, msgflags)
3516 struct scsi_low_softc *slp;
3519 struct targ_info *ti = slp->sl_Tnexus;
3521 MSGIN_WIDTHP(ti) = 0;
3527 scsi_low_errfunc_qtag(slp, msgflags)
3528 struct scsi_low_softc *slp;
3532 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3534 if (slp->sl_Qnexus != NULL)
3536 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3538 if (slp->sl_Lnexus != NULL)
3540 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3541 scsi_low_calcf_lun(slp->sl_Lnexus);
3543 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3550 scsi_low_msgout(slp, ti, fl)
3551 struct scsi_low_softc *slp;
3552 struct targ_info *ti;
3555 struct scsi_low_msgout_data *mdp;
3558 #ifdef SCSI_LOW_DIAGNOSTIC
3559 if (ti != slp->sl_Tnexus)
3561 scsi_low_print(slp, NULL);
3562 panic("scsi_low_msgout: Target nexus inconsistent");
3564 #endif /* SCSI_LOW_DIAGNOSTIC */
3566 slp->sl_ph_count ++;
3567 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3569 printf("%s: too many phase changes\n", slp->sl_xname);
3570 slp->sl_error |= FATALIO;
3571 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3575 * Scsi phase changes.
3576 * Previously msgs asserted are accepted by our target or
3577 * processed by scsi_low_msgin.
3578 * Thus clear all saved informations.
3580 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3582 ti->ti_omsgflags = 0;
3583 ti->ti_emsgflags = 0;
3585 else if (slp->sl_atten == 0)
3588 * We did not assert attention, however still our target required
3589 * msgs. Resend previous msgs.
3591 ti->ti_msgflags |= ti->ti_omsgflags;
3592 ti->ti_omsgflags = 0;
3593 #ifdef SCSI_LOW_DIAGNOSTIC
3594 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3595 #endif /* SCSI_LOW_DIAGNOSTIC */
3599 * We have no msgs. send MSG_NOOP (OK?)
3601 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3602 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3607 ti->ti_msgoutlen = 0;
3608 slp->sl_clear_atten = 0;
3609 mdp = &scsi_low_msgout_data[0];
3610 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3612 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3614 ti->ti_omsgflags |= mdp->md_flags;
3615 ti->ti_msgflags &= ~mdp->md_flags;
3616 ti->ti_emsgflags = mdp->md_flags;
3618 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3619 if (mdp->md_msgfunc != NULL)
3620 len = (*mdp->md_msgfunc) (slp);
3624 #ifdef SCSI_LOW_DIAGNOSTIC
3625 scsi_low_msg_log_write(&ti->ti_log_msgout,
3626 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3627 #endif /* SCSI_LOW_DIAGNOSTIC */
3629 ti->ti_msgoutlen += len;
3630 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3632 slp->sl_clear_atten = 1;
3636 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3637 ti->ti_msgflags == 0)
3640 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3645 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3646 slp->sl_clear_atten = 1;
3648 return ti->ti_msgoutlen;
3651 /**************************************************************
3653 **************************************************************/
3655 scsi_low_msginfunc_noop(slp)
3656 struct scsi_low_softc *slp;
3663 scsi_low_msginfunc_rejop(slp)
3664 struct scsi_low_softc *slp;
3666 struct targ_info *ti = slp->sl_Tnexus;
3667 u_int8_t msg = ti->ti_msgin[0];
3669 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3670 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3675 scsi_low_msginfunc_cc(slp)
3676 struct scsi_low_softc *slp;
3678 struct lun_info *li;
3680 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3682 /* validate status */
3683 if (slp->sl_Qnexus == NULL)
3686 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3687 li = slp->sl_Lnexus;
3688 switch (slp->sl_scp.scp_status)
3691 li->li_maxnqio = li->li_maxnexus;
3696 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3697 scsi_low_reset_nexus_lun(slp, li, 0);
3705 if (li->li_maxnexus >= li->li_nqio)
3706 li->li_maxnexus = li->li_nqio - 1;
3707 li->li_maxnqio = li->li_maxnexus;
3712 slp->sl_error |= MSGERR;
3722 scsi_low_msginfunc_lcc(slp)
3723 struct scsi_low_softc *slp;
3725 struct targ_info *ti;
3726 struct lun_info *li;
3727 struct slccb *ncb, *cb;
3729 ti = slp->sl_Tnexus;
3730 li = slp->sl_Lnexus;
3731 if ((cb = slp->sl_Qnexus) == NULL)
3734 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3735 switch (slp->sl_scp.scp_status)
3739 li->li_maxnqio = li->li_maxnexus;
3743 slp->sl_error |= MSGERR;
3747 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3750 cb->ccb_error |= slp->sl_error;
3751 if (cb->ccb_error != 0)
3754 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3755 ncb = TAILQ_NEXT(ncb, ccb_chain))
3758 goto cmd_link_start;
3763 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3764 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3768 ncb->ccb_flags &= ~CCB_STARTQ;
3769 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3771 scsi_low_dealloc_qtag(ncb);
3772 ncb->ccb_tag = cb->ccb_tag;
3773 ncb->ccb_otag = cb->ccb_otag;
3774 cb->ccb_tag = SCSI_LOW_UNKTAG;
3775 cb->ccb_otag = SCSI_LOW_UNKTAG;
3776 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3777 panic("%s: linked ccb retried\n", slp->sl_xname);
3779 slp->sl_Qnexus = ncb;
3780 slp->sl_ph_count = 0;
3783 ncb->ccb_datalen = -1;
3784 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3785 ncb->ccb_flags &= ~CCB_INTERNAL;
3787 scsi_low_init_msgsys(slp, ti);
3789 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3791 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3792 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3793 ncb->ccb_tc = ncb->ccb_tcmax;
3795 /* setup saved scsi data pointer */
3796 ncb->ccb_sscp = ncb->ccb_scp;
3797 slp->sl_scp = ncb->ccb_sscp;
3798 slp->sl_error = ncb->ccb_error;
3800 #ifdef SCSI_LOW_DIAGNOSTIC
3801 scsi_low_msg_log_init(&ti->ti_log_msgin);
3802 scsi_low_msg_log_init(&ti->ti_log_msgout);
3803 #endif /* SCSI_LOW_DIAGNOSTIC */
3808 scsi_low_msginfunc_disc(slp)
3809 struct scsi_low_softc *slp;
3812 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3817 scsi_low_msginfunc_sdp(slp)
3818 struct scsi_low_softc *slp;
3820 struct slccb *cb = slp->sl_Qnexus;
3824 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3825 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3828 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3833 scsi_low_msginfunc_rp(slp)
3834 struct scsi_low_softc *slp;
3837 if (slp->sl_Qnexus != NULL)
3838 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3840 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3846 struct scsi_low_softc *slp;
3848 struct targ_info *ti = slp->sl_Tnexus;
3849 u_int period = 0, offset = 0, speed;
3853 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3854 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3855 MSGIN_OFFSET(ti) == 0)
3857 if ((offset = MSGIN_OFFSET(ti)) != 0)
3858 period = MSGIN_PERIOD(ti);
3859 s = offset ? "synchronous" : "async";
3864 * Target seems to be brain damaged.
3865 * Force async transfer.
3867 ti->ti_maxsynch.period = 0;
3868 ti->ti_maxsynch.offset = 0;
3869 printf("%s: target brain damaged. async transfer\n",
3874 ti->ti_maxsynch.period = period;
3875 ti->ti_maxsynch.offset = offset;
3877 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3881 * Current period and offset are not acceptable
3883 * The adapter changes max synch and max offset.
3885 printf("%s: synch neg failed. retry synch msg neg ...\n",
3890 ti->ti_osynch = ti->ti_maxsynch;
3893 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3897 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3899 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3900 struct slccb *cb = slp->sl_Qnexus;
3902 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3904 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3906 printf("%s(%d:*): <%s> offset %d period %dns ",
3907 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3911 speed = 1000 * 10 / (period * 4);
3912 printf("%d.%d M/s", speed / 10, speed % 10);
3921 struct scsi_low_softc *slp;
3923 struct targ_info *ti = slp->sl_Tnexus;
3926 ti->ti_width = MSGIN_WIDTHP(ti);
3927 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3931 * Current width is not acceptable for our adapter.
3932 * The adapter changes max width.
3934 printf("%s: wide neg failed. retry wide msg neg ...\n",
3939 ti->ti_owidth = ti->ti_width;
3940 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3942 ti->ti_setup_msg_done |=
3943 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3947 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3949 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3950 struct slccb *cb = slp->sl_Qnexus;
3952 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3954 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3956 printf("%s(%d:*): transfer width %d bits\n",
3957 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3963 scsi_low_msginfunc_simple_qtag(slp)
3964 struct scsi_low_softc *slp;
3966 struct targ_info *ti = slp->sl_Tnexus;
3967 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3969 if (slp->sl_Qnexus != NULL)
3971 if (slp->sl_Qnexus->ccb_tag != etag)
3973 slp->sl_error |= FATALIO;
3974 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3975 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3978 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3980 #ifdef SCSI_LOW_DEBUG
3981 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3983 #endif /* SCSI_LOW_DEBUG */
3985 slp->sl_error |= FATALIO;
3986 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3987 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3993 scsi_low_msginfunc_i_wide_residue(slp)
3994 struct scsi_low_softc *slp;
3996 struct targ_info *ti = slp->sl_Tnexus;
3997 struct slccb *cb = slp->sl_Qnexus;
3998 int res = (int) ti->ti_msgin[1];
4000 if (cb == NULL || res <= 0 ||
4001 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
4002 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
4005 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
4008 slp->sl_scp.scp_datalen += res;
4009 slp->sl_scp.scp_data -= res;
4010 scsi_low_data_finish(slp);
4015 scsi_low_msginfunc_ext(slp)
4016 struct scsi_low_softc *slp;
4018 struct slccb *cb = slp->sl_Qnexus;
4019 struct lun_info *li = slp->sl_Lnexus;
4020 struct targ_info *ti = slp->sl_Tnexus;
4024 if (ti->ti_msginptr == 2)
4026 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4030 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4032 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4036 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4037 count = (int) htonl((long) (*ptr));
4038 if(slp->sl_scp.scp_datalen - count < 0 ||
4039 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4042 slp->sl_scp.scp_datalen -= count;
4043 slp->sl_scp.scp_data += count;
4046 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4050 retry = scsi_low_synch(slp);
4051 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4052 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4054 #ifdef SCSI_LOW_DEBUG
4055 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4057 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4059 #endif /* SCSI_LOW_DEBUG */
4062 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4066 retry = scsi_low_wide(slp);
4067 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4068 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4076 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4081 scsi_low_msginfunc_parity(slp)
4082 struct scsi_low_softc *slp;
4084 struct targ_info *ti = slp->sl_Tnexus;
4086 /* only I -> T, invalid! */
4087 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4092 scsi_low_msginfunc_msg_reject(slp)
4093 struct scsi_low_softc *slp;
4095 struct targ_info *ti = slp->sl_Tnexus;
4096 struct scsi_low_msgout_data *mdp;
4099 if (ti->ti_emsgflags != 0)
4101 printf("%s: msg flags [0x%x] rejected\n",
4102 slp->sl_xname, ti->ti_emsgflags);
4103 msgflags = SCSI_LOW_MSG_REJECT;
4104 mdp = &scsi_low_msgout_data[0];
4105 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4107 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4109 ti->ti_emsgflags &= ~mdp->md_flags;
4110 if (mdp->md_errfunc != NULL)
4111 (*mdp->md_errfunc) (slp, msgflags);
4119 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4120 slp->sl_error |= MSGERR;
4126 scsi_low_msgin(slp, ti, c)
4127 struct scsi_low_softc *slp;
4128 struct targ_info *ti;
4131 struct scsi_low_msgin_data *sdp;
4132 struct lun_info *li;
4135 #ifdef SCSI_LOW_DIAGNOSTIC
4136 if (ti != slp->sl_Tnexus)
4138 scsi_low_print(slp, NULL);
4139 panic("scsi_low_msgin: Target nexus inconsistent");
4141 #endif /* SCSI_LOW_DIAGNOSTIC */
4144 * Phase changes, clear the pointer.
4146 if (ti->ti_ophase != ti->ti_phase)
4149 ti->ti_msgin_parity_error = 0;
4151 slp->sl_ph_count ++;
4152 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4154 printf("%s: too many phase changes\n", slp->sl_xname);
4155 slp->sl_error |= FATALIO;
4156 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4161 * Store a current messages byte into buffer and
4162 * wait for the completion of the current msg.
4164 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4165 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4167 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4168 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4172 * Check parity errors.
4174 if ((c & SCSI_LOW_DATA_PE) != 0)
4176 ti->ti_msgin_parity_error ++;
4177 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4181 if (ti->ti_msgin_parity_error != 0)
4185 * Calculate messages length.
4187 msg = ti->ti_msgin[0];
4188 if (msg < MSGIN_DATA_LAST)
4189 sdp = &scsi_low_msgin_data[msg];
4191 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4193 if (ti->ti_msginlen == 0)
4195 ti->ti_msginlen = sdp->md_len;
4201 if (ti->ti_msginptr < ti->ti_msginlen)
4207 if ((msg & MSG_IDENTIFY) == 0)
4209 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4214 li = slp->sl_Lnexus;
4217 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4220 slp->sl_Lnexus = li;
4221 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4225 if (MSGCMD_LUN(msg) != li->li_lun)
4229 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4231 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4233 #ifdef SCSI_LOW_DEBUG
4234 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4238 #endif /* SCSI_LOW_DEBUG */
4246 * Msg process completed, reset msgin pointer and assert ATN if desired.
4249 slp->sl_error |= FATALIO;
4250 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4251 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4254 if (ti->ti_msginptr < ti->ti_msginlen)
4257 #ifdef SCSI_LOW_DIAGNOSTIC
4258 scsi_low_msg_log_write(&ti->ti_log_msgin,
4259 &ti->ti_msgin[0], ti->ti_msginlen);
4260 #endif /* SCSI_LOW_DIAGNOSTIC */
4266 /**********************************************************
4268 **********************************************************/
4270 scsi_low_disconnected(slp, ti)
4271 struct scsi_low_softc *slp;
4272 struct targ_info *ti;
4274 struct slccb *cb = slp->sl_Qnexus;
4276 /* check phase completion */
4277 switch (slp->sl_msgphase)
4280 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4281 scsi_low_msginfunc_cc(slp);
4282 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4286 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4287 scsi_low_msginfunc_cc(slp);
4288 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4292 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4293 scsi_low_msginfunc_cc(slp);
4299 struct lun_info *li;
4302 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4303 cb->ccb_flags |= CCB_DISCQ;
4304 cb->ccb_error |= slp->sl_error;
4310 #ifdef SCSI_LOW_STATICS
4311 scsi_low_statics.nexus_disconnected ++;
4312 #endif /* SCSI_LOW_STATICS */
4314 #ifdef SCSI_LOW_DEBUG
4315 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4317 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4318 scsi_low_print(slp, NULL);
4320 #endif /* SCSI_LOW_DEBUG */
4324 slp->sl_error |= FATALIO;
4325 if (ti->ti_phase == PH_SELSTART)
4326 slp->sl_error |= SELTIMEOUTIO;
4328 slp->sl_error |= UBFERR;
4337 #ifdef SCSI_LOW_DEBUG
4338 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4340 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4341 (cb->ccb_msgoutflag != 0 ||
4342 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4344 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4347 #endif /* SCSI_LOW_DEBUG */
4349 cb->ccb_error |= slp->sl_error;
4350 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4352 cb->ccb_flags |= CCB_STARTQ;
4353 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4358 scsi_low_bus_release(slp, ti);
4359 scsi_low_start(slp);
4363 /**********************************************************
4365 **********************************************************/
4367 scsi_low_alloc_qtag(cb)
4370 struct lun_info *li = cb->li;
4371 scsi_low_tag_t etag;
4373 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4376 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4377 etag = ffs(li->li_qtagbits);
4381 li->li_qtagbits &= ~(1 << (etag - 1));
4382 cb->ccb_otag = etag;
4385 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4386 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4387 if (li->li_qtagarray[li->li_qd] == 0)
4390 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4391 if (li->li_qtagarray[li->li_qd] == 0)
4397 li->li_qtagarray[li->li_qd] ++;
4398 cb->ccb_otag = (li->li_qd ++);
4400 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4404 scsi_low_dealloc_qtag(cb)
4407 struct lun_info *li = cb->li;
4408 scsi_low_tag_t etag;
4410 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4413 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4414 etag = cb->ccb_otag - 1;
4415 #ifdef SCSI_LOW_DIAGNOSTIC
4416 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4417 panic("scsi_low_dealloc_tag: illegal tag");
4418 #endif /* SCSI_LOW_DIAGNOSTIC */
4419 li->li_qtagbits |= (1 << etag);
4421 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4422 etag = cb->ccb_otag;
4423 #ifdef SCSI_LOW_DIAGNOSTIC
4424 if (etag >= SCSI_LOW_MAXNEXUS)
4425 panic("scsi_low_dealloc_tag: illegal tag");
4426 #endif /* SCSI_LOW_DIAGNOSTIC */
4427 li->li_qtagarray[etag] --;
4428 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4430 cb->ccb_otag = SCSI_LOW_UNKTAG;
4435 scsi_low_revoke_ccb(slp, cb, fdone)
4436 struct scsi_low_softc *slp;
4440 struct targ_info *ti = cb->ti;
4441 struct lun_info *li = cb->li;
4443 #ifdef SCSI_LOW_DIAGNOSTIC
4444 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4445 (CCB_STARTQ | CCB_DISCQ))
4447 panic("%s: ccb in both queue\n", slp->sl_xname);
4449 #endif /* SCSI_LOW_DIAGNOSTIC */
4451 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4453 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4456 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4458 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4464 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4465 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4468 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4469 (cb->ccb_flags & CCB_NORETRY) != 0))
4471 cb->ccb_error |= FATALIO;
4472 cb->ccb_flags &= ~CCB_AUTOSENSE;
4473 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4474 panic("%s: done ccb retried\n", slp->sl_xname);
4479 cb->ccb_error |= PENDINGIO;
4480 scsi_low_deactivate_qtag(cb);
4481 scsi_low_ccb_message_retry(cb);
4482 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4488 scsi_low_reset_nexus_lun(slp, li, fdone)
4489 struct scsi_low_softc *slp;
4490 struct lun_info *li;
4493 struct slccb *cb, *ncb, *ecb;
4499 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4501 ncb = TAILQ_NEXT(cb, ccb_chain);
4502 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4506 * presumely keep ordering of io
4508 cb->ccb_flags |= CCB_STARTQ;
4511 TAILQ_INSERT_HEAD(&slp->sl_start,\
4516 TAILQ_INSERT_AFTER(&slp->sl_start,\
4517 ecb, cb, ccb_chain);
4524 /**************************************************************
4526 **************************************************************/
4528 scsi_low_calcf_lun(li)
4529 struct lun_info *li;
4531 struct targ_info *ti = li->li_ti;
4532 struct scsi_low_softc *slp = ti->ti_sc;
4533 u_int cfgflags, diskflags;
4535 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4536 cfgflags = li->li_cfgflags;
4540 diskflags = li->li_diskflags & li->li_quirks;
4543 li->li_flags &= ~SCSI_LOW_DISC;
4544 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4545 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4546 (cfgflags & SCSI_LOW_DISC) != 0)
4547 li->li_flags |= SCSI_LOW_DISC;
4550 li->li_flags |= SCSI_LOW_NOPARITY;
4551 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4552 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4553 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4554 li->li_flags &= ~SCSI_LOW_NOPARITY;
4557 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4558 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4559 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4561 li->li_flags |= SCSI_LOW_QTAG;
4562 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4563 li->li_maxnqio = li->li_maxnexus;
4567 li->li_flags &= ~SCSI_LOW_QTAG;
4568 li->li_maxnexus = 0;
4569 li->li_maxnqio = li->li_maxnexus;
4573 li->li_flags &= ~SCSI_LOW_LINK;
4574 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4575 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4576 li->li_flags |= SCSI_LOW_LINK;
4578 /* compatible flags */
4579 li->li_flags &= ~SCSI_LOW_SYNC;
4580 if (ti->ti_maxsynch.offset > 0)
4581 li->li_flags |= SCSI_LOW_SYNC;
4583 #ifdef SCSI_LOW_DEBUG
4584 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4586 scsi_low_calcf_show(li);
4588 #endif /* SCSI_LOW_DEBUG */
4592 scsi_low_calcf_target(ti)
4593 struct targ_info *ti;
4595 struct scsi_low_softc *slp = ti->ti_sc;
4596 u_int offset, period, diskflags;
4598 diskflags = ti->ti_diskflags & ti->ti_quirks;
4601 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4602 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4604 offset = ti->ti_maxsynch.offset;
4605 period = ti->ti_maxsynch.period;
4606 if (offset == 0 || period == 0)
4607 offset = period = 0;
4611 offset = period = 0;
4614 ti->ti_maxsynch.offset = offset;
4615 ti->ti_maxsynch.period = period;
4618 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4619 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4620 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4622 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4623 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4624 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4626 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4628 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4629 ti->ti_maxsynch.period != ti->ti_osynch.period)
4630 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4631 if (ti->ti_width != ti->ti_owidth)
4632 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4634 ti->ti_osynch = ti->ti_maxsynch;
4635 ti->ti_owidth = ti->ti_width;
4638 #ifdef SCSI_LOW_DEBUG
4639 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4641 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4642 slp->sl_xname, ti->ti_id,
4643 ti->ti_maxsynch.period * 4,
4644 ti->ti_maxsynch.offset,
4647 #endif /* SCSI_LOW_DEBUG */
4651 scsi_low_calcf_show(li)
4652 struct lun_info *li;
4654 struct targ_info *ti = li->li_ti;
4655 struct scsi_low_softc *slp = ti->ti_sc;
4657 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4658 slp->sl_xname, ti->ti_id, li->li_lun,
4659 ti->ti_maxsynch.period * 4,
4660 ti->ti_maxsynch.offset,
4662 li->li_flags, SCSI_LOW_BITS);
4665 #ifdef SCSI_LOW_START_UP_CHECK
4666 /**************************************************************
4667 * scsi world start up
4668 **************************************************************/
4669 static int scsi_low_poll __P((struct scsi_low_softc *, struct slccb *));
4672 scsi_low_start_up(slp)
4673 struct scsi_low_softc *slp;
4675 struct targ_info *ti;
4676 struct lun_info *li;
4680 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4682 for (target = 0; target < slp->sl_ntargs; target ++)
4684 if (target == slp->sl_hostid)
4686 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4688 printf("%s: scsi_low: target %d (host card)\n",
4689 slp->sl_xname, target);
4694 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4696 printf("%s: scsi_low: target %d lun ",
4697 slp->sl_xname, target);
4700 ti = slp->sl_ti[target];
4701 for (lun = 0; lun < slp->sl_nluns; lun ++)
4703 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4709 li = scsi_low_alloc_li(ti, lun, 1);
4711 scsi_low_enqueue(slp, ti, li, cb,
4712 CCB_AUTOSENSE | CCB_POLLED, 0);
4714 scsi_low_poll(slp, cb);
4716 if (li->li_state != SCSI_LOW_LUN_OK)
4719 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4725 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4734 scsi_low_poll(slp, cb)
4735 struct scsi_low_softc *slp;
4741 while (slp->sl_nio > 0)
4743 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4745 (*slp->sl_funcs->scsi_low_poll) (slp);
4746 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4750 scsi_low_timeout_check(slp);
4755 #endif /* SCSI_LOW_START_UP_CHECK */
4757 /**********************************************************
4759 **********************************************************/
4760 #ifdef SCSI_LOW_DEBUG
4762 scsi_low_test_abort(slp, ti, li)
4763 struct scsi_low_softc *slp;
4764 struct targ_info *ti;
4765 struct lun_info *li;
4769 if (li->li_disc > 1)
4771 acb = TAILQ_FIRST(&li->li_discq);
4772 if (scsi_low_abort_ccb(slp, acb) == 0)
4774 printf("%s: aborting ccb(0x%lx) start\n",
4775 slp->sl_xname, (u_long) acb);
4781 scsi_low_test_atten(slp, ti, msg)
4782 struct scsi_low_softc *slp;
4783 struct targ_info *ti;
4787 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4788 scsi_low_assert_msg(slp, ti, msg, 0);
4790 printf("%s: atten check OK\n", slp->sl_xname);
4794 scsi_low_test_cmdlnk(slp, cb)
4795 struct scsi_low_softc *slp;
4798 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4800 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4803 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4804 slp->sl_scp.scp_cmdlen);
4805 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4806 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4808 #endif /* SCSI_LOW_DEBUG */
4811 scsi_low_info(slp, ti, s)
4812 struct scsi_low_softc *slp;
4813 struct targ_info *ti;
4818 slp = LIST_FIRST(&sl_tab);
4822 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4825 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4826 ti = TAILQ_NEXT(ti, ti_chain))
4828 scsi_low_print(slp, ti);
4833 scsi_low_print(slp, ti);
4837 static u_char *phase[] =
4839 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4840 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4844 scsi_low_print(slp, ti)
4845 struct scsi_low_softc *slp;
4846 struct targ_info *ti;
4848 struct lun_info *li;
4852 if (ti == NULL || ti == slp->sl_Tnexus)
4854 ti = slp->sl_Tnexus;
4855 li = slp->sl_Lnexus;
4856 cb = slp->sl_Qnexus;
4860 li = LIST_FIRST(&ti->ti_litab);
4861 cb = TAILQ_FIRST(&li->li_discq);
4865 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4866 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4872 u_int flags = 0, maxnqio = 0, nqio = 0;
4878 flags = li->li_flags;
4879 maxnqio = li->li_maxnqio;
4883 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4885 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4886 phase[(int) ti->ti_phase], ti->ti_disc,
4891 printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4892 (u_int) cb->ccb_scp.scp_cmd[0],
4893 cb->ccb_scp.scp_cmdlen,
4895 cb->ccb_scp.scp_datalen,
4896 (u_int) cb->ccb_sscp.scp_status,
4897 cb->ccb_error, SCSI_LOW_ERRORBITS);
4900 printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4901 (u_int) (ti->ti_msginptr),
4902 (u_int) (ti->ti_msgin[0]),
4903 (u_int) (ti->ti_msgin[1]),
4904 (u_int) (ti->ti_msgin[2]),
4905 (u_int) (ti->ti_msgin[3]),
4906 (u_int) (ti->ti_msgin[4]),
4909 printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4910 (u_int) ti->ti_msgflags,
4911 (u_int) (ti->ti_msgoutstr[0]),
4912 (u_int) (ti->ti_msgoutstr[1]),
4913 (u_int) (ti->ti_msgoutstr[2]),
4914 (u_int) (ti->ti_msgoutstr[3]),
4915 (u_int) (ti->ti_msgoutstr[4]),
4917 flags, SCSI_LOW_BITS);
4919 #ifdef SCSI_LOW_DIAGNOSTIC
4920 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4921 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4922 #endif /* SCSI_LOW_DIAGNOSTIC */
4926 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4927 (u_long) sp->scp_data,
4929 (u_int) sp->scp_status,
4930 slp->sl_error, SCSI_LOW_ERRORBITS);