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: src/sys/cam/scsi/scsi_low.c,v 1.29 2007/06/17 05:55:54 scottl Exp $");
6
7 #define SCSI_LOW_STATICS
8 #define SCSI_LOW_DEBUG
9 #define SCSI_LOW_NEGOTIATE_BEFORE_SENSE
10 #define SCSI_LOW_START_UP_CHECK
11
12 /* #define SCSI_LOW_INFO_DETAIL */
13
14 /* #define SCSI_LOW_QCLEAR_AFTER_CA */
15 /* #define SCSI_LOW_FLAGS_QUIRKS_OK */
16
17 #ifdef __NetBSD__
18 #define SCSI_LOW_TARGET_OPEN
19 #endif /* __NetBSD__ */
20
21 #ifdef __FreeBSD__
22 #define SCSI_LOW_FLAGS_QUIRKS_OK
23 #endif /* __FreeBSD__ */
24
25 /*-
26 * [NetBSD for NEC PC-98 series]
27 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
28 * NetBSD/pc98 porting staff. All rights reserved.
29 * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001
30 * Naofumi HONDA. All rights reserved.
31 *
32 * [Ported for FreeBSD CAM]
33 * Copyright (c) 2000, 2001
34 * MITSUNAGA Noriaki, NOKUBI Hirotaka and TAKAHASHI Yoshihiro.
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. The name of the author may not be used to endorse or promote products
46 * derived from this software without specific prior written permission.
47 *
48 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
49 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
57 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 * POSSIBILITY OF SUCH DAMAGE.
59 */
60
61 /* <On the nexus establishment>
62 * When our host is reselected,
63 * nexus establish processes are little complicated.
64 * Normal steps are followings:
65 * 1) Our host selected by target => target nexus (slp->sl_Tnexus)
66 * 2) Identify msgin => lun nexus (slp->sl_Lnexus)
67 * 3) Qtag msg => ccb nexus (slp->sl_Qnexus)
68 */
69 #include "opt_ddb.h"
70
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
74
75 #ifdef __FreeBSD__
76 #if __FreeBSD_version >= 500001
77 #include <sys/bio.h>
78 #else
79 #include <machine/clock.h>
80 #endif
81 #endif /* __FreeBSD__ */
82
83 #include <sys/buf.h>
84 #include <sys/queue.h>
85 #include <sys/malloc.h>
86 #include <sys/errno.h>
87
88 #ifdef __NetBSD__
89 #include <sys/device.h>
90 #include <vm/vm.h>
91
92 #include <machine/bus.h>
93 #include <machine/intr.h>
94 #include <machine/dvcfg.h>
95
96 #include <dev/cons.h>
97
98 #include <dev/scsipi/scsipi_all.h>
99 #include <dev/scsipi/scsipiconf.h>
100 #include <dev/scsipi/scsipi_disk.h>
101 #include <dev/scsipi/scsi_all.h>
102 #include <dev/scsipi/scsiconf.h>
103 #include <sys/scsiio.h>
104
105 #include <i386/Cbus/dev/scsi_low.h>
106 #endif /* __NetBSD__ */
107
108 #ifdef __FreeBSD__
109 #include <cam/cam.h>
110 #include <cam/cam_ccb.h>
111 #include <cam/cam_sim.h>
112 #include <cam/cam_debug.h>
113 #include <cam/cam_periph.h>
114 #include <cam/cam_xpt_periph.h>
115
116 #include <cam/scsi/scsi_all.h>
117 #include <cam/scsi/scsi_message.h>
118
119 #include <cam/scsi/scsi_low.h>
120
121 #include <sys/cons.h>
122 #endif /* __FreeBSD__ */
123
124 /**************************************************************
125 * Constants
126 **************************************************************/
127 #define SCSI_LOW_POLL_HZ 1000
128
129 /* functions return values */
130 #define SCSI_LOW_START_NO_QTAG 0
131 #define SCSI_LOW_START_QTAG 1
132
133 #define SCSI_LOW_DONE_COMPLETE 0
134 #define SCSI_LOW_DONE_RETRY 1
135
136 /* internal disk flags */
137 #define SCSI_LOW_DISK_DISC 0x00000001
138 #define SCSI_LOW_DISK_QTAG 0x00000002
139 #define SCSI_LOW_DISK_LINK 0x00000004
140 #define SCSI_LOW_DISK_PARITY 0x00000008
141 #define SCSI_LOW_DISK_SYNC 0x00010000
142 #define SCSI_LOW_DISK_WIDE_16 0x00020000
143 #define SCSI_LOW_DISK_WIDE_32 0x00040000
144 #define SCSI_LOW_DISK_WIDE (SCSI_LOW_DISK_WIDE_16 | SCSI_LOW_DISK_WIDE_32)
145 #define SCSI_LOW_DISK_LFLAGS 0x0000ffff
146 #define SCSI_LOW_DISK_TFLAGS 0xffff0000
147
148 MALLOC_DEFINE(M_SCSILOW, "SCSI low", "SCSI low buffers");
149
150 /**************************************************************
151 * Declarations
152 **************************************************************/
153 /* static */ void scsi_low_info(struct scsi_low_softc *, struct targ_info *, u_char *);
154 static void scsi_low_engage(void *);
155 static struct slccb *scsi_low_establish_ccb(struct targ_info *, struct lun_info *, scsi_low_tag_t);
156 static int scsi_low_done(struct scsi_low_softc *, struct slccb *);
157 static int scsi_low_setup_done(struct scsi_low_softc *, struct slccb *);
158 static void scsi_low_bus_release(struct scsi_low_softc *, struct targ_info *);
159 static void scsi_low_twiddle_wait(void);
160 static struct lun_info *scsi_low_alloc_li(struct targ_info *, int, int);
161 static struct targ_info *scsi_low_alloc_ti(struct scsi_low_softc *, int);
162 static void scsi_low_calcf_lun(struct lun_info *);
163 static void scsi_low_calcf_target(struct targ_info *);
164 static void scsi_low_calcf_show(struct lun_info *);
165 static void scsi_low_reset_nexus(struct scsi_low_softc *, int);
166 static void scsi_low_reset_nexus_target(struct scsi_low_softc *, struct targ_info *, int);
167 static void scsi_low_reset_nexus_lun(struct scsi_low_softc *, struct lun_info *, int);
168 static int scsi_low_init(struct scsi_low_softc *, u_int);
169 static void scsi_low_start(struct scsi_low_softc *);
170 static void scsi_low_free_ti(struct scsi_low_softc *);
171
172 static int scsi_low_alloc_qtag(struct slccb *);
173 static int scsi_low_dealloc_qtag(struct slccb *);
174 static int scsi_low_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *, u_int, u_int);
175 static int scsi_low_message_enqueue(struct scsi_low_softc *, struct targ_info *, struct lun_info *, u_int);
176 static void scsi_low_unit_ready_cmd(struct slccb *);
177 static void scsi_low_timeout(void *);
178 static int scsi_low_timeout_check(struct scsi_low_softc *);
179 #ifdef SCSI_LOW_START_UP_CHECK
180 static int scsi_low_start_up(struct scsi_low_softc *);
181 #endif /* SCSI_LOW_START_UP_CHECK */
182 static int scsi_low_abort_ccb(struct scsi_low_softc *, struct slccb *);
183 static struct slccb *scsi_low_revoke_ccb(struct scsi_low_softc *, struct slccb *, int);
184
185 int scsi_low_version_major = 2;
186 int scsi_low_version_minor = 17;
187
188 static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab);
189
190 /**************************************************************
191 * Debug, Run test and Statics
192 **************************************************************/
193 #ifdef SCSI_LOW_INFO_DETAIL
194 #define SCSI_LOW_INFO(slp, ti, s) scsi_low_info((slp), (ti), (s))
195 #else /* !SCSI_LOW_INFO_DETAIL */
196 #define SCSI_LOW_INFO(slp, ti, s) printf("%s: %s\n", (slp)->sl_xname, (s))
197 #endif /* !SCSI_LOW_INFO_DETAIL */
198
199 #ifdef SCSI_LOW_STATICS
200 static struct scsi_low_statics {
201 int nexus_win;
202 int nexus_fail;
203 int nexus_disconnected;
204 int nexus_reselected;
205 int nexus_conflict;
206 } scsi_low_statics;
207 #endif /* SCSI_LOW_STATICS */
208
209 #ifdef SCSI_LOW_DEBUG
210 #define SCSI_LOW_DEBUG_DONE 0x00001
211 #define SCSI_LOW_DEBUG_DISC 0x00002
212 #define SCSI_LOW_DEBUG_SENSE 0x00004
213 #define SCSI_LOW_DEBUG_CALCF 0x00008
214 #define SCSI_LOW_DEBUG_ACTION 0x10000
215 int scsi_low_debug = 0;
216
217 #define SCSI_LOW_MAX_ATTEN_CHECK 32
218 #define SCSI_LOW_ATTEN_CHECK 0x0001
219 #define SCSI_LOW_CMDLNK_CHECK 0x0002
220 #define SCSI_LOW_ABORT_CHECK 0x0004
221 #define SCSI_LOW_NEXUS_CHECK 0x0008
222 int scsi_low_test = 0;
223 int scsi_low_test_id = 0;
224
225 static void scsi_low_test_abort(struct scsi_low_softc *, struct targ_info *, struct lun_info *);
226 static void scsi_low_test_cmdlnk(struct scsi_low_softc *, struct slccb *);
227 static void scsi_low_test_atten(struct scsi_low_softc *, struct targ_info *, u_int);
228 #define SCSI_LOW_DEBUG_TEST_GO(fl, id) \
229 ((scsi_low_test & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
230 #define SCSI_LOW_DEBUG_GO(fl, id) \
231 ((scsi_low_debug & (fl)) != 0 && (scsi_low_test_id & (1 << (id))) == 0)
232 #endif /* SCSI_LOW_DEBUG */
233
234 /**************************************************************
235 * CCB
236 **************************************************************/
237 GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb)
238 GENERIC_CCB(scsi_low, slccb, ccb_chain)
239
240 /**************************************************************
241 * Inline functions
242 **************************************************************/
243 #define SCSI_LOW_INLINE static __inline
244 SCSI_LOW_INLINE void scsi_low_activate_qtag(struct slccb *);
245 SCSI_LOW_INLINE void scsi_low_deactivate_qtag(struct slccb *);
246 SCSI_LOW_INLINE void scsi_low_ccb_message_assert(struct slccb *, u_int);
247 SCSI_LOW_INLINE void scsi_low_ccb_message_exec(struct scsi_low_softc *, struct slccb *);
248 SCSI_LOW_INLINE void scsi_low_ccb_message_retry(struct slccb *);
249 SCSI_LOW_INLINE void scsi_low_ccb_message_clear(struct slccb *);
250 SCSI_LOW_INLINE void scsi_low_init_msgsys(struct scsi_low_softc *, struct targ_info *);
251
252 SCSI_LOW_INLINE void
253 scsi_low_activate_qtag(cb)
254 struct slccb *cb;
255 {
256 struct lun_info *li = cb->li;
257
258 if (cb->ccb_tag != SCSI_LOW_UNKTAG)
259 return;
260
261 li->li_nqio ++;
262 cb->ccb_tag = cb->ccb_otag;
263 }
264
265 SCSI_LOW_INLINE void
266 scsi_low_deactivate_qtag(cb)
267 struct slccb *cb;
268 {
269 struct lun_info *li = cb->li;
270
271 if (cb->ccb_tag == SCSI_LOW_UNKTAG)
272 return;
273
274 li->li_nqio --;
275 cb->ccb_tag = SCSI_LOW_UNKTAG;
276 }
277
278 SCSI_LOW_INLINE void
279 scsi_low_ccb_message_exec(slp, cb)
280 struct scsi_low_softc *slp;
281 struct slccb *cb;
282 {
283
284 scsi_low_assert_msg(slp, cb->ti, cb->ccb_msgoutflag, 0);
285 cb->ccb_msgoutflag = 0;
286 }
287
288 SCSI_LOW_INLINE void
289 scsi_low_ccb_message_assert(cb, msg)
290 struct slccb *cb;
291 u_int msg;
292 {
293
294 cb->ccb_msgoutflag = cb->ccb_omsgoutflag = msg;
295 }
296
297 SCSI_LOW_INLINE void
298 scsi_low_ccb_message_retry(cb)
299 struct slccb *cb;
300 {
301 cb->ccb_msgoutflag = cb->ccb_omsgoutflag;
302 }
303
304 SCSI_LOW_INLINE void
305 scsi_low_ccb_message_clear(cb)
306 struct slccb *cb;
307 {
308 cb->ccb_msgoutflag = 0;
309 }
310
311 SCSI_LOW_INLINE void
312 scsi_low_init_msgsys(slp, ti)
313 struct scsi_low_softc *slp;
314 struct targ_info *ti;
315 {
316
317 ti->ti_msginptr = 0;
318 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0;
319 SCSI_LOW_DEASSERT_ATN(slp);
320 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL);
321 }
322
323 /*=============================================================
324 * START OF OS switch (All OS depend fucntions should be here)
325 =============================================================*/
326 /* common os depend utitlities */
327 #define SCSI_LOW_CMD_RESIDUAL_CHK 0x0001
328 #define SCSI_LOW_CMD_ORDERED_QTAG 0x0002
329 #define SCSI_LOW_CMD_ABORT_WARNING 0x0004
330
331 static u_int8_t scsi_low_cmd_flags[256] = {
332 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
333 /**/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 0, 0,
334 /*1*/ 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
335 /*2*/ 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 5, 0, 0, 0, 5, 5,
336 /*3*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5,
337 };
338
339 struct scsi_low_error_code {
340 int error_bits;
341 int error_code;
342 };
343
344 static struct slccb *scsi_low_find_ccb(struct scsi_low_softc *, u_int, u_int, void *);
345 static int scsi_low_translate_error_code(struct slccb *, struct scsi_low_error_code *);
346
347 static struct slccb *
348 scsi_low_find_ccb(slp, target, lun, osdep)
349 struct scsi_low_softc *slp;
350 u_int target, lun;
351 void *osdep;
352 {
353 struct targ_info *ti;
354 struct lun_info *li;
355 struct slccb *cb;
356
357 ti = slp->sl_ti[target];
358 li = scsi_low_alloc_li(ti, lun, 0);
359 if (li == NULL)
360 return NULL;
361
362 if ((cb = slp->sl_Qnexus) != NULL && cb->osdep == osdep)
363 return cb;
364
365 for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
366 cb = TAILQ_NEXT(cb, ccb_chain))
367 {
368 if (cb->osdep == osdep)
369 return cb;
370 }
371
372 for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL;
373 cb = TAILQ_NEXT(cb, ccb_chain))
374 {
375 if (cb->osdep == osdep)
376 return cb;
377 }
378 return NULL;
379 }
380
381 static int
382 scsi_low_translate_error_code(cb, tp)
383 struct slccb *cb;
384 struct scsi_low_error_code *tp;
385 {
386
387 if (cb->ccb_error == 0)
388 return tp->error_code;
389
390 for (tp ++; (cb->ccb_error & tp->error_bits) == 0; tp ++)
391 ;
392 return tp->error_code;
393 }
394
395 #ifdef SCSI_LOW_INTERFACE_XS
396 /**************************************************************
397 * SCSI INTERFACE (XS)
398 **************************************************************/
399 #define SCSI_LOW_MINPHYS 0x10000
400 #define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
401 #define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
402 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb((flags))
403 #define SCSI_LOW_XS_POLL_HZ 1000
404
405 static int scsi_low_poll_xs(struct scsi_low_softc *, struct slccb *);
406 static void scsi_low_scsi_minphys_xs(struct buf *);
407 #ifdef SCSI_LOW_TARGET_OPEN
408 static int scsi_low_target_open(struct scsipi_link *, struct cfdata *);
409 #endif /* SCSI_LOW_TARGET_OPEN */
410 static int scsi_low_scsi_cmd_xs(struct scsipi_xfer *);
411 static int scsi_low_enable_xs(void *, int);
412 static int scsi_low_ioctl_xs(struct scsipi_link *, u_long, caddr_t, int, struct proc *);
413
414 static int scsi_low_attach_xs(struct scsi_low_softc *);
415 static int scsi_low_world_start_xs(struct scsi_low_softc *);
416 static int scsi_low_dettach_xs(struct scsi_low_softc *);
417 static int scsi_low_ccb_setup_xs(struct scsi_low_softc *, struct slccb *);
418 static int scsi_low_done_xs(struct scsi_low_softc *, struct slccb *);
419 static void scsi_low_timeout_xs(struct scsi_low_softc *, int, int);
420 static u_int scsi_low_translate_quirks_xs(u_int);
421 static void scsi_low_setup_quirks_xs(struct targ_info *, struct lun_info *, u_int);
422
423 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_xs = {
424 scsi_low_attach_xs,
425 scsi_low_world_start_xs,
426 scsi_low_dettach_xs,
427 scsi_low_ccb_setup_xs,
428 scsi_low_done_xs,
429 scsi_low_timeout_xs
430 };
431
432 struct scsipi_device scsi_low_dev = {
433 NULL, /* Use default error handler */
434 NULL, /* have a queue, served by this */
435 NULL, /* have no async handler */
436 NULL, /* Use default 'done' routine */
437 };
438
439 struct scsi_low_error_code scsi_low_error_code_xs[] = {
440 {0, XS_NOERROR},
441 {SENSEIO, XS_SENSE},
442 {BUSYERR, XS_BUSY },
443 {SELTIMEOUTIO, XS_SELTIMEOUT},
444 {TIMEOUTIO, XS_TIMEOUT},
445 {-1, XS_DRIVER_STUFFUP}
446 };
447
448 static int
449 scsi_low_ioctl_xs(link, cmd, addr, flag, p)
450 struct scsipi_link *link;
451 u_long cmd;
452 caddr_t addr;
453 int flag;
454 struct proc *p;
455 {
456 struct scsi_low_softc *slp;
457 int s, error = ENOTTY;
458
459 slp = (struct scsi_low_softc *) link->adapter_softc;
460 if ((slp->sl_flags & HW_INACTIVE) != 0)
461 return ENXIO;
462
463 if (cmd == SCBUSIORESET)
464 {
465 s = SCSI_LOW_SPLSCSI();
466 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
467 splx(s);
468 error = 0;
469 }
470 else if (slp->sl_funcs->scsi_low_ioctl != 0)
471 {
472 error = (*slp->sl_funcs->scsi_low_ioctl)
473 (slp, cmd, addr, flag, p);
474 }
475
476 return error;
477 }
478
479 static int
480 scsi_low_enable_xs(arg, enable)
481 void *arg;
482 int enable;
483 {
484 struct scsi_low_softc *slp = arg;
485
486 if (enable != 0)
487 {
488 if ((slp->sl_flags & HW_INACTIVE) != 0)
489 return ENXIO;
490 }
491 else
492 {
493 if ((slp->sl_flags & HW_INACTIVE) != 0 ||
494 (slp->sl_flags & HW_POWERCTRL) == 0)
495 return 0;
496
497 slp->sl_flags |= HW_POWDOWN;
498 if (slp->sl_funcs->scsi_low_power != NULL)
499 {
500 (*slp->sl_funcs->scsi_low_power)
501 (slp, SCSI_LOW_POWDOWN);
502 }
503 }
504 return 0;
505 }
506
507 static void
508 scsi_low_scsi_minphys_xs(bp)
509 struct buf *bp;
510 {
511
512 if (bp->b_bcount > SCSI_LOW_MINPHYS)
513 bp->b_bcount = SCSI_LOW_MINPHYS;
514 minphys(bp);
515 }
516
517 static int
518 scsi_low_poll_xs(slp, cb)
519 struct scsi_low_softc *slp;
520 struct slccb *cb;
521 {
522 struct scsipi_xfer *xs = cb->osdep;
523 int tcount;
524
525 cb->ccb_flags |= CCB_NOSDONE;
526 tcount = 0;
527
528 while (slp->sl_nio > 0)
529 {
530 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_XS_POLL_HZ);
531
532 (*slp->sl_funcs->scsi_low_poll) (slp);
533
534 if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
535 {
536 cb->ccb_flags |= CCB_NORETRY;
537 cb->ccb_error |= FATALIO;
538 (void) scsi_low_revoke_ccb(slp, cb, 1);
539 printf("%s: hardware inactive in poll mode\n",
540 slp->sl_xname);
541 }
542
543 if ((xs->flags & ITSDONE) != 0)
544 break;
545
546 if (tcount ++ < SCSI_LOW_XS_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
547 continue;
548
549 tcount = 0;
550 scsi_low_timeout_check(slp);
551 }
552
553 xs->flags |= ITSDONE;
554 scsipi_done(xs);
555 return COMPLETE;
556 }
557
558 static int
559 scsi_low_scsi_cmd_xs(xs)
560 struct scsipi_xfer *xs;
561 {
562 struct scsipi_link *splp = xs->sc_link;
563 struct scsi_low_softc *slp = splp->adapter_softc;
564 struct targ_info *ti;
565 struct lun_info *li;
566 struct slccb *cb;
567 int s, targ, lun, flags, rv;
568
569 if ((cb = SCSI_LOW_ALLOC_CCB(xs->flags & SCSI_NOSLEEP)) == NULL)
570 return TRY_AGAIN_LATER;
571
572 targ = splp->scsipi_scsi.target,
573 lun = splp->scsipi_scsi.lun;
574 ti = slp->sl_ti[targ];
575
576 cb->osdep = xs;
577 cb->bp = xs->bp;
578
579 if ((xs->flags & SCSI_POLL) == 0)
580 flags = CCB_AUTOSENSE;
581 else
582 flags = CCB_AUTOSENSE | CCB_POLLED;
583
584
585 s = SCSI_LOW_SPLSCSI();
586 li = scsi_low_alloc_li(ti, lun, 1);
587 if ((u_int) splp->quirks != li->li_sloi.sloi_quirks)
588 {
589 scsi_low_setup_quirks_xs(ti, li, (u_int) splp->quirks);
590 }
591
592 if ((xs->flags & SCSI_RESET) != 0)
593 {
594 flags |= CCB_NORETRY | CCB_URGENT;
595 scsi_low_enqueue(slp, ti, li, cb, flags, SCSI_LOW_MSG_RESET);
596 }
597 else
598 {
599 if (ti->ti_setup_msg != 0)
600 {
601 scsi_low_message_enqueue(slp, ti, li, flags);
602 }
603
604 flags |= CCB_SCSIIO;
605 scsi_low_enqueue(slp, ti, li, cb, flags, 0);
606 }
607
608 #ifdef SCSI_LOW_DEBUG
609 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ABORT_CHECK, ti->ti_id) != 0)
610 {
611 scsi_low_test_abort(slp, ti, li);
612 }
613 #endif /* SCSI_LOW_DEBUG */
614
615 if ((cb->ccb_flags & CCB_POLLED) != 0)
616 {
617 rv = scsi_low_poll_xs(slp, cb);
618 }
619 else
620 {
621 rv = SUCCESSFULLY_QUEUED;
622 }
623 splx(s);
624 return rv;
625 }
626
627 static int
628 scsi_low_attach_xs(slp)
629 struct scsi_low_softc *slp;
630 {
631 struct scsipi_adapter *sap;
632 struct scsipi_link *splp;
633
634 strncpy(slp->sl_xname, slp->sl_dev.dv_xname, 16);
635
636 sap = SCSI_LOW_MALLOC(sizeof(*sap));
637 if (sap == NULL)
638 return ENOMEM;
639 splp = SCSI_LOW_MALLOC(sizeof(*splp));
640 if (splp == NULL)
641 return ENOMEM;
642
643 SCSI_LOW_BZERO(sap, sizeof(*sap));
644 SCSI_LOW_BZERO(splp, sizeof(*splp));
645
646 sap->scsipi_cmd = scsi_low_scsi_cmd_xs;
647 sap->scsipi_minphys = scsi_low_scsi_minphys_xs;
648 sap->scsipi_enable = scsi_low_enable_xs;
649 sap->scsipi_ioctl = scsi_low_ioctl_xs;
650 #ifdef SCSI_LOW_TARGET_OPEN
651 sap->open_target_lu = scsi_low_target_open;
652 #endif /* SCSI_LOW_TARGET_OPEN */
653
654 splp->adapter_softc = slp;
655 splp->scsipi_scsi.adapter_target = slp->sl_hostid;
656 splp->scsipi_scsi.max_target = slp->sl_ntargs - 1;
657 splp->scsipi_scsi.max_lun = slp->sl_nluns - 1;
658 splp->scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE;
659 splp->openings = slp->sl_openings;
660 splp->type = BUS_SCSI;
661 splp->adapter_softc = slp;
662 splp->adapter = sap;
663 splp->device = &scsi_low_dev;
664
665 slp->sl_si.si_splp = splp;
666 slp->sl_show_result = SHOW_ALL_NEG;
667 return 0;
668 }
669
670 static int
671 scsi_low_world_start_xs(slp)
672 struct scsi_low_softc *slp;
673 {
674
675 return 0;
676 }
677
678 static int
679 scsi_low_dettach_xs(slp)
680 struct scsi_low_softc *slp;
681 {
682
683 /*
684 * scsipi does not have dettach bus fucntion.
685 *
686 scsipi_dettach_scsibus(slp->sl_si.si_splp);
687 */
688 return 0;
689 }
690
691 static int
692 scsi_low_ccb_setup_xs(slp, cb)
693 struct scsi_low_softc *slp;
694 struct slccb *cb;
695 {
696 struct scsipi_xfer *xs = (struct scsipi_xfer *) cb->osdep;
697
698 if ((cb->ccb_flags & CCB_SCSIIO) != 0)
699 {
700 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd;
701 cb->ccb_scp.scp_cmdlen = xs->cmdlen;
702 cb->ccb_scp.scp_data = xs->data;
703 cb->ccb_scp.scp_datalen = xs->datalen;
704 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ?
705 SCSI_LOW_WRITE : SCSI_LOW_READ;
706 cb->ccb_tcmax = xs->timeout / 1000;
707 }
708 else
709 {
710 scsi_low_unit_ready_cmd(cb);
711 }
712 return SCSI_LOW_START_QTAG;
713 }
714
715 static int
716 scsi_low_done_xs(slp, cb)
717 struct scsi_low_softc *slp;
718 struct slccb *cb;
719 {
720 struct scsipi_xfer *xs;
721
722 xs = (struct scsipi_xfer *) cb->osdep;
723 if (cb->ccb_error == 0)
724 {
725 xs->error = XS_NOERROR;
726 xs->resid = 0;
727 }
728 else
729 {
730 if (cb->ccb_rcnt >= slp->sl_max_retry)
731 cb->ccb_error |= ABORTIO;
732
733 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
734 (cb->ccb_error & ABORTIO) == 0)
735 return EJUSTRETURN;
736
737 if ((cb->ccb_error & SENSEIO) != 0)
738 {
739 xs->sense.scsi_sense = cb->ccb_sense;
740 }
741
742 xs->error = scsi_low_translate_error_code(cb,
743 &scsi_low_error_code_xs[0]);
744
745 #ifdef SCSI_LOW_DIAGNOSTIC
746 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
747 cb->ccb_scp.scp_cmdlen > 0 &&
748 (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
749 SCSI_LOW_CMD_ABORT_WARNING) != 0)
750 {
751 printf("%s: WARNING: scsi_low IO abort\n",
752 slp->sl_xname);
753 scsi_low_print(slp, NULL);
754 }
755 #endif /* SCSI_LOW_DIAGNOSTIC */
756 }
757
758 if (cb->ccb_scp.scp_status == ST_UNKNOWN)
759 xs->status = 0; /* XXX */
760 else
761 xs->status = cb->ccb_scp.scp_status;
762
763 xs->flags |= ITSDONE;
764 if ((cb->ccb_flags & CCB_NOSDONE) == 0)
765 scsipi_done(xs);
766
767 return 0;
768 }
769
770 static void
771 scsi_low_timeout_xs(slp, ch, action)
772 struct scsi_low_softc *slp;
773 int ch;
774 int action;
775 {
776
777 switch (ch)
778 {
779 case SCSI_LOW_TIMEOUT_CH_IO:
780 switch (action)
781 {
782 case SCSI_LOW_TIMEOUT_START:
783 timeout(scsi_low_timeout, slp,
784 hz / SCSI_LOW_TIMEOUT_HZ);
785 break;
786 case SCSI_LOW_TIMEOUT_STOP:
787 untimeout(scsi_low_timeout, slp);
788 break;
789 }
790 break;
791
792 case SCSI_LOW_TIMEOUT_CH_ENGAGE:
793 switch (action)
794 {
795 case SCSI_LOW_TIMEOUT_START:
796 timeout(scsi_low_engage, slp, 1);
797 break;
798 case SCSI_LOW_TIMEOUT_STOP:
799 untimeout(scsi_low_engage, slp);
800 break;
801 }
802 break;
803
804 case SCSI_LOW_TIMEOUT_CH_RECOVER:
805 break;
806 }
807 }
808
809 u_int
810 scsi_low_translate_quirks_xs(quirks)
811 u_int quirks;
812 {
813 u_int flags;
814
815 flags = SCSI_LOW_DISK_LFLAGS | SCSI_LOW_DISK_TFLAGS;
816
817 #ifdef SDEV_NODISC
818 if (quirks & SDEV_NODISC)
819 flags &= ~SCSI_LOW_DISK_DISC;
820 #endif /* SDEV_NODISC */
821 #ifdef SDEV_NOPARITY
822 if (quirks & SDEV_NOPARITY)
823 flags &= ~SCSI_LOW_DISK_PARITY;
824 #endif /* SDEV_NOPARITY */
825 #ifdef SDEV_NOCMDLNK
826 if (quirks & SDEV_NOCMDLNK)
827 flags &= ~SCSI_LOW_DISK_LINK;
828 #endif /* SDEV_NOCMDLNK */
829 #ifdef SDEV_NOTAG
830 if (quirks & SDEV_NOTAG)
831 flags &= ~SCSI_LOW_DISK_QTAG;
832 #endif /* SDEV_NOTAG */
833 #ifdef SDEV_NOSYNC
834 if (quirks & SDEV_NOSYNC)
835 flags &= ~SCSI_LOW_DISK_SYNC;
836 #endif /* SDEV_NOSYNC */
837
838 return flags;
839 }
840
841 static void
842 scsi_low_setup_quirks_xs(ti, li, flags)
843 struct targ_info *ti;
844 struct lun_info *li;
845 u_int flags;
846 {
847 u_int quirks;
848
849 li->li_sloi.sloi_quirks = flags;
850 quirks = scsi_low_translate_quirks_xs(flags);
851 ti->ti_quirks = quirks & SCSI_LOW_DISK_TFLAGS;
852 li->li_quirks = quirks & SCSI_LOW_DISK_LFLAGS;
853 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
854 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
855 scsi_low_calcf_target(ti);
856 scsi_low_calcf_lun(li);
857 scsi_low_calcf_show(li);
858 }
859
860 #ifdef SCSI_LOW_TARGET_OPEN
861 static int
862 scsi_low_target_open(link, cf)
863 struct scsipi_link *link;
864 struct cfdata *cf;
865 {
866 u_int target = link->scsipi_scsi.target;
867 u_int lun = link->scsipi_scsi.lun;
868 struct scsi_low_softc *slp;
869 struct targ_info *ti;
870 struct lun_info *li;
871
872 slp = (struct scsi_low_softc *) link->adapter_softc;
873 ti = slp->sl_ti[target];
874 li = scsi_low_alloc_li(ti, lun, 0);
875 if (li == NULL)
876 return 0;
877
878 li->li_cfgflags = cf->cf_flags;
879 scsi_low_setup_quirks_xs(ti, li, (u_int) link->quirks);
880 return 0;
881 }
882 #endif /* SCSI_LOW_TARGET_OPEN */
883
884 #endif /* SCSI_LOW_INTERFACE_XS */
885
886 #ifdef SCSI_LOW_INTERFACE_CAM
887 /**************************************************************
888 * SCSI INTERFACE (CAM)
889 **************************************************************/
890 #define SCSI_LOW_MALLOC(size) malloc((size), M_SCSILOW, M_NOWAIT)
891 #define SCSI_LOW_FREE(pt) free((pt), M_SCSILOW)
892 #define SCSI_LOW_ALLOC_CCB(flags) scsi_low_get_ccb()
893
894 static void scsi_low_poll_cam(struct cam_sim *);
895 static void scsi_low_cam_rescan_callback(struct cam_periph *, union ccb *);
896 static void scsi_low_rescan_bus_cam(struct scsi_low_softc *);
897 void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *);
898
899 static int scsi_low_attach_cam(struct scsi_low_softc *);
900 static int scsi_low_world_start_cam(struct scsi_low_softc *);
901 static int scsi_low_dettach_cam(struct scsi_low_softc *);
902 static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *);
903 static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *);
904 static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int);
905
906 struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = {
907 scsi_low_attach_cam,
908 scsi_low_world_start_cam,
909 scsi_low_dettach_cam,
910 scsi_low_ccb_setup_cam,
911 scsi_low_done_cam,
912 scsi_low_timeout_cam
913 };
914
915 struct scsi_low_error_code scsi_low_error_code_cam[] = {
916 {0, CAM_REQ_CMP},
917 {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR},
918 {SENSEERR, CAM_AUTOSENSE_FAIL},
919 {UACAERR, CAM_SCSI_STATUS_ERROR},
920 {BUSYERR | STATERR, CAM_SCSI_STATUS_ERROR},
921 {SELTIMEOUTIO, CAM_SEL_TIMEOUT},
922 {TIMEOUTIO, CAM_CMD_TIMEOUT},
923 {PDMAERR, CAM_DATA_RUN_ERR},
924 {PARITYERR, CAM_UNCOR_PARITY},
925 {UBFERR, CAM_UNEXP_BUSFREE},
926 {ABORTIO, CAM_REQ_ABORTED},
927 {-1, CAM_UNREC_HBA_ERROR}
928 };
929
930 #define SIM2SLP(sim) ((struct scsi_low_softc *) cam_sim_softc((sim)))
931
932 /* XXX:
933 * Please check a polling hz, currently we assume scsi_low_poll() is
934 * called each 1 ms.
935 */
936 #define SCSI_LOW_CAM_POLL_HZ 1000 /* OK ? */
937
938 static void
939 scsi_low_poll_cam(sim)
940 struct cam_sim *sim;
941 {
942 struct scsi_low_softc *slp = SIM2SLP(sim);
943
944 (*slp->sl_funcs->scsi_low_poll) (slp);
945
946 if (slp->sl_si.si_poll_count ++ >=
947 SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
948 {
949 slp->sl_si.si_poll_count = 0;
950 scsi_low_timeout_check(slp);
951 }
952 }
953
954 static void
955 scsi_low_cam_rescan_callback(periph, ccb)
956 struct cam_periph *periph;
957 union ccb *ccb;
958 {
959
960 xpt_free_path(ccb->ccb_h.path);
961 xpt_free_ccb(ccb);
962 }
963
964 static void
965 scsi_low_rescan_bus_cam(slp)
966 struct scsi_low_softc *slp;
967 {
968 struct cam_path *path;
969 union ccb *ccb = xpt_alloc_ccb();
970 cam_status status;
971
972 bzero(ccb, sizeof(union ccb));
973
974 status = xpt_create_path(&path, xpt_periph,
975 cam_sim_path(slp->sl_si.sim), -1, 0);
976 if ( |