scsi_low.c revision 67964
1187692Snwhitehorn/* $FreeBSD: head/sys/cam/scsi/scsi_low.c 67964 2000-10-30 12:21:19Z non $ */ 2187692Snwhitehorn/* $NecBSD: scsi_low.c,v 1.24 1999/07/26 06:27:01 honda Exp $ */ 3187692Snwhitehorn/* $NetBSD$ */ 4187692Snwhitehorn 5187692Snwhitehorn#define SCSI_LOW_STATICS 6187692Snwhitehorn#define SCSI_LOW_WARNINGS 7187692Snwhitehorn#ifdef __NetBSD__ 8187692Snwhitehorn#define SCSI_LOW_TARGET_OPEN 9187692Snwhitehorn#define SCSI_LOW_INFORM 10187692Snwhitehorn#endif 11187692Snwhitehorn#ifdef __FreeBSD__ 12187692Snwhitehorn#define CAM 13187692Snwhitehorn#endif 14187692Snwhitehorn 15187692Snwhitehorn/* 16187692Snwhitehorn * [NetBSD for NEC PC-98 series] 17187692Snwhitehorn * Copyright (c) 1995, 1996, 1997, 1998, 1999 18187692Snwhitehorn * NetBSD/pc98 porting staff. All rights reserved. 19187692Snwhitehorn * Copyright (c) 1995, 1996, 1997, 1998, 1999 20187692Snwhitehorn * Naofumi HONDA. All rights reserved. 21187692Snwhitehorn * 22187692Snwhitehorn * Redistribution and use in source and binary forms, with or without 23187692Snwhitehorn * modification, are permitted provided that the following conditions 24187692Snwhitehorn * are met: 25187692Snwhitehorn * 1. Redistributions of source code must retain the above copyright 26187692Snwhitehorn * notice, this list of conditions and the following disclaimer. 27187692Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 28187692Snwhitehorn * notice, this list of conditions and the following disclaimer in the 29187692Snwhitehorn * documentation and/or other materials provided with the distribution. 30187692Snwhitehorn * 3. The name of the author may not be used to endorse or promote products 31187692Snwhitehorn * derived from this software without specific prior written permission. 32187692Snwhitehorn * 33187692Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 34187692Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35187692Snwhitehorn * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 36187692Snwhitehorn * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 37187692Snwhitehorn * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 38187692Snwhitehorn * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 39187692Snwhitehorn * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 40187692Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 41187692Snwhitehorn * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 42187692Snwhitehorn * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 43187692Snwhitehorn * POSSIBILITY OF SUCH DAMAGE. 44187692Snwhitehorn */ 45187692Snwhitehorn 46187692Snwhitehorn/* <On the nexus establishment> 47187692Snwhitehorn * When our host is reselected, 48187692Snwhitehorn * nexus establish processes are little complicated. 49187692Snwhitehorn * Normal steps are followings: 50187692Snwhitehorn * 1) Our host selected by target => target nexus (slp->sl_nexus) 51187692Snwhitehorn * 2) Identify msgin => lun nexus (ti->ti_li) 52187692Snwhitehorn * 3) Qtag msg => slccb nexus (ti->ti_nexus) 53187692Snwhitehorn */ 54187692Snwhitehorn#include "opt_ddb.h" 55187692Snwhitehorn 56187692Snwhitehorn#include <sys/param.h> 57187692Snwhitehorn#include <sys/systm.h> 58187692Snwhitehorn#include <sys/kernel.h> 59187692Snwhitehorn#ifdef __NetBSD__ 60187692Snwhitehorn#include <sys/disklabel.h> 61187692Snwhitehorn#endif 62187692Snwhitehorn#if defined(__FreeBSD__) && __FreeBSD_version >= 500001 63187692Snwhitehorn#include <sys/bio.h> 64187692Snwhitehorn#endif 65187692Snwhitehorn#include <sys/buf.h> 66276292Sjoel#include <sys/queue.h> 67276292Sjoel#include <sys/malloc.h> 68187692Snwhitehorn#include <sys/device_port.h> 69187692Snwhitehorn#include <sys/errno.h> 70187692Snwhitehorn 71187692Snwhitehorn#ifdef __NetBSD__ 72187692Snwhitehorn#include <vm/vm.h> 73187692Snwhitehorn 74187692Snwhitehorn#include <machine/bus.h> 75187692Snwhitehorn#include <machine/intr.h> 76187692Snwhitehorn#include <machine/dvcfg.h> 77187692Snwhitehorn 78267938Sbapt#include <dev/cons.h> 79208027Suqs 80208027Suqs#include <dev/scsipi/scsipi_all.h> 81#include <dev/scsipi/scsipiconf.h> 82#include <dev/scsipi/scsipi_disk.h> 83#include <dev/scsipi/scsi_all.h> 84#include <dev/scsipi/scsiconf.h> 85 86#include <i386/Cbus/dev/scsi_low.h> 87#endif 88#ifdef __FreeBSD__ 89#include <cam/cam.h> 90#include <cam/cam_ccb.h> 91#include <cam/cam_sim.h> 92#include <cam/cam_debug.h> 93#include <cam/cam_periph.h> 94 95#include <cam/scsi/scsi_all.h> 96 97#include <cam/scsi/scsi_low.h> 98 99#if !defined(__FreeBSD__) || __FreeBSD_version < 400001 100#include <i386/i386/cons.h> 101#else 102#include <sys/cons.h> 103#endif 104#define delay(time) DELAY(time) 105 106/* from sys/dev/usb/usb_port.h 107 XXX Change this when FreeBSD has memset 108 */ 109#define memset(d, v, s) \ 110 do{ \ 111 if ((v) == 0) \ 112 bzero((d), (s)); \ 113 else \ 114 panic("Non zero filler for memset, cannot handle!"); \ 115 } while (0) 116#endif 117 118#define SCSI_LOW_DONE_COMPLETE 0 119#define SCSI_LOW_DONE_RETRY 1 120 121static void scsi_low_engage __P((void *)); 122static void scsi_low_info __P((struct scsi_low_softc *, struct targ_info *, u_char *)); 123static void scsi_low_init_msgsys __P((struct scsi_low_softc *, struct targ_info *)); 124static struct slccb *scsi_low_establish_ccb __P((struct targ_info *, struct lun_info *, scsi_low_tag_t)); 125static int scsi_low_done __P((struct scsi_low_softc *, struct slccb *)); 126static void scsi_low_twiddle_wait __P((void)); 127static struct lun_info *scsi_low_alloc_li __P((struct targ_info *, int, int)); 128static struct targ_info *scsi_low_alloc_ti __P((struct scsi_low_softc *, int)); 129static void scsi_low_calcf __P((struct targ_info *, struct lun_info *)); 130static struct lun_info *scsi_low_establish_lun __P((struct targ_info *, int)); 131#ifndef CAM 132static void scsi_low_scsi_minphys __P((struct buf *)); 133#endif 134#ifdef SCSI_LOW_TARGET_OPEN 135static int scsi_low_target_open __P((struct scsipi_link *, struct cfdata *)); 136#endif /* SCSI_LOW_TARGET_OPEN */ 137#ifdef CAM 138void scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb); 139static void scsi_low_poll (struct cam_sim *sim); 140#else 141static int scsi_low_scsi_cmd __P((struct scsipi_xfer *)); 142#endif 143static void scsi_low_reset_nexus __P((struct scsi_low_softc *, int)); 144static int scsi_low_init __P((struct scsi_low_softc *, u_int)); 145static void scsi_low_start __P((struct scsi_low_softc *)); 146static void scsi_low_free_ti __P((struct scsi_low_softc *)); 147static void scsi_low_clear_ccb __P((struct slccb *)); 148 149#ifdef SCSI_LOW_STATICS 150struct scsi_low_statics { 151 int nexus_win; 152 int nexus_fail; 153 int nexus_disconnected; 154 int nexus_reselected; 155 int nexus_conflict; 156} scsi_low_statics; 157#endif /* SCSI_LOW_STATICS */ 158/************************************************************** 159 * power control 160 **************************************************************/ 161static void 162scsi_low_engage(arg) 163 void *arg; 164{ 165 struct scsi_low_softc *slp = arg; 166 int s = splbio(); 167 168 switch (slp->sl_rstep) 169 { 170 case 0: 171 slp->sl_rstep ++; 172 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); 173#ifdef __FreeBSD__ 174 slp->engage_ch = 175#endif 176 timeout(scsi_low_engage, slp, 1); 177 break; 178 179 case 1: 180 slp->sl_rstep ++; 181 slp->sl_flags &= ~HW_RESUME; 182 scsi_low_start(slp); 183 break; 184 185 case 2: 186 break; 187 } 188 splx(s); 189} 190 191static int 192scsi_low_init(slp, flags) 193 struct scsi_low_softc *slp; 194 u_int flags; 195{ 196 197 if ((slp->sl_flags & HW_POWERCTRL) != 0) 198 { 199#ifdef __FreeBSD__ 200 untimeout(scsi_low_engage, slp, slp->engage_ch); 201#else /* NetBSD */ 202 untimeout(scsi_low_engage, slp); 203#endif 204 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); 205 slp->sl_active = 1; 206 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 207 } 208 209 /* reset current nexus */ 210 scsi_low_reset_nexus(slp, flags); 211 if ((slp->sl_flags & HW_INACTIVE) != 0) 212 return EBUSY; 213 214 if (flags == SCSI_LOW_RESTART_SOFT) 215 return 0; 216 217 return ((*slp->sl_funcs->scsi_low_init) (slp, flags)); 218} 219 220/************************************************************** 221 * allocate lun_info 222 **************************************************************/ 223static struct lun_info * 224scsi_low_alloc_li(ti, lun, alloc) 225 struct targ_info *ti; 226 int lun; 227 int alloc; 228{ 229 struct scsi_low_softc *slp = ti->ti_sc; 230 struct lun_info *li; 231 232 li = LIST_FIRST(&ti->ti_litab); 233 if (li != NULL) 234 { 235 if (li->li_lun == lun) 236 return li; 237 238 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 239 { 240 if (li->li_lun == lun) 241 { 242 LIST_REMOVE(li, lun_chain); 243 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 244 return li; 245 } 246 } 247 } 248 249 if (alloc == 0) 250 return li; 251 252 li = malloc(ti->ti_lunsize, M_DEVBUF, M_NOWAIT); 253 if (li == NULL) 254 panic("no lun info mem\n"); 255 256 memset(li, 0, ti->ti_lunsize); 257 li->li_lun = lun; 258 li->li_ti = ti; 259#if defined(SDEV_NOPARITY) && defined(SDEV_NODISC) 260 li->li_quirks = SDEV_NOPARITY | SDEV_NODISC; 261#endif /* SDEV_NOPARITY && SDEV_NODISC */ 262 li->li_cfgflags = 0xffff0000 | SCSI_LOW_SYNC; 263 264 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain); 265 266 /* host specific structure initialization per lun */ 267 (void) ((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li)); 268 269 return li; 270} 271 272/************************************************************** 273 * allocate targ_info 274 **************************************************************/ 275static struct targ_info * 276scsi_low_alloc_ti(slp, targ) 277 struct scsi_low_softc *slp; 278 int targ; 279{ 280 struct targ_info *ti; 281 282 if (slp->sl_titab.tqh_first == NULL) 283 TAILQ_INIT(&slp->sl_titab); 284 285 ti = malloc(sizeof(struct targ_info), M_DEVBUF, M_NOWAIT); 286 if (ti == NULL) 287 panic("%s short of memory\n", slp->sl_xname); 288 289 memset(ti, 0, sizeof(struct targ_info)); 290 ti->ti_id = targ; 291 ti->ti_sc = slp; 292 293 slp->sl_ti[targ] = ti; 294 TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain); 295 TAILQ_INIT(&ti->ti_discq); 296 LIST_INIT(&ti->ti_litab); 297 298 return ti; 299} 300 301static void 302scsi_low_free_ti(slp) 303 struct scsi_low_softc *slp; 304{ 305 struct targ_info *ti, *tib; 306 struct lun_info *li, *nli; 307 308 for (ti = slp->sl_titab.tqh_first; ti; ti = tib) 309 { 310 tib = ti->ti_chain.tqe_next; 311 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli) 312 { 313 nli = LIST_NEXT(li, lun_chain); 314 free(li, M_DEVBUF); 315 } 316 free(ti, M_DEVBUF); 317 } 318} 319 320/************************************************************** 321 * timeout 322 **************************************************************/ 323void 324scsi_low_timeout(arg) 325 void *arg; 326{ 327 struct scsi_low_softc *slp = arg; 328 struct targ_info *ti; 329 struct slccb *cb = NULL; /* XXX */ 330 int s = splbio(); 331 332 /* check */ 333 if ((ti = slp->sl_nexus) != NULL && (cb = ti->ti_nexus) != NULL) 334 { 335 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 336 if (cb->ccb_tc < 0) 337 goto bus_reset; 338 } 339 else if (slp->sl_disc > 0) 340 { 341 struct targ_info *ti; 342 343 for (ti = slp->sl_titab.tqh_first; ti != NULL; 344 ti = ti->ti_chain.tqe_next) 345 { 346 for (cb = ti->ti_discq.tqh_first; cb != NULL; 347 cb = cb->ccb_chain.tqe_next) 348 { 349 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 350 if (cb->ccb_tc < 0) 351 goto bus_reset; 352 } 353 } 354 } 355 else 356 { 357 cb = slp->sl_start.tqh_first; 358 if (cb != NULL) 359 { 360 cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL; 361 if (cb->ccb_tc < 0) 362 goto bus_reset; 363 } 364 else if ((slp->sl_flags & HW_POWERCTRL) != 0) 365 { 366 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0) 367 goto out; 368 369 if (slp->sl_active != 0) 370 { 371 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 372 slp->sl_active = 0; 373 goto out; 374 } 375 376 slp->sl_powc --; 377 if (slp->sl_powc < 0) 378 { 379 slp->sl_powc = SCSI_LOW_POWDOWN_TC; 380 slp->sl_flags |= HW_POWDOWN; 381 (*slp->sl_funcs->scsi_low_power) 382 (slp, SCSI_LOW_POWDOWN); 383 } 384 } 385 } 386 387out: 388#ifdef __FreeBSD__ 389 slp->timeout_ch = 390#endif 391 timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz); 392 393 splx(s); 394 return; 395 396bus_reset: 397 cb->ccb_error |= TIMEOUTIO; 398 scsi_low_info(slp, NULL, "scsi bus hangup. try to recover."); 399 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 400 scsi_low_start(slp); 401#ifdef __FreeBSD__ 402 slp->timeout_ch = 403#endif 404 timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz); 405 406 splx(s); 407} 408 409/************************************************************** 410 * CCB 411 **************************************************************/ 412GENERIC_CCB_STATIC_ALLOC(scsi_low, slccb) 413GENERIC_CCB(scsi_low, slccb, ccb_chain) 414 415/************************************************************** 416 * SCSI INTERFACE (XS) 417 **************************************************************/ 418#define SCSI_LOW_MINPHYS 0x10000 419 420#ifdef __NetBSD__ 421struct scsipi_device scsi_low_dev = { 422 NULL, /* Use default error handler */ 423 NULL, /* have a queue, served by this */ 424 NULL, /* have no async handler */ 425 NULL, /* Use default 'done' routine */ 426}; 427#endif 428 429#ifdef CAM 430static void 431scsi_low_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) 432{ 433 xpt_free_path(ccb->ccb_h.path); 434 free(ccb, M_DEVBUF); 435#if defined(__FreeBSD__) && __FreeBSD_version < 400001 436 free(periph, M_DEVBUF); 437#endif 438} 439 440static void 441scsi_low_rescan_bus(struct scsi_low_softc *slp) 442{ 443 struct cam_path *path; 444 union ccb *ccb = malloc(sizeof(union ccb), M_DEVBUF, M_WAITOK); 445#if defined(__FreeBSD__) && __FreeBSD_version < 400001 446 struct cam_periph *xpt_periph = malloc(sizeof(struct cam_periph), 447 M_DEVBUF, M_WAITOK); 448#endif 449 cam_status status; 450 451 bzero(ccb, sizeof(union ccb)); 452 453 status = xpt_create_path(&path, xpt_periph, 454 cam_sim_path(slp->sim), -1, 0); 455 if (status != CAM_REQ_CMP) 456 return; 457 458 xpt_setup_ccb(&ccb->ccb_h, path, 5); 459 ccb->ccb_h.func_code = XPT_SCAN_BUS; 460 ccb->ccb_h.cbfcnp = scsi_low_cam_rescan_callback; 461 ccb->crcn.flags = CAM_FLAG_NONE; 462 xpt_action(ccb); 463} 464#endif 465 466int 467scsi_low_attach(slp, openings, ntargs, nluns, lunsize) 468 struct scsi_low_softc *slp; 469 int openings, ntargs, nluns, lunsize; 470{ 471 struct targ_info *ti; 472 struct lun_info *li; 473#ifdef CAM 474 struct cam_devq *devq; 475#else 476 struct scsipi_adapter *sap; 477#endif 478 int i, nccb; 479 480#ifdef CAM 481 OS_DEPEND(sprintf(slp->sl_xname, "%s%d", 482 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev))); 483#else 484 OS_DEPEND(strncpy(slp->sl_xname, DEVPORT_DEVNAME(slp->sl_dev), 16)); 485#endif 486 if (ntargs > SCSI_LOW_NTARGETS) 487 { 488 printf("scsi_low: %d targets are too large\n", ntargs); 489 printf("change kernel options SCSI_LOW_NTARGETS"); 490 } 491 492 if (lunsize < sizeof(struct lun_info)) 493 lunsize = sizeof(struct lun_info); 494 495 for (i = 0; i < ntargs; i ++) 496 { 497 ti = scsi_low_alloc_ti(slp, i); 498 ti->ti_lunsize = lunsize; 499 li = scsi_low_alloc_li(ti, 0, 1); 500 } 501 502#ifndef CAM 503 sap = malloc(sizeof(*sap), M_DEVBUF, M_NOWAIT); 504 if (sap == NULL) 505 return ENOMEM; 506 507 memset(sap, 0, sizeof(*sap)); 508 sap->scsipi_cmd = scsi_low_scsi_cmd; 509 sap->scsipi_minphys = scsi_low_scsi_minphys; 510#ifdef SCSI_LOW_TARGET_OPEN 511 sap->open_target_lu = scsi_low_target_open; 512#endif /* SCSI_LOW_TARGET_OPEN */ 513#endif 514 515 if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) 516 return EINVAL; 517 518 /* initialize queue */ 519 nccb = openings * (ntargs - 1); 520 if (nccb >= SCSI_LOW_NCCB || nccb <= 0) 521 nccb = SCSI_LOW_NCCB; 522 scsi_low_init_ccbque(nccb); 523 TAILQ_INIT(&slp->sl_start); 524 525 slp->sl_openings = openings; 526 slp->sl_ntargs = ntargs; 527 slp->sl_nluns = nluns; 528 529#ifdef CAM 530 /* 531 * Prepare the scsibus_data area for the upperlevel 532 * scsi code. 533 */ 534 devq = cam_simq_alloc(256/*MAX_START*/); 535 if (devq == NULL) 536 return (0); 537 /* scbus->adapter_link = &slp->sc_link; */ 538 /* 539 * ask the adapter what subunits are present 540 */ 541 542 slp->sim = cam_sim_alloc(scsi_low_scsi_action, scsi_low_poll, 543 DEVPORT_DEVNAME(slp->sl_dev), slp, 544 DEVPORT_DEVUNIT(slp->sl_dev), 1, 32/*MAX_TAGS*/, devq); 545 if (slp->sim == NULL) { 546 cam_simq_free(devq); 547 return 0; 548 } 549 550 if (xpt_bus_register(slp->sim, 0) != CAM_SUCCESS) { 551 free(slp->sim, M_DEVBUF); 552 return 0; 553 } 554 555 if (xpt_create_path(&slp->path, /*periph*/NULL, 556 cam_sim_path(slp->sim), CAM_TARGET_WILDCARD, 557 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 558 xpt_bus_deregister(cam_sim_path(slp->sim)); 559 cam_sim_free(slp->sim, /*free_simq*/TRUE); 560 free(slp->sim, M_DEVBUF); 561 return 0; 562 } 563#else /* !CAM */ 564 slp->sl_link.adapter_softc = slp; 565 slp->sl_link.scsipi_scsi.adapter_target = slp->sl_hostid; 566 slp->sl_link.scsipi_scsi.max_target = ntargs - 1; 567 slp->sl_link.scsipi_scsi.max_lun = nluns - 1; 568 slp->sl_link.scsipi_scsi.channel = SCSI_CHANNEL_ONLY_ONE; 569 slp->sl_link.openings = openings; 570 slp->sl_link.type = BUS_SCSI; 571 slp->sl_link.adapter_softc = slp; 572 slp->sl_link.adapter = sap; 573 slp->sl_link.device = &scsi_low_dev; 574#endif 575 576 /* start watch dog */ 577 slp->sl_max_retry = SCSI_LOW_MAX_RETRY; 578#ifdef __FreeBSD__ 579 slp->timeout_ch = 580#endif 581 timeout(scsi_low_timeout, slp, SCSI_LOW_TIMEOUT_CHECK_INTERVAL * hz); 582#ifdef CAM 583 if (!cold) 584 scsi_low_rescan_bus(slp); 585#endif 586 587 return 0; 588} 589 590#ifndef CAM 591static void 592scsi_low_scsi_minphys(bp) 593 struct buf *bp; 594{ 595 596 if (bp->b_bcount > SCSI_LOW_MINPHYS) 597 bp->b_bcount = SCSI_LOW_MINPHYS; 598 minphys(bp); 599} 600#endif 601 602int 603scsi_low_dettach(slp) 604 struct scsi_low_softc *slp; 605{ 606 607 if (slp->sl_disc > 0 || slp->sl_start.tqh_first != NULL) 608 return EBUSY; 609 610 /* 611 * scsipi does not have dettach bus fucntion. 612 * 613 scsipi_dettach_scsibus(&slp->sl_link); 614 */ 615 616#ifdef CAM 617 xpt_async(AC_LOST_DEVICE, slp->path, NULL); 618 xpt_free_path(slp->path); 619 xpt_bus_deregister(cam_sim_path(slp->sim)); 620 cam_sim_free(slp->sim, /* free_devq */ TRUE); 621#endif 622 623 scsi_low_free_ti(slp); 624 return 0; 625} 626 627#ifdef CAM 628static void 629scsi_low_poll(struct cam_sim *sim) 630{ 631 struct scsi_low_softc *slp = (struct scsi_low_softc *) cam_sim_softc(sim); 632 (*slp->sl_funcs->scsi_low_poll) (slp); 633} 634 635void 636scsi_low_scsi_action(struct cam_sim *sim, union ccb *ccb) 637{ 638 struct scsi_low_softc *slp = (struct scsi_low_softc *) cam_sim_softc(sim); 639 int s, target = (u_int) (ccb->ccb_h.target_id); 640 struct targ_info *ti; 641 struct lun_info *li; 642 struct slccb *cb; 643 644#if 0 645 printf("scsi_low_scsi_action() func code %d Target: %d, LUN: %d\n", 646 ccb->ccb_h.func_code, target, ccb->ccb_h.target_lun); 647#endif 648 switch (ccb->ccb_h.func_code) { 649 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 650 if (((cb = scsi_low_get_ccb()) == NULL)) { 651 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 652 xpt_done(ccb); 653 return; 654 } 655 656 cb->ccb = ccb; 657 cb->ccb_tag = SCSI_LOW_UNKTAG; 658 cb->bp = (struct buf *)NULL; 659 cb->ti = ti = slp->sl_ti[target]; 660 cb->li = scsi_low_alloc_li(ti, ccb->ccb_h.target_lun, 1); 661 cb->ccb_flags = 0; 662 cb->ccb_rcnt = 0; 663 664 s = splcam(); 665 666 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 667 668 if (slp->sl_nexus == NULL) { 669 scsi_low_start(slp); 670 } 671 672 splx(s); 673 break; 674 case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ 675 case XPT_EN_LUN: /* Enable LUN as a target */ 676 case XPT_TARGET_IO: /* Execute target I/O request */ 677 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 678 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 679 case XPT_ABORT: /* Abort the specified CCB */ 680 /* XXX Implement */ 681 ccb->ccb_h.status = CAM_REQ_INVALID; 682 xpt_done(ccb); 683 break; 684 case XPT_SET_TRAN_SETTINGS: 685 /* XXX Implement */ 686 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 687 xpt_done(ccb); 688 break; 689 case XPT_GET_TRAN_SETTINGS: { 690 struct ccb_trans_settings *cts; 691 struct targ_info *ti; 692 int lun = ccb->ccb_h.target_lun; 693 /*int s;*/ 694 695 cts = &ccb->cts; 696 ti = slp->sl_ti[ccb->ccb_h.target_id]; 697 li = LIST_FIRST(&ti->ti_litab); 698 if (li != NULL && li->li_lun != lun) 699 while ((li = LIST_NEXT(li, lun_chain)) != NULL) 700 if (li->li_lun == lun) 701 break; 702 s = splcam(); 703 if (li != NULL && (cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { 704 if (li->li_cfgflags & SCSI_LOW_DISC) 705 cts->flags = CCB_TRANS_DISC_ENB; 706 else 707 cts->flags = 0; 708 if (li->li_cfgflags & SCSI_LOW_QTAG) 709 cts->flags |= CCB_TRANS_TAG_ENB; 710 711 cts->bus_width = 0;/*HN2*/ 712 713 cts->valid = CCB_TRANS_SYNC_RATE_VALID 714 | CCB_TRANS_SYNC_OFFSET_VALID 715 | CCB_TRANS_BUS_WIDTH_VALID 716 | CCB_TRANS_DISC_VALID 717 | CCB_TRANS_TQ_VALID; 718 ccb->ccb_h.status = CAM_REQ_CMP; 719 } else 720 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 721 722 splx(s); 723 xpt_done(ccb); 724 break; 725 } 726 case XPT_CALC_GEOMETRY: { /* not yet HN2 */ 727 struct ccb_calc_geometry *ccg; 728 u_int32_t size_mb; 729 u_int32_t secs_per_cylinder; 730 int extended; 731 732 extended = 1; 733 ccg = &ccb->ccg; 734 size_mb = ccg->volume_size 735 / ((1024L * 1024L) / ccg->block_size); 736 737 if (size_mb > 1024 && extended) { 738 ccg->heads = 255; 739 ccg->secs_per_track = 63; 740 } else { 741 ccg->heads = 64; 742 ccg->secs_per_track = 32; 743 } 744 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 745 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 746 ccb->ccb_h.status = CAM_REQ_CMP; 747 xpt_done(ccb); 748 break; 749 } 750 case XPT_RESET_BUS: /* Reset the specified SCSI bus */ 751#if 0 752 scsi_low_bus_reset(slp); 753#endif 754 ccb->ccb_h.status = CAM_REQ_CMP; 755 xpt_done(ccb); 756 break; 757 case XPT_TERM_IO: /* Terminate the I/O process */ 758 /* XXX Implement */ 759 ccb->ccb_h.status = CAM_REQ_INVALID; 760 xpt_done(ccb); 761 break; 762 case XPT_PATH_INQ: { /* Path routing inquiry */ 763 struct ccb_pathinq *cpi = &ccb->cpi; 764 765 cpi->version_num = 1; /* XXX??? */ 766 cpi->hba_inquiry = PI_SDTR_ABLE; 767 cpi->target_sprt = 0; 768 cpi->hba_misc = 0; 769 cpi->hba_eng_cnt = 0; 770 cpi->max_target = SCSI_LOW_NTARGETS - 1; 771 cpi->max_lun = 7; 772 cpi->initiator_id = 7; /* HOST_SCSI_ID */ 773 cpi->bus_id = cam_sim_bus(sim); 774 cpi->base_transfer_speed = 3300; 775 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 776 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN); 777 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 778 cpi->unit_number = cam_sim_unit(sim); 779 cpi->ccb_h.status = CAM_REQ_CMP; 780 xpt_done(ccb); 781 break; 782 } 783 default: 784 printf("scsi_low: non support func_code = %d ", ccb->ccb_h.func_code); 785 ccb->ccb_h.status = CAM_REQ_INVALID; 786 xpt_done(ccb); 787 break; 788 } 789} 790#else /* !CAM */ 791static int 792scsi_low_scsi_cmd(xs) 793 struct scsipi_xfer *xs; 794{ 795 struct scsi_low_softc *slp = xs->sc_link->adapter_softc; 796 struct targ_info *ti; 797 struct slccb *cb; 798 int s, lun, timeo; 799 800 if (slp->sl_cfgflags & CFG_NOATTEN) 801 { 802 if (xs->sc_link->scsipi_scsi.lun > 0) 803 { 804 xs->error = XS_DRIVER_STUFFUP; 805 return COMPLETE; 806 } 807 } 808 809 if ((cb = scsi_low_get_ccb(xs->flags & SCSI_NOSLEEP)) == NULL) 810 return TRY_AGAIN_LATER; 811 812 lun = xs->sc_link->scsipi_scsi.lun; 813 cb->xs = xs; 814 cb->ccb_tag = SCSI_LOW_UNKTAG; 815 cb->ti = ti = slp->sl_ti[xs->sc_link->scsipi_scsi.target]; 816 cb->li = scsi_low_alloc_li(ti, lun, 1); 817 cb->ccb_flags = 0; 818 cb->ccb_rcnt = 0; 819 820 s = splbio(); 821 822 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain); 823 if (slp->sl_nexus == NULL) 824 scsi_low_start(slp); 825 826 if ((xs->flags & SCSI_POLL) == 0) 827 { 828 splx(s); 829 return SUCCESSFULLY_QUEUED; 830 } 831 832#define SCSI_LOW_POLL_INTERVAL 1000 /* 1 ms */ 833 timeo = xs->timeout * (1000 / SCSI_LOW_POLL_INTERVAL); 834 835 while ((xs->flags & ITSDONE) == 0 && timeo -- > 0) 836 { 837 delay(SCSI_LOW_POLL_INTERVAL); 838 (*slp->sl_funcs->scsi_low_poll) (slp); 839 } 840 841 if ((xs->flags & ITSDONE) == 0) 842 { 843 cb->ccb_error |= (TIMEOUTIO | ABORTIO); 844 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL); 845 scsi_low_disconnected(slp, ti); 846 scsi_low_init(slp, SCSI_LOW_RESTART_HARD); 847 } 848 849 scsipi_done(xs); 850 splx(s); 851 return COMPLETE; 852} 853#endif 854 855/************************************************************** 856 * Start & Done 857 **************************************************************/ 858#ifdef __NetBSD__ 859static struct scsipi_start_stop ss_cmd = { START_STOP, 0, {0,0,}, SSS_START, }; 860static struct scsipi_test_unit_ready unit_ready_cmd; 861#endif 862#ifdef __FreeBSD__ 863static struct scsi_start_stop_unit ss_cmd = { START_STOP, 0, {0,0,}, SSS_START, }; 864static struct scsi_test_unit_ready unit_ready_cmd; 865#endif 866static void scsi_low_unit_ready_cmd __P((struct slccb *)); 867 868static void 869scsi_low_unit_ready_cmd(cb) 870 struct slccb *cb; 871{ 872 873 cb->ccb_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 874 cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd); 875 cb->ccb_scp.scp_datalen = 0; 876 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 877 cb->ccb_tcmax = 15; 878} 879 880static void 881scsi_low_start(slp) 882 struct scsi_low_softc *slp; 883{ 884#ifdef CAM 885 union ccb *ccb; 886#else 887 struct scsipi_xfer *xs; 888#endif 889 struct targ_info *ti; 890 struct lun_info *li; 891 struct slccb *cb; 892 int rv; 893 894 /* check hardware exists ? */ 895 if ((slp->sl_flags & HW_INACTIVE) != 0) 896 return; 897 898 /* check hardware power up ? */ 899 if ((slp->sl_flags & HW_POWERCTRL) != 0) 900 { 901 slp->sl_active ++; 902 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME)) 903 { 904 if (slp->sl_flags & HW_RESUME) 905 return; 906 slp->sl_flags &= ~HW_POWDOWN; 907 if (slp->sl_funcs->scsi_low_power != NULL) 908 { 909 slp->sl_flags |= HW_RESUME; 910 slp->sl_rstep = 0; 911 (*slp->sl_funcs->scsi_low_power) 912 (slp, SCSI_LOW_ENGAGE); 913#ifdef __FreeBSD__ 914 slp->engage_ch = 915#endif 916 timeout(scsi_low_engage, slp, 1); 917 return; 918 } 919 } 920 } 921 922 /* setup nexus */ 923#ifdef SCSI_LOW_DIAGNOSTIC 924 ti = slp->sl_nexus; 925 if (ti != NULL) 926 { 927 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 928 panic("%s: inconsistent(target)\n", slp->sl_xname); 929 } 930#endif /* SCSI_LOW_DIAGNOSTIC */ 931 932 for (cb = slp->sl_start.tqh_first; cb != NULL; 933 cb = cb->ccb_chain.tqe_next) 934 { 935 ti = cb->ti; 936 li = cb->li; 937 if (ti->ti_phase == PH_NULL) 938 goto scsi_low_cmd_start; 939 if (ti->ti_phase == PH_DISC && li->li_disc < li->li_maxnexus) 940 goto scsi_low_cmd_start; 941 } 942 return; 943 944scsi_low_cmd_start: 945#ifdef CAM 946 ccb = cb->ccb; 947#else 948 xs = cb->xs; 949#endif 950#ifdef SCSI_LOW_DIAGNOSTIC 951 if (ti->ti_nexus != NULL || ti->ti_li != NULL) 952 { 953 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT"); 954 panic("%s: inconsistent(lun or ccb)\n", slp->sl_xname); 955 } 956#endif /* SCSI_LOW_DIAGNOSTIC */ 957 958 /* clear all error flag bits (for restart) */ 959 cb->ccb_error = 0; 960 961 /* setup nexus pointer */ 962 ti->ti_nexus = cb; 963 ti->ti_li = li; 964 slp->sl_nexus = ti; 965 966 /* initialize msgsys */ 967 scsi_low_init_msgsys(slp, ti); 968 969 /* target lun state check */ 970#ifdef CAM 971 li->li_maxstate = UNIT_OK; 972#else 973 if ((xs->flags & SCSI_POLL) != 0) 974 li->li_maxstate = UNIT_NEGSTART; 975 else 976 li->li_maxstate = UNIT_OK; 977#endif 978 979 /* exec cmds */ 980scsi_low_cmd_exec: 981 if ((cb->ccb_flags & CCB_SENSE) != 0) 982 { 983 memset(&cb->ccb_sense, 0, sizeof(cb->ccb_sense)); 984#ifdef CAM 985#else 986 cb->ccb_sense_cmd.opcode = REQUEST_SENSE; 987 cb->ccb_sense_cmd.byte2 = (li->li_lun << 5); 988 cb->ccb_sense_cmd.length = sizeof(cb->ccb_sense); 989#endif 990 cb->ccb_scp.scp_cmd = (u_int8_t *) &cb->ccb_sense_cmd; 991 cb->ccb_scp.scp_cmdlen = sizeof(cb->ccb_sense_cmd); 992 cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense; 993 cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense); 994 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 995 cb->ccb_tcmax = 15; 996 } 997 else if (li->li_state >= li->li_maxstate) 998 { 999#ifdef CAM 1000 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes; 1001 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len; 1002 cb->ccb_scp.scp_data = ccb->csio.data_ptr; 1003 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len; 1004 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) 1005 cb->ccb_scp.scp_direction = SCSI_LOW_WRITE; 1006 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */ 1007 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1008 cb->ccb_tcmax = (ccb->ccb_h.timeout >> 10); 1009#else 1010 cb->ccb_scp.scp_cmd = (u_int8_t *) xs->cmd; 1011 cb->ccb_scp.scp_cmdlen = xs->cmdlen; 1012 cb->ccb_scp.scp_data = xs->data; 1013 cb->ccb_scp.scp_datalen = xs->datalen; 1014 cb->ccb_scp.scp_direction = (xs->flags & SCSI_DATA_OUT) ? 1015 SCSI_LOW_WRITE : SCSI_LOW_READ; 1016 cb->ccb_tcmax = (xs->timeout >> 10); 1017#endif 1018 1019 } 1020 else switch(li->li_state) 1021 { 1022 case UNIT_SLEEP: 1023 scsi_low_unit_ready_cmd(cb); 1024 break; 1025 1026 case UNIT_START: 1027 cb->ccb_scp.scp_cmd = (u_int8_t *) &ss_cmd; 1028 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd); 1029 cb->ccb_scp.scp_datalen = 0; 1030 cb->ccb_scp.scp_direction = SCSI_LOW_READ; 1031 cb->ccb_tcmax = 30; 1032 break; 1033 1034 case UNIT_SYNCH: 1035 if (li->li_maxsynch.offset > 0) 1036 { 1037 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 1038 scsi_low_unit_ready_cmd(cb); 1039 break; 1040 } 1041 li->li_state = UNIT_WIDE; 1042 1043 case UNIT_WIDE: 1044#ifdef SCSI_LOW_SUPPORT_WIDE 1045 if (li->li_width > 0) 1046 { 1047 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 1048 scsi_low_unit_ready_cmd(cb); 1049 break; 1050 } 1051#endif /* SCSI_LOW_SUPPORT_WIDE */ 1052 li->li_state = UNIT_OK; 1053 1054 case UNIT_OK: 1055 goto scsi_low_cmd_exec; 1056 } 1057 1058 /* timeout */ 1059 if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT) 1060 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT; 1061 cb->ccb_tc = cb->ccb_tcmax; 1062 1063 /* setup saved scsi data pointer */ 1064 cb->ccb_sscp = cb->ccb_scp; 1065 1066 /* setup current scsi pointer */ 1067 slp->sl_scp = cb->ccb_sscp; 1068 slp->sl_error = cb->ccb_error; 1069 1070 /* selection start */ 1071 slp->sl_selid = ti; 1072 rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb)); 1073 if (rv == SCSI_LOW_START_OK) 1074 { 1075#ifdef SCSI_LOW_STATICS 1076 scsi_low_statics.nexus_win ++; 1077#endif /* SCSI_LOW_STATICS */ 1078 return; 1079 } 1080 1081#ifdef SCSI_LOW_STATICS 1082 scsi_low_statics.nexus_fail ++; 1083#endif /* SCSI_LOW_STATICS */ 1084 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 1085 scsi_low_clear_nexus(slp, ti); 1086} 1087 1088void 1089scsi_low_clear_nexus(slp, ti) 1090 struct scsi_low_softc *slp; 1091 struct targ_info *ti; 1092{ 1093 1094 /* clear all nexus pointer */ 1095 ti->ti_nexus = NULL; 1096 ti->ti_li = NULL; 1097 slp->sl_nexus = NULL; 1098 1099 /* clear selection assert */ 1100 slp->sl_selid = NULL; 1101 1102 /* clear nexus data */ 1103 slp->sl_nexus_call = 0; 1104 slp->sl_scp.scp_direction = SCSI_LOW_RWUNK; 1105} 1106 1107static int 1108scsi_low_done(slp, cb) 1109 struct scsi_low_softc *slp; 1110 struct slccb *cb; 1111{ 1112#ifdef CAM 1113 union ccb *ccb; 1114#else 1115 struct scsipi_xfer *xs; 1116#endif 1117 struct targ_info *ti; 1118 struct lun_info *li; 1119 1120 ti = cb->ti; 1121 li = cb->li; 1122#ifdef CAM 1123 ccb = cb->ccb; 1124#else 1125 xs = cb->xs; 1126#endif 1127 if (cb->ccb_error == 0) 1128 { 1129 if ((cb->ccb_flags & CCB_SENSE) != 0) 1130 { 1131 cb->ccb_flags &= ~CCB_SENSE; 1132#ifdef CAM 1133 ccb->csio.sense_data = cb->ccb_sense; 1134 /* ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; */ 1135 ccb->ccb_h.status = CAM_REQ_CMP; 1136 /* ccb->ccb_h.status = CAM_AUTOSNS_VALID|CAM_SCSI_STATUS_ERROR; */ 1137#else 1138 xs->sense.scsi_sense = cb->ccb_sense; 1139 xs->error = XS_SENSE; 1140#endif 1141 } 1142 else switch (ti->ti_status) 1143 { 1144 case ST_GOOD: 1145 if (slp->sl_scp.scp_datalen == 0) 1146 { 1147#ifdef CAM 1148 ccb->ccb_h.status = CAM_REQ_CMP; 1149#else 1150 xs->error = XS_NOERROR; 1151#endif 1152 break; 1153 } 1154 1155#define SCSIPI_SCSI_CD_COMPLETELY_BUGGY "YES" 1156#ifdef SCSIPI_SCSI_CD_COMPLETELY_BUGGY 1157#ifdef CAM 1158 if (/* cb->bp == NULL && */ 1159 slp->sl_scp.scp_datalen < cb->ccb_scp.scp_datalen) 1160#else 1161 if (xs->bp == NULL && 1162 slp->sl_scp.scp_datalen < cb->ccb_scp.scp_datalen) 1163#endif 1164 { 1165#ifdef CAM 1166 ccb->ccb_h.status = CAM_REQ_CMP; 1167#else 1168 xs->error = XS_NOERROR; 1169#endif 1170 break; 1171 } 1172#endif /* SCSIPI_SCSI_CD_COMPLETELY_BUGGY */ 1173 1174 cb->ccb_error |= PDMAERR; 1175#ifdef CAM 1176 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1177#else 1178 xs->error = XS_DRIVER_STUFFUP; 1179#endif 1180 break; 1181 1182 case ST_CHKCOND: 1183 case ST_MET: 1184 cb->ccb_flags |= CCB_SENSE; 1185#ifdef CAM 1186 ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; 1187#else 1188 xs->error = XS_SENSE; 1189#endif 1190 goto retry; 1191 1192 case ST_BUSY: 1193 cb->ccb_error |= BUSYERR; 1194#ifdef CAM 1195 ccb->ccb_h.status = CAM_BUSY; /* SCSI_STATUS_ERROR; */ 1196#else 1197 xs->error = XS_BUSY; 1198#endif 1199 break; 1200 1201 default: 1202 cb->ccb_error |= FATALIO; 1203#ifdef CAM 1204 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1205#else 1206 xs->error = XS_DRIVER_STUFFUP; 1207#endif 1208 break; 1209 } 1210 } 1211 else 1212 { 1213 cb->ccb_flags &= ~CCB_SENSE; 1214 if (ti->ti_phase == PH_SELSTART) 1215 { 1216#ifdef CAM 1217 ccb->ccb_h.status = CAM_CMD_TIMEOUT; 1218#else 1219 xs->error = XS_TIMEOUT; 1220#endif 1221 slp->sl_error |= SELTIMEOUTIO; 1222 if (li->li_state == UNIT_SLEEP) 1223 cb->ccb_error |= ABORTIO; 1224 } 1225 else 1226 { 1227#ifdef CAM 1228 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1229#else 1230 xs->error = XS_DRIVER_STUFFUP; 1231#endif 1232 } 1233 1234 if ((cb->ccb_error & ABORTIO) != 0) 1235 { 1236 cb->ccb_rcnt = slp->sl_max_retry; 1237#ifdef CAM 1238 ccb->ccb_h.status = CAM_REQ_ABORTED; 1239#endif 1240 } 1241 } 1242 1243 /* target state check */ 1244 if (li->li_state < li->li_maxstate) 1245 { 1246 if (cb->ccb_rcnt < slp->sl_max_retry) 1247 { 1248 li->li_state ++; 1249 cb->ccb_rcnt = 0; 1250 goto retry; 1251 } 1252 } 1253 1254 /* internal retry check */ 1255#ifdef CAM 1256 if (ccb->ccb_h.status == CAM_REQ_CMP) 1257 { 1258 ccb->csio.resid = 0; 1259 } 1260 else 1261 { 1262#if 0 1263 if (ccb->ccb_h.status != CAM_AUTOSENSE_FAIL && 1264 cb->ccb_rcnt < slp->sl_max_retry) 1265 goto retry; 1266#endif 1267#else 1268 if (xs->error == XS_NOERROR) 1269 { 1270 xs->resid = 0; 1271 } 1272 else 1273 { 1274 if (xs->error != XS_SENSE && 1275 cb->ccb_rcnt < slp->sl_max_retry) 1276 goto retry; 1277#endif 1278 1279#ifndef CAM 1280#ifdef SCSI_LOW_WARNINGS 1281 if (xs->bp != NULL) 1282 { 1283 scsi_low_print(slp, ti); 1284 printf("%s: WARNING: File system IO abort\n", 1285 slp->sl_xname); 1286 } 1287#endif /* SCSI_LOW_WARNINGS */ 1288#endif 1289 } 1290 1291#ifdef CAM 1292 ccb->csio.scsi_status = ti->ti_status; 1293 xpt_done(ccb); 1294#else 1295 xs->flags |= ITSDONE; 1296 if ((xs->flags & SCSI_POLL) == 0) 1297 scsipi_done(xs); 1298#endif 1299 1300 /* free our target */ 1301 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 1302 scsi_low_free_ccb(cb); 1303 return SCSI_LOW_DONE_COMPLETE; 1304 1305retry: 1306 cb->ccb_rcnt ++; 1307 if (slp->sl_start.tqh_first != cb) 1308 { 1309 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 1310 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 1311 } 1312 return SCSI_LOW_DONE_RETRY; 1313} 1314 1315/************************************************************** 1316 * Reset 1317 **************************************************************/ 1318static void 1319scsi_low_clear_ccb(cb) 1320 struct slccb *cb; 1321{ 1322 1323 cb->ccb_flags &= ~CCB_SENSE; 1324 cb->ccb_tag = SCSI_LOW_UNKTAG; 1325} 1326 1327static void 1328scsi_low_reset_nexus(slp, fdone) 1329 struct scsi_low_softc *slp; 1330 int fdone; 1331{ 1332 struct targ_info *ti; 1333 struct lun_info *li; 1334 struct slccb *cb, *ncb; 1335 1336 /* current nexus */ 1337 ti = slp->sl_nexus; 1338 if (ti != NULL && (cb = ti->ti_nexus) != NULL) 1339 { 1340 scsi_low_clear_ccb(cb); 1341 if (fdone != 0 && cb->ccb_rcnt ++ >= slp->sl_max_retry) 1342 { 1343 cb->ccb_error |= FATALIO; 1344 scsi_low_done(slp, cb); 1345 } 1346 } 1347 1348 /* disconnected nexus */ 1349 for (ti = slp->sl_titab.tqh_first; ti != NULL; 1350 ti = ti->ti_chain.tqe_next) 1351 { 1352 for (cb = ti->ti_discq.tqh_first; cb != NULL; cb = ncb) 1353 { 1354 ncb = cb->ccb_chain.tqe_next; 1355 TAILQ_REMOVE(&ti->ti_discq, cb, ccb_chain); 1356 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 1357 scsi_low_clear_ccb(cb); 1358 if (fdone != 0 && cb->ccb_rcnt ++ >= slp->sl_max_retry) 1359 { 1360 cb->ccb_error |= FATALIO; 1361 scsi_low_done(slp, cb); 1362 } 1363 } 1364 1365 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; 1366 li = LIST_NEXT(li, lun_chain)) 1367 { 1368 li->li_state = UNIT_SLEEP; 1369 li->li_disc = 0; 1370 ((*slp->sl_funcs->scsi_low_lun_init) (slp, ti, li)); 1371 scsi_low_calcf(ti, li); 1372 } 1373 1374 scsi_low_init_msgsys(slp, ti); 1375 scsi_low_clear_nexus(slp, ti); 1376 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 1377 } 1378 1379 slp->sl_flags &= ~HW_PDMASTART; 1380 slp->sl_disc = 0; 1381} 1382 1383/* misc */ 1384static int tw_pos; 1385static char tw_chars[] = "|/-\\"; 1386 1387static void 1388scsi_low_twiddle_wait(void) 1389{ 1390 1391 cnputc('\b'); 1392 cnputc(tw_chars[tw_pos++]); 1393 tw_pos %= (sizeof(tw_chars) - 1); 1394 delay(TWIDDLEWAIT); 1395} 1396 1397void 1398scsi_low_bus_reset(slp) 1399 struct scsi_low_softc *slp; 1400{ 1401 int i; 1402 1403 (*slp->sl_funcs->scsi_low_bus_reset) (slp); 1404 1405 printf("%s: try to reset scsi bus ", slp->sl_xname); 1406 for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++) 1407 scsi_low_twiddle_wait(); 1408 cnputc('\b'); 1409 printf("\n"); 1410} 1411 1412int 1413scsi_low_restart(slp, flags, s) 1414 struct scsi_low_softc *slp; 1415 int flags; 1416 u_char *s; 1417{ 1418 int error; 1419 1420 if (s != NULL) 1421 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s); 1422 1423 if ((error = scsi_low_init(slp, flags)) != 0) 1424 return error; 1425 1426 scsi_low_start(slp); 1427 return 0; 1428} 1429 1430/************************************************************** 1431 * disconnect and reselect 1432 **************************************************************/ 1433#define MSGCMD_LUN(msg) (msg & 0x07) 1434 1435static struct lun_info * 1436scsi_low_establish_lun(ti, lun) 1437 struct targ_info *ti; 1438 int lun; 1439{ 1440 struct lun_info *li; 1441 1442 li = scsi_low_alloc_li(ti, lun, 0); 1443 if (li == NULL) 1444 return li; 1445 1446 ti->ti_li = li; 1447 return li; 1448} 1449 1450static struct slccb * 1451scsi_low_establish_ccb(ti, li, tag) 1452 struct targ_info *ti; 1453 struct lun_info *li; 1454 scsi_low_tag_t tag; 1455{ 1456 struct scsi_low_softc *slp = ti->ti_sc; 1457 struct slccb *cb; 1458 1459 /* 1460 * Search ccb matching with lun and tag. 1461 */ 1462 cb = ti->ti_discq.tqh_first; 1463 for ( ; cb != NULL; cb = cb->ccb_chain.tqe_next) 1464 if (cb->li == li && cb->ccb_tag == tag) 1465 goto found; 1466 return cb; 1467 1468 /* 1469 * establish our ccb nexus 1470 */ 1471found: 1472 TAILQ_REMOVE(&ti->ti_discq, cb, ccb_chain); 1473 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain); 1474 ti->ti_nexus = cb; 1475 1476 slp->sl_scp = cb->ccb_sscp; 1477 slp->sl_error |= cb->ccb_error; 1478 1479 slp->sl_disc --; 1480 li->li_disc --; 1481 1482 /* inform "ccb nexus established" to the host driver */ 1483 slp->sl_nexus_call = 1; 1484 (*slp->sl_funcs->scsi_low_establish_nexus) (slp, ti); 1485 return cb; 1486} 1487 1488struct targ_info * 1489scsi_low_reselected(slp, targ) 1490 struct scsi_low_softc *slp; 1491 u_int targ; 1492{ 1493 struct targ_info *ti; 1494 u_char *s; 1495 1496 /* 1497 * Check select vs reselected collision. 1498 */ 1499 1500 if ((ti = slp->sl_selid) != NULL) 1501 { 1502 scsi_low_clear_nexus(slp, ti); 1503 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 1504#ifdef SCSI_LOW_STATICS 1505 scsi_low_statics.nexus_conflict ++; 1506#endif /* SCSI_LOW_STATICS */ 1507 } 1508 else if (slp->sl_nexus != NULL) 1509 { 1510 s = "host busy"; 1511 goto world_restart; 1512 } 1513 1514 /* 1515 * Check a valid target id asserted ? 1516 */ 1517 if (targ >= slp->sl_ntargs || targ == slp->sl_hostid) 1518 { 1519 s = "scsi id illegal"; 1520 goto world_restart; 1521 } 1522 1523 /* 1524 * Check the target scsi status. 1525 */ 1526 ti = slp->sl_ti[targ]; 1527 if (ti->ti_phase != PH_DISC) 1528 { 1529 s = "phase mismatch"; 1530 goto world_restart; 1531 } 1532 1533 /* 1534 * Setup lun and init msgsys 1535 */ 1536 slp->sl_error = 0; 1537 scsi_low_init_msgsys(slp, ti); 1538 1539 /* 1540 * Establish our target nexus 1541 * Remark: ccb and scsi pointer not yet restored 1542 * if lun != SCSI_LOW_UNKLUN. 1543 */ 1544 SCSI_LOW_SETUP_PHASE(ti, PH_RESEL); 1545 slp->sl_nexus = ti; 1546#ifdef SCSI_LOW_STATICS 1547 scsi_low_statics.nexus_reselected ++; 1548#endif /* SCSI_LOW_STATICS */ 1549 return ti; 1550 1551world_restart: 1552 printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s); 1553 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 1554 "reselect: scsi world confused"); 1555 return NULL; 1556} 1557 1558int 1559scsi_low_disconnected(slp, ti) 1560 struct scsi_low_softc *slp; 1561 struct targ_info *ti; 1562{ 1563 struct slccb *cb = ti->ti_nexus; 1564 1565 /* check phase completion */ 1566 switch (slp->sl_msgphase) 1567 { 1568 case MSGPH_DISC: 1569 if (cb != NULL) 1570 { 1571 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain); 1572 TAILQ_INSERT_TAIL(&ti->ti_discq, cb, ccb_chain); 1573 cb->ccb_error |= slp->sl_error; 1574 cb->li->li_disc ++; 1575 slp->sl_disc ++; 1576 } 1577 SCSI_LOW_SETUP_PHASE(ti, PH_DISC); 1578#ifdef SCSI_LOW_STATICS 1579 scsi_low_statics.nexus_disconnected ++; 1580#endif /* SCSI_LOW_STATICS */ 1581 break; 1582 1583 case MSGPH_NULL: 1584 slp->sl_error |= FATALIO; 1585 1586 case MSGPH_CMDC: 1587 if (cb != NULL) 1588 { 1589 cb->ccb_error |= slp->sl_error; 1590 scsi_low_done(slp, cb); 1591 } 1592 SCSI_LOW_SETUP_PHASE(ti, PH_NULL); 1593 break; 1594 } 1595 1596 scsi_low_clear_nexus(slp, ti); 1597 scsi_low_start(slp); 1598 return 1; 1599} 1600 1601/************************************************************** 1602 * cmd out pointer setup 1603 **************************************************************/ 1604int 1605scsi_low_cmd(slp, ti) 1606 struct scsi_low_softc *slp; 1607 struct targ_info *ti; 1608{ 1609 struct slccb *cb = ti->ti_nexus; 1610 1611 if (cb == NULL) 1612 { 1613 /* 1614 * no slccb, abort! 1615 */ 1616 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd; 1617 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd); 1618 slp->sl_scp.scp_datalen = 0; 1619 slp->sl_scp.scp_direction = SCSI_LOW_READ; 1620 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); 1621 scsi_low_info(slp, ti, "CMDOUT: slccb nexus not found"); 1622 } 1623 else if (slp->sl_nexus_call == 0) 1624 { 1625 slp->sl_nexus_call = 1; 1626 (*slp->sl_funcs->scsi_low_establish_nexus) (slp, ti); 1627 } 1628 return 0; 1629} 1630 1631/************************************************************** 1632 * data out pointer setup 1633 **************************************************************/ 1634int 1635scsi_low_data(slp, ti, bp, direction) 1636 struct scsi_low_softc *slp; 1637 struct targ_info *ti; 1638 struct buf **bp; 1639 int direction; 1640{ 1641 struct slccb *cb = ti->ti_nexus; 1642 1643 if (cb == NULL) 1644 { 1645 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); 1646 scsi_low_info(slp, ti, "DATA PHASE: slccb nexus not found"); 1647 return EINVAL; 1648 } 1649 1650 if (direction != cb->ccb_scp.scp_direction) 1651 { 1652 scsi_low_info(slp, ti, "DATA PHASE: xfer direction mismatch"); 1653 return EINVAL; 1654 } 1655 1656#ifdef CAM 1657 *bp = NULL; /* (cb->ccb == NULL) ? NULL : cb->bp; */ 1658#else 1659 *bp = (cb->xs == NULL) ? NULL : cb->xs->bp; 1660#endif 1661 return 0; 1662} 1663 1664/************************************************************** 1665 * MSG_SYS 1666 **************************************************************/ 1667#define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;} 1668#define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3]) 1669#define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4]) 1670#define MSGIN_DATA_LAST 0x30 1671 1672static int scsi_low_errfunc_synch __P((struct targ_info *, u_int)); 1673static int scsi_low_errfunc_wide __P((struct targ_info *, u_int)); 1674static int scsi_low_errfunc_identify __P((struct targ_info *, u_int)); 1675 1676static int scsi_low_msgfunc_synch __P((struct targ_info *)); 1677static int scsi_low_msgfunc_wide __P((struct targ_info *)); 1678static int scsi_low_msgfunc_identify __P((struct targ_info *)); 1679static int scsi_low_msgfunc_user __P((struct targ_info *)); 1680static int scsi_low_msgfunc_abort __P((struct targ_info *)); 1681 1682struct scsi_low_msgout_data { 1683 u_int md_flags; 1684 u_int8_t md_msg; 1685 int (*md_msgfunc) __P((struct targ_info *)); 1686 int (*md_errfunc) __P((struct targ_info *, u_int)); 1687}; 1688 1689struct scsi_low_msgout_data scsi_low_msgout_data[] = { 1690/* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_abort, NULL}, 1691/* 1 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL}, 1692/* 2 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL}, 1693/* 3 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL}, 1694/* 4 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL}, 1695/* 5 */ {SCSI_LOW_MSG_IDENTIFY, 0, scsi_low_msgfunc_identify, scsi_low_errfunc_identify}, 1696/* 6 */ {SCSI_LOW_MSG_SYNCH, 0, scsi_low_msgfunc_synch, scsi_low_errfunc_synch}, 1697/* 7 */ {SCSI_LOW_MSG_WIDE, 0, scsi_low_msgfunc_wide, scsi_low_errfunc_wide}, 1698/* 8 */ {SCSI_LOW_MSG_USER, 0, scsi_low_msgfunc_user, NULL}, 1699/* 9 */ {SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL}, 1700/* 10 */ {SCSI_LOW_MSG_ALL, 0}, 1701}; 1702 1703static int scsi_low_msginfunc_ext __P((struct targ_info *)); 1704static int scsi_low_synch __P((struct targ_info *)); 1705static int scsi_low_msginfunc_msg_reject __P((struct targ_info *)); 1706static int scsi_low_msginfunc_rejop __P((struct targ_info *)); 1707static int scsi_low_msginfunc_rdp __P((struct targ_info *)); 1708static int scsi_low_msginfunc_sdp __P((struct targ_info *)); 1709static int scsi_low_msginfunc_disc __P((struct targ_info *)); 1710static int scsi_low_msginfunc_cc __P((struct targ_info *)); 1711static int scsi_low_msginfunc_parity __P((struct targ_info *)); 1712static int scsi_low_msginfunc_noop __P((struct targ_info *)); 1713static void scsi_low_retry_phase __P((struct targ_info *)); 1714 1715struct scsi_low_msgin_data { 1716 u_int md_len; 1717 int (*md_msgfunc) __P((struct targ_info *)); 1718}; 1719 1720struct scsi_low_msgin_data scsi_low_msgin_data[] = { 1721/* 0 */ {1, scsi_low_msginfunc_cc}, 1722/* 1 */ {2, scsi_low_msginfunc_ext}, 1723/* 2 */ {1, scsi_low_msginfunc_sdp}, 1724/* 3 */ {1, scsi_low_msginfunc_rdp}, 1725/* 4 */ {1, scsi_low_msginfunc_disc}, 1726/* 5 */ {1, scsi_low_msginfunc_rejop}, 1727/* 6 */ {1, scsi_low_msginfunc_rejop}, 1728/* 7 */ {1, scsi_low_msginfunc_msg_reject}, 1729/* 8 */ {1, scsi_low_msginfunc_noop}, 1730/* 9 */ {1, scsi_low_msginfunc_parity}, 1731/* a */ {1, scsi_low_msginfunc_rejop}, 1732/* b */ {1, scsi_low_msginfunc_rejop}, 1733/* c */ {1, scsi_low_msginfunc_rejop}, 1734/* d */ {2, scsi_low_msginfunc_rejop}, 1735/* e */ {1, scsi_low_msginfunc_rejop}, 1736/* f */ {1, scsi_low_msginfunc_rejop}, 1737/* 0x10 */ {1, scsi_low_msginfunc_rejop}, 1738/* 0x11 */ {1, scsi_low_msginfunc_rejop}, 1739/* 0x12 */ {1, scsi_low_msginfunc_rejop}, 1740/* 0x13 */ {1, scsi_low_msginfunc_rejop}, 1741/* 0x14 */ {1, scsi_low_msginfunc_rejop}, 1742/* 0x15 */ {1, scsi_low_msginfunc_rejop}, 1743/* 0x16 */ {1, scsi_low_msginfunc_rejop}, 1744/* 0x17 */ {1, scsi_low_msginfunc_rejop}, 1745/* 0x18 */ {1, scsi_low_msginfunc_rejop}, 1746/* 0x19 */ {1, scsi_low_msginfunc_rejop}, 1747/* 0x1a */ {1, scsi_low_msginfunc_rejop}, 1748/* 0x1b */ {1, scsi_low_msginfunc_rejop}, 1749/* 0x1c */ {1, scsi_low_msginfunc_rejop}, 1750/* 0x1d */ {1, scsi_low_msginfunc_rejop}, 1751/* 0x1e */ {1, scsi_low_msginfunc_rejop}, 1752/* 0x1f */ {1, scsi_low_msginfunc_rejop}, 1753/* 0x20 */ {2, scsi_low_msginfunc_rejop}, 1754/* 0x21 */ {2, scsi_low_msginfunc_rejop}, 1755/* 0x22 */ {2, scsi_low_msginfunc_rejop}, 1756/* 0x23 */ {2, scsi_low_msginfunc_rejop}, 1757/* 0x24 */ {2, scsi_low_msginfunc_rejop}, 1758/* 0x25 */ {2, scsi_low_msginfunc_rejop}, 1759/* 0x26 */ {2, scsi_low_msginfunc_rejop}, 1760/* 0x27 */ {2, scsi_low_msginfunc_rejop}, 1761/* 0x28 */ {2, scsi_low_msginfunc_rejop}, 1762/* 0x29 */ {2, scsi_low_msginfunc_rejop}, 1763/* 0x2a */ {2, scsi_low_msginfunc_rejop}, 1764/* 0x2b */ {2, scsi_low_msginfunc_rejop}, 1765/* 0x2c */ {2, scsi_low_msginfunc_rejop}, 1766/* 0x2d */ {2, scsi_low_msginfunc_rejop}, 1767/* 0x2e */ {2, scsi_low_msginfunc_rejop}, 1768/* 0x2f */ {2, scsi_low_msginfunc_rejop}, 1769/* 0x30 */ {1, scsi_low_msginfunc_rejop} /* default rej op */ 1770}; 1771 1772static void 1773scsi_low_init_msgsys(slp, ti) 1774 struct scsi_low_softc *slp; 1775 struct targ_info *ti; 1776{ 1777 1778 ti->ti_msginptr = 0; 1779 ti->ti_emsgflags = ti->ti_msgflags = ti->ti_omsgflags = 0; 1780 ti->ti_tflags &= ~TARG_ASSERT_ATN; 1781 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_NULL); 1782} 1783 1784/************************************************************** 1785 * msgout 1786 **************************************************************/ 1787static int 1788scsi_low_msgfunc_synch(ti) 1789 struct targ_info *ti; 1790{ 1791 struct lun_info *li = ti->ti_li; 1792 int ptr = ti->ti_msgoutlen; 1793 1794 if (li == NULL) 1795 { 1796 scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0); 1797 return EINVAL; 1798 } 1799 1800 ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND; 1801 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN; 1802 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE; 1803 ti->ti_msgoutstr[ptr + 3] = li->li_maxsynch.period; 1804 ti->ti_msgoutstr[ptr + 4] = li->li_maxsynch.offset; 1805 return MSG_EXTEND_SYNCHLEN + 2; 1806} 1807 1808static int 1809scsi_low_msgfunc_wide(ti) 1810 struct targ_info *ti; 1811{ 1812 struct lun_info *li = ti->ti_li; 1813 int ptr = ti->ti_msgoutlen; 1814 1815 if (li == NULL) 1816 { 1817 scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0); 1818 return EINVAL; 1819 } 1820 1821 ti->ti_msgoutstr[ptr + 0] = MSG_EXTEND; 1822 ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN; 1823 ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE; 1824 ti->ti_msgoutstr[ptr + 3] = li->li_width; 1825 return MSG_EXTEND_WIDELEN + 2; 1826} 1827 1828static int 1829scsi_low_msgfunc_identify(ti) 1830 struct targ_info *ti; 1831{ 1832 int ptr = ti->ti_msgoutlen;; 1833 1834 if (ti->ti_li == NULL) 1835 { 1836 ti->ti_msgoutstr[ptr + 0] = 0x80; 1837 scsi_low_info(ti->ti_sc, ti, "MSGOUT: lun unknown"); 1838 scsi_low_assert_msg(ti->ti_sc, ti, SCSI_LOW_MSG_ABORT, 0); 1839 } 1840 else 1841 { 1842 ti->ti_msgoutstr[ptr + 0] = ID_MSG_SETUP(ti); 1843 } 1844 return 1; 1845} 1846 1847static int 1848scsi_low_msgfunc_user(ti) 1849 struct targ_info *ti; 1850{ 1851#ifdef SCSI_LOW_SUPPORT_USER_MSGOUT 1852 struct slccb *cb = ti->ti_nexus; 1853 int ptr = ti->ti_msgoutlen;; 1854 1855 if (ti->ti_nexus == NULL) 1856 { 1857 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP; 1858 return 1; 1859 } 1860 else 1861 { 1862 bcopy(cb->msgout, ti->ti_msgoutstr + ptr, SCSI_LOW_MAX_MSGLEN); 1863 return cb->msgoutlen; 1864 } 1865#else /* !SCSI_LOW_SUPPORT_USER_MSGOUT */ 1866 return 0; 1867#endif /* !SCSI_LOW_SUPPORT_USER_MSGOUT */ 1868} 1869 1870static int 1871scsi_low_msgfunc_abort(ti) 1872 struct targ_info *ti; 1873{ 1874 struct scsi_low_softc *slp = ti->ti_sc; 1875 1876 /* The target should releases bus */ 1877 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 1878 slp->sl_error |= /* ABORTIO */ FATALIO; 1879 return 1; 1880} 1881 1882/* 1883 * The following functions are called when targets give unexpected 1884 * responces in msgin (after msgout). 1885 */ 1886static int 1887scsi_low_errfunc_identify(ti, msgflags) 1888 struct targ_info *ti; 1889 u_int msgflags; 1890{ 1891 struct lun_info *li = ti->ti_li; 1892 1893 li->li_flags &= ~SCSI_LOW_DISC; 1894 return 0; 1895} 1896 1897static int 1898scsi_low_errfunc_synch(ti, msgflags) 1899 struct targ_info *ti; 1900 u_int msgflags; 1901{ 1902 1903 /* XXX: 1904 * illegal behavior, however 1905 * there are buggy devices! 1906 */ 1907 MSGIN_PERIOD(ti) = 0; 1908 MSGIN_OFFSET(ti) = 0; 1909 scsi_low_synch(ti); 1910 return 0; 1911} 1912 1913static int 1914scsi_low_errfunc_wide(ti, msgflags) 1915 struct targ_info *ti; 1916 u_int msgflags; 1917{ 1918 struct lun_info *li = ti->ti_li; 1919 1920 li->li_width = 0; 1921 return 0; 1922} 1923 1924int 1925scsi_low_msgout(slp, ti) 1926 struct scsi_low_softc *slp; 1927 struct targ_info *ti; 1928{ 1929 struct scsi_low_msgout_data *mdp; 1930 int len = 0; 1931 1932 /* STEP I. 1933 * Scsi phase changes. 1934 * Previously msgs asserted are accepted by our target or 1935 * processed by scsi_low_msgin. 1936 * Thus clear all saved informations. 1937 */ 1938 if (ti->ti_ophase != ti->ti_phase) 1939 { 1940 ti->ti_omsgflags = 0; 1941 ti->ti_emsgflags = 0; 1942 } 1943 1944 /* STEP II. 1945 * We did not assert attention, however still our target required 1946 * msgs. Resend previous msgs. 1947 */ 1948 if (ti->ti_ophase == PH_MSGOUT && !(ti->ti_tflags & TARG_ASSERT_ATN)) 1949 { 1950 ti->ti_msgflags |= ti->ti_omsgflags; 1951#ifdef SCSI_LOW_DIAGNOSTIC 1952 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname); 1953#endif /* SCSI_LOW_DIAGNOSTIC */ 1954 } 1955 1956 /* 1957 * OK. clear flags. 1958 */ 1959 ti->ti_tflags &= ~TARG_ASSERT_ATN; 1960 1961 /* STEP III. 1962 * We have no msgs. send MSG_LOOP (OK?) 1963 */ 1964 if (scsi_low_is_msgout_continue(ti) == 0) 1965 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0); 1966 1967 /* STEP IV. 1968 * Process all msgs 1969 */ 1970 ti->ti_msgoutlen = 0; 1971 mdp = &scsi_low_msgout_data[0]; 1972 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 1973 { 1974 if ((ti->ti_msgflags & mdp->md_flags) != 0) 1975 { 1976 ti->ti_omsgflags |= mdp->md_flags; 1977 ti->ti_msgflags &= ~mdp->md_flags; 1978 ti->ti_emsgflags = mdp->md_flags; 1979 1980 ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg; 1981 if (mdp->md_msgfunc != NULL) 1982 len = (*mdp->md_msgfunc) (ti); 1983 else 1984 len = 1; 1985 1986 ti->ti_msgoutlen += len; 1987 if ((slp->sl_cfgflags & CFG_MSGUNIFY) == 0 || 1988 ti->ti_msgflags == 0) 1989 break; 1990 if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5) 1991 break; 1992 } 1993 } 1994 1995 if (scsi_low_is_msgout_continue(ti) != 0) 1996 { 1997#ifdef SCSI_LOW_DIAGNOSTIC 1998 printf("SCSI_LOW_ATTENTION(msgout): 0x%x\n", ti->ti_msgflags); 1999#endif /* SCSI_LOW_DIAGNOSTIC */ 2000 scsi_low_attention(slp, ti); 2001 } 2002 2003 /* 2004 * OK. advance old phase. 2005 */ 2006 ti->ti_ophase = ti->ti_phase; 2007 return ti->ti_msgoutlen; 2008} 2009 2010/************************************************************** 2011 * msgin 2012 **************************************************************/ 2013static int 2014scsi_low_msginfunc_noop(ti) 2015 struct targ_info *ti; 2016{ 2017 2018 return 0; 2019} 2020 2021static int 2022scsi_low_msginfunc_rejop(ti) 2023 struct targ_info *ti; 2024{ 2025 struct scsi_low_softc *slp = ti->ti_sc; 2026 u_int8_t msg = ti->ti_msgin[0]; 2027 2028 printf("%s: MSGIN: msg 0x%x reject\n", slp->sl_xname, (u_int) msg); 2029 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 2030 return 0; 2031} 2032 2033static int 2034scsi_low_msginfunc_cc(ti) 2035 struct targ_info *ti; 2036{ 2037 struct scsi_low_softc *slp = ti->ti_sc; 2038 2039 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC); 2040 return 0; 2041} 2042 2043static int 2044scsi_low_msginfunc_disc(ti) 2045 struct targ_info *ti; 2046{ 2047 struct scsi_low_softc *slp = ti->ti_sc; 2048 2049 SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC); 2050 return 0; 2051} 2052 2053static int 2054scsi_low_msginfunc_sdp(ti) 2055 struct targ_info *ti; 2056{ 2057 struct scsi_low_softc *slp = ti->ti_sc; 2058 2059 if (ti->ti_nexus != NULL) 2060 ti->ti_nexus->ccb_sscp = slp->sl_scp; 2061 else 2062 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 2063 return 0; 2064} 2065 2066static int 2067scsi_low_msginfunc_rdp(ti) 2068 struct targ_info *ti; 2069{ 2070 struct scsi_low_softc *slp = ti->ti_sc; 2071 2072 if (ti->ti_nexus != NULL) 2073 slp->sl_scp = ti->ti_nexus->ccb_sscp; 2074 else 2075 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 2076 return 0; 2077} 2078 2079static int 2080scsi_low_synch(ti) 2081 struct targ_info *ti; 2082{ 2083 struct scsi_low_softc *slp = ti->ti_sc; 2084 struct lun_info *li = ti->ti_li; 2085 u_int period = 0, offset = 0, speed; 2086 u_char *s; 2087 int error; 2088 2089 if (MSGIN_PERIOD(ti) >= li->li_maxsynch.period && 2090 MSGIN_OFFSET(ti) <= li->li_maxsynch.offset) 2091 { 2092 if ((offset = MSGIN_OFFSET(ti)) != 0) 2093 period = MSGIN_PERIOD(ti); 2094 s = offset ? "synchronous" : "async"; 2095 } 2096 else 2097 { 2098 /* XXX: 2099 * Target seems to be brain damaged. 2100 * Force async transfer. 2101 */ 2102 li->li_maxsynch.period = 0; 2103 li->li_maxsynch.offset = 0; 2104 printf("%s: target brain damaged. async transfer\n", 2105 slp->sl_xname); 2106 return EINVAL; 2107 } 2108 2109 li->li_maxsynch.period = period; 2110 li->li_maxsynch.offset = offset; 2111 2112 error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH); 2113 if (error != 0) 2114 { 2115 /* XXX: 2116 * Current period and offset are not acceptable 2117 * for our adapter. 2118 * The adapter changes max synch and max offset. 2119 */ 2120 printf("%s: synch neg failed. retry synch msg neg ...\n", 2121 slp->sl_xname); 2122 return error; 2123 } 2124 2125#ifdef SCSI_LOW_INFORM 2126 /* inform data */ 2127 printf("%s(%d:%d): <%s> offset %d period %dns ", 2128 slp->sl_xname, ti->ti_id, li->li_lun, s, offset, period * 4); 2129 if (period != 0) 2130 { 2131 speed = 1000 * 10 / (period * 4); 2132 printf("%d.%d M/s", speed / 10, speed % 10); 2133 } 2134 printf("\n"); 2135#endif 2136 2137 return 0; 2138} 2139 2140static int 2141scsi_low_msginfunc_ext(ti) 2142 struct targ_info *ti; 2143{ 2144 struct scsi_low_softc *slp = ti->ti_sc; 2145 struct slccb *cb = ti->ti_nexus; 2146 struct lun_info *li = ti->ti_li; 2147 int count, retry; 2148 u_int32_t *ptr; 2149 2150 if (ti->ti_msginptr == 2) 2151 { 2152 ti->ti_msginlen = ti->ti_msgin[1] + 2; 2153 return 0; 2154 } 2155 2156 switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2])) 2157 { 2158 case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE): 2159 if (cb == NULL) 2160 break; 2161 2162 ptr = (u_int32_t *)(&ti->ti_msgin[3]); 2163 count = (int) htonl((long) (*ptr)); 2164 if(slp->sl_scp.scp_datalen - count < 0 || 2165 slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen) 2166 break; 2167 2168 slp->sl_scp.scp_datalen -= count; 2169 slp->sl_scp.scp_data += count; 2170 return 0; 2171 2172 case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE): 2173 if (li == NULL) 2174 break; 2175 2176 retry = scsi_low_synch(ti); 2177 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0) 2178 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0); 2179 return 0; 2180 2181 case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE): 2182 if (li == NULL) 2183 break; 2184 2185 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0); 2186 return 0; 2187 2188 default: 2189 break; 2190 } 2191 2192 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 2193 return EINVAL; 2194} 2195 2196static void 2197scsi_low_retry_phase(ti) 2198 struct targ_info *ti; 2199{ 2200 2201 switch (ti->ti_sphase) 2202 { 2203 case PH_MSGOUT: 2204 ti->ti_msgflags |= ti->ti_omsgflags; 2205 break; 2206 2207 default: 2208 break; 2209 } 2210} 2211 2212static int 2213scsi_low_msginfunc_parity(ti) 2214 struct targ_info *ti; 2215{ 2216 struct scsi_low_softc *slp = ti->ti_sc; 2217 2218 if (ti->ti_sphase != PH_MSGOUT) 2219 slp->sl_error |= PARITYERR; 2220 scsi_low_retry_phase(ti); 2221 return 0; 2222} 2223 2224static int 2225scsi_low_msginfunc_msg_reject(ti) 2226 struct targ_info *ti; 2227{ 2228 struct scsi_low_softc *slp = ti->ti_sc; 2229 struct lun_info *li = ti->ti_li; 2230 struct scsi_low_msgout_data *mdp; 2231 u_int msgflags; 2232 2233 if (li == NULL) 2234 { 2235 /* not yet lun nexus established! */ 2236 goto out; 2237 } 2238 2239 switch (ti->ti_sphase) 2240 { 2241 case PH_CMD: 2242 slp->sl_error |= CMDREJECT; 2243 break; 2244 2245 case PH_MSGOUT: 2246 if (ti->ti_emsgflags == 0) 2247 break; 2248 2249 msgflags = SCSI_LOW_MSG_REJECT; 2250 mdp = &scsi_low_msgout_data[0]; 2251 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++) 2252 { 2253 if ((ti->ti_emsgflags & mdp->md_flags) != 0) 2254 { 2255 ti->ti_emsgflags &= ~mdp->md_flags; 2256 if (mdp->md_errfunc != NULL) 2257 (*mdp->md_errfunc) (ti, msgflags); 2258 break; 2259 } 2260 } 2261 break; 2262 2263 default: 2264 break; 2265 } 2266 2267out: 2268 scsi_low_info(slp, ti, "msg rejected"); 2269 slp->sl_error |= MSGERR; 2270 return 0; 2271} 2272 2273void 2274scsi_low_msgin(slp, ti, c) 2275 struct scsi_low_softc *slp; 2276 struct targ_info *ti; 2277 u_int8_t c; 2278{ 2279 struct scsi_low_msgin_data *sdp; 2280 struct lun_info *li; 2281 u_int8_t msg; 2282 2283 /* 2284 * Phase changes, clear the pointer. 2285 */ 2286 if (ti->ti_ophase != ti->ti_phase) 2287 { 2288 ti->ti_sphase = ti->ti_ophase; 2289 ti->ti_ophase = ti->ti_phase; 2290 MSGINPTR_CLR(ti); 2291#ifdef SCSI_LOW_DIAGNOSTIC 2292 ti->ti_msgin_hist_pointer = 0; 2293#endif /* SCSI_LOW_DIAGNOSTIC */ 2294 } 2295 2296 /* 2297 * Store a current messages byte into buffer and 2298 * wait for the completion of the current msg. 2299 */ 2300 ti->ti_msgin[ti->ti_msginptr ++] = c; 2301 if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN) 2302 { 2303 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1; 2304 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0); 2305 } 2306 2307 /* 2308 * Calculate messages length. 2309 */ 2310 msg = ti->ti_msgin[0]; 2311 if (msg < MSGIN_DATA_LAST) 2312 sdp = &scsi_low_msgin_data[msg]; 2313 else 2314 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST]; 2315 2316 if (ti->ti_msginlen == 0) 2317 { 2318 ti->ti_msginlen = sdp->md_len; 2319#ifdef SCSI_LOW_DIAGNOSTIC 2320 if (ti->ti_msgin_hist_pointer < MSGIN_HISTORY_LEN) 2321 { 2322 ti->ti_msgin_history[ti->ti_msgin_hist_pointer] = msg; 2323 ti->ti_msgin_hist_pointer ++; 2324 } 2325#endif /* SCSI_LOW_DIAGNOSTIC */ 2326 } 2327 2328 /* 2329 * Check comletion. 2330 */ 2331 if (ti->ti_msginptr < ti->ti_msginlen) 2332 return; 2333 2334 /* 2335 * Do process. 2336 */ 2337 if ((msg & MSG_IDENTIFY) == 0) 2338 { 2339 (void) ((*sdp->md_msgfunc) (ti)); 2340 } 2341 else 2342 { 2343 li = ti->ti_li; 2344 if (li == NULL) 2345 { 2346 li = scsi_low_establish_lun(ti, MSGCMD_LUN(msg)); 2347 if (li == NULL) 2348 goto badlun; 2349 } 2350 2351 if (ti->ti_nexus == NULL) 2352 { 2353 /* XXX: 2354 * move the following functions to 2355 * tag queue msg process in the future. 2356 */ 2357 if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG)) 2358 goto badlun; 2359 } 2360 2361 if (MSGCMD_LUN(msg) != li->li_lun) 2362 goto badlun; 2363 } 2364 2365 /* 2366 * Msg process completed, reset msin pointer and assert ATN if desired. 2367 */ 2368 if (ti->ti_msginptr >= ti->ti_msginlen) 2369 { 2370 ti->ti_sphase = ti->ti_phase; 2371 MSGINPTR_CLR(ti); 2372 2373 if (scsi_low_is_msgout_continue(ti) != 0) 2374 { 2375#ifdef SCSI_LOW_DIAGNOSTIC 2376 printf("SCSI_LOW_ATTETION(msgin): 0x%x\n", 2377 ti->ti_msgflags); 2378#endif /* SCSI_LOW_DIAGNOSTIC */ 2379 scsi_low_attention(slp, ti); 2380 } 2381 } 2382 return; 2383 2384badlun: 2385 scsi_low_info(slp, ti, "MSGIN: identify lun mismatch"); 2386 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0); 2387} 2388 2389/************************************************************** 2390 * Qurik setup 2391 **************************************************************/ 2392#define MAXOFFSET 0x10 2393 2394static void 2395scsi_low_calcf(ti, li) 2396 struct targ_info *ti; 2397 struct lun_info *li; 2398{ 2399 u_int period; 2400 u_int8_t offset; 2401 struct scsi_low_softc *slp = ti->ti_sc; 2402 2403 li->li_flags &= ~SCSI_LOW_DISC; 2404 if ((slp->sl_cfgflags & CFG_NODISC) == 0 && 2405#ifdef SDEV_NODISC 2406 (li->li_quirks & SDEV_NODISC) == 0 && 2407#endif /* SDEV_NODISC */ 2408 (li->li_cfgflags & SCSI_LOW_DISC) != 0) 2409 li->li_flags |= SCSI_LOW_DISC; 2410 2411 li->li_flags |= SCSI_LOW_NOPARITY; 2412 if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 && 2413#ifdef SDEV_NOPARITY 2414 (li->li_quirks & SDEV_NOPARITY) == 0 && 2415#endif /* SDEV_NOPARITY */ 2416 (li->li_cfgflags & SCSI_LOW_NOPARITY) == 0) 2417 li->li_flags &= ~SCSI_LOW_NOPARITY; 2418 2419 li->li_flags &= ~SCSI_LOW_SYNC; 2420 if ((li->li_cfgflags & SCSI_LOW_SYNC) && 2421 (slp->sl_cfgflags & CFG_ASYNC) == 0) 2422 { 2423 offset = SCSI_LOW_OFFSET(li->li_cfgflags); 2424 if (offset > li->li_maxsynch.offset) 2425 offset = li->li_maxsynch.offset; 2426 li->li_flags |= SCSI_LOW_SYNC; 2427 } 2428 else 2429 offset = 0; 2430 2431 if (offset > 0) 2432 { 2433 period = SCSI_LOW_PERIOD(li->li_cfgflags); 2434 if (period > SCSI_LOW_MAX_SYNCH_SPEED) 2435 period = SCSI_LOW_MAX_SYNCH_SPEED; 2436 if (period != 0) 2437 period = 1000 * 10 / (period * 4); 2438 if (period < li->li_maxsynch.period) 2439 period = li->li_maxsynch.period; 2440 } 2441 else 2442 period = 0; 2443 2444 li->li_maxsynch.offset = offset; 2445 li->li_maxsynch.period = period; 2446} 2447 2448#ifdef SCSI_LOW_TARGET_OPEN 2449static int 2450scsi_low_target_open(link, cf) 2451 struct scsipi_link *link; 2452 struct cfdata *cf; 2453{ 2454 u_int target = link->scsipi_scsi.target; 2455 u_int lun = link->scsipi_scsi.lun; 2456 struct scsi_low_softc *slp; 2457 struct targ_info *ti; 2458 struct lun_info *li; 2459 2460 slp = (struct scsi_low_softc *) link->adapter_softc; 2461 ti = slp->sl_ti[target]; 2462 li = scsi_low_alloc_li(ti, lun, 0); 2463 if (li == NULL) 2464 return 0; 2465 2466 li->li_quirks = (u_int) link->quirks; 2467 li->li_cfgflags = cf->cf_flags; 2468 if (li->li_state > UNIT_SYNCH) 2469 li->li_state = UNIT_SYNCH; 2470 2471 scsi_low_calcf(ti, li); 2472 2473 printf("%s(%d:%d): max period(%dns) max offset(%d) flags 0x%b\n", 2474 slp->sl_xname, target, lun, 2475 li->li_maxsynch.period * 4, 2476 li->li_maxsynch.offset, 2477 li->li_flags, SCSI_LOW_BITS); 2478 return 0; 2479} 2480#endif /* SCSI_LOW_TARGET_OPEN */ 2481 2482/********************************************************** 2483 * DEBUG SECTION 2484 **********************************************************/ 2485static void 2486scsi_low_info(slp, ti, s) 2487 struct scsi_low_softc *slp; 2488 struct targ_info *ti; 2489 u_char *s; 2490{ 2491 2492 printf("%s: SCSI_LOW: %s\n", slp->sl_xname, s); 2493 if (ti == NULL) 2494 { 2495 for (ti = slp->sl_titab.tqh_first; ti != NULL; 2496 ti = ti->ti_chain.tqe_next) 2497 scsi_low_print(slp, ti); 2498 } 2499 else 2500 scsi_low_print(slp, ti); 2501 2502} 2503 2504static u_char *phase[] = 2505{ 2506 "FREE", "ARBSTART", "SELSTART", "SELECTED", 2507 "CMDOUT", "DATA", "MSGIN", "MSGOUT", "STATIN", "DISC", "RESEL" 2508}; 2509 2510void 2511scsi_low_print(slp, ti) 2512 struct scsi_low_softc *slp; 2513 struct targ_info *ti; 2514{ 2515 struct slccb *cb = NULL; 2516 2517 if (ti == NULL) 2518 ti = slp->sl_nexus; 2519 if (ti != NULL) 2520 cb = ti->ti_nexus; 2521 2522 printf("%s: TARGET(0x%lx) T_NEXUS(0x%lx) C_NEXUS(0x%lx) NDISCS(%d)\n", 2523 slp->sl_xname, (u_long) ti, (u_long) slp->sl_nexus, 2524 (u_long) cb, slp->sl_disc); 2525 2526 /* target stat */ 2527 if (ti != NULL) 2528 { 2529 struct sc_p *sp = &slp->sl_scp; 2530 struct lun_info *li = ti->ti_li; 2531 u_int flags = 0; 2532 int lun = -1; 2533 2534 if (li != NULL) 2535 { 2536 lun = li->li_lun; 2537 flags = li->li_flags; 2538 } 2539 2540 printf("%s(%d:%d) ph<%s> => ph<%s>\n", slp->sl_xname, 2541 ti->ti_id, lun, phase[(int) ti->ti_ophase], 2542 phase[(int) ti->ti_phase]); 2543 2544printf("MSGIN: ptr(%x) [%x][%x][%x][%x][%x] STATUSIN: 0x%x T_FLAGS: 0x%x\n", 2545 (u_int) (ti->ti_msginptr), 2546 (u_int) (ti->ti_msgin[0]), 2547 (u_int) (ti->ti_msgin[1]), 2548 (u_int) (ti->ti_msgin[2]), 2549 (u_int) (ti->ti_msgin[3]), 2550 (u_int) (ti->ti_msgin[4]), 2551 ti->ti_status, ti->ti_tflags); 2552#ifdef SCSI_LOW_DIAGNOSTIC 2553printf("MSGIN HISTORY: (%d) [0x%x] => [0x%x] => [0x%x] => [0x%x] => [0x%x]\n", 2554 ti->ti_msgin_hist_pointer, 2555 (u_int) (ti->ti_msgin_history[0]), 2556 (u_int) (ti->ti_msgin_history[1]), 2557 (u_int) (ti->ti_msgin_history[2]), 2558 (u_int) (ti->ti_msgin_history[3]), 2559 (u_int) (ti->ti_msgin_history[4])); 2560#endif /* SCSI_LOW_DIAGNOSTIC */ 2561 2562printf("MSGOUT: msgflags 0x%x [%x][%x][%x][%x][%x] msgoutlen %d C_FLAGS: %b\n", 2563 (u_int) ti->ti_msgflags, 2564 (u_int) (ti->ti_msgoutstr[0]), 2565 (u_int) (ti->ti_msgoutstr[1]), 2566 (u_int) (ti->ti_msgoutstr[2]), 2567 (u_int) (ti->ti_msgoutstr[3]), 2568 (u_int) (ti->ti_msgoutstr[4]), 2569 ti->ti_msgoutlen, 2570 flags, SCSI_LOW_BITS); 2571 2572printf("SCP: datalen 0x%x dataaddr 0x%lx ", 2573 sp->scp_datalen, 2574 (u_long) sp->scp_data); 2575 2576 if (cb != NULL) 2577 { 2578printf("CCB: cmdlen %x cmdaddr %lx cmd[0] %x datalen %x", 2579 cb->ccb_scp.scp_cmdlen, 2580 (u_long) cb->ccb_scp.scp_cmd, 2581 (u_int) cb->ccb_scp.scp_cmd[0], 2582 cb->ccb_scp.scp_datalen); 2583 } 2584 printf("\n"); 2585 } 2586 printf("error flags %b\n", slp->sl_error, SCSI_LOW_ERRORBITS); 2587} 2588