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