1 /*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * Copyright (C) 2003 5 * Hidetoshi Shimokawa. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * 18 * This product includes software developed by Hidetoshi Shimokawa. 19 * 20 * 4. Neither the name of the author nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/kernel.h> 39 #include <sys/systm.h> 40 #include <sys/sysctl.h> 41 #include <sys/types.h> 42 #include <sys/conf.h> 43 #include <sys/malloc.h> 44 #include <sys/endian.h> 45 46 #include <sys/bus.h> 47 #include <machine/bus.h> 48 49 #include <dev/firewire/firewire.h> 50 #include <dev/firewire/firewirereg.h> 51 #include <dev/firewire/iec13213.h> 52 #include <dev/firewire/sbp.h> 53 #include <dev/firewire/fwmem.h> 54 55 #include <cam/cam.h> 56 #include <cam/cam_ccb.h> 57 #include <cam/cam_sim.h> 58 #include <cam/cam_xpt_sim.h> 59 #include <cam/cam_debug.h> 60 #include <cam/cam_periph.h> 61 #include <cam/scsi/scsi_all.h> 62 #include <cam/scsi/scsi_message.h> 63 64 #define SBP_TARG_RECV_LEN 8 65 #define MAX_INITIATORS 8 66 #define MAX_LUN 63 67 #define MAX_LOGINS 63 68 #define MAX_NODES 63 69 /* 70 * management/command block agent registers 71 * 72 * BASE 0xffff f001 0000 management port 73 * BASE 0xffff f001 0020 command port for login id 0 74 * BASE 0xffff f001 0040 command port for login id 1 75 * 76 */ 77 #define SBP_TARG_MGM 0x10000 /* offset from 0xffff f000 000 */ 78 #define SBP_TARG_BIND_HI 0xffff 79 #define SBP_TARG_BIND_LO(l) (0xf0000000 + SBP_TARG_MGM + 0x20 * ((l) + 1)) 80 #define SBP_TARG_BIND_START (((u_int64_t)SBP_TARG_BIND_HI << 32) | \ 81 SBP_TARG_BIND_LO(-1)) 82 #define SBP_TARG_BIND_END (((u_int64_t)SBP_TARG_BIND_HI << 32) | \ 83 SBP_TARG_BIND_LO(MAX_LOGINS)) 84 #define SBP_TARG_LOGIN_ID(lo) (((lo) - SBP_TARG_BIND_LO(0))/0x20) 85 86 #define FETCH_MGM 0 87 #define FETCH_CMD 1 88 #define FETCH_POINTER 2 89 90 #define F_LINK_ACTIVE (1 << 0) 91 #define F_ATIO_STARVED (1 << 1) 92 #define F_LOGIN (1 << 2) 93 #define F_HOLD (1 << 3) 94 #define F_FREEZED (1 << 4) 95 96 static MALLOC_DEFINE(M_SBP_TARG, "sbp_targ", "SBP-II/FireWire target mode"); 97 98 static int debug = 0; 99 100 SYSCTL_INT(_debug, OID_AUTO, sbp_targ_debug, CTLFLAG_RW, &debug, 0, 101 "SBP target mode debug flag"); 102 103 struct sbp_targ_login { 104 struct sbp_targ_lstate *lstate; 105 struct fw_device *fwdev; 106 struct sbp_login_res loginres; 107 uint16_t fifo_hi; 108 uint16_t last_hi; 109 uint32_t fifo_lo; 110 uint32_t last_lo; 111 STAILQ_HEAD(, orb_info) orbs; 112 STAILQ_ENTRY(sbp_targ_login) link; 113 uint16_t hold_sec; 114 uint16_t id; 115 uint8_t flags; 116 uint8_t spd; 117 struct callout hold_callout; 118 }; 119 120 struct sbp_targ_lstate { 121 uint16_t lun; 122 struct sbp_targ_softc *sc; 123 struct cam_path *path; 124 struct ccb_hdr_slist accept_tios; 125 struct ccb_hdr_slist immed_notifies; 126 struct crom_chunk model; 127 uint32_t flags; 128 STAILQ_HEAD(, sbp_targ_login) logins; 129 }; 130 131 struct sbp_targ_softc { 132 struct firewire_dev_comm fd; 133 struct cam_sim *sim; 134 struct cam_path *path; 135 struct fw_bind fwb; 136 int ndevs; 137 int flags; 138 struct crom_chunk unit; 139 struct sbp_targ_lstate *lstate[MAX_LUN]; 140 struct sbp_targ_lstate *black_hole; 141 struct sbp_targ_login *logins[MAX_LOGINS]; 142 struct mtx mtx; 143 }; 144 #define SBP_LOCK(sc) mtx_lock(&(sc)->mtx) 145 #define SBP_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 146 147 struct corb4 { 148 #if BYTE_ORDER == BIG_ENDIAN 149 uint32_t n:1, 150 rq_fmt:2, 151 :1, 152 dir:1, 153 spd:3, 154 max_payload:4, 155 page_table_present:1, 156 page_size:3, 157 data_size:16; 158 #else 159 uint32_t data_size:16, 160 page_size:3, 161 page_table_present:1, 162 max_payload:4, 163 spd:3, 164 dir:1, 165 :1, 166 rq_fmt:2, 167 n:1; 168 #endif 169 }; 170 171 struct morb4 { 172 #if BYTE_ORDER == BIG_ENDIAN 173 uint32_t n:1, 174 rq_fmt:2, 175 :9, 176 fun:4, 177 id:16; 178 #else 179 uint32_t id:16, 180 fun:4, 181 :9, 182 rq_fmt:2, 183 n:1; 184 #endif 185 }; 186 187 188 /* 189 * Urestricted page table format 190 * states that the segment length 191 * and high base addr are in the first 192 * 32 bits and the base low is in 193 * the second 194 */ 195 struct unrestricted_page_table_fmt { 196 uint16_t segment_len; 197 uint16_t segment_base_high; 198 uint32_t segment_base_low; 199 }; 200 201 202 struct orb_info { 203 struct sbp_targ_softc *sc; 204 struct fw_device *fwdev; 205 struct sbp_targ_login *login; 206 union ccb *ccb; 207 struct ccb_accept_tio *atio; 208 uint8_t state; 209 #define ORBI_STATUS_NONE 0 210 #define ORBI_STATUS_FETCH 1 211 #define ORBI_STATUS_ATIO 2 212 #define ORBI_STATUS_CTIO 3 213 #define ORBI_STATUS_STATUS 4 214 #define ORBI_STATUS_POINTER 5 215 #define ORBI_STATUS_ABORTED 7 216 uint8_t refcount; 217 uint16_t orb_hi; 218 uint32_t orb_lo; 219 uint32_t data_hi; 220 uint32_t data_lo; 221 struct corb4 orb4; 222 STAILQ_ENTRY(orb_info) link; 223 uint32_t orb[8]; 224 struct unrestricted_page_table_fmt *page_table; 225 struct unrestricted_page_table_fmt *cur_pte; 226 struct unrestricted_page_table_fmt *last_pte; 227 uint32_t last_block_read; 228 struct sbp_status status; 229 }; 230 231 static char *orb_fun_name[] = { 232 ORB_FUN_NAMES 233 }; 234 235 static void sbp_targ_recv(struct fw_xfer *); 236 static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *, 237 uint16_t, uint32_t, struct sbp_targ_login *, int); 238 static void sbp_targ_xfer_pt(struct orb_info *); 239 static void sbp_targ_abort(struct sbp_targ_softc *, struct orb_info *); 240 241 static void 242 sbp_targ_identify(driver_t *driver, device_t parent) 243 { 244 BUS_ADD_CHILD(parent, 0, "sbp_targ", device_get_unit(parent)); 245 } 246 247 static int 248 sbp_targ_probe(device_t dev) 249 { 250 device_t pa; 251 252 pa = device_get_parent(dev); 253 if (device_get_unit(dev) != device_get_unit(pa)) { 254 return (ENXIO); 255 } 256 257 device_set_desc(dev, "SBP-2/SCSI over FireWire target mode"); 258 return (0); 259 } 260 261 static void 262 sbp_targ_dealloc_login(struct sbp_targ_login *login) 263 { 264 struct orb_info *orbi, *next; 265 266 if (login == NULL) { 267 printf("%s: login = NULL\n", __func__); 268 return; 269 } 270 for (orbi = STAILQ_FIRST(&login->orbs); orbi != NULL; orbi = next) { 271 next = STAILQ_NEXT(orbi, link); 272 if (debug) 273 printf("%s: free orbi %p\n", __func__, orbi); 274 free(orbi, M_SBP_TARG); 275 orbi = NULL; 276 } 277 callout_stop(&login->hold_callout); 278 279 STAILQ_REMOVE(&login->lstate->logins, login, sbp_targ_login, link); 280 login->lstate->sc->logins[login->id] = NULL; 281 if (debug) 282 printf("%s: free login %p\n", __func__, login); 283 free((void *)login, M_SBP_TARG); 284 login = NULL; 285 } 286 287 static void 288 sbp_targ_hold_expire(void *arg) 289 { 290 struct sbp_targ_login *login; 291 292 login = (struct sbp_targ_login *)arg; 293 294 if (login->flags & F_HOLD) { 295 printf("%s: login_id=%d expired\n", __func__, login->id); 296 sbp_targ_dealloc_login(login); 297 } else { 298 printf("%s: login_id=%d not hold\n", __func__, login->id); 299 } 300 } 301 302 static void 303 sbp_targ_post_busreset(void *arg) 304 { 305 struct sbp_targ_softc *sc; 306 struct crom_src *src; 307 struct crom_chunk *root; 308 struct crom_chunk *unit; 309 struct sbp_targ_lstate *lstate; 310 struct sbp_targ_login *login; 311 int i; 312 313 sc = (struct sbp_targ_softc *)arg; 314 src = sc->fd.fc->crom_src; 315 root = sc->fd.fc->crom_root; 316 317 unit = &sc->unit; 318 319 if ((sc->flags & F_FREEZED) == 0) { 320 sc->flags |= F_FREEZED; 321 xpt_freeze_simq(sc->sim, /*count*/1); 322 } else { 323 printf("%s: already freezed\n", __func__); 324 } 325 326 bzero(unit, sizeof(struct crom_chunk)); 327 328 crom_add_chunk(src, root, unit, CROM_UDIR); 329 crom_add_entry(unit, CSRKEY_SPEC, CSRVAL_ANSIT10); 330 crom_add_entry(unit, CSRKEY_VER, CSRVAL_T10SBP2); 331 crom_add_entry(unit, CSRKEY_COM_SPEC, CSRVAL_ANSIT10); 332 crom_add_entry(unit, CSRKEY_COM_SET, CSRVAL_SCSI); 333 334 crom_add_entry(unit, CROM_MGM, SBP_TARG_MGM >> 2); 335 crom_add_entry(unit, CSRKEY_UNIT_CH, (10<<8) | 8); 336 337 for (i = 0; i < MAX_LUN; i++) { 338 lstate = sc->lstate[i]; 339 if (lstate == NULL) 340 continue; 341 crom_add_entry(unit, CSRKEY_FIRM_VER, 1); 342 crom_add_entry(unit, CROM_LUN, i); 343 crom_add_entry(unit, CSRKEY_MODEL, 1); 344 crom_add_simple_text(src, unit, &lstate->model, "TargetMode"); 345 } 346 347 /* Process for reconnection hold time */ 348 for (i = 0; i < MAX_LOGINS; i++) { 349 login = sc->logins[i]; 350 if (login == NULL) 351 continue; 352 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); 353 if (login->flags & F_LOGIN) { 354 login->flags |= F_HOLD; 355 callout_reset(&login->hold_callout, 356 hz * login->hold_sec, 357 sbp_targ_hold_expire, (void *)login); 358 } 359 } 360 } 361 362 static void 363 sbp_targ_post_explore(void *arg) 364 { 365 struct sbp_targ_softc *sc; 366 367 sc = (struct sbp_targ_softc *)arg; 368 sc->flags &= ~F_FREEZED; 369 xpt_release_simq(sc->sim, /*run queue*/TRUE); 370 return; 371 } 372 373 static cam_status 374 sbp_targ_find_devs(struct sbp_targ_softc *sc, union ccb *ccb, 375 struct sbp_targ_lstate **lstate, int notfound_failure) 376 { 377 u_int lun; 378 379 /* XXX 0 is the only vaild target_id */ 380 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD && 381 ccb->ccb_h.target_lun == CAM_LUN_WILDCARD) { 382 *lstate = sc->black_hole; 383 if (debug) 384 printf("setting black hole for this target id(%d)\n", ccb->ccb_h.target_id); 385 return (CAM_REQ_CMP); 386 } 387 388 lun = ccb->ccb_h.target_lun; 389 if (lun >= MAX_LUN) 390 return (CAM_LUN_INVALID); 391 392 *lstate = sc->lstate[lun]; 393 394 if (notfound_failure != 0 && *lstate == NULL) { 395 if (debug) 396 printf("%s: lstate for lun is invalid, target(%d), lun(%d)\n", 397 __func__, ccb->ccb_h.target_id, lun); 398 return (CAM_PATH_INVALID); 399 } else 400 if (debug) 401 printf("%s: setting lstate for tgt(%d) lun(%d)\n", 402 __func__,ccb->ccb_h.target_id, lun); 403 404 return (CAM_REQ_CMP); 405 } 406 407 static void 408 sbp_targ_en_lun(struct sbp_targ_softc *sc, union ccb *ccb) 409 { 410 struct ccb_en_lun *cel = &ccb->cel; 411 struct sbp_targ_lstate *lstate; 412 cam_status status; 413 414 status = sbp_targ_find_devs(sc, ccb, &lstate, 0); 415 if (status != CAM_REQ_CMP) { 416 ccb->ccb_h.status = status; 417 return; 418 } 419 420 if (cel->enable != 0) { 421 if (lstate != NULL) { 422 xpt_print_path(ccb->ccb_h.path); 423 printf("Lun already enabled\n"); 424 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 425 return; 426 } 427 if (cel->grp6_len != 0 || cel->grp7_len != 0) { 428 ccb->ccb_h.status = CAM_REQ_INVALID; 429 printf("Non-zero Group Codes\n"); 430 return; 431 } 432 lstate = (struct sbp_targ_lstate *) 433 malloc(sizeof(*lstate), M_SBP_TARG, M_NOWAIT | M_ZERO); 434 if (lstate == NULL) { 435 xpt_print_path(ccb->ccb_h.path); 436 printf("Couldn't allocate lstate\n"); 437 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 438 return; 439 } else { 440 if (debug) 441 printf("%s: malloc'd lstate %p\n",__func__, lstate); 442 } 443 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) { 444 sc->black_hole = lstate; 445 if (debug) 446 printf("Blackhole set due to target id == %d\n", 447 ccb->ccb_h.target_id); 448 } else 449 sc->lstate[ccb->ccb_h.target_lun] = lstate; 450 451 memset(lstate, 0, sizeof(*lstate)); 452 lstate->sc = sc; 453 status = xpt_create_path(&lstate->path, /*periph*/NULL, 454 xpt_path_path_id(ccb->ccb_h.path), 455 xpt_path_target_id(ccb->ccb_h.path), 456 xpt_path_lun_id(ccb->ccb_h.path)); 457 if (status != CAM_REQ_CMP) { 458 free(lstate, M_SBP_TARG); 459 lstate = NULL; 460 xpt_print_path(ccb->ccb_h.path); 461 printf("Couldn't allocate path\n"); 462 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 463 return; 464 } 465 SLIST_INIT(&lstate->accept_tios); 466 SLIST_INIT(&lstate->immed_notifies); 467 STAILQ_INIT(&lstate->logins); 468 469 ccb->ccb_h.status = CAM_REQ_CMP; 470 xpt_print_path(ccb->ccb_h.path); 471 printf("Lun now enabled for target mode\n"); 472 /* bus reset */ 473 sc->fd.fc->ibr(sc->fd.fc); 474 } else { 475 struct sbp_targ_login *login, *next; 476 477 if (lstate == NULL) { 478 ccb->ccb_h.status = CAM_LUN_INVALID; 479 printf("Invalid lstate for this target\n"); 480 return; 481 } 482 ccb->ccb_h.status = CAM_REQ_CMP; 483 484 if (SLIST_FIRST(&lstate->accept_tios) != NULL) { 485 printf("ATIOs pending\n"); 486 ccb->ccb_h.status = CAM_REQ_INVALID; 487 } 488 489 if (SLIST_FIRST(&lstate->immed_notifies) != NULL) { 490 printf("INOTs pending\n"); 491 ccb->ccb_h.status = CAM_REQ_INVALID; 492 } 493 494 if (ccb->ccb_h.status != CAM_REQ_CMP) { 495 printf("status != CAM_REQ_CMP\n"); 496 return; 497 } 498 499 xpt_print_path(ccb->ccb_h.path); 500 printf("Target mode disabled\n"); 501 xpt_free_path(lstate->path); 502 503 for (login = STAILQ_FIRST(&lstate->logins); login != NULL; 504 login = next) { 505 next = STAILQ_NEXT(login, link); 506 sbp_targ_dealloc_login(login); 507 } 508 509 if (ccb->ccb_h.target_id == CAM_TARGET_WILDCARD) 510 sc->black_hole = NULL; 511 else 512 sc->lstate[ccb->ccb_h.target_lun] = NULL; 513 if (debug) 514 printf("%s: free lstate %p\n", __func__, lstate); 515 free(lstate, M_SBP_TARG); 516 lstate = NULL; 517 518 /* bus reset */ 519 sc->fd.fc->ibr(sc->fd.fc); 520 } 521 } 522 523 static void 524 sbp_targ_send_lstate_events(struct sbp_targ_softc *sc, 525 struct sbp_targ_lstate *lstate) 526 { 527 #if 0 528 struct ccb_hdr *ccbh; 529 struct ccb_immediate_notify *inot; 530 531 printf("%s: not implemented yet\n", __func__); 532 #endif 533 } 534 535 536 static __inline void 537 sbp_targ_remove_orb_info_locked(struct sbp_targ_login *login, struct orb_info *orbi) 538 { 539 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); 540 } 541 542 static __inline void 543 sbp_targ_remove_orb_info(struct sbp_targ_login *login, struct orb_info *orbi) 544 { 545 SBP_LOCK(orbi->sc); 546 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); 547 SBP_UNLOCK(orbi->sc); 548 } 549 550 /* 551 * tag_id/init_id encoding 552 * 553 * tag_id and init_id has only 32bit for each. 554 * scsi_target can handle very limited number(up to 15) of init_id. 555 * we have to encode 48bit orb and 64bit EUI64 into these 556 * variables. 557 * 558 * tag_id represents lower 32bit of ORB address. 559 * init_id represents login_id. 560 * 561 */ 562 563 static struct orb_info * 564 sbp_targ_get_orb_info(struct sbp_targ_lstate *lstate, 565 u_int tag_id, u_int init_id) 566 { 567 struct sbp_targ_login *login; 568 struct orb_info *orbi; 569 570 login = lstate->sc->logins[init_id]; 571 if (login == NULL) { 572 printf("%s: no such login\n", __func__); 573 return (NULL); 574 } 575 STAILQ_FOREACH(orbi, &login->orbs, link) 576 if (orbi->orb_lo == tag_id) 577 goto found; 578 printf("%s: orb not found tag_id=0x%08x init_id=%d\n", 579 __func__, tag_id, init_id); 580 return (NULL); 581 found: 582 return (orbi); 583 } 584 585 static void 586 sbp_targ_abort(struct sbp_targ_softc *sc, struct orb_info *orbi) 587 { 588 struct orb_info *norbi; 589 590 SBP_LOCK(sc); 591 for (; orbi != NULL; orbi = norbi) { 592 printf("%s: status=%d ccb=%p\n", __func__, orbi->state, orbi->ccb); 593 norbi = STAILQ_NEXT(orbi, link); 594 if (orbi->state != ORBI_STATUS_ABORTED) { 595 if (orbi->ccb != NULL) { 596 orbi->ccb->ccb_h.status = CAM_REQ_ABORTED; 597 xpt_done(orbi->ccb); 598 orbi->ccb = NULL; 599 } 600 if (orbi->state <= ORBI_STATUS_ATIO) { 601 sbp_targ_remove_orb_info_locked(orbi->login, orbi); 602 if (debug) 603 printf("%s: free orbi %p\n", __func__, orbi); 604 free(orbi, M_SBP_TARG); 605 orbi = NULL; 606 } else 607 orbi->state = ORBI_STATUS_ABORTED; 608 } 609 } 610 SBP_UNLOCK(sc); 611 } 612 613 static void 614 sbp_targ_free_orbi(struct fw_xfer *xfer) 615 { 616 struct orb_info *orbi; 617 618 if (xfer->resp != 0) { 619 /* XXX */ 620 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 621 } 622 orbi = (struct orb_info *)xfer->sc; 623 if ( orbi->page_table != NULL ) { 624 if (debug) 625 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); 626 free(orbi->page_table, M_SBP_TARG); 627 orbi->page_table = NULL; 628 } 629 if (debug) 630 printf("%s: free orbi %p\n", __func__, orbi); 631 free(orbi, M_SBP_TARG); 632 orbi = NULL; 633 fw_xfer_free(xfer); 634 } 635 636 static void 637 sbp_targ_status_FIFO(struct orb_info *orbi, 638 uint32_t fifo_hi, uint32_t fifo_lo, int dequeue) 639 { 640 struct fw_xfer *xfer; 641 642 if (dequeue) 643 sbp_targ_remove_orb_info(orbi->login, orbi); 644 645 xfer = fwmem_write_block(orbi->fwdev, (void *)orbi, 646 /*spd*/FWSPD_S400, fifo_hi, fifo_lo, 647 sizeof(uint32_t) * (orbi->status.len + 1), (char *)&orbi->status, 648 sbp_targ_free_orbi); 649 650 if (xfer == NULL) { 651 /* XXX */ 652 printf("%s: xfer == NULL\n", __func__); 653 } 654 } 655 656 /* 657 * Generate the appropriate CAM status for the 658 * target. 659 */ 660 static void 661 sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb) 662 { 663 struct sbp_status *sbp_status; 664 #if 0 665 struct orb_info *norbi; 666 #endif 667 668 sbp_status = &orbi->status; 669 670 orbi->state = ORBI_STATUS_STATUS; 671 672 sbp_status->resp = 0; /* XXX */ 673 sbp_status->status = 0; /* XXX */ 674 sbp_status->dead = 0; /* XXX */ 675 676 ccb->ccb_h.status= CAM_REQ_CMP; 677 678 switch (ccb->csio.scsi_status) { 679 case SCSI_STATUS_OK: 680 if (debug) 681 printf("%s: STATUS_OK\n", __func__); 682 sbp_status->len = 1; 683 break; 684 case SCSI_STATUS_CHECK_COND: 685 if (debug) 686 printf("%s: STATUS SCSI_STATUS_CHECK_COND\n", __func__); 687 goto process_scsi_status; 688 case SCSI_STATUS_BUSY: 689 if (debug) 690 printf("%s: STATUS SCSI_STATUS_BUSY\n", __func__); 691 goto process_scsi_status; 692 case SCSI_STATUS_CMD_TERMINATED: 693 process_scsi_status: 694 { 695 struct sbp_cmd_status *sbp_cmd_status; 696 struct scsi_sense_data *sense; 697 int error_code, sense_key, asc, ascq; 698 uint8_t stream_bits; 699 uint8_t sks[3]; 700 uint64_t info; 701 int64_t sinfo; 702 int sense_len; 703 704 sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0]; 705 sbp_cmd_status->status = ccb->csio.scsi_status; 706 sense = &ccb->csio.sense_data; 707 708 #if 0 /* XXX What we should do? */ 709 #if 0 710 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 711 #else 712 norbi = STAILQ_NEXT(orbi, link); 713 while (norbi) { 714 printf("%s: status=%d\n", __func__, norbi->state); 715 if (norbi->ccb != NULL) { 716 norbi->ccb->ccb_h.status = CAM_REQ_ABORTED; 717 xpt_done(norbi->ccb); 718 norbi->ccb = NULL; 719 } 720 sbp_targ_remove_orb_info_locked(orbi->login, norbi); 721 norbi = STAILQ_NEXT(norbi, link); 722 free(norbi, M_SBP_TARG); 723 } 724 #endif 725 #endif 726 727 sense_len = ccb->csio.sense_len - ccb->csio.sense_resid; 728 scsi_extract_sense_len(sense, sense_len, &error_code, 729 &sense_key, &asc, &ascq, /*show_errors*/ 0); 730 731 switch (error_code) { 732 case SSD_CURRENT_ERROR: 733 case SSD_DESC_CURRENT_ERROR: 734 sbp_cmd_status->sfmt = SBP_SFMT_CURR; 735 break; 736 default: 737 sbp_cmd_status->sfmt = SBP_SFMT_DEFER; 738 break; 739 } 740 741 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, 742 &sinfo) == 0) { 743 uint32_t info_trunc; 744 sbp_cmd_status->valid = 1; 745 info_trunc = info; 746 747 sbp_cmd_status->info = htobe32(info_trunc); 748 } else { 749 sbp_cmd_status->valid = 0; 750 } 751 752 sbp_cmd_status->s_key = sense_key; 753 754 if (scsi_get_stream_info(sense, sense_len, NULL, 755 &stream_bits) == 0) { 756 sbp_cmd_status->mark = 757 (stream_bits & SSD_FILEMARK) ? 1 : 0; 758 sbp_cmd_status->eom = 759 (stream_bits & SSD_EOM) ? 1 : 0; 760 sbp_cmd_status->ill_len = 761 (stream_bits & SSD_ILI) ? 1 : 0; 762 } else { 763 sbp_cmd_status->mark = 0; 764 sbp_cmd_status->eom = 0; 765 sbp_cmd_status->ill_len = 0; 766 } 767 768 769 /* add_sense_code(_qual), info, cmd_spec_info */ 770 sbp_status->len = 4; 771 772 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND, 773 &info, &sinfo) == 0) { 774 uint32_t cmdspec_trunc; 775 776 cmdspec_trunc = info; 777 778 sbp_cmd_status->cdb = htobe32(cmdspec_trunc); 779 } 780 781 sbp_cmd_status->s_code = asc; 782 sbp_cmd_status->s_qlfr = ascq; 783 784 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU, &info, 785 &sinfo) == 0) { 786 sbp_cmd_status->fru = (uint8_t)info; 787 sbp_status->len = 5; 788 } else { 789 sbp_cmd_status->fru = 0; 790 } 791 792 if (scsi_get_sks(sense, sense_len, sks) == 0) { 793 bcopy(sks, &sbp_cmd_status->s_keydep[0], sizeof(sks)); 794 sbp_status->len = 5; 795 ccb->ccb_h.status |= CAM_SENT_SENSE; 796 } 797 798 break; 799 } 800 default: 801 printf("%s: unknown scsi status 0x%x\n", __func__, 802 sbp_status->status); 803 } 804 805 806 sbp_targ_status_FIFO(orbi, 807 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 808 } 809 810 /* 811 * Invoked as a callback handler from fwmem_read/write_block 812 * 813 * Process read/write of initiator address space 814 * completion and pass status onto the backend target. 815 * If this is a partial read/write for a CCB then 816 * we decrement the orbi's refcount to indicate 817 * the status of the read/write is complete 818 */ 819 static void 820 sbp_targ_cam_done(struct fw_xfer *xfer) 821 { 822 struct orb_info *orbi; 823 union ccb *ccb; 824 825 orbi = (struct orb_info *)xfer->sc; 826 827 if (debug) 828 printf("%s: resp=%d refcount=%d\n", __func__, 829 xfer->resp, orbi->refcount); 830 831 if (xfer->resp != 0) { 832 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 833 orbi->status.resp = SBP_TRANS_FAIL; 834 orbi->status.status = OBJ_DATA | SBE_TIMEOUT/*XXX*/; 835 orbi->status.dead = 1; 836 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 837 } 838 839 orbi->refcount--; 840 841 ccb = orbi->ccb; 842 if (orbi->refcount == 0) { 843 orbi->ccb = NULL; 844 if (orbi->state == ORBI_STATUS_ABORTED) { 845 if (debug) 846 printf("%s: orbi aborted\n", __func__); 847 sbp_targ_remove_orb_info(orbi->login, orbi); 848 if (orbi->page_table != NULL) { 849 if (debug) 850 printf("%s: free orbi->page_table %p\n", 851 __func__, orbi->page_table); 852 free(orbi->page_table, M_SBP_TARG); 853 } 854 if (debug) 855 printf("%s: free orbi %p\n", __func__, orbi); 856 free(orbi, M_SBP_TARG); 857 orbi = NULL; 858 } else if (orbi->status.resp == ORBI_STATUS_NONE) { 859 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 860 if (debug) 861 printf("%s: CAM_SEND_STATUS set %0x\n", __func__, ccb->ccb_h.flags); 862 sbp_targ_send_status(orbi, ccb); 863 } else { 864 if (debug) 865 printf("%s: CAM_SEND_STATUS not set %0x\n", __func__, ccb->ccb_h.flags); 866 ccb->ccb_h.status = CAM_REQ_CMP; 867 } 868 xpt_done(ccb); 869 } else { 870 orbi->status.len = 1; 871 sbp_targ_status_FIFO(orbi, 872 orbi->login->fifo_hi, orbi->login->fifo_lo, 873 /*dequeue*/1); 874 ccb->ccb_h.status = CAM_REQ_ABORTED; 875 xpt_done(ccb); 876 } 877 } 878 879 fw_xfer_free(xfer); 880 } 881 882 static cam_status 883 sbp_targ_abort_ccb(struct sbp_targ_softc *sc, union ccb *ccb) 884 { 885 union ccb *accb; 886 struct sbp_targ_lstate *lstate; 887 struct ccb_hdr_slist *list; 888 struct ccb_hdr *curelm; 889 int found; 890 cam_status status; 891 892 status = sbp_targ_find_devs(sc, ccb, &lstate, 0); 893 if (status != CAM_REQ_CMP) 894 return (status); 895 896 accb = ccb->cab.abort_ccb; 897 898 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) 899 list = &lstate->accept_tios; 900 else if (accb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) 901 list = &lstate->immed_notifies; 902 else 903 return (CAM_UA_ABORT); 904 905 curelm = SLIST_FIRST(list); 906 found = 0; 907 if (curelm == &accb->ccb_h) { 908 found = 1; 909 SLIST_REMOVE_HEAD(list, sim_links.sle); 910 } else { 911 while (curelm != NULL) { 912 struct ccb_hdr *nextelm; 913 914 nextelm = SLIST_NEXT(curelm, sim_links.sle); 915 if (nextelm == &accb->ccb_h) { 916 found = 1; 917 SLIST_NEXT(curelm, sim_links.sle) = 918 SLIST_NEXT(nextelm, sim_links.sle); 919 break; 920 } 921 curelm = nextelm; 922 } 923 } 924 if (found) { 925 accb->ccb_h.status = CAM_REQ_ABORTED; 926 xpt_done(accb); 927 return (CAM_REQ_CMP); 928 } 929 printf("%s: not found\n", __func__); 930 return (CAM_PATH_INVALID); 931 } 932 933 /* 934 * directly execute a read or write to the initiator 935 * address space and set hand(sbp_targ_cam_done) to 936 * process the completion from the SIM to the target. 937 * set orbi->refcount to inidicate that a read/write 938 * is inflight to/from the initiator. 939 */ 940 static void 941 sbp_targ_xfer_buf(struct orb_info *orbi, u_int offset, 942 uint16_t dst_hi, uint32_t dst_lo, u_int size, 943 void (*hand)(struct fw_xfer *)) 944 { 945 struct fw_xfer *xfer; 946 u_int len, ccb_dir, off = 0; 947 char *ptr; 948 949 if (debug > 1) 950 printf("%s: offset=%d size=%d\n", __func__, offset, size); 951 ccb_dir = orbi->ccb->ccb_h.flags & CAM_DIR_MASK; 952 ptr = (char *)orbi->ccb->csio.data_ptr + offset; 953 954 while (size > 0) { 955 /* XXX assume dst_lo + off doesn't overflow */ 956 len = MIN(size, 2048 /* XXX */); 957 size -= len; 958 orbi->refcount ++; 959 if (ccb_dir == CAM_DIR_OUT) { 960 if (debug) 961 printf("%s: CAM_DIR_OUT --> read block in?\n",__func__); 962 xfer = fwmem_read_block(orbi->fwdev, 963 (void *)orbi, /*spd*/FWSPD_S400, 964 dst_hi, dst_lo + off, len, 965 ptr + off, hand); 966 } else { 967 if (debug) 968 printf("%s: CAM_DIR_IN --> write block out?\n",__func__); 969 xfer = fwmem_write_block(orbi->fwdev, 970 (void *)orbi, /*spd*/FWSPD_S400, 971 dst_hi, dst_lo + off, len, 972 ptr + off, hand); 973 } 974 if (xfer == NULL) { 975 printf("%s: xfer == NULL", __func__); 976 /* XXX what should we do?? */ 977 orbi->refcount--; 978 } 979 off += len; 980 } 981 } 982 983 static void 984 sbp_targ_pt_done(struct fw_xfer *xfer) 985 { 986 struct orb_info *orbi; 987 struct unrestricted_page_table_fmt *pt; 988 uint32_t i; 989 990 orbi = (struct orb_info *)xfer->sc; 991 992 if (orbi->state == ORBI_STATUS_ABORTED) { 993 if (debug) 994 printf("%s: orbi aborted\n", __func__); 995 sbp_targ_remove_orb_info(orbi->login, orbi); 996 if (debug) { 997 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); 998 printf("%s: free orbi %p\n", __func__, orbi); 999 } 1000 free(orbi->page_table, M_SBP_TARG); 1001 free(orbi, M_SBP_TARG); 1002 orbi = NULL; 1003 fw_xfer_free(xfer); 1004 return; 1005 } 1006 if (xfer->resp != 0) { 1007 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1008 orbi->status.resp = SBP_TRANS_FAIL; 1009 orbi->status.status = OBJ_PT | SBE_TIMEOUT/*XXX*/; 1010 orbi->status.dead = 1; 1011 orbi->status.len = 1; 1012 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 1013 1014 if (debug) 1015 printf("%s: free orbi->page_table %p\n", __func__, orbi->page_table); 1016 1017 sbp_targ_status_FIFO(orbi, 1018 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 1019 free(orbi->page_table, M_SBP_TARG); 1020 orbi->page_table = NULL; 1021 fw_xfer_free(xfer); 1022 return; 1023 } 1024 orbi->refcount++; 1025 /* 1026 * Set endianness here so we don't have 1027 * to deal with is later 1028 */ 1029 for (i = 0, pt = orbi->page_table; i < orbi->orb4.data_size; i++, pt++) { 1030 pt->segment_len = ntohs(pt->segment_len); 1031 if (debug) 1032 printf("%s:segment_len = %u\n", __func__,pt->segment_len); 1033 pt->segment_base_high = ntohs(pt->segment_base_high); 1034 pt->segment_base_low = ntohl(pt->segment_base_low); 1035 } 1036 1037 sbp_targ_xfer_pt(orbi); 1038 1039 orbi->refcount--; 1040 if (orbi->refcount == 0) 1041 printf("%s: refcount == 0\n", __func__); 1042 1043 fw_xfer_free(xfer); 1044 return; 1045 } 1046 1047 static void sbp_targ_xfer_pt(struct orb_info *orbi) 1048 { 1049 union ccb *ccb; 1050 uint32_t res, offset, len; 1051 1052 ccb = orbi->ccb; 1053 if (debug) 1054 printf("%s: dxfer_len=%d\n", __func__, ccb->csio.dxfer_len); 1055 res = ccb->csio.dxfer_len; 1056 /* 1057 * If the page table required multiple CTIO's to 1058 * complete, then cur_pte is non NULL 1059 * and we need to start from the last position 1060 * If this is the first pass over a page table 1061 * then we just start at the beginning of the page 1062 * table. 1063 * 1064 * Parse the unrestricted page table and figure out where we need 1065 * to shove the data from this read request. 1066 */ 1067 for (offset = 0, len = 0; (res != 0) && (orbi->cur_pte < orbi->last_pte); offset += len) { 1068 len = MIN(orbi->cur_pte->segment_len, res); 1069 res -= len; 1070 if (debug) 1071 printf("%s:page_table: %04x:%08x segment_len(%u) res(%u) len(%u)\n", 1072 __func__, orbi->cur_pte->segment_base_high, 1073 orbi->cur_pte->segment_base_low, 1074 orbi->cur_pte->segment_len, 1075 res, len); 1076 sbp_targ_xfer_buf(orbi, offset, 1077 orbi->cur_pte->segment_base_high, 1078 orbi->cur_pte->segment_base_low, 1079 len, sbp_targ_cam_done); 1080 /* 1081 * If we have only written partially to 1082 * this page table, then we need to save 1083 * our position for the next CTIO. If we 1084 * have completed the page table, then we 1085 * are safe to move on to the next entry. 1086 */ 1087 if (len == orbi->cur_pte->segment_len) { 1088 orbi->cur_pte++; 1089 } else { 1090 uint32_t saved_base_low; 1091 1092 /* Handle transfers that cross a 4GB boundary. */ 1093 saved_base_low = orbi->cur_pte->segment_base_low; 1094 orbi->cur_pte->segment_base_low += len; 1095 if (orbi->cur_pte->segment_base_low < saved_base_low) 1096 orbi->cur_pte->segment_base_high++; 1097 1098 orbi->cur_pte->segment_len -= len; 1099 } 1100 } 1101 if (debug) { 1102 printf("%s: base_low(%08x) page_table_off(%p) last_block(%u)\n", 1103 __func__, orbi->cur_pte->segment_base_low, 1104 orbi->cur_pte, orbi->last_block_read); 1105 } 1106 if (res != 0) 1107 printf("Warning - short pt encountered. " 1108 "Could not transfer all data.\n"); 1109 return; 1110 } 1111 1112 /* 1113 * Create page table in local memory 1114 * and transfer it from the initiator 1115 * in order to know where we are supposed 1116 * to put the data. 1117 */ 1118 1119 static void 1120 sbp_targ_fetch_pt(struct orb_info *orbi) 1121 { 1122 struct fw_xfer *xfer; 1123 1124 /* 1125 * Pull in page table from initiator 1126 * and setup for data from our 1127 * backend device. 1128 */ 1129 if (orbi->page_table == NULL) { 1130 orbi->page_table = malloc(orbi->orb4.data_size* 1131 sizeof(struct unrestricted_page_table_fmt), 1132 M_SBP_TARG, M_NOWAIT|M_ZERO); 1133 if (orbi->page_table == NULL) 1134 goto error; 1135 orbi->cur_pte = orbi->page_table; 1136 orbi->last_pte = orbi->page_table + orbi->orb4.data_size; 1137 orbi->last_block_read = orbi->orb4.data_size; 1138 if (debug && orbi->page_table != NULL) 1139 printf("%s: malloc'd orbi->page_table(%p), orb4.data_size(%u)\n", 1140 __func__, orbi->page_table, orbi->orb4.data_size); 1141 1142 xfer = fwmem_read_block(orbi->fwdev, (void *)orbi, /*spd*/FWSPD_S400, 1143 orbi->data_hi, orbi->data_lo, orbi->orb4.data_size* 1144 sizeof(struct unrestricted_page_table_fmt), 1145 (void *)orbi->page_table, sbp_targ_pt_done); 1146 1147 if (xfer != NULL) 1148 return; 1149 } else { 1150 /* 1151 * This is a CTIO for a page table we have 1152 * already malloc'd, so just directly invoke 1153 * the xfer function on the orbi. 1154 */ 1155 sbp_targ_xfer_pt(orbi); 1156 return; 1157 } 1158 error: 1159 orbi->ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 1160 if (debug) 1161 printf("%s: free orbi->page_table %p due to xfer == NULL\n", __func__, orbi->page_table); 1162 if (orbi->page_table != NULL) { 1163 free(orbi->page_table, M_SBP_TARG); 1164 orbi->page_table = NULL; 1165 } 1166 xpt_done(orbi->ccb); 1167 return; 1168 } 1169 1170 static void 1171 sbp_targ_action1(struct cam_sim *sim, union ccb *ccb) 1172 { 1173 struct sbp_targ_softc *sc; 1174 struct sbp_targ_lstate *lstate; 1175 cam_status status; 1176 u_int ccb_dir; 1177 1178 sc = (struct sbp_targ_softc *)cam_sim_softc(sim); 1179 1180 status = sbp_targ_find_devs(sc, ccb, &lstate, TRUE); 1181 1182 switch (ccb->ccb_h.func_code) { 1183 case XPT_CONT_TARGET_IO: 1184 { 1185 struct orb_info *orbi; 1186 1187 if (debug) 1188 printf("%s: XPT_CONT_TARGET_IO (0x%08x)\n", 1189 __func__, ccb->csio.tag_id); 1190 1191 if (status != CAM_REQ_CMP) { 1192 ccb->ccb_h.status = status; 1193 xpt_done(ccb); 1194 break; 1195 } 1196 /* XXX transfer from/to initiator */ 1197 orbi = sbp_targ_get_orb_info(lstate, 1198 ccb->csio.tag_id, ccb->csio.init_id); 1199 if (orbi == NULL) { 1200 ccb->ccb_h.status = CAM_REQ_ABORTED; /* XXX */ 1201 xpt_done(ccb); 1202 break; 1203 } 1204 if (orbi->state == ORBI_STATUS_ABORTED) { 1205 if (debug) 1206 printf("%s: ctio aborted\n", __func__); 1207 sbp_targ_remove_orb_info_locked(orbi->login, orbi); 1208 if (debug) 1209 printf("%s: free orbi %p\n", __func__, orbi); 1210 free(orbi, M_SBP_TARG); 1211 ccb->ccb_h.status = CAM_REQ_ABORTED; 1212 xpt_done(ccb); 1213 break; 1214 } 1215 orbi->state = ORBI_STATUS_CTIO; 1216 1217 orbi->ccb = ccb; 1218 ccb_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 1219 1220 /* XXX */ 1221 if (ccb->csio.dxfer_len == 0) 1222 ccb_dir = CAM_DIR_NONE; 1223 1224 /* Sanity check */ 1225 if (ccb_dir == CAM_DIR_IN && orbi->orb4.dir == 0) 1226 printf("%s: direction mismatch\n", __func__); 1227 1228 /* check page table */ 1229 if (ccb_dir != CAM_DIR_NONE && orbi->orb4.page_table_present) { 1230 if (debug) 1231 printf("%s: page_table_present\n", 1232 __func__); 1233 if (orbi->orb4.page_size != 0) { 1234 printf("%s: unsupported pagesize %d != 0\n", 1235 __func__, orbi->orb4.page_size); 1236 ccb->ccb_h.status = CAM_REQ_INVALID; 1237 xpt_done(ccb); 1238 break; 1239 } 1240 sbp_targ_fetch_pt(orbi); 1241 break; 1242 } 1243 1244 /* Sanity check */ 1245 if (ccb_dir != CAM_DIR_NONE) { 1246 sbp_targ_xfer_buf(orbi, 0, orbi->data_hi, 1247 orbi->data_lo, 1248 MIN(orbi->orb4.data_size, ccb->csio.dxfer_len), 1249 sbp_targ_cam_done); 1250 if ( orbi->orb4.data_size > ccb->csio.dxfer_len ) { 1251 orbi->data_lo += ccb->csio.dxfer_len; 1252 orbi->orb4.data_size -= ccb->csio.dxfer_len; 1253 } 1254 } 1255 1256 if (ccb_dir == CAM_DIR_NONE) { 1257 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 1258 /* XXX */ 1259 SBP_UNLOCK(sc); 1260 sbp_targ_send_status(orbi, ccb); 1261 SBP_LOCK(sc); 1262 } 1263 ccb->ccb_h.status = CAM_REQ_CMP; 1264 xpt_done(ccb); 1265 } 1266 break; 1267 } 1268 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 1269 if (status != CAM_REQ_CMP) { 1270 ccb->ccb_h.status = status; 1271 xpt_done(ccb); 1272 break; 1273 } 1274 SLIST_INSERT_HEAD(&lstate->accept_tios, &ccb->ccb_h, 1275 sim_links.sle); 1276 ccb->ccb_h.status = CAM_REQ_INPROG; 1277 if ((lstate->flags & F_ATIO_STARVED) != 0) { 1278 struct sbp_targ_login *login; 1279 1280 if (debug) 1281 printf("%s: new atio arrived\n", __func__); 1282 lstate->flags &= ~F_ATIO_STARVED; 1283 STAILQ_FOREACH(login, &lstate->logins, link) 1284 if ((login->flags & F_ATIO_STARVED) != 0) { 1285 login->flags &= ~F_ATIO_STARVED; 1286 sbp_targ_fetch_orb(lstate->sc, 1287 login->fwdev, 1288 login->last_hi, login->last_lo, 1289 login, FETCH_CMD); 1290 } 1291 } 1292 break; 1293 case XPT_NOTIFY_ACKNOWLEDGE: /* recycle notify ack */ 1294 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */ 1295 if (status != CAM_REQ_CMP) { 1296 ccb->ccb_h.status = status; 1297 xpt_done(ccb); 1298 break; 1299 } 1300 SLIST_INSERT_HEAD(&lstate->immed_notifies, &ccb->ccb_h, 1301 sim_links.sle); 1302 ccb->ccb_h.status = CAM_REQ_INPROG; 1303 sbp_targ_send_lstate_events(sc, lstate); 1304 break; 1305 case XPT_EN_LUN: 1306 sbp_targ_en_lun(sc, ccb); 1307 xpt_done(ccb); 1308 break; 1309 case XPT_PATH_INQ: 1310 { 1311 struct ccb_pathinq *cpi = &ccb->cpi; 1312 1313 cpi->version_num = 1; /* XXX??? */ 1314 cpi->hba_inquiry = PI_TAG_ABLE; 1315 cpi->target_sprt = PIT_PROCESSOR 1316 | PIT_DISCONNECT 1317 | PIT_TERM_IO; 1318 cpi->transport = XPORT_SPI; /* FIXME add XPORT_FW type to cam */ 1319 cpi->hba_misc = PIM_NOINITIATOR | PIM_NOBUSRESET | 1320 PIM_NO_6_BYTE; 1321 cpi->hba_eng_cnt = 0; 1322 cpi->max_target = 7; /* XXX */ 1323 cpi->max_lun = MAX_LUN - 1; 1324 cpi->initiator_id = 7; /* XXX */ 1325 cpi->bus_id = sim->bus_id; 1326 cpi->base_transfer_speed = 400 * 1000 / 8; 1327 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1328 strlcpy(cpi->hba_vid, "SBP_TARG", HBA_IDLEN); 1329 strlcpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); 1330 cpi->unit_number = sim->unit_number; 1331 1332 cpi->ccb_h.status = CAM_REQ_CMP; 1333 xpt_done(ccb); 1334 break; 1335 } 1336 case XPT_ABORT: 1337 { 1338 union ccb *accb = ccb->cab.abort_ccb; 1339 1340 switch (accb->ccb_h.func_code) { 1341 case XPT_ACCEPT_TARGET_IO: 1342 case XPT_IMMEDIATE_NOTIFY: 1343 ccb->ccb_h.status = sbp_targ_abort_ccb(sc, ccb); 1344 break; 1345 case XPT_CONT_TARGET_IO: 1346 /* XXX */ 1347 ccb->ccb_h.status = CAM_UA_ABORT; 1348 break; 1349 default: 1350 printf("%s: aborting unknown function %d\n", 1351 __func__, accb->ccb_h.func_code); 1352 ccb->ccb_h.status = CAM_REQ_INVALID; 1353 break; 1354 } 1355 xpt_done(ccb); 1356 break; 1357 } 1358 #ifdef CAM_NEW_TRAN_CODE 1359 case XPT_SET_TRAN_SETTINGS: 1360 ccb->ccb_h.status = CAM_REQ_INVALID; 1361 xpt_done(ccb); 1362 break; 1363 case XPT_GET_TRAN_SETTINGS: 1364 { 1365 struct ccb_trans_settings *cts = &ccb->cts; 1366 struct ccb_trans_settings_scsi *scsi = 1367 &cts->proto_specific.scsi; 1368 struct ccb_trans_settings_spi *spi = 1369 &cts->xport_specific.spi; 1370 1371 cts->protocol = PROTO_SCSI; 1372 cts->protocol_version = SCSI_REV_2; 1373 cts->transport = XPORT_FW; /* should have a FireWire */ 1374 cts->transport_version = 2; 1375 spi->valid = CTS_SPI_VALID_DISC; 1376 spi->flags = CTS_SPI_FLAGS_DISC_ENB; 1377 scsi->valid = CTS_SCSI_VALID_TQ; 1378 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 1379 #if 0 1380 printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:\n", 1381 device_get_nameunit(sc->fd.dev), 1382 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 1383 #endif 1384 cts->ccb_h.status = CAM_REQ_CMP; 1385 xpt_done(ccb); 1386 break; 1387 } 1388 #endif 1389 1390 default: 1391 printf("%s: unknown function 0x%x\n", 1392 __func__, ccb->ccb_h.func_code); 1393 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1394 xpt_done(ccb); 1395 break; 1396 } 1397 return; 1398 } 1399 1400 static void 1401 sbp_targ_action(struct cam_sim *sim, union ccb *ccb) 1402 { 1403 int s; 1404 1405 s = splfw(); 1406 sbp_targ_action1(sim, ccb); 1407 splx(s); 1408 } 1409 1410 static void 1411 sbp_targ_poll(struct cam_sim *sim) 1412 { 1413 /* XXX */ 1414 return; 1415 } 1416 1417 static void 1418 sbp_targ_cmd_handler(struct fw_xfer *xfer) 1419 { 1420 uint32_t *orb; 1421 struct corb4 *orb4; 1422 struct orb_info *orbi; 1423 struct ccb_accept_tio *atio; 1424 u_char *bytes; 1425 int i; 1426 1427 orbi = (struct orb_info *)xfer->sc; 1428 if (xfer->resp != 0) { 1429 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1430 orbi->status.resp = SBP_TRANS_FAIL; 1431 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1432 orbi->status.dead = 1; 1433 orbi->status.len = 1; 1434 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 1435 1436 sbp_targ_status_FIFO(orbi, 1437 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 1438 fw_xfer_free(xfer); 1439 return; 1440 } 1441 1442 atio = orbi->atio; 1443 1444 if (orbi->state == ORBI_STATUS_ABORTED) { 1445 printf("%s: aborted\n", __func__); 1446 sbp_targ_remove_orb_info(orbi->login, orbi); 1447 free(orbi, M_SBP_TARG); 1448 atio->ccb_h.status = CAM_REQ_ABORTED; 1449 xpt_done((union ccb*)atio); 1450 goto done0; 1451 } 1452 orbi->state = ORBI_STATUS_ATIO; 1453 1454 orb = orbi->orb; 1455 /* swap payload except SCSI command */ 1456 for (i = 0; i < 5; i++) 1457 orb[i] = ntohl(orb[i]); 1458 1459 orb4 = (struct corb4 *)&orb[4]; 1460 if (orb4->rq_fmt != 0) { 1461 /* XXX */ 1462 printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt); 1463 } 1464 1465 atio->ccb_h.target_id = 0; /* XXX */ 1466 atio->ccb_h.target_lun = orbi->login->lstate->lun; 1467 atio->sense_len = 0; 1468 atio->tag_action = MSG_SIMPLE_TASK; 1469 atio->tag_id = orbi->orb_lo; 1470 atio->init_id = orbi->login->id; 1471 1472 atio->ccb_h.flags |= CAM_TAG_ACTION_VALID; 1473 bytes = (u_char *)&orb[5]; 1474 if (debug) 1475 printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1476 __func__, (void *)atio, 1477 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], 1478 bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]); 1479 switch (bytes[0] >> 5) { 1480 case 0: 1481 atio->cdb_len = 6; 1482 break; 1483 case 1: 1484 case 2: 1485 atio->cdb_len = 10; 1486 break; 1487 case 4: 1488 atio->cdb_len = 16; 1489 break; 1490 case 5: 1491 atio->cdb_len = 12; 1492 break; 1493 case 3: 1494 default: 1495 /* Only copy the opcode. */ 1496 atio->cdb_len = 1; 1497 printf("Reserved or VU command code type encountered\n"); 1498 break; 1499 } 1500 1501 memcpy(atio->cdb_io.cdb_bytes, bytes, atio->cdb_len); 1502 1503 atio->ccb_h.status |= CAM_CDB_RECVD; 1504 1505 /* next ORB */ 1506 if ((orb[0] & (1<<31)) == 0) { 1507 if (debug) 1508 printf("%s: fetch next orb\n", __func__); 1509 orbi->status.src = SRC_NEXT_EXISTS; 1510 sbp_targ_fetch_orb(orbi->sc, orbi->fwdev, 1511 orb[0], orb[1], orbi->login, FETCH_CMD); 1512 } else { 1513 orbi->status.src = SRC_NO_NEXT; 1514 orbi->login->flags &= ~F_LINK_ACTIVE; 1515 } 1516 1517 orbi->data_hi = orb[2]; 1518 orbi->data_lo = orb[3]; 1519 orbi->orb4 = *orb4; 1520 1521 xpt_done((union ccb*)atio); 1522 done0: 1523 fw_xfer_free(xfer); 1524 return; 1525 } 1526 1527 static struct sbp_targ_login * 1528 sbp_targ_get_login(struct sbp_targ_softc *sc, struct fw_device *fwdev, int lun) 1529 { 1530 struct sbp_targ_lstate *lstate; 1531 struct sbp_targ_login *login; 1532 int i; 1533 1534 lstate = sc->lstate[lun]; 1535 1536 STAILQ_FOREACH(login, &lstate->logins, link) 1537 if (login->fwdev == fwdev) 1538 return (login); 1539 1540 for (i = 0; i < MAX_LOGINS; i++) 1541 if (sc->logins[i] == NULL) 1542 goto found; 1543 1544 printf("%s: increase MAX_LOGIN\n", __func__); 1545 return (NULL); 1546 1547 found: 1548 login = (struct sbp_targ_login *)malloc( 1549 sizeof(struct sbp_targ_login), M_SBP_TARG, M_NOWAIT | M_ZERO); 1550 1551 if (login == NULL) { 1552 printf("%s: malloc failed\n", __func__); 1553 return (NULL); 1554 } 1555 1556 login->id = i; 1557 login->fwdev = fwdev; 1558 login->lstate = lstate; 1559 login->last_hi = 0xffff; 1560 login->last_lo = 0xffffffff; 1561 login->hold_sec = 1; 1562 STAILQ_INIT(&login->orbs); 1563 CALLOUT_INIT(&login->hold_callout); 1564 sc->logins[i] = login; 1565 return (login); 1566 } 1567 1568 static void 1569 sbp_targ_mgm_handler(struct fw_xfer *xfer) 1570 { 1571 struct sbp_targ_lstate *lstate; 1572 struct sbp_targ_login *login; 1573 uint32_t *orb; 1574 struct morb4 *orb4; 1575 struct orb_info *orbi; 1576 int i; 1577 1578 orbi = (struct orb_info *)xfer->sc; 1579 if (xfer->resp != 0) { 1580 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1581 orbi->status.resp = SBP_TRANS_FAIL; 1582 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1583 orbi->status.dead = 1; 1584 orbi->status.len = 1; 1585 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 1586 1587 sbp_targ_status_FIFO(orbi, 1588 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0); 1589 fw_xfer_free(xfer); 1590 return; 1591 } 1592 1593 orb = orbi->orb; 1594 /* swap payload */ 1595 for (i = 0; i < 8; i++) { 1596 orb[i] = ntohl(orb[i]); 1597 } 1598 orb4 = (struct morb4 *)&orb[4]; 1599 if (debug) 1600 printf("%s: %s\n", __func__, orb_fun_name[orb4->fun]); 1601 1602 orbi->status.src = SRC_NO_NEXT; 1603 1604 switch (orb4->fun << 16) { 1605 case ORB_FUN_LGI: 1606 { 1607 int exclusive = 0, lun; 1608 1609 if (orb[4] & ORB_EXV) 1610 exclusive = 1; 1611 1612 lun = orb4->id; 1613 lstate = orbi->sc->lstate[lun]; 1614 1615 if (lun >= MAX_LUN || lstate == NULL || 1616 (exclusive && 1617 STAILQ_FIRST(&lstate->logins) != NULL && 1618 STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev) 1619 ) { 1620 /* error */ 1621 orbi->status.dead = 1; 1622 orbi->status.status = STATUS_ACCESS_DENY; 1623 orbi->status.len = 1; 1624 break; 1625 } 1626 1627 /* allocate login */ 1628 login = sbp_targ_get_login(orbi->sc, orbi->fwdev, lun); 1629 if (login == NULL) { 1630 printf("%s: sbp_targ_get_login failed\n", 1631 __func__); 1632 orbi->status.dead = 1; 1633 orbi->status.status = STATUS_RES_UNAVAIL; 1634 orbi->status.len = 1; 1635 break; 1636 } 1637 printf("%s: login id=%d\n", __func__, login->id); 1638 1639 login->fifo_hi = orb[6]; 1640 login->fifo_lo = orb[7]; 1641 login->loginres.len = htons(sizeof(uint32_t) * 4); 1642 login->loginres.id = htons(login->id); 1643 login->loginres.cmd_hi = htons(SBP_TARG_BIND_HI); 1644 login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id)); 1645 login->loginres.recon_hold = htons(login->hold_sec); 1646 1647 STAILQ_INSERT_TAIL(&lstate->logins, login, link); 1648 fwmem_write_block(orbi->fwdev, NULL, /*spd*/FWSPD_S400, orb[2], orb[3], 1649 sizeof(struct sbp_login_res), (void *)&login->loginres, 1650 fw_asy_callback_free); 1651 /* XXX return status after loginres is successfully written */ 1652 break; 1653 } 1654 case ORB_FUN_RCN: 1655 login = orbi->sc->logins[orb4->id]; 1656 if (login != NULL && login->fwdev == orbi->fwdev) { 1657 login->flags &= ~F_HOLD; 1658 callout_stop(&login->hold_callout); 1659 printf("%s: reconnected id=%d\n", 1660 __func__, login->id); 1661 } else { 1662 orbi->status.dead = 1; 1663 orbi->status.status = STATUS_ACCESS_DENY; 1664 printf("%s: reconnection failed id=%d\n", 1665 __func__, orb4->id); 1666 } 1667 break; 1668 case ORB_FUN_LGO: 1669 login = orbi->sc->logins[orb4->id]; 1670 if (login->fwdev != orbi->fwdev) { 1671 printf("%s: wrong initiator\n", __func__); 1672 break; 1673 } 1674 sbp_targ_dealloc_login(login); 1675 break; 1676 default: 1677 printf("%s: %s not implemented yet\n", 1678 __func__, orb_fun_name[orb4->fun]); 1679 break; 1680 } 1681 orbi->status.len = 1; 1682 sbp_targ_status_FIFO(orbi, orb[6], orb[7], /*dequeue*/0); 1683 fw_xfer_free(xfer); 1684 return; 1685 } 1686 1687 static void 1688 sbp_targ_pointer_handler(struct fw_xfer *xfer) 1689 { 1690 struct orb_info *orbi; 1691 uint32_t orb0, orb1; 1692 1693 orbi = (struct orb_info *)xfer->sc; 1694 if (xfer->resp != 0) { 1695 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1696 goto done; 1697 } 1698 1699 orb0 = ntohl(orbi->orb[0]); 1700 orb1 = ntohl(orbi->orb[1]); 1701 if ((orb0 & (1U << 31)) != 0) { 1702 printf("%s: invalid pointer\n", __func__); 1703 goto done; 1704 } 1705 sbp_targ_fetch_orb(orbi->login->lstate->sc, orbi->fwdev, 1706 (uint16_t)orb0, orb1, orbi->login, FETCH_CMD); 1707 done: 1708 free(orbi, M_SBP_TARG); 1709 fw_xfer_free(xfer); 1710 return; 1711 } 1712 1713 static void 1714 sbp_targ_fetch_orb(struct sbp_targ_softc *sc, struct fw_device *fwdev, 1715 uint16_t orb_hi, uint32_t orb_lo, struct sbp_targ_login *login, 1716 int mode) 1717 { 1718 struct orb_info *orbi; 1719 1720 if (debug) 1721 printf("%s: fetch orb %04x:%08x\n", __func__, orb_hi, orb_lo); 1722 orbi = malloc(sizeof(struct orb_info), M_SBP_TARG, M_NOWAIT | M_ZERO); 1723 if (orbi == NULL) { 1724 printf("%s: malloc failed\n", __func__); 1725 return; 1726 } 1727 orbi->sc = sc; 1728 orbi->fwdev = fwdev; 1729 orbi->login = login; 1730 orbi->orb_hi = orb_hi; 1731 orbi->orb_lo = orb_lo; 1732 orbi->status.orb_hi = htons(orb_hi); 1733 orbi->status.orb_lo = htonl(orb_lo); 1734 orbi->page_table = NULL; 1735 1736 switch (mode) { 1737 case FETCH_MGM: 1738 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1739 sizeof(uint32_t) * 8, &orbi->orb[0], 1740 sbp_targ_mgm_handler); 1741 break; 1742 case FETCH_CMD: 1743 orbi->state = ORBI_STATUS_FETCH; 1744 login->last_hi = orb_hi; 1745 login->last_lo = orb_lo; 1746 login->flags |= F_LINK_ACTIVE; 1747 /* dequeue */ 1748 SBP_LOCK(sc); 1749 orbi->atio = (struct ccb_accept_tio *) 1750 SLIST_FIRST(&login->lstate->accept_tios); 1751 if (orbi->atio == NULL) { 1752 SBP_UNLOCK(sc); 1753 printf("%s: no free atio\n", __func__); 1754 login->lstate->flags |= F_ATIO_STARVED; 1755 login->flags |= F_ATIO_STARVED; 1756 #if 0 1757 /* XXX ?? */ 1758 login->fwdev = fwdev; 1759 #endif 1760 break; 1761 } 1762 SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); 1763 STAILQ_INSERT_TAIL(&login->orbs, orbi, link); 1764 SBP_UNLOCK(sc); 1765 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1766 sizeof(uint32_t) * 8, &orbi->orb[0], 1767 sbp_targ_cmd_handler); 1768 break; 1769 case FETCH_POINTER: 1770 orbi->state = ORBI_STATUS_POINTER; 1771 login->flags |= F_LINK_ACTIVE; 1772 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1773 sizeof(uint32_t) * 2, &orbi->orb[0], 1774 sbp_targ_pointer_handler); 1775 break; 1776 default: 1777 printf("%s: invalid mode %d\n", __func__, mode); 1778 } 1779 } 1780 1781 static void 1782 sbp_targ_resp_callback(struct fw_xfer *xfer) 1783 { 1784 struct sbp_targ_softc *sc; 1785 int s; 1786 1787 if (debug) 1788 printf("%s: xfer=%p\n", __func__, xfer); 1789 sc = (struct sbp_targ_softc *)xfer->sc; 1790 fw_xfer_unload(xfer); 1791 xfer->recv.pay_len = SBP_TARG_RECV_LEN; 1792 xfer->hand = sbp_targ_recv; 1793 s = splfw(); 1794 STAILQ_INSERT_TAIL(&sc->fwb.xferlist, xfer, link); 1795 splx(s); 1796 } 1797 1798 static int 1799 sbp_targ_cmd(struct fw_xfer *xfer, struct fw_device *fwdev, int login_id, 1800 int reg) 1801 { 1802 struct sbp_targ_login *login; 1803 struct sbp_targ_softc *sc; 1804 int rtcode = 0; 1805 1806 if (login_id < 0 || login_id >= MAX_LOGINS) 1807 return (RESP_ADDRESS_ERROR); 1808 1809 sc = (struct sbp_targ_softc *)xfer->sc; 1810 login = sc->logins[login_id]; 1811 if (login == NULL) 1812 return (RESP_ADDRESS_ERROR); 1813 1814 if (login->fwdev != fwdev) { 1815 /* XXX */ 1816 return (RESP_ADDRESS_ERROR); 1817 } 1818 1819 switch (reg) { 1820 case 0x08: /* ORB_POINTER */ 1821 if (debug) 1822 printf("%s: ORB_POINTER(%d)\n", __func__, login_id); 1823 if ((login->flags & F_LINK_ACTIVE) != 0) { 1824 if (debug) 1825 printf("link active (ORB_POINTER)\n"); 1826 break; 1827 } 1828 sbp_targ_fetch_orb(sc, fwdev, 1829 ntohl(xfer->recv.payload[0]), 1830 ntohl(xfer->recv.payload[1]), 1831 login, FETCH_CMD); 1832 break; 1833 case 0x04: /* AGENT_RESET */ 1834 if (debug) 1835 printf("%s: AGENT RESET(%d)\n", __func__, login_id); 1836 login->last_hi = 0xffff; 1837 login->last_lo = 0xffffffff; 1838 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); 1839 break; 1840 case 0x10: /* DOORBELL */ 1841 if (debug) 1842 printf("%s: DOORBELL(%d)\n", __func__, login_id); 1843 if (login->last_hi == 0xffff && 1844 login->last_lo == 0xffffffff) { 1845 printf("%s: no previous pointer(DOORBELL)\n", 1846 __func__); 1847 break; 1848 } 1849 if ((login->flags & F_LINK_ACTIVE) != 0) { 1850 if (debug) 1851 printf("link active (DOORBELL)\n"); 1852 break; 1853 } 1854 sbp_targ_fetch_orb(sc, fwdev, 1855 login->last_hi, login->last_lo, 1856 login, FETCH_POINTER); 1857 break; 1858 case 0x00: /* AGENT_STATE */ 1859 printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id); 1860 break; 1861 case 0x14: /* UNSOLICITED_STATE_ENABLE */ 1862 printf("%s: UNSOLICITED_STATE_ENABLE (%d:ignore)\n", 1863 __func__, login_id); 1864 break; 1865 default: 1866 printf("%s: invalid register %d(%d)\n", 1867 __func__, reg, login_id); 1868 rtcode = RESP_ADDRESS_ERROR; 1869 } 1870 1871 return (rtcode); 1872 } 1873 1874 static int 1875 sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev) 1876 { 1877 struct sbp_targ_softc *sc; 1878 struct fw_pkt *fp; 1879 1880 sc = (struct sbp_targ_softc *)xfer->sc; 1881 1882 fp = &xfer->recv.hdr; 1883 if (fp->mode.wreqb.tcode != FWTCODE_WREQB) { 1884 printf("%s: tcode = %d\n", __func__, fp->mode.wreqb.tcode); 1885 return (RESP_TYPE_ERROR); 1886 } 1887 1888 sbp_targ_fetch_orb(sc, fwdev, 1889 ntohl(xfer->recv.payload[0]), 1890 ntohl(xfer->recv.payload[1]), 1891 NULL, FETCH_MGM); 1892 1893 return (0); 1894 } 1895 1896 static void 1897 sbp_targ_recv(struct fw_xfer *xfer) 1898 { 1899 struct fw_pkt *fp, *sfp; 1900 struct fw_device *fwdev; 1901 uint32_t lo; 1902 int s, rtcode; 1903 struct sbp_targ_softc *sc; 1904 1905 s = splfw(); 1906 sc = (struct sbp_targ_softc *)xfer->sc; 1907 fp = &xfer->recv.hdr; 1908 fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); 1909 if (fwdev == NULL) { 1910 printf("%s: cannot resolve nodeid=%d\n", 1911 __func__, fp->mode.wreqb.src & 0x3f); 1912 rtcode = RESP_TYPE_ERROR; /* XXX */ 1913 goto done; 1914 } 1915 lo = fp->mode.wreqb.dest_lo; 1916 1917 if (lo == SBP_TARG_BIND_LO(-1)) 1918 rtcode = sbp_targ_mgm(xfer, fwdev); 1919 else if (lo >= SBP_TARG_BIND_LO(0)) 1920 rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), 1921 lo % 0x20); 1922 else 1923 rtcode = RESP_ADDRESS_ERROR; 1924 1925 done: 1926 if (rtcode != 0) 1927 printf("%s: rtcode = %d\n", __func__, rtcode); 1928 sfp = &xfer->send.hdr; 1929 xfer->send.spd = FWSPD_S400; 1930 xfer->hand = sbp_targ_resp_callback; 1931 sfp->mode.wres.dst = fp->mode.wreqb.src; 1932 sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt; 1933 sfp->mode.wres.tcode = FWTCODE_WRES; 1934 sfp->mode.wres.rtcode = rtcode; 1935 sfp->mode.wres.pri = 0; 1936 1937 fw_asyreq(xfer->fc, -1, xfer); 1938 splx(s); 1939 } 1940 1941 static int 1942 sbp_targ_attach(device_t dev) 1943 { 1944 struct sbp_targ_softc *sc; 1945 struct cam_devq *devq; 1946 struct firewire_comm *fc; 1947 1948 sc = (struct sbp_targ_softc *) device_get_softc(dev); 1949 bzero((void *)sc, sizeof(struct sbp_targ_softc)); 1950 1951 mtx_init(&sc->mtx, "sbp_targ", NULL, MTX_DEF); 1952 sc->fd.fc = fc = device_get_ivars(dev); 1953 sc->fd.dev = dev; 1954 sc->fd.post_explore = (void *) sbp_targ_post_explore; 1955 sc->fd.post_busreset = (void *) sbp_targ_post_busreset; 1956 1957 devq = cam_simq_alloc(/*maxopenings*/MAX_LUN*MAX_INITIATORS); 1958 if (devq == NULL) 1959 return (ENXIO); 1960 1961 sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll, 1962 "sbp_targ", sc, device_get_unit(dev), &sc->mtx, 1963 /*untagged*/ 1, /*tagged*/ 1, devq); 1964 if (sc->sim == NULL) { 1965 cam_simq_free(devq); 1966 return (ENXIO); 1967 } 1968 1969 SBP_LOCK(sc); 1970 if (xpt_bus_register(sc->sim, dev, /*bus*/0) != CAM_SUCCESS) 1971 goto fail; 1972 1973 if (xpt_create_path(&sc->path, /*periph*/ NULL, cam_sim_path(sc->sim), 1974 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1975 xpt_bus_deregister(cam_sim_path(sc->sim)); 1976 goto fail; 1977 } 1978 SBP_UNLOCK(sc); 1979 1980 sc->fwb.start = SBP_TARG_BIND_START; 1981 sc->fwb.end = SBP_TARG_BIND_END; 1982 1983 /* pre-allocate xfer */ 1984 STAILQ_INIT(&sc->fwb.xferlist); 1985 fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, 1986 /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, 1987 fc, (void *)sc, sbp_targ_recv); 1988 fw_bindadd(fc, &sc->fwb); 1989 return 0; 1990 1991 fail: 1992 SBP_UNLOCK(sc); 1993 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1994 return (ENXIO); 1995 } 1996 1997 static int 1998 sbp_targ_detach(device_t dev) 1999 { 2000 struct sbp_targ_softc *sc; 2001 struct sbp_targ_lstate *lstate; 2002 int i; 2003 2004 sc = (struct sbp_targ_softc *)device_get_softc(dev); 2005 sc->fd.post_busreset = NULL; 2006 2007 SBP_LOCK(sc); 2008 xpt_free_path(sc->path); 2009 xpt_bus_deregister(cam_sim_path(sc->sim)); 2010 cam_sim_free(sc->sim, /*free_devq*/TRUE); 2011 SBP_UNLOCK(sc); 2012 2013 for (i = 0; i < MAX_LUN; i++) { 2014 lstate = sc->lstate[i]; 2015 if (lstate != NULL) { 2016 xpt_free_path(lstate->path); 2017 free(lstate, M_SBP_TARG); 2018 } 2019 } 2020 if (sc->black_hole != NULL) { 2021 xpt_free_path(sc->black_hole->path); 2022 free(sc->black_hole, M_SBP_TARG); 2023 } 2024 2025 fw_bindremove(sc->fd.fc, &sc->fwb); 2026 fw_xferlist_remove(&sc->fwb.xferlist); 2027 2028 mtx_destroy(&sc->mtx); 2029 2030 return 0; 2031 } 2032 2033 static device_method_t sbp_targ_methods[] = { 2034 /* device interface */ 2035 DEVMETHOD(device_identify, sbp_targ_identify), 2036 DEVMETHOD(device_probe, sbp_targ_probe), 2037 DEVMETHOD(device_attach, sbp_targ_attach), 2038 DEVMETHOD(device_detach, sbp_targ_detach), 2039 { 0, 0 } 2040 }; 2041 2042 static driver_t sbp_targ_driver = { 2043 "sbp_targ", 2044 sbp_targ_methods, 2045 sizeof(struct sbp_targ_softc), 2046 }; 2047 2048 DRIVER_MODULE(sbp_targ, firewire, sbp_targ_driver, 0, 0); 2049 MODULE_VERSION(sbp_targ, 1); 2050 MODULE_DEPEND(sbp_targ, firewire, 1, 1, 1); 2051 MODULE_DEPEND(sbp_targ, cam, 1, 1, 1); 2052