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