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