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