1 /*- 2 * Copyright (C) 2003 3 * Hidetoshi Shimokawa. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * 16 * This product includes software developed by Hidetoshi Shimokawa. 17 * 18 * 4. Neither the name of the author nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * $FreeBSD$ 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 struct fw_pkt *fp; 1421 uint32_t *orb; 1422 struct corb4 *orb4; 1423 struct orb_info *orbi; 1424 struct ccb_accept_tio *atio; 1425 u_char *bytes; 1426 int i; 1427 1428 orbi = (struct orb_info *)xfer->sc; 1429 if (xfer->resp != 0) { 1430 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1431 orbi->status.resp = SBP_TRANS_FAIL; 1432 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1433 orbi->status.dead = 1; 1434 orbi->status.len = 1; 1435 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 1436 1437 sbp_targ_status_FIFO(orbi, 1438 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 1439 fw_xfer_free(xfer); 1440 return; 1441 } 1442 fp = &xfer->recv.hdr; 1443 1444 atio = orbi->atio; 1445 1446 if (orbi->state == ORBI_STATUS_ABORTED) { 1447 printf("%s: aborted\n", __func__); 1448 sbp_targ_remove_orb_info(orbi->login, orbi); 1449 free(orbi, M_SBP_TARG); 1450 atio->ccb_h.status = CAM_REQ_ABORTED; 1451 xpt_done((union ccb*)atio); 1452 goto done0; 1453 } 1454 orbi->state = ORBI_STATUS_ATIO; 1455 1456 orb = orbi->orb; 1457 /* swap payload except SCSI command */ 1458 for (i = 0; i < 5; i++) 1459 orb[i] = ntohl(orb[i]); 1460 1461 orb4 = (struct corb4 *)&orb[4]; 1462 if (orb4->rq_fmt != 0) { 1463 /* XXX */ 1464 printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt); 1465 } 1466 1467 atio->ccb_h.target_id = 0; /* XXX */ 1468 atio->ccb_h.target_lun = orbi->login->lstate->lun; 1469 atio->sense_len = 0; 1470 atio->tag_action = MSG_SIMPLE_TASK; 1471 atio->tag_id = orbi->orb_lo; 1472 atio->init_id = orbi->login->id; 1473 1474 atio->ccb_h.flags |= CAM_TAG_ACTION_VALID; 1475 bytes = (u_char *)&orb[5]; 1476 if (debug) 1477 printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1478 __func__, (void *)atio, 1479 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], 1480 bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]); 1481 switch (bytes[0] >> 5) { 1482 case 0: 1483 atio->cdb_len = 6; 1484 break; 1485 case 1: 1486 case 2: 1487 atio->cdb_len = 10; 1488 break; 1489 case 4: 1490 atio->cdb_len = 16; 1491 break; 1492 case 5: 1493 atio->cdb_len = 12; 1494 break; 1495 case 3: 1496 default: 1497 /* Only copy the opcode. */ 1498 atio->cdb_len = 1; 1499 printf("Reserved or VU command code type encountered\n"); 1500 break; 1501 } 1502 1503 memcpy(atio->cdb_io.cdb_bytes, bytes, atio->cdb_len); 1504 1505 atio->ccb_h.status |= CAM_CDB_RECVD; 1506 1507 /* next ORB */ 1508 if ((orb[0] & (1<<31)) == 0) { 1509 if (debug) 1510 printf("%s: fetch next orb\n", __func__); 1511 orbi->status.src = SRC_NEXT_EXISTS; 1512 sbp_targ_fetch_orb(orbi->sc, orbi->fwdev, 1513 orb[0], orb[1], orbi->login, FETCH_CMD); 1514 } else { 1515 orbi->status.src = SRC_NO_NEXT; 1516 orbi->login->flags &= ~F_LINK_ACTIVE; 1517 } 1518 1519 orbi->data_hi = orb[2]; 1520 orbi->data_lo = orb[3]; 1521 orbi->orb4 = *orb4; 1522 1523 xpt_done((union ccb*)atio); 1524 done0: 1525 fw_xfer_free(xfer); 1526 return; 1527 } 1528 1529 static struct sbp_targ_login * 1530 sbp_targ_get_login(struct sbp_targ_softc *sc, struct fw_device *fwdev, int lun) 1531 { 1532 struct sbp_targ_lstate *lstate; 1533 struct sbp_targ_login *login; 1534 int i; 1535 1536 lstate = sc->lstate[lun]; 1537 1538 STAILQ_FOREACH(login, &lstate->logins, link) 1539 if (login->fwdev == fwdev) 1540 return (login); 1541 1542 for (i = 0; i < MAX_LOGINS; i++) 1543 if (sc->logins[i] == NULL) 1544 goto found; 1545 1546 printf("%s: increase MAX_LOGIN\n", __func__); 1547 return (NULL); 1548 1549 found: 1550 login = (struct sbp_targ_login *)malloc( 1551 sizeof(struct sbp_targ_login), M_SBP_TARG, M_NOWAIT | M_ZERO); 1552 1553 if (login == NULL) { 1554 printf("%s: malloc failed\n", __func__); 1555 return (NULL); 1556 } 1557 1558 login->id = i; 1559 login->fwdev = fwdev; 1560 login->lstate = lstate; 1561 login->last_hi = 0xffff; 1562 login->last_lo = 0xffffffff; 1563 login->hold_sec = 1; 1564 STAILQ_INIT(&login->orbs); 1565 CALLOUT_INIT(&login->hold_callout); 1566 sc->logins[i] = login; 1567 return (login); 1568 } 1569 1570 static void 1571 sbp_targ_mgm_handler(struct fw_xfer *xfer) 1572 { 1573 struct sbp_targ_lstate *lstate; 1574 struct sbp_targ_login *login; 1575 struct fw_pkt *fp; 1576 uint32_t *orb; 1577 struct morb4 *orb4; 1578 struct orb_info *orbi; 1579 int i; 1580 1581 orbi = (struct orb_info *)xfer->sc; 1582 if (xfer->resp != 0) { 1583 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1584 orbi->status.resp = SBP_TRANS_FAIL; 1585 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1586 orbi->status.dead = 1; 1587 orbi->status.len = 1; 1588 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 1589 1590 sbp_targ_status_FIFO(orbi, 1591 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0); 1592 fw_xfer_free(xfer); 1593 return; 1594 } 1595 fp = &xfer->recv.hdr; 1596 1597 orb = orbi->orb; 1598 /* swap payload */ 1599 for (i = 0; i < 8; i++) { 1600 orb[i] = ntohl(orb[i]); 1601 } 1602 orb4 = (struct morb4 *)&orb[4]; 1603 if (debug) 1604 printf("%s: %s\n", __func__, orb_fun_name[orb4->fun]); 1605 1606 orbi->status.src = SRC_NO_NEXT; 1607 1608 switch (orb4->fun << 16) { 1609 case ORB_FUN_LGI: 1610 { 1611 int exclusive = 0, lun; 1612 1613 if (orb[4] & ORB_EXV) 1614 exclusive = 1; 1615 1616 lun = orb4->id; 1617 lstate = orbi->sc->lstate[lun]; 1618 1619 if (lun >= MAX_LUN || lstate == NULL || 1620 (exclusive && 1621 STAILQ_FIRST(&lstate->logins) != NULL && 1622 STAILQ_FIRST(&lstate->logins)->fwdev != orbi->fwdev) 1623 ) { 1624 /* error */ 1625 orbi->status.dead = 1; 1626 orbi->status.status = STATUS_ACCESS_DENY; 1627 orbi->status.len = 1; 1628 break; 1629 } 1630 1631 /* allocate login */ 1632 login = sbp_targ_get_login(orbi->sc, orbi->fwdev, lun); 1633 if (login == NULL) { 1634 printf("%s: sbp_targ_get_login failed\n", 1635 __func__); 1636 orbi->status.dead = 1; 1637 orbi->status.status = STATUS_RES_UNAVAIL; 1638 orbi->status.len = 1; 1639 break; 1640 } 1641 printf("%s: login id=%d\n", __func__, login->id); 1642 1643 login->fifo_hi = orb[6]; 1644 login->fifo_lo = orb[7]; 1645 login->loginres.len = htons(sizeof(uint32_t) * 4); 1646 login->loginres.id = htons(login->id); 1647 login->loginres.cmd_hi = htons(SBP_TARG_BIND_HI); 1648 login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id)); 1649 login->loginres.recon_hold = htons(login->hold_sec); 1650 1651 STAILQ_INSERT_TAIL(&lstate->logins, login, link); 1652 fwmem_write_block(orbi->fwdev, NULL, /*spd*/FWSPD_S400, orb[2], orb[3], 1653 sizeof(struct sbp_login_res), (void *)&login->loginres, 1654 fw_asy_callback_free); 1655 /* XXX return status after loginres is successfully written */ 1656 break; 1657 } 1658 case ORB_FUN_RCN: 1659 login = orbi->sc->logins[orb4->id]; 1660 if (login != NULL && login->fwdev == orbi->fwdev) { 1661 login->flags &= ~F_HOLD; 1662 callout_stop(&login->hold_callout); 1663 printf("%s: reconnected id=%d\n", 1664 __func__, login->id); 1665 } else { 1666 orbi->status.dead = 1; 1667 orbi->status.status = STATUS_ACCESS_DENY; 1668 printf("%s: reconnection faild id=%d\n", 1669 __func__, orb4->id); 1670 } 1671 break; 1672 case ORB_FUN_LGO: 1673 login = orbi->sc->logins[orb4->id]; 1674 if (login->fwdev != orbi->fwdev) { 1675 printf("%s: wrong initiator\n", __func__); 1676 break; 1677 } 1678 sbp_targ_dealloc_login(login); 1679 break; 1680 default: 1681 printf("%s: %s not implemented yet\n", 1682 __func__, orb_fun_name[orb4->fun]); 1683 break; 1684 } 1685 orbi->status.len = 1; 1686 sbp_targ_status_FIFO(orbi, orb[6], orb[7], /*dequeue*/0); 1687 fw_xfer_free(xfer); 1688 return; 1689 } 1690 1691 static void 1692 sbp_targ_pointer_handler(struct fw_xfer *xfer) 1693 { 1694 struct orb_info *orbi; 1695 uint32_t orb0, orb1; 1696 1697 orbi = (struct orb_info *)xfer->sc; 1698 if (xfer->resp != 0) { 1699 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1700 goto done; 1701 } 1702 1703 orb0 = ntohl(orbi->orb[0]); 1704 orb1 = ntohl(orbi->orb[1]); 1705 if ((orb0 & (1U << 31)) != 0) { 1706 printf("%s: invalid pointer\n", __func__); 1707 goto done; 1708 } 1709 sbp_targ_fetch_orb(orbi->login->lstate->sc, orbi->fwdev, 1710 (uint16_t)orb0, orb1, orbi->login, FETCH_CMD); 1711 done: 1712 free(orbi, M_SBP_TARG); 1713 fw_xfer_free(xfer); 1714 return; 1715 } 1716 1717 static void 1718 sbp_targ_fetch_orb(struct sbp_targ_softc *sc, struct fw_device *fwdev, 1719 uint16_t orb_hi, uint32_t orb_lo, struct sbp_targ_login *login, 1720 int mode) 1721 { 1722 struct orb_info *orbi; 1723 1724 if (debug) 1725 printf("%s: fetch orb %04x:%08x\n", __func__, orb_hi, orb_lo); 1726 orbi = malloc(sizeof(struct orb_info), M_SBP_TARG, M_NOWAIT | M_ZERO); 1727 if (orbi == NULL) { 1728 printf("%s: malloc failed\n", __func__); 1729 return; 1730 } 1731 orbi->sc = sc; 1732 orbi->fwdev = fwdev; 1733 orbi->login = login; 1734 orbi->orb_hi = orb_hi; 1735 orbi->orb_lo = orb_lo; 1736 orbi->status.orb_hi = htons(orb_hi); 1737 orbi->status.orb_lo = htonl(orb_lo); 1738 orbi->page_table = NULL; 1739 1740 switch (mode) { 1741 case FETCH_MGM: 1742 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1743 sizeof(uint32_t) * 8, &orbi->orb[0], 1744 sbp_targ_mgm_handler); 1745 break; 1746 case FETCH_CMD: 1747 orbi->state = ORBI_STATUS_FETCH; 1748 login->last_hi = orb_hi; 1749 login->last_lo = orb_lo; 1750 login->flags |= F_LINK_ACTIVE; 1751 /* dequeue */ 1752 SBP_LOCK(sc); 1753 orbi->atio = (struct ccb_accept_tio *) 1754 SLIST_FIRST(&login->lstate->accept_tios); 1755 if (orbi->atio == NULL) { 1756 SBP_UNLOCK(sc); 1757 printf("%s: no free atio\n", __func__); 1758 login->lstate->flags |= F_ATIO_STARVED; 1759 login->flags |= F_ATIO_STARVED; 1760 #if 0 1761 /* XXX ?? */ 1762 login->fwdev = fwdev; 1763 #endif 1764 break; 1765 } 1766 SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); 1767 STAILQ_INSERT_TAIL(&login->orbs, orbi, link); 1768 SBP_UNLOCK(sc); 1769 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1770 sizeof(uint32_t) * 8, &orbi->orb[0], 1771 sbp_targ_cmd_handler); 1772 break; 1773 case FETCH_POINTER: 1774 orbi->state = ORBI_STATUS_POINTER; 1775 login->flags |= F_LINK_ACTIVE; 1776 fwmem_read_block(fwdev, (void *)orbi, /*spd*/FWSPD_S400, orb_hi, orb_lo, 1777 sizeof(uint32_t) * 2, &orbi->orb[0], 1778 sbp_targ_pointer_handler); 1779 break; 1780 default: 1781 printf("%s: invalid mode %d\n", __func__, mode); 1782 } 1783 } 1784 1785 static void 1786 sbp_targ_resp_callback(struct fw_xfer *xfer) 1787 { 1788 struct sbp_targ_softc *sc; 1789 int s; 1790 1791 if (debug) 1792 printf("%s: xfer=%p\n", __func__, xfer); 1793 sc = (struct sbp_targ_softc *)xfer->sc; 1794 fw_xfer_unload(xfer); 1795 xfer->recv.pay_len = SBP_TARG_RECV_LEN; 1796 xfer->hand = sbp_targ_recv; 1797 s = splfw(); 1798 STAILQ_INSERT_TAIL(&sc->fwb.xferlist, xfer, link); 1799 splx(s); 1800 } 1801 1802 static int 1803 sbp_targ_cmd(struct fw_xfer *xfer, struct fw_device *fwdev, int login_id, 1804 int reg) 1805 { 1806 struct sbp_targ_login *login; 1807 struct sbp_targ_softc *sc; 1808 int rtcode = 0; 1809 1810 if (login_id < 0 || login_id >= MAX_LOGINS) 1811 return (RESP_ADDRESS_ERROR); 1812 1813 sc = (struct sbp_targ_softc *)xfer->sc; 1814 login = sc->logins[login_id]; 1815 if (login == NULL) 1816 return (RESP_ADDRESS_ERROR); 1817 1818 if (login->fwdev != fwdev) { 1819 /* XXX */ 1820 return (RESP_ADDRESS_ERROR); 1821 } 1822 1823 switch (reg) { 1824 case 0x08: /* ORB_POINTER */ 1825 if (debug) 1826 printf("%s: ORB_POINTER(%d)\n", __func__, login_id); 1827 if ((login->flags & F_LINK_ACTIVE) != 0) { 1828 if (debug) 1829 printf("link active (ORB_POINTER)\n"); 1830 break; 1831 } 1832 sbp_targ_fetch_orb(sc, fwdev, 1833 ntohl(xfer->recv.payload[0]), 1834 ntohl(xfer->recv.payload[1]), 1835 login, FETCH_CMD); 1836 break; 1837 case 0x04: /* AGENT_RESET */ 1838 if (debug) 1839 printf("%s: AGENT RESET(%d)\n", __func__, login_id); 1840 login->last_hi = 0xffff; 1841 login->last_lo = 0xffffffff; 1842 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); 1843 break; 1844 case 0x10: /* DOORBELL */ 1845 if (debug) 1846 printf("%s: DOORBELL(%d)\n", __func__, login_id); 1847 if (login->last_hi == 0xffff && 1848 login->last_lo == 0xffffffff) { 1849 printf("%s: no previous pointer(DOORBELL)\n", 1850 __func__); 1851 break; 1852 } 1853 if ((login->flags & F_LINK_ACTIVE) != 0) { 1854 if (debug) 1855 printf("link active (DOORBELL)\n"); 1856 break; 1857 } 1858 sbp_targ_fetch_orb(sc, fwdev, 1859 login->last_hi, login->last_lo, 1860 login, FETCH_POINTER); 1861 break; 1862 case 0x00: /* AGENT_STATE */ 1863 printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id); 1864 break; 1865 case 0x14: /* UNSOLICITED_STATE_ENABLE */ 1866 printf("%s: UNSOLICITED_STATE_ENABLE (%d:ignore)\n", 1867 __func__, login_id); 1868 break; 1869 default: 1870 printf("%s: invalid register %d(%d)\n", 1871 __func__, reg, login_id); 1872 rtcode = RESP_ADDRESS_ERROR; 1873 } 1874 1875 return (rtcode); 1876 } 1877 1878 static int 1879 sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev) 1880 { 1881 struct sbp_targ_softc *sc; 1882 struct fw_pkt *fp; 1883 1884 sc = (struct sbp_targ_softc *)xfer->sc; 1885 1886 fp = &xfer->recv.hdr; 1887 if (fp->mode.wreqb.tcode != FWTCODE_WREQB) { 1888 printf("%s: tcode = %d\n", __func__, fp->mode.wreqb.tcode); 1889 return (RESP_TYPE_ERROR); 1890 } 1891 1892 sbp_targ_fetch_orb(sc, fwdev, 1893 ntohl(xfer->recv.payload[0]), 1894 ntohl(xfer->recv.payload[1]), 1895 NULL, FETCH_MGM); 1896 1897 return (0); 1898 } 1899 1900 static void 1901 sbp_targ_recv(struct fw_xfer *xfer) 1902 { 1903 struct fw_pkt *fp, *sfp; 1904 struct fw_device *fwdev; 1905 uint32_t lo; 1906 int s, rtcode; 1907 struct sbp_targ_softc *sc; 1908 1909 s = splfw(); 1910 sc = (struct sbp_targ_softc *)xfer->sc; 1911 fp = &xfer->recv.hdr; 1912 fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); 1913 if (fwdev == NULL) { 1914 printf("%s: cannot resolve nodeid=%d\n", 1915 __func__, fp->mode.wreqb.src & 0x3f); 1916 rtcode = RESP_TYPE_ERROR; /* XXX */ 1917 goto done; 1918 } 1919 lo = fp->mode.wreqb.dest_lo; 1920 1921 if (lo == SBP_TARG_BIND_LO(-1)) 1922 rtcode = sbp_targ_mgm(xfer, fwdev); 1923 else if (lo >= SBP_TARG_BIND_LO(0)) 1924 rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), 1925 lo % 0x20); 1926 else 1927 rtcode = RESP_ADDRESS_ERROR; 1928 1929 done: 1930 if (rtcode != 0) 1931 printf("%s: rtcode = %d\n", __func__, rtcode); 1932 sfp = &xfer->send.hdr; 1933 xfer->send.spd = FWSPD_S400; 1934 xfer->hand = sbp_targ_resp_callback; 1935 sfp->mode.wres.dst = fp->mode.wreqb.src; 1936 sfp->mode.wres.tlrt = fp->mode.wreqb.tlrt; 1937 sfp->mode.wres.tcode = FWTCODE_WRES; 1938 sfp->mode.wres.rtcode = rtcode; 1939 sfp->mode.wres.pri = 0; 1940 1941 fw_asyreq(xfer->fc, -1, xfer); 1942 splx(s); 1943 } 1944 1945 static int 1946 sbp_targ_attach(device_t dev) 1947 { 1948 struct sbp_targ_softc *sc; 1949 struct cam_devq *devq; 1950 struct firewire_comm *fc; 1951 1952 sc = (struct sbp_targ_softc *) device_get_softc(dev); 1953 bzero((void *)sc, sizeof(struct sbp_targ_softc)); 1954 1955 mtx_init(&sc->mtx, "sbp_targ", NULL, MTX_DEF); 1956 sc->fd.fc = fc = device_get_ivars(dev); 1957 sc->fd.dev = dev; 1958 sc->fd.post_explore = (void *) sbp_targ_post_explore; 1959 sc->fd.post_busreset = (void *) sbp_targ_post_busreset; 1960 1961 devq = cam_simq_alloc(/*maxopenings*/MAX_LUN*MAX_INITIATORS); 1962 if (devq == NULL) 1963 return (ENXIO); 1964 1965 sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll, 1966 "sbp_targ", sc, device_get_unit(dev), &sc->mtx, 1967 /*untagged*/ 1, /*tagged*/ 1, devq); 1968 if (sc->sim == NULL) { 1969 cam_simq_free(devq); 1970 return (ENXIO); 1971 } 1972 1973 SBP_LOCK(sc); 1974 if (xpt_bus_register(sc->sim, dev, /*bus*/0) != CAM_SUCCESS) 1975 goto fail; 1976 1977 if (xpt_create_path(&sc->path, /*periph*/ NULL, cam_sim_path(sc->sim), 1978 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1979 xpt_bus_deregister(cam_sim_path(sc->sim)); 1980 goto fail; 1981 } 1982 SBP_UNLOCK(sc); 1983 1984 sc->fwb.start = SBP_TARG_BIND_START; 1985 sc->fwb.end = SBP_TARG_BIND_END; 1986 1987 /* pre-allocate xfer */ 1988 STAILQ_INIT(&sc->fwb.xferlist); 1989 fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, 1990 /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, 1991 fc, (void *)sc, sbp_targ_recv); 1992 fw_bindadd(fc, &sc->fwb); 1993 return 0; 1994 1995 fail: 1996 SBP_UNLOCK(sc); 1997 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1998 return (ENXIO); 1999 } 2000 2001 static int 2002 sbp_targ_detach(device_t dev) 2003 { 2004 struct sbp_targ_softc *sc; 2005 struct sbp_targ_lstate *lstate; 2006 int i; 2007 2008 sc = (struct sbp_targ_softc *)device_get_softc(dev); 2009 sc->fd.post_busreset = NULL; 2010 2011 SBP_LOCK(sc); 2012 xpt_free_path(sc->path); 2013 xpt_bus_deregister(cam_sim_path(sc->sim)); 2014 cam_sim_free(sc->sim, /*free_devq*/TRUE); 2015 SBP_UNLOCK(sc); 2016 2017 for (i = 0; i < MAX_LUN; i++) { 2018 lstate = sc->lstate[i]; 2019 if (lstate != NULL) { 2020 xpt_free_path(lstate->path); 2021 free(lstate, M_SBP_TARG); 2022 } 2023 } 2024 if (sc->black_hole != NULL) { 2025 xpt_free_path(sc->black_hole->path); 2026 free(sc->black_hole, M_SBP_TARG); 2027 } 2028 2029 fw_bindremove(sc->fd.fc, &sc->fwb); 2030 fw_xferlist_remove(&sc->fwb.xferlist); 2031 2032 mtx_destroy(&sc->mtx); 2033 2034 return 0; 2035 } 2036 2037 static devclass_t sbp_targ_devclass; 2038 2039 static device_method_t sbp_targ_methods[] = { 2040 /* device interface */ 2041 DEVMETHOD(device_identify, sbp_targ_identify), 2042 DEVMETHOD(device_probe, sbp_targ_probe), 2043 DEVMETHOD(device_attach, sbp_targ_attach), 2044 DEVMETHOD(device_detach, sbp_targ_detach), 2045 { 0, 0 } 2046 }; 2047 2048 static driver_t sbp_targ_driver = { 2049 "sbp_targ", 2050 sbp_targ_methods, 2051 sizeof(struct sbp_targ_softc), 2052 }; 2053 2054 DRIVER_MODULE(sbp_targ, firewire, sbp_targ_driver, sbp_targ_devclass, 0, 0); 2055 MODULE_VERSION(sbp_targ, 1); 2056 MODULE_DEPEND(sbp_targ, firewire, 1, 1, 1); 2057 MODULE_DEPEND(sbp_targ, cam, 1, 1, 1); 2058