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