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