sbp_targ.c (169475) | sbp_targ.c (170374) |
---|---|
1/*- 2 * Copyright (C) 2003 3 * Hidetoshi Shimokawa. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * | 1/*- 2 * Copyright (C) 2003 3 * Hidetoshi Shimokawa. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * |
34 * $FreeBSD: head/sys/dev/firewire/sbp_targ.c 169475 2007-05-11 14:51:13Z simokawa $ | 34 * $FreeBSD: head/sys/dev/firewire/sbp_targ.c 170374 2007-06-06 14:31:36Z simokawa $ |
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> --- 92 unchanged lines hidden (view full) --- 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]; | 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> --- 92 unchanged lines hidden (view full) --- 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; |
|
143}; | 144}; |
145#define SBP_LOCK(sc) mtx_lock(&(sc)->mtx) 146#define SBP_UNLOCK(sc) mtx_unlock(&(sc)->mtx) |
|
144 145struct corb4 { 146#if BYTE_ORDER == BIG_ENDIAN 147 uint32_t n:1, 148 rq_fmt:2, 149 :1, 150 dir:1, 151 spd:3, --- 58 unchanged lines hidden (view full) --- 210 211static char *orb_fun_name[] = { 212 ORB_FUN_NAMES 213}; 214 215static void sbp_targ_recv(struct fw_xfer *); 216static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *, 217 uint16_t, uint32_t, struct sbp_targ_login *, int); | 147 148struct corb4 { 149#if BYTE_ORDER == BIG_ENDIAN 150 uint32_t n:1, 151 rq_fmt:2, 152 :1, 153 dir:1, 154 spd:3, --- 58 unchanged lines hidden (view full) --- 213 214static char *orb_fun_name[] = { 215 ORB_FUN_NAMES 216}; 217 218static void sbp_targ_recv(struct fw_xfer *); 219static void sbp_targ_fetch_orb(struct sbp_targ_softc *, struct fw_device *, 220 uint16_t, uint32_t, struct sbp_targ_login *, int); |
221static void sbp_targ_abort(struct sbp_targ_softc *, struct orb_info *); |
|
218 219static void 220sbp_targ_identify(driver_t *driver, device_t parent) 221{ 222 BUS_ADD_CHILD(parent, 0, "sbp_targ", device_get_unit(parent)); 223} 224 225static int --- 58 unchanged lines hidden (view full) --- 284 285 sc = (struct sbp_targ_softc *)arg; 286 src = sc->fd.fc->crom_src; 287 root = sc->fd.fc->crom_root; 288 289 unit = &sc->unit; 290 291 if ((sc->flags & F_FREEZED) == 0) { | 222 223static void 224sbp_targ_identify(driver_t *driver, device_t parent) 225{ 226 BUS_ADD_CHILD(parent, 0, "sbp_targ", device_get_unit(parent)); 227} 228 229static int --- 58 unchanged lines hidden (view full) --- 288 289 sc = (struct sbp_targ_softc *)arg; 290 src = sc->fd.fc->crom_src; 291 root = sc->fd.fc->crom_root; 292 293 unit = &sc->unit; 294 295 if ((sc->flags & F_FREEZED) == 0) { |
296 SBP_LOCK(sc); |
|
292 sc->flags |= F_FREEZED; 293 xpt_freeze_simq(sc->sim, /*count*/1); | 297 sc->flags |= F_FREEZED; 298 xpt_freeze_simq(sc->sim, /*count*/1); |
299 SBP_UNLOCK(sc); |
|
294 } else { 295 printf("%s: already freezed\n", __func__); 296 } 297 298 bzero(unit, sizeof(struct crom_chunk)); 299 300 crom_add_chunk(src, root, unit, CROM_UDIR); 301 crom_add_entry(unit, CSRKEY_SPEC, CSRVAL_ANSIT10); --- 14 unchanged lines hidden (view full) --- 316 crom_add_simple_text(src, unit, &lstate->model, "TargetMode"); 317 } 318 319 /* Process for reconnection hold time */ 320 for (i = 0; i < MAX_LOGINS; i ++) { 321 login = sc->logins[i]; 322 if (login == NULL) 323 continue; | 300 } else { 301 printf("%s: already freezed\n", __func__); 302 } 303 304 bzero(unit, sizeof(struct crom_chunk)); 305 306 crom_add_chunk(src, root, unit, CROM_UDIR); 307 crom_add_entry(unit, CSRKEY_SPEC, CSRVAL_ANSIT10); --- 14 unchanged lines hidden (view full) --- 322 crom_add_simple_text(src, unit, &lstate->model, "TargetMode"); 323 } 324 325 /* Process for reconnection hold time */ 326 for (i = 0; i < MAX_LOGINS; i ++) { 327 login = sc->logins[i]; 328 if (login == NULL) 329 continue; |
330 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); |
|
324 if (login->flags & F_LOGIN) { 325 login->flags |= F_HOLD; 326 callout_reset(&login->hold_callout, 327 hz * login->hold_sec, 328 sbp_targ_hold_expire, (void *)login); 329 } 330 } 331} 332 333static void 334sbp_targ_post_explore(void *arg) 335{ 336 struct sbp_targ_softc *sc; 337 338 sc = (struct sbp_targ_softc *)arg; | 331 if (login->flags & F_LOGIN) { 332 login->flags |= F_HOLD; 333 callout_reset(&login->hold_callout, 334 hz * login->hold_sec, 335 sbp_targ_hold_expire, (void *)login); 336 } 337 } 338} 339 340static void 341sbp_targ_post_explore(void *arg) 342{ 343 struct sbp_targ_softc *sc; 344 345 sc = (struct sbp_targ_softc *)arg; |
346 SBP_LOCK(sc); |
|
339 sc->flags &= ~F_FREEZED; 340 xpt_release_simq(sc->sim, /*run queue*/TRUE); | 347 sc->flags &= ~F_FREEZED; 348 xpt_release_simq(sc->sim, /*run queue*/TRUE); |
349 SBP_UNLOCK(sc); |
|
341 return; 342} 343 344static cam_status 345sbp_targ_find_devs(struct sbp_targ_softc *sc, union ccb *ccb, 346 struct sbp_targ_lstate **lstate, int notfound_failure) 347{ 348 u_int lun; --- 130 unchanged lines hidden (view full) --- 479#if 0 480 struct ccb_hdr *ccbh; 481 struct ccb_immed_notify *inot; 482 483 printf("%s: not implemented yet\n", __func__); 484#endif 485} 486 | 350 return; 351} 352 353static cam_status 354sbp_targ_find_devs(struct sbp_targ_softc *sc, union ccb *ccb, 355 struct sbp_targ_lstate **lstate, int notfound_failure) 356{ 357 u_int lun; --- 130 unchanged lines hidden (view full) --- 488#if 0 489 struct ccb_hdr *ccbh; 490 struct ccb_immed_notify *inot; 491 492 printf("%s: not implemented yet\n", __func__); 493#endif 494} 495 |
496 |
|
487static __inline void | 497static __inline void |
498sbp_targ_remove_orb_info_locked(struct sbp_targ_login *login, struct orb_info *orbi) 499{ 500 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); 501} 502 503static __inline void |
|
488sbp_targ_remove_orb_info(struct sbp_targ_login *login, struct orb_info *orbi) 489{ | 504sbp_targ_remove_orb_info(struct sbp_targ_login *login, struct orb_info *orbi) 505{ |
506 SBP_LOCK(orbi->sc); |
|
490 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); | 507 STAILQ_REMOVE(&login->orbs, orbi, orb_info, link); |
508 SBP_UNLOCK(orbi->sc); |
|
491} 492 493/* 494 * tag_id/init_id encoding 495 * 496 * tag_id and init_id has only 32bit for each. 497 * scsi_target can handle very limited number(up to 15) of init_id. 498 * we have to encode 48bit orb and 64bit EUI64 into these --- 14 unchanged lines hidden (view full) --- 513 login = lstate->sc->logins[init_id]; 514 if (login == NULL) { 515 printf("%s: no such login\n", __func__); 516 return (NULL); 517 } 518 STAILQ_FOREACH(orbi, &login->orbs, link) 519 if (orbi->orb_lo == tag_id) 520 goto found; | 509} 510 511/* 512 * tag_id/init_id encoding 513 * 514 * tag_id and init_id has only 32bit for each. 515 * scsi_target can handle very limited number(up to 15) of init_id. 516 * we have to encode 48bit orb and 64bit EUI64 into these --- 14 unchanged lines hidden (view full) --- 531 login = lstate->sc->logins[init_id]; 532 if (login == NULL) { 533 printf("%s: no such login\n", __func__); 534 return (NULL); 535 } 536 STAILQ_FOREACH(orbi, &login->orbs, link) 537 if (orbi->orb_lo == tag_id) 538 goto found; |
521 printf("%s: orb not found tag_id=0x%08x\n", __func__, tag_id); | 539 printf("%s: orb not found tag_id=0x%08x init_id=%d\n", 540 __func__, tag_id, init_id); |
522 return (NULL); 523found: 524 return (orbi); 525} 526 527static void | 541 return (NULL); 542found: 543 return (orbi); 544} 545 546static void |
528sbp_targ_abort(struct orb_info *orbi) | 547sbp_targ_abort(struct sbp_targ_softc *sc, struct orb_info *orbi) |
529{ 530 struct orb_info *norbi; 531 | 548{ 549 struct orb_info *norbi; 550 |
551 SBP_LOCK(sc); |
|
532 for (; orbi != NULL; orbi = norbi) { | 552 for (; orbi != NULL; orbi = norbi) { |
533 printf("%s: status=%d\n", __func__, orbi->state); | 553 printf("%s: status=%d ccb=%p\n", __func__, orbi->state, orbi->ccb); |
534 norbi = STAILQ_NEXT(orbi, link); 535 if (orbi->state != ORBI_STATUS_ABORTED) { 536 if (orbi->ccb != NULL) { 537 orbi->ccb->ccb_h.status = CAM_REQ_ABORTED; 538 xpt_done(orbi->ccb); 539 orbi->ccb = NULL; 540 } | 554 norbi = STAILQ_NEXT(orbi, link); 555 if (orbi->state != ORBI_STATUS_ABORTED) { 556 if (orbi->ccb != NULL) { 557 orbi->ccb->ccb_h.status = CAM_REQ_ABORTED; 558 xpt_done(orbi->ccb); 559 orbi->ccb = NULL; 560 } |
561#if 0 |
|
541 if (orbi->state <= ORBI_STATUS_ATIO) { | 562 if (orbi->state <= ORBI_STATUS_ATIO) { |
542 sbp_targ_remove_orb_info(orbi->login, orbi); | 563 sbp_targ_remove_orb_info_locked(orbi->login, orbi); |
543 free(orbi, M_SBP_TARG); 544 } else | 564 free(orbi, M_SBP_TARG); 565 } else |
566#endif |
|
545 orbi->state = ORBI_STATUS_ABORTED; 546 } 547 } | 567 orbi->state = ORBI_STATUS_ABORTED; 568 } 569 } |
570 SBP_UNLOCK(sc); |
|
548} 549 550static void 551sbp_targ_free_orbi(struct fw_xfer *xfer) 552{ 553 struct orb_info *orbi; 554 555 orbi = (struct orb_info *)xfer->sc; --- 24 unchanged lines hidden (view full) --- 580 printf("%s: xfer == NULL\n", __func__); 581 } 582} 583 584static void 585sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb) 586{ 587 struct sbp_status *sbp_status; | 571} 572 573static void 574sbp_targ_free_orbi(struct fw_xfer *xfer) 575{ 576 struct orb_info *orbi; 577 578 orbi = (struct orb_info *)xfer->sc; --- 24 unchanged lines hidden (view full) --- 603 printf("%s: xfer == NULL\n", __func__); 604 } 605} 606 607static void 608sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb) 609{ 610 struct sbp_status *sbp_status; |
611 struct orb_info *norbi; |
|
588 589 sbp_status = &orbi->status; 590 591 orbi->state = ORBI_STATUS_STATUS; 592 593 sbp_status->resp = 0; /* XXX */ 594 sbp_status->status = 0; /* XXX */ 595 sbp_status->dead = 0; /* XXX */ --- 13 unchanged lines hidden (view full) --- 609 610 if (debug) 611 printf("%s: STATUS %d\n", __func__, 612 ccb->csio.scsi_status); 613 sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0]; 614 sbp_cmd_status->status = ccb->csio.scsi_status; 615 sense = &ccb->csio.sense_data; 616 | 612 613 sbp_status = &orbi->status; 614 615 orbi->state = ORBI_STATUS_STATUS; 616 617 sbp_status->resp = 0; /* XXX */ 618 sbp_status->status = 0; /* XXX */ 619 sbp_status->dead = 0; /* XXX */ --- 13 unchanged lines hidden (view full) --- 633 634 if (debug) 635 printf("%s: STATUS %d\n", __func__, 636 ccb->csio.scsi_status); 637 sbp_cmd_status = (struct sbp_cmd_status *)&sbp_status->data[0]; 638 sbp_cmd_status->status = ccb->csio.scsi_status; 639 sense = &ccb->csio.sense_data; 640 |
617 sbp_targ_abort(STAILQ_NEXT(orbi, link)); | 641#if 0 /* XXX What we should do? */ 642#if 0 643 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); 644#else 645 norbi = STAILQ_NEXT(orbi, link); 646 while (norbi) { 647 printf("%s: status=%d\n", __func__, norbi->state); 648 if (norbi->ccb != NULL) { 649 norbi->ccb->ccb_h.status = CAM_REQ_ABORTED; 650 xpt_done(norbi->ccb); 651 norbi->ccb = NULL; 652 } 653 sbp_targ_remove_orb_info_locked(orbi->login, norbi); 654 norbi = STAILQ_NEXT(norbi, link); 655 free(norbi, M_SBP_TARG); 656 } 657#endif 658#endif |
618 619 if ((sense->error_code & SSD_ERRCODE) == SSD_CURRENT_ERROR) 620 sbp_cmd_status->sfmt = SBP_SFMT_CURR; 621 else 622 sbp_cmd_status->sfmt = SBP_SFMT_DEFER; 623 624 sbp_cmd_status->valid = (sense->error_code & SSD_ERRCODE_VALID) 625 ? 1 : 0; --- 22 unchanged lines hidden (view full) --- 648 649 break; 650 } 651 default: 652 printf("%s: unknown scsi status 0x%x\n", __func__, 653 sbp_status->status); 654 } 655 | 659 660 if ((sense->error_code & SSD_ERRCODE) == SSD_CURRENT_ERROR) 661 sbp_cmd_status->sfmt = SBP_SFMT_CURR; 662 else 663 sbp_cmd_status->sfmt = SBP_SFMT_DEFER; 664 665 sbp_cmd_status->valid = (sense->error_code & SSD_ERRCODE_VALID) 666 ? 1 : 0; --- 22 unchanged lines hidden (view full) --- 689 690 break; 691 } 692 default: 693 printf("%s: unknown scsi status 0x%x\n", __func__, 694 sbp_status->status); 695 } 696 |
656 sbp_targ_status_FIFO(orbi, 657 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 658 | |
659 if (orbi->page_table != NULL) 660 free(orbi->page_table, M_SBP_TARG); | 697 if (orbi->page_table != NULL) 698 free(orbi->page_table, M_SBP_TARG); |
699 700 sbp_targ_status_FIFO(orbi, 701 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); |
|
661} 662 663static void 664sbp_targ_cam_done(struct fw_xfer *xfer) 665{ 666 struct orb_info *orbi; 667 union ccb *ccb; 668 669 orbi = (struct orb_info *)xfer->sc; 670 671 if (debug > 1) 672 printf("%s: resp=%d refcount=%d\n", __func__, 673 xfer->resp, orbi->refcount); 674 675 if (xfer->resp != 0) { 676 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 677 orbi->status.resp = SBP_TRANS_FAIL; 678 orbi->status.status = OBJ_DATA | SBE_TIMEOUT/*XXX*/; 679 orbi->status.dead = 1; | 702} 703 704static void 705sbp_targ_cam_done(struct fw_xfer *xfer) 706{ 707 struct orb_info *orbi; 708 union ccb *ccb; 709 710 orbi = (struct orb_info *)xfer->sc; 711 712 if (debug > 1) 713 printf("%s: resp=%d refcount=%d\n", __func__, 714 xfer->resp, orbi->refcount); 715 716 if (xfer->resp != 0) { 717 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 718 orbi->status.resp = SBP_TRANS_FAIL; 719 orbi->status.status = OBJ_DATA | SBE_TIMEOUT/*XXX*/; 720 orbi->status.dead = 1; |
680 sbp_targ_abort(STAILQ_NEXT(orbi, link)); | 721 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); |
681 } 682 683 orbi->refcount --; 684 685 ccb = orbi->ccb; 686 if (orbi->refcount == 0) { | 722 } 723 724 orbi->refcount --; 725 726 ccb = orbi->ccb; 727 if (orbi->refcount == 0) { |
728 orbi->ccb = NULL; |
|
687 if (orbi->state == ORBI_STATUS_ABORTED) { 688 if (debug) 689 printf("%s: orbi aborted\n", __func__); 690 sbp_targ_remove_orb_info(orbi->login, orbi); 691 if (orbi->page_table != NULL) 692 free(orbi->page_table, M_SBP_TARG); 693 free(orbi, M_SBP_TARG); 694 } else if (orbi->status.resp == 0) { 695 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) 696 sbp_targ_send_status(orbi, ccb); 697 ccb->ccb_h.status = CAM_REQ_CMP; | 729 if (orbi->state == ORBI_STATUS_ABORTED) { 730 if (debug) 731 printf("%s: orbi aborted\n", __func__); 732 sbp_targ_remove_orb_info(orbi->login, orbi); 733 if (orbi->page_table != NULL) 734 free(orbi->page_table, M_SBP_TARG); 735 free(orbi, M_SBP_TARG); 736 } else if (orbi->status.resp == 0) { 737 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) 738 sbp_targ_send_status(orbi, ccb); 739 ccb->ccb_h.status = CAM_REQ_CMP; |
740 SBP_LOCK(orbi->sc); |
|
698 xpt_done(ccb); | 741 xpt_done(ccb); |
742 SBP_UNLOCK(orbi->sc); |
|
699 } else { 700 orbi->status.len = 1; 701 sbp_targ_status_FIFO(orbi, 702 orbi->login->fifo_hi, orbi->login->fifo_lo, 703 /*dequeue*/1); 704 ccb->ccb_h.status = CAM_REQ_ABORTED; | 743 } else { 744 orbi->status.len = 1; 745 sbp_targ_status_FIFO(orbi, 746 orbi->login->fifo_hi, orbi->login->fifo_lo, 747 /*dequeue*/1); 748 ccb->ccb_h.status = CAM_REQ_ABORTED; |
749 SBP_LOCK(orbi->sc); |
|
705 xpt_done(ccb); | 750 xpt_done(ccb); |
751 SBP_UNLOCK(orbi->sc); |
|
706 } 707 } 708 709 fw_xfer_free(xfer); 710} 711 712static cam_status 713sbp_targ_abort_ccb(struct sbp_targ_softc *sc, union ccb *ccb) --- 104 unchanged lines hidden (view full) --- 818 return; 819 } 820 if (xfer->resp != 0) { 821 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 822 orbi->status.resp = SBP_TRANS_FAIL; 823 orbi->status.status = OBJ_PT | SBE_TIMEOUT/*XXX*/; 824 orbi->status.dead = 1; 825 orbi->status.len = 1; | 752 } 753 } 754 755 fw_xfer_free(xfer); 756} 757 758static cam_status 759sbp_targ_abort_ccb(struct sbp_targ_softc *sc, union ccb *ccb) --- 104 unchanged lines hidden (view full) --- 864 return; 865 } 866 if (xfer->resp != 0) { 867 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 868 orbi->status.resp = SBP_TRANS_FAIL; 869 orbi->status.status = OBJ_PT | SBE_TIMEOUT/*XXX*/; 870 orbi->status.dead = 1; 871 orbi->status.len = 1; |
826 sbp_targ_abort(STAILQ_NEXT(orbi, link)); | 872 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); |
827 828 sbp_targ_status_FIFO(orbi, 829 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 830 free(orbi->page_table, M_SBP_TARG); 831 fw_xfer_free(xfer); 832 return; 833 } 834 res = ccb->csio.dxfer_len; --- 61 unchanged lines hidden (view full) --- 896 status = sbp_targ_find_devs(sc, ccb, &lstate, TRUE); 897 898 switch (ccb->ccb_h.func_code) { 899 case XPT_CONT_TARGET_IO: 900 { 901 struct orb_info *orbi; 902 903 if (debug) | 873 874 sbp_targ_status_FIFO(orbi, 875 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 876 free(orbi->page_table, M_SBP_TARG); 877 fw_xfer_free(xfer); 878 return; 879 } 880 res = ccb->csio.dxfer_len; --- 61 unchanged lines hidden (view full) --- 942 status = sbp_targ_find_devs(sc, ccb, &lstate, TRUE); 943 944 switch (ccb->ccb_h.func_code) { 945 case XPT_CONT_TARGET_IO: 946 { 947 struct orb_info *orbi; 948 949 if (debug) |
904 printf("%s: XPT_CONT_TARGET_IO\n", __func__); | 950 printf("%s: XPT_CONT_TARGET_IO (0x%08x)\n", 951 __func__, ccb->csio.tag_id); |
905 906 if (status != CAM_REQ_CMP) { 907 ccb->ccb_h.status = status; 908 xpt_done(ccb); 909 break; 910 } 911 /* XXX transfer from/to initiator */ 912 orbi = sbp_targ_get_orb_info(lstate, 913 ccb->csio.tag_id, ccb->csio.init_id); 914 if (orbi == NULL) { 915 ccb->ccb_h.status = CAM_REQ_ABORTED; /* XXX */ 916 xpt_done(ccb); 917 break; 918 } 919 if (orbi->state == ORBI_STATUS_ABORTED) { 920 if (debug) 921 printf("%s: ctio aborted\n", __func__); | 952 953 if (status != CAM_REQ_CMP) { 954 ccb->ccb_h.status = status; 955 xpt_done(ccb); 956 break; 957 } 958 /* XXX transfer from/to initiator */ 959 orbi = sbp_targ_get_orb_info(lstate, 960 ccb->csio.tag_id, ccb->csio.init_id); 961 if (orbi == NULL) { 962 ccb->ccb_h.status = CAM_REQ_ABORTED; /* XXX */ 963 xpt_done(ccb); 964 break; 965 } 966 if (orbi->state == ORBI_STATUS_ABORTED) { 967 if (debug) 968 printf("%s: ctio aborted\n", __func__); |
922 sbp_targ_remove_orb_info(orbi->login, orbi); | 969 sbp_targ_remove_orb_info_locked(orbi->login, orbi); |
923 free(orbi, M_SBP_TARG); | 970 free(orbi, M_SBP_TARG); |
971 ccb->ccb_h.status = CAM_REQ_ABORTED; 972 xpt_done(ccb); |
|
924 break; 925 } 926 orbi->state = ORBI_STATUS_CTIO; 927 928 orbi->ccb = ccb; 929 ccb_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 930 931 /* XXX */ --- 29 unchanged lines hidden (view full) --- 961 962 if (ccb_dir != CAM_DIR_NONE) 963 sbp_targ_xfer_buf(orbi, 0, orbi->data_hi, 964 orbi->data_lo, 965 MIN(orbi->orb4.data_size, ccb->csio.dxfer_len), 966 sbp_targ_cam_done); 967 968 if (ccb_dir == CAM_DIR_NONE) { | 973 break; 974 } 975 orbi->state = ORBI_STATUS_CTIO; 976 977 orbi->ccb = ccb; 978 ccb_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 979 980 /* XXX */ --- 29 unchanged lines hidden (view full) --- 1010 1011 if (ccb_dir != CAM_DIR_NONE) 1012 sbp_targ_xfer_buf(orbi, 0, orbi->data_hi, 1013 orbi->data_lo, 1014 MIN(orbi->orb4.data_size, ccb->csio.dxfer_len), 1015 sbp_targ_cam_done); 1016 1017 if (ccb_dir == CAM_DIR_NONE) { |
969 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) | 1018 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 1019 /* XXX */ 1020 SBP_UNLOCK(sc); |
970 sbp_targ_send_status(orbi, ccb); | 1021 sbp_targ_send_status(orbi, ccb); |
1022 SBP_LOCK(sc); 1023 } |
|
971 ccb->ccb_h.status = CAM_REQ_CMP; 972 xpt_done(ccb); 973 } 974 break; 975 } 976 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 977 if (status != CAM_REQ_CMP) { 978 ccb->ccb_h.status = status; --- 122 unchanged lines hidden (view full) --- 1101 1102 orbi = (struct orb_info *)xfer->sc; 1103 if (xfer->resp != 0) { 1104 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1105 orbi->status.resp = SBP_TRANS_FAIL; 1106 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1107 orbi->status.dead = 1; 1108 orbi->status.len = 1; | 1024 ccb->ccb_h.status = CAM_REQ_CMP; 1025 xpt_done(ccb); 1026 } 1027 break; 1028 } 1029 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 1030 if (status != CAM_REQ_CMP) { 1031 ccb->ccb_h.status = status; --- 122 unchanged lines hidden (view full) --- 1154 1155 orbi = (struct orb_info *)xfer->sc; 1156 if (xfer->resp != 0) { 1157 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1158 orbi->status.resp = SBP_TRANS_FAIL; 1159 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1160 orbi->status.dead = 1; 1161 orbi->status.len = 1; |
1109 sbp_targ_abort(STAILQ_NEXT(orbi, link)); | 1162 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); |
1110 1111 sbp_targ_status_FIFO(orbi, 1112 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 1113 fw_xfer_free(xfer); 1114 return; 1115 } 1116 fp = &xfer->recv.hdr; 1117 | 1163 1164 sbp_targ_status_FIFO(orbi, 1165 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/1); 1166 fw_xfer_free(xfer); 1167 return; 1168 } 1169 fp = &xfer->recv.hdr; 1170 |
1171 atio = orbi->atio; 1172 |
|
1118 if (orbi->state == ORBI_STATUS_ABORTED) { 1119 printf("%s: aborted\n", __func__); 1120 sbp_targ_remove_orb_info(orbi->login, orbi); 1121 free(orbi, M_SBP_TARG); | 1173 if (orbi->state == ORBI_STATUS_ABORTED) { 1174 printf("%s: aborted\n", __func__); 1175 sbp_targ_remove_orb_info(orbi->login, orbi); 1176 free(orbi, M_SBP_TARG); |
1177 atio->ccb_h.status = CAM_REQ_ABORTED; 1178 SBP_LOCK(orbi->sc); 1179 xpt_done((union ccb*)atio); 1180 SBP_UNLOCK(orbi->sc); |
|
1122 goto done0; 1123 } 1124 orbi->state = ORBI_STATUS_ATIO; 1125 1126 orb = orbi->orb; 1127 /* swap payload except SCSI command */ 1128 for (i = 0; i < 5; i ++) 1129 orb[i] = ntohl(orb[i]); 1130 1131 orb4 = (struct corb4 *)&orb[4]; 1132 if (orb4->rq_fmt != 0) { 1133 /* XXX */ 1134 printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt); 1135 } 1136 | 1181 goto done0; 1182 } 1183 orbi->state = ORBI_STATUS_ATIO; 1184 1185 orb = orbi->orb; 1186 /* swap payload except SCSI command */ 1187 for (i = 0; i < 5; i ++) 1188 orb[i] = ntohl(orb[i]); 1189 1190 orb4 = (struct corb4 *)&orb[4]; 1191 if (orb4->rq_fmt != 0) { 1192 /* XXX */ 1193 printf("%s: rq_fmt(%d) != 0\n", __func__, orb4->rq_fmt); 1194 } 1195 |
1137 atio = orbi->atio; | |
1138 atio->ccb_h.target_id = 0; /* XXX */ 1139 atio->ccb_h.target_lun = orbi->login->lstate->lun; 1140 atio->sense_len = 0; 1141 atio->tag_action = 1; /* XXX */ 1142 atio->tag_id = orbi->orb_lo; 1143 atio->init_id = orbi->login->id; 1144 1145 atio->ccb_h.flags = CAM_TAG_ACTION_VALID; | 1196 atio->ccb_h.target_id = 0; /* XXX */ 1197 atio->ccb_h.target_lun = orbi->login->lstate->lun; 1198 atio->sense_len = 0; 1199 atio->tag_action = 1; /* XXX */ 1200 atio->tag_id = orbi->orb_lo; 1201 atio->init_id = orbi->login->id; 1202 1203 atio->ccb_h.flags = CAM_TAG_ACTION_VALID; |
1146 bytes = (char *)&orb[5]; | 1204 bytes = (u_char *)&orb[5]; |
1147 if (debug) | 1205 if (debug) |
1148 printf("%s: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1149 __func__, | 1206 printf("%s: %p %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", 1207 __func__, (void *)atio, |
1150 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], 1151 bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]); 1152 switch (bytes[0] >> 5) { 1153 case 0: 1154 atio->cdb_len = 6; 1155 break; 1156 case 1: 1157 case 2: --- 28 unchanged lines hidden (view full) --- 1186 orbi->status.src = SRC_NO_NEXT; 1187 orbi->login->flags &= ~F_LINK_ACTIVE; 1188 } 1189 1190 orbi->data_hi = orb[2]; 1191 orbi->data_lo = orb[3]; 1192 orbi->orb4 = *orb4; 1193 | 1208 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], 1209 bytes[5], bytes[6], bytes[7], bytes[8], bytes[9]); 1210 switch (bytes[0] >> 5) { 1211 case 0: 1212 atio->cdb_len = 6; 1213 break; 1214 case 1: 1215 case 2: --- 28 unchanged lines hidden (view full) --- 1244 orbi->status.src = SRC_NO_NEXT; 1245 orbi->login->flags &= ~F_LINK_ACTIVE; 1246 } 1247 1248 orbi->data_hi = orb[2]; 1249 orbi->data_lo = orb[3]; 1250 orbi->orb4 = *orb4; 1251 |
1252 SBP_LOCK(orbi->sc); |
|
1194 xpt_done((union ccb*)atio); | 1253 xpt_done((union ccb*)atio); |
1254 SBP_UNLOCK(orbi->sc); |
|
1195done0: 1196 fw_xfer_free(xfer); 1197 return; 1198} 1199 1200static struct sbp_targ_login * 1201sbp_targ_get_login(struct sbp_targ_softc *sc, struct fw_device *fwdev, int lun) 1202{ --- 48 unchanged lines hidden (view full) --- 1251 1252 orbi = (struct orb_info *)xfer->sc; 1253 if (xfer->resp != 0) { 1254 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1255 orbi->status.resp = SBP_TRANS_FAIL; 1256 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1257 orbi->status.dead = 1; 1258 orbi->status.len = 1; | 1255done0: 1256 fw_xfer_free(xfer); 1257 return; 1258} 1259 1260static struct sbp_targ_login * 1261sbp_targ_get_login(struct sbp_targ_softc *sc, struct fw_device *fwdev, int lun) 1262{ --- 48 unchanged lines hidden (view full) --- 1311 1312 orbi = (struct orb_info *)xfer->sc; 1313 if (xfer->resp != 0) { 1314 printf("%s: xfer->resp = %d\n", __func__, xfer->resp); 1315 orbi->status.resp = SBP_TRANS_FAIL; 1316 orbi->status.status = OBJ_ORB | SBE_TIMEOUT/*XXX*/; 1317 orbi->status.dead = 1; 1318 orbi->status.len = 1; |
1259 sbp_targ_abort(STAILQ_NEXT(orbi, link)); | 1319 sbp_targ_abort(orbi->sc, STAILQ_NEXT(orbi, link)); |
1260 1261 sbp_targ_status_FIFO(orbi, 1262 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0); 1263 fw_xfer_free(xfer); 1264 return; 1265 } 1266 fp = &xfer->recv.hdr; 1267 --- 36 unchanged lines hidden (view full) --- 1304 if (login == NULL) { 1305 printf("%s: sbp_targ_get_login failed\n", 1306 __func__); 1307 orbi->status.dead = 1; 1308 orbi->status.status = STATUS_RES_UNAVAIL; 1309 orbi->status.len = 1; 1310 break; 1311 } | 1320 1321 sbp_targ_status_FIFO(orbi, 1322 orbi->login->fifo_hi, orbi->login->fifo_lo, /*dequeue*/0); 1323 fw_xfer_free(xfer); 1324 return; 1325 } 1326 fp = &xfer->recv.hdr; 1327 --- 36 unchanged lines hidden (view full) --- 1364 if (login == NULL) { 1365 printf("%s: sbp_targ_get_login failed\n", 1366 __func__); 1367 orbi->status.dead = 1; 1368 orbi->status.status = STATUS_RES_UNAVAIL; 1369 orbi->status.len = 1; 1370 break; 1371 } |
1372 printf("%s: login id=%d\n", __func__, login->id); |
|
1312 1313 login->fifo_hi = orb[6]; 1314 login->fifo_lo = orb[7]; 1315 login->loginres.len = htons(sizeof(uint32_t) * 4); 1316 login->loginres.id = htons(login->id); 1317 login->loginres.cmd_hi = htons(SBP_TARG_BIND_HI); 1318 login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id)); 1319 login->loginres.recon_hold = htons(login->hold_sec); 1320 | 1373 1374 login->fifo_hi = orb[6]; 1375 login->fifo_lo = orb[7]; 1376 login->loginres.len = htons(sizeof(uint32_t) * 4); 1377 login->loginres.id = htons(login->id); 1378 login->loginres.cmd_hi = htons(SBP_TARG_BIND_HI); 1379 login->loginres.cmd_lo = htonl(SBP_TARG_BIND_LO(login->id)); 1380 login->loginres.recon_hold = htons(login->hold_sec); 1381 |
1382 STAILQ_INSERT_TAIL(&lstate->logins, login, link); |
|
1321 fwmem_write_block(orbi->fwdev, NULL, /*spd*/2, orb[2], orb[3], 1322 sizeof(struct sbp_login_res), (void *)&login->loginres, 1323 fw_asy_callback_free); | 1383 fwmem_write_block(orbi->fwdev, NULL, /*spd*/2, orb[2], orb[3], 1384 sizeof(struct sbp_login_res), (void *)&login->loginres, 1385 fw_asy_callback_free); |
1324 STAILQ_INSERT_TAIL(&lstate->logins, login, link); | |
1325 /* XXX return status after loginres is successfully written */ 1326 break; 1327 } 1328 case ORB_FUN_RCN: 1329 login = orbi->sc->logins[orb4->id]; 1330 if (login != NULL && login->fwdev == orbi->fwdev) { 1331 login->flags &= ~F_HOLD; 1332 callout_stop(&login->hold_callout); --- 80 unchanged lines hidden (view full) --- 1413 sbp_targ_mgm_handler); 1414 break; 1415 case FETCH_CMD: 1416 orbi->state = ORBI_STATUS_FETCH; 1417 login->last_hi = orb_hi; 1418 login->last_lo = orb_lo; 1419 login->flags |= F_LINK_ACTIVE; 1420 /* dequeue */ | 1386 /* XXX return status after loginres is successfully written */ 1387 break; 1388 } 1389 case ORB_FUN_RCN: 1390 login = orbi->sc->logins[orb4->id]; 1391 if (login != NULL && login->fwdev == orbi->fwdev) { 1392 login->flags &= ~F_HOLD; 1393 callout_stop(&login->hold_callout); --- 80 unchanged lines hidden (view full) --- 1474 sbp_targ_mgm_handler); 1475 break; 1476 case FETCH_CMD: 1477 orbi->state = ORBI_STATUS_FETCH; 1478 login->last_hi = orb_hi; 1479 login->last_lo = orb_lo; 1480 login->flags |= F_LINK_ACTIVE; 1481 /* dequeue */ |
1482 SBP_LOCK(sc); |
|
1421 orbi->atio = (struct ccb_accept_tio *) 1422 SLIST_FIRST(&login->lstate->accept_tios); 1423 if (orbi->atio == NULL) { | 1483 orbi->atio = (struct ccb_accept_tio *) 1484 SLIST_FIRST(&login->lstate->accept_tios); 1485 if (orbi->atio == NULL) { |
1486 SBP_UNLOCK(sc); |
|
1424 printf("%s: no free atio\n", __func__); 1425 login->lstate->flags |= F_ATIO_STARVED; 1426 login->flags |= F_ATIO_STARVED; 1427#if 0 1428 /* XXX ?? */ 1429 login->fwdev = fwdev; 1430#endif 1431 break; 1432 } 1433 SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); | 1487 printf("%s: no free atio\n", __func__); 1488 login->lstate->flags |= F_ATIO_STARVED; 1489 login->flags |= F_ATIO_STARVED; 1490#if 0 1491 /* XXX ?? */ 1492 login->fwdev = fwdev; 1493#endif 1494 break; 1495 } 1496 SLIST_REMOVE_HEAD(&login->lstate->accept_tios, sim_links.sle); |
1497 STAILQ_INSERT_TAIL(&login->orbs, orbi, link); 1498 SBP_UNLOCK(sc); |
|
1434 fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, 1435 sizeof(uint32_t) * 8, &orbi->orb[0], 1436 sbp_targ_cmd_handler); | 1499 fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, 1500 sizeof(uint32_t) * 8, &orbi->orb[0], 1501 sbp_targ_cmd_handler); |
1437 STAILQ_INSERT_TAIL(&login->orbs, orbi, link); | |
1438 break; 1439 case FETCH_POINTER: 1440 orbi->state = ORBI_STATUS_POINTER; 1441 login->flags |= F_LINK_ACTIVE; 1442 fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, 1443 sizeof(uint32_t) * 2, &orbi->orb[0], 1444 sbp_targ_pointer_handler); 1445 break; --- 38 unchanged lines hidden (view full) --- 1484 if (login->fwdev != fwdev) { 1485 /* XXX */ 1486 return(RESP_ADDRESS_ERROR); 1487 } 1488 1489 switch (reg) { 1490 case 0x08: /* ORB_POINTER */ 1491 if (debug) | 1502 break; 1503 case FETCH_POINTER: 1504 orbi->state = ORBI_STATUS_POINTER; 1505 login->flags |= F_LINK_ACTIVE; 1506 fwmem_read_block(fwdev, (void *)orbi, /*spd*/2, orb_hi, orb_lo, 1507 sizeof(uint32_t) * 2, &orbi->orb[0], 1508 sbp_targ_pointer_handler); 1509 break; --- 38 unchanged lines hidden (view full) --- 1548 if (login->fwdev != fwdev) { 1549 /* XXX */ 1550 return(RESP_ADDRESS_ERROR); 1551 } 1552 1553 switch (reg) { 1554 case 0x08: /* ORB_POINTER */ 1555 if (debug) |
1492 printf("%s: ORB_POINTER\n", __func__); | 1556 printf("%s: ORB_POINTER(%d)\n", __func__, login_id); |
1493 if ((login->flags & F_LINK_ACTIVE) != 0) { 1494 if (debug) 1495 printf("link active (ORB_POINTER)\n"); 1496 break; 1497 } 1498 sbp_targ_fetch_orb(sc, fwdev, 1499 ntohl(xfer->recv.payload[0]), 1500 ntohl(xfer->recv.payload[1]), 1501 login, FETCH_CMD); 1502 break; 1503 case 0x04: /* AGENT_RESET */ 1504 if (debug) | 1557 if ((login->flags & F_LINK_ACTIVE) != 0) { 1558 if (debug) 1559 printf("link active (ORB_POINTER)\n"); 1560 break; 1561 } 1562 sbp_targ_fetch_orb(sc, fwdev, 1563 ntohl(xfer->recv.payload[0]), 1564 ntohl(xfer->recv.payload[1]), 1565 login, FETCH_CMD); 1566 break; 1567 case 0x04: /* AGENT_RESET */ 1568 if (debug) |
1505 printf("%s: AGENT RESET\n", __func__); | 1569 printf("%s: AGENT RESET(%d)\n", __func__, login_id); |
1506 login->last_hi = 0xffff; 1507 login->last_lo = 0xffffffff; | 1570 login->last_hi = 0xffff; 1571 login->last_lo = 0xffffffff; |
1508 sbp_targ_abort(STAILQ_FIRST(&login->orbs)); | 1572 sbp_targ_abort(sc, STAILQ_FIRST(&login->orbs)); |
1509 break; 1510 case 0x10: /* DOORBELL */ 1511 if (debug) | 1573 break; 1574 case 0x10: /* DOORBELL */ 1575 if (debug) |
1512 printf("%s: DOORBELL\n", __func__); | 1576 printf("%s: DOORBELL(%d)\n", __func__, login_id); |
1513 if (login->last_hi == 0xffff && 1514 login->last_lo == 0xffffffff) { 1515 printf("%s: no previous pointer(DOORBELL)\n", 1516 __func__); 1517 break; 1518 } 1519 if ((login->flags & F_LINK_ACTIVE) != 0) { 1520 if (debug) 1521 printf("link active (DOORBELL)\n"); 1522 break; 1523 } 1524 sbp_targ_fetch_orb(sc, fwdev, 1525 login->last_hi, login->last_lo, 1526 login, FETCH_POINTER); 1527 break; 1528 case 0x00: /* AGENT_STATE */ | 1577 if (login->last_hi == 0xffff && 1578 login->last_lo == 0xffffffff) { 1579 printf("%s: no previous pointer(DOORBELL)\n", 1580 __func__); 1581 break; 1582 } 1583 if ((login->flags & F_LINK_ACTIVE) != 0) { 1584 if (debug) 1585 printf("link active (DOORBELL)\n"); 1586 break; 1587 } 1588 sbp_targ_fetch_orb(sc, fwdev, 1589 login->last_hi, login->last_lo, 1590 login, FETCH_POINTER); 1591 break; 1592 case 0x00: /* AGENT_STATE */ |
1529 printf("%s: AGENT_STATE (ignore)\n", __func__); | 1593 printf("%s: AGENT_STATE (%d:ignore)\n", __func__, login_id); |
1530 break; 1531 case 0x14: /* UNSOLICITED_STATE_ENABLE */ | 1594 break; 1595 case 0x14: /* UNSOLICITED_STATE_ENABLE */ |
1532 printf("%s: UNSOLICITED_STATE_ENABLE (ignore)\n", __func__); | 1596 printf("%s: UNSOLICITED_STATE_ENABLE (%d:ignore)\n", 1597 __func__, login_id); |
1533 break; 1534 default: | 1598 break; 1599 default: |
1535 printf("%s: invalid register %d\n", __func__, reg); | 1600 printf("%s: invalid register %d(%d)\n", 1601 __func__, reg, login_id); |
1536 rtcode = RESP_ADDRESS_ERROR; 1537 } 1538 1539 return (rtcode); 1540} 1541 1542static int 1543sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev) --- 12 unchanged lines hidden (view full) --- 1556 sbp_targ_fetch_orb(sc, fwdev, 1557 ntohl(xfer->recv.payload[0]), 1558 ntohl(xfer->recv.payload[1]), 1559 NULL, FETCH_MGM); 1560 1561 return(0); 1562} 1563 | 1602 rtcode = RESP_ADDRESS_ERROR; 1603 } 1604 1605 return (rtcode); 1606} 1607 1608static int 1609sbp_targ_mgm(struct fw_xfer *xfer, struct fw_device *fwdev) --- 12 unchanged lines hidden (view full) --- 1622 sbp_targ_fetch_orb(sc, fwdev, 1623 ntohl(xfer->recv.payload[0]), 1624 ntohl(xfer->recv.payload[1]), 1625 NULL, FETCH_MGM); 1626 1627 return(0); 1628} 1629 |
1564 | |
1565static void 1566sbp_targ_recv(struct fw_xfer *xfer) 1567{ 1568 struct fw_pkt *fp, *sfp; 1569 struct fw_device *fwdev; 1570 uint32_t lo; 1571 int s, rtcode; 1572 struct sbp_targ_softc *sc; --- 4 unchanged lines hidden (view full) --- 1577 fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); 1578 if (fwdev == NULL) { 1579 printf("%s: cannot resolve nodeid=%d\n", 1580 __func__, fp->mode.wreqb.src & 0x3f); 1581 rtcode = RESP_TYPE_ERROR; /* XXX */ 1582 goto done; 1583 } 1584 lo = fp->mode.wreqb.dest_lo; | 1630static void 1631sbp_targ_recv(struct fw_xfer *xfer) 1632{ 1633 struct fw_pkt *fp, *sfp; 1634 struct fw_device *fwdev; 1635 uint32_t lo; 1636 int s, rtcode; 1637 struct sbp_targ_softc *sc; --- 4 unchanged lines hidden (view full) --- 1642 fwdev = fw_noderesolve_nodeid(sc->fd.fc, fp->mode.wreqb.src & 0x3f); 1643 if (fwdev == NULL) { 1644 printf("%s: cannot resolve nodeid=%d\n", 1645 __func__, fp->mode.wreqb.src & 0x3f); 1646 rtcode = RESP_TYPE_ERROR; /* XXX */ 1647 goto done; 1648 } 1649 lo = fp->mode.wreqb.dest_lo; |
1650 |
|
1585 if (lo == SBP_TARG_BIND_LO(-1)) 1586 rtcode = sbp_targ_mgm(xfer, fwdev); 1587 else if (lo >= SBP_TARG_BIND_LO(0)) 1588 rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), 1589 lo % 0x20); 1590 else 1591 rtcode = RESP_ADDRESS_ERROR; 1592 --- 13 unchanged lines hidden (view full) --- 1606 splx(s); 1607} 1608 1609static int 1610sbp_targ_attach(device_t dev) 1611{ 1612 struct sbp_targ_softc *sc; 1613 struct cam_devq *devq; | 1651 if (lo == SBP_TARG_BIND_LO(-1)) 1652 rtcode = sbp_targ_mgm(xfer, fwdev); 1653 else if (lo >= SBP_TARG_BIND_LO(0)) 1654 rtcode = sbp_targ_cmd(xfer, fwdev, SBP_TARG_LOGIN_ID(lo), 1655 lo % 0x20); 1656 else 1657 rtcode = RESP_ADDRESS_ERROR; 1658 --- 13 unchanged lines hidden (view full) --- 1672 splx(s); 1673} 1674 1675static int 1676sbp_targ_attach(device_t dev) 1677{ 1678 struct sbp_targ_softc *sc; 1679 struct cam_devq *devq; |
1680 struct firewire_comm *fc; |
|
1614 1615 sc = (struct sbp_targ_softc *) device_get_softc(dev); 1616 bzero((void *)sc, sizeof(struct sbp_targ_softc)); 1617 | 1681 1682 sc = (struct sbp_targ_softc *) device_get_softc(dev); 1683 bzero((void *)sc, sizeof(struct sbp_targ_softc)); 1684 |
1618 sc->fd.fc = device_get_ivars(dev); | 1685 mtx_init(&sc->mtx, "sbp_targ", NULL, MTX_DEF); 1686 sc->fd.fc = fc = device_get_ivars(dev); |
1619 sc->fd.dev = dev; 1620 sc->fd.post_explore = (void *) sbp_targ_post_explore; 1621 sc->fd.post_busreset = (void *) sbp_targ_post_busreset; 1622 1623 devq = cam_simq_alloc(/*maxopenings*/MAX_LUN*MAX_INITIATORS); 1624 if (devq == NULL) 1625 return (ENXIO); 1626 1627 sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll, | 1687 sc->fd.dev = dev; 1688 sc->fd.post_explore = (void *) sbp_targ_post_explore; 1689 sc->fd.post_busreset = (void *) sbp_targ_post_busreset; 1690 1691 devq = cam_simq_alloc(/*maxopenings*/MAX_LUN*MAX_INITIATORS); 1692 if (devq == NULL) 1693 return (ENXIO); 1694 1695 sc->sim = cam_sim_alloc(sbp_targ_action, sbp_targ_poll, |
1628 "sbp_targ", sc, device_get_unit(dev), &Giant, | 1696 "sbp_targ", sc, device_get_unit(dev), &sc->mtx, |
1629 /*untagged*/ 1, /*tagged*/ 1, devq); 1630 if (sc->sim == NULL) { 1631 cam_simq_free(devq); 1632 return (ENXIO); 1633 } 1634 | 1697 /*untagged*/ 1, /*tagged*/ 1, devq); 1698 if (sc->sim == NULL) { 1699 cam_simq_free(devq); 1700 return (ENXIO); 1701 } 1702 |
1703 SBP_LOCK(sc); |
|
1635 if (xpt_bus_register(sc->sim, /*bus*/0) != CAM_SUCCESS) 1636 goto fail; 1637 1638 if (xpt_create_path(&sc->path, /*periph*/ NULL, cam_sim_path(sc->sim), 1639 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1640 xpt_bus_deregister(cam_sim_path(sc->sim)); 1641 goto fail; 1642 } | 1704 if (xpt_bus_register(sc->sim, /*bus*/0) != CAM_SUCCESS) 1705 goto fail; 1706 1707 if (xpt_create_path(&sc->path, /*periph*/ NULL, cam_sim_path(sc->sim), 1708 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1709 xpt_bus_deregister(cam_sim_path(sc->sim)); 1710 goto fail; 1711 } |
1712 SBP_UNLOCK(sc); |
|
1643 1644 sc->fwb.start = SBP_TARG_BIND_START; 1645 sc->fwb.end = SBP_TARG_BIND_END; 1646 1647 /* pre-allocate xfer */ 1648 STAILQ_INIT(&sc->fwb.xferlist); 1649 fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, 1650 /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, | 1713 1714 sc->fwb.start = SBP_TARG_BIND_START; 1715 sc->fwb.end = SBP_TARG_BIND_END; 1716 1717 /* pre-allocate xfer */ 1718 STAILQ_INIT(&sc->fwb.xferlist); 1719 fw_xferlist_add(&sc->fwb.xferlist, M_SBP_TARG, 1720 /*send*/ 0, /*recv*/ SBP_TARG_RECV_LEN, MAX_LUN /* XXX */, |
1651 sc->fd.fc, (void *)sc, sbp_targ_recv); 1652 fw_bindadd(sc->fd.fc, &sc->fwb); | 1721 fc, (void *)sc, sbp_targ_recv); 1722 fw_bindadd(fc, &sc->fwb); |
1653 return 0; 1654 1655fail: | 1723 return 0; 1724 1725fail: |
1726 SBP_UNLOCK(sc); |
|
1656 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1657 return (ENXIO); 1658} 1659 1660static int 1661sbp_targ_detach(device_t dev) 1662{ 1663 struct sbp_targ_softc *sc; 1664 struct sbp_targ_lstate *lstate; 1665 int i; 1666 1667 sc = (struct sbp_targ_softc *)device_get_softc(dev); 1668 sc->fd.post_busreset = NULL; 1669 | 1727 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1728 return (ENXIO); 1729} 1730 1731static int 1732sbp_targ_detach(device_t dev) 1733{ 1734 struct sbp_targ_softc *sc; 1735 struct sbp_targ_lstate *lstate; 1736 int i; 1737 1738 sc = (struct sbp_targ_softc *)device_get_softc(dev); 1739 sc->fd.post_busreset = NULL; 1740 |
1741 SBP_LOCK(sc); |
|
1670 xpt_free_path(sc->path); 1671 xpt_bus_deregister(cam_sim_path(sc->sim)); | 1742 xpt_free_path(sc->path); 1743 xpt_bus_deregister(cam_sim_path(sc->sim)); |
1744 SBP_UNLOCK(sc); |
|
1672 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1673 1674 for (i = 0; i < MAX_LUN; i ++) { 1675 lstate = sc->lstate[i]; 1676 if (lstate != NULL) { 1677 xpt_free_path(lstate->path); 1678 free(lstate, M_SBP_TARG); 1679 } 1680 } 1681 if (sc->black_hole != NULL) { 1682 xpt_free_path(sc->black_hole->path); 1683 free(sc->black_hole, M_SBP_TARG); 1684 } 1685 1686 fw_bindremove(sc->fd.fc, &sc->fwb); 1687 fw_xferlist_remove(&sc->fwb.xferlist); 1688 | 1745 cam_sim_free(sc->sim, /*free_devq*/TRUE); 1746 1747 for (i = 0; i < MAX_LUN; i ++) { 1748 lstate = sc->lstate[i]; 1749 if (lstate != NULL) { 1750 xpt_free_path(lstate->path); 1751 free(lstate, M_SBP_TARG); 1752 } 1753 } 1754 if (sc->black_hole != NULL) { 1755 xpt_free_path(sc->black_hole->path); 1756 free(sc->black_hole, M_SBP_TARG); 1757 } 1758 1759 fw_bindremove(sc->fd.fc, &sc->fwb); 1760 fw_xferlist_remove(&sc->fwb.xferlist); 1761 |
1762 mtx_destroy(&sc->mtx); 1763 |
|
1689 return 0; 1690} 1691 1692static devclass_t sbp_targ_devclass; 1693 1694static device_method_t sbp_targ_methods[] = { 1695 /* device interface */ 1696 DEVMETHOD(device_identify, sbp_targ_identify), --- 16 unchanged lines hidden --- | 1764 return 0; 1765} 1766 1767static devclass_t sbp_targ_devclass; 1768 1769static device_method_t sbp_targ_methods[] = { 1770 /* device interface */ 1771 DEVMETHOD(device_identify, sbp_targ_identify), --- 16 unchanged lines hidden --- |