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