kernel/bus: Remove some unused variables and put others in #ifdef...
[dragonfly.git] / sys / bus / cam / scsi / scsi_low.c
bloba4a0218e2cd6e8a96dc06c5577450eebbf161d1d
1 /*
2 * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $
3 * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $
4 */
6 #define SCSI_LOW_STATICS
7 #define SCSI_LOW_DEBUG
8 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
9 #define SCSI_LOW_START_UP_CHECK
11 /* #define SCSI_LOW_INFO_DETAIL */
12 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
13 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
15 #define SCSI_LOW_FLAGS_QUIRKS_OK
18 * [NetBSD for NEC PC-98 series]
19 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
20 * NetBSD/pc98 porting staff. All rights reserved.
21 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
22 * Naofumi HONDA. All rights reserved.
24 * [Ported for FreeBSD CAM]
25 * Copyright (c) 2000, 2001
26 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. The name of the author may not be used to endorse or promote products
38 * derived from this software without specific prior written permission.
40 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
42 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
44 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
45 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
49 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
50 * POSSIBILITY OF SUCH DAMAGE.
53 /* <On the nexus establishment>
54 * When our host is reselected,
55 * nexus establish processes are little complicated.
56 * Normal steps are followings:
57 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
58 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
59 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
62 #include <sys/param.h>
63 #include <sys/buf.h>
64 #include <sys/cons.h>
65 #include <sys/devicestat.h>
66 #include <sys/errno.h>
67 #include <sys/kernel.h>
68 #include <sys/malloc.h>
69 #include <sys/queue.h>
70 #include <sys/systm.h>
71 #include <sys/thread2.h>
73 #include <bus/cam/cam.h>
74 #include <bus/cam/cam_ccb.h>
75 #include <bus/cam/cam_sim.h>
76 #include <bus/cam/cam_debug.h>
77 #include <bus/cam/cam_periph.h>
78 #include <bus/cam/cam_xpt_periph.h>
80 #include <bus/cam/scsi/scsi_all.h>
81 #include <bus/cam/scsi/scsi_low.h>
83 /**************************************************************
84 * Constants
85 **************************************************************/
86 #define SCSI_LOW_POLL_HZ 1000
88 /* functions return values */
89 #define SCSI_LOW_START_NO_QTAG 0
90 #define SCSI_LOW_START_QTAG 1
92 #define SCSI_LOW_DONE_COMPLETE 0
93 #define SCSI_LOW_DONE_RETRY 1
95 /* internal disk flags */
96 #define SCSI_LOW_DISK_DISC 0x00000001
97 #define SCSI_LOW_DISK_QTAG 0x00000002
98 #define SCSI_LOW_DISK_LINK 0x00000004
99 #define SCSI_LOW_DISK_PARITY 0x00000008
100 #define SCSI_LOW_DISK_SYNC 0x00010000
101 #define SCSI_LOW_DISK_WIDE_16 0x00020000
102 #define SCSI_LOW_DISK_WIDE_32 0x00040000
103 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
104 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
105 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
107 MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
109 /**************************************************************
110 * Declarations
111 **************************************************************/
112 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
113 static void scsi_low_engage (void *);
114 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
115 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
116 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
117 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
118 static void scsi_low_twiddle_wait (void);
119 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
120 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
121 static void scsi_low_calcf_lun (struct lun_info *);
122 static void scsi_low_calcf_target (struct targ_info *);
123 static void scsi_low_calcf_show (struct lun_info *);
124 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
125 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
126 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
127 static int scsi_low_init (struct scsi_low_softc *, u_int);
128 static void scsi_low_start (struct scsi_low_softc *);
129 static void scsi_low_free_ti (struct scsi_low_softc *);
131 static int scsi_low_alloc_qtag (struct slccb *);
132 static int scsi_low_dealloc_qtag (struct slccb *);
133 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
134 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
135 static void scsi_low_unit_ready_cmd (struct slccb *);
136 static void scsi_low_timeout (void *);
137 static int scsi_low_timeout_check (struct scsi_low_softc *);
138 #ifdef SCSI_LOW_START_UP_CHECK
139 static int scsi_low_start_up (struct scsi_low_softc *);
140 #endif /* SCSI_LOW_START_UP_CHECK */
141 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
142 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
144 int scsi_low_version_major = 2;
145 int scsi_low_version_minor = 17;
147 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
149 /**************************************************************
150 * Debug, Run test and Statics
151 **************************************************************/
152 #ifdef SCSI_LOW_INFO_DETAIL
153 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
154 #else /* !SCSI_LOW_INFO_DETAIL */
155 #define SCSI_LOW_INFO(slp, ti, s) kprintf("%s: %s\n", (slp)->sl_xname, (s))
156 #endif /* !SCSI_LOW_INFO_DETAIL */
158 #ifdef SCSI_LOW_STATICS
159 static struct scsi_low_statics {
160 int nexus_win;
161 int nexus_fail;
162 int nexus_disconnected;
163 int nexus_reselected;
164 int nexus_conflict;
165 } scsi_low_statics;
166 #endif /* SCSI_LOW_STATICS */
168 #ifdef SCSI_LOW_DEBUG
169 #define SCSI_LOW_DEBUG_DONE 0x00001
170 #define SCSI_LOW_DEBUG_DISC 0x00002
171 #define SCSI_LOW_DEBUG_SENSE 0x00004
172 #define SCSI_LOW_DEBUG_CALCF 0x00008
173 #define SCSI_LOW_DEBUG_ACTION 0x10000
174 int scsi_low_debug = 0;
176 #define SCSI_LOW_MAX_ATTEN_CHECK 32
177 #define SCSI_LOW_ATTEN_CHECK 0x0001
178 #define SCSI_LOW_CMDLNK_CHECK 0x0002
179 #define SCSI_LOW_ABORT_CHECK 0x0004
180 #define SCSI_LOW_NEXUS_CHECK 0x0008
181 int scsi_low_test = 0;
182 int scsi_low_test_id = 0;
184 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
185 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
186 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
187 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
188 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
189 #define SCSI_LOW_DEBUG_GO(fl, id) \
190 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
191 #endif /* SCSI_LOW_DEBUG */
193 /**************************************************************
194 * CCB
195 **************************************************************/
196 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
197 GENERIC_CCB(scsi_low, slccb, ccb_chain)
199 /**************************************************************
200 * Inline functions
201 **************************************************************/
202 #define SCSI_LOW_INLINE static __inline
203 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
204 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
205 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
206 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
207 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
208 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
209 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
211 SCSI_LOW_INLINE void
212 scsi_low_activate_qtag(struct slccb *cb)
214 struct lun_info *li = cb->li;
216 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
217 return;
219 li->li_nqio ++;
220 cb->ccb_tag = cb->ccb_otag;
223 SCSI_LOW_INLINE void
224 scsi_low_deactivate_qtag(struct slccb *cb)
226 struct lun_info *li = cb->li;
228 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
229 return;
231 li->li_nqio --;
232 cb->ccb_tag = SCSI_LOW_UNKTAG;
235 SCSI_LOW_INLINE void
236 scsi_low_ccb_message_exec(struct scsi_low_softc *slp, struct slccb *cb)
238 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
239 cb->ccb_msgoutflag = 0;
242 SCSI_LOW_INLINE void
243 scsi_low_ccb_message_assert(struct slccb *cb, u_int msg)
245 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
248 SCSI_LOW_INLINE void
249 scsi_low_ccb_message_retry(struct slccb *cb)
251 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
254 SCSI_LOW_INLINE void
255 scsi_low_ccb_message_clear(struct slccb *cb)
257 cb->ccb_msgoutflag = 0;
260 SCSI_LOW_INLINE void
261 scsi_low_init_msgsys(struct scsi_low_softc *slp, struct targ_info *ti)
263 ti->ti_msginptr = 0;
264 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
265 SCSI_LOW_DEASSERT_ATN(slp);
266 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
269 /*=============================================================
270 * START OF OS switch (All OS depend fucntions should be here)
271 =============================================================*/
272 /* common os depend utitlities */
273 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
274 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
275 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
277 static u_int8_t scsi_low_cmd_flags[256] = {
278 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
279 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
280 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
281 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
282 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
285 struct scsi_low_error_code {
286 int error_bits;
287 int error_code;
290 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
291 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
293 static struct slccb *
294 scsi_low_find_ccb(struct scsi_low_softc *slp, u_int target, u_int lun, void *osdep)
296 struct targ_info *ti;
297 struct lun_info *li;
298 struct slccb *cb;
300 ti = slp->sl_ti[target];
301 li = scsi_low_alloc_li(ti, lun, 0);
302 if (li == NULL)
303 return NULL;
305 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
306 return cb;
308 TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
310 if (cb->osdep == osdep)
311 return cb;
314 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
316 if (cb->osdep == osdep)
317 return cb;
319 return NULL;
322 static int
323 scsi_low_translate_error_code(struct slccb *cb, struct scsi_low_error_code *tp)
325 if (cb->ccb_error == 0)
326 return tp->error_code;
328 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
330 return tp->error_code;
333 /**************************************************************
334 * SCSI INTERFACE (CAM)
335 **************************************************************/
336 #define SCSI_LOW_MALLOC(size) kmalloc((size), M_SCSILOW, M_INTWAIT)
337 #define SCSI_LOW_FREE(pt) kfree((pt), M_SCSILOW)
338 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
340 static void scsi_low_poll_cam (struct cam_sim *);
341 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
342 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
343 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
345 static int scsi_low_attach_cam (struct scsi_low_softc *);
346 static int scsi_low_world_start_cam (struct scsi_low_softc *);
347 static int scsi_low_dettach_cam (struct scsi_low_softc *);
348 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
349 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
350 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
352 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
353 scsi_low_attach_cam,
354 scsi_low_world_start_cam,
355 scsi_low_dettach_cam,
356 scsi_low_ccb_setup_cam,
357 scsi_low_done_cam,
358 scsi_low_timeout_cam
361 struct scsi_low_error_code scsi_low_error_code_cam[] = {
362 {0, CAM_REQ_CMP},
363 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
364 {SENSEERR, CAM_AUTOSENSE_FAIL},
365 {UACAERR, CAM_SCSI_STATUS_ERROR},
366 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
367 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
368 {TIMEOUTIO, CAM_CMD_TIMEOUT},
369 {PDMAERR, CAM_DATA_RUN_ERR},
370 {PARITYERR, CAM_UNCOR_PARITY},
371 {UBFERR, CAM_UNEXP_BUSFREE},
372 {ABORTIO, CAM_REQ_ABORTED},
373 {-1, CAM_UNREC_HBA_ERROR}
376 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
378 /* XXX:
379 * Please check a polling hz, currently we assume scsi_low_poll() is
380 * called each 1 ms.
382 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
384 static void
385 scsi_low_poll_cam(struct cam_sim *sim)
387 struct scsi_low_softc *slp = SIM2SLP(sim);
389 (*slp->sl_funcs->scsi_low_poll) (slp);
391 if (slp->sl_si.si_poll_count ++ >=
392 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
394 slp->sl_si.si_poll_count = 0;
395 scsi_low_timeout_check(slp);
399 static void
400 scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
402 xpt_free_path(ccb->ccb_h.path);
403 xpt_free_ccb(ccb);
406 static void
407 scsi_low_rescan_bus_cam(struct scsi_low_softc *slp)
409 struct cam_path *path;
410 union ccb *ccb = xpt_alloc_ccb();
411 cam_status status;
413 status = xpt_create_path(&path, xpt_periph,
414 cam_sim_path(slp->sl_si.sim), -1, 0);
415 if (status != CAM_REQ_CMP)
416 return;
418 xpt_setup_ccb(&ccb->ccb_h, path, 5);
419 ccb->ccb_h.func_code = XPT_SCAN_BUS;
420 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
421 ccb->crcn.flags = CAM_FLAG_NONE;
422 xpt_action(ccb);
425 void
426 scsi_low_scsi_action_cam(struct cam_sim *sim, union ccb *ccb)
428 struct scsi_low_softc *slp = SIM2SLP(sim);
429 struct targ_info *ti;
430 struct lun_info *li;
431 struct slccb *cb;
432 u_int lun, flags, msg, target;
433 int rv;
435 target = (u_int) (ccb->ccb_h.target_id);
436 lun = (u_int) ccb->ccb_h.target_lun;
438 #ifdef SCSI_LOW_DEBUG
439 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
441 kprintf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
442 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
444 #endif /* SCSI_LOW_DEBUG */
446 switch (ccb->ccb_h.func_code) {
447 case XPT_SCSI_IO: /* Execute the requested I/O operation */
448 #ifdef SCSI_LOW_DIAGNOSTIC
449 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
451 kprintf("%s: invalid target/lun\n", slp->sl_xname);
452 ccb->ccb_h.status = CAM_REQ_INVALID;
453 xpt_done(ccb);
454 return;
456 #endif /* SCSI_LOW_DIAGNOSTIC */
458 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
459 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
460 xpt_done(ccb);
461 return;
464 ti = slp->sl_ti[target];
465 cb->osdep = ccb;
466 cb->bp = NULL;
467 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
468 flags = CCB_AUTOSENSE | CCB_SCSIIO;
469 else
470 flags = CCB_SCSIIO;
472 crit_enter();
473 li = scsi_low_alloc_li(ti, lun, 1);
475 if (ti->ti_setup_msg != 0)
477 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
480 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
482 #ifdef SCSI_LOW_DEBUG
483 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
485 scsi_low_test_abort(slp, ti, li);
487 #endif /* SCSI_LOW_DEBUG */
488 crit_exit();
489 break;
491 case XPT_EN_LUN: /* Enable LUN as a target */
492 case XPT_TARGET_IO: /* Execute target I/O request */
493 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
494 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
495 /* XXX Implement */
496 ccb->ccb_h.status = CAM_REQ_INVALID;
497 xpt_done(ccb);
498 break;
500 case XPT_ABORT: /* Abort the specified CCB */
501 #ifdef SCSI_LOW_DIAGNOSTIC
502 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
504 kprintf("%s: invalid target/lun\n", slp->sl_xname);
505 ccb->ccb_h.status = CAM_REQ_INVALID;
506 xpt_done(ccb);
507 return;
509 #endif /* SCSI_LOW_DIAGNOSTIC */
511 crit_enter();
512 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
513 rv = scsi_low_abort_ccb(slp, cb);
514 crit_exit();
516 if (rv == 0)
517 ccb->ccb_h.status = CAM_REQ_CMP;
518 else
519 ccb->ccb_h.status = CAM_REQ_INVALID;
520 xpt_done(ccb);
521 break;
523 case XPT_SET_TRAN_SETTINGS: {
524 struct ccb_trans_settings_scsi *scsi;
525 struct ccb_trans_settings_spi *spi;
526 struct ccb_trans_settings *cts;
527 u_int val;
529 #ifdef SCSI_LOW_DIAGNOSTIC
530 if (target == CAM_TARGET_WILDCARD)
532 kprintf("%s: invalid target\n", slp->sl_xname);
533 ccb->ccb_h.status = CAM_REQ_INVALID;
534 xpt_done(ccb);
535 return;
537 #endif /* SCSI_LOW_DIAGNOSTIC */
538 cts = &ccb->cts;
539 ti = slp->sl_ti[target];
540 if (lun == CAM_LUN_WILDCARD)
541 lun = 0;
543 crit_enter();
544 scsi = &cts->proto_specific.scsi;
545 spi = &cts->xport_specific.spi;
546 if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH |
547 CTS_SPI_VALID_SYNC_RATE |
548 CTS_SPI_VALID_SYNC_OFFSET)) != 0)
550 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
551 val = spi->bus_width;
552 if (val < ti->ti_width)
553 ti->ti_width = val;
555 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
556 val = spi->sync_period;
557 if (val == 0 || val > ti->ti_maxsynch.period)
558 ti->ti_maxsynch.period = val;
560 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
561 val = spi->sync_offset;
562 if (val < ti->ti_maxsynch.offset)
563 ti->ti_maxsynch.offset = val;
565 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
566 scsi_low_calcf_target(ti);
569 if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 ||
570 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
572 li = scsi_low_alloc_li(ti, lun, 1);
573 if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) {
574 li->li_quirks |= SCSI_LOW_DISK_DISC;
575 } else {
576 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
579 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
580 li->li_quirks |= SCSI_LOW_DISK_QTAG;
581 } else {
582 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
584 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
585 scsi_low_calcf_target(ti);
586 scsi_low_calcf_lun(li);
587 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
588 scsi_low_calcf_show(li);
590 crit_exit();
592 ccb->ccb_h.status = CAM_REQ_CMP;
593 xpt_done(ccb);
594 break;
597 case XPT_GET_TRAN_SETTINGS: {
598 struct ccb_trans_settings *cts;
599 u_int diskflags;
601 cts = &ccb->cts;
602 #ifdef SCSI_LOW_DIAGNOSTIC
603 if (target == CAM_TARGET_WILDCARD)
605 kprintf("%s: invalid target\n", slp->sl_xname);
606 ccb->ccb_h.status = CAM_REQ_INVALID;
607 xpt_done(ccb);
608 return;
610 #endif /* SCSI_LOW_DIAGNOSTIC */
611 ti = slp->sl_ti[target];
612 if (lun == CAM_LUN_WILDCARD)
613 lun = 0;
615 crit_enter();
616 li = scsi_low_alloc_li(ti, lun, 1);
617 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
618 struct ccb_trans_settings_scsi *scsi =
619 &cts->proto_specific.scsi;
620 struct ccb_trans_settings_spi *spi =
621 &cts->xport_specific.spi;
622 #ifdef SCSI_LOW_DIAGNOSTIC
623 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
625 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
626 kprintf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
627 slp->sl_xname);
628 goto settings_out;
630 #endif /* SCSI_LOW_DIAGNOSTIC */
631 cts->protocol = PROTO_SCSI;
632 cts->protocol_version = SCSI_REV_2;
633 cts->transport = XPORT_SPI;
634 cts->transport_version = 2;
636 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
637 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
639 diskflags = li->li_diskflags & li->li_cfgflags;
640 if (diskflags & SCSI_LOW_DISK_DISC)
641 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
642 if (diskflags & SCSI_LOW_DISK_QTAG)
643 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
645 spi->sync_period = ti->ti_maxsynch.period;
646 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
647 spi->sync_offset = ti->ti_maxsynch.offset;
648 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
650 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
651 spi->bus_width = ti->ti_width;
653 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
654 scsi->valid = CTS_SCSI_VALID_TQ;
655 spi->valid |= CTS_SPI_VALID_DISC;
656 } else
657 scsi->valid = 0;
658 } else
659 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
660 settings_out:
661 crit_exit();
662 xpt_done(ccb);
663 break;
666 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
667 cam_calc_geometry(&ccb->ccg, /*extended*/1);
668 xpt_done(ccb);
669 break;
672 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
673 crit_enter();
674 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
675 crit_exit();
676 ccb->ccb_h.status = CAM_REQ_CMP;
677 xpt_done(ccb);
678 break;
680 case XPT_TERM_IO: /* Terminate the I/O process */
681 ccb->ccb_h.status = CAM_REQ_INVALID;
682 xpt_done(ccb);
683 break;
685 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
686 #ifdef SCSI_LOW_DIAGNOSTIC
687 if (target == CAM_TARGET_WILDCARD)
689 kprintf("%s: invalid target\n", slp->sl_xname);
690 ccb->ccb_h.status = CAM_REQ_INVALID;
691 xpt_done(ccb);
692 return;
694 #endif /* SCSI_LOW_DIAGNOSTIC */
696 msg = SCSI_LOW_MSG_RESET;
697 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
699 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
700 xpt_done(ccb);
701 return;
704 ti = slp->sl_ti[target];
705 if (lun == CAM_LUN_WILDCARD)
706 lun = 0;
707 cb->osdep = ccb;
708 cb->bp = NULL;
709 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
710 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
711 else
712 flags = CCB_NORETRY | CCB_URGENT;
714 crit_enter();
715 li = scsi_low_alloc_li(ti, lun, 1);
716 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
717 crit_exit();
718 break;
720 case XPT_PATH_INQ: { /* Path routing inquiry */
721 struct ccb_pathinq *cpi = &ccb->cpi;
723 cpi->version_num = scsi_low_version_major;
724 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
725 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
726 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
727 cpi->hba_inquiry |= PI_WIDE_16;
728 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
729 cpi->hba_inquiry |= PI_WIDE_32;
730 if (ti->ti_maxsynch.offset > 0)
731 cpi->hba_inquiry |= PI_SDTR_ABLE;
732 cpi->target_sprt = 0;
733 cpi->hba_misc = 0;
734 cpi->hba_eng_cnt = 0;
735 cpi->max_target = slp->sl_ntargs - 1;
736 cpi->max_lun = slp->sl_nluns - 1;
737 cpi->initiator_id = slp->sl_hostid;
738 cpi->bus_id = cam_sim_bus(sim);
739 cpi->base_transfer_speed = 3300;
740 cpi->transport = XPORT_SPI;
741 cpi->transport_version = 2;
742 cpi->protocol = PROTO_SCSI;
743 cpi->protocol_version = SCSI_REV_2;
744 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
745 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
746 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
747 cpi->unit_number = cam_sim_unit(sim);
748 cpi->ccb_h.status = CAM_REQ_CMP;
749 xpt_done(ccb);
750 break;
753 default:
754 kprintf("scsi_low: non support func_code = %d ",
755 ccb->ccb_h.func_code);
756 ccb->ccb_h.status = CAM_REQ_INVALID;
757 xpt_done(ccb);
758 break;
762 static int
763 scsi_low_attach_cam(struct scsi_low_softc *slp)
765 struct cam_devq *devq;
766 int tagged_openings;
768 ksprintf(slp->sl_xname, "%s%d",
769 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
771 devq = cam_simq_alloc(SCSI_LOW_NCCB);
772 if (devq == NULL)
773 return (ENOMEM);
776 * ask the adapter what subunits are present
778 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
779 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
780 scsi_low_poll_cam,
781 DEVPORT_DEVNAME(slp->sl_dev), slp,
782 DEVPORT_DEVUNIT(slp->sl_dev), &sim_mplock,
783 slp->sl_openings, tagged_openings, devq);
784 cam_simq_release(devq);
785 if (slp->sl_si.sim == NULL) {
786 return ENODEV;
789 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
790 cam_sim_free(slp->sl_si.sim);
791 slp->sl_si.sim = NULL;
792 return ENODEV;
795 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
796 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
797 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
798 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
799 cam_sim_free(slp->sl_si.sim);
800 slp->sl_si.sim = NULL;
801 return ENODEV;
804 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
805 return 0;
808 static int
809 scsi_low_world_start_cam(struct scsi_low_softc *slp)
811 #if 0
812 if (!cold)
813 scsi_low_rescan_bus_cam(slp);
814 #endif
815 scsi_low_rescan_bus_cam(slp);
816 return 0;
819 static int
820 scsi_low_dettach_cam(struct scsi_low_softc *slp)
822 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
823 xpt_free_path(slp->sl_si.path);
824 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
825 cam_sim_free(slp->sl_si.sim);
826 slp->sl_si.sim = NULL;
827 return 0;
830 static int
831 scsi_low_ccb_setup_cam(struct scsi_low_softc *slp, struct slccb *cb)
833 union ccb *ccb = (union ccb *) cb->osdep;
835 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
837 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
838 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
839 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
840 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
841 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
842 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
843 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
844 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
845 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
847 else
849 scsi_low_unit_ready_cmd(cb);
851 return SCSI_LOW_START_QTAG;
854 static int
855 scsi_low_done_cam(struct scsi_low_softc *slp, struct slccb *cb)
857 union ccb *ccb;
859 ccb = (union ccb *) cb->osdep;
860 if (cb->ccb_error == 0)
862 ccb->ccb_h.status = CAM_REQ_CMP;
863 ccb->csio.resid = 0;
865 else
867 if (cb->ccb_rcnt >= slp->sl_max_retry)
868 cb->ccb_error |= ABORTIO;
870 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
871 (cb->ccb_error & ABORTIO) == 0)
872 return EJUSTRETURN;
874 if ((cb->ccb_error & SENSEIO) != 0)
876 memcpy(&ccb->csio.sense_data,
877 &cb->ccb_sense,
878 sizeof(ccb->csio.sense_data));
881 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
882 &scsi_low_error_code_cam[0]);
884 #ifdef SCSI_LOW_DIAGNOSTIC
885 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
886 cb->ccb_scp.scp_cmdlen > 0 &&
887 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
888 SCSI_LOW_CMD_ABORT_WARNING) != 0)
890 kprintf("%s: WARNING: scsi_low IO abort\n",
891 slp->sl_xname);
892 scsi_low_print(slp, NULL);
894 #endif /* SCSI_LOW_DIAGNOSTIC */
897 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
898 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
900 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
901 ccb->csio.scsi_status = 0; /* XXX */
902 else
903 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
905 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
906 xpt_done(ccb);
907 return 0;
910 static void
911 scsi_low_timeout_cam(struct scsi_low_softc *slp, int ch, int action)
913 switch (ch)
915 case SCSI_LOW_TIMEOUT_CH_IO:
916 switch (action)
918 case SCSI_LOW_TIMEOUT_START:
919 callout_reset(&slp->sl_si.timeout_ch,
920 hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
921 break;
922 case SCSI_LOW_TIMEOUT_STOP:
923 callout_stop(&slp->sl_si.timeout_ch);
924 break;
926 break;
928 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
929 switch (action)
931 case SCSI_LOW_TIMEOUT_START:
932 callout_reset(&slp->sl_si.engage_ch, 1,
933 scsi_low_engage, slp);
934 break;
935 case SCSI_LOW_TIMEOUT_STOP:
936 callout_stop(&slp->sl_si.engage_ch);
937 break;
939 break;
940 case SCSI_LOW_TIMEOUT_CH_RECOVER:
941 break;
945 /**************************************************************
946 * scsi low deactivate and activate
947 **************************************************************/
949 scsi_low_is_busy(struct scsi_low_softc *slp)
951 if (slp->sl_nio > 0)
952 return EBUSY;
953 return 0;
957 scsi_low_deactivate(struct scsi_low_softc *slp)
959 crit_enter();
960 slp->sl_flags |= HW_INACTIVE;
961 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
962 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
963 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
964 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
965 crit_exit();
966 return 0;
970 scsi_low_activate(struct scsi_low_softc *slp)
972 int error;
974 crit_enter();
975 slp->sl_flags &= ~HW_INACTIVE;
976 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
978 slp->sl_flags |= HW_INACTIVE;
979 crit_exit();
980 return error;
983 slp->sl_timeout_count = 0;
984 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
985 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
986 crit_exit();
987 return 0;
990 /**************************************************************
991 * scsi low log
992 **************************************************************/
993 #ifdef SCSI_LOW_DIAGNOSTIC
994 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
995 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
996 int);
997 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
999 static void
1000 scsi_low_msg_log_init(struct scsi_low_msg_log *slmlp)
1002 slmlp->slml_ptr = 0;
1005 static void
1006 scsi_low_msg_log_write(struct scsi_low_msg_log *slmlp, u_int8_t *datap, int len)
1008 int ptr, ind;
1010 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1011 return;
1013 ptr = slmlp->slml_ptr ++;
1014 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1015 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1016 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1017 slmlp->slml_msg[ptr].msg[ind] = 0;
1020 static void
1021 scsi_low_msg_log_show(struct scsi_low_msg_log *slmlp, char *s, int len)
1023 int ptr, ind;
1025 kprintf("%s: (%d) ", s, slmlp->slml_ptr);
1026 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1028 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1029 ind ++)
1031 kprintf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1033 kprintf(">");
1035 kprintf("\n");
1037 #endif /* SCSI_LOW_DIAGNOSTIC */
1039 /**************************************************************
1040 * power control
1041 **************************************************************/
1042 static void
1043 scsi_low_engage(void *arg)
1045 struct scsi_low_softc *slp = arg;
1047 crit_enter();
1049 switch (slp->sl_rstep)
1051 case 0:
1052 slp->sl_rstep ++;
1053 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1054 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1055 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1056 break;
1058 case 1:
1059 slp->sl_rstep ++;
1060 slp->sl_flags &= ~HW_RESUME;
1061 scsi_low_start(slp);
1062 break;
1064 case 2:
1065 break;
1067 crit_exit();
1070 static int
1071 scsi_low_init(struct scsi_low_softc *slp, u_int flags)
1073 int rv = 0;
1075 slp->sl_flags |= HW_INITIALIZING;
1077 /* clear power control timeout */
1078 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1080 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1081 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1082 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1083 slp->sl_active = 1;
1084 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1087 /* reset current nexus */
1088 scsi_low_reset_nexus(slp, flags);
1089 if ((slp->sl_flags & HW_INACTIVE) != 0)
1091 rv = EBUSY;
1092 goto out;
1095 if (flags != SCSI_LOW_RESTART_SOFT)
1097 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1100 out:
1101 slp->sl_flags &= ~HW_INITIALIZING;
1102 return rv;
1105 /**************************************************************
1106 * allocate lun_info
1107 **************************************************************/
1108 static struct lun_info *
1109 scsi_low_alloc_li(struct targ_info *ti, int lun, int alloc)
1111 struct scsi_low_softc *slp = ti->ti_sc;
1112 struct lun_info *li;
1114 li = LIST_FIRST(&ti->ti_litab);
1115 if (li != NULL)
1117 if (li->li_lun == lun)
1118 return li;
1120 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1122 if (li->li_lun == lun)
1124 LIST_REMOVE(li, lun_chain);
1125 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1126 return li;
1131 if (alloc == 0)
1132 return li;
1134 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1135 if (li == NULL)
1136 panic("no lun info mem");
1138 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1139 li->li_lun = lun;
1140 li->li_ti = ti;
1142 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1143 SCSI_LOW_QTAG;
1144 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1145 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1146 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1147 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1148 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1150 li->li_qtagbits = (u_int) -1;
1152 TAILQ_INIT(&li->li_discq);
1153 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1155 /* host specific structure initialization per lun */
1156 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1157 (*slp->sl_funcs->scsi_low_lun_init)
1158 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1159 scsi_low_calcf_lun(li);
1160 return li;
1163 /**************************************************************
1164 * allocate targ_info
1165 **************************************************************/
1166 static struct targ_info *
1167 scsi_low_alloc_ti(struct scsi_low_softc *slp, int targ)
1169 struct targ_info *ti;
1171 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1172 TAILQ_INIT(&slp->sl_titab);
1174 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1175 if (ti == NULL)
1176 panic("%s short of memory", slp->sl_xname);
1178 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1179 ti->ti_id = targ;
1180 ti->ti_sc = slp;
1182 slp->sl_ti[targ] = ti;
1183 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1184 LIST_INIT(&ti->ti_litab);
1186 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1187 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1188 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1189 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1190 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1191 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1193 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1195 (*slp->sl_funcs->scsi_low_targ_init)
1196 (slp, ti, SCSI_LOW_INFO_ALLOC);
1198 scsi_low_calcf_target(ti);
1199 return ti;
1202 static void
1203 scsi_low_free_ti(struct scsi_low_softc *slp)
1205 struct targ_info *ti, *tib;
1206 struct lun_info *li, *nli;
1208 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1210 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1212 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1214 (*slp->sl_funcs->scsi_low_lun_init)
1215 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1217 nli = LIST_NEXT(li, lun_chain);
1218 SCSI_LOW_FREE(li);
1221 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1223 (*slp->sl_funcs->scsi_low_targ_init)
1224 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1226 tib = TAILQ_NEXT(ti, ti_chain);
1227 SCSI_LOW_FREE(ti);
1231 /**************************************************************
1232 * timeout
1233 **************************************************************/
1234 void
1235 scsi_low_bus_idle(struct scsi_low_softc *slp)
1237 slp->sl_retry_sel = 0;
1238 if (slp->sl_Tnexus == NULL)
1239 scsi_low_start(slp);
1242 static void
1243 scsi_low_timeout(void *arg)
1245 struct scsi_low_softc *slp = arg;
1247 crit_enter();
1248 scsi_low_timeout_check(slp);
1249 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1250 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1251 crit_exit();
1254 static int
1255 scsi_low_timeout_check(struct scsi_low_softc *slp)
1257 struct targ_info *ti;
1258 struct lun_info *li;
1259 struct slccb *cb = NULL; /* XXX */
1261 /* selection restart */
1262 if (slp->sl_retry_sel != 0)
1264 slp->sl_retry_sel = 0;
1265 if (slp->sl_Tnexus != NULL)
1266 goto step1;
1268 cb = TAILQ_FIRST(&slp->sl_start);
1269 if (cb == NULL)
1270 goto step1;
1272 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1274 cb->ccb_flags |= CCB_NORETRY;
1275 cb->ccb_error |= SELTIMEOUTIO;
1276 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1277 panic("%s: ccb not finished", slp->sl_xname);
1280 if (slp->sl_Tnexus == NULL)
1281 scsi_low_start(slp);
1284 /* call hardware timeout */
1285 step1:
1286 if (slp->sl_funcs->scsi_low_timeout != NULL)
1288 (*slp->sl_funcs->scsi_low_timeout) (slp);
1291 if (slp->sl_timeout_count ++ <
1292 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1293 return 0;
1295 slp->sl_timeout_count = 0;
1296 if (slp->sl_nio > 0)
1298 if ((cb = slp->sl_Qnexus) != NULL)
1300 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1301 if (cb->ccb_tc < 0)
1302 goto bus_reset;
1304 else if (slp->sl_disc == 0)
1306 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1307 return 0;
1309 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1310 if (cb->ccb_tc < 0)
1311 goto bus_reset;
1313 else TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
1315 if (ti->ti_disc == 0)
1316 continue;
1318 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
1320 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
1322 cb->ccb_tc -=
1323 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1324 if (cb->ccb_tc < 0)
1325 goto bus_reset;
1331 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1333 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1334 return 0;
1336 if (slp->sl_active != 0)
1338 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1339 slp->sl_active = 0;
1340 return 0;
1343 slp->sl_powc --;
1344 if (slp->sl_powc < 0)
1346 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1347 slp->sl_flags |= HW_POWDOWN;
1348 (*slp->sl_funcs->scsi_low_power)
1349 (slp, SCSI_LOW_POWDOWN);
1352 return 0;
1354 bus_reset:
1355 cb->ccb_error |= TIMEOUTIO;
1356 kprintf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1357 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1358 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1359 scsi_low_start(slp);
1360 return ERESTART;
1364 static int
1365 scsi_low_abort_ccb(struct scsi_low_softc *slp, struct slccb *cb)
1367 struct targ_info *ti;
1368 u_int msg;
1370 if (cb == NULL)
1371 return EINVAL;
1372 if ((cb->ccb_omsgoutflag &
1373 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1374 return EBUSY;
1376 ti = cb->ti;
1377 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1378 msg = SCSI_LOW_MSG_ABORT;
1379 else
1380 msg = SCSI_LOW_MSG_ABORT_QTAG;
1382 cb->ccb_error |= ABORTIO;
1383 cb->ccb_flags |= CCB_NORETRY;
1384 scsi_low_ccb_message_assert(cb, msg);
1386 if (cb == slp->sl_Qnexus)
1388 scsi_low_assert_msg(slp, ti, msg, 1);
1390 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1392 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1393 panic("%s: revoked ccb done", slp->sl_xname);
1395 cb->ccb_flags |= CCB_STARTQ;
1396 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1398 if (slp->sl_Tnexus == NULL)
1399 scsi_low_start(slp);
1401 else
1403 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1404 panic("%s: revoked ccb retried", slp->sl_xname);
1406 return 0;
1409 /**************************************************************
1410 * Generic SCSI INTERFACE
1411 **************************************************************/
1413 scsi_low_attach(struct scsi_low_softc *slp, int openings, int ntargs, int nluns,
1414 int targsize, int lunsize)
1416 struct targ_info *ti;
1417 struct lun_info *li;
1418 int i, nccb, rv;
1420 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1422 if (slp->sl_osdep_fp == NULL)
1423 panic("scsi_low: interface not spcified");
1425 if (ntargs > SCSI_LOW_NTARGETS)
1427 kprintf("scsi_low: %d targets are too large\n", ntargs);
1428 kprintf("change kernel options SCSI_LOW_NTARGETS");
1429 return EINVAL;
1432 if (openings <= 0)
1433 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1434 else
1435 slp->sl_openings = openings;
1436 slp->sl_ntargs = ntargs;
1437 slp->sl_nluns = nluns;
1438 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1440 if (lunsize < sizeof(struct lun_info))
1441 lunsize = sizeof(struct lun_info);
1443 if (targsize < sizeof(struct targ_info))
1444 targsize = sizeof(struct targ_info);
1446 slp->sl_targsize = targsize;
1447 for (i = 0; i < ntargs; i ++)
1449 ti = scsi_low_alloc_ti(slp, i);
1450 ti->ti_lunsize = lunsize;
1451 li = scsi_low_alloc_li(ti, 0, 1);
1454 /* initialize queue */
1455 nccb = openings * ntargs;
1456 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1457 nccb = SCSI_LOW_NCCB;
1458 scsi_low_init_ccbque(nccb);
1459 TAILQ_INIT(&slp->sl_start);
1461 /* call os depend attach */
1462 callout_init(&slp->sl_si.timeout_ch);
1463 callout_init(&slp->sl_si.engage_ch);
1465 crit_enter();
1466 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1467 if (rv != 0)
1469 crit_exit();
1470 kprintf("%s: scsi_low_attach: osdep attach failed\n",
1471 slp->sl_xname);
1472 return EINVAL;
1475 /* check hardware */
1476 SCSI_LOW_DELAY(1000); /* wait for 1ms */
1477 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1479 crit_exit();
1480 kprintf("%s: scsi_low_attach: initialization failed\n",
1481 slp->sl_xname);
1482 return EINVAL;
1485 /* start watch dog */
1486 slp->sl_timeout_count = 0;
1487 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1488 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1489 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1491 /* fake call */
1492 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1494 #ifdef SCSI_LOW_START_UP_CHECK
1495 /* probing devices */
1496 scsi_low_start_up(slp);
1497 #endif /* SCSI_LOW_START_UP_CHECK */
1499 /* call os depend attach done*/
1500 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1501 crit_exit();
1502 return 0;
1506 scsi_low_dettach(struct scsi_low_softc *slp)
1508 int rv;
1510 crit_enter();
1511 if (scsi_low_is_busy(slp) != 0)
1513 crit_exit();
1514 return EBUSY;
1517 scsi_low_deactivate(slp);
1519 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1520 if (rv != 0)
1522 crit_exit();
1523 return EBUSY;
1526 scsi_low_free_ti(slp);
1527 LIST_REMOVE(slp, sl_chain);
1528 crit_exit();
1529 return 0;
1532 /**************************************************************
1533 * Generic enqueue
1534 **************************************************************/
1535 static int
1536 scsi_low_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1537 struct lun_info *li, struct slccb *cb, u_int flags,
1538 u_int msg)
1541 cb->ti = ti;
1542 cb->li = li;
1544 scsi_low_ccb_message_assert(cb, msg);
1546 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1547 scsi_low_alloc_qtag(cb);
1549 cb->ccb_flags = flags | CCB_STARTQ;
1550 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1551 cb->ccb_error |= PENDINGIO;
1553 if ((flags & CCB_URGENT) != 0)
1555 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1557 else
1559 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1562 slp->sl_nio ++;
1564 if (slp->sl_Tnexus == NULL)
1565 scsi_low_start(slp);
1566 return 0;
1569 static int
1570 scsi_low_message_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1571 struct lun_info *li, u_int flags)
1573 struct slccb *cb;
1574 u_int tmsgflags;
1576 tmsgflags = ti->ti_setup_msg;
1577 ti->ti_setup_msg = 0;
1579 flags |= CCB_NORETRY;
1580 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1581 return ENOMEM;
1583 cb->osdep = NULL;
1584 cb->bp = NULL;
1585 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1586 return 0;
1589 /**************************************************************
1590 * Generic Start & Done
1591 **************************************************************/
1592 #define SLSC_MODE_SENSE_SHORT 0x1a
1593 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1594 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1595 sizeof(struct scsi_low_mode_sense_data), 0};
1596 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1597 sizeof(struct scsi_low_inq_data), 0};
1598 static u_int8_t unit_ready_cmd[6];
1599 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1600 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1601 static int scsi_low_resume (struct scsi_low_softc *);
1603 static void
1604 scsi_low_unit_ready_cmd(struct slccb *cb)
1606 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1607 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1608 cb->ccb_scp.scp_datalen = 0;
1609 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1610 cb->ccb_tcmax = 15;
1613 static int
1614 scsi_low_sense_abort_start(struct scsi_low_softc *slp, struct targ_info *ti,
1615 struct lun_info *li, struct slccb *cb)
1617 cb->ccb_scp.scp_cmdlen = 6;
1618 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1619 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1620 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1621 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1622 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1623 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1624 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1625 cb->ccb_tcmax = 15;
1626 scsi_low_ccb_message_clear(cb);
1627 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1629 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1631 else
1633 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1634 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1635 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1636 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1639 return SCSI_LOW_START_NO_QTAG;
1642 static int
1643 scsi_low_setup_start(struct scsi_low_softc *slp, struct targ_info *ti,
1644 struct lun_info *li, struct slccb *cb)
1646 switch(li->li_state)
1648 case SCSI_LOW_LUN_SLEEP:
1649 scsi_low_unit_ready_cmd(cb);
1650 break;
1652 case SCSI_LOW_LUN_START:
1653 cb->ccb_scp.scp_cmd = ss_cmd;
1654 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1655 cb->ccb_scp.scp_datalen = 0;
1656 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1657 cb->ccb_tcmax = 30;
1658 break;
1660 case SCSI_LOW_LUN_INQ:
1661 cb->ccb_scp.scp_cmd = inq_cmd;
1662 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1663 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1664 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1665 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1666 cb->ccb_tcmax = 15;
1667 break;
1669 case SCSI_LOW_LUN_MODEQ:
1670 cb->ccb_scp.scp_cmd = sms_cmd;
1671 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1672 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1673 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1674 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1675 cb->ccb_tcmax = 15;
1676 return SCSI_LOW_START_QTAG;
1678 default:
1679 panic("%s: no setup phase", slp->sl_xname);
1682 return SCSI_LOW_START_NO_QTAG;
1685 static int
1686 scsi_low_resume(struct scsi_low_softc *slp)
1688 if (slp->sl_flags & HW_RESUME)
1689 return EJUSTRETURN;
1690 slp->sl_flags &= ~HW_POWDOWN;
1691 if (slp->sl_funcs->scsi_low_power != NULL)
1693 slp->sl_flags |= HW_RESUME;
1694 slp->sl_rstep = 0;
1695 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1696 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1697 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1698 SCSI_LOW_TIMEOUT_START);
1699 return EJUSTRETURN;
1701 return 0;
1704 static void
1705 scsi_low_start(struct scsi_low_softc *slp)
1707 struct targ_info *ti;
1708 struct lun_info *li;
1709 struct slccb *cb;
1710 int rv;
1712 /* check hardware exists or under initializations ? */
1713 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1714 return;
1716 /* check hardware power up ? */
1717 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1719 slp->sl_active ++;
1720 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1722 if (scsi_low_resume(slp) == EJUSTRETURN)
1723 return;
1727 /* setup nexus */
1728 #ifdef SCSI_LOW_DIAGNOSTIC
1729 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1731 scsi_low_info(slp, NULL, "NEXUS INCONSISTENT");
1732 panic("%s: inconsistent", slp->sl_xname);
1734 #endif /* SCSI_LOW_DIAGNOSTIC */
1736 TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
1738 li = cb->li;
1740 if (li->li_disc == 0)
1742 goto scsi_low_cmd_start;
1744 else if (li->li_nqio > 0)
1746 if (li->li_nqio < li->li_maxnqio ||
1747 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1748 goto scsi_low_cmd_start;
1751 return;
1753 scsi_low_cmd_start:
1754 cb->ccb_flags &= ~CCB_STARTQ;
1755 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1756 ti = cb->ti;
1758 /* clear all error flag bits (for restart) */
1759 cb->ccb_error = 0;
1760 cb->ccb_datalen = -1;
1761 cb->ccb_scp.scp_status = ST_UNKNOWN;
1763 /* setup nexus pointer */
1764 slp->sl_Qnexus = cb;
1765 slp->sl_Lnexus = li;
1766 slp->sl_Tnexus = ti;
1768 /* initialize msgsys */
1769 scsi_low_init_msgsys(slp, ti);
1771 /* exec cmd */
1772 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1774 /* CA state or forced abort */
1775 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1777 else if (li->li_state >= SCSI_LOW_LUN_OK)
1779 cb->ccb_flags &= ~CCB_INTERNAL;
1780 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1781 if (cb->ccb_msgoutflag != 0)
1783 scsi_low_ccb_message_exec(slp, cb);
1786 else
1788 cb->ccb_flags |= CCB_INTERNAL;
1789 rv = scsi_low_setup_start(slp, ti, li, cb);
1792 /* allocate qtag */
1793 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1795 if (rv == SCSI_LOW_START_QTAG &&
1796 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1797 li->li_maxnqio > 0)
1799 u_int qmsg;
1801 scsi_low_activate_qtag(cb);
1802 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1803 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1804 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1805 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1806 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1807 else
1808 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1809 scsi_low_assert_msg(slp, ti, qmsg, 0);
1812 /* timeout */
1813 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1814 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1815 cb->ccb_tc = cb->ccb_tcmax;
1817 /* setup saved scsi data pointer */
1818 cb->ccb_sscp = cb->ccb_scp;
1820 /* setup current scsi pointer */
1821 slp->sl_scp = cb->ccb_sscp;
1822 slp->sl_error = cb->ccb_error;
1824 /* assert always an identify msg */
1825 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1827 /* debug section */
1828 #ifdef SCSI_LOW_DIAGNOSTIC
1829 scsi_low_msg_log_init(&ti->ti_log_msgin);
1830 scsi_low_msg_log_init(&ti->ti_log_msgout);
1831 #endif /* SCSI_LOW_DIAGNOSTIC */
1833 /* selection start */
1834 slp->sl_selid = cb;
1835 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1836 if (rv == SCSI_LOW_START_OK)
1838 #ifdef SCSI_LOW_STATICS
1839 scsi_low_statics.nexus_win ++;
1840 #endif /* SCSI_LOW_STATICS */
1841 return;
1844 scsi_low_arbit_fail(slp, cb);
1845 #ifdef SCSI_LOW_STATICS
1846 scsi_low_statics.nexus_fail ++;
1847 #endif /* SCSI_LOW_STATICS */
1850 void
1851 scsi_low_arbit_fail(struct scsi_low_softc *slp, struct slccb *cb)
1853 struct targ_info *ti = cb->ti;
1855 scsi_low_deactivate_qtag(cb);
1856 scsi_low_ccb_message_retry(cb);
1857 cb->ccb_flags |= CCB_STARTQ;
1858 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1860 scsi_low_bus_release(slp, ti);
1862 cb->ccb_selrcnt ++;
1863 if (slp->sl_disc == 0)
1865 #ifdef SCSI_LOW_DIAGNOSTIC
1866 kprintf("%s: try selection again\n", slp->sl_xname);
1867 #endif /* SCSI_LOW_DIAGNOSTIC */
1868 slp->sl_retry_sel = 1;
1872 static void
1873 scsi_low_bus_release(struct scsi_low_softc *slp, struct targ_info *ti)
1875 if (ti->ti_disc > 0)
1877 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1879 else
1881 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1884 /* clear all nexus pointer */
1885 slp->sl_Qnexus = NULL;
1886 slp->sl_Lnexus = NULL;
1887 slp->sl_Tnexus = NULL;
1889 /* clear selection assert */
1890 slp->sl_selid = NULL;
1892 /* clear nexus data */
1893 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1895 /* clear phase change counter */
1896 slp->sl_ph_count = 0;
1899 static int
1900 scsi_low_setup_done(struct scsi_low_softc *slp, struct slccb *cb)
1902 struct targ_info *ti;
1903 struct lun_info *li;
1905 ti = cb->ti;
1906 li = cb->li;
1908 if (cb->ccb_rcnt >= slp->sl_max_retry)
1910 cb->ccb_error |= ABORTIO;
1911 return SCSI_LOW_DONE_COMPLETE;
1914 /* XXX: special huck for selection timeout */
1915 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1916 (cb->ccb_error & SELTIMEOUTIO) != 0)
1918 cb->ccb_error |= ABORTIO;
1919 return SCSI_LOW_DONE_COMPLETE;
1922 switch(li->li_state)
1924 case SCSI_LOW_LUN_INQ:
1925 if (cb->ccb_error != 0)
1927 li->li_diskflags &=
1928 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
1929 if (li->li_lun > 0)
1930 goto resume;
1931 ti->ti_diskflags &=
1932 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
1934 else if ((li->li_inq.sd_version & 7) >= 2 ||
1935 (li->li_inq.sd_len >= 4))
1937 if ((li->li_inq.sd_support & 0x2) == 0)
1938 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1939 if ((li->li_inq.sd_support & 0x8) == 0)
1940 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
1941 if (li->li_lun > 0)
1942 goto resume;
1943 if ((li->li_inq.sd_support & 0x10) == 0)
1944 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
1945 if ((li->li_inq.sd_support & 0x20) == 0)
1946 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
1947 if ((li->li_inq.sd_support & 0x40) == 0)
1948 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
1950 else
1952 li->li_diskflags &=
1953 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
1954 if (li->li_lun > 0)
1955 goto resume;
1956 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
1958 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
1959 resume:
1960 scsi_low_calcf_target(ti);
1961 scsi_low_calcf_lun(li);
1962 break;
1964 case SCSI_LOW_LUN_MODEQ:
1965 if (cb->ccb_error != 0)
1967 if (cb->ccb_error & SENSEIO)
1969 #ifdef SCSI_LOW_DEBUG
1970 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
1972 kprintf("SENSE: [%x][%x][%x][%x][%x]\n",
1973 (u_int) cb->ccb_sense.error_code,
1974 (u_int) cb->ccb_sense.segment,
1975 (u_int) cb->ccb_sense.flags,
1976 (u_int) cb->ccb_sense.add_sense_code,
1977 (u_int) cb->ccb_sense.add_sense_code_qual);
1979 #endif /* SCSI_LOW_DEBUG */
1981 else
1983 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1986 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
1988 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
1989 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
1990 else
1991 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
1992 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
1993 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1995 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
1996 scsi_low_calcf_lun(li);
1997 break;
1999 default:
2000 break;
2003 li->li_state ++;
2004 if (li->li_state == SCSI_LOW_LUN_OK)
2006 scsi_low_calcf_target(ti);
2007 scsi_low_calcf_lun(li);
2008 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2009 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2011 scsi_low_calcf_show(li);
2015 cb->ccb_rcnt --;
2016 return SCSI_LOW_DONE_RETRY;
2019 static int
2020 scsi_low_done(struct scsi_low_softc *slp, struct slccb *cb)
2022 int rv;
2024 if (cb->ccb_error == 0)
2026 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2028 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2029 /* XXX:
2030 * SCSI-2 draft suggests
2031 * page 0x0a QErr bit determins if
2032 * the target aborts or continues
2033 * the queueing io's after CA state resolved.
2034 * However many targets seem not to support
2035 * the page 0x0a. Thus we should manually clear the
2036 * queuing io's after CA state.
2038 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2040 cb->ccb_rcnt --;
2041 cb->ccb_flags |= CCB_CLEARQ;
2042 goto retry;
2044 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2046 if ((cb->ccb_flags & CCB_SENSE) != 0)
2047 cb->ccb_error |= (SENSEIO | ABORTIO);
2048 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2050 else switch (cb->ccb_sscp.scp_status)
2052 case ST_GOOD:
2053 case ST_MET:
2054 case ST_INTERGOOD:
2055 case ST_INTERMET:
2056 if (cb->ccb_datalen == 0 ||
2057 cb->ccb_scp.scp_datalen == 0)
2058 break;
2060 if (cb->ccb_scp.scp_cmdlen > 0 &&
2061 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2062 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2063 break;
2065 cb->ccb_error |= PDMAERR;
2066 break;
2068 case ST_BUSY:
2069 case ST_QUEFULL:
2070 cb->ccb_error |= (BUSYERR | STATERR);
2071 break;
2073 case ST_CONFLICT:
2074 cb->ccb_error |= (STATERR | ABORTIO);
2075 break;
2077 case ST_CHKCOND:
2078 case ST_CMDTERM:
2079 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2081 cb->ccb_rcnt --;
2082 cb->ccb_flags |= CCB_SENSE;
2083 goto retry;
2085 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2086 break;
2088 case ST_UNKNOWN:
2089 default:
2090 cb->ccb_error |= FATALIO;
2091 break;
2094 else
2096 if (cb->ccb_flags & CCB_SENSE)
2098 cb->ccb_error |= (SENSEERR | ABORTIO);
2100 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2103 /* internal ccb */
2104 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2106 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2107 goto retry;
2110 /* check a ccb msgout flag */
2111 if (cb->ccb_omsgoutflag != 0)
2113 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2114 SCSI_LOW_MSG_ABORT_QTAG | \
2115 SCSI_LOW_MSG_CLEAR_QTAG | \
2116 SCSI_LOW_MSG_TERMIO)
2118 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2120 cb->ccb_error |= ABORTIO;
2124 /* call OS depend done */
2125 if (cb->osdep != NULL)
2127 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2128 if (rv == EJUSTRETURN)
2129 goto retry;
2131 else if (cb->ccb_error != 0)
2133 if (cb->ccb_rcnt >= slp->sl_max_retry)
2134 cb->ccb_error |= ABORTIO;
2136 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2137 (cb->ccb_error & ABORTIO) == 0)
2138 goto retry;
2141 /* free our target */
2142 #ifdef SCSI_LOW_DEBUG
2143 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2145 kprintf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2146 scsi_low_print(slp, NULL);
2148 #endif /* SCSI_LOW_DEBUG */
2150 scsi_low_deactivate_qtag(cb);
2151 scsi_low_dealloc_qtag(cb);
2152 scsi_low_free_ccb(cb);
2153 slp->sl_nio --;
2154 return SCSI_LOW_DONE_COMPLETE;
2156 retry:
2157 #ifdef SCSI_LOW_DEBUG
2158 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2160 kprintf("** SCSI_LOW_DONE_RETRY ===============\n");
2161 scsi_low_print(slp, NULL);
2163 #endif /* SCSI_LOW_DEBUG */
2165 cb->ccb_rcnt ++;
2166 scsi_low_deactivate_qtag(cb);
2167 scsi_low_ccb_message_retry(cb);
2168 return SCSI_LOW_DONE_RETRY;
2171 /**************************************************************
2172 * Reset
2173 **************************************************************/
2174 static void
2175 scsi_low_reset_nexus_target(struct scsi_low_softc *slp, struct targ_info *ti,
2176 int fdone)
2178 struct lun_info *li;
2180 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
2182 scsi_low_reset_nexus_lun(slp, li, fdone);
2183 li->li_state = SCSI_LOW_LUN_SLEEP;
2184 li->li_maxnqio = 0;
2187 ti->ti_disc = 0;
2188 ti->ti_setup_msg = 0;
2189 ti->ti_setup_msg_done = 0;
2191 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2192 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2194 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2195 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2197 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2199 ((*slp->sl_funcs->scsi_low_targ_init)
2200 (slp, ti, SCSI_LOW_INFO_REVOKE));
2202 scsi_low_calcf_target(ti);
2204 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
2206 li->li_flags = 0;
2208 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2209 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2211 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2213 ((*slp->sl_funcs->scsi_low_lun_init)
2214 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2216 scsi_low_calcf_lun(li);
2220 static void
2221 scsi_low_reset_nexus(struct scsi_low_softc *slp, int fdone)
2223 struct targ_info *ti;
2224 struct slccb *cb, *topcb;
2226 if ((cb = slp->sl_Qnexus) != NULL)
2228 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2230 else
2232 topcb = NULL;
2235 TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
2237 scsi_low_reset_nexus_target(slp, ti, fdone);
2238 scsi_low_bus_release(slp, ti);
2239 scsi_low_init_msgsys(slp, ti);
2242 if (topcb != NULL)
2244 topcb->ccb_flags |= CCB_STARTQ;
2245 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2248 slp->sl_disc = 0;
2249 slp->sl_retry_sel = 0;
2250 slp->sl_flags &= ~HW_PDMASTART;
2253 /* misc */
2254 static int tw_pos;
2255 static char tw_chars[] = "|/-\\";
2256 #define TWIDDLEWAIT 10000
2258 static void
2259 scsi_low_twiddle_wait(void)
2261 kprintf("\b%c", tw_chars[tw_pos++]);
2262 tw_pos %= (sizeof(tw_chars) - 1);
2263 SCSI_LOW_DELAY(TWIDDLEWAIT);
2266 void
2267 scsi_low_bus_reset(struct scsi_low_softc *slp)
2269 int i;
2271 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2273 kprintf("%s: try to reset scsi bus ", slp->sl_xname);
2274 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2275 scsi_low_twiddle_wait();
2276 kprintf("\b\n");
2280 scsi_low_restart(struct scsi_low_softc *slp, int flags, u_char *s)
2282 int error;
2284 if (s != NULL)
2285 kprintf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2287 if ((error = scsi_low_init(slp, flags)) != 0)
2288 return error;
2290 scsi_low_start(slp);
2291 return 0;
2294 /**************************************************************
2295 * disconnect and reselect
2296 **************************************************************/
2297 #define MSGCMD_LUN(msg) (msg & 0x07)
2299 static struct slccb *
2300 scsi_low_establish_ccb(struct targ_info *ti, struct lun_info *li, scsi_low_tag_t tag)
2302 struct scsi_low_softc *slp = ti->ti_sc;
2303 struct slccb *cb;
2305 if (li == NULL)
2306 return NULL;
2308 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
2309 if (cb->ccb_tag == tag)
2310 goto found;
2311 return cb;
2314 * establish our ccb nexus
2316 found:
2317 #ifdef SCSI_LOW_DEBUG
2318 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2320 kprintf("%s: nexus(0x%lx) abort check start\n",
2321 slp->sl_xname, (u_long) cb);
2322 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2323 scsi_low_revoke_ccb(slp, cb, 1);
2324 return NULL;
2327 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2329 if (cb->ccb_omsgoutflag == 0)
2330 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2332 #endif /* SCSI_LOW_DEBUG */
2334 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2335 cb->ccb_flags &= ~CCB_DISCQ;
2336 slp->sl_Qnexus = cb;
2338 slp->sl_scp = cb->ccb_sscp;
2339 slp->sl_error |= cb->ccb_error;
2341 slp->sl_disc --;
2342 ti->ti_disc --;
2343 li->li_disc --;
2345 /* inform "ccb nexus established" to the host driver */
2346 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2348 /* check msg */
2349 if (cb->ccb_msgoutflag != 0)
2351 scsi_low_ccb_message_exec(slp, cb);
2354 return cb;
2357 struct targ_info *
2358 scsi_low_reselected(struct scsi_low_softc *slp, u_int targ)
2360 struct targ_info *ti;
2361 struct slccb *cb;
2362 u_char *s;
2365 * Check select vs reselected collision.
2368 if ((cb = slp->sl_selid) != NULL)
2370 scsi_low_arbit_fail(slp, cb);
2371 #ifdef SCSI_LOW_STATICS
2372 scsi_low_statics.nexus_conflict ++;
2373 #endif /* SCSI_LOW_STATICS */
2377 * Check if no current active nexus.
2379 if (slp->sl_Tnexus != NULL)
2381 s = "host busy";
2382 goto world_restart;
2386 * Check a valid target id asserted ?
2388 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2390 s = "scsi id illegal";
2391 goto world_restart;
2395 * Check the target scsi status.
2397 ti = slp->sl_ti[targ];
2398 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2400 s = "phase mismatch";
2401 goto world_restart;
2405 * Setup init msgsys
2407 slp->sl_error = 0;
2408 scsi_low_init_msgsys(slp, ti);
2411 * Establish our target nexus
2413 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2414 slp->sl_Tnexus = ti;
2415 #ifdef SCSI_LOW_STATICS
2416 scsi_low_statics.nexus_reselected ++;
2417 #endif /* SCSI_LOW_STATICS */
2418 return ti;
2420 world_restart:
2421 kprintf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2422 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2423 "reselect: scsi world confused");
2424 return NULL;
2427 /**************************************************************
2428 * cmd out pointer setup
2429 **************************************************************/
2431 scsi_low_cmd(struct scsi_low_softc *slp, struct targ_info *ti)
2433 struct slccb *cb = slp->sl_Qnexus;
2435 slp->sl_ph_count ++;
2436 if (cb == NULL)
2439 * no ccb, abort!
2441 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2442 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2443 slp->sl_scp.scp_datalen = 0;
2444 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2445 slp->sl_error |= FATALIO;
2446 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2447 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2448 return EINVAL;
2450 else
2452 #ifdef SCSI_LOW_DEBUG
2453 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2455 scsi_low_test_cmdlnk(slp, cb);
2457 #endif /* SCSI_LOW_DEBUG */
2459 return 0;
2462 /**************************************************************
2463 * data out pointer setup
2464 **************************************************************/
2466 scsi_low_data(struct scsi_low_softc *slp, struct targ_info *ti,
2467 struct buf **bp, int direction)
2469 struct slccb *cb = slp->sl_Qnexus;
2471 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2473 *bp = cb->bp;
2474 return 0;
2477 slp->sl_error |= (FATALIO | PDMAERR);
2478 slp->sl_scp.scp_datalen = 0;
2479 slp->sl_scp.scp_direction = direction;
2480 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2481 if (ti->ti_ophase != ti->ti_phase)
2483 char *s;
2485 if (cb == NULL)
2486 s = "DATA PHASE: ccb nexus not found";
2487 else
2488 s = "DATA PHASE: xfer direction mismatch";
2489 SCSI_LOW_INFO(slp, ti, s);
2492 *bp = NULL;
2493 return EINVAL;
2496 /**************************************************************
2497 * MSG_SYS
2498 **************************************************************/
2499 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2500 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2501 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2502 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2503 #define MSGIN_DATA_LAST 0x30
2505 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2506 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2507 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2508 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2510 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2511 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2512 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2513 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2514 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2515 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2516 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2518 struct scsi_low_msgout_data {
2519 u_int md_flags;
2520 u_int8_t md_msg;
2521 int (*md_msgfunc) (struct scsi_low_softc *);
2522 int (*md_errfunc) (struct scsi_low_softc *, u_int);
2523 #define MSG_RELEASE_ATN 0x0001
2524 u_int md_condition;
2527 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2528 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2529 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2530 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2531 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2532 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2533 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2534 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2535 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2536 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2537 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2538 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2539 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2540 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2541 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2542 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2543 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2546 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2547 static int scsi_low_synch (struct scsi_low_softc *);
2548 static int scsi_low_wide (struct scsi_low_softc *);
2549 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2550 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2551 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2552 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2553 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2554 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2555 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2556 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2557 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2558 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2559 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2561 struct scsi_low_msgin_data {
2562 u_int md_len;
2563 int (*md_msgfunc) (struct scsi_low_softc *);
2566 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2567 /* 0 */ {1, scsi_low_msginfunc_cc},
2568 /* 1 */ {2, scsi_low_msginfunc_ext},
2569 /* 2 */ {1, scsi_low_msginfunc_sdp},
2570 /* 3 */ {1, scsi_low_msginfunc_rp},
2571 /* 4 */ {1, scsi_low_msginfunc_disc},
2572 /* 5 */ {1, scsi_low_msginfunc_rejop},
2573 /* 6 */ {1, scsi_low_msginfunc_rejop},
2574 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2575 /* 8 */ {1, scsi_low_msginfunc_noop},
2576 /* 9 */ {1, scsi_low_msginfunc_parity},
2577 /* a */ {1, scsi_low_msginfunc_lcc},
2578 /* b */ {1, scsi_low_msginfunc_lcc},
2579 /* c */ {1, scsi_low_msginfunc_rejop},
2580 /* d */ {2, scsi_low_msginfunc_rejop},
2581 /* e */ {1, scsi_low_msginfunc_rejop},
2582 /* f */ {1, scsi_low_msginfunc_rejop},
2583 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2584 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2585 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2586 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2587 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2588 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2589 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2590 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2591 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2592 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2593 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2594 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2595 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2596 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2597 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2598 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2599 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2600 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2601 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2602 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2603 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2604 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2605 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2606 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2607 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2608 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2609 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2610 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2611 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2612 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2613 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2614 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2615 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2618 /**************************************************************
2619 * msgout
2620 **************************************************************/
2621 static int
2622 scsi_low_msgfunc_synch(struct scsi_low_softc *slp)
2624 struct targ_info *ti = slp->sl_Tnexus;
2625 int ptr = ti->ti_msgoutlen;
2627 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2628 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2629 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2630 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2631 return MSG_EXTEND_SYNCHLEN + 2;
2634 static int
2635 scsi_low_msgfunc_wide(struct scsi_low_softc *slp)
2637 struct targ_info *ti = slp->sl_Tnexus;
2638 int ptr = ti->ti_msgoutlen;
2640 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2641 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2642 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2643 return MSG_EXTEND_WIDELEN + 2;
2646 static int
2647 scsi_low_msgfunc_identify(struct scsi_low_softc *slp)
2649 struct targ_info *ti = slp->sl_Tnexus;
2650 struct lun_info *li = slp->sl_Lnexus;
2651 struct slccb *cb = slp->sl_Qnexus;
2652 int ptr = ti->ti_msgoutlen;
2653 u_int8_t msg;
2655 msg = MSG_IDENTIFY;
2656 if (cb == NULL)
2658 slp->sl_error |= FATALIO;
2659 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2660 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2662 else
2664 if (scsi_low_is_disconnect_ok(cb) != 0)
2665 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2666 else
2667 msg |= li->li_lun;
2669 if (ti->ti_phase == PH_MSGOUT)
2671 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2672 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2674 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2678 ti->ti_msgoutstr[ptr + 0] = msg;
2679 return 1;
2682 static int
2683 scsi_low_msgfunc_abort(struct scsi_low_softc *slp)
2685 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2686 return 1;
2689 static int
2690 scsi_low_msgfunc_qabort(struct scsi_low_softc *slp)
2692 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2693 return 1;
2696 static int
2697 scsi_low_msgfunc_reset(struct scsi_low_softc *slp)
2699 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2700 return 1;
2703 static int
2704 scsi_low_msgfunc_qtag(struct scsi_low_softc *slp)
2706 struct targ_info *ti = slp->sl_Tnexus;
2707 struct slccb *cb = slp->sl_Qnexus;
2708 int ptr = ti->ti_msgoutlen;
2710 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2712 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2713 return 1;
2715 else
2717 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2718 if (ti->ti_phase == PH_MSGOUT)
2720 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2723 return 2;
2727 * The following functions are called when targets give unexpected
2728 * responces in msgin (after msgout).
2730 static int
2731 scsi_low_errfunc_identify(struct scsi_low_softc *slp, u_int msgflags)
2733 if (slp->sl_Lnexus != NULL)
2735 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2736 scsi_low_calcf_lun(slp->sl_Lnexus);
2738 return 0;
2741 static int
2742 scsi_low_errfunc_synch(struct scsi_low_softc *slp, u_int msgflags)
2744 struct targ_info *ti = slp->sl_Tnexus;
2746 MSGIN_PERIOD(ti) = 0;
2747 MSGIN_OFFSET(ti) = 0;
2748 scsi_low_synch(slp);
2749 return 0;
2752 static int
2753 scsi_low_errfunc_wide(struct scsi_low_softc *slp, u_int msgflags)
2755 struct targ_info *ti = slp->sl_Tnexus;
2757 MSGIN_WIDTHP(ti) = 0;
2758 scsi_low_wide(slp);
2759 return 0;
2762 static int
2763 scsi_low_errfunc_qtag(struct scsi_low_softc *slp, u_int msgflags)
2765 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2767 if (slp->sl_Qnexus != NULL)
2769 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2771 if (slp->sl_Lnexus != NULL)
2773 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2774 scsi_low_calcf_lun(slp->sl_Lnexus);
2776 kprintf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2778 return 0;
2783 scsi_low_msgout(struct scsi_low_softc *slp, struct targ_info *ti, u_int fl)
2785 struct scsi_low_msgout_data *mdp;
2786 int len = 0;
2788 #ifdef SCSI_LOW_DIAGNOSTIC
2789 if (ti != slp->sl_Tnexus)
2791 scsi_low_print(slp, NULL);
2792 panic("scsi_low_msgout: Target nexus inconsistent");
2794 #endif /* SCSI_LOW_DIAGNOSTIC */
2796 slp->sl_ph_count ++;
2797 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2799 kprintf("%s: too many phase changes\n", slp->sl_xname);
2800 slp->sl_error |= FATALIO;
2801 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2804 /* STEP I.
2805 * Scsi phase changes.
2806 * Previously msgs asserted are accepted by our target or
2807 * processed by scsi_low_msgin.
2808 * Thus clear all saved informations.
2810 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2812 ti->ti_omsgflags = 0;
2813 ti->ti_emsgflags = 0;
2815 else if (slp->sl_atten == 0)
2817 /* STEP II.
2818 * We did not assert attention, however still our target required
2819 * msgs. Resend previous msgs.
2821 ti->ti_msgflags |= ti->ti_omsgflags;
2822 ti->ti_omsgflags = 0;
2823 #ifdef SCSI_LOW_DIAGNOSTIC
2824 kprintf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
2825 #endif /* SCSI_LOW_DIAGNOSTIC */
2828 /* STEP III.
2829 * We have no msgs. send MSG_NOOP (OK?)
2831 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2832 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2834 /* STEP IV.
2835 * Process all msgs
2837 ti->ti_msgoutlen = 0;
2838 slp->sl_clear_atten = 0;
2839 mdp = &scsi_low_msgout_data[0];
2840 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2842 if ((ti->ti_msgflags & mdp->md_flags) != 0)
2844 ti->ti_omsgflags |= mdp->md_flags;
2845 ti->ti_msgflags &= ~mdp->md_flags;
2846 ti->ti_emsgflags = mdp->md_flags;
2848 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2849 if (mdp->md_msgfunc != NULL)
2850 len = (*mdp->md_msgfunc) (slp);
2851 else
2852 len = 1;
2854 #ifdef SCSI_LOW_DIAGNOSTIC
2855 scsi_low_msg_log_write(&ti->ti_log_msgout,
2856 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2857 #endif /* SCSI_LOW_DIAGNOSTIC */
2859 ti->ti_msgoutlen += len;
2860 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2862 slp->sl_clear_atten = 1;
2863 break;
2866 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2867 ti->ti_msgflags == 0)
2868 break;
2870 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2871 break;
2875 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2876 slp->sl_clear_atten = 1;
2878 return ti->ti_msgoutlen;
2881 /**************************************************************
2882 * msgin
2883 **************************************************************/
2884 static int
2885 scsi_low_msginfunc_noop(struct scsi_low_softc *slp)
2887 return 0;
2890 static int
2891 scsi_low_msginfunc_rejop(struct scsi_low_softc *slp)
2893 struct targ_info *ti = slp->sl_Tnexus;
2894 u_int8_t msg = ti->ti_msgin[0];
2896 kprintf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
2897 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2898 return 0;
2901 static int
2902 scsi_low_msginfunc_cc(struct scsi_low_softc *slp)
2904 struct lun_info *li;
2906 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2908 /* validate status */
2909 if (slp->sl_Qnexus == NULL)
2910 return ENOENT;
2912 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2913 li = slp->sl_Lnexus;
2914 switch (slp->sl_scp.scp_status)
2916 case ST_GOOD:
2917 li->li_maxnqio = li->li_maxnexus;
2918 break;
2920 case ST_CHKCOND:
2921 li->li_maxnqio = 0;
2922 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
2923 scsi_low_reset_nexus_lun(slp, li, 0);
2924 break;
2926 case ST_BUSY:
2927 li->li_maxnqio = 0;
2928 break;
2930 case ST_QUEFULL:
2931 if (li->li_maxnexus >= li->li_nqio)
2932 li->li_maxnexus = li->li_nqio - 1;
2933 li->li_maxnqio = li->li_maxnexus;
2934 break;
2936 case ST_INTERGOOD:
2937 case ST_INTERMET:
2938 slp->sl_error |= MSGERR;
2939 break;
2941 default:
2942 break;
2944 return 0;
2947 static int
2948 scsi_low_msginfunc_lcc(struct scsi_low_softc *slp)
2950 struct targ_info *ti;
2951 struct lun_info *li;
2952 struct slccb *ncb, *cb;
2954 ti = slp->sl_Tnexus;
2955 li = slp->sl_Lnexus;
2956 if ((cb = slp->sl_Qnexus) == NULL)
2957 goto bad;
2959 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2960 switch (slp->sl_scp.scp_status)
2962 case ST_INTERGOOD:
2963 case ST_INTERMET:
2964 li->li_maxnqio = li->li_maxnexus;
2965 break;
2967 default:
2968 slp->sl_error |= MSGERR;
2969 break;
2972 if ((li->li_flags & SCSI_LOW_LINK) == 0)
2973 goto bad;
2975 cb->ccb_error |= slp->sl_error;
2976 if (cb->ccb_error != 0)
2977 goto bad;
2979 TAILQ_FOREACH(ncb, &slp->sl_start, ccb_chain)
2981 if (ncb->li == li)
2982 goto cmd_link_start;
2986 bad:
2987 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
2988 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2989 return EIO;
2991 cmd_link_start:
2992 ncb->ccb_flags &= ~CCB_STARTQ;
2993 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
2995 scsi_low_dealloc_qtag(ncb);
2996 ncb->ccb_tag = cb->ccb_tag;
2997 ncb->ccb_otag = cb->ccb_otag;
2998 cb->ccb_tag = SCSI_LOW_UNKTAG;
2999 cb->ccb_otag = SCSI_LOW_UNKTAG;
3000 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3001 panic("%s: linked ccb retried", slp->sl_xname);
3003 slp->sl_Qnexus = ncb;
3004 slp->sl_ph_count = 0;
3006 ncb->ccb_error = 0;
3007 ncb->ccb_datalen = -1;
3008 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3009 ncb->ccb_flags &= ~CCB_INTERNAL;
3011 scsi_low_init_msgsys(slp, ti);
3013 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3015 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3016 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3017 ncb->ccb_tc = ncb->ccb_tcmax;
3019 /* setup saved scsi data pointer */
3020 ncb->ccb_sscp = ncb->ccb_scp;
3021 slp->sl_scp = ncb->ccb_sscp;
3022 slp->sl_error = ncb->ccb_error;
3024 #ifdef SCSI_LOW_DIAGNOSTIC
3025 scsi_low_msg_log_init(&ti->ti_log_msgin);
3026 scsi_low_msg_log_init(&ti->ti_log_msgout);
3027 #endif /* SCSI_LOW_DIAGNOSTIC */
3028 return EJUSTRETURN;
3031 static int
3032 scsi_low_msginfunc_disc(struct scsi_low_softc *slp)
3034 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3035 return 0;
3038 static int
3039 scsi_low_msginfunc_sdp(struct scsi_low_softc *slp)
3041 struct slccb *cb = slp->sl_Qnexus;
3043 if (cb != NULL)
3045 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3046 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3048 else
3049 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3050 return 0;
3053 static int
3054 scsi_low_msginfunc_rp(struct scsi_low_softc *slp)
3056 if (slp->sl_Qnexus != NULL)
3057 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3058 else
3059 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3060 return 0;
3063 static int
3064 scsi_low_synch(struct scsi_low_softc *slp)
3066 struct targ_info *ti = slp->sl_Tnexus;
3067 u_int period = 0, offset = 0, speed;
3068 u_char *s;
3069 int error;
3071 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3072 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3073 MSGIN_OFFSET(ti) == 0)
3075 if ((offset = MSGIN_OFFSET(ti)) != 0)
3076 period = MSGIN_PERIOD(ti);
3077 s = offset ? "synchronous" : "async";
3079 else
3081 /* XXX:
3082 * Target seems to be brain damaged.
3083 * Force async transfer.
3085 ti->ti_maxsynch.period = 0;
3086 ti->ti_maxsynch.offset = 0;
3087 kprintf("%s: target brain damaged. async transfer\n",
3088 slp->sl_xname);
3089 return EINVAL;
3092 ti->ti_maxsynch.period = period;
3093 ti->ti_maxsynch.offset = offset;
3095 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3096 if (error != 0)
3098 /* XXX:
3099 * Current period and offset are not acceptable
3100 * for our adapter.
3101 * The adapter changes max synch and max offset.
3103 kprintf("%s: synch neg failed. retry synch msg neg ...\n",
3104 slp->sl_xname);
3105 return error;
3108 ti->ti_osynch = ti->ti_maxsynch;
3109 if (offset > 0)
3111 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3114 /* inform data */
3115 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3117 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3118 struct slccb *cb = slp->sl_Qnexus;
3120 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3121 return 0;
3122 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3124 kprintf("%s(%d:*): <%s> offset %d period %dns ",
3125 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3127 if (period != 0)
3129 speed = 1000 * 10 / (period * 4);
3130 kprintf("%d.%d M/s", speed / 10, speed % 10);
3132 kprintf("\n");
3134 return 0;
3137 static int
3138 scsi_low_wide(struct scsi_low_softc *slp)
3140 struct targ_info *ti = slp->sl_Tnexus;
3141 int error;
3143 ti->ti_width = MSGIN_WIDTHP(ti);
3144 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3145 if (error != 0)
3147 /* XXX:
3148 * Current width is not acceptable for our adapter.
3149 * The adapter changes max width.
3151 kprintf("%s: wide neg failed. retry wide msg neg ...\n",
3152 slp->sl_xname);
3153 return error;
3156 ti->ti_owidth = ti->ti_width;
3157 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3159 ti->ti_setup_msg_done |=
3160 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3163 /* inform data */
3164 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3166 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3167 struct slccb *cb = slp->sl_Qnexus;
3169 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3170 return 0;
3171 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3173 kprintf("%s(%d:*): transfer width %d bits\n",
3174 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3176 return 0;
3179 static int
3180 scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *slp)
3182 struct targ_info *ti = slp->sl_Tnexus;
3183 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3185 if (slp->sl_Qnexus != NULL)
3187 if (slp->sl_Qnexus->ccb_tag != etag)
3189 slp->sl_error |= FATALIO;
3190 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3191 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3194 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3196 #ifdef SCSI_LOW_DEBUG
3197 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3198 return 0;
3199 #endif /* SCSI_LOW_DEBUG */
3201 slp->sl_error |= FATALIO;
3202 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3203 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3205 return 0;
3208 static int
3209 scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *slp)
3211 struct targ_info *ti = slp->sl_Tnexus;
3212 struct slccb *cb = slp->sl_Qnexus;
3213 int res = (int) ti->ti_msgin[1];
3215 if (cb == NULL || res <= 0 ||
3216 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3217 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3218 return EINVAL;
3220 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3221 return EINVAL;
3223 slp->sl_scp.scp_datalen += res;
3224 slp->sl_scp.scp_data -= res;
3225 scsi_low_data_finish(slp);
3226 return 0;
3229 static int
3230 scsi_low_msginfunc_ext(struct scsi_low_softc *slp)
3232 struct slccb *cb = slp->sl_Qnexus;
3233 struct lun_info *li = slp->sl_Lnexus;
3234 struct targ_info *ti = slp->sl_Tnexus;
3235 int count, retry;
3236 u_int32_t *ptr;
3238 if (ti->ti_msginptr == 2)
3240 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3241 return 0;
3244 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3246 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3247 if (cb == NULL)
3248 break;
3250 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3251 count = (int) htonl((long) (*ptr));
3252 if(slp->sl_scp.scp_datalen - count < 0 ||
3253 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3254 break;
3256 slp->sl_scp.scp_datalen -= count;
3257 slp->sl_scp.scp_data += count;
3258 return 0;
3260 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3261 if (li == NULL)
3262 break;
3264 retry = scsi_low_synch(slp);
3265 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3266 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3268 #ifdef SCSI_LOW_DEBUG
3269 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3271 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3273 #endif /* SCSI_LOW_DEBUG */
3274 return 0;
3276 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3277 if (li == NULL)
3278 break;
3280 retry = scsi_low_wide(slp);
3281 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3282 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3284 return 0;
3286 default:
3287 break;
3290 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3291 return EINVAL;
3294 static int
3295 scsi_low_msginfunc_parity(struct scsi_low_softc *slp)
3297 struct targ_info *ti = slp->sl_Tnexus;
3299 /* only I -> T, invalid! */
3300 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3301 return 0;
3304 static int
3305 scsi_low_msginfunc_msg_reject(struct scsi_low_softc *slp)
3307 struct targ_info *ti = slp->sl_Tnexus;
3308 struct scsi_low_msgout_data *mdp;
3309 u_int msgflags;
3311 if (ti->ti_emsgflags != 0)
3313 kprintf("%s: msg flags [0x%x] rejected\n",
3314 slp->sl_xname, ti->ti_emsgflags);
3315 msgflags = SCSI_LOW_MSG_REJECT;
3316 mdp = &scsi_low_msgout_data[0];
3317 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3319 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3321 ti->ti_emsgflags &= ~mdp->md_flags;
3322 if (mdp->md_errfunc != NULL)
3323 (*mdp->md_errfunc) (slp, msgflags);
3324 break;
3327 return 0;
3329 else
3331 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3332 slp->sl_error |= MSGERR;
3334 return EINVAL;
3338 scsi_low_msgin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c)
3340 struct scsi_low_msgin_data *sdp;
3341 struct lun_info *li;
3342 u_int8_t msg;
3344 #ifdef SCSI_LOW_DIAGNOSTIC
3345 if (ti != slp->sl_Tnexus)
3347 scsi_low_print(slp, NULL);
3348 panic("scsi_low_msgin: Target nexus inconsistent");
3350 #endif /* SCSI_LOW_DIAGNOSTIC */
3353 * Phase changes, clear the pointer.
3355 if (ti->ti_ophase != ti->ti_phase)
3357 MSGINPTR_CLR(ti);
3358 ti->ti_msgin_parity_error = 0;
3360 slp->sl_ph_count ++;
3361 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3363 kprintf("%s: too many phase changes\n", slp->sl_xname);
3364 slp->sl_error |= FATALIO;
3365 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3370 * Store a current messages byte into buffer and
3371 * wait for the completion of the current msg.
3373 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3374 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3376 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3377 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3381 * Check parity errors.
3383 if ((c & SCSI_LOW_DATA_PE) != 0)
3385 ti->ti_msgin_parity_error ++;
3386 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3387 goto out;
3390 if (ti->ti_msgin_parity_error != 0)
3391 goto out;
3394 * Calculate messages length.
3396 msg = ti->ti_msgin[0];
3397 if (msg < MSGIN_DATA_LAST)
3398 sdp = &scsi_low_msgin_data[msg];
3399 else
3400 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3402 if (ti->ti_msginlen == 0)
3404 ti->ti_msginlen = sdp->md_len;
3408 * Check comletion.
3410 if (ti->ti_msginptr < ti->ti_msginlen)
3411 return EJUSTRETURN;
3414 * Do process.
3416 if ((msg & MSG_IDENTIFY) == 0)
3418 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3419 return EJUSTRETURN;
3421 else
3423 li = slp->sl_Lnexus;
3424 if (li == NULL)
3426 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3427 if (li == NULL)
3428 goto badlun;
3429 slp->sl_Lnexus = li;
3430 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3432 else
3434 if (MSGCMD_LUN(msg) != li->li_lun)
3435 goto badlun;
3438 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3440 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3442 #ifdef SCSI_LOW_DEBUG
3443 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3445 goto out;
3447 #endif /* SCSI_LOW_DEBUG */
3448 goto badlun;
3452 goto out;
3455 * Msg process completed, reset msgin pointer and assert ATN if desired.
3457 badlun:
3458 slp->sl_error |= FATALIO;
3459 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3460 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3462 out:
3463 if (ti->ti_msginptr < ti->ti_msginlen)
3464 return EJUSTRETURN;
3466 #ifdef SCSI_LOW_DIAGNOSTIC
3467 scsi_low_msg_log_write(&ti->ti_log_msgin,
3468 &ti->ti_msgin[0], ti->ti_msginlen);
3469 #endif /* SCSI_LOW_DIAGNOSTIC */
3471 MSGINPTR_CLR(ti);
3472 return 0;
3475 /**********************************************************
3476 * disconnect
3477 **********************************************************/
3479 scsi_low_disconnected(struct scsi_low_softc *slp, struct targ_info *ti)
3481 struct slccb *cb = slp->sl_Qnexus;
3483 /* check phase completion */
3484 switch (slp->sl_msgphase)
3486 case MSGPH_RESET:
3487 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3488 scsi_low_msginfunc_cc(slp);
3489 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3490 goto io_resume;
3492 case MSGPH_ABORT:
3493 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3494 scsi_low_msginfunc_cc(slp);
3495 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3496 goto io_resume;
3498 case MSGPH_TERM:
3499 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3500 scsi_low_msginfunc_cc(slp);
3501 goto io_resume;
3503 case MSGPH_DISC:
3504 if (cb != NULL)
3506 struct lun_info *li;
3508 li = cb->li;
3509 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3510 cb->ccb_flags |= CCB_DISCQ;
3511 cb->ccb_error |= slp->sl_error;
3512 li->li_disc ++;
3513 ti->ti_disc ++;
3514 slp->sl_disc ++;
3517 #ifdef SCSI_LOW_STATICS
3518 scsi_low_statics.nexus_disconnected ++;
3519 #endif /* SCSI_LOW_STATICS */
3521 #ifdef SCSI_LOW_DEBUG
3522 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3524 kprintf("## SCSI_LOW_DISCONNECTED ===============\n");
3525 scsi_low_print(slp, NULL);
3527 #endif /* SCSI_LOW_DEBUG */
3528 break;
3530 case MSGPH_NULL:
3531 slp->sl_error |= FATALIO;
3532 if (ti->ti_phase == PH_SELSTART)
3533 slp->sl_error |= SELTIMEOUTIO;
3534 else
3535 slp->sl_error |= UBFERR;
3536 /* fall through */
3538 case MSGPH_LCTERM:
3539 case MSGPH_CMDC:
3540 io_resume:
3541 if (cb == NULL)
3542 break;
3544 #ifdef SCSI_LOW_DEBUG
3545 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3547 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3548 (cb->ccb_msgoutflag != 0 ||
3549 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3551 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3554 #endif /* SCSI_LOW_DEBUG */
3556 cb->ccb_error |= slp->sl_error;
3557 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3559 cb->ccb_flags |= CCB_STARTQ;
3560 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3562 break;
3565 scsi_low_bus_release(slp, ti);
3566 scsi_low_start(slp);
3567 return 1;
3570 /**********************************************************
3571 * TAG operations
3572 **********************************************************/
3573 static int
3574 scsi_low_alloc_qtag(struct slccb *cb)
3576 struct lun_info *li = cb->li;
3577 scsi_low_tag_t etag;
3579 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3580 return 0;
3582 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3583 etag = ffs(li->li_qtagbits);
3584 if (etag == 0)
3585 return ENOSPC;
3587 li->li_qtagbits &= ~(1 << (etag - 1));
3588 cb->ccb_otag = etag;
3589 return 0;
3591 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3592 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3593 if (li->li_qtagarray[li->li_qd] == 0)
3594 goto found;
3596 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3597 if (li->li_qtagarray[li->li_qd] == 0)
3598 goto found;
3600 return ENOSPC;
3602 found:
3603 li->li_qtagarray[li->li_qd] ++;
3604 cb->ccb_otag = (li->li_qd ++);
3605 return 0;
3606 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3609 static int
3610 scsi_low_dealloc_qtag(struct slccb *cb)
3612 struct lun_info *li = cb->li;
3613 scsi_low_tag_t etag;
3615 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3616 return 0;
3618 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3619 etag = cb->ccb_otag - 1;
3620 #ifdef SCSI_LOW_DIAGNOSTIC
3621 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3622 panic("scsi_low_dealloc_tag: illegal tag");
3623 #endif /* SCSI_LOW_DIAGNOSTIC */
3624 li->li_qtagbits |= (1 << etag);
3626 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3627 etag = cb->ccb_otag;
3628 #ifdef SCSI_LOW_DIAGNOSTIC
3629 if (etag >= SCSI_LOW_MAXNEXUS)
3630 panic("scsi_low_dealloc_tag: illegal tag");
3631 #endif /* SCSI_LOW_DIAGNOSTIC */
3632 li->li_qtagarray[etag] --;
3633 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3635 cb->ccb_otag = SCSI_LOW_UNKTAG;
3636 return 0;
3639 static struct slccb *
3640 scsi_low_revoke_ccb(struct scsi_low_softc *slp, struct slccb *cb, int fdone)
3642 struct targ_info *ti = cb->ti;
3643 struct lun_info *li = cb->li;
3645 #ifdef SCSI_LOW_DIAGNOSTIC
3646 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3647 (CCB_STARTQ | CCB_DISCQ))
3649 panic("%s: ccb in both queue", slp->sl_xname);
3651 #endif /* SCSI_LOW_DIAGNOSTIC */
3653 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3655 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3658 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3660 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3661 li->li_disc --;
3662 ti->ti_disc --;
3663 slp->sl_disc --;
3666 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3667 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3669 if (fdone != 0 &&
3670 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3671 (cb->ccb_flags & CCB_NORETRY) != 0))
3673 cb->ccb_error |= FATALIO;
3674 cb->ccb_flags &= ~CCB_AUTOSENSE;
3675 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3676 panic("%s: done ccb retried", slp->sl_xname);
3677 return NULL;
3679 else
3681 cb->ccb_error |= PENDINGIO;
3682 scsi_low_deactivate_qtag(cb);
3683 scsi_low_ccb_message_retry(cb);
3684 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3685 return cb;
3689 static void
3690 scsi_low_reset_nexus_lun(struct scsi_low_softc *slp, struct lun_info *li, int fdone)
3692 struct slccb *cb, *ncb, *ecb;
3694 if (li == NULL)
3695 return;
3697 ecb = NULL;
3698 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3700 ncb = TAILQ_NEXT(cb, ccb_chain);
3701 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3702 if (cb != NULL)
3705 * presumely keep ordering of io
3707 cb->ccb_flags |= CCB_STARTQ;
3708 if (ecb == NULL)
3710 TAILQ_INSERT_HEAD(&slp->sl_start,\
3711 cb, ccb_chain);
3713 else
3715 TAILQ_INSERT_AFTER(&slp->sl_start,\
3716 ecb, cb, ccb_chain);
3718 ecb = cb;
3723 /**************************************************************
3724 * Qurik setup
3725 **************************************************************/
3726 static void
3727 scsi_low_calcf_lun(struct lun_info *li)
3729 struct targ_info *ti = li->li_ti;
3730 struct scsi_low_softc *slp = ti->ti_sc;
3731 u_int cfgflags, diskflags;
3733 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3734 cfgflags = li->li_cfgflags;
3735 else
3736 cfgflags = 0;
3738 diskflags = li->li_diskflags & li->li_quirks;
3740 /* disconnect */
3741 li->li_flags &= ~SCSI_LOW_DISC;
3742 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3743 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3744 (cfgflags & SCSI_LOW_DISC) != 0)
3745 li->li_flags |= SCSI_LOW_DISC;
3747 /* parity */
3748 li->li_flags |= SCSI_LOW_NOPARITY;
3749 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3750 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3751 (cfgflags & SCSI_LOW_NOPARITY) == 0)
3752 li->li_flags &= ~SCSI_LOW_NOPARITY;
3754 /* qtag */
3755 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3756 (cfgflags & SCSI_LOW_QTAG) != 0 &&
3757 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3759 li->li_flags |= SCSI_LOW_QTAG;
3760 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3761 li->li_maxnqio = li->li_maxnexus;
3763 else
3765 li->li_flags &= ~SCSI_LOW_QTAG;
3766 li->li_maxnexus = 0;
3767 li->li_maxnqio = li->li_maxnexus;
3770 /* cmd link */
3771 li->li_flags &= ~SCSI_LOW_LINK;
3772 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3773 (diskflags & SCSI_LOW_DISK_LINK) != 0)
3774 li->li_flags |= SCSI_LOW_LINK;
3776 /* compatible flags */
3777 li->li_flags &= ~SCSI_LOW_SYNC;
3778 if (ti->ti_maxsynch.offset > 0)
3779 li->li_flags |= SCSI_LOW_SYNC;
3781 #ifdef SCSI_LOW_DEBUG
3782 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3784 scsi_low_calcf_show(li);
3786 #endif /* SCSI_LOW_DEBUG */
3789 static void
3790 scsi_low_calcf_target(struct targ_info *ti)
3792 struct scsi_low_softc *slp = ti->ti_sc;
3793 u_int offset, period, diskflags;
3795 diskflags = ti->ti_diskflags & ti->ti_quirks;
3797 /* synch */
3798 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
3799 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
3801 offset = ti->ti_maxsynch.offset;
3802 period = ti->ti_maxsynch.period;
3803 if (offset == 0 || period == 0)
3804 offset = period = 0;
3806 else
3808 offset = period = 0;
3811 ti->ti_maxsynch.offset = offset;
3812 ti->ti_maxsynch.period = period;
3814 /* wide */
3815 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
3816 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
3817 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
3819 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
3820 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3821 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
3823 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
3825 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
3826 ti->ti_maxsynch.period != ti->ti_osynch.period)
3827 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
3828 if (ti->ti_width != ti->ti_owidth)
3829 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
3831 ti->ti_osynch = ti->ti_maxsynch;
3832 ti->ti_owidth = ti->ti_width;
3835 #ifdef SCSI_LOW_DEBUG
3836 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3838 kprintf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
3839 slp->sl_xname, ti->ti_id,
3840 ti->ti_maxsynch.period * 4,
3841 ti->ti_maxsynch.offset,
3842 ti->ti_width);
3844 #endif /* SCSI_LOW_DEBUG */
3847 static void
3848 scsi_low_calcf_show(struct lun_info *li)
3850 struct targ_info *ti = li->li_ti;
3851 struct scsi_low_softc *slp = ti->ti_sc;
3853 kprintf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
3854 slp->sl_xname, ti->ti_id, li->li_lun,
3855 ti->ti_maxsynch.period * 4,
3856 ti->ti_maxsynch.offset,
3857 ti->ti_width,
3858 li->li_flags, SCSI_LOW_BITS);
3861 #ifdef SCSI_LOW_START_UP_CHECK
3862 /**************************************************************
3863 * scsi world start up
3864 **************************************************************/
3865 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
3867 static int
3868 scsi_low_start_up(struct scsi_low_softc *slp)
3870 struct targ_info *ti;
3871 struct lun_info *li;
3872 struct slccb *cb;
3873 int target, lun;
3875 kprintf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
3877 for (target = 0; target < slp->sl_ntargs; target ++)
3879 if (target == slp->sl_hostid)
3881 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3883 kprintf("%s: scsi_low: target %d (host card)\n",
3884 slp->sl_xname, target);
3886 continue;
3889 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3891 kprintf("%s: scsi_low: target %d lun ",
3892 slp->sl_xname, target);
3895 ti = slp->sl_ti[target];
3896 for (lun = 0; lun < slp->sl_nluns; lun ++)
3898 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
3899 break;
3901 cb->osdep = NULL;
3902 cb->bp = NULL;
3904 li = scsi_low_alloc_li(ti, lun, 1);
3906 scsi_low_enqueue(slp, ti, li, cb,
3907 CCB_AUTOSENSE | CCB_POLLED, 0);
3909 scsi_low_poll(slp, cb);
3911 if (li->li_state != SCSI_LOW_LUN_OK)
3912 break;
3914 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3916 kprintf("%d ", lun);
3920 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3922 kprintf("\n");
3925 return 0;
3928 static int
3929 scsi_low_poll(struct scsi_low_softc *slp, struct slccb *cb)
3931 int tcount;
3933 tcount = 0;
3934 while (slp->sl_nio > 0)
3936 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
3938 (*slp->sl_funcs->scsi_low_poll) (slp);
3939 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
3940 continue;
3942 tcount = 0;
3943 scsi_low_timeout_check(slp);
3946 return 0;
3948 #endif /* SCSI_LOW_START_UP_CHECK */
3950 /**********************************************************
3951 * DEBUG SECTION
3952 **********************************************************/
3953 #ifdef SCSI_LOW_DEBUG
3954 static void
3955 scsi_low_test_abort(struct scsi_low_softc *slp, struct targ_info *ti,
3956 struct lun_info *li)
3958 struct slccb *acb;
3960 if (li->li_disc > 1)
3962 acb = TAILQ_FIRST(&li->li_discq);
3963 if (scsi_low_abort_ccb(slp, acb) == 0)
3965 kprintf("%s: aborting ccb(0x%lx) start\n",
3966 slp->sl_xname, (u_long) acb);
3971 static void
3972 scsi_low_test_atten(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg)
3974 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
3975 scsi_low_assert_msg(slp, ti, msg, 0);
3976 else
3977 kprintf("%s: atten check OK\n", slp->sl_xname);
3980 static void
3981 scsi_low_test_cmdlnk(struct scsi_low_softc *slp, struct slccb *cb)
3983 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
3985 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
3986 return;
3988 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
3989 slp->sl_scp.scp_cmdlen);
3990 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
3991 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
3993 #endif /* SCSI_LOW_DEBUG */
3995 /* static */ void
3996 scsi_low_info(struct scsi_low_softc *slp, struct targ_info *ti, u_char *s)
3998 if (slp == NULL)
3999 slp = LIST_FIRST(&sl_tab);
4000 if (s == NULL)
4001 s = "no message";
4003 kprintf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4004 if (ti == NULL)
4006 TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
4008 scsi_low_print(slp, ti);
4011 else
4013 scsi_low_print(slp, ti);
4017 static u_char *phase[] =
4019 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4020 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4023 void
4024 scsi_low_print(struct scsi_low_softc *slp, struct targ_info *ti)
4026 struct lun_info *li;
4027 struct slccb *cb;
4028 struct sc_p *sp;
4030 if (ti == NULL || ti == slp->sl_Tnexus)
4032 ti = slp->sl_Tnexus;
4033 li = slp->sl_Lnexus;
4034 cb = slp->sl_Qnexus;
4036 else
4038 li = LIST_FIRST(&ti->ti_litab);
4039 cb = TAILQ_FIRST(&li->li_discq);
4041 sp = &slp->sl_scp;
4043 kprintf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4044 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4045 slp->sl_nio);
4047 /* target stat */
4048 if (ti != NULL)
4050 u_int flags = 0, maxnqio = 0, nqio = 0;
4051 int lun = -1;
4053 if (li != NULL)
4055 lun = li->li_lun;
4056 flags = li->li_flags;
4057 maxnqio = li->li_maxnqio;
4058 nqio = li->li_nqio;
4061 kprintf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4062 slp->sl_xname,
4063 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4064 phase[(int) ti->ti_phase], ti->ti_disc,
4065 nqio, maxnqio);
4067 if (cb != NULL)
4069 kprintf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4070 (u_int) cb->ccb_scp.scp_cmd[0],
4071 cb->ccb_scp.scp_cmdlen,
4072 cb->ccb_datalen,
4073 cb->ccb_scp.scp_datalen,
4074 (u_int) cb->ccb_sscp.scp_status,
4075 cb->ccb_error, SCSI_LOW_ERRORBITS);
4078 kprintf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4079 (u_int) (ti->ti_msginptr),
4080 (u_int) (ti->ti_msgin[0]),
4081 (u_int) (ti->ti_msgin[1]),
4082 (u_int) (ti->ti_msgin[2]),
4083 (u_int) (ti->ti_msgin[3]),
4084 (u_int) (ti->ti_msgin[4]),
4085 slp->sl_atten);
4087 kprintf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4088 (u_int) ti->ti_msgflags,
4089 (u_int) (ti->ti_msgoutstr[0]),
4090 (u_int) (ti->ti_msgoutstr[1]),
4091 (u_int) (ti->ti_msgoutstr[2]),
4092 (u_int) (ti->ti_msgoutstr[3]),
4093 (u_int) (ti->ti_msgoutstr[4]),
4094 ti->ti_msgoutlen,
4095 flags, SCSI_LOW_BITS);
4097 #ifdef SCSI_LOW_DIAGNOSTIC
4098 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4099 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4100 #endif /* SCSI_LOW_DIAGNOSTIC */
4104 kprintf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4105 (u_long) sp->scp_data,
4106 sp->scp_datalen,
4107 (u_int) sp->scp_status,
4108 slp->sl_error, SCSI_LOW_ERRORBITS);