Deleted Added
full compact
1/* $NecBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $ */
2/* $NetBSD$ */
3
4#include <sys/cdefs.h>
5__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_low.c 143839 2005-03-19 06:32:57Z scottl $");
5__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_low.c 147723 2005-07-01 15:21:30Z avatar $");
6
7#define SCSI_LOW_STATICS
8#define SCSI_LOW_DEBUG
9#define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10#define SCSI_LOW_START_UP_CHECK
11
12/* #define SCSI_LOW_INFO_DETAIL */
13
14/* #define SCSI_LOW_QCLEAR_AFTER_CA */
15/* #define SCSI_LOW_FLAGS_QUIRKS_OK */
16
17#ifdef __NetBSD__
18#define SCSI_LOW_TARGET_OPEN
19#endif /* __NetBSD__ */
20
21#ifdef __FreeBSD__
22#define SCSI_LOW_FLAGS_QUIRKS_OK
23#endif /* __FreeBSD__ */
24
25/*-
26 * [NetBSD for NEC PC-98 series]
27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
28 * NetBSD/pc98 porting staff. All rights reserved.
29 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
30 * Naofumi HONDA. All rights reserved.
31 *
32 * [Ported for FreeBSD CAM]
33 * Copyright (c) 2000, 2001
34 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. The name of the author may not be used to endorse or promote products
46 * derived from this software without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 * POSSIBILITY OF SUCH DAMAGE.
59 */
60
61/* <On the nexus establishment>
62 * When our host is reselected,
63 * nexus establish processes are little complicated.
64 * Normal steps are followings:
65 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
66 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
67 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
68 */
69#include "opt_ddb.h"
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/kernel.h>
74
75#ifdef __FreeBSD__
76#if __FreeBSD_version >= 500001
77#include <sys/bio.h>
78#else
79#include <machine/clock.h>
80#endif
81#endif /* __FreeBSD__ */
82
83#include <sys/buf.h>
84#include <sys/queue.h>
85#include <sys/malloc.h>
86#include <sys/errno.h>
87
88#ifdef __NetBSD__
89#include <sys/device.h>
90#include <vm/vm.h>
91
92#include <machine/bus.h>
93#include <machine/intr.h>
94#include <machine/dvcfg.h>
95
96#include <dev/cons.h>
97
98#include <dev/scsipi/scsipi_all.h>
99#include <dev/scsipi/scsipiconf.h>
100#include <dev/scsipi/scsipi_disk.h>
101#include <dev/scsipi/scsi_all.h>
102#include <dev/scsipi/scsiconf.h>
103#include <sys/scsiio.h>
104
105#include <i386/Cbus/dev/scsi_low.h>
106#endif /* __NetBSD__ */
107
108#ifdef __FreeBSD__
109#include <cam/cam.h>
110#include <cam/cam_ccb.h>
111#include <cam/cam_sim.h>
112#include <cam/cam_debug.h>
113#include <cam/cam_periph.h>
114#include <cam/cam_xpt_periph.h>
115
116#include <cam/scsi/scsi_all.h>
117#include <cam/scsi/scsi_message.h>
118
119#include <cam/scsi/scsi_low.h>
120
121#include <sys/cons.h>
122#endif /* __FreeBSD__ */
123
124/**************************************************************
125 * Constants
126 **************************************************************/
127#define SCSI_LOW_POLL_HZ 1000
128
129/* functions return values */
130#define SCSI_LOW_START_NO_QTAG 0
131#define SCSI_LOW_START_QTAG 1
132
133#define SCSI_LOW_DONE_COMPLETE 0
134#define SCSI_LOW_DONE_RETRY 1
135
136/* internal disk flags */
137#define SCSI_LOW_DISK_DISC 0x00000001
138#define SCSI_LOW_DISK_QTAG 0x00000002
139#define SCSI_LOW_DISK_LINK 0x00000004
140#define SCSI_LOW_DISK_PARITY 0x00000008
141#define SCSI_LOW_DISK_SYNC 0x00010000
142#define SCSI_LOW_DISK_WIDE_16 0x00020000
143#define SCSI_LOW_DISK_WIDE_32 0x00040000
144#define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
145#define SCSI_LOW_DISK_LFLAGS 0x0000ffff
146#define SCSI_LOW_DISK_TFLAGS 0xffff0000
147
148MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
149
150/**************************************************************
151 * Declarations
152 **************************************************************/
153/* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *);
154static void scsi_low_engage(void *);
155static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
156static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
157static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
158static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
159static void scsi_low_twiddle_wait(void);
160static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
161static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
162static void scsi_low_calcf_lun(struct lun_info *);
163static void scsi_low_calcf_target(struct targ_info *);
164static void scsi_low_calcf_show(struct lun_info *);
165static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
166static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
167static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
168static int scsi_low_init(struct scsi_low_softc *, u_int);
169static void scsi_low_start(struct scsi_low_softc *);
170static void scsi_low_free_ti(struct scsi_low_softc *);
171
172static int scsi_low_alloc_qtag(struct slccb *);
173static int scsi_low_dealloc_qtag(struct slccb *);
174static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
175static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
176static void scsi_low_unit_ready_cmd(struct slccb *);
177static void scsi_low_timeout(void *);
178static int scsi_low_timeout_check(struct scsi_low_softc *);
179#ifdef SCSI_LOW_START_UP_CHECK
180static int scsi_low_start_up(struct scsi_low_softc *);
181#endif /* SCSI_LOW_START_UP_CHECK */
182static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
183static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
184
185int scsi_low_version_major = 2;
186int scsi_low_version_minor = 17;
187
188static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
189
190/**************************************************************
191 * Debug, Run test and Statics
192 **************************************************************/
193#ifdef SCSI_LOW_INFO_DETAIL
194#define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
195#else /* !SCSI_LOW_INFO_DETAIL */
196#define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
197#endif /* !SCSI_LOW_INFO_DETAIL */
198
199#ifdef SCSI_LOW_STATICS
200static struct scsi_low_statics {
201 int nexus_win;
202 int nexus_fail;
203 int nexus_disconnected;
204 int nexus_reselected;
205 int nexus_conflict;
206} scsi_low_statics;
207#endif /* SCSI_LOW_STATICS */
208
209#ifdef SCSI_LOW_DEBUG
210#define SCSI_LOW_DEBUG_DONE 0x00001
211#define SCSI_LOW_DEBUG_DISC 0x00002
212#define SCSI_LOW_DEBUG_SENSE 0x00004
213#define SCSI_LOW_DEBUG_CALCF 0x00008
214#define SCSI_LOW_DEBUG_ACTION 0x10000
215int scsi_low_debug = 0;
216
217#define SCSI_LOW_MAX_ATTEN_CHECK 32
218#define SCSI_LOW_ATTEN_CHECK 0x0001
219#define SCSI_LOW_CMDLNK_CHECK 0x0002
220#define SCSI_LOW_ABORT_CHECK 0x0004
221#define SCSI_LOW_NEXUS_CHECK 0x0008
222int scsi_low_test = 0;
223int scsi_low_test_id = 0;
224
225static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
226static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
227static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int);
228#define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
229 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
230#define SCSI_LOW_DEBUG_GO(fl, id) \
231 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
232#endif /* SCSI_LOW_DEBUG */
233
234/**************************************************************
235 * CCB
236 **************************************************************/
237GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
238GENERIC_CCB(scsi_low, slccb, ccb_chain)
239
240/**************************************************************
241 * Inline functions
242 **************************************************************/
243#define SCSI_LOW_INLINE static __inline
244SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
245SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
246SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
247SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
248SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
249SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
250SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
251
252SCSI_LOW_INLINE void
253scsi_low_activate_qtag(cb)
254 struct slccb *cb;
255{
256 struct lun_info *li = cb->li;
257
258 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
259 return;
260
261 li->li_nqio ++;
262 cb->ccb_tag = cb->ccb_otag;
263}
264
265SCSI_LOW_INLINE void
266scsi_low_deactivate_qtag(cb)
267 struct slccb *cb;
268{
269 struct lun_info *li = cb->li;
270
271 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
272 return;
273
274 li->li_nqio --;
275 cb->ccb_tag = SCSI_LOW_UNKTAG;
276}
277
278SCSI_LOW_INLINE void
279scsi_low_ccb_message_exec(slp, cb)
280 struct scsi_low_softc *slp;
281 struct slccb *cb;
282{
283
284 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
285 cb->ccb_msgoutflag = 0;
286}
287
288SCSI_LOW_INLINE void
289scsi_low_ccb_message_assert(cb, msg)
290 struct slccb *cb;
291 u_int msg;
292{
293
294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
295}
296
297SCSI_LOW_INLINE void
298scsi_low_ccb_message_retry(cb)
299 struct slccb *cb;
300{
301 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
302}
303
304SCSI_LOW_INLINE void
305scsi_low_ccb_message_clear(cb)
306 struct slccb *cb;
307{
308 cb->ccb_msgoutflag = 0;
309}
310
311SCSI_LOW_INLINE void
312scsi_low_init_msgsys(slp, ti)
313 struct scsi_low_softc *slp;
314 struct targ_info *ti;
315{
316
317 ti->ti_msginptr = 0;
318 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
319 SCSI_LOW_DEASSERT_ATN(slp);
320 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
321}
322
323/*=============================================================
324 * START OF OS switch (All OS depend fucntions should be here)
325 =============================================================*/
326/* common os depend utitlities */
327#define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
328#define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
329#define SCSI_LOW_CMD_ABORT_WARNING 0x0004
330
331static u_int8_t scsi_low_cmd_flags[256] = {
332/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
333/*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
334/*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
335/*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
336/*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
337};
338
339struct scsi_low_error_code {
340 int error_bits;
341 int error_code;
342};
343
344static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
345static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
346
347static struct slccb *
348scsi_low_find_ccb(slp, target, lun, osdep)
349 struct scsi_low_softc *slp;
350 u_int target, lun;
351 void *osdep;
352{
353 struct targ_info *ti;
354 struct lun_info *li;
355 struct slccb *cb;
356
357 ti = slp->sl_ti[target];
358 li = scsi_low_alloc_li(ti, lun, 0);
359 if (li == NULL)
360 return NULL;
361
362 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
363 return cb;
364
365 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
366 cb = TAILQ_NEXT(cb, ccb_chain))
367 {
368 if (cb->osdep == osdep)
369 return cb;
370 }
371
372 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
373 cb = TAILQ_NEXT(cb, ccb_chain))
374 {
375 if (cb->osdep == osdep)
376 return cb;
377 }
378 return NULL;
379}
380
381static int
382scsi_low_translate_error_code(cb, tp)
383 struct slccb *cb;
384 struct scsi_low_error_code *tp;
385{
386
387 if (cb->ccb_error == 0)
388 return tp->error_code;
389
390 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
391 ;
392 return tp->error_code;
393}
394
395#ifdef SCSI_LOW_INTERFACE_XS
396/**************************************************************
397 * SCSI INTERFACE (XS)
398 **************************************************************/
399#define SCSI_LOW_MINPHYS 0x10000
397#define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
398#define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
400#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
401#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
402#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
403#define SCSI_LOW_XS_POLL_HZ 1000
404
405static int scsi_low_poll_xs(struct scsi_low_softc *, struct slccb *);
406static void scsi_low_scsi_minphys_xs(struct buf *);
407#ifdef SCSI_LOW_TARGET_OPEN
408static int scsi_low_target_open(struct scsipi_link *, struct cfdata *);
409#endif /* SCSI_LOW_TARGET_OPEN */
410static int scsi_low_scsi_cmd_xs(struct scsipi_xfer *);
411static int scsi_low_enable_xs(void *, int);
412static int scsi_low_ioctl_xs(struct scsipi_link *, u_long, caddr_t, int, struct proc *);
413
414static int scsi_low_attach_xs(struct scsi_low_softc *);
415static int scsi_low_world_start_xs(struct scsi_low_softc *);
416static int scsi_low_dettach_xs(struct scsi_low_softc *);
417static int scsi_low_ccb_setup_xs(struct scsi_low_softc *, struct slccb *);
418static int scsi_low_done_xs(struct scsi_low_softc *, struct slccb *);
419static void scsi_low_timeout_xs(struct scsi_low_softc *, int, int);
420static u_int scsi_low_translate_quirks_xs(u_int);
421static void scsi_low_setup_quirks_xs(struct targ_info *, struct lun_info *, u_int);
422
423struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
424 scsi_low_attach_xs,
425 scsi_low_world_start_xs,
426 scsi_low_dettach_xs,
427 scsi_low_ccb_setup_xs,
428 scsi_low_done_xs,
429 scsi_low_timeout_xs
430};
431
432struct scsipi_device scsi_low_dev = {
433 NULL, /* Use default error handler */
434 NULL, /* have a queue, served by this */
435 NULL, /* have no async handler */
436 NULL, /* Use default 'done' routine */
437};
438
439struct scsi_low_error_code scsi_low_error_code_xs[] = {
440 {0, XS_NOERROR},
441 {SENSEIO, XS_SENSE},
442 {BUSYERR, XS_BUSY },
443 {SELTIMEOUTIO, XS_SELTIMEOUT},
444 {TIMEOUTIO, XS_TIMEOUT},
445 {-1, XS_DRIVER_STUFFUP}
446};
447
448static int
449scsi_low_ioctl_xs(link, cmd, addr, flag, p)
450 struct scsipi_link *link;
451 u_long cmd;
452 caddr_t addr;
453 int flag;
454 struct proc *p;
455{
456 struct scsi_low_softc *slp;
457 int s, error = ENOTTY;
458
459 slp = (struct scsi_low_softc *) link->adapter_softc;
460 if ((slp->sl_flags & HW_INACTIVE) != 0)
461 return ENXIO;
462
463 if (cmd == SCBUSIORESET)
464 {
465 s = SCSI_LOW_SPLSCSI();
466 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
467 splx(s);
468 error = 0;
469 }
470 else if (slp->sl_funcs->scsi_low_ioctl != 0)
471 {
472 error = (*slp->sl_funcs->scsi_low_ioctl)
473 (slp, cmd, addr, flag, p);
474 }
475
476 return error;
477}
478
479static int
480scsi_low_enable_xs(arg, enable)
481 void *arg;
482 int enable;
483{
484 struct scsi_low_softc *slp = arg;
485
486 if (enable != 0)
487 {
488 if ((slp->sl_flags & HW_INACTIVE) != 0)
489 return ENXIO;
490 }
491 else
492 {
493 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
494 (slp->sl_flags & HW_POWERCTRL) == 0)
495 return 0;
496
497 slp->sl_flags |= HW_POWDOWN;
498 if (slp->sl_funcs->scsi_low_power != NULL)
499 {
500 (*slp->sl_funcs->scsi_low_power)
501 (slp, SCSI_LOW_POWDOWN);
502 }
503 }
504 return 0;
505}
506
507static void
508scsi_low_scsi_minphys_xs(bp)
509 struct buf *bp;
510{
511
512 if (bp->b_bcount > SCSI_LOW_MINPHYS)
513 bp->b_bcount = SCSI_LOW_MINPHYS;
514 minphys(bp);
515}
516
517static int
518scsi_low_poll_xs(slp, cb)
519 struct scsi_low_softc *slp;
520 struct slccb *cb;
521{
522 struct scsipi_xfer *xs = cb->osdep;
523 int tcount;
524
525 cb->ccb_flags |= CCB_NOSDONE;
526 tcount = 0;
527
528 while (slp->sl_nio > 0)
529 {
530 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
531
532 (*slp->sl_funcs->scsi_low_poll) (slp);
533
534 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
535 {
536 cb->ccb_flags |= CCB_NORETRY;
537 cb->ccb_error |= FATALIO;
538 (void) scsi_low_revoke_ccb(slp, cb, 1);
539 printf("%s: hardware inactive in poll mode\n",
540 slp->sl_xname);
541 }
542
543 if ((xs->flags & ITSDONE) != 0)
544 break;
545
546 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
547 continue;
548
549 tcount = 0;
550 scsi_low_timeout_check(slp);
551 }
552
553 xs->flags |= ITSDONE;
554 scsipi_done(xs);
555 return COMPLETE;
556}
557
558static int
559scsi_low_scsi_cmd_xs(xs)
560 struct scsipi_xfer *xs;
561{
562 struct scsipi_link *splp = xs->sc_link;
563 struct scsi_low_softc *slp = splp->adapter_softc;
564 struct targ_info *ti;
565 struct lun_info *li;
566 struct slccb *cb;
567 int s, targ, lun, flags, rv;
568
569 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
570 return TRY_AGAIN_LATER;
571
572 targ = splp->scsipi_scsi.target,
573 lun = splp->scsipi_scsi.lun;
574 ti = slp->sl_ti[targ];
575
576 cb->osdep = xs;
577 cb->bp = xs->bp;
578
579 if ((xs->flags & SCSI_POLL) == 0)
580 flags = CCB_AUTOSENSE;
581 else
582 flags = CCB_AUTOSENSE | CCB_POLLED;
583
584
585 s = SCSI_LOW_SPLSCSI();
586 li = scsi_low_alloc_li(ti, lun, 1);
587 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
588 {
589 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
590 }
591
592 if ((xs->flags & SCSI_RESET) != 0)
593 {
594 flags |= CCB_NORETRY | CCB_URGENT;
595 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
596 }
597 else
598 {
599 if (ti->ti_setup_msg != 0)
600 {
601 scsi_low_message_enqueue(slp, ti, li, flags);
602 }
603
604 flags |= CCB_SCSIIO;
605 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
606 }
607
608#ifdef SCSI_LOW_DEBUG
609 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
610 {
611 scsi_low_test_abort(slp, ti, li);
612 }
613#endif /* SCSI_LOW_DEBUG */
614
615 if ((cb->ccb_flags & CCB_POLLED) != 0)
616 {
617 rv = scsi_low_poll_xs(slp, cb);
618 }
619 else
620 {
621 rv = SUCCESSFULLY_QUEUED;
622 }
623 splx(s);
624 return rv;
625}
626
627static int
628scsi_low_attach_xs(slp)
629 struct scsi_low_softc *slp;
630{
631 struct scsipi_adapter *sap;
632 struct scsipi_link *splp;
633
634 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
635
636 sap = SCSI_LOW_MALLOC(sizeof(*sap));
637 if (sap == NULL)
638 return ENOMEM;
639 splp = SCSI_LOW_MALLOC(sizeof(*splp));
640 if (splp == NULL)
641 return ENOMEM;
642
643 SCSI_LOW_BZERO(sap, sizeof(*sap));
644 SCSI_LOW_BZERO(splp, sizeof(*splp));
645
646 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
647 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
648 sap->scsipi_enable = scsi_low_enable_xs;
649 sap->scsipi_ioctl = scsi_low_ioctl_xs;
650#ifdef SCSI_LOW_TARGET_OPEN
651 sap->open_target_lu = scsi_low_target_open;
652#endif /* SCSI_LOW_TARGET_OPEN */
653
654 splp->adapter_softc = slp;
655 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
656 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
657 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
658 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
659 splp->openings = slp->sl_openings;
660 splp->type = BUS_SCSI;
661 splp->adapter_softc = slp;
662 splp->adapter = sap;
663 splp->device = &scsi_low_dev;
664
665 slp->sl_si.si_splp = splp;
666 slp->sl_show_result = SHOW_ALL_NEG;
667 return 0;
668}
669
670static int
671scsi_low_world_start_xs(slp)
672 struct scsi_low_softc *slp;
673{
674
675 return 0;
676}
677
678static int
679scsi_low_dettach_xs(slp)
680 struct scsi_low_softc *slp;
681{
682
683 /*
684 * scsipi does not have dettach bus fucntion.
685 *
686 scsipi_dettach_scsibus(slp->sl_si.si_splp);
687 */
688 return 0;
689}
690
691static int
692scsi_low_ccb_setup_xs(slp, cb)
693 struct scsi_low_softc *slp;
694 struct slccb *cb;
695{
696 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
697
698 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
699 {
700 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
701 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
702 cb->ccb_scp.scp_data = xs->data;
703 cb->ccb_scp.scp_datalen = xs->datalen;
704 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
705 SCSI_LOW_WRITE : SCSI_LOW_READ;
706 cb->ccb_tcmax = xs->timeout / 1000;
707 }
708 else
709 {
710 scsi_low_unit_ready_cmd(cb);
711 }
712 return SCSI_LOW_START_QTAG;
713}
714
715static int
716scsi_low_done_xs(slp, cb)
717 struct scsi_low_softc *slp;
718 struct slccb *cb;
719{
720 struct scsipi_xfer *xs;
721
722 xs = (struct scsipi_xfer *) cb->osdep;
723 if (cb->ccb_error == 0)
724 {
725 xs->error = XS_NOERROR;
726 xs->resid = 0;
727 }
728 else
729 {
730 if (cb->ccb_rcnt >= slp->sl_max_retry)
731 cb->ccb_error |= ABORTIO;
732
733 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
734 (cb->ccb_error & ABORTIO) == 0)
735 return EJUSTRETURN;
736
737 if ((cb->ccb_error & SENSEIO) != 0)
738 {
739 xs->sense.scsi_sense = cb->ccb_sense;
740 }
741
742 xs->error = scsi_low_translate_error_code(cb,
743 &scsi_low_error_code_xs[0]);
744
745#ifdef SCSI_LOW_DIAGNOSTIC
746 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
747 cb->ccb_scp.scp_cmdlen > 0 &&
748 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
749 SCSI_LOW_CMD_ABORT_WARNING) != 0)
750 {
751 printf("%s: WARNING: scsi_low IO abort\n",
752 slp->sl_xname);
753 scsi_low_print(slp, NULL);
754 }
755#endif /* SCSI_LOW_DIAGNOSTIC */
756 }
757
758 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
759 xs->status = 0; /* XXX */
760 else
761 xs->status = cb->ccb_scp.scp_status;
762
763 xs->flags |= ITSDONE;
764 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
765 scsipi_done(xs);
766
767 return 0;
768}
769
770static void
771scsi_low_timeout_xs(slp, ch, action)
772 struct scsi_low_softc *slp;
773 int ch;
774 int action;
775{
776
777 switch (ch)
778 {
779 case SCSI_LOW_TIMEOUT_CH_IO:
780 switch (action)
781 {
782 case SCSI_LOW_TIMEOUT_START:
783 timeout(scsi_low_timeout, slp,
784 hz / SCSI_LOW_TIMEOUT_HZ);
785 break;
786 case SCSI_LOW_TIMEOUT_STOP:
787 untimeout(scsi_low_timeout, slp);
788 break;
789 }
790 break;
791
792 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
793 switch (action)
794 {
795 case SCSI_LOW_TIMEOUT_START:
796 timeout(scsi_low_engage, slp, 1);
797 break;
798 case SCSI_LOW_TIMEOUT_STOP:
799 untimeout(scsi_low_engage, slp);
800 break;
801 }
802 break;
803
804 case SCSI_LOW_TIMEOUT_CH_RECOVER:
805 break;
806 }
807}
808
809u_int
810scsi_low_translate_quirks_xs(quirks)
811 u_int quirks;
812{
813 u_int flags;
814
815 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
816
817#ifdef SDEV_NODISC
818 if (quirks & SDEV_NODISC)
819 flags &= ~SCSI_LOW_DISK_DISC;
820#endif /* SDEV_NODISC */
821#ifdef SDEV_NOPARITY
822 if (quirks & SDEV_NOPARITY)
823 flags &= ~SCSI_LOW_DISK_PARITY;
824#endif /* SDEV_NOPARITY */
825#ifdef SDEV_NOCMDLNK
826 if (quirks & SDEV_NOCMDLNK)
827 flags &= ~SCSI_LOW_DISK_LINK;
828#endif /* SDEV_NOCMDLNK */
829#ifdef SDEV_NOTAG
830 if (quirks & SDEV_NOTAG)
831 flags &= ~SCSI_LOW_DISK_QTAG;
832#endif /* SDEV_NOTAG */
833#ifdef SDEV_NOSYNC
834 if (quirks & SDEV_NOSYNC)
835 flags &= ~SCSI_LOW_DISK_SYNC;
836#endif /* SDEV_NOSYNC */
837
838 return flags;
839}
840
841static void
842scsi_low_setup_quirks_xs(ti, li, flags)
843 struct targ_info *ti;
844 struct lun_info *li;
845 u_int flags;
846{
847 u_int quirks;
848
849 li->li_sloi.sloi_quirks = flags;
850 quirks = scsi_low_translate_quirks_xs(flags);
851 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
852 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
853 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
854 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
855 scsi_low_calcf_target(ti);
856 scsi_low_calcf_lun(li);
857 scsi_low_calcf_show(li);
858}
859
860#ifdef SCSI_LOW_TARGET_OPEN
861static int
862scsi_low_target_open(link, cf)
863 struct scsipi_link *link;
864 struct cfdata *cf;
865{
866 u_int target = link->scsipi_scsi.target;
867 u_int lun = link->scsipi_scsi.lun;
868 struct scsi_low_softc *slp;
869 struct targ_info *ti;
870 struct lun_info *li;
871
872 slp = (struct scsi_low_softc *) link->adapter_softc;
873 ti = slp->sl_ti[target];
874 li = scsi_low_alloc_li(ti, lun, 0);
875 if (li == NULL)
876 return 0;
877
878 li->li_cfgflags = cf->cf_flags;
879 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
880 return 0;
881}
882#endif /* SCSI_LOW_TARGET_OPEN */
883
884#endif /* SCSI_LOW_INTERFACE_XS */
885
886#ifdef SCSI_LOW_INTERFACE_CAM
887/**************************************************************
888 * SCSI INTERFACE (CAM)
889 **************************************************************/
887#define SCSI_LOW_MALLOC(size) malloc((size), M_DEVBUF, M_NOWAIT)
888#define SCSI_LOW_FREE(pt) free((pt), M_DEVBUF)
890#define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
891#define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
892#define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
893
894static void scsi_low_poll_cam(struct cam_sim *);
895static void scsi_low_cam_rescan_callback(struct cam_periph *, union ccb *);
896static void scsi_low_rescan_bus_cam(struct scsi_low_softc *);
897void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
898
899static int scsi_low_attach_cam(struct scsi_low_softc *);
900static int scsi_low_world_start_cam(struct scsi_low_softc *);
901static int scsi_low_dettach_cam(struct scsi_low_softc *);
902static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
903static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
904static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int);
905
906struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
907 scsi_low_attach_cam,
908 scsi_low_world_start_cam,
909 scsi_low_dettach_cam,
910 scsi_low_ccb_setup_cam,
911 scsi_low_done_cam,
912 scsi_low_timeout_cam
913};
914
915struct scsi_low_error_code scsi_low_error_code_cam[] = {
916 {0, CAM_REQ_CMP},
917 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
918 {SENSEERR, CAM_AUTOSENSE_FAIL},
919 {UACAERR, CAM_SCSI_STATUS_ERROR},
920 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
921 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
922 {TIMEOUTIO, CAM_CMD_TIMEOUT},
923 {PDMAERR, CAM_DATA_RUN_ERR},
924 {PARITYERR, CAM_UNCOR_PARITY},
925 {UBFERR, CAM_UNEXP_BUSFREE},
926 {ABORTIO, CAM_REQ_ABORTED},
927 {-1, CAM_UNREC_HBA_ERROR}
928};
929
930#define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
931
932/* XXX:
933 * Please check a polling hz, currently we assume scsi_low_poll() is
934 * called each 1 ms.
935 */
936#define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
937
938static void
939scsi_low_poll_cam(sim)
940 struct cam_sim *sim;
941{
942 struct scsi_low_softc *slp = SIM2SLP(sim);
943
944 (*slp->sl_funcs->scsi_low_poll) (slp);
945
946 if (slp->sl_si.si_poll_count ++ >=
947 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
948 {
949 slp->sl_si.si_poll_count = 0;
950 scsi_low_timeout_check(slp);
951 }
952}
953
954static void
955scsi_low_cam_rescan_callback(periph, ccb)
956 struct cam_periph *periph;
957 union ccb *ccb;
958{
959
960 xpt_free_path(ccb->ccb_h.path);
958 free(ccb, M_DEVBUF);
961 xpt_free_ccb(ccb);
962}
963
964static void
965scsi_low_rescan_bus_cam(slp)
966 struct scsi_low_softc *slp;
967{
968 struct cam_path *path;
966 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK);
969 union ccb *ccb = xpt_alloc_ccb();
970 cam_status status;
971
972 bzero(ccb, sizeof(union ccb));
973
974 status = xpt_create_path(&path, xpt_periph,
975 cam_sim_path(slp->sl_si.sim), -1, 0);
976 if (status != CAM_REQ_CMP)
977 return;
978
979 xpt_setup_ccb(&ccb->ccb_h, path, 5);
980 ccb->ccb_h.func_code = XPT_SCAN_BUS;
981 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
982 ccb->crcn.flags = CAM_FLAG_NONE;
983 xpt_action(ccb);
984}
985
986void
987scsi_low_scsi_action_cam(sim, ccb)
988 struct cam_sim *sim;
989 union ccb *ccb;
990{
991 struct scsi_low_softc *slp = SIM2SLP(sim);
992 struct targ_info *ti;
993 struct lun_info *li;
994 struct slccb *cb;
995 u_int lun, flags, msg, target;
996 int s, rv;
997
998 target = (u_int) (ccb->ccb_h.target_id);
999 lun = (u_int) ccb->ccb_h.target_lun;
1000
1001#ifdef SCSI_LOW_DEBUG
1002 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
1003 {
1004 printf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
1005 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
1006 }
1007#endif /* SCSI_LOW_DEBUG */
1008
1009 switch (ccb->ccb_h.func_code) {
1010 case XPT_SCSI_IO: /* Execute the requested I/O operation */
1011#ifdef SCSI_LOW_DIAGNOSTIC
1012 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1013 {
1014 printf("%s: invalid target/lun\n", slp->sl_xname);
1015 ccb->ccb_h.status = CAM_REQ_INVALID;
1016 xpt_done(ccb);
1017 return;
1018 }
1019#endif /* SCSI_LOW_DIAGNOSTIC */
1020
1021 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
1022 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1023 xpt_done(ccb);
1024 return;
1025 }
1026
1027 ti = slp->sl_ti[target];
1028 cb->osdep = ccb;
1029 cb->bp = NULL;
1030 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1031 flags = CCB_AUTOSENSE | CCB_SCSIIO;
1032 else
1033 flags = CCB_SCSIIO;
1034
1035 s = SCSI_LOW_SPLSCSI();
1036 li = scsi_low_alloc_li(ti, lun, 1);
1037
1038 if (ti->ti_setup_msg != 0)
1039 {
1040 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
1041 }
1042
1043 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
1044
1045#ifdef SCSI_LOW_DEBUG
1046 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
1047 {
1048 scsi_low_test_abort(slp, ti, li);
1049 }
1050#endif /* SCSI_LOW_DEBUG */
1051 splx(s);
1052 break;
1053
1054 case XPT_EN_LUN: /* Enable LUN as a target */
1055 case XPT_TARGET_IO: /* Execute target I/O request */
1056 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
1057 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
1058 /* XXX Implement */
1059 ccb->ccb_h.status = CAM_REQ_INVALID;
1060 xpt_done(ccb);
1061 break;
1062
1063 case XPT_ABORT: /* Abort the specified CCB */
1064#ifdef SCSI_LOW_DIAGNOSTIC
1065 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
1066 {
1067 printf("%s: invalid target/lun\n", slp->sl_xname);
1068 ccb->ccb_h.status = CAM_REQ_INVALID;
1069 xpt_done(ccb);
1070 return;
1071 }
1072#endif /* SCSI_LOW_DIAGNOSTIC */
1073
1074 s = SCSI_LOW_SPLSCSI();
1075 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
1076 rv = scsi_low_abort_ccb(slp, cb);
1077 splx(s);
1078
1079 if (rv == 0)
1080 ccb->ccb_h.status = CAM_REQ_CMP;
1081 else
1082 ccb->ccb_h.status = CAM_REQ_INVALID;
1083 xpt_done(ccb);
1084 break;
1085
1086 case XPT_SET_TRAN_SETTINGS: {
1087 struct ccb_trans_settings *cts;
1088 u_int val;
1089
1090#ifdef SCSI_LOW_DIAGNOSTIC
1091 if (target == CAM_TARGET_WILDCARD)
1092 {
1093 printf("%s: invalid target\n", slp->sl_xname);
1094 ccb->ccb_h.status = CAM_REQ_INVALID;
1095 xpt_done(ccb);
1096 return;
1097 }
1098#endif /* SCSI_LOW_DIAGNOSTIC */
1099 cts = &ccb->cts;
1100 ti = slp->sl_ti[target];
1101 if (lun == CAM_LUN_WILDCARD)
1102 lun = 0;
1103
1104 s = SCSI_LOW_SPLSCSI();
1105 if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID |
1106 CCB_TRANS_SYNC_RATE_VALID |
1107 CCB_TRANS_SYNC_OFFSET_VALID)) != 0)
1108 {
1109 if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0) {
1110 val = cts->bus_width;
1111 if (val < ti->ti_width)
1112 ti->ti_width = val;
1113 }
1114 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
1115 val = cts->sync_period;
1116 if (val == 0 || val > ti->ti_maxsynch.period)
1117 ti->ti_maxsynch.period = val;
1118 }
1119 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0) {
1120 val = cts->sync_offset;
1121 if (val < ti->ti_maxsynch.offset)
1122 ti->ti_maxsynch.offset = val;
1123 }
1124
1125 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1126 scsi_low_calcf_target(ti);
1127 }
1128
1129 if ((cts->valid & (CCB_TRANS_DISC_VALID |
1130 CCB_TRANS_TQ_VALID)) != 0)
1131 {
1132 li = scsi_low_alloc_li(ti, lun, 1);
1133 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0)
1134 {
1135 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
1136 li->li_quirks |= SCSI_LOW_DISK_DISC;
1137 else
1138 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
1139 }
1140 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0)
1141 {
1142 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0)
1143 li->li_quirks |= SCSI_LOW_DISK_QTAG;
1144 else
1145 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
1146 }
1147
1148 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1149 scsi_low_calcf_target(ti);
1150 scsi_low_calcf_lun(li);
1151 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
1152 scsi_low_calcf_show(li);
1153 }
1154 splx(s);
1155
1156 ccb->ccb_h.status = CAM_REQ_CMP;
1157 xpt_done(ccb);
1158 break;
1159 }
1160
1161 case XPT_GET_TRAN_SETTINGS: {
1162 struct ccb_trans_settings *cts;
1163 u_int diskflags;
1164
1165 cts = &ccb->cts;
1166#ifdef SCSI_LOW_DIAGNOSTIC
1167 if (target == CAM_TARGET_WILDCARD)
1168 {
1169 printf("%s: invalid target\n", slp->sl_xname);
1170 ccb->ccb_h.status = CAM_REQ_INVALID;
1171 xpt_done(ccb);
1172 return;
1173 }
1174#endif /* SCSI_LOW_DIAGNOSTIC */
1175 ti = slp->sl_ti[target];
1176 if (lun == CAM_LUN_WILDCARD)
1177 lun = 0;
1178
1179 s = SCSI_LOW_SPLSCSI();
1180 li = scsi_low_alloc_li(ti, lun, 1);
1181#ifdef CAM_NEW_TRAN_CODE
1182 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
1183 struct ccb_trans_settings_scsi *scsi =
1184 &cts->proto_specific.scsi;
1185 struct ccb_trans_settings_spi *spi =
1186 &cts->xport_specific.spi;
1187#ifdef SCSI_LOW_DIAGNOSTIC
1188 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1189 {
1190 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1191 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1192 slp->sl_xname);
1193 goto settings_out;
1194 }
1195#endif /* SCSI_LOW_DIAGNOSTIC */
1196 cts->protocol = PROTO_SCSI;
1197 cts->protocol_version = SCSI_REV_2;
1198 cts->transport = XPORT_SPI;
1199 cts->transport_version = 2;
1200
1201 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1202 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1203
1204 diskflags = li->li_diskflags & li->li_cfgflags;
1205 if (diskflags & SCSI_LOW_DISK_DISC)
1206 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
1207 if (diskflags & SCSI_LOW_DISK_QTAG)
1208 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1209
1210 spi->sync_period = ti->ti_maxsynch.period;
1211 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
1212 spi->sync_offset = ti->ti_maxsynch.offset;
1213 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
1214
1215 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
1216 spi->bus_width = ti->ti_width;
1217
1218 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
1219 scsi->valid = CTS_SCSI_VALID_TQ;
1220 spi->valid |= CTS_SPI_VALID_DISC;
1221 } else
1222 scsi->valid = 0;
1223 } else
1224 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1225#else
1226 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
1227 {
1228#ifdef SCSI_LOW_DIAGNOSTIC
1229 if ((li->li_flags_valid & SCSI_LOW_LUN_FLAGS_DISK_VALID) == 0)
1230 {
1231 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1232 printf("%s: invalid GET_TRANS_USER_SETTINGS call\n",
1233 slp->sl_xname);
1234 goto settings_out;
1235 }
1236#endif /* SCSI_LOW_DIAGNOSTIC */
1237 diskflags = li->li_diskflags & li->li_cfgflags;
1238 if ((diskflags & SCSI_LOW_DISK_DISC) != 0)
1239 cts->flags |= CCB_TRANS_DISC_ENB;
1240 else
1241 cts->flags &= ~CCB_TRANS_DISC_ENB;
1242 if ((diskflags & SCSI_LOW_DISK_QTAG) != 0)
1243 cts->flags |= CCB_TRANS_TAG_ENB;
1244 else
1245 cts->flags &= ~CCB_TRANS_TAG_ENB;
1246 }
1247 else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
1248 {
1249#ifdef SCSI_LOW_DIAGNOSTIC
1250 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
1251 {
1252 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1253 printf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
1254 slp->sl_xname);
1255 goto settings_out;
1256 }
1257#endif /* SCSI_LOW_DIAGNOSTIC */
1258 if ((li->li_flags & SCSI_LOW_DISC) != 0)
1259 cts->flags |= CCB_TRANS_DISC_ENB;
1260 else
1261 cts->flags &= ~CCB_TRANS_DISC_ENB;
1262 if ((li->li_flags & SCSI_LOW_QTAG) != 0)
1263 cts->flags |= CCB_TRANS_TAG_ENB;
1264 else
1265 cts->flags &= ~CCB_TRANS_TAG_ENB;
1266 }
1267 else
1268 {
1269 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
1270 goto settings_out;
1271 }
1272
1273 cts->sync_period = ti->ti_maxsynch.period;
1274 cts->sync_offset = ti->ti_maxsynch.offset;
1275 cts->bus_width = ti->ti_width;
1276
1277 cts->valid = CCB_TRANS_SYNC_RATE_VALID
1278 | CCB_TRANS_SYNC_OFFSET_VALID
1279 | CCB_TRANS_BUS_WIDTH_VALID
1280 | CCB_TRANS_DISC_VALID
1281 | CCB_TRANS_TQ_VALID;
1282 ccb->ccb_h.status = CAM_REQ_CMP;
1283#endif
1284settings_out:
1285 splx(s);
1286 xpt_done(ccb);
1287 break;
1288 }
1289
1290 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
1291 cam_calc_geometry(&ccb->ccg, /*extended*/1);
1292 xpt_done(ccb);
1293 break;
1294 }
1295
1296 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
1297 s = SCSI_LOW_SPLSCSI();
1298 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1299 splx(s);
1300 ccb->ccb_h.status = CAM_REQ_CMP;
1301 xpt_done(ccb);
1302 break;
1303
1304 case XPT_TERM_IO: /* Terminate the I/O process */
1305 ccb->ccb_h.status = CAM_REQ_INVALID;
1306 xpt_done(ccb);
1307 break;
1308
1309 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
1310#ifdef SCSI_LOW_DIAGNOSTIC
1311 if (target == CAM_TARGET_WILDCARD)
1312 {
1313 printf("%s: invalid target\n", slp->sl_xname);
1314 ccb->ccb_h.status = CAM_REQ_INVALID;
1315 xpt_done(ccb);
1316 return;
1317 }
1318#endif /* SCSI_LOW_DIAGNOSTIC */
1319
1320 msg = SCSI_LOW_MSG_RESET;
1321 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1322 {
1323 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1324 xpt_done(ccb);
1325 return;
1326 }
1327
1328 ti = slp->sl_ti[target];
1329 if (lun == CAM_LUN_WILDCARD)
1330 lun = 0;
1331 cb->osdep = ccb;
1332 cb->bp = NULL;
1333 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1334 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1335 else
1336 flags = CCB_NORETRY | CCB_URGENT;
1337
1338 s = SCSI_LOW_SPLSCSI();
1339 li = scsi_low_alloc_li(ti, lun, 1);
1340 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1341 splx(s);
1342 break;
1343
1344 case XPT_PATH_INQ: { /* Path routing inquiry */
1345 struct ccb_pathinq *cpi = &ccb->cpi;
1346
1347 cpi->version_num = scsi_low_version_major;
1348 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1349 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
1350 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1351 cpi->hba_inquiry |= PI_WIDE_16;
1352 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1353 cpi->hba_inquiry |= PI_WIDE_32;
1354 if (ti->ti_maxsynch.offset > 0)
1355 cpi->hba_inquiry |= PI_SDTR_ABLE;
1356 cpi->target_sprt = 0;
1357 cpi->hba_misc = 0;
1358 cpi->hba_eng_cnt = 0;
1359 cpi->max_target = slp->sl_ntargs - 1;
1360 cpi->max_lun = slp->sl_nluns - 1;
1361 cpi->initiator_id = slp->sl_hostid;
1362 cpi->bus_id = cam_sim_bus(sim);
1363 cpi->base_transfer_speed = 3300;
1364#ifdef CAM_NEW_TRAN_CODE
1365 cpi->transport = XPORT_SPI;
1366 cpi->transport_version = 2;
1367 cpi->protocol = PROTO_SCSI;
1368 cpi->protocol_version = SCSI_REV_2;
1369#endif
1370 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1371 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1372 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1373 cpi->unit_number = cam_sim_unit(sim);
1374 cpi->ccb_h.status = CAM_REQ_CMP;
1375 xpt_done(ccb);
1376 break;
1377 }
1378
1379 default:
1380 printf("scsi_low: non support func_code = %d ",
1381 ccb->ccb_h.func_code);
1382 ccb->ccb_h.status = CAM_REQ_INVALID;
1383 xpt_done(ccb);
1384 break;
1385 }
1386}
1387
1388static int
1389scsi_low_attach_cam(slp)
1390 struct scsi_low_softc *slp;
1391{
1392 struct cam_devq *devq;
1393 int tagged_openings;
1394
1395 sprintf(slp->sl_xname, "%s%d",
1396 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1397
1398 devq = cam_simq_alloc(SCSI_LOW_NCCB);
1399 if (devq == NULL)
1400 return (ENOMEM);
1401
1402 /*
1403 * ask the adapter what subunits are present
1404 */
1405 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1406 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1407 scsi_low_poll_cam,
1408 DEVPORT_DEVNAME(slp->sl_dev), slp,
1409 DEVPORT_DEVUNIT(slp->sl_dev),
1410 slp->sl_openings, tagged_openings, devq);
1411
1412 if (slp->sl_si.sim == NULL) {
1413 cam_simq_free(devq);
1414 return ENODEV;
1415 }
1416
1417 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1415 free(slp->sl_si.sim, M_DEVBUF);
1418 free(slp->sl_si.sim, M_SCSILOW);
1419 return ENODEV;
1420 }
1421
1422 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1423 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1424 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1425 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1426 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1427 return ENODEV;
1428 }
1429
1430 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
1431 return 0;
1432}
1433
1434static int
1435scsi_low_world_start_cam(slp)
1436 struct scsi_low_softc *slp;
1437{
1438
1439 if (!cold)
1440 scsi_low_rescan_bus_cam(slp);
1441 return 0;
1442}
1443
1444static int
1445scsi_low_dettach_cam(slp)
1446 struct scsi_low_softc *slp;
1447{
1448
1449 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1450 xpt_free_path(slp->sl_si.path);
1451 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1452 cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1453 return 0;
1454}
1455
1456static int
1457scsi_low_ccb_setup_cam(slp, cb)
1458 struct scsi_low_softc *slp;
1459 struct slccb *cb;
1460{
1461 union ccb *ccb = (union ccb *) cb->osdep;
1462
1463 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1464 {
1465 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1466 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1467 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1468 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1469 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1470 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1471 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1472 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1473 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1474 }
1475 else
1476 {
1477 scsi_low_unit_ready_cmd(cb);
1478 }
1479 return SCSI_LOW_START_QTAG;
1480}
1481
1482static int
1483scsi_low_done_cam(slp, cb)
1484 struct scsi_low_softc *slp;
1485 struct slccb *cb;
1486{
1487 union ccb *ccb;
1488
1489 ccb = (union ccb *) cb->osdep;
1490 if (cb->ccb_error == 0)
1491 {
1492 ccb->ccb_h.status = CAM_REQ_CMP;
1493 ccb->csio.resid = 0;
1494 }
1495 else
1496 {
1497 if (cb->ccb_rcnt >= slp->sl_max_retry)
1498 cb->ccb_error |= ABORTIO;
1499
1500 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1501 (cb->ccb_error & ABORTIO) == 0)
1502 return EJUSTRETURN;
1503
1504 if ((cb->ccb_error & SENSEIO) != 0)
1505 {
1506 memcpy(&ccb->csio.sense_data,
1507 &cb->ccb_sense,
1508 sizeof(ccb->csio.sense_data));
1509 }
1510
1511 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1512 &scsi_low_error_code_cam[0]);
1513
1514#ifdef SCSI_LOW_DIAGNOSTIC
1515 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1516 cb->ccb_scp.scp_cmdlen > 0 &&
1517 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1518 SCSI_LOW_CMD_ABORT_WARNING) != 0)
1519 {
1520 printf("%s: WARNING: scsi_low IO abort\n",
1521 slp->sl_xname);
1522 scsi_low_print(slp, NULL);
1523 }
1524#endif /* SCSI_LOW_DIAGNOSTIC */
1525 }
1526
1527 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1528 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1529
1530 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1531 ccb->csio.scsi_status = 0; /* XXX */
1532 else
1533 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1534
1535 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1536 xpt_done(ccb);
1537 return 0;
1538}
1539
1540static void
1541scsi_low_timeout_cam(slp, ch, action)
1542 struct scsi_low_softc *slp;
1543 int ch;
1544 int action;
1545{
1546
1547 switch (ch)
1548 {
1549 case SCSI_LOW_TIMEOUT_CH_IO:
1550 switch (action)
1551 {
1552 case SCSI_LOW_TIMEOUT_START:
1553 slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1554 hz / SCSI_LOW_TIMEOUT_HZ);
1555 break;
1556 case SCSI_LOW_TIMEOUT_STOP:
1557 untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1558 break;
1559 }
1560 break;
1561
1562 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1563 switch (action)
1564 {
1565 case SCSI_LOW_TIMEOUT_START:
1566 slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1567 break;
1568 case SCSI_LOW_TIMEOUT_STOP:
1569 untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1570 break;
1571 }
1572 break;
1573 case SCSI_LOW_TIMEOUT_CH_RECOVER:
1574 break;
1575 }
1576}
1577
1578#endif /* SCSI_LOW_INTERFACE_CAM */
1579
1580/*=============================================================
1581 * END OF OS switch (All OS depend fucntions should be above)
1582 =============================================================*/
1583
1584/**************************************************************
1585 * scsi low deactivate and activate
1586 **************************************************************/
1587int
1588scsi_low_is_busy(slp)
1589 struct scsi_low_softc *slp;
1590{
1591
1592 if (slp->sl_nio > 0)
1593 return EBUSY;
1594 return 0;
1595}
1596
1597int
1598scsi_low_deactivate(slp)
1599 struct scsi_low_softc *slp;
1600{
1601 int s;
1602
1603 s = SCSI_LOW_SPLSCSI();
1604 slp->sl_flags |= HW_INACTIVE;
1605 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1606 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1607 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1608 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1609 splx(s);
1610 return 0;
1611}
1612
1613int
1614scsi_low_activate(slp)
1615 struct scsi_low_softc *slp;
1616{
1617 int error, s;
1618
1619 s = SCSI_LOW_SPLSCSI();
1620 slp->sl_flags &= ~HW_INACTIVE;
1621 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1622 {
1623 slp->sl_flags |= HW_INACTIVE;
1624 splx(s);
1625 return error;
1626 }
1627
1628 slp->sl_timeout_count = 0;
1629 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1630 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1631 splx(s);
1632 return 0;
1633}
1634
1635/**************************************************************
1636 * scsi low log
1637 **************************************************************/
1638#ifdef SCSI_LOW_DIAGNOSTIC
1639static void scsi_low_msg_log_init(struct scsi_low_msg_log *);
1640static void scsi_low_msg_log_write(struct scsi_low_msg_log *, u_int8_t *, int);
1641static void scsi_low_msg_log_show(struct scsi_low_msg_log *, char *, int);
1642
1643static void
1644scsi_low_msg_log_init(slmlp)
1645 struct scsi_low_msg_log *slmlp;
1646{
1647
1648 slmlp->slml_ptr = 0;
1649}
1650
1651static void
1652scsi_low_msg_log_write(slmlp, datap, len)
1653 struct scsi_low_msg_log *slmlp;
1654 u_int8_t *datap;
1655 int len;
1656{
1657 int ptr, ind;
1658
1659 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1660 return;
1661
1662 ptr = slmlp->slml_ptr ++;
1663 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1664 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1665 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1666 slmlp->slml_msg[ptr].msg[ind] = 0;
1667}
1668
1669static void
1670scsi_low_msg_log_show(slmlp, s, len)
1671 struct scsi_low_msg_log *slmlp;
1672 char *s;
1673 int len;
1674{
1675 int ptr, ind;
1676
1677 printf("%s: (%d) ", s, slmlp->slml_ptr);
1678 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1679 {
1680 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1681 ind ++)
1682 {
1683 printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1684 }
1685 printf(">");
1686 }
1687 printf("\n");
1688}
1689#endif /* SCSI_LOW_DIAGNOSTIC */
1690
1691/**************************************************************
1692 * power control
1693 **************************************************************/
1694static void
1695scsi_low_engage(arg)
1696 void *arg;
1697{
1698 struct scsi_low_softc *slp = arg;
1699 int s = SCSI_LOW_SPLSCSI();
1700
1701 switch (slp->sl_rstep)
1702 {
1703 case 0:
1704 slp->sl_rstep ++;
1705 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1706 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1707 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1708 break;
1709
1710 case 1:
1711 slp->sl_rstep ++;
1712 slp->sl_flags &= ~HW_RESUME;
1713 scsi_low_start(slp);
1714 break;
1715
1716 case 2:
1717 break;
1718 }
1719 splx(s);
1720}
1721
1722static int
1723scsi_low_init(slp, flags)
1724 struct scsi_low_softc *slp;
1725 u_int flags;
1726{
1727 int rv = 0;
1728
1729 slp->sl_flags |= HW_INITIALIZING;
1730
1731 /* clear power control timeout */
1732 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1733 {
1734 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1735 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1736 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1737 slp->sl_active = 1;
1738 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1739 }
1740
1741 /* reset current nexus */
1742 scsi_low_reset_nexus(slp, flags);
1743 if ((slp->sl_flags & HW_INACTIVE) != 0)
1744 {
1745 rv = EBUSY;
1746 goto out;
1747 }
1748
1749 if (flags != SCSI_LOW_RESTART_SOFT)
1750 {
1751 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1752 }
1753
1754out:
1755 slp->sl_flags &= ~HW_INITIALIZING;
1756 return rv;
1757}
1758
1759/**************************************************************
1760 * allocate lun_info
1761 **************************************************************/
1762static struct lun_info *
1763scsi_low_alloc_li(ti, lun, alloc)
1764 struct targ_info *ti;
1765 int lun;
1766 int alloc;
1767{
1768 struct scsi_low_softc *slp = ti->ti_sc;
1769 struct lun_info *li;
1770
1771 li = LIST_FIRST(&ti->ti_litab);
1772 if (li != NULL)
1773 {
1774 if (li->li_lun == lun)
1775 return li;
1776
1777 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1778 {
1779 if (li->li_lun == lun)
1780 {
1781 LIST_REMOVE(li, lun_chain);
1782 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1783 return li;
1784 }
1785 }
1786 }
1787
1788 if (alloc == 0)
1789 return li;
1790
1791 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1792 if (li == NULL)
1793 panic("no lun info mem");
1794
1795 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1796 li->li_lun = lun;
1797 li->li_ti = ti;
1798
1799 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1800 SCSI_LOW_QTAG;
1801 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1802 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1803#ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1804 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1805#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1806
1807 li->li_qtagbits = (u_int) -1;
1808
1809 TAILQ_INIT(&li->li_discq);
1810 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1811
1812 /* host specific structure initialization per lun */
1813 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1814 (*slp->sl_funcs->scsi_low_lun_init)
1815 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1816 scsi_low_calcf_lun(li);
1817 return li;
1818}
1819
1820/**************************************************************
1821 * allocate targ_info
1822 **************************************************************/
1823static struct targ_info *
1824scsi_low_alloc_ti(slp, targ)
1825 struct scsi_low_softc *slp;
1826 int targ;
1827{
1828 struct targ_info *ti;
1829
1830 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1831 TAILQ_INIT(&slp->sl_titab);
1832
1833 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1834 if (ti == NULL)
1835 panic("%s short of memory", slp->sl_xname);
1836
1837 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1838 ti->ti_id = targ;
1839 ti->ti_sc = slp;
1840
1841 slp->sl_ti[targ] = ti;
1842 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1843 LIST_INIT(&ti->ti_litab);
1844
1845 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1846 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1847 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1848#ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1849 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1850#endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1851
1852 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1853 {
1854 (*slp->sl_funcs->scsi_low_targ_init)
1855 (slp, ti, SCSI_LOW_INFO_ALLOC);
1856 }
1857 scsi_low_calcf_target(ti);
1858 return ti;
1859}
1860
1861static void
1862scsi_low_free_ti(slp)
1863 struct scsi_low_softc *slp;
1864{
1865 struct targ_info *ti, *tib;
1866 struct lun_info *li, *nli;
1867
1868 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1869 {
1870 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1871 {
1872 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1873 {
1874 (*slp->sl_funcs->scsi_low_lun_init)
1875 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1876 }
1877 nli = LIST_NEXT(li, lun_chain);
1878 SCSI_LOW_FREE(li);
1879 }
1880
1881 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1882 {
1883 (*slp->sl_funcs->scsi_low_targ_init)
1884 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1885 }
1886 tib = TAILQ_NEXT(ti, ti_chain);
1887 SCSI_LOW_FREE(ti);
1888 }
1889}
1890
1891/**************************************************************
1892 * timeout
1893 **************************************************************/
1894void
1895scsi_low_bus_idle(slp)
1896 struct scsi_low_softc *slp;
1897{
1898
1899 slp->sl_retry_sel = 0;
1900 if (slp->sl_Tnexus == NULL)
1901 scsi_low_start(slp);
1902}
1903
1904static void
1905scsi_low_timeout(arg)
1906 void *arg;
1907{
1908 struct scsi_low_softc *slp = arg;
1909 int s;
1910
1911 s = SCSI_LOW_SPLSCSI();
1912 (void) scsi_low_timeout_check(slp);
1913 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1914 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1915 splx(s);
1916}
1917
1918static int
1919scsi_low_timeout_check(slp)
1920 struct scsi_low_softc *slp;
1921{
1922 struct targ_info *ti;
1923 struct lun_info *li;
1924 struct slccb *cb = NULL; /* XXX */
1925
1926 /* selection restart */
1927 if (slp->sl_retry_sel != 0)
1928 {
1929 slp->sl_retry_sel = 0;
1930 if (slp->sl_Tnexus != NULL)
1931 goto step1;
1932
1933 cb = TAILQ_FIRST(&slp->sl_start);
1934 if (cb == NULL)
1935 goto step1;
1936
1937 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1938 {
1939 cb->ccb_flags |= CCB_NORETRY;
1940 cb->ccb_error |= SELTIMEOUTIO;
1941 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1942 panic("%s: ccb not finished", slp->sl_xname);
1943 }
1944
1945 if (slp->sl_Tnexus == NULL)
1946 scsi_low_start(slp);
1947 }
1948
1949 /* call hardware timeout */
1950step1:
1951 if (slp->sl_funcs->scsi_low_timeout != NULL)
1952 {
1953 (*slp->sl_funcs->scsi_low_timeout) (slp);
1954 }
1955
1956 if (slp->sl_timeout_count ++ <
1957 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1958 return 0;
1959
1960 slp->sl_timeout_count = 0;
1961 if (slp->sl_nio > 0)
1962 {
1963 if ((cb = slp->sl_Qnexus) != NULL)
1964 {
1965 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1966 if (cb->ccb_tc < 0)
1967 goto bus_reset;
1968 }
1969 else if (slp->sl_disc == 0)
1970 {
1971 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1972 return 0;
1973
1974 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1975 if (cb->ccb_tc < 0)
1976 goto bus_reset;
1977 }
1978 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1979 ti = TAILQ_NEXT(ti, ti_chain))
1980 {
1981 if (ti->ti_disc == 0)
1982 continue;
1983
1984 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1985 li = LIST_NEXT(li, lun_chain))
1986 {
1987 for (cb = TAILQ_FIRST(&li->li_discq);
1988 cb != NULL;
1989 cb = TAILQ_NEXT(cb, ccb_chain))
1990 {
1991 cb->ccb_tc -=
1992 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1993 if (cb->ccb_tc < 0)
1994 goto bus_reset;
1995 }
1996 }
1997 }
1998
1999 }
2000 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
2001 {
2002 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2003 return 0;
2004
2005 if (slp->sl_active != 0)
2006 {
2007 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2008 slp->sl_active = 0;
2009 return 0;
2010 }
2011
2012 slp->sl_powc --;
2013 if (slp->sl_powc < 0)
2014 {
2015 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2016 slp->sl_flags |= HW_POWDOWN;
2017 (*slp->sl_funcs->scsi_low_power)
2018 (slp, SCSI_LOW_POWDOWN);
2019 }
2020 }
2021 return 0;
2022
2023bus_reset:
2024 cb->ccb_error |= TIMEOUTIO;
2025 printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2026 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2027 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2028 scsi_low_start(slp);
2029 return ERESTART;
2030}
2031
2032
2033static int
2034scsi_low_abort_ccb(slp, cb)
2035 struct scsi_low_softc *slp;
2036 struct slccb *cb;
2037{
2038 struct targ_info *ti;
2039 struct lun_info *li;
2040 u_int msg;
2041
2042 if (cb == NULL)
2043 return EINVAL;
2044 if ((cb->ccb_omsgoutflag &
2045 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2046 return EBUSY;
2047
2048 ti = cb->ti;
2049 li = cb->li;
2050 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2051 msg = SCSI_LOW_MSG_ABORT;
2052 else
2053 msg = SCSI_LOW_MSG_ABORT_QTAG;
2054
2055 cb->ccb_error |= ABORTIO;
2056 cb->ccb_flags |= CCB_NORETRY;
2057 scsi_low_ccb_message_assert(cb, msg);
2058
2059 if (cb == slp->sl_Qnexus)
2060 {
2061 scsi_low_assert_msg(slp, ti, msg, 1);
2062 }
2063 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2064 {
2065 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2066 panic("%s: revoked ccb done", slp->sl_xname);
2067
2068 cb->ccb_flags |= CCB_STARTQ;
2069 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2070
2071 if (slp->sl_Tnexus == NULL)
2072 scsi_low_start(slp);
2073 }
2074 else
2075 {
2076 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2077 panic("%s: revoked ccb retried", slp->sl_xname);
2078 }
2079 return 0;
2080}
2081
2082/**************************************************************
2083 * Generic SCSI INTERFACE
2084 **************************************************************/
2085int
2086scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2087 struct scsi_low_softc *slp;
2088 int openings, ntargs, nluns, targsize, lunsize;
2089{
2090 struct targ_info *ti;
2091 struct lun_info *li;
2092 int s, i, nccb, rv;
2093
2094#ifdef SCSI_LOW_INTERFACE_XS
2095 slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2096#endif /* SCSI_LOW_INTERFACE_XS */
2097#ifdef SCSI_LOW_INTERFACE_CAM
2098 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2099#endif /* SCSI_LOW_INTERFACE_CAM */
2100
2101 if (slp->sl_osdep_fp == NULL)
2102 panic("scsi_low: interface not spcified");
2103
2104 if (ntargs > SCSI_LOW_NTARGETS)
2105 {
2106 printf("scsi_low: %d targets are too large\n", ntargs);
2107 printf("change kernel options SCSI_LOW_NTARGETS");
2108 return EINVAL;
2109 }
2110
2111 if (openings <= 0)
2112 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2113 else
2114 slp->sl_openings = openings;
2115 slp->sl_ntargs = ntargs;
2116 slp->sl_nluns = nluns;
2117 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2118
2119 if (lunsize < sizeof(struct lun_info))
2120 lunsize = sizeof(struct lun_info);
2121
2122 if (targsize < sizeof(struct targ_info))
2123 targsize = sizeof(struct targ_info);
2124
2125 slp->sl_targsize = targsize;
2126 for (i = 0; i < ntargs; i ++)
2127 {
2128 ti = scsi_low_alloc_ti(slp, i);
2129 ti->ti_lunsize = lunsize;
2130 li = scsi_low_alloc_li(ti, 0, 1);
2131 }
2132
2133 /* initialize queue */
2134 nccb = openings * ntargs;
2135 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2136 nccb = SCSI_LOW_NCCB;
2137 scsi_low_init_ccbque(nccb);
2138 TAILQ_INIT(&slp->sl_start);
2139
2140 /* call os depend attach */
2141 s = SCSI_LOW_SPLSCSI();
2142 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2143 if (rv != 0)
2144 {
2145 splx(s);
2146 printf("%s: scsi_low_attach: osdep attach failed\n",
2147 slp->sl_xname);
2148 return EINVAL;
2149 }
2150
2151 /* check hardware */
2152 SCSI_LOW_DELAY(1000); /* wait for 1ms */
2153 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2154 {
2155 splx(s);
2156 printf("%s: scsi_low_attach: initialization failed\n",
2157 slp->sl_xname);
2158 return EINVAL;
2159 }
2160
2161 /* start watch dog */
2162 slp->sl_timeout_count = 0;
2163 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2164 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2165 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2166
2167 /* fake call */
2168 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2169
2170#ifdef SCSI_LOW_START_UP_CHECK
2171 /* probing devices */
2172 scsi_low_start_up(slp);
2173#endif /* SCSI_LOW_START_UP_CHECK */
2174
2175 /* call os depend attach done*/
2176 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2177 splx(s);
2178 return 0;
2179}
2180
2181int
2182scsi_low_dettach(slp)
2183 struct scsi_low_softc *slp;
2184{
2185 int s, rv;
2186
2187 s = SCSI_LOW_SPLSCSI();
2188 if (scsi_low_is_busy(slp) != 0)
2189 {
2190 splx(s);
2191 return EBUSY;
2192 }
2193
2194 scsi_low_deactivate(slp);
2195
2196 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2197 if (rv != 0)
2198 {
2199 splx(s);
2200 return EBUSY;
2201 }
2202
2203 scsi_low_free_ti(slp);
2204 LIST_REMOVE(slp, sl_chain);
2205 splx(s);
2206 return 0;
2207}
2208
2209/**************************************************************
2210 * Generic enqueue
2211 **************************************************************/
2212static int
2213scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2214 struct scsi_low_softc *slp;
2215 struct targ_info *ti;
2216 struct lun_info *li;
2217 struct slccb *cb;
2218 u_int flags, msg;
2219{
2220
2221 cb->ti = ti;
2222 cb->li = li;
2223
2224 scsi_low_ccb_message_assert(cb, msg);
2225
2226 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2227 scsi_low_alloc_qtag(cb);
2228
2229 cb->ccb_flags = flags | CCB_STARTQ;
2230 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2231 cb->ccb_error |= PENDINGIO;
2232
2233 if ((flags & CCB_URGENT) != 0)
2234 {
2235 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2236 }
2237 else
2238 {
2239 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2240 }
2241
2242 slp->sl_nio ++;
2243
2244 if (slp->sl_Tnexus == NULL)
2245 scsi_low_start(slp);
2246 return 0;
2247}
2248
2249static int
2250scsi_low_message_enqueue(slp, ti, li, flags)
2251 struct scsi_low_softc *slp;
2252 struct targ_info *ti;
2253 struct lun_info *li;
2254 u_int flags;
2255{
2256 struct slccb *cb;
2257 u_int tmsgflags;
2258
2259 tmsgflags = ti->ti_setup_msg;
2260 ti->ti_setup_msg = 0;
2261
2262 flags |= CCB_NORETRY;
2263 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2264 return ENOMEM;
2265
2266 cb->osdep = NULL;
2267 cb->bp = NULL;
2268 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2269 return 0;
2270}
2271
2272/**************************************************************
2273 * Generic Start & Done
2274 **************************************************************/
2275#define SLSC_MODE_SENSE_SHORT 0x1a
2276static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
2277static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
2278 sizeof(struct scsi_low_mode_sense_data), 0};
2279static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
2280 sizeof(struct scsi_low_inq_data), 0};
2281static u_int8_t unit_ready_cmd[6];
2282static int scsi_low_setup_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2283static int scsi_low_sense_abort_start(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2284static int scsi_low_resume(struct scsi_low_softc *);
2285
2286static void
2287scsi_low_unit_ready_cmd(cb)
2288 struct slccb *cb;
2289{
2290
2291 cb->ccb_scp.scp_cmd = unit_ready_cmd;
2292 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2293 cb->ccb_scp.scp_datalen = 0;
2294 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2295 cb->ccb_tcmax = 15;
2296}
2297
2298static int
2299scsi_low_sense_abort_start(slp, ti, li, cb)
2300 struct scsi_low_softc *slp;
2301 struct targ_info *ti;
2302 struct lun_info *li;
2303 struct slccb *cb;
2304{
2305
2306 cb->ccb_scp.scp_cmdlen = 6;
2307 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2308 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2309 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2310 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2311 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2312 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2313 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2314 cb->ccb_tcmax = 15;
2315 scsi_low_ccb_message_clear(cb);
2316 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2317 {
2318 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2319 }
2320 else
2321 {
2322 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2323#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2324 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2325#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2326 }
2327
2328 return SCSI_LOW_START_NO_QTAG;
2329}
2330
2331static int
2332scsi_low_setup_start(slp, ti, li, cb)
2333 struct scsi_low_softc *slp;
2334 struct targ_info *ti;
2335 struct lun_info *li;
2336 struct slccb *cb;
2337{
2338
2339 switch(li->li_state)
2340 {
2341 case SCSI_LOW_LUN_SLEEP:
2342 scsi_low_unit_ready_cmd(cb);
2343 break;
2344
2345 case SCSI_LOW_LUN_START:
2346 cb->ccb_scp.scp_cmd = ss_cmd;
2347 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2348 cb->ccb_scp.scp_datalen = 0;
2349 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2350 cb->ccb_tcmax = 30;
2351 break;
2352
2353 case SCSI_LOW_LUN_INQ:
2354 cb->ccb_scp.scp_cmd = inq_cmd;
2355 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2356 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2357 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2358 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2359 cb->ccb_tcmax = 15;
2360 break;
2361
2362 case SCSI_LOW_LUN_MODEQ:
2363 cb->ccb_scp.scp_cmd = sms_cmd;
2364 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2365 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2366 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2367 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2368 cb->ccb_tcmax = 15;
2369 return SCSI_LOW_START_QTAG;
2370
2371 default:
2372 panic("%s: no setup phase", slp->sl_xname);
2373 }
2374
2375 return SCSI_LOW_START_NO_QTAG;
2376}
2377
2378static int
2379scsi_low_resume(slp)
2380 struct scsi_low_softc *slp;
2381{
2382
2383 if (slp->sl_flags & HW_RESUME)
2384 return EJUSTRETURN;
2385 slp->sl_flags &= ~HW_POWDOWN;
2386 if (slp->sl_funcs->scsi_low_power != NULL)
2387 {
2388 slp->sl_flags |= HW_RESUME;
2389 slp->sl_rstep = 0;
2390 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2391 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2392 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2393 SCSI_LOW_TIMEOUT_START);
2394 return EJUSTRETURN;
2395 }
2396 return 0;
2397}
2398
2399static void
2400scsi_low_start(slp)
2401 struct scsi_low_softc *slp;
2402{
2403 struct targ_info *ti;
2404 struct lun_info *li;
2405 struct slccb *cb;
2406 int rv;
2407
2408 /* check hardware exists or under initializations ? */
2409 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2410 return;
2411
2412 /* check hardware power up ? */
2413 if ((slp->sl_flags & HW_POWERCTRL) != 0)
2414 {
2415 slp->sl_active ++;
2416 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2417 {
2418 if (scsi_low_resume(slp) == EJUSTRETURN)
2419 return;
2420 }
2421 }
2422
2423 /* setup nexus */
2424#ifdef SCSI_LOW_DIAGNOSTIC
2425 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2426 {
2427 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2428 panic("%s: inconsistent", slp->sl_xname);
2429 }
2430#endif /* SCSI_LOW_DIAGNOSTIC */
2431
2432 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2433 cb = TAILQ_NEXT(cb, ccb_chain))
2434 {
2435 li = cb->li;
2436
2437 if (li->li_disc == 0)
2438 {
2439 goto scsi_low_cmd_start;
2440 }
2441 else if (li->li_nqio > 0)
2442 {
2443 if (li->li_nqio < li->li_maxnqio ||
2444 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2445 goto scsi_low_cmd_start;
2446 }
2447 }
2448 return;
2449
2450scsi_low_cmd_start:
2451 cb->ccb_flags &= ~CCB_STARTQ;
2452 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2453 ti = cb->ti;
2454
2455 /* clear all error flag bits (for restart) */
2456 cb->ccb_error = 0;
2457 cb->ccb_datalen = -1;
2458 cb->ccb_scp.scp_status = ST_UNKNOWN;
2459
2460 /* setup nexus pointer */
2461 slp->sl_Qnexus = cb;
2462 slp->sl_Lnexus = li;
2463 slp->sl_Tnexus = ti;
2464
2465 /* initialize msgsys */
2466 scsi_low_init_msgsys(slp, ti);
2467
2468 /* exec cmd */
2469 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2470 {
2471 /* CA state or forced abort */
2472 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2473 }
2474 else if (li->li_state >= SCSI_LOW_LUN_OK)
2475 {
2476 cb->ccb_flags &= ~CCB_INTERNAL;
2477 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2478 if (cb->ccb_msgoutflag != 0)
2479 {
2480 scsi_low_ccb_message_exec(slp, cb);
2481 }
2482 }
2483 else
2484 {
2485 cb->ccb_flags |= CCB_INTERNAL;
2486 rv = scsi_low_setup_start(slp, ti, li, cb);
2487 }
2488
2489 /* allocate qtag */
2490#define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2491
2492 if (rv == SCSI_LOW_START_QTAG &&
2493 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2494 li->li_maxnqio > 0)
2495 {
2496 u_int qmsg;
2497
2498 scsi_low_activate_qtag(cb);
2499 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2500 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2501 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2502 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2503 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2504 else
2505 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2506 scsi_low_assert_msg(slp, ti, qmsg, 0);
2507 }
2508
2509 /* timeout */
2510 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2511 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2512 cb->ccb_tc = cb->ccb_tcmax;
2513
2514 /* setup saved scsi data pointer */
2515 cb->ccb_sscp = cb->ccb_scp;
2516
2517 /* setup current scsi pointer */
2518 slp->sl_scp = cb->ccb_sscp;
2519 slp->sl_error = cb->ccb_error;
2520
2521 /* assert always an identify msg */
2522 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2523
2524 /* debug section */
2525#ifdef SCSI_LOW_DIAGNOSTIC
2526 scsi_low_msg_log_init(&ti->ti_log_msgin);
2527 scsi_low_msg_log_init(&ti->ti_log_msgout);
2528#endif /* SCSI_LOW_DIAGNOSTIC */
2529
2530 /* selection start */
2531 slp->sl_selid = cb;
2532 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2533 if (rv == SCSI_LOW_START_OK)
2534 {
2535#ifdef SCSI_LOW_STATICS
2536 scsi_low_statics.nexus_win ++;
2537#endif /* SCSI_LOW_STATICS */
2538 return;
2539 }
2540
2541 scsi_low_arbit_fail(slp, cb);
2542#ifdef SCSI_LOW_STATICS
2543 scsi_low_statics.nexus_fail ++;
2544#endif /* SCSI_LOW_STATICS */
2545}
2546
2547void
2548scsi_low_arbit_fail(slp, cb)
2549 struct scsi_low_softc *slp;
2550 struct slccb *cb;
2551{
2552 struct targ_info *ti = cb->ti;
2553
2554 scsi_low_deactivate_qtag(cb);
2555 scsi_low_ccb_message_retry(cb);
2556 cb->ccb_flags |= CCB_STARTQ;
2557 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2558
2559 scsi_low_bus_release(slp, ti);
2560
2561 cb->ccb_selrcnt ++;
2562 if (slp->sl_disc == 0)
2563 {
2564#ifdef SCSI_LOW_DIAGNOSTIC
2565 printf("%s: try selection again\n", slp->sl_xname);
2566#endif /* SCSI_LOW_DIAGNOSTIC */
2567 slp->sl_retry_sel = 1;
2568 }
2569}
2570
2571static void
2572scsi_low_bus_release(slp, ti)
2573 struct scsi_low_softc *slp;
2574 struct targ_info *ti;
2575{
2576
2577 if (ti->ti_disc > 0)
2578 {
2579 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2580 }
2581 else
2582 {
2583 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2584 }
2585
2586 /* clear all nexus pointer */
2587 slp->sl_Qnexus = NULL;
2588 slp->sl_Lnexus = NULL;
2589 slp->sl_Tnexus = NULL;
2590
2591 /* clear selection assert */
2592 slp->sl_selid = NULL;
2593
2594 /* clear nexus data */
2595 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2596
2597 /* clear phase change counter */
2598 slp->sl_ph_count = 0;
2599}
2600
2601static int
2602scsi_low_setup_done(slp, cb)
2603 struct scsi_low_softc *slp;
2604 struct slccb *cb;
2605{
2606 struct targ_info *ti;
2607 struct lun_info *li;
2608
2609 ti = cb->ti;
2610 li = cb->li;
2611
2612 if (cb->ccb_rcnt >= slp->sl_max_retry)
2613 {
2614 cb->ccb_error |= ABORTIO;
2615 return SCSI_LOW_DONE_COMPLETE;
2616 }
2617
2618 /* XXX: special huck for selection timeout */
2619 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2620 (cb->ccb_error & SELTIMEOUTIO) != 0)
2621 {
2622 cb->ccb_error |= ABORTIO;
2623 return SCSI_LOW_DONE_COMPLETE;
2624 }
2625
2626 switch(li->li_state)
2627 {
2628 case SCSI_LOW_LUN_INQ:
2629 if (cb->ccb_error != 0)
2630 {
2631 li->li_diskflags &=
2632 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2633 if (li->li_lun > 0)
2634 goto resume;
2635 ti->ti_diskflags &=
2636 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2637 }
2638 else if ((li->li_inq.sd_version & 7) >= 2 ||
2639 (li->li_inq.sd_len >= 4))
2640 {
2641 if ((li->li_inq.sd_support & 0x2) == 0)
2642 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2643 if ((li->li_inq.sd_support & 0x8) == 0)
2644 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2645 if (li->li_lun > 0)
2646 goto resume;
2647 if ((li->li_inq.sd_support & 0x10) == 0)
2648 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2649 if ((li->li_inq.sd_support & 0x20) == 0)
2650 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2651 if ((li->li_inq.sd_support & 0x40) == 0)
2652 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2653 }
2654 else
2655 {
2656 li->li_diskflags &=
2657 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2658 if (li->li_lun > 0)
2659 goto resume;
2660 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2661 }
2662 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2663resume:
2664 scsi_low_calcf_target(ti);
2665 scsi_low_calcf_lun(li);
2666 break;
2667
2668 case SCSI_LOW_LUN_MODEQ:
2669 if (cb->ccb_error != 0)
2670 {
2671 if (cb->ccb_error & SENSEIO)
2672 {
2673#ifdef SCSI_LOW_DEBUG
2674 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2675 {
2676 printf("SENSE: [%x][%x][%x][%x][%x]\n",
2677 (u_int) cb->ccb_sense.error_code,
2678 (u_int) cb->ccb_sense.segment,
2679 (u_int) cb->ccb_sense.flags,
2680 (u_int) cb->ccb_sense.add_sense_code,
2681 (u_int) cb->ccb_sense.add_sense_code_qual);
2682 }
2683#endif /* SCSI_LOW_DEBUG */
2684 }
2685 else
2686 {
2687 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2688 }
2689 }
2690 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2691 {
2692 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2693 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2694 else
2695 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2696 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2697 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2698 }
2699 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2700 scsi_low_calcf_lun(li);
2701 break;
2702
2703 default:
2704 break;
2705 }
2706
2707 li->li_state ++;
2708 if (li->li_state == SCSI_LOW_LUN_OK)
2709 {
2710 scsi_low_calcf_target(ti);
2711 scsi_low_calcf_lun(li);
2712 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2713 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2714 {
2715 scsi_low_calcf_show(li);
2716 }
2717 }
2718
2719 cb->ccb_rcnt --;
2720 return SCSI_LOW_DONE_RETRY;
2721}
2722
2723static int
2724scsi_low_done(slp, cb)
2725 struct scsi_low_softc *slp;
2726 struct slccb *cb;
2727{
2728 int rv;
2729
2730 if (cb->ccb_error == 0)
2731 {
2732 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2733 {
2734#ifdef SCSI_LOW_QCLEAR_AFTER_CA
2735 /* XXX:
2736 * SCSI-2 draft suggests
2737 * page 0x0a QErr bit determins if
2738 * the target aborts or continues
2739 * the queueing io's after CA state resolved.
2740 * However many targets seem not to support
2741 * the page 0x0a. Thus we should manually clear the
2742 * queuing io's after CA state.
2743 */
2744 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2745 {
2746 cb->ccb_rcnt --;
2747 cb->ccb_flags |= CCB_CLEARQ;
2748 goto retry;
2749 }
2750#endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2751
2752 if ((cb->ccb_flags & CCB_SENSE) != 0)
2753 cb->ccb_error |= (SENSEIO | ABORTIO);
2754 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2755 }
2756 else switch (cb->ccb_sscp.scp_status)
2757 {
2758 case ST_GOOD:
2759 case ST_MET:
2760 case ST_INTERGOOD:
2761 case ST_INTERMET:
2762 if (cb->ccb_datalen == 0 ||
2763 cb->ccb_scp.scp_datalen == 0)
2764 break;
2765
2766 if (cb->ccb_scp.scp_cmdlen > 0 &&
2767 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2768 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2769 break;
2770
2771 cb->ccb_error |= PDMAERR;
2772 break;
2773
2774 case ST_BUSY:
2775 case ST_QUEFULL:
2776 cb->ccb_error |= (BUSYERR | STATERR);
2777 break;
2778
2779 case ST_CONFLICT:
2780 cb->ccb_error |= (STATERR | ABORTIO);
2781 break;
2782
2783 case ST_CHKCOND:
2784 case ST_CMDTERM:
2785 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2786 {
2787 cb->ccb_rcnt --;
2788 cb->ccb_flags |= CCB_SENSE;
2789 goto retry;
2790 }
2791 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2792 break;
2793
2794 case ST_UNKNOWN:
2795 default:
2796 cb->ccb_error |= FATALIO;
2797 break;
2798 }
2799 }
2800 else
2801 {
2802 if (cb->ccb_flags & CCB_SENSE)
2803 {
2804 cb->ccb_error |= (SENSEERR | ABORTIO);
2805 }
2806 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2807 }
2808
2809 /* internal ccb */
2810 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2811 {
2812 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2813 goto retry;
2814 }
2815
2816 /* check a ccb msgout flag */
2817 if (cb->ccb_omsgoutflag != 0)
2818 {
2819#define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2820 SCSI_LOW_MSG_ABORT_QTAG | \
2821 SCSI_LOW_MSG_CLEAR_QTAG | \
2822 SCSI_LOW_MSG_TERMIO)
2823
2824 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2825 {
2826 cb->ccb_error |= ABORTIO;
2827 }
2828 }
2829
2830 /* call OS depend done */
2831 if (cb->osdep != NULL)
2832 {
2833 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2834 if (rv == EJUSTRETURN)
2835 goto retry;
2836 }
2837 else if (cb->ccb_error != 0)
2838 {
2839 if (cb->ccb_rcnt >= slp->sl_max_retry)
2840 cb->ccb_error |= ABORTIO;
2841
2842 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2843 (cb->ccb_error & ABORTIO) == 0)
2844 goto retry;
2845 }
2846
2847 /* free our target */
2848#ifdef SCSI_LOW_DEBUG
2849 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2850 {
2851 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2852 scsi_low_print(slp, NULL);
2853 }
2854#endif /* SCSI_LOW_DEBUG */
2855
2856 scsi_low_deactivate_qtag(cb);
2857 scsi_low_dealloc_qtag(cb);
2858 scsi_low_free_ccb(cb);
2859 slp->sl_nio --;
2860 return SCSI_LOW_DONE_COMPLETE;
2861
2862retry:
2863#ifdef SCSI_LOW_DEBUG
2864 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2865 {
2866 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2867 scsi_low_print(slp, NULL);
2868 }
2869#endif /* SCSI_LOW_DEBUG */
2870
2871 cb->ccb_rcnt ++;
2872 scsi_low_deactivate_qtag(cb);
2873 scsi_low_ccb_message_retry(cb);
2874 return SCSI_LOW_DONE_RETRY;
2875}
2876
2877/**************************************************************
2878 * Reset
2879 **************************************************************/
2880static void
2881scsi_low_reset_nexus_target(slp, ti, fdone)
2882 struct scsi_low_softc *slp;
2883 struct targ_info *ti;
2884 int fdone;
2885{
2886 struct lun_info *li;
2887
2888 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2889 li = LIST_NEXT(li, lun_chain))
2890 {
2891 scsi_low_reset_nexus_lun(slp, li, fdone);
2892 li->li_state = SCSI_LOW_LUN_SLEEP;
2893 li->li_maxnqio = 0;
2894 }
2895
2896 ti->ti_disc = 0;
2897 ti->ti_setup_msg = 0;
2898 ti->ti_setup_msg_done = 0;
2899
2900 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2901 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2902
2903 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2904 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2905
2906 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2907 {
2908 ((*slp->sl_funcs->scsi_low_targ_init)
2909 (slp, ti, SCSI_LOW_INFO_REVOKE));
2910 }
2911 scsi_low_calcf_target(ti);
2912
2913 for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2914 li = LIST_NEXT(li, lun_chain))
2915 {
2916 li->li_flags = 0;
2917
2918 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2919 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2920
2921 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2922 {
2923 ((*slp->sl_funcs->scsi_low_lun_init)
2924 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2925 }
2926 scsi_low_calcf_lun(li);
2927 }
2928}
2929
2930static void
2931scsi_low_reset_nexus(slp, fdone)
2932 struct scsi_low_softc *slp;
2933 int fdone;
2934{
2935 struct targ_info *ti;
2936 struct slccb *cb, *topcb;
2937
2938 if ((cb = slp->sl_Qnexus) != NULL)
2939 {
2940 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2941 }
2942 else
2943 {
2944 topcb = NULL;
2945 }
2946
2947 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2948 ti = TAILQ_NEXT(ti, ti_chain))
2949 {
2950 scsi_low_reset_nexus_target(slp, ti, fdone);
2951 scsi_low_bus_release(slp, ti);
2952 scsi_low_init_msgsys(slp, ti);
2953 }
2954
2955 if (topcb != NULL)
2956 {
2957 topcb->ccb_flags |= CCB_STARTQ;
2958 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2959 }
2960
2961 slp->sl_disc = 0;
2962 slp->sl_retry_sel = 0;
2963 slp->sl_flags &= ~HW_PDMASTART;
2964}
2965
2966/* misc */
2967static int tw_pos;
2968static char tw_chars[] = "|/-\\";
2969#define TWIDDLEWAIT 10000
2970
2971static void
2972scsi_low_twiddle_wait(void)
2973{
2974
2975 cnputc('\b');
2976 cnputc(tw_chars[tw_pos++]);
2977 tw_pos %= (sizeof(tw_chars) - 1);
2978 SCSI_LOW_DELAY(TWIDDLEWAIT);
2979}
2980
2981void
2982scsi_low_bus_reset(slp)
2983 struct scsi_low_softc *slp;
2984{
2985 int i;
2986
2987 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2988
2989 printf("%s: try to reset scsi bus ", slp->sl_xname);
2990 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2991 scsi_low_twiddle_wait();
2992 cnputc('\b');
2993 printf("\n");
2994}
2995
2996int
2997scsi_low_restart(slp, flags, s)
2998 struct scsi_low_softc *slp;
2999 int flags;
3000 u_char *s;
3001{
3002 int error;
3003
3004 if (s != NULL)
3005 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3006
3007 if ((error = scsi_low_init(slp, flags)) != 0)
3008 return error;
3009
3010 scsi_low_start(slp);
3011 return 0;
3012}
3013
3014/**************************************************************
3015 * disconnect and reselect
3016 **************************************************************/
3017#define MSGCMD_LUN(msg) (msg & 0x07)
3018
3019static struct slccb *
3020scsi_low_establish_ccb(ti, li, tag)
3021 struct targ_info *ti;
3022 struct lun_info *li;
3023 scsi_low_tag_t tag;
3024{
3025 struct scsi_low_softc *slp = ti->ti_sc;
3026 struct slccb *cb;
3027
3028 if (li == NULL)
3029 return NULL;
3030
3031 cb = TAILQ_FIRST(&li->li_discq);
3032 for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3033 if (cb->ccb_tag == tag)
3034 goto found;
3035 return cb;
3036
3037 /*
3038 * establish our ccb nexus
3039 */
3040found:
3041#ifdef SCSI_LOW_DEBUG
3042 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3043 {
3044 printf("%s: nexus(0x%lx) abort check start\n",
3045 slp->sl_xname, (u_long) cb);
3046 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3047 scsi_low_revoke_ccb(slp, cb, 1);
3048 return NULL;
3049 }
3050
3051 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3052 {
3053 if (cb->ccb_omsgoutflag == 0)
3054 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3055 }
3056#endif /* SCSI_LOW_DEBUG */
3057
3058 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3059 cb->ccb_flags &= ~CCB_DISCQ;
3060 slp->sl_Qnexus = cb;
3061
3062 slp->sl_scp = cb->ccb_sscp;
3063 slp->sl_error |= cb->ccb_error;
3064
3065 slp->sl_disc --;
3066 ti->ti_disc --;
3067 li->li_disc --;
3068
3069 /* inform "ccb nexus established" to the host driver */
3070 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3071
3072 /* check msg */
3073 if (cb->ccb_msgoutflag != 0)
3074 {
3075 scsi_low_ccb_message_exec(slp, cb);
3076 }
3077
3078 return cb;
3079}
3080
3081struct targ_info *
3082scsi_low_reselected(slp, targ)
3083 struct scsi_low_softc *slp;
3084 u_int targ;
3085{
3086 struct targ_info *ti;
3087 struct slccb *cb;
3088 u_char *s;
3089
3090 /*
3091 * Check select vs reselected collision.
3092 */
3093
3094 if ((cb = slp->sl_selid) != NULL)
3095 {
3096 scsi_low_arbit_fail(slp, cb);
3097#ifdef SCSI_LOW_STATICS
3098 scsi_low_statics.nexus_conflict ++;
3099#endif /* SCSI_LOW_STATICS */
3100 }
3101
3102 /*
3103 * Check if no current active nexus.
3104 */
3105 if (slp->sl_Tnexus != NULL)
3106 {
3107 s = "host busy";
3108 goto world_restart;
3109 }
3110
3111 /*
3112 * Check a valid target id asserted ?
3113 */
3114 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3115 {
3116 s = "scsi id illegal";
3117 goto world_restart;
3118 }
3119
3120 /*
3121 * Check the target scsi status.
3122 */
3123 ti = slp->sl_ti[targ];
3124 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3125 {
3126 s = "phase mismatch";
3127 goto world_restart;
3128 }
3129
3130 /*
3131 * Setup init msgsys
3132 */
3133 slp->sl_error = 0;
3134 scsi_low_init_msgsys(slp, ti);
3135
3136 /*
3137 * Establish our target nexus
3138 */
3139 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3140 slp->sl_Tnexus = ti;
3141#ifdef SCSI_LOW_STATICS
3142 scsi_low_statics.nexus_reselected ++;
3143#endif /* SCSI_LOW_STATICS */
3144 return ti;
3145
3146world_restart:
3147 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3148 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
3149 "reselect: scsi world confused");
3150 return NULL;
3151}
3152
3153/**************************************************************
3154 * cmd out pointer setup
3155 **************************************************************/
3156int
3157scsi_low_cmd(slp, ti)
3158 struct scsi_low_softc *slp;
3159 struct targ_info *ti;
3160{
3161 struct slccb *cb = slp->sl_Qnexus;
3162
3163 slp->sl_ph_count ++;
3164 if (cb == NULL)
3165 {
3166 /*
3167 * no ccb, abort!
3168 */
3169 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3170 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3171 slp->sl_scp.scp_datalen = 0;
3172 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3173 slp->sl_error |= FATALIO;
3174 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3175 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3176 return EINVAL;
3177 }
3178 else
3179 {
3180#ifdef SCSI_LOW_DEBUG
3181 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3182 {
3183 scsi_low_test_cmdlnk(slp, cb);
3184 }
3185#endif /* SCSI_LOW_DEBUG */
3186 }
3187 return 0;
3188}
3189
3190/**************************************************************
3191 * data out pointer setup
3192 **************************************************************/
3193int
3194scsi_low_data(slp, ti, bp, direction)
3195 struct scsi_low_softc *slp;
3196 struct targ_info *ti;
3197 struct buf **bp;
3198 int direction;
3199{
3200 struct slccb *cb = slp->sl_Qnexus;
3201
3202 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3203 {
3204 *bp = cb->bp;
3205 return 0;
3206 }
3207
3208 slp->sl_error |= (FATALIO | PDMAERR);
3209 slp->sl_scp.scp_datalen = 0;
3210 slp->sl_scp.scp_direction = direction;
3211 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3212 if (ti->ti_ophase != ti->ti_phase)
3213 {
3214 char *s;
3215
3216 if (cb == NULL)
3217 s = "DATA PHASE: ccb nexus not found";
3218 else
3219 s = "DATA PHASE: xfer direction mismatch";
3220 SCSI_LOW_INFO(slp, ti, s);
3221 }
3222
3223 *bp = NULL;
3224 return EINVAL;
3225}
3226
3227/**************************************************************
3228 * MSG_SYS
3229 **************************************************************/
3230#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3231#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3232#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3233#define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3234#define MSGIN_DATA_LAST 0x30
3235
3236static int scsi_low_errfunc_synch(struct scsi_low_softc *, u_int);
3237static int scsi_low_errfunc_wide(struct scsi_low_softc *, u_int);
3238static int scsi_low_errfunc_identify(struct scsi_low_softc *, u_int);
3239static int scsi_low_errfunc_qtag(struct scsi_low_softc *, u_int);
3240
3241static int scsi_low_msgfunc_synch(struct scsi_low_softc *);
3242static int scsi_low_msgfunc_wide(struct scsi_low_softc *);
3243static int scsi_low_msgfunc_identify(struct scsi_low_softc *);
3244static int scsi_low_msgfunc_abort(struct scsi_low_softc *);
3245static int scsi_low_msgfunc_qabort(struct scsi_low_softc *);
3246static int scsi_low_msgfunc_qtag(struct scsi_low_softc *);
3247static int scsi_low_msgfunc_reset(struct scsi_low_softc *);
3248
3249struct scsi_low_msgout_data {
3250 u_int md_flags;
3251 u_int8_t md_msg;
3252 int (*md_msgfunc)(struct scsi_low_softc *);
3253 int (*md_errfunc)(struct scsi_low_softc *, u_int);
3254#define MSG_RELEASE_ATN 0x0001
3255 u_int md_condition;
3256};
3257
3258struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3259/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3260/* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3261/* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3262/* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3263/* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3264/* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3265/* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3266/* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3267/* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3268/* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3269/* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
3270/* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3271/* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3272/* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3273/* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3274/* 15 */{SCSI_LOW_MSG_ALL, 0},
3275};
3276
3277static int scsi_low_msginfunc_ext(struct scsi_low_softc *);
3278static int scsi_low_synch(struct scsi_low_softc *);
3279static int scsi_low_wide(struct scsi_low_softc *);
3280static int scsi_low_msginfunc_msg_reject(struct scsi_low_softc *);
3281static int scsi_low_msginfunc_rejop(struct scsi_low_softc *);
3282static int scsi_low_msginfunc_rp(struct scsi_low_softc *);
3283static int scsi_low_msginfunc_sdp(struct scsi_low_softc *);
3284static int scsi_low_msginfunc_disc(struct scsi_low_softc *);
3285static int scsi_low_msginfunc_cc(struct scsi_low_softc *);
3286static int scsi_low_msginfunc_lcc(struct scsi_low_softc *);
3287static int scsi_low_msginfunc_parity(struct scsi_low_softc *);
3288static int scsi_low_msginfunc_noop(struct scsi_low_softc *);
3289static int scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *);
3290static int scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *);
3291
3292struct scsi_low_msgin_data {
3293 u_int md_len;
3294 int (*md_msgfunc)(struct scsi_low_softc *);
3295};
3296
3297struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3298/* 0 */ {1, scsi_low_msginfunc_cc},
3299/* 1 */ {2, scsi_low_msginfunc_ext},
3300/* 2 */ {1, scsi_low_msginfunc_sdp},
3301/* 3 */ {1, scsi_low_msginfunc_rp},
3302/* 4 */ {1, scsi_low_msginfunc_disc},
3303/* 5 */ {1, scsi_low_msginfunc_rejop},
3304/* 6 */ {1, scsi_low_msginfunc_rejop},
3305/* 7 */ {1, scsi_low_msginfunc_msg_reject},
3306/* 8 */ {1, scsi_low_msginfunc_noop},
3307/* 9 */ {1, scsi_low_msginfunc_parity},
3308/* a */ {1, scsi_low_msginfunc_lcc},
3309/* b */ {1, scsi_low_msginfunc_lcc},
3310/* c */ {1, scsi_low_msginfunc_rejop},
3311/* d */ {2, scsi_low_msginfunc_rejop},
3312/* e */ {1, scsi_low_msginfunc_rejop},
3313/* f */ {1, scsi_low_msginfunc_rejop},
3314/* 0x10 */ {1, scsi_low_msginfunc_rejop},
3315/* 0x11 */ {1, scsi_low_msginfunc_rejop},
3316/* 0x12 */ {1, scsi_low_msginfunc_rejop},
3317/* 0x13 */ {1, scsi_low_msginfunc_rejop},
3318/* 0x14 */ {1, scsi_low_msginfunc_rejop},
3319/* 0x15 */ {1, scsi_low_msginfunc_rejop},
3320/* 0x16 */ {1, scsi_low_msginfunc_rejop},
3321/* 0x17 */ {1, scsi_low_msginfunc_rejop},
3322/* 0x18 */ {1, scsi_low_msginfunc_rejop},
3323/* 0x19 */ {1, scsi_low_msginfunc_rejop},
3324/* 0x1a */ {1, scsi_low_msginfunc_rejop},
3325/* 0x1b */ {1, scsi_low_msginfunc_rejop},
3326/* 0x1c */ {1, scsi_low_msginfunc_rejop},
3327/* 0x1d */ {1, scsi_low_msginfunc_rejop},
3328/* 0x1e */ {1, scsi_low_msginfunc_rejop},
3329/* 0x1f */ {1, scsi_low_msginfunc_rejop},
3330/* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
3331/* 0x21 */ {2, scsi_low_msginfunc_rejop},
3332/* 0x22 */ {2, scsi_low_msginfunc_rejop},
3333/* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
3334/* 0x24 */ {2, scsi_low_msginfunc_rejop},
3335/* 0x25 */ {2, scsi_low_msginfunc_rejop},
3336/* 0x26 */ {2, scsi_low_msginfunc_rejop},
3337/* 0x27 */ {2, scsi_low_msginfunc_rejop},
3338/* 0x28 */ {2, scsi_low_msginfunc_rejop},
3339/* 0x29 */ {2, scsi_low_msginfunc_rejop},
3340/* 0x2a */ {2, scsi_low_msginfunc_rejop},
3341/* 0x2b */ {2, scsi_low_msginfunc_rejop},
3342/* 0x2c */ {2, scsi_low_msginfunc_rejop},
3343/* 0x2d */ {2, scsi_low_msginfunc_rejop},
3344/* 0x2e */ {2, scsi_low_msginfunc_rejop},
3345/* 0x2f */ {2, scsi_low_msginfunc_rejop},
3346/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
3347};
3348
3349/**************************************************************
3350 * msgout
3351 **************************************************************/
3352static int
3353scsi_low_msgfunc_synch(slp)
3354 struct scsi_low_softc *slp;
3355{
3356 struct targ_info *ti = slp->sl_Tnexus;
3357 int ptr = ti->ti_msgoutlen;
3358
3359 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3360 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3361 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3362 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3363 return MSG_EXTEND_SYNCHLEN + 2;
3364}
3365
3366static int
3367scsi_low_msgfunc_wide(slp)
3368 struct scsi_low_softc *slp;
3369{
3370 struct targ_info *ti = slp->sl_Tnexus;
3371 int ptr = ti->ti_msgoutlen;
3372
3373 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3374 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3375 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3376 return MSG_EXTEND_WIDELEN + 2;
3377}
3378
3379static int
3380scsi_low_msgfunc_identify(slp)
3381 struct scsi_low_softc *slp;
3382{
3383 struct targ_info *ti = slp->sl_Tnexus;
3384 struct lun_info *li = slp->sl_Lnexus;
3385 struct slccb *cb = slp->sl_Qnexus;
3386 int ptr = ti->ti_msgoutlen;
3387 u_int8_t msg;
3388
3389 msg = MSG_IDENTIFY;
3390 if (cb == NULL)
3391 {
3392 slp->sl_error |= FATALIO;
3393 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3394 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3395 }
3396 else
3397 {
3398 if (scsi_low_is_disconnect_ok(cb) != 0)
3399 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3400 else
3401 msg |= li->li_lun;
3402
3403 if (ti->ti_phase == PH_MSGOUT)
3404 {
3405 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3406 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3407 {
3408 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3409 }
3410 }
3411 }
3412 ti->ti_msgoutstr[ptr + 0] = msg;
3413 return 1;
3414}
3415
3416static int
3417scsi_low_msgfunc_abort(slp)
3418 struct scsi_low_softc *slp;
3419{
3420
3421 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3422 return 1;
3423}
3424
3425static int
3426scsi_low_msgfunc_qabort(slp)
3427 struct scsi_low_softc *slp;
3428{
3429
3430 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3431 return 1;
3432}
3433
3434static int
3435scsi_low_msgfunc_reset(slp)
3436 struct scsi_low_softc *slp;
3437{
3438
3439 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3440 return 1;
3441}
3442
3443static int
3444scsi_low_msgfunc_qtag(slp)
3445 struct scsi_low_softc *slp;
3446{
3447 struct targ_info *ti = slp->sl_Tnexus;
3448 struct slccb *cb = slp->sl_Qnexus;
3449 int ptr = ti->ti_msgoutlen;
3450
3451 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3452 {
3453 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3454 return 1;
3455 }
3456 else
3457 {
3458 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3459 if (ti->ti_phase == PH_MSGOUT)
3460 {
3461 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3462 }
3463 }
3464 return 2;
3465}
3466
3467/*
3468 * The following functions are called when targets give unexpected
3469 * responces in msgin (after msgout).
3470 */
3471static int
3472scsi_low_errfunc_identify(slp, msgflags)
3473 struct scsi_low_softc *slp;
3474 u_int msgflags;
3475{
3476
3477 if (slp->sl_Lnexus != NULL)
3478 {
3479 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3480 scsi_low_calcf_lun(slp->sl_Lnexus);
3481 }
3482 return 0;
3483}
3484
3485static int
3486scsi_low_errfunc_synch(slp, msgflags)
3487 struct scsi_low_softc *slp;
3488 u_int msgflags;
3489{
3490 struct targ_info *ti = slp->sl_Tnexus;
3491
3492 MSGIN_PERIOD(ti) = 0;
3493 MSGIN_OFFSET(ti) = 0;
3494 scsi_low_synch(slp);
3495 return 0;
3496}
3497
3498static int
3499scsi_low_errfunc_wide(slp, msgflags)
3500 struct scsi_low_softc *slp;
3501 u_int msgflags;
3502{
3503 struct targ_info *ti = slp->sl_Tnexus;
3504
3505 MSGIN_WIDTHP(ti) = 0;
3506 scsi_low_wide(slp);
3507 return 0;
3508}
3509
3510static int
3511scsi_low_errfunc_qtag(slp, msgflags)
3512 struct scsi_low_softc *slp;
3513 u_int msgflags;
3514{
3515
3516 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3517 {
3518 if (slp->sl_Qnexus != NULL)
3519 {
3520 scsi_low_deactivate_qtag(slp->sl_Qnexus);
3521 }
3522 if (slp->sl_Lnexus != NULL)
3523 {
3524 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3525 scsi_low_calcf_lun(slp->sl_Lnexus);
3526 }
3527 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3528 }
3529 return 0;
3530}
3531
3532
3533int
3534scsi_low_msgout(slp, ti, fl)
3535 struct scsi_low_softc *slp;
3536 struct targ_info *ti;
3537 u_int fl;
3538{
3539 struct scsi_low_msgout_data *mdp;
3540 int len = 0;
3541
3542#ifdef SCSI_LOW_DIAGNOSTIC
3543 if (ti != slp->sl_Tnexus)
3544 {
3545 scsi_low_print(slp, NULL);
3546 panic("scsi_low_msgout: Target nexus inconsistent");
3547 }
3548#endif /* SCSI_LOW_DIAGNOSTIC */
3549
3550 slp->sl_ph_count ++;
3551 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3552 {
3553 printf("%s: too many phase changes\n", slp->sl_xname);
3554 slp->sl_error |= FATALIO;
3555 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3556 }
3557
3558 /* STEP I.
3559 * Scsi phase changes.
3560 * Previously msgs asserted are accepted by our target or
3561 * processed by scsi_low_msgin.
3562 * Thus clear all saved informations.
3563 */
3564 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3565 {
3566 ti->ti_omsgflags = 0;
3567 ti->ti_emsgflags = 0;
3568 }
3569 else if (slp->sl_atten == 0)
3570 {
3571 /* STEP II.
3572 * We did not assert attention, however still our target required
3573 * msgs. Resend previous msgs.
3574 */
3575 ti->ti_msgflags |= ti->ti_omsgflags;
3576 ti->ti_omsgflags = 0;
3577#ifdef SCSI_LOW_DIAGNOSTIC
3578 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3579#endif /* SCSI_LOW_DIAGNOSTIC */
3580 }
3581
3582 /* STEP III.
3583 * We have no msgs. send MSG_NOOP (OK?)
3584 */
3585 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3586 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3587
3588 /* STEP IV.
3589 * Process all msgs
3590 */
3591 ti->ti_msgoutlen = 0;
3592 slp->sl_clear_atten = 0;
3593 mdp = &scsi_low_msgout_data[0];
3594 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3595 {
3596 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3597 {
3598 ti->ti_omsgflags |= mdp->md_flags;
3599 ti->ti_msgflags &= ~mdp->md_flags;
3600 ti->ti_emsgflags = mdp->md_flags;
3601
3602 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3603 if (mdp->md_msgfunc != NULL)
3604 len = (*mdp->md_msgfunc) (slp);
3605 else
3606 len = 1;
3607
3608#ifdef SCSI_LOW_DIAGNOSTIC
3609 scsi_low_msg_log_write(&ti->ti_log_msgout,
3610 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3611#endif /* SCSI_LOW_DIAGNOSTIC */
3612
3613 ti->ti_msgoutlen += len;
3614 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3615 {
3616 slp->sl_clear_atten = 1;
3617 break;
3618 }
3619
3620 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3621 ti->ti_msgflags == 0)
3622 break;
3623
3624 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3625 break;
3626 }
3627 }
3628
3629 if (scsi_low_is_msgout_continue(ti, 0) == 0)
3630 slp->sl_clear_atten = 1;
3631
3632 return ti->ti_msgoutlen;
3633}
3634
3635/**************************************************************
3636 * msgin
3637 **************************************************************/
3638static int
3639scsi_low_msginfunc_noop(slp)
3640 struct scsi_low_softc *slp;
3641{
3642
3643 return 0;
3644}
3645
3646static int
3647scsi_low_msginfunc_rejop(slp)
3648 struct scsi_low_softc *slp;
3649{
3650 struct targ_info *ti = slp->sl_Tnexus;
3651 u_int8_t msg = ti->ti_msgin[0];
3652
3653 printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3654 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3655 return 0;
3656}
3657
3658static int
3659scsi_low_msginfunc_cc(slp)
3660 struct scsi_low_softc *slp;
3661{
3662 struct lun_info *li;
3663
3664 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3665
3666 /* validate status */
3667 if (slp->sl_Qnexus == NULL)
3668 return ENOENT;
3669
3670 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3671 li = slp->sl_Lnexus;
3672 switch (slp->sl_scp.scp_status)
3673 {
3674 case ST_GOOD:
3675 li->li_maxnqio = li->li_maxnexus;
3676 break;
3677
3678 case ST_CHKCOND:
3679 li->li_maxnqio = 0;
3680 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3681 scsi_low_reset_nexus_lun(slp, li, 0);
3682 break;
3683
3684 case ST_BUSY:
3685 li->li_maxnqio = 0;
3686 break;
3687
3688 case ST_QUEFULL:
3689 if (li->li_maxnexus >= li->li_nqio)
3690 li->li_maxnexus = li->li_nqio - 1;
3691 li->li_maxnqio = li->li_maxnexus;
3692 break;
3693
3694 case ST_INTERGOOD:
3695 case ST_INTERMET:
3696 slp->sl_error |= MSGERR;
3697 break;
3698
3699 default:
3700 break;
3701 }
3702 return 0;
3703}
3704
3705static int
3706scsi_low_msginfunc_lcc(slp)
3707 struct scsi_low_softc *slp;
3708{
3709 struct targ_info *ti;
3710 struct lun_info *li;
3711 struct slccb *ncb, *cb;
3712
3713 ti = slp->sl_Tnexus;
3714 li = slp->sl_Lnexus;
3715 if ((cb = slp->sl_Qnexus) == NULL)
3716 goto bad;
3717
3718 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3719 switch (slp->sl_scp.scp_status)
3720 {
3721 case ST_INTERGOOD:
3722 case ST_INTERMET:
3723 li->li_maxnqio = li->li_maxnexus;
3724 break;
3725
3726 default:
3727 slp->sl_error |= MSGERR;
3728 break;
3729 }
3730
3731 if ((li->li_flags & SCSI_LOW_LINK) == 0)
3732 goto bad;
3733
3734 cb->ccb_error |= slp->sl_error;
3735 if (cb->ccb_error != 0)
3736 goto bad;
3737
3738 for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3739 ncb = TAILQ_NEXT(ncb, ccb_chain))
3740 {
3741 if (ncb->li == li)
3742 goto cmd_link_start;
3743 }
3744
3745
3746bad:
3747 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3748 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3749 return EIO;
3750
3751cmd_link_start:
3752 ncb->ccb_flags &= ~CCB_STARTQ;
3753 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3754
3755 scsi_low_dealloc_qtag(ncb);
3756 ncb->ccb_tag = cb->ccb_tag;
3757 ncb->ccb_otag = cb->ccb_otag;
3758 cb->ccb_tag = SCSI_LOW_UNKTAG;
3759 cb->ccb_otag = SCSI_LOW_UNKTAG;
3760 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3761 panic("%s: linked ccb retried", slp->sl_xname);
3762
3763 slp->sl_Qnexus = ncb;
3764 slp->sl_ph_count = 0;
3765
3766 ncb->ccb_error = 0;
3767 ncb->ccb_datalen = -1;
3768 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3769 ncb->ccb_flags &= ~CCB_INTERNAL;
3770
3771 scsi_low_init_msgsys(slp, ti);
3772
3773 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3774
3775 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3776 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3777 ncb->ccb_tc = ncb->ccb_tcmax;
3778
3779 /* setup saved scsi data pointer */
3780 ncb->ccb_sscp = ncb->ccb_scp;
3781 slp->sl_scp = ncb->ccb_sscp;
3782 slp->sl_error = ncb->ccb_error;
3783
3784#ifdef SCSI_LOW_DIAGNOSTIC
3785 scsi_low_msg_log_init(&ti->ti_log_msgin);
3786 scsi_low_msg_log_init(&ti->ti_log_msgout);
3787#endif /* SCSI_LOW_DIAGNOSTIC */
3788 return EJUSTRETURN;
3789}
3790
3791static int
3792scsi_low_msginfunc_disc(slp)
3793 struct scsi_low_softc *slp;
3794{
3795
3796 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3797 return 0;
3798}
3799
3800static int
3801scsi_low_msginfunc_sdp(slp)
3802 struct scsi_low_softc *slp;
3803{
3804 struct slccb *cb = slp->sl_Qnexus;
3805
3806 if (cb != NULL)
3807 {
3808 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3809 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3810 }
3811 else
3812 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3813 return 0;
3814}
3815
3816static int
3817scsi_low_msginfunc_rp(slp)
3818 struct scsi_low_softc *slp;
3819{
3820
3821 if (slp->sl_Qnexus != NULL)
3822 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3823 else
3824 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3825 return 0;
3826}
3827
3828static int
3829scsi_low_synch(slp)
3830 struct scsi_low_softc *slp;
3831{
3832 struct targ_info *ti = slp->sl_Tnexus;
3833 u_int period = 0, offset = 0, speed;
3834 u_char *s;
3835 int error;
3836
3837 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3838 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3839 MSGIN_OFFSET(ti) == 0)
3840 {
3841 if ((offset = MSGIN_OFFSET(ti)) != 0)
3842 period = MSGIN_PERIOD(ti);
3843 s = offset ? "synchronous" : "async";
3844 }
3845 else
3846 {
3847 /* XXX:
3848 * Target seems to be brain damaged.
3849 * Force async transfer.
3850 */
3851 ti->ti_maxsynch.period = 0;
3852 ti->ti_maxsynch.offset = 0;
3853 printf("%s: target brain damaged. async transfer\n",
3854 slp->sl_xname);
3855 return EINVAL;
3856 }
3857
3858 ti->ti_maxsynch.period = period;
3859 ti->ti_maxsynch.offset = offset;
3860
3861 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3862 if (error != 0)
3863 {
3864 /* XXX:
3865 * Current period and offset are not acceptable
3866 * for our adapter.
3867 * The adapter changes max synch and max offset.
3868 */
3869 printf("%s: synch neg failed. retry synch msg neg ...\n",
3870 slp->sl_xname);
3871 return error;
3872 }
3873
3874 ti->ti_osynch = ti->ti_maxsynch;
3875 if (offset > 0)
3876 {
3877 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3878 }
3879
3880 /* inform data */
3881 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3882 {
3883#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3884 struct slccb *cb = slp->sl_Qnexus;
3885
3886 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3887 return 0;
3888#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3889
3890 printf("%s(%d:*): <%s> offset %d period %dns ",
3891 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3892
3893 if (period != 0)
3894 {
3895 speed = 1000 * 10 / (period * 4);
3896 printf("%d.%d M/s", speed / 10, speed % 10);
3897 }
3898 printf("\n");
3899 }
3900 return 0;
3901}
3902
3903static int
3904scsi_low_wide(slp)
3905 struct scsi_low_softc *slp;
3906{
3907 struct targ_info *ti = slp->sl_Tnexus;
3908 int error;
3909
3910 ti->ti_width = MSGIN_WIDTHP(ti);
3911 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3912 if (error != 0)
3913 {
3914 /* XXX:
3915 * Current width is not acceptable for our adapter.
3916 * The adapter changes max width.
3917 */
3918 printf("%s: wide neg failed. retry wide msg neg ...\n",
3919 slp->sl_xname);
3920 return error;
3921 }
3922
3923 ti->ti_owidth = ti->ti_width;
3924 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3925 {
3926 ti->ti_setup_msg_done |=
3927 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3928 }
3929
3930 /* inform data */
3931 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3932 {
3933#ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3934 struct slccb *cb = slp->sl_Qnexus;
3935
3936 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3937 return 0;
3938#endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3939
3940 printf("%s(%d:*): transfer width %d bits\n",
3941 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3942 }
3943 return 0;
3944}
3945
3946static int
3947scsi_low_msginfunc_simple_qtag(slp)
3948 struct scsi_low_softc *slp;
3949{
3950 struct targ_info *ti = slp->sl_Tnexus;
3951 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3952
3953 if (slp->sl_Qnexus != NULL)
3954 {
3955 if (slp->sl_Qnexus->ccb_tag != etag)
3956 {
3957 slp->sl_error |= FATALIO;
3958 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3959 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3960 }
3961 }
3962 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3963 {
3964#ifdef SCSI_LOW_DEBUG
3965 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3966 return 0;
3967#endif /* SCSI_LOW_DEBUG */
3968
3969 slp->sl_error |= FATALIO;
3970 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3971 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3972 }
3973 return 0;
3974}
3975
3976static int
3977scsi_low_msginfunc_i_wide_residue(slp)
3978 struct scsi_low_softc *slp;
3979{
3980 struct targ_info *ti = slp->sl_Tnexus;
3981 struct slccb *cb = slp->sl_Qnexus;
3982 int res = (int) ti->ti_msgin[1];
3983
3984 if (cb == NULL || res <= 0 ||
3985 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3986 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3987 return EINVAL;
3988
3989 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3990 return EINVAL;
3991
3992 slp->sl_scp.scp_datalen += res;
3993 slp->sl_scp.scp_data -= res;
3994 scsi_low_data_finish(slp);
3995 return 0;
3996}
3997
3998static int
3999scsi_low_msginfunc_ext(slp)
4000 struct scsi_low_softc *slp;
4001{
4002 struct slccb *cb = slp->sl_Qnexus;
4003 struct lun_info *li = slp->sl_Lnexus;
4004 struct targ_info *ti = slp->sl_Tnexus;
4005 int count, retry;
4006 u_int32_t *ptr;
4007
4008 if (ti->ti_msginptr == 2)
4009 {
4010 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4011 return 0;
4012 }
4013
4014 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4015 {
4016 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4017 if (cb == NULL)
4018 break;
4019
4020 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4021 count = (int) htonl((long) (*ptr));
4022 if(slp->sl_scp.scp_datalen - count < 0 ||
4023 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4024 break;
4025
4026 slp->sl_scp.scp_datalen -= count;
4027 slp->sl_scp.scp_data += count;
4028 return 0;
4029
4030 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4031 if (li == NULL)
4032 break;
4033
4034 retry = scsi_low_synch(slp);
4035 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4036 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4037
4038#ifdef SCSI_LOW_DEBUG
4039 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4040 {
4041 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4042 }
4043#endif /* SCSI_LOW_DEBUG */
4044 return 0;
4045
4046 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4047 if (li == NULL)
4048 break;
4049
4050 retry = scsi_low_wide(slp);
4051 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4052 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4053
4054 return 0;
4055
4056 default:
4057 break;
4058 }
4059
4060 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4061 return EINVAL;
4062}
4063
4064static int
4065scsi_low_msginfunc_parity(slp)
4066 struct scsi_low_softc *slp;
4067{
4068 struct targ_info *ti = slp->sl_Tnexus;
4069
4070 /* only I -> T, invalid! */
4071 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4072 return 0;
4073}
4074
4075static int
4076scsi_low_msginfunc_msg_reject(slp)
4077 struct scsi_low_softc *slp;
4078{
4079 struct targ_info *ti = slp->sl_Tnexus;
4080 struct scsi_low_msgout_data *mdp;
4081 u_int msgflags;
4082
4083 if (ti->ti_emsgflags != 0)
4084 {
4085 printf("%s: msg flags [0x%x] rejected\n",
4086 slp->sl_xname, ti->ti_emsgflags);
4087 msgflags = SCSI_LOW_MSG_REJECT;
4088 mdp = &scsi_low_msgout_data[0];
4089 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4090 {
4091 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4092 {
4093 ti->ti_emsgflags &= ~mdp->md_flags;
4094 if (mdp->md_errfunc != NULL)
4095 (*mdp->md_errfunc) (slp, msgflags);
4096 break;
4097 }
4098 }
4099 return 0;
4100 }
4101 else
4102 {
4103 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4104 slp->sl_error |= MSGERR;
4105 }
4106 return EINVAL;
4107}
4108
4109int
4110scsi_low_msgin(slp, ti, c)
4111 struct scsi_low_softc *slp;
4112 struct targ_info *ti;
4113 u_int c;
4114{
4115 struct scsi_low_msgin_data *sdp;
4116 struct lun_info *li;
4117 u_int8_t msg;
4118
4119#ifdef SCSI_LOW_DIAGNOSTIC
4120 if (ti != slp->sl_Tnexus)
4121 {
4122 scsi_low_print(slp, NULL);
4123 panic("scsi_low_msgin: Target nexus inconsistent");
4124 }
4125#endif /* SCSI_LOW_DIAGNOSTIC */
4126
4127 /*
4128 * Phase changes, clear the pointer.
4129 */
4130 if (ti->ti_ophase != ti->ti_phase)
4131 {
4132 MSGINPTR_CLR(ti);
4133 ti->ti_msgin_parity_error = 0;
4134
4135 slp->sl_ph_count ++;
4136 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4137 {
4138 printf("%s: too many phase changes\n", slp->sl_xname);
4139 slp->sl_error |= FATALIO;
4140 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4141 }
4142 }
4143
4144 /*
4145 * Store a current messages byte into buffer and
4146 * wait for the completion of the current msg.
4147 */
4148 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4149 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4150 {
4151 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4152 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4153 }
4154
4155 /*
4156 * Check parity errors.
4157 */
4158 if ((c & SCSI_LOW_DATA_PE) != 0)
4159 {
4160 ti->ti_msgin_parity_error ++;
4161 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4162 goto out;
4163 }
4164
4165 if (ti->ti_msgin_parity_error != 0)
4166 goto out;
4167
4168 /*
4169 * Calculate messages length.
4170 */
4171 msg = ti->ti_msgin[0];
4172 if (msg < MSGIN_DATA_LAST)
4173 sdp = &scsi_low_msgin_data[msg];
4174 else
4175 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
4176
4177 if (ti->ti_msginlen == 0)
4178 {
4179 ti->ti_msginlen = sdp->md_len;
4180 }
4181
4182 /*
4183 * Check comletion.
4184 */
4185 if (ti->ti_msginptr < ti->ti_msginlen)
4186 return EJUSTRETURN;
4187
4188 /*
4189 * Do process.
4190 */
4191 if ((msg & MSG_IDENTIFY) == 0)
4192 {
4193 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
4194 return EJUSTRETURN;
4195 }
4196 else
4197 {
4198 li = slp->sl_Lnexus;
4199 if (li == NULL)
4200 {
4201 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
4202 if (li == NULL)
4203 goto badlun;
4204 slp->sl_Lnexus = li;
4205 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
4206 }
4207 else
4208 {
4209 if (MSGCMD_LUN(msg) != li->li_lun)
4210 goto badlun;
4211 }
4212
4213 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
4214 {
4215 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
4216 {
4217#ifdef SCSI_LOW_DEBUG
4218 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
4219 {
4220 goto out;
4221 }
4222#endif /* SCSI_LOW_DEBUG */
4223 goto badlun;
4224 }
4225 }
4226 }
4227 goto out;
4228
4229 /*
4230 * Msg process completed, reset msgin pointer and assert ATN if desired.
4231 */
4232badlun:
4233 slp->sl_error |= FATALIO;
4234 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4235 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
4236
4237out:
4238 if (ti->ti_msginptr < ti->ti_msginlen)
4239 return EJUSTRETURN;
4240
4241#ifdef SCSI_LOW_DIAGNOSTIC
4242 scsi_low_msg_log_write(&ti->ti_log_msgin,
4243 &ti->ti_msgin[0], ti->ti_msginlen);
4244#endif /* SCSI_LOW_DIAGNOSTIC */
4245
4246 MSGINPTR_CLR(ti);
4247 return 0;
4248}
4249
4250/**********************************************************
4251 * disconnect
4252 **********************************************************/
4253int
4254scsi_low_disconnected(slp, ti)
4255 struct scsi_low_softc *slp;
4256 struct targ_info *ti;
4257{
4258 struct slccb *cb = slp->sl_Qnexus;
4259
4260 /* check phase completion */
4261 switch (slp->sl_msgphase)
4262 {
4263 case MSGPH_RESET:
4264 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4265 scsi_low_msginfunc_cc(slp);
4266 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
4267 goto io_resume;
4268
4269 case MSGPH_ABORT:
4270 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4271 scsi_low_msginfunc_cc(slp);
4272 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
4273 goto io_resume;
4274
4275 case MSGPH_TERM:
4276 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
4277 scsi_low_msginfunc_cc(slp);
4278 goto io_resume;
4279
4280 case MSGPH_DISC:
4281 if (cb != NULL)
4282 {
4283 struct lun_info *li;
4284
4285 li = cb->li;
4286 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
4287 cb->ccb_flags |= CCB_DISCQ;
4288 cb->ccb_error |= slp->sl_error;
4289 li->li_disc ++;
4290 ti->ti_disc ++;
4291 slp->sl_disc ++;
4292 }
4293
4294#ifdef SCSI_LOW_STATICS
4295 scsi_low_statics.nexus_disconnected ++;
4296#endif /* SCSI_LOW_STATICS */
4297
4298#ifdef SCSI_LOW_DEBUG
4299 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
4300 {
4301 printf("## SCSI_LOW_DISCONNECTED ===============\n");
4302 scsi_low_print(slp, NULL);
4303 }
4304#endif /* SCSI_LOW_DEBUG */
4305 break;
4306
4307 case MSGPH_NULL:
4308 slp->sl_error |= FATALIO;
4309 if (ti->ti_phase == PH_SELSTART)
4310 slp->sl_error |= SELTIMEOUTIO;
4311 else
4312 slp->sl_error |= UBFERR;
4313 /* fall through */
4314
4315 case MSGPH_LCTERM:
4316 case MSGPH_CMDC:
4317io_resume:
4318 if (cb == NULL)
4319 break;
4320
4321#ifdef SCSI_LOW_DEBUG
4322 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4323 {
4324 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
4325 (cb->ccb_msgoutflag != 0 ||
4326 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
4327 {
4328 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
4329 }
4330 }
4331#endif /* SCSI_LOW_DEBUG */
4332
4333 cb->ccb_error |= slp->sl_error;
4334 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
4335 {
4336 cb->ccb_flags |= CCB_STARTQ;
4337 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
4338 }
4339 break;
4340 }
4341
4342 scsi_low_bus_release(slp, ti);
4343 scsi_low_start(slp);
4344 return 1;
4345}
4346
4347/**********************************************************
4348 * TAG operations
4349 **********************************************************/
4350static int
4351scsi_low_alloc_qtag(cb)
4352 struct slccb *cb;
4353{
4354 struct lun_info *li = cb->li;
4355 scsi_low_tag_t etag;
4356
4357 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
4358 return 0;
4359
4360#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4361 etag = ffs(li->li_qtagbits);
4362 if (etag == 0)
4363 return ENOSPC;
4364
4365 li->li_qtagbits &= ~(1 << (etag - 1));
4366 cb->ccb_otag = etag;
4367 return 0;
4368
4369#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4370 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
4371 if (li->li_qtagarray[li->li_qd] == 0)
4372 goto found;
4373
4374 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
4375 if (li->li_qtagarray[li->li_qd] == 0)
4376 goto found;
4377
4378 return ENOSPC;
4379
4380found:
4381 li->li_qtagarray[li->li_qd] ++;
4382 cb->ccb_otag = (li->li_qd ++);
4383 return 0;
4384#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4385}
4386
4387static int
4388scsi_low_dealloc_qtag(cb)
4389 struct slccb *cb;
4390{
4391 struct lun_info *li = cb->li;
4392 scsi_low_tag_t etag;
4393
4394 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
4395 return 0;
4396
4397#ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
4398 etag = cb->ccb_otag - 1;
4399#ifdef SCSI_LOW_DIAGNOSTIC
4400 if (etag >= sizeof(li->li_qtagbits) * NBBY)
4401 panic("scsi_low_dealloc_tag: illegal tag");
4402#endif /* SCSI_LOW_DIAGNOSTIC */
4403 li->li_qtagbits |= (1 << etag);
4404
4405#else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4406 etag = cb->ccb_otag;
4407#ifdef SCSI_LOW_DIAGNOSTIC
4408 if (etag >= SCSI_LOW_MAXNEXUS)
4409 panic("scsi_low_dealloc_tag: illegal tag");
4410#endif /* SCSI_LOW_DIAGNOSTIC */
4411 li->li_qtagarray[etag] --;
4412#endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
4413
4414 cb->ccb_otag = SCSI_LOW_UNKTAG;
4415 return 0;
4416}
4417
4418static struct slccb *
4419scsi_low_revoke_ccb(slp, cb, fdone)
4420 struct scsi_low_softc *slp;
4421 struct slccb *cb;
4422 int fdone;
4423{
4424 struct targ_info *ti = cb->ti;
4425 struct lun_info *li = cb->li;
4426
4427#ifdef SCSI_LOW_DIAGNOSTIC
4428 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
4429 (CCB_STARTQ | CCB_DISCQ))
4430 {
4431 panic("%s: ccb in both queue", slp->sl_xname);
4432 }
4433#endif /* SCSI_LOW_DIAGNOSTIC */
4434
4435 if ((cb->ccb_flags & CCB_STARTQ) != 0)
4436 {
4437 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
4438 }
4439
4440 if ((cb->ccb_flags & CCB_DISCQ) != 0)
4441 {
4442 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
4443 li->li_disc --;
4444 ti->ti_disc --;
4445 slp->sl_disc --;
4446 }
4447
4448 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
4449 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
4450
4451 if (fdone != 0 &&
4452 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
4453 (cb->ccb_flags & CCB_NORETRY) != 0))
4454 {
4455 cb->ccb_error |= FATALIO;
4456 cb->ccb_flags &= ~CCB_AUTOSENSE;
4457 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
4458 panic("%s: done ccb retried", slp->sl_xname);
4459 return NULL;
4460 }
4461 else
4462 {
4463 cb->ccb_error |= PENDINGIO;
4464 scsi_low_deactivate_qtag(cb);
4465 scsi_low_ccb_message_retry(cb);
4466 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
4467 return cb;
4468 }
4469}
4470
4471static void
4472scsi_low_reset_nexus_lun(slp, li, fdone)
4473 struct scsi_low_softc *slp;
4474 struct lun_info *li;
4475 int fdone;
4476{
4477 struct slccb *cb, *ncb, *ecb;
4478
4479 if (li == NULL)
4480 return;
4481
4482 ecb = NULL;
4483 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
4484 {
4485 ncb = TAILQ_NEXT(cb, ccb_chain);
4486 cb = scsi_low_revoke_ccb(slp, cb, fdone);
4487 if (cb != NULL)
4488 {
4489 /*
4490 * presumely keep ordering of io
4491 */
4492 cb->ccb_flags |= CCB_STARTQ;
4493 if (ecb == NULL)
4494 {
4495 TAILQ_INSERT_HEAD(&slp->sl_start,\
4496 cb, ccb_chain);
4497 }
4498 else
4499 {
4500 TAILQ_INSERT_AFTER(&slp->sl_start,\
4501 ecb, cb, ccb_chain);
4502 }
4503 ecb = cb;
4504 }
4505 }
4506}
4507
4508/**************************************************************
4509 * Qurik setup
4510 **************************************************************/
4511static void
4512scsi_low_calcf_lun(li)
4513 struct lun_info *li;
4514{
4515 struct targ_info *ti = li->li_ti;
4516 struct scsi_low_softc *slp = ti->ti_sc;
4517 u_int cfgflags, diskflags;
4518
4519 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
4520 cfgflags = li->li_cfgflags;
4521 else
4522 cfgflags = 0;
4523
4524 diskflags = li->li_diskflags & li->li_quirks;
4525
4526 /* disconnect */
4527 li->li_flags &= ~SCSI_LOW_DISC;
4528 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
4529 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
4530 (cfgflags & SCSI_LOW_DISC) != 0)
4531 li->li_flags |= SCSI_LOW_DISC;
4532
4533 /* parity */
4534 li->li_flags |= SCSI_LOW_NOPARITY;
4535 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
4536 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
4537 (cfgflags & SCSI_LOW_NOPARITY) == 0)
4538 li->li_flags &= ~SCSI_LOW_NOPARITY;
4539
4540 /* qtag */
4541 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
4542 (cfgflags & SCSI_LOW_QTAG) != 0 &&
4543 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
4544 {
4545 li->li_flags |= SCSI_LOW_QTAG;
4546 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
4547 li->li_maxnqio = li->li_maxnexus;
4548 }
4549 else
4550 {
4551 li->li_flags &= ~SCSI_LOW_QTAG;
4552 li->li_maxnexus = 0;
4553 li->li_maxnqio = li->li_maxnexus;
4554 }
4555
4556 /* cmd link */
4557 li->li_flags &= ~SCSI_LOW_LINK;
4558 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
4559 (diskflags & SCSI_LOW_DISK_LINK) != 0)
4560 li->li_flags |= SCSI_LOW_LINK;
4561
4562 /* compatible flags */
4563 li->li_flags &= ~SCSI_LOW_SYNC;
4564 if (ti->ti_maxsynch.offset > 0)
4565 li->li_flags |= SCSI_LOW_SYNC;
4566
4567#ifdef SCSI_LOW_DEBUG
4568 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4569 {
4570 scsi_low_calcf_show(li);
4571 }
4572#endif /* SCSI_LOW_DEBUG */
4573}
4574
4575static void
4576scsi_low_calcf_target(ti)
4577 struct targ_info *ti;
4578{
4579 struct scsi_low_softc *slp = ti->ti_sc;
4580 u_int offset, period, diskflags;
4581
4582 diskflags = ti->ti_diskflags & ti->ti_quirks;
4583
4584 /* synch */
4585 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
4586 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
4587 {
4588 offset = ti->ti_maxsynch.offset;
4589 period = ti->ti_maxsynch.period;
4590 if (offset == 0 || period == 0)
4591 offset = period = 0;
4592 }
4593 else
4594 {
4595 offset = period = 0;
4596 }
4597
4598 ti->ti_maxsynch.offset = offset;
4599 ti->ti_maxsynch.period = period;
4600
4601 /* wide */
4602 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
4603 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
4604 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
4605
4606 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
4607 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
4608 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
4609
4610 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
4611 {
4612 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
4613 ti->ti_maxsynch.period != ti->ti_osynch.period)
4614 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
4615 if (ti->ti_width != ti->ti_owidth)
4616 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
4617
4618 ti->ti_osynch = ti->ti_maxsynch;
4619 ti->ti_owidth = ti->ti_width;
4620 }
4621
4622#ifdef SCSI_LOW_DEBUG
4623 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
4624 {
4625 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
4626 slp->sl_xname, ti->ti_id,
4627 ti->ti_maxsynch.period * 4,
4628 ti->ti_maxsynch.offset,
4629 ti->ti_width);
4630 }
4631#endif /* SCSI_LOW_DEBUG */
4632}
4633
4634static void
4635scsi_low_calcf_show(li)
4636 struct lun_info *li;
4637{
4638 struct targ_info *ti = li->li_ti;
4639 struct scsi_low_softc *slp = ti->ti_sc;
4640
4641 printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
4642 slp->sl_xname, ti->ti_id, li->li_lun,
4643 ti->ti_maxsynch.period * 4,
4644 ti->ti_maxsynch.offset,
4645 ti->ti_width,
4646 li->li_flags, SCSI_LOW_BITS);
4647}
4648
4649#ifdef SCSI_LOW_START_UP_CHECK
4650/**************************************************************
4651 * scsi world start up
4652 **************************************************************/
4653static int scsi_low_poll(struct scsi_low_softc *, struct slccb *);
4654
4655static int
4656scsi_low_start_up(slp)
4657 struct scsi_low_softc *slp;
4658{
4659 struct targ_info *ti;
4660 struct lun_info *li;
4661 struct slccb *cb;
4662 int target, lun;
4663
4664 printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
4665
4666 for (target = 0; target < slp->sl_ntargs; target ++)
4667 {
4668 if (target == slp->sl_hostid)
4669 {
4670 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4671 {
4672 printf("%s: scsi_low: target %d (host card)\n",
4673 slp->sl_xname, target);
4674 }
4675 continue;
4676 }
4677
4678 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4679 {
4680 printf("%s: scsi_low: target %d lun ",
4681 slp->sl_xname, target);
4682 }
4683
4684 ti = slp->sl_ti[target];
4685 for (lun = 0; lun < slp->sl_nluns; lun ++)
4686 {
4687 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
4688 break;
4689
4690 cb->osdep = NULL;
4691 cb->bp = NULL;
4692
4693 li = scsi_low_alloc_li(ti, lun, 1);
4694
4695 scsi_low_enqueue(slp, ti, li, cb,
4696 CCB_AUTOSENSE | CCB_POLLED, 0);
4697
4698 scsi_low_poll(slp, cb);
4699
4700 if (li->li_state != SCSI_LOW_LUN_OK)
4701 break;
4702
4703 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4704 {
4705 printf("%d ", lun);
4706 }
4707 }
4708
4709 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
4710 {
4711 printf("\n");
4712 }
4713 }
4714 return 0;
4715}
4716
4717static int
4718scsi_low_poll(slp, cb)
4719 struct scsi_low_softc *slp;
4720 struct slccb *cb;
4721{
4722 int tcount;
4723
4724 tcount = 0;
4725 while (slp->sl_nio > 0)
4726 {
4727 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4728
4729 (*slp->sl_funcs->scsi_low_poll) (slp);
4730 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4731 continue;
4732
4733 tcount = 0;
4734 scsi_low_timeout_check(slp);
4735 }
4736
4737 return 0;
4738}
4739#endif /* SCSI_LOW_START_UP_CHECK */
4740
4741/**********************************************************
4742 * DEBUG SECTION
4743 **********************************************************/
4744#ifdef SCSI_LOW_DEBUG
4745static void
4746scsi_low_test_abort(slp, ti, li)
4747 struct scsi_low_softc *slp;
4748 struct targ_info *ti;
4749 struct lun_info *li;
4750{
4751 struct slccb *acb;
4752
4753 if (li->li_disc > 1)
4754 {
4755 acb = TAILQ_FIRST(&li->li_discq);
4756 if (scsi_low_abort_ccb(slp, acb) == 0)
4757 {
4758 printf("%s: aborting ccb(0x%lx) start\n",
4759 slp->sl_xname, (u_long) acb);
4760 }
4761 }
4762}
4763
4764static void
4765scsi_low_test_atten(slp, ti, msg)
4766 struct scsi_low_softc *slp;
4767 struct targ_info *ti;
4768 u_int msg;
4769{
4770
4771 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4772 scsi_low_assert_msg(slp, ti, msg, 0);
4773 else
4774 printf("%s: atten check OK\n", slp->sl_xname);
4775}
4776
4777static void
4778scsi_low_test_cmdlnk(slp, cb)
4779 struct scsi_low_softc *slp;
4780 struct slccb *cb;
4781{
4782#define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4783
4784 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4785 return;
4786
4787 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4788 slp->sl_scp.scp_cmdlen);
4789 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4790 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4791}
4792#endif /* SCSI_LOW_DEBUG */
4793
4794/* static */ void
4795scsi_low_info(slp, ti, s)
4796 struct scsi_low_softc *slp;
4797 struct targ_info *ti;
4798 u_char *s;
4799{
4800
4801 if (slp == NULL)
4802 slp = LIST_FIRST(&sl_tab);
4803 if (s == NULL)
4804 s = "no message";
4805
4806 printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4807 if (ti == NULL)
4808 {
4809 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4810 ti = TAILQ_NEXT(ti, ti_chain))
4811 {
4812 scsi_low_print(slp, ti);
4813 }
4814 }
4815 else
4816 {
4817 scsi_low_print(slp, ti);
4818 }
4819}
4820
4821static u_char *phase[] =
4822{
4823 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4824 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4825};
4826
4827void
4828scsi_low_print(slp, ti)
4829 struct scsi_low_softc *slp;
4830 struct targ_info *ti;
4831{
4832 struct lun_info *li;
4833 struct slccb *cb;
4834 struct sc_p *sp;
4835
4836 if (ti == NULL || ti == slp->sl_Tnexus)
4837 {
4838 ti = slp->sl_Tnexus;
4839 li = slp->sl_Lnexus;
4840 cb = slp->sl_Qnexus;
4841 }
4842 else
4843 {
4844 li = LIST_FIRST(&ti->ti_litab);
4845 cb = TAILQ_FIRST(&li->li_discq);
4846 }
4847 sp = &slp->sl_scp;
4848
4849 printf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4850 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4851 slp->sl_nio);
4852
4853 /* target stat */
4854 if (ti != NULL)
4855 {
4856 u_int flags = 0, maxnqio = 0, nqio = 0;
4857 int lun = -1;
4858
4859 if (li != NULL)
4860 {
4861 lun = li->li_lun;
4862 flags = li->li_flags;
4863 maxnqio = li->li_maxnqio;
4864 nqio = li->li_nqio;
4865 }
4866
4867 printf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4868 slp->sl_xname,
4869 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4870 phase[(int) ti->ti_phase], ti->ti_disc,
4871 nqio, maxnqio);
4872
4873 if (cb != NULL)
4874 {
4875printf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4876 (u_int) cb->ccb_scp.scp_cmd[0],
4877 cb->ccb_scp.scp_cmdlen,
4878 cb->ccb_datalen,
4879 cb->ccb_scp.scp_datalen,
4880 (u_int) cb->ccb_sscp.scp_status,
4881 cb->ccb_error, SCSI_LOW_ERRORBITS);
4882 }
4883
4884printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4885 (u_int) (ti->ti_msginptr),
4886 (u_int) (ti->ti_msgin[0]),
4887 (u_int) (ti->ti_msgin[1]),
4888 (u_int) (ti->ti_msgin[2]),
4889 (u_int) (ti->ti_msgin[3]),
4890 (u_int) (ti->ti_msgin[4]),
4891 slp->sl_atten);
4892
4893printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4894 (u_int) ti->ti_msgflags,
4895 (u_int) (ti->ti_msgoutstr[0]),
4896 (u_int) (ti->ti_msgoutstr[1]),
4897 (u_int) (ti->ti_msgoutstr[2]),
4898 (u_int) (ti->ti_msgoutstr[3]),
4899 (u_int) (ti->ti_msgoutstr[4]),
4900 ti->ti_msgoutlen,
4901 flags, SCSI_LOW_BITS);
4902
4903#ifdef SCSI_LOW_DIAGNOSTIC
4904 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4905 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4906#endif /* SCSI_LOW_DIAGNOSTIC */
4907
4908 }
4909
4910 printf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4911 (u_long) sp->scp_data,
4912 sp->scp_datalen,
4913 (u_int) sp->scp_status,
4914 slp->sl_error, SCSI_LOW_ERRORBITS);
4915}