Fix numerous compiler warnings and format conversion specifiers.
[dragonfly.git] / sys / bus / cam / scsi / scsi_low.c
blob258b0e964ad3a2480e94b4f7ba7790d3b8ec2554
1 /*
2 * $FreeBSD: src/sys/cam/scsi/scsi_low.c,v 1.1.2.5 2003/08/09 06:18:30 non Exp $
3 * $DragonFly: src/sys/bus/cam/scsi/scsi_low.c,v 1.28 2008/05/18 20:30:20 pavalos Exp $
4 * $NetBSD: scsi_low.c,v 1.24.10.8 2001/06/26 07:39:44 honda Exp $
5 */
7 #define SCSI_LOW_STATICS
8 #define SCSI_LOW_DEBUG
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define SCSI_LOW_START_UP_CHECK
12 /* #define SCSI_LOW_INFO_DETAIL */
13 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
14 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
16 #define SCSI_LOW_FLAGS_QUIRKS_OK
19 * [NetBSD for NEC PC-98 series]
20 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
21 * NetBSD/pc98 porting staff. All rights reserved.
22 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
23 * Naofumi HONDA. All rights reserved.
25 * [Ported for FreeBSD CAM]
26 * Copyright (c) 2000, 2001
27 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
28 * All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. The name of the author may not be used to endorse or promote products
39 * derived from this software without specific prior written permission.
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
42 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
45 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
46 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
47 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
50 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
51 * POSSIBILITY OF SUCH DAMAGE.
54 /* <On the nexus establishment>
55 * When our host is reselected,
56 * nexus establish processes are little complicated.
57 * Normal steps are followings:
58 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
59 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
60 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
62 #include "opt_ddb.h"
64 #include <sys/param.h>
65 #include <sys/buf.h>
66 #include <sys/cons.h>
67 #include <sys/devicestat.h>
68 #include <sys/errno.h>
69 #include <sys/kernel.h>
70 #include <sys/malloc.h>
71 #include <sys/queue.h>
72 #include <sys/systm.h>
73 #include <sys/thread2.h>
75 #include <bus/cam/cam.h>
76 #include <bus/cam/cam_ccb.h>
77 #include <bus/cam/cam_sim.h>
78 #include <bus/cam/cam_debug.h>
79 #include <bus/cam/cam_periph.h>
80 #include <bus/cam/cam_xpt_periph.h>
82 #include <bus/cam/scsi/scsi_all.h>
83 #include <bus/cam/scsi/scsi_low.h>
85 /**************************************************************
86 * Constants
87 **************************************************************/
88 #define SCSI_LOW_POLL_HZ 1000
90 /* functions return values */
91 #define SCSI_LOW_START_NO_QTAG 0
92 #define SCSI_LOW_START_QTAG 1
94 #define SCSI_LOW_DONE_COMPLETE 0
95 #define SCSI_LOW_DONE_RETRY 1
97 /* internal disk flags */
98 #define SCSI_LOW_DISK_DISC 0x00000001
99 #define SCSI_LOW_DISK_QTAG 0x00000002
100 #define SCSI_LOW_DISK_LINK 0x00000004
101 #define SCSI_LOW_DISK_PARITY 0x00000008
102 #define SCSI_LOW_DISK_SYNC 0x00010000
103 #define SCSI_LOW_DISK_WIDE_16 0x00020000
104 #define SCSI_LOW_DISK_WIDE_32 0x00040000
105 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
106 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
107 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
109 MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
111 /**************************************************************
112 * Declarations
113 **************************************************************/
114 /* static */ void scsi_low_info (struct scsi_low_softc *, struct targ_info *, u_char *);
115 static void scsi_low_engage (void *);
116 static struct slccb *scsi_low_establish_ccb (struct targ_info *, struct lun_info *, scsi_low_tag_t);
117 static int scsi_low_done (struct scsi_low_softc *, struct slccb *);
118 static int scsi_low_setup_done (struct scsi_low_softc *, struct slccb *);
119 static void scsi_low_bus_release (struct scsi_low_softc *, struct targ_info *);
120 static void scsi_low_twiddle_wait (void);
121 static struct lun_info *scsi_low_alloc_li (struct targ_info *, int, int);
122 static struct targ_info *scsi_low_alloc_ti (struct scsi_low_softc *, int);
123 static void scsi_low_calcf_lun (struct lun_info *);
124 static void scsi_low_calcf_target (struct targ_info *);
125 static void scsi_low_calcf_show (struct lun_info *);
126 static void scsi_low_reset_nexus (struct scsi_low_softc *, int);
127 static void scsi_low_reset_nexus_target (struct scsi_low_softc *, struct targ_info *, int);
128 static void scsi_low_reset_nexus_lun (struct scsi_low_softc *, struct lun_info *, int);
129 static int scsi_low_init (struct scsi_low_softc *, u_int);
130 static void scsi_low_start (struct scsi_low_softc *);
131 static void scsi_low_free_ti (struct scsi_low_softc *);
133 static int scsi_low_alloc_qtag (struct slccb *);
134 static int scsi_low_dealloc_qtag (struct slccb *);
135 static int scsi_low_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
136 static int scsi_low_message_enqueue (struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
137 static void scsi_low_unit_ready_cmd (struct slccb *);
138 static void scsi_low_timeout (void *);
139 static int scsi_low_timeout_check (struct scsi_low_softc *);
140 #ifdef SCSI_LOW_START_UP_CHECK
141 static int scsi_low_start_up (struct scsi_low_softc *);
142 #endif /* SCSI_LOW_START_UP_CHECK */
143 static int scsi_low_abort_ccb (struct scsi_low_softc *, struct slccb *);
144 static struct slccb *scsi_low_revoke_ccb (struct scsi_low_softc *, struct slccb *, int);
146 int scsi_low_version_major = 2;
147 int scsi_low_version_minor = 17;
149 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
151 /**************************************************************
152 * Debug, Run test and Statics
153 **************************************************************/
154 #ifdef SCSI_LOW_INFO_DETAIL
155 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
156 #else /* !SCSI_LOW_INFO_DETAIL */
157 #define SCSI_LOW_INFO(slp, ti, s) kprintf("%s: %s\n", (slp)->sl_xname, (s))
158 #endif /* !SCSI_LOW_INFO_DETAIL */
160 #ifdef SCSI_LOW_STATICS
161 static struct scsi_low_statics {
162 int nexus_win;
163 int nexus_fail;
164 int nexus_disconnected;
165 int nexus_reselected;
166 int nexus_conflict;
167 } scsi_low_statics;
168 #endif /* SCSI_LOW_STATICS */
170 #ifdef SCSI_LOW_DEBUG
171 #define SCSI_LOW_DEBUG_DONE 0x00001
172 #define SCSI_LOW_DEBUG_DISC 0x00002
173 #define SCSI_LOW_DEBUG_SENSE 0x00004
174 #define SCSI_LOW_DEBUG_CALCF 0x00008
175 #define SCSI_LOW_DEBUG_ACTION 0x10000
176 int scsi_low_debug = 0;
178 #define SCSI_LOW_MAX_ATTEN_CHECK 32
179 #define SCSI_LOW_ATTEN_CHECK 0x0001
180 #define SCSI_LOW_CMDLNK_CHECK 0x0002
181 #define SCSI_LOW_ABORT_CHECK 0x0004
182 #define SCSI_LOW_NEXUS_CHECK 0x0008
183 int scsi_low_test = 0;
184 int scsi_low_test_id = 0;
186 static void scsi_low_test_abort (struct scsi_low_softc *, struct targ_info *, struct lun_info *);
187 static void scsi_low_test_cmdlnk (struct scsi_low_softc *, struct slccb *);
188 static void scsi_low_test_atten (struct scsi_low_softc *, struct targ_info *, u_int);
189 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
190 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
191 #define SCSI_LOW_DEBUG_GO(fl, id) \
192 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
193 #endif /* SCSI_LOW_DEBUG */
195 /**************************************************************
196 * CCB
197 **************************************************************/
198 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
199 GENERIC_CCB(scsi_low, slccb, ccb_chain)
201 /**************************************************************
202 * Inline functions
203 **************************************************************/
204 #define SCSI_LOW_INLINE static __inline
205 SCSI_LOW_INLINE void scsi_low_activate_qtag (struct slccb *);
206 SCSI_LOW_INLINE void scsi_low_deactivate_qtag (struct slccb *);
207 SCSI_LOW_INLINE void scsi_low_ccb_message_assert (struct slccb *, u_int);
208 SCSI_LOW_INLINE void scsi_low_ccb_message_exec (struct scsi_low_softc *, struct slccb *);
209 SCSI_LOW_INLINE void scsi_low_ccb_message_retry (struct slccb *);
210 SCSI_LOW_INLINE void scsi_low_ccb_message_clear (struct slccb *);
211 SCSI_LOW_INLINE void scsi_low_init_msgsys (struct scsi_low_softc *, struct targ_info *);
213 SCSI_LOW_INLINE void
214 scsi_low_activate_qtag(struct slccb *cb)
216 struct lun_info *li = cb->li;
218 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
219 return;
221 li->li_nqio ++;
222 cb->ccb_tag = cb->ccb_otag;
225 SCSI_LOW_INLINE void
226 scsi_low_deactivate_qtag(struct slccb *cb)
228 struct lun_info *li = cb->li;
230 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
231 return;
233 li->li_nqio --;
234 cb->ccb_tag = SCSI_LOW_UNKTAG;
237 SCSI_LOW_INLINE void
238 scsi_low_ccb_message_exec(struct scsi_low_softc *slp, struct slccb *cb)
240 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
241 cb->ccb_msgoutflag = 0;
244 SCSI_LOW_INLINE void
245 scsi_low_ccb_message_assert(struct slccb *cb, u_int msg)
247 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
250 SCSI_LOW_INLINE void
251 scsi_low_ccb_message_retry(struct slccb *cb)
253 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
256 SCSI_LOW_INLINE void
257 scsi_low_ccb_message_clear(struct slccb *cb)
259 cb->ccb_msgoutflag = 0;
262 SCSI_LOW_INLINE void
263 scsi_low_init_msgsys(struct scsi_low_softc *slp, struct targ_info *ti)
265 ti->ti_msginptr = 0;
266 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
267 SCSI_LOW_DEASSERT_ATN(slp);
268 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
271 /*=============================================================
272 * START OF OS switch (All OS depend fucntions should be here)
273 =============================================================*/
274 /* common os depend utitlities */
275 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
276 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
277 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
279 static u_int8_t scsi_low_cmd_flags[256] = {
280 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
281 /*0*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
282 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
283 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
284 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
287 struct scsi_low_error_code {
288 int error_bits;
289 int error_code;
292 static struct slccb *scsi_low_find_ccb (struct scsi_low_softc *, u_int, u_int, void *);
293 static int scsi_low_translate_error_code (struct slccb *, struct scsi_low_error_code *);
295 static struct slccb *
296 scsi_low_find_ccb(struct scsi_low_softc *slp, u_int target, u_int lun, void *osdep)
298 struct targ_info *ti;
299 struct lun_info *li;
300 struct slccb *cb;
302 ti = slp->sl_ti[target];
303 li = scsi_low_alloc_li(ti, lun, 0);
304 if (li == NULL)
305 return NULL;
307 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
308 return cb;
310 TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
312 if (cb->osdep == osdep)
313 return cb;
316 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
318 if (cb->osdep == osdep)
319 return cb;
321 return NULL;
324 static int
325 scsi_low_translate_error_code(struct slccb *cb, struct scsi_low_error_code *tp)
327 if (cb->ccb_error == 0)
328 return tp->error_code;
330 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
332 return tp->error_code;
335 /**************************************************************
336 * SCSI INTERFACE (CAM)
337 **************************************************************/
338 #define SCSI_LOW_MALLOC(size) kmalloc((size), M_SCSILOW, M_INTWAIT)
339 #define SCSI_LOW_FREE(pt) kfree((pt), M_SCSILOW)
340 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
342 static void scsi_low_poll_cam (struct cam_sim *);
343 static void scsi_low_cam_rescan_callback (struct cam_periph *, union ccb *);
344 static void scsi_low_rescan_bus_cam (struct scsi_low_softc *);
345 void scsi_low_scsi_action_cam (struct cam_sim *, union ccb *);
347 static int scsi_low_attach_cam (struct scsi_low_softc *);
348 static int scsi_low_world_start_cam (struct scsi_low_softc *);
349 static int scsi_low_dettach_cam (struct scsi_low_softc *);
350 static int scsi_low_ccb_setup_cam (struct scsi_low_softc *, struct slccb *);
351 static int scsi_low_done_cam (struct scsi_low_softc *, struct slccb *);
352 static void scsi_low_timeout_cam (struct scsi_low_softc *, int, int);
354 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
355 scsi_low_attach_cam,
356 scsi_low_world_start_cam,
357 scsi_low_dettach_cam,
358 scsi_low_ccb_setup_cam,
359 scsi_low_done_cam,
360 scsi_low_timeout_cam
363 struct scsi_low_error_code scsi_low_error_code_cam[] = {
364 {0, CAM_REQ_CMP},
365 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
366 {SENSEERR, CAM_AUTOSENSE_FAIL},
367 {UACAERR, CAM_SCSI_STATUS_ERROR},
368 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
369 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
370 {TIMEOUTIO, CAM_CMD_TIMEOUT},
371 {PDMAERR, CAM_DATA_RUN_ERR},
372 {PARITYERR, CAM_UNCOR_PARITY},
373 {UBFERR, CAM_UNEXP_BUSFREE},
374 {ABORTIO, CAM_REQ_ABORTED},
375 {-1, CAM_UNREC_HBA_ERROR}
378 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
380 /* XXX:
381 * Please check a polling hz, currently we assume scsi_low_poll() is
382 * called each 1 ms.
384 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
386 static void
387 scsi_low_poll_cam(struct cam_sim *sim)
389 struct scsi_low_softc *slp = SIM2SLP(sim);
391 (*slp->sl_funcs->scsi_low_poll) (slp);
393 if (slp->sl_si.si_poll_count ++ >=
394 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
396 slp->sl_si.si_poll_count = 0;
397 scsi_low_timeout_check(slp);
401 static void
402 scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb)
404 xpt_free_path(ccb->ccb_h.path);
405 xpt_free_ccb(ccb);
408 static void
409 scsi_low_rescan_bus_cam(struct scsi_low_softc *slp)
411 struct cam_path *path;
412 union ccb *ccb = xpt_alloc_ccb();
413 cam_status status;
415 status = xpt_create_path(&path, xpt_periph,
416 cam_sim_path(slp->sl_si.sim), -1, 0);
417 if (status != CAM_REQ_CMP)
418 return;
420 xpt_setup_ccb(&ccb->ccb_h, path, 5);
421 ccb->ccb_h.func_code = XPT_SCAN_BUS;
422 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback;
423 ccb->crcn.flags = CAM_FLAG_NONE;
424 xpt_action(ccb);
427 void
428 scsi_low_scsi_action_cam(struct cam_sim *sim, union ccb *ccb)
430 struct scsi_low_softc *slp = SIM2SLP(sim);
431 struct targ_info *ti;
432 struct lun_info *li;
433 struct slccb *cb;
434 u_int lun, flags, msg, target;
435 int rv;
437 target = (u_int) (ccb->ccb_h.target_id);
438 lun = (u_int) ccb->ccb_h.target_lun;
440 #ifdef SCSI_LOW_DEBUG
441 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_ACTION, target) != 0)
443 kprintf("%s: cam_action: func code 0x%x target: %d, lun: %d\n",
444 slp->sl_xname, ccb->ccb_h.func_code, target, lun);
446 #endif /* SCSI_LOW_DEBUG */
448 switch (ccb->ccb_h.func_code) {
449 case XPT_SCSI_IO: /* Execute the requested I/O operation */
450 #ifdef SCSI_LOW_DIAGNOSTIC
451 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
453 kprintf("%s: invalid target/lun\n", slp->sl_xname);
454 ccb->ccb_h.status = CAM_REQ_INVALID;
455 xpt_done(ccb);
456 return;
458 #endif /* SCSI_LOW_DIAGNOSTIC */
460 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)) {
461 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
462 xpt_done(ccb);
463 return;
466 ti = slp->sl_ti[target];
467 cb->osdep = ccb;
468 cb->bp = NULL;
469 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
470 flags = CCB_AUTOSENSE | CCB_SCSIIO;
471 else
472 flags = CCB_SCSIIO;
474 crit_enter();
475 li = scsi_low_alloc_li(ti, lun, 1);
477 if (ti->ti_setup_msg != 0)
479 scsi_low_message_enqueue(slp, ti, li, CCB_AUTOSENSE);
482 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
484 #ifdef SCSI_LOW_DEBUG
485 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, target) != 0)
487 scsi_low_test_abort(slp, ti, li);
489 #endif /* SCSI_LOW_DEBUG */
490 crit_exit();
491 break;
493 case XPT_EN_LUN: /* Enable LUN as a target */
494 case XPT_TARGET_IO: /* Execute target I/O request */
495 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
496 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
497 /* XXX Implement */
498 ccb->ccb_h.status = CAM_REQ_INVALID;
499 xpt_done(ccb);
500 break;
502 case XPT_ABORT: /* Abort the specified CCB */
503 #ifdef SCSI_LOW_DIAGNOSTIC
504 if (target == CAM_TARGET_WILDCARD || lun == CAM_LUN_WILDCARD)
506 kprintf("%s: invalid target/lun\n", slp->sl_xname);
507 ccb->ccb_h.status = CAM_REQ_INVALID;
508 xpt_done(ccb);
509 return;
511 #endif /* SCSI_LOW_DIAGNOSTIC */
513 crit_enter();
514 cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb);
515 rv = scsi_low_abort_ccb(slp, cb);
516 crit_exit();
518 if (rv == 0)
519 ccb->ccb_h.status = CAM_REQ_CMP;
520 else
521 ccb->ccb_h.status = CAM_REQ_INVALID;
522 xpt_done(ccb);
523 break;
525 case XPT_SET_TRAN_SETTINGS: {
526 struct ccb_trans_settings_scsi *scsi;
527 struct ccb_trans_settings_spi *spi;
528 struct ccb_trans_settings *cts;
529 u_int val;
531 #ifdef SCSI_LOW_DIAGNOSTIC
532 if (target == CAM_TARGET_WILDCARD)
534 kprintf("%s: invalid target\n", slp->sl_xname);
535 ccb->ccb_h.status = CAM_REQ_INVALID;
536 xpt_done(ccb);
537 return;
539 #endif /* SCSI_LOW_DIAGNOSTIC */
540 cts = &ccb->cts;
541 ti = slp->sl_ti[target];
542 if (lun == CAM_LUN_WILDCARD)
543 lun = 0;
545 crit_enter();
546 scsi = &cts->proto_specific.scsi;
547 spi = &cts->xport_specific.spi;
548 if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH |
549 CTS_SPI_VALID_SYNC_RATE |
550 CTS_SPI_VALID_SYNC_OFFSET)) != 0)
552 if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) {
553 val = spi->bus_width;
554 if (val < ti->ti_width)
555 ti->ti_width = val;
557 if (spi->valid & CTS_SPI_VALID_SYNC_RATE) {
558 val = spi->sync_period;
559 if (val == 0 || val > ti->ti_maxsynch.period)
560 ti->ti_maxsynch.period = val;
562 if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) {
563 val = spi->sync_offset;
564 if (val < ti->ti_maxsynch.offset)
565 ti->ti_maxsynch.offset = val;
567 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
568 scsi_low_calcf_target(ti);
571 if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 ||
572 (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
574 li = scsi_low_alloc_li(ti, lun, 1);
575 if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) {
576 li->li_quirks |= SCSI_LOW_DISK_DISC;
577 } else {
578 li->li_quirks &= ~SCSI_LOW_DISK_DISC;
581 if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) {
582 li->li_quirks |= SCSI_LOW_DISK_QTAG;
583 } else {
584 li->li_quirks &= ~SCSI_LOW_DISK_QTAG;
586 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
587 scsi_low_calcf_target(ti);
588 scsi_low_calcf_lun(li);
589 if ((slp->sl_show_result & SHOW_CALCF_RES) != 0)
590 scsi_low_calcf_show(li);
592 crit_exit();
594 ccb->ccb_h.status = CAM_REQ_CMP;
595 xpt_done(ccb);
596 break;
599 case XPT_GET_TRAN_SETTINGS: {
600 struct ccb_trans_settings *cts;
601 u_int diskflags;
603 cts = &ccb->cts;
604 #ifdef SCSI_LOW_DIAGNOSTIC
605 if (target == CAM_TARGET_WILDCARD)
607 kprintf("%s: invalid target\n", slp->sl_xname);
608 ccb->ccb_h.status = CAM_REQ_INVALID;
609 xpt_done(ccb);
610 return;
612 #endif /* SCSI_LOW_DIAGNOSTIC */
613 ti = slp->sl_ti[target];
614 if (lun == CAM_LUN_WILDCARD)
615 lun = 0;
617 crit_enter();
618 li = scsi_low_alloc_li(ti, lun, 1);
619 if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) {
620 struct ccb_trans_settings_scsi *scsi =
621 &cts->proto_specific.scsi;
622 struct ccb_trans_settings_spi *spi =
623 &cts->xport_specific.spi;
624 #ifdef SCSI_LOW_DIAGNOSTIC
625 if (li->li_flags_valid != SCSI_LOW_LUN_FLAGS_ALL_VALID)
627 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
628 kprintf("%s: invalid GET_TRANS_CURRENT_SETTINGS call\n",
629 slp->sl_xname);
630 goto settings_out;
632 #endif /* SCSI_LOW_DIAGNOSTIC */
633 cts->protocol = PROTO_SCSI;
634 cts->protocol_version = SCSI_REV_2;
635 cts->transport = XPORT_SPI;
636 cts->transport_version = 2;
638 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
639 spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
641 diskflags = li->li_diskflags & li->li_cfgflags;
642 if (diskflags & SCSI_LOW_DISK_DISC)
643 spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
644 if (diskflags & SCSI_LOW_DISK_QTAG)
645 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
647 spi->sync_period = ti->ti_maxsynch.period;
648 spi->valid |= CTS_SPI_VALID_SYNC_RATE;
649 spi->sync_offset = ti->ti_maxsynch.offset;
650 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
652 spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
653 spi->bus_width = ti->ti_width;
655 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
656 scsi->valid = CTS_SCSI_VALID_TQ;
657 spi->valid |= CTS_SPI_VALID_DISC;
658 } else
659 scsi->valid = 0;
660 } else
661 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
662 settings_out:
663 crit_exit();
664 xpt_done(ccb);
665 break;
668 case XPT_CALC_GEOMETRY: { /* not yet HN2 */
669 cam_calc_geometry(&ccb->ccg, /*extended*/1);
670 xpt_done(ccb);
671 break;
674 case XPT_RESET_BUS: /* Reset the specified SCSI bus */
675 crit_enter();
676 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
677 crit_exit();
678 ccb->ccb_h.status = CAM_REQ_CMP;
679 xpt_done(ccb);
680 break;
682 case XPT_TERM_IO: /* Terminate the I/O process */
683 ccb->ccb_h.status = CAM_REQ_INVALID;
684 xpt_done(ccb);
685 break;
687 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
688 #ifdef SCSI_LOW_DIAGNOSTIC
689 if (target == CAM_TARGET_WILDCARD)
691 kprintf("%s: invalid target\n", slp->sl_xname);
692 ccb->ccb_h.status = CAM_REQ_INVALID;
693 xpt_done(ccb);
694 return;
696 #endif /* SCSI_LOW_DIAGNOSTIC */
698 msg = SCSI_LOW_MSG_RESET;
699 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
701 ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
702 xpt_done(ccb);
703 return;
706 ti = slp->sl_ti[target];
707 if (lun == CAM_LUN_WILDCARD)
708 lun = 0;
709 cb->osdep = ccb;
710 cb->bp = NULL;
711 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
712 flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
713 else
714 flags = CCB_NORETRY | CCB_URGENT;
716 crit_enter();
717 li = scsi_low_alloc_li(ti, lun, 1);
718 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
719 crit_exit();
720 break;
722 case XPT_PATH_INQ: { /* Path routing inquiry */
723 struct ccb_pathinq *cpi = &ccb->cpi;
725 cpi->version_num = scsi_low_version_major;
726 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
727 ti = slp->sl_ti[slp->sl_hostid]; /* host id */
728 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
729 cpi->hba_inquiry |= PI_WIDE_16;
730 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
731 cpi->hba_inquiry |= PI_WIDE_32;
732 if (ti->ti_maxsynch.offset > 0)
733 cpi->hba_inquiry |= PI_SDTR_ABLE;
734 cpi->target_sprt = 0;
735 cpi->hba_misc = 0;
736 cpi->hba_eng_cnt = 0;
737 cpi->max_target = slp->sl_ntargs - 1;
738 cpi->max_lun = slp->sl_nluns - 1;
739 cpi->initiator_id = slp->sl_hostid;
740 cpi->bus_id = cam_sim_bus(sim);
741 cpi->base_transfer_speed = 3300;
742 cpi->transport = XPORT_SPI;
743 cpi->transport_version = 2;
744 cpi->protocol = PROTO_SCSI;
745 cpi->protocol_version = SCSI_REV_2;
746 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
747 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
748 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
749 cpi->unit_number = cam_sim_unit(sim);
750 cpi->ccb_h.status = CAM_REQ_CMP;
751 xpt_done(ccb);
752 break;
755 default:
756 kprintf("scsi_low: non support func_code = %d ",
757 ccb->ccb_h.func_code);
758 ccb->ccb_h.status = CAM_REQ_INVALID;
759 xpt_done(ccb);
760 break;
764 static int
765 scsi_low_attach_cam(struct scsi_low_softc *slp)
767 struct cam_devq *devq;
768 int tagged_openings;
770 ksprintf(slp->sl_xname, "%s%d",
771 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
773 devq = cam_simq_alloc(SCSI_LOW_NCCB);
774 if (devq == NULL)
775 return (ENOMEM);
778 * ask the adapter what subunits are present
780 tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
781 slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
782 scsi_low_poll_cam,
783 DEVPORT_DEVNAME(slp->sl_dev), slp,
784 DEVPORT_DEVUNIT(slp->sl_dev), &sim_mplock,
785 slp->sl_openings, tagged_openings, devq);
786 cam_simq_release(devq);
787 if (slp->sl_si.sim == NULL) {
788 return ENODEV;
791 if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
792 cam_sim_free(slp->sl_si.sim);
793 slp->sl_si.sim = NULL;
794 return ENODEV;
797 if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
798 cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
799 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
800 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
801 cam_sim_free(slp->sl_si.sim);
802 slp->sl_si.sim = NULL;
803 return ENODEV;
806 slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */
807 return 0;
810 static int
811 scsi_low_world_start_cam(struct scsi_low_softc *slp)
813 #if 0
814 if (!cold)
815 scsi_low_rescan_bus_cam(slp);
816 #endif
817 scsi_low_rescan_bus_cam(slp);
818 return 0;
821 static int
822 scsi_low_dettach_cam(struct scsi_low_softc *slp)
824 xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
825 xpt_free_path(slp->sl_si.path);
826 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
827 cam_sim_free(slp->sl_si.sim);
828 slp->sl_si.sim = NULL;
829 return 0;
832 static int
833 scsi_low_ccb_setup_cam(struct scsi_low_softc *slp, struct slccb *cb)
835 union ccb *ccb = (union ccb *) cb->osdep;
837 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
839 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
840 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
841 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
842 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
843 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
844 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
845 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
846 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
847 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
849 else
851 scsi_low_unit_ready_cmd(cb);
853 return SCSI_LOW_START_QTAG;
856 static int
857 scsi_low_done_cam(struct scsi_low_softc *slp, struct slccb *cb)
859 union ccb *ccb;
861 ccb = (union ccb *) cb->osdep;
862 if (cb->ccb_error == 0)
864 ccb->ccb_h.status = CAM_REQ_CMP;
865 ccb->csio.resid = 0;
867 else
869 if (cb->ccb_rcnt >= slp->sl_max_retry)
870 cb->ccb_error |= ABORTIO;
872 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
873 (cb->ccb_error & ABORTIO) == 0)
874 return EJUSTRETURN;
876 if ((cb->ccb_error & SENSEIO) != 0)
878 memcpy(&ccb->csio.sense_data,
879 &cb->ccb_sense,
880 sizeof(ccb->csio.sense_data));
883 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
884 &scsi_low_error_code_cam[0]);
886 #ifdef SCSI_LOW_DIAGNOSTIC
887 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
888 cb->ccb_scp.scp_cmdlen > 0 &&
889 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
890 SCSI_LOW_CMD_ABORT_WARNING) != 0)
892 kprintf("%s: WARNING: scsi_low IO abort\n",
893 slp->sl_xname);
894 scsi_low_print(slp, NULL);
896 #endif /* SCSI_LOW_DIAGNOSTIC */
899 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
900 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
902 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
903 ccb->csio.scsi_status = 0; /* XXX */
904 else
905 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
907 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
908 xpt_done(ccb);
909 return 0;
912 static void
913 scsi_low_timeout_cam(struct scsi_low_softc *slp, int ch, int action)
915 switch (ch)
917 case SCSI_LOW_TIMEOUT_CH_IO:
918 switch (action)
920 case SCSI_LOW_TIMEOUT_START:
921 callout_reset(&slp->sl_si.timeout_ch,
922 hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
923 break;
924 case SCSI_LOW_TIMEOUT_STOP:
925 callout_stop(&slp->sl_si.timeout_ch);
926 break;
928 break;
930 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
931 switch (action)
933 case SCSI_LOW_TIMEOUT_START:
934 callout_reset(&slp->sl_si.engage_ch, 1,
935 scsi_low_engage, slp);
936 break;
937 case SCSI_LOW_TIMEOUT_STOP:
938 callout_stop(&slp->sl_si.engage_ch);
939 break;
941 break;
942 case SCSI_LOW_TIMEOUT_CH_RECOVER:
943 break;
947 /**************************************************************
948 * scsi low deactivate and activate
949 **************************************************************/
951 scsi_low_is_busy(struct scsi_low_softc *slp)
953 if (slp->sl_nio > 0)
954 return EBUSY;
955 return 0;
959 scsi_low_deactivate(struct scsi_low_softc *slp)
961 crit_enter();
962 slp->sl_flags |= HW_INACTIVE;
963 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
964 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
965 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
966 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
967 crit_exit();
968 return 0;
972 scsi_low_activate(struct scsi_low_softc *slp)
974 int error;
976 crit_enter();
977 slp->sl_flags &= ~HW_INACTIVE;
978 if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
980 slp->sl_flags |= HW_INACTIVE;
981 crit_exit();
982 return error;
985 slp->sl_timeout_count = 0;
986 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
987 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
988 crit_exit();
989 return 0;
992 /**************************************************************
993 * scsi low log
994 **************************************************************/
995 #ifdef SCSI_LOW_DIAGNOSTIC
996 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
997 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
998 int);
999 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1001 static void
1002 scsi_low_msg_log_init(struct scsi_low_msg_log *slmlp)
1004 slmlp->slml_ptr = 0;
1007 static void
1008 scsi_low_msg_log_write(struct scsi_low_msg_log *slmlp, u_int8_t *datap, int len)
1010 int ptr, ind;
1012 if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1013 return;
1015 ptr = slmlp->slml_ptr ++;
1016 for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1017 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1018 for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1019 slmlp->slml_msg[ptr].msg[ind] = 0;
1022 static void
1023 scsi_low_msg_log_show(struct scsi_low_msg_log *slmlp, char *s, int len)
1025 int ptr, ind;
1027 kprintf("%s: (%d) ", s, slmlp->slml_ptr);
1028 for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1030 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1031 ind ++)
1033 kprintf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1035 kprintf(">");
1037 kprintf("\n");
1039 #endif /* SCSI_LOW_DIAGNOSTIC */
1041 /**************************************************************
1042 * power control
1043 **************************************************************/
1044 static void
1045 scsi_low_engage(void *arg)
1047 struct scsi_low_softc *slp = arg;
1049 crit_enter();
1051 switch (slp->sl_rstep)
1053 case 0:
1054 slp->sl_rstep ++;
1055 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1056 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1057 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1058 break;
1060 case 1:
1061 slp->sl_rstep ++;
1062 slp->sl_flags &= ~HW_RESUME;
1063 scsi_low_start(slp);
1064 break;
1066 case 2:
1067 break;
1069 crit_exit();
1072 static int
1073 scsi_low_init(struct scsi_low_softc *slp, u_int flags)
1075 int rv = 0;
1077 slp->sl_flags |= HW_INITIALIZING;
1079 /* clear power control timeout */
1080 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1082 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp,
1083 SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1084 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1085 slp->sl_active = 1;
1086 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1089 /* reset current nexus */
1090 scsi_low_reset_nexus(slp, flags);
1091 if ((slp->sl_flags & HW_INACTIVE) != 0)
1093 rv = EBUSY;
1094 goto out;
1097 if (flags != SCSI_LOW_RESTART_SOFT)
1099 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1102 out:
1103 slp->sl_flags &= ~HW_INITIALIZING;
1104 return rv;
1107 /**************************************************************
1108 * allocate lun_info
1109 **************************************************************/
1110 static struct lun_info *
1111 scsi_low_alloc_li(struct targ_info *ti, int lun, int alloc)
1113 struct scsi_low_softc *slp = ti->ti_sc;
1114 struct lun_info *li;
1116 li = LIST_FIRST(&ti->ti_litab);
1117 if (li != NULL)
1119 if (li->li_lun == lun)
1120 return li;
1122 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1124 if (li->li_lun == lun)
1126 LIST_REMOVE(li, lun_chain);
1127 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1128 return li;
1133 if (alloc == 0)
1134 return li;
1136 li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1137 if (li == NULL)
1138 panic("no lun info mem");
1140 SCSI_LOW_BZERO(li, ti->ti_lunsize);
1141 li->li_lun = lun;
1142 li->li_ti = ti;
1144 li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1145 SCSI_LOW_QTAG;
1146 li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1147 li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1148 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1149 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1150 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1152 li->li_qtagbits = (u_int) -1;
1154 TAILQ_INIT(&li->li_discq);
1155 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1157 /* host specific structure initialization per lun */
1158 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1159 (*slp->sl_funcs->scsi_low_lun_init)
1160 (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1161 scsi_low_calcf_lun(li);
1162 return li;
1165 /**************************************************************
1166 * allocate targ_info
1167 **************************************************************/
1168 static struct targ_info *
1169 scsi_low_alloc_ti(struct scsi_low_softc *slp, int targ)
1171 struct targ_info *ti;
1173 if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1174 TAILQ_INIT(&slp->sl_titab);
1176 ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1177 if (ti == NULL)
1178 panic("%s short of memory", slp->sl_xname);
1180 SCSI_LOW_BZERO(ti, slp->sl_targsize);
1181 ti->ti_id = targ;
1182 ti->ti_sc = slp;
1184 slp->sl_ti[targ] = ti;
1185 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1186 LIST_INIT(&ti->ti_litab);
1188 ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1189 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1190 ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1191 #ifdef SCSI_LOW_FLAGS_QUIRKS_OK
1192 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1193 #endif /* SCSI_LOW_FLAGS_QUIRKS_OK */
1195 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1197 (*slp->sl_funcs->scsi_low_targ_init)
1198 (slp, ti, SCSI_LOW_INFO_ALLOC);
1200 scsi_low_calcf_target(ti);
1201 return ti;
1204 static void
1205 scsi_low_free_ti(struct scsi_low_softc *slp)
1207 struct targ_info *ti, *tib;
1208 struct lun_info *li, *nli;
1210 for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1212 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1214 if (slp->sl_funcs->scsi_low_lun_init != NULL)
1216 (*slp->sl_funcs->scsi_low_lun_init)
1217 (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1219 nli = LIST_NEXT(li, lun_chain);
1220 SCSI_LOW_FREE(li);
1223 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1225 (*slp->sl_funcs->scsi_low_targ_init)
1226 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1228 tib = TAILQ_NEXT(ti, ti_chain);
1229 SCSI_LOW_FREE(ti);
1233 /**************************************************************
1234 * timeout
1235 **************************************************************/
1236 void
1237 scsi_low_bus_idle(struct scsi_low_softc *slp)
1239 slp->sl_retry_sel = 0;
1240 if (slp->sl_Tnexus == NULL)
1241 scsi_low_start(slp);
1244 static void
1245 scsi_low_timeout(void *arg)
1247 struct scsi_low_softc *slp = arg;
1249 crit_enter();
1250 scsi_low_timeout_check(slp);
1251 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1252 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1253 crit_exit();
1256 static int
1257 scsi_low_timeout_check(struct scsi_low_softc *slp)
1259 struct targ_info *ti;
1260 struct lun_info *li;
1261 struct slccb *cb = NULL; /* XXX */
1263 /* selection restart */
1264 if (slp->sl_retry_sel != 0)
1266 slp->sl_retry_sel = 0;
1267 if (slp->sl_Tnexus != NULL)
1268 goto step1;
1270 cb = TAILQ_FIRST(&slp->sl_start);
1271 if (cb == NULL)
1272 goto step1;
1274 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1276 cb->ccb_flags |= CCB_NORETRY;
1277 cb->ccb_error |= SELTIMEOUTIO;
1278 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1279 panic("%s: ccb not finished", slp->sl_xname);
1282 if (slp->sl_Tnexus == NULL)
1283 scsi_low_start(slp);
1286 /* call hardware timeout */
1287 step1:
1288 if (slp->sl_funcs->scsi_low_timeout != NULL)
1290 (*slp->sl_funcs->scsi_low_timeout) (slp);
1293 if (slp->sl_timeout_count ++ <
1294 SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1295 return 0;
1297 slp->sl_timeout_count = 0;
1298 if (slp->sl_nio > 0)
1300 if ((cb = slp->sl_Qnexus) != NULL)
1302 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1303 if (cb->ccb_tc < 0)
1304 goto bus_reset;
1306 else if (slp->sl_disc == 0)
1308 if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1309 return 0;
1311 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1312 if (cb->ccb_tc < 0)
1313 goto bus_reset;
1315 else TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
1317 if (ti->ti_disc == 0)
1318 continue;
1320 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
1322 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
1324 cb->ccb_tc -=
1325 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1326 if (cb->ccb_tc < 0)
1327 goto bus_reset;
1333 else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1335 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1336 return 0;
1338 if (slp->sl_active != 0)
1340 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1341 slp->sl_active = 0;
1342 return 0;
1345 slp->sl_powc --;
1346 if (slp->sl_powc < 0)
1348 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1349 slp->sl_flags |= HW_POWDOWN;
1350 (*slp->sl_funcs->scsi_low_power)
1351 (slp, SCSI_LOW_POWDOWN);
1354 return 0;
1356 bus_reset:
1357 cb->ccb_error |= TIMEOUTIO;
1358 kprintf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1359 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1360 scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1361 scsi_low_start(slp);
1362 return ERESTART;
1366 static int
1367 scsi_low_abort_ccb(struct scsi_low_softc *slp, struct slccb *cb)
1369 struct targ_info *ti;
1370 struct lun_info *li;
1371 u_int msg;
1373 if (cb == NULL)
1374 return EINVAL;
1375 if ((cb->ccb_omsgoutflag &
1376 (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1377 return EBUSY;
1379 ti = cb->ti;
1380 li = cb->li;
1381 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1382 msg = SCSI_LOW_MSG_ABORT;
1383 else
1384 msg = SCSI_LOW_MSG_ABORT_QTAG;
1386 cb->ccb_error |= ABORTIO;
1387 cb->ccb_flags |= CCB_NORETRY;
1388 scsi_low_ccb_message_assert(cb, msg);
1390 if (cb == slp->sl_Qnexus)
1392 scsi_low_assert_msg(slp, ti, msg, 1);
1394 else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1396 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1397 panic("%s: revoked ccb done", slp->sl_xname);
1399 cb->ccb_flags |= CCB_STARTQ;
1400 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1402 if (slp->sl_Tnexus == NULL)
1403 scsi_low_start(slp);
1405 else
1407 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1408 panic("%s: revoked ccb retried", slp->sl_xname);
1410 return 0;
1413 /**************************************************************
1414 * Generic SCSI INTERFACE
1415 **************************************************************/
1417 scsi_low_attach(struct scsi_low_softc *slp, int openings, int ntargs, int nluns,
1418 int targsize, int lunsize)
1420 struct targ_info *ti;
1421 struct lun_info *li;
1422 int i, nccb, rv;
1424 slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1426 if (slp->sl_osdep_fp == NULL)
1427 panic("scsi_low: interface not spcified");
1429 if (ntargs > SCSI_LOW_NTARGETS)
1431 kprintf("scsi_low: %d targets are too large\n", ntargs);
1432 kprintf("change kernel options SCSI_LOW_NTARGETS");
1433 return EINVAL;
1436 if (openings <= 0)
1437 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1438 else
1439 slp->sl_openings = openings;
1440 slp->sl_ntargs = ntargs;
1441 slp->sl_nluns = nluns;
1442 slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1444 if (lunsize < sizeof(struct lun_info))
1445 lunsize = sizeof(struct lun_info);
1447 if (targsize < sizeof(struct targ_info))
1448 targsize = sizeof(struct targ_info);
1450 slp->sl_targsize = targsize;
1451 for (i = 0; i < ntargs; i ++)
1453 ti = scsi_low_alloc_ti(slp, i);
1454 ti->ti_lunsize = lunsize;
1455 li = scsi_low_alloc_li(ti, 0, 1);
1458 /* initialize queue */
1459 nccb = openings * ntargs;
1460 if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1461 nccb = SCSI_LOW_NCCB;
1462 scsi_low_init_ccbque(nccb);
1463 TAILQ_INIT(&slp->sl_start);
1465 /* call os depend attach */
1466 callout_init(&slp->sl_si.timeout_ch);
1467 callout_init(&slp->sl_si.engage_ch);
1469 crit_enter();
1470 rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1471 if (rv != 0)
1473 crit_exit();
1474 kprintf("%s: scsi_low_attach: osdep attach failed\n",
1475 slp->sl_xname);
1476 return EINVAL;
1479 /* check hardware */
1480 SCSI_LOW_DELAY(1000); /* wait for 1ms */
1481 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1483 crit_exit();
1484 kprintf("%s: scsi_low_attach: initialization failed\n",
1485 slp->sl_xname);
1486 return EINVAL;
1489 /* start watch dog */
1490 slp->sl_timeout_count = 0;
1491 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1492 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1493 LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1495 /* fake call */
1496 scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1498 #ifdef SCSI_LOW_START_UP_CHECK
1499 /* probing devices */
1500 scsi_low_start_up(slp);
1501 #endif /* SCSI_LOW_START_UP_CHECK */
1503 /* call os depend attach done*/
1504 (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1505 crit_exit();
1506 return 0;
1510 scsi_low_dettach(struct scsi_low_softc *slp)
1512 int rv;
1514 crit_enter();
1515 if (scsi_low_is_busy(slp) != 0)
1517 crit_exit();
1518 return EBUSY;
1521 scsi_low_deactivate(slp);
1523 rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1524 if (rv != 0)
1526 crit_exit();
1527 return EBUSY;
1530 scsi_low_free_ti(slp);
1531 LIST_REMOVE(slp, sl_chain);
1532 crit_exit();
1533 return 0;
1536 /**************************************************************
1537 * Generic enqueue
1538 **************************************************************/
1539 static int
1540 scsi_low_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1541 struct lun_info *li, struct slccb *cb, u_int flags,
1542 u_int msg)
1545 cb->ti = ti;
1546 cb->li = li;
1548 scsi_low_ccb_message_assert(cb, msg);
1550 cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1551 scsi_low_alloc_qtag(cb);
1553 cb->ccb_flags = flags | CCB_STARTQ;
1554 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1555 cb->ccb_error |= PENDINGIO;
1557 if ((flags & CCB_URGENT) != 0)
1559 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1561 else
1563 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1566 slp->sl_nio ++;
1568 if (slp->sl_Tnexus == NULL)
1569 scsi_low_start(slp);
1570 return 0;
1573 static int
1574 scsi_low_message_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1575 struct lun_info *li, u_int flags)
1577 struct slccb *cb;
1578 u_int tmsgflags;
1580 tmsgflags = ti->ti_setup_msg;
1581 ti->ti_setup_msg = 0;
1583 flags |= CCB_NORETRY;
1584 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1585 return ENOMEM;
1587 cb->osdep = NULL;
1588 cb->bp = NULL;
1589 scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1590 return 0;
1593 /**************************************************************
1594 * Generic Start & Done
1595 **************************************************************/
1596 #define SLSC_MODE_SENSE_SHORT 0x1a
1597 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0};
1598 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0,
1599 sizeof(struct scsi_low_mode_sense_data), 0};
1600 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0,
1601 sizeof(struct scsi_low_inq_data), 0};
1602 static u_int8_t unit_ready_cmd[6];
1603 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1604 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1605 static int scsi_low_resume (struct scsi_low_softc *);
1607 static void
1608 scsi_low_unit_ready_cmd(struct slccb *cb)
1610 cb->ccb_scp.scp_cmd = unit_ready_cmd;
1611 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1612 cb->ccb_scp.scp_datalen = 0;
1613 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1614 cb->ccb_tcmax = 15;
1617 static int
1618 scsi_low_sense_abort_start(struct scsi_low_softc *slp, struct targ_info *ti,
1619 struct lun_info *li, struct slccb *cb)
1621 cb->ccb_scp.scp_cmdlen = 6;
1622 SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1623 cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1624 cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1625 cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1626 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1627 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1628 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1629 cb->ccb_tcmax = 15;
1630 scsi_low_ccb_message_clear(cb);
1631 if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1633 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1635 else
1637 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1638 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1639 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1640 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1643 return SCSI_LOW_START_NO_QTAG;
1646 static int
1647 scsi_low_setup_start(struct scsi_low_softc *slp, struct targ_info *ti,
1648 struct lun_info *li, struct slccb *cb)
1650 switch(li->li_state)
1652 case SCSI_LOW_LUN_SLEEP:
1653 scsi_low_unit_ready_cmd(cb);
1654 break;
1656 case SCSI_LOW_LUN_START:
1657 cb->ccb_scp.scp_cmd = ss_cmd;
1658 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1659 cb->ccb_scp.scp_datalen = 0;
1660 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1661 cb->ccb_tcmax = 30;
1662 break;
1664 case SCSI_LOW_LUN_INQ:
1665 cb->ccb_scp.scp_cmd = inq_cmd;
1666 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1667 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1668 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1669 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1670 cb->ccb_tcmax = 15;
1671 break;
1673 case SCSI_LOW_LUN_MODEQ:
1674 cb->ccb_scp.scp_cmd = sms_cmd;
1675 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1676 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1677 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1678 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1679 cb->ccb_tcmax = 15;
1680 return SCSI_LOW_START_QTAG;
1682 default:
1683 panic("%s: no setup phase", slp->sl_xname);
1686 return SCSI_LOW_START_NO_QTAG;
1689 static int
1690 scsi_low_resume(struct scsi_low_softc *slp)
1692 if (slp->sl_flags & HW_RESUME)
1693 return EJUSTRETURN;
1694 slp->sl_flags &= ~HW_POWDOWN;
1695 if (slp->sl_funcs->scsi_low_power != NULL)
1697 slp->sl_flags |= HW_RESUME;
1698 slp->sl_rstep = 0;
1699 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1700 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1701 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1702 SCSI_LOW_TIMEOUT_START);
1703 return EJUSTRETURN;
1705 return 0;
1708 static void
1709 scsi_low_start(struct scsi_low_softc *slp)
1711 struct targ_info *ti;
1712 struct lun_info *li;
1713 struct slccb *cb;
1714 int rv;
1716 /* check hardware exists or under initializations ? */
1717 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1718 return;
1720 /* check hardware power up ? */
1721 if ((slp->sl_flags & HW_POWERCTRL) != 0)
1723 slp->sl_active ++;
1724 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1726 if (scsi_low_resume(slp) == EJUSTRETURN)
1727 return;
1731 /* setup nexus */
1732 #ifdef SCSI_LOW_DIAGNOSTIC
1733 if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1735 scsi_low_info(slp, NULL, "NEXUS INCONSISTENT");
1736 panic("%s: inconsistent", slp->sl_xname);
1738 #endif /* SCSI_LOW_DIAGNOSTIC */
1740 TAILQ_FOREACH(cb, &slp->sl_start, ccb_chain)
1742 li = cb->li;
1744 if (li->li_disc == 0)
1746 goto scsi_low_cmd_start;
1748 else if (li->li_nqio > 0)
1750 if (li->li_nqio < li->li_maxnqio ||
1751 (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1752 goto scsi_low_cmd_start;
1755 return;
1757 scsi_low_cmd_start:
1758 cb->ccb_flags &= ~CCB_STARTQ;
1759 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1760 ti = cb->ti;
1762 /* clear all error flag bits (for restart) */
1763 cb->ccb_error = 0;
1764 cb->ccb_datalen = -1;
1765 cb->ccb_scp.scp_status = ST_UNKNOWN;
1767 /* setup nexus pointer */
1768 slp->sl_Qnexus = cb;
1769 slp->sl_Lnexus = li;
1770 slp->sl_Tnexus = ti;
1772 /* initialize msgsys */
1773 scsi_low_init_msgsys(slp, ti);
1775 /* exec cmd */
1776 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1778 /* CA state or forced abort */
1779 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1781 else if (li->li_state >= SCSI_LOW_LUN_OK)
1783 cb->ccb_flags &= ~CCB_INTERNAL;
1784 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1785 if (cb->ccb_msgoutflag != 0)
1787 scsi_low_ccb_message_exec(slp, cb);
1790 else
1792 cb->ccb_flags |= CCB_INTERNAL;
1793 rv = scsi_low_setup_start(slp, ti, li, cb);
1796 /* allocate qtag */
1797 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1799 if (rv == SCSI_LOW_START_QTAG &&
1800 (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1801 li->li_maxnqio > 0)
1803 u_int qmsg;
1805 scsi_low_activate_qtag(cb);
1806 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1807 SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1808 qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1809 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1810 qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1811 else
1812 qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1813 scsi_low_assert_msg(slp, ti, qmsg, 0);
1816 /* timeout */
1817 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1818 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1819 cb->ccb_tc = cb->ccb_tcmax;
1821 /* setup saved scsi data pointer */
1822 cb->ccb_sscp = cb->ccb_scp;
1824 /* setup current scsi pointer */
1825 slp->sl_scp = cb->ccb_sscp;
1826 slp->sl_error = cb->ccb_error;
1828 /* assert always an identify msg */
1829 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1831 /* debug section */
1832 #ifdef SCSI_LOW_DIAGNOSTIC
1833 scsi_low_msg_log_init(&ti->ti_log_msgin);
1834 scsi_low_msg_log_init(&ti->ti_log_msgout);
1835 #endif /* SCSI_LOW_DIAGNOSTIC */
1837 /* selection start */
1838 slp->sl_selid = cb;
1839 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1840 if (rv == SCSI_LOW_START_OK)
1842 #ifdef SCSI_LOW_STATICS
1843 scsi_low_statics.nexus_win ++;
1844 #endif /* SCSI_LOW_STATICS */
1845 return;
1848 scsi_low_arbit_fail(slp, cb);
1849 #ifdef SCSI_LOW_STATICS
1850 scsi_low_statics.nexus_fail ++;
1851 #endif /* SCSI_LOW_STATICS */
1854 void
1855 scsi_low_arbit_fail(struct scsi_low_softc *slp, struct slccb *cb)
1857 struct targ_info *ti = cb->ti;
1859 scsi_low_deactivate_qtag(cb);
1860 scsi_low_ccb_message_retry(cb);
1861 cb->ccb_flags |= CCB_STARTQ;
1862 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1864 scsi_low_bus_release(slp, ti);
1866 cb->ccb_selrcnt ++;
1867 if (slp->sl_disc == 0)
1869 #ifdef SCSI_LOW_DIAGNOSTIC
1870 kprintf("%s: try selection again\n", slp->sl_xname);
1871 #endif /* SCSI_LOW_DIAGNOSTIC */
1872 slp->sl_retry_sel = 1;
1876 static void
1877 scsi_low_bus_release(struct scsi_low_softc *slp, struct targ_info *ti)
1879 if (ti->ti_disc > 0)
1881 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1883 else
1885 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1888 /* clear all nexus pointer */
1889 slp->sl_Qnexus = NULL;
1890 slp->sl_Lnexus = NULL;
1891 slp->sl_Tnexus = NULL;
1893 /* clear selection assert */
1894 slp->sl_selid = NULL;
1896 /* clear nexus data */
1897 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1899 /* clear phase change counter */
1900 slp->sl_ph_count = 0;
1903 static int
1904 scsi_low_setup_done(struct scsi_low_softc *slp, struct slccb *cb)
1906 struct targ_info *ti;
1907 struct lun_info *li;
1909 ti = cb->ti;
1910 li = cb->li;
1912 if (cb->ccb_rcnt >= slp->sl_max_retry)
1914 cb->ccb_error |= ABORTIO;
1915 return SCSI_LOW_DONE_COMPLETE;
1918 /* XXX: special huck for selection timeout */
1919 if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1920 (cb->ccb_error & SELTIMEOUTIO) != 0)
1922 cb->ccb_error |= ABORTIO;
1923 return SCSI_LOW_DONE_COMPLETE;
1926 switch(li->li_state)
1928 case SCSI_LOW_LUN_INQ:
1929 if (cb->ccb_error != 0)
1931 li->li_diskflags &=
1932 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
1933 if (li->li_lun > 0)
1934 goto resume;
1935 ti->ti_diskflags &=
1936 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
1938 else if ((li->li_inq.sd_version & 7) >= 2 ||
1939 (li->li_inq.sd_len >= 4))
1941 if ((li->li_inq.sd_support & 0x2) == 0)
1942 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1943 if ((li->li_inq.sd_support & 0x8) == 0)
1944 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
1945 if (li->li_lun > 0)
1946 goto resume;
1947 if ((li->li_inq.sd_support & 0x10) == 0)
1948 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
1949 if ((li->li_inq.sd_support & 0x20) == 0)
1950 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
1951 if ((li->li_inq.sd_support & 0x40) == 0)
1952 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
1954 else
1956 li->li_diskflags &=
1957 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
1958 if (li->li_lun > 0)
1959 goto resume;
1960 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
1962 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
1963 resume:
1964 scsi_low_calcf_target(ti);
1965 scsi_low_calcf_lun(li);
1966 break;
1968 case SCSI_LOW_LUN_MODEQ:
1969 if (cb->ccb_error != 0)
1971 if (cb->ccb_error & SENSEIO)
1973 #ifdef SCSI_LOW_DEBUG
1974 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
1976 kprintf("SENSE: [%x][%x][%x][%x][%x]\n",
1977 (u_int) cb->ccb_sense.error_code,
1978 (u_int) cb->ccb_sense.segment,
1979 (u_int) cb->ccb_sense.flags,
1980 (u_int) cb->ccb_sense.add_sense_code,
1981 (u_int) cb->ccb_sense.add_sense_code_qual);
1983 #endif /* SCSI_LOW_DEBUG */
1985 else
1987 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1990 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
1992 if (li->li_sms.sms_cmp.cmp_qc & 0x02)
1993 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
1994 else
1995 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
1996 if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
1997 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
1999 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2000 scsi_low_calcf_lun(li);
2001 break;
2003 default:
2004 break;
2007 li->li_state ++;
2008 if (li->li_state == SCSI_LOW_LUN_OK)
2010 scsi_low_calcf_target(ti);
2011 scsi_low_calcf_lun(li);
2012 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2013 (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2015 scsi_low_calcf_show(li);
2019 cb->ccb_rcnt --;
2020 return SCSI_LOW_DONE_RETRY;
2023 static int
2024 scsi_low_done(struct scsi_low_softc *slp, struct slccb *cb)
2026 int rv;
2028 if (cb->ccb_error == 0)
2030 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2032 #ifdef SCSI_LOW_QCLEAR_AFTER_CA
2033 /* XXX:
2034 * SCSI-2 draft suggests
2035 * page 0x0a QErr bit determins if
2036 * the target aborts or continues
2037 * the queueing io's after CA state resolved.
2038 * However many targets seem not to support
2039 * the page 0x0a. Thus we should manually clear the
2040 * queuing io's after CA state.
2042 if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2044 cb->ccb_rcnt --;
2045 cb->ccb_flags |= CCB_CLEARQ;
2046 goto retry;
2048 #endif /* SCSI_LOW_QCLEAR_AFTER_CA */
2050 if ((cb->ccb_flags & CCB_SENSE) != 0)
2051 cb->ccb_error |= (SENSEIO | ABORTIO);
2052 cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2054 else switch (cb->ccb_sscp.scp_status)
2056 case ST_GOOD:
2057 case ST_MET:
2058 case ST_INTERGOOD:
2059 case ST_INTERMET:
2060 if (cb->ccb_datalen == 0 ||
2061 cb->ccb_scp.scp_datalen == 0)
2062 break;
2064 if (cb->ccb_scp.scp_cmdlen > 0 &&
2065 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2066 SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2067 break;
2069 cb->ccb_error |= PDMAERR;
2070 break;
2072 case ST_BUSY:
2073 case ST_QUEFULL:
2074 cb->ccb_error |= (BUSYERR | STATERR);
2075 break;
2077 case ST_CONFLICT:
2078 cb->ccb_error |= (STATERR | ABORTIO);
2079 break;
2081 case ST_CHKCOND:
2082 case ST_CMDTERM:
2083 if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2085 cb->ccb_rcnt --;
2086 cb->ccb_flags |= CCB_SENSE;
2087 goto retry;
2089 cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2090 break;
2092 case ST_UNKNOWN:
2093 default:
2094 cb->ccb_error |= FATALIO;
2095 break;
2098 else
2100 if (cb->ccb_flags & CCB_SENSE)
2102 cb->ccb_error |= (SENSEERR | ABORTIO);
2104 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2107 /* internal ccb */
2108 if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2110 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2111 goto retry;
2114 /* check a ccb msgout flag */
2115 if (cb->ccb_omsgoutflag != 0)
2117 #define SCSI_LOW_MSG_ABORT_OK (SCSI_LOW_MSG_ABORT | \
2118 SCSI_LOW_MSG_ABORT_QTAG | \
2119 SCSI_LOW_MSG_CLEAR_QTAG | \
2120 SCSI_LOW_MSG_TERMIO)
2122 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2124 cb->ccb_error |= ABORTIO;
2128 /* call OS depend done */
2129 if (cb->osdep != NULL)
2131 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2132 if (rv == EJUSTRETURN)
2133 goto retry;
2135 else if (cb->ccb_error != 0)
2137 if (cb->ccb_rcnt >= slp->sl_max_retry)
2138 cb->ccb_error |= ABORTIO;
2140 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2141 (cb->ccb_error & ABORTIO) == 0)
2142 goto retry;
2145 /* free our target */
2146 #ifdef SCSI_LOW_DEBUG
2147 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2149 kprintf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2150 scsi_low_print(slp, NULL);
2152 #endif /* SCSI_LOW_DEBUG */
2154 scsi_low_deactivate_qtag(cb);
2155 scsi_low_dealloc_qtag(cb);
2156 scsi_low_free_ccb(cb);
2157 slp->sl_nio --;
2158 return SCSI_LOW_DONE_COMPLETE;
2160 retry:
2161 #ifdef SCSI_LOW_DEBUG
2162 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2164 kprintf("** SCSI_LOW_DONE_RETRY ===============\n");
2165 scsi_low_print(slp, NULL);
2167 #endif /* SCSI_LOW_DEBUG */
2169 cb->ccb_rcnt ++;
2170 scsi_low_deactivate_qtag(cb);
2171 scsi_low_ccb_message_retry(cb);
2172 return SCSI_LOW_DONE_RETRY;
2175 /**************************************************************
2176 * Reset
2177 **************************************************************/
2178 static void
2179 scsi_low_reset_nexus_target(struct scsi_low_softc *slp, struct targ_info *ti,
2180 int fdone)
2182 struct lun_info *li;
2184 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
2186 scsi_low_reset_nexus_lun(slp, li, fdone);
2187 li->li_state = SCSI_LOW_LUN_SLEEP;
2188 li->li_maxnqio = 0;
2191 ti->ti_disc = 0;
2192 ti->ti_setup_msg = 0;
2193 ti->ti_setup_msg_done = 0;
2195 ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2196 ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2198 ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2199 ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2201 if (slp->sl_funcs->scsi_low_targ_init != NULL)
2203 ((*slp->sl_funcs->scsi_low_targ_init)
2204 (slp, ti, SCSI_LOW_INFO_REVOKE));
2206 scsi_low_calcf_target(ti);
2208 LIST_FOREACH(li, &ti->ti_litab, lun_chain)
2210 li->li_flags = 0;
2212 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2213 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2215 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2217 ((*slp->sl_funcs->scsi_low_lun_init)
2218 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2220 scsi_low_calcf_lun(li);
2224 static void
2225 scsi_low_reset_nexus(struct scsi_low_softc *slp, int fdone)
2227 struct targ_info *ti;
2228 struct slccb *cb, *topcb;
2230 if ((cb = slp->sl_Qnexus) != NULL)
2232 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2234 else
2236 topcb = NULL;
2239 TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
2241 scsi_low_reset_nexus_target(slp, ti, fdone);
2242 scsi_low_bus_release(slp, ti);
2243 scsi_low_init_msgsys(slp, ti);
2246 if (topcb != NULL)
2248 topcb->ccb_flags |= CCB_STARTQ;
2249 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2252 slp->sl_disc = 0;
2253 slp->sl_retry_sel = 0;
2254 slp->sl_flags &= ~HW_PDMASTART;
2257 /* misc */
2258 static int tw_pos;
2259 static char tw_chars[] = "|/-\\";
2260 #define TWIDDLEWAIT 10000
2262 static void
2263 scsi_low_twiddle_wait(void)
2265 cnputc('\b');
2266 cnputc(tw_chars[tw_pos++]);
2267 tw_pos %= (sizeof(tw_chars) - 1);
2268 SCSI_LOW_DELAY(TWIDDLEWAIT);
2271 void
2272 scsi_low_bus_reset(struct scsi_low_softc *slp)
2274 int i;
2276 (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2278 kprintf("%s: try to reset scsi bus ", slp->sl_xname);
2279 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2280 scsi_low_twiddle_wait();
2281 cnputc('\b');
2282 kprintf("\n");
2286 scsi_low_restart(struct scsi_low_softc *slp, int flags, u_char *s)
2288 int error;
2290 if (s != NULL)
2291 kprintf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2293 if ((error = scsi_low_init(slp, flags)) != 0)
2294 return error;
2296 scsi_low_start(slp);
2297 return 0;
2300 /**************************************************************
2301 * disconnect and reselect
2302 **************************************************************/
2303 #define MSGCMD_LUN(msg) (msg & 0x07)
2305 static struct slccb *
2306 scsi_low_establish_ccb(struct targ_info *ti, struct lun_info *li, scsi_low_tag_t tag)
2308 struct scsi_low_softc *slp = ti->ti_sc;
2309 struct slccb *cb;
2311 if (li == NULL)
2312 return NULL;
2314 TAILQ_FOREACH(cb, &li->li_discq, ccb_chain)
2315 if (cb->ccb_tag == tag)
2316 goto found;
2317 return cb;
2320 * establish our ccb nexus
2322 found:
2323 #ifdef SCSI_LOW_DEBUG
2324 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2326 kprintf("%s: nexus(0x%lx) abort check start\n",
2327 slp->sl_xname, (u_long) cb);
2328 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2329 scsi_low_revoke_ccb(slp, cb, 1);
2330 return NULL;
2333 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2335 if (cb->ccb_omsgoutflag == 0)
2336 scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2338 #endif /* SCSI_LOW_DEBUG */
2340 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2341 cb->ccb_flags &= ~CCB_DISCQ;
2342 slp->sl_Qnexus = cb;
2344 slp->sl_scp = cb->ccb_sscp;
2345 slp->sl_error |= cb->ccb_error;
2347 slp->sl_disc --;
2348 ti->ti_disc --;
2349 li->li_disc --;
2351 /* inform "ccb nexus established" to the host driver */
2352 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2354 /* check msg */
2355 if (cb->ccb_msgoutflag != 0)
2357 scsi_low_ccb_message_exec(slp, cb);
2360 return cb;
2363 struct targ_info *
2364 scsi_low_reselected(struct scsi_low_softc *slp, u_int targ)
2366 struct targ_info *ti;
2367 struct slccb *cb;
2368 u_char *s;
2371 * Check select vs reselected collision.
2374 if ((cb = slp->sl_selid) != NULL)
2376 scsi_low_arbit_fail(slp, cb);
2377 #ifdef SCSI_LOW_STATICS
2378 scsi_low_statics.nexus_conflict ++;
2379 #endif /* SCSI_LOW_STATICS */
2383 * Check if no current active nexus.
2385 if (slp->sl_Tnexus != NULL)
2387 s = "host busy";
2388 goto world_restart;
2392 * Check a valid target id asserted ?
2394 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2396 s = "scsi id illegal";
2397 goto world_restart;
2401 * Check the target scsi status.
2403 ti = slp->sl_ti[targ];
2404 if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2406 s = "phase mismatch";
2407 goto world_restart;
2411 * Setup init msgsys
2413 slp->sl_error = 0;
2414 scsi_low_init_msgsys(slp, ti);
2417 * Establish our target nexus
2419 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2420 slp->sl_Tnexus = ti;
2421 #ifdef SCSI_LOW_STATICS
2422 scsi_low_statics.nexus_reselected ++;
2423 #endif /* SCSI_LOW_STATICS */
2424 return ti;
2426 world_restart:
2427 kprintf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2428 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD,
2429 "reselect: scsi world confused");
2430 return NULL;
2433 /**************************************************************
2434 * cmd out pointer setup
2435 **************************************************************/
2437 scsi_low_cmd(struct scsi_low_softc *slp, struct targ_info *ti)
2439 struct slccb *cb = slp->sl_Qnexus;
2441 slp->sl_ph_count ++;
2442 if (cb == NULL)
2445 * no ccb, abort!
2447 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2448 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2449 slp->sl_scp.scp_datalen = 0;
2450 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2451 slp->sl_error |= FATALIO;
2452 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2453 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2454 return EINVAL;
2456 else
2458 #ifdef SCSI_LOW_DEBUG
2459 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2461 scsi_low_test_cmdlnk(slp, cb);
2463 #endif /* SCSI_LOW_DEBUG */
2465 return 0;
2468 /**************************************************************
2469 * data out pointer setup
2470 **************************************************************/
2472 scsi_low_data(struct scsi_low_softc *slp, struct targ_info *ti,
2473 struct buf **bp, int direction)
2475 struct slccb *cb = slp->sl_Qnexus;
2477 if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2479 *bp = cb->bp;
2480 return 0;
2483 slp->sl_error |= (FATALIO | PDMAERR);
2484 slp->sl_scp.scp_datalen = 0;
2485 slp->sl_scp.scp_direction = direction;
2486 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2487 if (ti->ti_ophase != ti->ti_phase)
2489 char *s;
2491 if (cb == NULL)
2492 s = "DATA PHASE: ccb nexus not found";
2493 else
2494 s = "DATA PHASE: xfer direction mismatch";
2495 SCSI_LOW_INFO(slp, ti, s);
2498 *bp = NULL;
2499 return EINVAL;
2502 /**************************************************************
2503 * MSG_SYS
2504 **************************************************************/
2505 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2506 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2507 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2508 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2509 #define MSGIN_DATA_LAST 0x30
2511 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2512 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2513 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2514 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2516 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2517 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2518 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2519 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2520 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2521 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2522 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2524 struct scsi_low_msgout_data {
2525 u_int md_flags;
2526 u_int8_t md_msg;
2527 int (*md_msgfunc) (struct scsi_low_softc *);
2528 int (*md_errfunc) (struct scsi_low_softc *, u_int);
2529 #define MSG_RELEASE_ATN 0x0001
2530 u_int md_condition;
2533 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2534 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2535 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2536 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2537 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2538 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2539 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2540 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2541 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG, MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2542 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2543 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG, MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2544 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL, MSG_RELEASE_ATN},
2545 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2546 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2547 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2548 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2549 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2552 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2553 static int scsi_low_synch (struct scsi_low_softc *);
2554 static int scsi_low_wide (struct scsi_low_softc *);
2555 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2556 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2557 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2558 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2559 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2560 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2561 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2562 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2563 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2564 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2565 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2567 struct scsi_low_msgin_data {
2568 u_int md_len;
2569 int (*md_msgfunc) (struct scsi_low_softc *);
2572 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2573 /* 0 */ {1, scsi_low_msginfunc_cc},
2574 /* 1 */ {2, scsi_low_msginfunc_ext},
2575 /* 2 */ {1, scsi_low_msginfunc_sdp},
2576 /* 3 */ {1, scsi_low_msginfunc_rp},
2577 /* 4 */ {1, scsi_low_msginfunc_disc},
2578 /* 5 */ {1, scsi_low_msginfunc_rejop},
2579 /* 6 */ {1, scsi_low_msginfunc_rejop},
2580 /* 7 */ {1, scsi_low_msginfunc_msg_reject},
2581 /* 8 */ {1, scsi_low_msginfunc_noop},
2582 /* 9 */ {1, scsi_low_msginfunc_parity},
2583 /* a */ {1, scsi_low_msginfunc_lcc},
2584 /* b */ {1, scsi_low_msginfunc_lcc},
2585 /* c */ {1, scsi_low_msginfunc_rejop},
2586 /* d */ {2, scsi_low_msginfunc_rejop},
2587 /* e */ {1, scsi_low_msginfunc_rejop},
2588 /* f */ {1, scsi_low_msginfunc_rejop},
2589 /* 0x10 */ {1, scsi_low_msginfunc_rejop},
2590 /* 0x11 */ {1, scsi_low_msginfunc_rejop},
2591 /* 0x12 */ {1, scsi_low_msginfunc_rejop},
2592 /* 0x13 */ {1, scsi_low_msginfunc_rejop},
2593 /* 0x14 */ {1, scsi_low_msginfunc_rejop},
2594 /* 0x15 */ {1, scsi_low_msginfunc_rejop},
2595 /* 0x16 */ {1, scsi_low_msginfunc_rejop},
2596 /* 0x17 */ {1, scsi_low_msginfunc_rejop},
2597 /* 0x18 */ {1, scsi_low_msginfunc_rejop},
2598 /* 0x19 */ {1, scsi_low_msginfunc_rejop},
2599 /* 0x1a */ {1, scsi_low_msginfunc_rejop},
2600 /* 0x1b */ {1, scsi_low_msginfunc_rejop},
2601 /* 0x1c */ {1, scsi_low_msginfunc_rejop},
2602 /* 0x1d */ {1, scsi_low_msginfunc_rejop},
2603 /* 0x1e */ {1, scsi_low_msginfunc_rejop},
2604 /* 0x1f */ {1, scsi_low_msginfunc_rejop},
2605 /* 0x20 */ {2, scsi_low_msginfunc_simple_qtag},
2606 /* 0x21 */ {2, scsi_low_msginfunc_rejop},
2607 /* 0x22 */ {2, scsi_low_msginfunc_rejop},
2608 /* 0x23 */ {2, scsi_low_msginfunc_i_wide_residue},
2609 /* 0x24 */ {2, scsi_low_msginfunc_rejop},
2610 /* 0x25 */ {2, scsi_low_msginfunc_rejop},
2611 /* 0x26 */ {2, scsi_low_msginfunc_rejop},
2612 /* 0x27 */ {2, scsi_low_msginfunc_rejop},
2613 /* 0x28 */ {2, scsi_low_msginfunc_rejop},
2614 /* 0x29 */ {2, scsi_low_msginfunc_rejop},
2615 /* 0x2a */ {2, scsi_low_msginfunc_rejop},
2616 /* 0x2b */ {2, scsi_low_msginfunc_rejop},
2617 /* 0x2c */ {2, scsi_low_msginfunc_rejop},
2618 /* 0x2d */ {2, scsi_low_msginfunc_rejop},
2619 /* 0x2e */ {2, scsi_low_msginfunc_rejop},
2620 /* 0x2f */ {2, scsi_low_msginfunc_rejop},
2621 /* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */
2624 /**************************************************************
2625 * msgout
2626 **************************************************************/
2627 static int
2628 scsi_low_msgfunc_synch(struct scsi_low_softc *slp)
2630 struct targ_info *ti = slp->sl_Tnexus;
2631 int ptr = ti->ti_msgoutlen;
2633 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2634 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2635 ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2636 ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2637 return MSG_EXTEND_SYNCHLEN + 2;
2640 static int
2641 scsi_low_msgfunc_wide(struct scsi_low_softc *slp)
2643 struct targ_info *ti = slp->sl_Tnexus;
2644 int ptr = ti->ti_msgoutlen;
2646 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2647 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2648 ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2649 return MSG_EXTEND_WIDELEN + 2;
2652 static int
2653 scsi_low_msgfunc_identify(struct scsi_low_softc *slp)
2655 struct targ_info *ti = slp->sl_Tnexus;
2656 struct lun_info *li = slp->sl_Lnexus;
2657 struct slccb *cb = slp->sl_Qnexus;
2658 int ptr = ti->ti_msgoutlen;
2659 u_int8_t msg;
2661 msg = MSG_IDENTIFY;
2662 if (cb == NULL)
2664 slp->sl_error |= FATALIO;
2665 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2666 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2668 else
2670 if (scsi_low_is_disconnect_ok(cb) != 0)
2671 msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2672 else
2673 msg |= li->li_lun;
2675 if (ti->ti_phase == PH_MSGOUT)
2677 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2678 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2680 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2684 ti->ti_msgoutstr[ptr + 0] = msg;
2685 return 1;
2688 static int
2689 scsi_low_msgfunc_abort(struct scsi_low_softc *slp)
2691 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2692 return 1;
2695 static int
2696 scsi_low_msgfunc_qabort(struct scsi_low_softc *slp)
2698 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2699 return 1;
2702 static int
2703 scsi_low_msgfunc_reset(struct scsi_low_softc *slp)
2705 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2706 return 1;
2709 static int
2710 scsi_low_msgfunc_qtag(struct scsi_low_softc *slp)
2712 struct targ_info *ti = slp->sl_Tnexus;
2713 struct slccb *cb = slp->sl_Qnexus;
2714 int ptr = ti->ti_msgoutlen;
2716 if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2718 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2719 return 1;
2721 else
2723 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2724 if (ti->ti_phase == PH_MSGOUT)
2726 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2729 return 2;
2733 * The following functions are called when targets give unexpected
2734 * responces in msgin (after msgout).
2736 static int
2737 scsi_low_errfunc_identify(struct scsi_low_softc *slp, u_int msgflags)
2739 if (slp->sl_Lnexus != NULL)
2741 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2742 scsi_low_calcf_lun(slp->sl_Lnexus);
2744 return 0;
2747 static int
2748 scsi_low_errfunc_synch(struct scsi_low_softc *slp, u_int msgflags)
2750 struct targ_info *ti = slp->sl_Tnexus;
2752 MSGIN_PERIOD(ti) = 0;
2753 MSGIN_OFFSET(ti) = 0;
2754 scsi_low_synch(slp);
2755 return 0;
2758 static int
2759 scsi_low_errfunc_wide(struct scsi_low_softc *slp, u_int msgflags)
2761 struct targ_info *ti = slp->sl_Tnexus;
2763 MSGIN_WIDTHP(ti) = 0;
2764 scsi_low_wide(slp);
2765 return 0;
2768 static int
2769 scsi_low_errfunc_qtag(struct scsi_low_softc *slp, u_int msgflags)
2771 if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2773 if (slp->sl_Qnexus != NULL)
2775 scsi_low_deactivate_qtag(slp->sl_Qnexus);
2777 if (slp->sl_Lnexus != NULL)
2779 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2780 scsi_low_calcf_lun(slp->sl_Lnexus);
2782 kprintf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2784 return 0;
2789 scsi_low_msgout(struct scsi_low_softc *slp, struct targ_info *ti, u_int fl)
2791 struct scsi_low_msgout_data *mdp;
2792 int len = 0;
2794 #ifdef SCSI_LOW_DIAGNOSTIC
2795 if (ti != slp->sl_Tnexus)
2797 scsi_low_print(slp, NULL);
2798 panic("scsi_low_msgout: Target nexus inconsistent");
2800 #endif /* SCSI_LOW_DIAGNOSTIC */
2802 slp->sl_ph_count ++;
2803 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2805 kprintf("%s: too many phase changes\n", slp->sl_xname);
2806 slp->sl_error |= FATALIO;
2807 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2810 /* STEP I.
2811 * Scsi phase changes.
2812 * Previously msgs asserted are accepted by our target or
2813 * processed by scsi_low_msgin.
2814 * Thus clear all saved informations.
2816 if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2818 ti->ti_omsgflags = 0;
2819 ti->ti_emsgflags = 0;
2821 else if (slp->sl_atten == 0)
2823 /* STEP II.
2824 * We did not assert attention, however still our target required
2825 * msgs. Resend previous msgs.
2827 ti->ti_msgflags |= ti->ti_omsgflags;
2828 ti->ti_omsgflags = 0;
2829 #ifdef SCSI_LOW_DIAGNOSTIC
2830 kprintf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
2831 #endif /* SCSI_LOW_DIAGNOSTIC */
2834 /* STEP III.
2835 * We have no msgs. send MSG_NOOP (OK?)
2837 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2838 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2840 /* STEP IV.
2841 * Process all msgs
2843 ti->ti_msgoutlen = 0;
2844 slp->sl_clear_atten = 0;
2845 mdp = &scsi_low_msgout_data[0];
2846 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2848 if ((ti->ti_msgflags & mdp->md_flags) != 0)
2850 ti->ti_omsgflags |= mdp->md_flags;
2851 ti->ti_msgflags &= ~mdp->md_flags;
2852 ti->ti_emsgflags = mdp->md_flags;
2854 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2855 if (mdp->md_msgfunc != NULL)
2856 len = (*mdp->md_msgfunc) (slp);
2857 else
2858 len = 1;
2860 #ifdef SCSI_LOW_DIAGNOSTIC
2861 scsi_low_msg_log_write(&ti->ti_log_msgout,
2862 &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2863 #endif /* SCSI_LOW_DIAGNOSTIC */
2865 ti->ti_msgoutlen += len;
2866 if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2868 slp->sl_clear_atten = 1;
2869 break;
2872 if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2873 ti->ti_msgflags == 0)
2874 break;
2876 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2877 break;
2881 if (scsi_low_is_msgout_continue(ti, 0) == 0)
2882 slp->sl_clear_atten = 1;
2884 return ti->ti_msgoutlen;
2887 /**************************************************************
2888 * msgin
2889 **************************************************************/
2890 static int
2891 scsi_low_msginfunc_noop(struct scsi_low_softc *slp)
2893 return 0;
2896 static int
2897 scsi_low_msginfunc_rejop(struct scsi_low_softc *slp)
2899 struct targ_info *ti = slp->sl_Tnexus;
2900 u_int8_t msg = ti->ti_msgin[0];
2902 kprintf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
2903 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2904 return 0;
2907 static int
2908 scsi_low_msginfunc_cc(struct scsi_low_softc *slp)
2910 struct lun_info *li;
2912 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2914 /* validate status */
2915 if (slp->sl_Qnexus == NULL)
2916 return ENOENT;
2918 slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2919 li = slp->sl_Lnexus;
2920 switch (slp->sl_scp.scp_status)
2922 case ST_GOOD:
2923 li->li_maxnqio = li->li_maxnexus;
2924 break;
2926 case ST_CHKCOND:
2927 li->li_maxnqio = 0;
2928 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
2929 scsi_low_reset_nexus_lun(slp, li, 0);
2930 break;
2932 case ST_BUSY:
2933 li->li_maxnqio = 0;
2934 break;
2936 case ST_QUEFULL:
2937 if (li->li_maxnexus >= li->li_nqio)
2938 li->li_maxnexus = li->li_nqio - 1;
2939 li->li_maxnqio = li->li_maxnexus;
2940 break;
2942 case ST_INTERGOOD:
2943 case ST_INTERMET:
2944 slp->sl_error |= MSGERR;
2945 break;
2947 default:
2948 break;
2950 return 0;
2953 static int
2954 scsi_low_msginfunc_lcc(struct scsi_low_softc *slp)
2956 struct targ_info *ti;
2957 struct lun_info *li;
2958 struct slccb *ncb, *cb;
2960 ti = slp->sl_Tnexus;
2961 li = slp->sl_Lnexus;
2962 if ((cb = slp->sl_Qnexus) == NULL)
2963 goto bad;
2965 cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2966 switch (slp->sl_scp.scp_status)
2968 case ST_INTERGOOD:
2969 case ST_INTERMET:
2970 li->li_maxnqio = li->li_maxnexus;
2971 break;
2973 default:
2974 slp->sl_error |= MSGERR;
2975 break;
2978 if ((li->li_flags & SCSI_LOW_LINK) == 0)
2979 goto bad;
2981 cb->ccb_error |= slp->sl_error;
2982 if (cb->ccb_error != 0)
2983 goto bad;
2985 TAILQ_FOREACH(ncb, &slp->sl_start, ccb_chain)
2987 if (ncb->li == li)
2988 goto cmd_link_start;
2992 bad:
2993 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
2994 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2995 return EIO;
2997 cmd_link_start:
2998 ncb->ccb_flags &= ~CCB_STARTQ;
2999 TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3001 scsi_low_dealloc_qtag(ncb);
3002 ncb->ccb_tag = cb->ccb_tag;
3003 ncb->ccb_otag = cb->ccb_otag;
3004 cb->ccb_tag = SCSI_LOW_UNKTAG;
3005 cb->ccb_otag = SCSI_LOW_UNKTAG;
3006 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3007 panic("%s: linked ccb retried", slp->sl_xname);
3009 slp->sl_Qnexus = ncb;
3010 slp->sl_ph_count = 0;
3012 ncb->ccb_error = 0;
3013 ncb->ccb_datalen = -1;
3014 ncb->ccb_scp.scp_status = ST_UNKNOWN;
3015 ncb->ccb_flags &= ~CCB_INTERNAL;
3017 scsi_low_init_msgsys(slp, ti);
3019 (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3021 if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3022 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3023 ncb->ccb_tc = ncb->ccb_tcmax;
3025 /* setup saved scsi data pointer */
3026 ncb->ccb_sscp = ncb->ccb_scp;
3027 slp->sl_scp = ncb->ccb_sscp;
3028 slp->sl_error = ncb->ccb_error;
3030 #ifdef SCSI_LOW_DIAGNOSTIC
3031 scsi_low_msg_log_init(&ti->ti_log_msgin);
3032 scsi_low_msg_log_init(&ti->ti_log_msgout);
3033 #endif /* SCSI_LOW_DIAGNOSTIC */
3034 return EJUSTRETURN;
3037 static int
3038 scsi_low_msginfunc_disc(struct scsi_low_softc *slp)
3040 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3041 return 0;
3044 static int
3045 scsi_low_msginfunc_sdp(struct scsi_low_softc *slp)
3047 struct slccb *cb = slp->sl_Qnexus;
3049 if (cb != NULL)
3051 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3052 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3054 else
3055 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3056 return 0;
3059 static int
3060 scsi_low_msginfunc_rp(struct scsi_low_softc *slp)
3062 if (slp->sl_Qnexus != NULL)
3063 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3064 else
3065 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3066 return 0;
3069 static int
3070 scsi_low_synch(struct scsi_low_softc *slp)
3072 struct targ_info *ti = slp->sl_Tnexus;
3073 u_int period = 0, offset = 0, speed;
3074 u_char *s;
3075 int error;
3077 if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3078 MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3079 MSGIN_OFFSET(ti) == 0)
3081 if ((offset = MSGIN_OFFSET(ti)) != 0)
3082 period = MSGIN_PERIOD(ti);
3083 s = offset ? "synchronous" : "async";
3085 else
3087 /* XXX:
3088 * Target seems to be brain damaged.
3089 * Force async transfer.
3091 ti->ti_maxsynch.period = 0;
3092 ti->ti_maxsynch.offset = 0;
3093 kprintf("%s: target brain damaged. async transfer\n",
3094 slp->sl_xname);
3095 return EINVAL;
3098 ti->ti_maxsynch.period = period;
3099 ti->ti_maxsynch.offset = offset;
3101 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3102 if (error != 0)
3104 /* XXX:
3105 * Current period and offset are not acceptable
3106 * for our adapter.
3107 * The adapter changes max synch and max offset.
3109 kprintf("%s: synch neg failed. retry synch msg neg ...\n",
3110 slp->sl_xname);
3111 return error;
3114 ti->ti_osynch = ti->ti_maxsynch;
3115 if (offset > 0)
3117 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3120 /* inform data */
3121 if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3123 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3124 struct slccb *cb = slp->sl_Qnexus;
3126 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3127 return 0;
3128 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3130 kprintf("%s(%d:*): <%s> offset %d period %dns ",
3131 slp->sl_xname, ti->ti_id, s, offset, period * 4);
3133 if (period != 0)
3135 speed = 1000 * 10 / (period * 4);
3136 kprintf("%d.%d M/s", speed / 10, speed % 10);
3138 kprintf("\n");
3140 return 0;
3143 static int
3144 scsi_low_wide(struct scsi_low_softc *slp)
3146 struct targ_info *ti = slp->sl_Tnexus;
3147 int error;
3149 ti->ti_width = MSGIN_WIDTHP(ti);
3150 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3151 if (error != 0)
3153 /* XXX:
3154 * Current width is not acceptable for our adapter.
3155 * The adapter changes max width.
3157 kprintf("%s: wide neg failed. retry wide msg neg ...\n",
3158 slp->sl_xname);
3159 return error;
3162 ti->ti_owidth = ti->ti_width;
3163 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3165 ti->ti_setup_msg_done |=
3166 (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3169 /* inform data */
3170 if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3172 #ifdef SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3173 struct slccb *cb = slp->sl_Qnexus;
3175 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3176 return 0;
3177 #endif /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3179 kprintf("%s(%d:*): transfer width %d bits\n",
3180 slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3182 return 0;
3185 static int
3186 scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *slp)
3188 struct targ_info *ti = slp->sl_Tnexus;
3189 scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3191 if (slp->sl_Qnexus != NULL)
3193 if (slp->sl_Qnexus->ccb_tag != etag)
3195 slp->sl_error |= FATALIO;
3196 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3197 SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3200 else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3202 #ifdef SCSI_LOW_DEBUG
3203 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3204 return 0;
3205 #endif /* SCSI_LOW_DEBUG */
3207 slp->sl_error |= FATALIO;
3208 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3209 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3211 return 0;
3214 static int
3215 scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *slp)
3217 struct targ_info *ti = slp->sl_Tnexus;
3218 struct slccb *cb = slp->sl_Qnexus;
3219 int res = (int) ti->ti_msgin[1];
3221 if (cb == NULL || res <= 0 ||
3222 (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3223 (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3224 return EINVAL;
3226 if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3227 return EINVAL;
3229 slp->sl_scp.scp_datalen += res;
3230 slp->sl_scp.scp_data -= res;
3231 scsi_low_data_finish(slp);
3232 return 0;
3235 static int
3236 scsi_low_msginfunc_ext(struct scsi_low_softc *slp)
3238 struct slccb *cb = slp->sl_Qnexus;
3239 struct lun_info *li = slp->sl_Lnexus;
3240 struct targ_info *ti = slp->sl_Tnexus;
3241 int count, retry;
3242 u_int32_t *ptr;
3244 if (ti->ti_msginptr == 2)
3246 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3247 return 0;
3250 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3252 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3253 if (cb == NULL)
3254 break;
3256 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3257 count = (int) htonl((long) (*ptr));
3258 if(slp->sl_scp.scp_datalen - count < 0 ||
3259 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3260 break;
3262 slp->sl_scp.scp_datalen -= count;
3263 slp->sl_scp.scp_data += count;
3264 return 0;
3266 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3267 if (li == NULL)
3268 break;
3270 retry = scsi_low_synch(slp);
3271 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3272 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3274 #ifdef SCSI_LOW_DEBUG
3275 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3277 scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3279 #endif /* SCSI_LOW_DEBUG */
3280 return 0;
3282 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3283 if (li == NULL)
3284 break;
3286 retry = scsi_low_wide(slp);
3287 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3288 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3290 return 0;
3292 default:
3293 break;
3296 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3297 return EINVAL;
3300 static int
3301 scsi_low_msginfunc_parity(struct scsi_low_softc *slp)
3303 struct targ_info *ti = slp->sl_Tnexus;
3305 /* only I -> T, invalid! */
3306 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3307 return 0;
3310 static int
3311 scsi_low_msginfunc_msg_reject(struct scsi_low_softc *slp)
3313 struct targ_info *ti = slp->sl_Tnexus;
3314 struct scsi_low_msgout_data *mdp;
3315 u_int msgflags;
3317 if (ti->ti_emsgflags != 0)
3319 kprintf("%s: msg flags [0x%x] rejected\n",
3320 slp->sl_xname, ti->ti_emsgflags);
3321 msgflags = SCSI_LOW_MSG_REJECT;
3322 mdp = &scsi_low_msgout_data[0];
3323 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3325 if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3327 ti->ti_emsgflags &= ~mdp->md_flags;
3328 if (mdp->md_errfunc != NULL)
3329 (*mdp->md_errfunc) (slp, msgflags);
3330 break;
3333 return 0;
3335 else
3337 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3338 slp->sl_error |= MSGERR;
3340 return EINVAL;
3344 scsi_low_msgin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c)
3346 struct scsi_low_msgin_data *sdp;
3347 struct lun_info *li;
3348 u_int8_t msg;
3350 #ifdef SCSI_LOW_DIAGNOSTIC
3351 if (ti != slp->sl_Tnexus)
3353 scsi_low_print(slp, NULL);
3354 panic("scsi_low_msgin: Target nexus inconsistent");
3356 #endif /* SCSI_LOW_DIAGNOSTIC */
3359 * Phase changes, clear the pointer.
3361 if (ti->ti_ophase != ti->ti_phase)
3363 MSGINPTR_CLR(ti);
3364 ti->ti_msgin_parity_error = 0;
3366 slp->sl_ph_count ++;
3367 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3369 kprintf("%s: too many phase changes\n", slp->sl_xname);
3370 slp->sl_error |= FATALIO;
3371 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3376 * Store a current messages byte into buffer and
3377 * wait for the completion of the current msg.
3379 ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3380 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3382 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3383 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3387 * Check parity errors.
3389 if ((c & SCSI_LOW_DATA_PE) != 0)
3391 ti->ti_msgin_parity_error ++;
3392 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3393 goto out;
3396 if (ti->ti_msgin_parity_error != 0)
3397 goto out;
3400 * Calculate messages length.
3402 msg = ti->ti_msgin[0];
3403 if (msg < MSGIN_DATA_LAST)
3404 sdp = &scsi_low_msgin_data[msg];
3405 else
3406 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3408 if (ti->ti_msginlen == 0)
3410 ti->ti_msginlen = sdp->md_len;
3414 * Check comletion.
3416 if (ti->ti_msginptr < ti->ti_msginlen)
3417 return EJUSTRETURN;
3420 * Do process.
3422 if ((msg & MSG_IDENTIFY) == 0)
3424 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3425 return EJUSTRETURN;
3427 else
3429 li = slp->sl_Lnexus;
3430 if (li == NULL)
3432 li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3433 if (li == NULL)
3434 goto badlun;
3435 slp->sl_Lnexus = li;
3436 (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3438 else
3440 if (MSGCMD_LUN(msg) != li->li_lun)
3441 goto badlun;
3444 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3446 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3448 #ifdef SCSI_LOW_DEBUG
3449 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3451 goto out;
3453 #endif /* SCSI_LOW_DEBUG */
3454 goto badlun;
3458 goto out;
3461 * Msg process completed, reset msgin pointer and assert ATN if desired.
3463 badlun:
3464 slp->sl_error |= FATALIO;
3465 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3466 SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3468 out:
3469 if (ti->ti_msginptr < ti->ti_msginlen)
3470 return EJUSTRETURN;
3472 #ifdef SCSI_LOW_DIAGNOSTIC
3473 scsi_low_msg_log_write(&ti->ti_log_msgin,
3474 &ti->ti_msgin[0], ti->ti_msginlen);
3475 #endif /* SCSI_LOW_DIAGNOSTIC */
3477 MSGINPTR_CLR(ti);
3478 return 0;
3481 /**********************************************************
3482 * disconnect
3483 **********************************************************/
3485 scsi_low_disconnected(struct scsi_low_softc *slp, struct targ_info *ti)
3487 struct slccb *cb = slp->sl_Qnexus;
3489 /* check phase completion */
3490 switch (slp->sl_msgphase)
3492 case MSGPH_RESET:
3493 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3494 scsi_low_msginfunc_cc(slp);
3495 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3496 goto io_resume;
3498 case MSGPH_ABORT:
3499 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3500 scsi_low_msginfunc_cc(slp);
3501 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3502 goto io_resume;
3504 case MSGPH_TERM:
3505 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3506 scsi_low_msginfunc_cc(slp);
3507 goto io_resume;
3509 case MSGPH_DISC:
3510 if (cb != NULL)
3512 struct lun_info *li;
3514 li = cb->li;
3515 TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3516 cb->ccb_flags |= CCB_DISCQ;
3517 cb->ccb_error |= slp->sl_error;
3518 li->li_disc ++;
3519 ti->ti_disc ++;
3520 slp->sl_disc ++;
3523 #ifdef SCSI_LOW_STATICS
3524 scsi_low_statics.nexus_disconnected ++;
3525 #endif /* SCSI_LOW_STATICS */
3527 #ifdef SCSI_LOW_DEBUG
3528 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3530 kprintf("## SCSI_LOW_DISCONNECTED ===============\n");
3531 scsi_low_print(slp, NULL);
3533 #endif /* SCSI_LOW_DEBUG */
3534 break;
3536 case MSGPH_NULL:
3537 slp->sl_error |= FATALIO;
3538 if (ti->ti_phase == PH_SELSTART)
3539 slp->sl_error |= SELTIMEOUTIO;
3540 else
3541 slp->sl_error |= UBFERR;
3542 /* fall through */
3544 case MSGPH_LCTERM:
3545 case MSGPH_CMDC:
3546 io_resume:
3547 if (cb == NULL)
3548 break;
3550 #ifdef SCSI_LOW_DEBUG
3551 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3553 if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3554 (cb->ccb_msgoutflag != 0 ||
3555 (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3557 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3560 #endif /* SCSI_LOW_DEBUG */
3562 cb->ccb_error |= slp->sl_error;
3563 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3565 cb->ccb_flags |= CCB_STARTQ;
3566 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3568 break;
3571 scsi_low_bus_release(slp, ti);
3572 scsi_low_start(slp);
3573 return 1;
3576 /**********************************************************
3577 * TAG operations
3578 **********************************************************/
3579 static int
3580 scsi_low_alloc_qtag(struct slccb *cb)
3582 struct lun_info *li = cb->li;
3583 scsi_low_tag_t etag;
3585 if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3586 return 0;
3588 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3589 etag = ffs(li->li_qtagbits);
3590 if (etag == 0)
3591 return ENOSPC;
3593 li->li_qtagbits &= ~(1 << (etag - 1));
3594 cb->ccb_otag = etag;
3595 return 0;
3597 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3598 for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3599 if (li->li_qtagarray[li->li_qd] == 0)
3600 goto found;
3602 for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3603 if (li->li_qtagarray[li->li_qd] == 0)
3604 goto found;
3606 return ENOSPC;
3608 found:
3609 li->li_qtagarray[li->li_qd] ++;
3610 cb->ccb_otag = (li->li_qd ++);
3611 return 0;
3612 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3615 static int
3616 scsi_low_dealloc_qtag(struct slccb *cb)
3618 struct lun_info *li = cb->li;
3619 scsi_low_tag_t etag;
3621 if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3622 return 0;
3624 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3625 etag = cb->ccb_otag - 1;
3626 #ifdef SCSI_LOW_DIAGNOSTIC
3627 if (etag >= sizeof(li->li_qtagbits) * NBBY)
3628 panic("scsi_low_dealloc_tag: illegal tag");
3629 #endif /* SCSI_LOW_DIAGNOSTIC */
3630 li->li_qtagbits |= (1 << etag);
3632 #else /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3633 etag = cb->ccb_otag;
3634 #ifdef SCSI_LOW_DIAGNOSTIC
3635 if (etag >= SCSI_LOW_MAXNEXUS)
3636 panic("scsi_low_dealloc_tag: illegal tag");
3637 #endif /* SCSI_LOW_DIAGNOSTIC */
3638 li->li_qtagarray[etag] --;
3639 #endif /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3641 cb->ccb_otag = SCSI_LOW_UNKTAG;
3642 return 0;
3645 static struct slccb *
3646 scsi_low_revoke_ccb(struct scsi_low_softc *slp, struct slccb *cb, int fdone)
3648 struct targ_info *ti = cb->ti;
3649 struct lun_info *li = cb->li;
3651 #ifdef SCSI_LOW_DIAGNOSTIC
3652 if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) ==
3653 (CCB_STARTQ | CCB_DISCQ))
3655 panic("%s: ccb in both queue", slp->sl_xname);
3657 #endif /* SCSI_LOW_DIAGNOSTIC */
3659 if ((cb->ccb_flags & CCB_STARTQ) != 0)
3661 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3664 if ((cb->ccb_flags & CCB_DISCQ) != 0)
3666 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3667 li->li_disc --;
3668 ti->ti_disc --;
3669 slp->sl_disc --;
3672 cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ |
3673 CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3675 if (fdone != 0 &&
3676 (cb->ccb_rcnt ++ >= slp->sl_max_retry ||
3677 (cb->ccb_flags & CCB_NORETRY) != 0))
3679 cb->ccb_error |= FATALIO;
3680 cb->ccb_flags &= ~CCB_AUTOSENSE;
3681 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3682 panic("%s: done ccb retried", slp->sl_xname);
3683 return NULL;
3685 else
3687 cb->ccb_error |= PENDINGIO;
3688 scsi_low_deactivate_qtag(cb);
3689 scsi_low_ccb_message_retry(cb);
3690 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3691 return cb;
3695 static void
3696 scsi_low_reset_nexus_lun(struct scsi_low_softc *slp, struct lun_info *li, int fdone)
3698 struct slccb *cb, *ncb, *ecb;
3700 if (li == NULL)
3701 return;
3703 ecb = NULL;
3704 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3706 ncb = TAILQ_NEXT(cb, ccb_chain);
3707 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3708 if (cb != NULL)
3711 * presumely keep ordering of io
3713 cb->ccb_flags |= CCB_STARTQ;
3714 if (ecb == NULL)
3716 TAILQ_INSERT_HEAD(&slp->sl_start,\
3717 cb, ccb_chain);
3719 else
3721 TAILQ_INSERT_AFTER(&slp->sl_start,\
3722 ecb, cb, ccb_chain);
3724 ecb = cb;
3729 /**************************************************************
3730 * Qurik setup
3731 **************************************************************/
3732 static void
3733 scsi_low_calcf_lun(struct lun_info *li)
3735 struct targ_info *ti = li->li_ti;
3736 struct scsi_low_softc *slp = ti->ti_sc;
3737 u_int cfgflags, diskflags;
3739 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3740 cfgflags = li->li_cfgflags;
3741 else
3742 cfgflags = 0;
3744 diskflags = li->li_diskflags & li->li_quirks;
3746 /* disconnect */
3747 li->li_flags &= ~SCSI_LOW_DISC;
3748 if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3749 (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3750 (cfgflags & SCSI_LOW_DISC) != 0)
3751 li->li_flags |= SCSI_LOW_DISC;
3753 /* parity */
3754 li->li_flags |= SCSI_LOW_NOPARITY;
3755 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3756 (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3757 (cfgflags & SCSI_LOW_NOPARITY) == 0)
3758 li->li_flags &= ~SCSI_LOW_NOPARITY;
3760 /* qtag */
3761 if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3762 (cfgflags & SCSI_LOW_QTAG) != 0 &&
3763 (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3765 li->li_flags |= SCSI_LOW_QTAG;
3766 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3767 li->li_maxnqio = li->li_maxnexus;
3769 else
3771 li->li_flags &= ~SCSI_LOW_QTAG;
3772 li->li_maxnexus = 0;
3773 li->li_maxnqio = li->li_maxnexus;
3776 /* cmd link */
3777 li->li_flags &= ~SCSI_LOW_LINK;
3778 if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3779 (diskflags & SCSI_LOW_DISK_LINK) != 0)
3780 li->li_flags |= SCSI_LOW_LINK;
3782 /* compatible flags */
3783 li->li_flags &= ~SCSI_LOW_SYNC;
3784 if (ti->ti_maxsynch.offset > 0)
3785 li->li_flags |= SCSI_LOW_SYNC;
3787 #ifdef SCSI_LOW_DEBUG
3788 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3790 scsi_low_calcf_show(li);
3792 #endif /* SCSI_LOW_DEBUG */
3795 static void
3796 scsi_low_calcf_target(struct targ_info *ti)
3798 struct scsi_low_softc *slp = ti->ti_sc;
3799 u_int offset, period, diskflags;
3801 diskflags = ti->ti_diskflags & ti->ti_quirks;
3803 /* synch */
3804 if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
3805 (diskflags & SCSI_LOW_DISK_SYNC) != 0)
3807 offset = ti->ti_maxsynch.offset;
3808 period = ti->ti_maxsynch.period;
3809 if (offset == 0 || period == 0)
3810 offset = period = 0;
3812 else
3814 offset = period = 0;
3817 ti->ti_maxsynch.offset = offset;
3818 ti->ti_maxsynch.period = period;
3820 /* wide */
3821 if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
3822 ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
3823 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
3825 if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
3826 ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3827 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
3829 if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
3831 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
3832 ti->ti_maxsynch.period != ti->ti_osynch.period)
3833 ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
3834 if (ti->ti_width != ti->ti_owidth)
3835 ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
3837 ti->ti_osynch = ti->ti_maxsynch;
3838 ti->ti_owidth = ti->ti_width;
3841 #ifdef SCSI_LOW_DEBUG
3842 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3844 kprintf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
3845 slp->sl_xname, ti->ti_id,
3846 ti->ti_maxsynch.period * 4,
3847 ti->ti_maxsynch.offset,
3848 ti->ti_width);
3850 #endif /* SCSI_LOW_DEBUG */
3853 static void
3854 scsi_low_calcf_show(struct lun_info *li)
3856 struct targ_info *ti = li->li_ti;
3857 struct scsi_low_softc *slp = ti->ti_sc;
3859 kprintf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
3860 slp->sl_xname, ti->ti_id, li->li_lun,
3861 ti->ti_maxsynch.period * 4,
3862 ti->ti_maxsynch.offset,
3863 ti->ti_width,
3864 li->li_flags, SCSI_LOW_BITS);
3867 #ifdef SCSI_LOW_START_UP_CHECK
3868 /**************************************************************
3869 * scsi world start up
3870 **************************************************************/
3871 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
3873 static int
3874 scsi_low_start_up(struct scsi_low_softc *slp)
3876 struct targ_info *ti;
3877 struct lun_info *li;
3878 struct slccb *cb;
3879 int target, lun;
3881 kprintf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
3883 for (target = 0; target < slp->sl_ntargs; target ++)
3885 if (target == slp->sl_hostid)
3887 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3889 kprintf("%s: scsi_low: target %d (host card)\n",
3890 slp->sl_xname, target);
3892 continue;
3895 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3897 kprintf("%s: scsi_low: target %d lun ",
3898 slp->sl_xname, target);
3901 ti = slp->sl_ti[target];
3902 for (lun = 0; lun < slp->sl_nluns; lun ++)
3904 if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
3905 break;
3907 cb->osdep = NULL;
3908 cb->bp = NULL;
3910 li = scsi_low_alloc_li(ti, lun, 1);
3912 scsi_low_enqueue(slp, ti, li, cb,
3913 CCB_AUTOSENSE | CCB_POLLED, 0);
3915 scsi_low_poll(slp, cb);
3917 if (li->li_state != SCSI_LOW_LUN_OK)
3918 break;
3920 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3922 kprintf("%d ", lun);
3926 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3928 kprintf("\n");
3931 return 0;
3934 static int
3935 scsi_low_poll(struct scsi_low_softc *slp, struct slccb *cb)
3937 int tcount;
3939 tcount = 0;
3940 while (slp->sl_nio > 0)
3942 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
3944 (*slp->sl_funcs->scsi_low_poll) (slp);
3945 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
3946 continue;
3948 tcount = 0;
3949 scsi_low_timeout_check(slp);
3952 return 0;
3954 #endif /* SCSI_LOW_START_UP_CHECK */
3956 /**********************************************************
3957 * DEBUG SECTION
3958 **********************************************************/
3959 #ifdef SCSI_LOW_DEBUG
3960 static void
3961 scsi_low_test_abort(struct scsi_low_softc *slp, struct targ_info *ti,
3962 struct lun_info *li)
3964 struct slccb *acb;
3966 if (li->li_disc > 1)
3968 acb = TAILQ_FIRST(&li->li_discq);
3969 if (scsi_low_abort_ccb(slp, acb) == 0)
3971 kprintf("%s: aborting ccb(0x%lx) start\n",
3972 slp->sl_xname, (u_long) acb);
3977 static void
3978 scsi_low_test_atten(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg)
3980 if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
3981 scsi_low_assert_msg(slp, ti, msg, 0);
3982 else
3983 kprintf("%s: atten check OK\n", slp->sl_xname);
3986 static void
3987 scsi_low_test_cmdlnk(struct scsi_low_softc *slp, struct slccb *cb)
3989 #define SCSI_LOW_CMDLNK_NOK (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
3991 if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
3992 return;
3994 memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
3995 slp->sl_scp.scp_cmdlen);
3996 cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
3997 slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
3999 #endif /* SCSI_LOW_DEBUG */
4001 /* static */ void
4002 scsi_low_info(struct scsi_low_softc *slp, struct targ_info *ti, u_char *s)
4004 if (slp == NULL)
4005 slp = LIST_FIRST(&sl_tab);
4006 if (s == NULL)
4007 s = "no message";
4009 kprintf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4010 if (ti == NULL)
4012 TAILQ_FOREACH(ti, &slp->sl_titab, ti_chain)
4014 scsi_low_print(slp, ti);
4017 else
4019 scsi_low_print(slp, ti);
4023 static u_char *phase[] =
4025 "FREE", "ARBSTART", "SELSTART", "SELECTED",
4026 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL"
4029 void
4030 scsi_low_print(struct scsi_low_softc *slp, struct targ_info *ti)
4032 struct lun_info *li;
4033 struct slccb *cb;
4034 struct sc_p *sp;
4036 if (ti == NULL || ti == slp->sl_Tnexus)
4038 ti = slp->sl_Tnexus;
4039 li = slp->sl_Lnexus;
4040 cb = slp->sl_Qnexus;
4042 else
4044 li = LIST_FIRST(&ti->ti_litab);
4045 cb = TAILQ_FIRST(&li->li_discq);
4047 sp = &slp->sl_scp;
4049 kprintf("%s: === NEXUS T(0x%lx) L(0x%lx) Q(0x%lx) NIO(%d) ===\n",
4050 slp->sl_xname, (u_long) ti, (u_long) li, (u_long) cb,
4051 slp->sl_nio);
4053 /* target stat */
4054 if (ti != NULL)
4056 u_int flags = 0, maxnqio = 0, nqio = 0;
4057 int lun = -1;
4059 if (li != NULL)
4061 lun = li->li_lun;
4062 flags = li->li_flags;
4063 maxnqio = li->li_maxnqio;
4064 nqio = li->li_nqio;
4067 kprintf("%s(%d:%d) ph<%s> => ph<%s> DISC(%d) QIO(%d:%d)\n",
4068 slp->sl_xname,
4069 ti->ti_id, lun, phase[(int) ti->ti_ophase],
4070 phase[(int) ti->ti_phase], ti->ti_disc,
4071 nqio, maxnqio);
4073 if (cb != NULL)
4075 kprintf("CCB: cmd[0] 0x%x clen 0x%x dlen 0x%x<0x%x stat 0x%x err %b\n",
4076 (u_int) cb->ccb_scp.scp_cmd[0],
4077 cb->ccb_scp.scp_cmdlen,
4078 cb->ccb_datalen,
4079 cb->ccb_scp.scp_datalen,
4080 (u_int) cb->ccb_sscp.scp_status,
4081 cb->ccb_error, SCSI_LOW_ERRORBITS);
4084 kprintf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] attention: %d\n",
4085 (u_int) (ti->ti_msginptr),
4086 (u_int) (ti->ti_msgin[0]),
4087 (u_int) (ti->ti_msgin[1]),
4088 (u_int) (ti->ti_msgin[2]),
4089 (u_int) (ti->ti_msgin[3]),
4090 (u_int) (ti->ti_msgin[4]),
4091 slp->sl_atten);
4093 kprintf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n",
4094 (u_int) ti->ti_msgflags,
4095 (u_int) (ti->ti_msgoutstr[0]),
4096 (u_int) (ti->ti_msgoutstr[1]),
4097 (u_int) (ti->ti_msgoutstr[2]),
4098 (u_int) (ti->ti_msgoutstr[3]),
4099 (u_int) (ti->ti_msgoutstr[4]),
4100 ti->ti_msgoutlen,
4101 flags, SCSI_LOW_BITS);
4103 #ifdef SCSI_LOW_DIAGNOSTIC
4104 scsi_low_msg_log_show(&ti->ti_log_msgin, "MIN LOG ", 2);
4105 scsi_low_msg_log_show(&ti->ti_log_msgout, "MOUT LOG", 2);
4106 #endif /* SCSI_LOW_DIAGNOSTIC */
4110 kprintf("SCB: daddr 0x%lx dlen 0x%x stat 0x%x err %b\n",
4111 (u_long) sp->scp_data,
4112 sp->scp_datalen,
4113 (u_int) sp->scp_status,
4114 slp->sl_error, SCSI_LOW_ERRORBITS);