Lines Matching refs:sf

28  * sf - Solaris Fibre Channel driver
82 static void sf_softstate_unlink(struct sf *);
91 static int sf_pkt_alloc_extern(struct sf *, struct sf_pkt *,
93 static void sf_pkt_destroy_extern(struct sf *, struct sf_pkt *);
103 static int sf_add_cr_pool(struct sf *);
104 static int sf_cr_alloc(struct sf *, struct sf_pkt *, int (*)());
106 static void sf_crpool_free(struct sf *);
110 static int sf_login(struct sf *, uchar_t, uchar_t, uint_t, int);
111 static int sf_els_transport(struct sf *, struct sf_els_hdr *);
113 static int sf_do_prli(struct sf *, struct sf_els_hdr *, struct la_els_logi *);
114 static int sf_do_adisc(struct sf *, struct sf_els_hdr *);
115 static int sf_do_reportlun(struct sf *, struct sf_els_hdr *,
118 static int sf_do_inquiry(struct sf *, struct sf_els_hdr *,
121 static struct fcal_packet *sf_els_alloc(struct sf *, uchar_t, int, int,
124 static struct sf_target *sf_create_target(struct sf *,
127 static struct sf_target *sf_lookup_target(struct sf *, uchar_t *, int);
129 static struct sf_target *sf_lookup_target(struct sf *, uchar_t *, int64_t);
131 static void sf_finish_init(struct sf *, int);
132 static void sf_offline_target(struct sf *, struct sf_target *);
133 static void sf_create_devinfo(struct sf *, struct sf_target *, int);
140 static void sf_abort_all(struct sf *, struct sf_target *, int, int, int);
142 static int sf_start_internal(struct sf *, struct sf_pkt *);
143 static void sf_fill_ids(struct sf *, struct sf_pkt *, struct sf_target *);
144 static int sf_prepare_pkt(struct sf *, struct sf_pkt *, struct sf_target *);
145 static int sf_dopoll(struct sf *, struct sf_pkt *);
147 static void sf_throttle(struct sf *);
149 static void sf_throttle_start(struct sf *);
150 static void sf_check_targets(struct sf *);
152 static int sf_target_timeout(struct sf *, struct sf_pkt *);
153 static void sf_force_lip(struct sf *);
155 static struct sf_els_hdr *sf_els_timeout(struct sf *, struct sf_els_hdr *);
157 static void sf_log(struct sf *, int, const char *, ...);
162 static struct sf_target *sf_get_target_from_dip(struct sf *, dev_info_t *);
232 static struct sf *sf_head = NULL;
358 i = ddi_soft_state_init(&sf_state, sizeof (struct sf),
416 struct sf *sf;
420 sf = ddi_get_soft_state(sf_state, instance);
421 if (sf != NULL)
422 *result = sf->sf_dip;
450 struct sf *sf, *tsf;
468 sf = ddi_get_soft_state(sf_state, instance);
469 SF_DEBUG(2, (sf, CE_CONT,
470 "sf_attach: DDI_RESUME for sf%d\n", instance));
471 if (sf == NULL) {
472 cmn_err(CE_WARN, "sf%d: bad soft state", instance);
479 mutex_enter(&sf->sf_mutex);
480 sf->sf_state &= ~SF_STATE_SUSPENDED;
481 mutex_exit(&sf->sf_mutex);
486 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
487 sf->sf_state = SF_STATE_OFFLINE;
493 soc_add_ulp(sf->sf_sochandle, sf->sf_socp,
494 sf->sf_sochandle->fcal_portno, TYPE_SCSI_FCP,
495 sf_statec_callback, sf_unsol_els_callback, NULL, sf);
500 (void) soc_force_lip(sf->sf_sochandle, sf->sf_socp,
501 sf->sf_sochandle->fcal_portno, 0, FCAL_NO_LIP);
528 cmn_err(CE_WARN, "sf%d: failed to allocate soft state",
533 sf = ddi_get_soft_state(sf_state, instance);
534 SF_DEBUG(4, (sf, CE_CONT,
535 "sf_attach: DDI_ATTACH for sf%d\n", instance));
536 if (sf == NULL) {
538 cmn_err(CE_WARN, "sf%d: bad soft state", instance);
549 "sf%d: failed to obtain transport handle",
555 sf->sf_dip = dip;
556 sf->sf_state = SF_STATE_INIT;
557 sf->sf_throttle = handle->fcal_cmdmax;
558 sf->sf_sochandle = handle;
559 sf->sf_socp = handle->fcal_handle;
560 sf->sf_check_n_close = 0;
563 if (sf_add_cr_pool(sf) != DDI_SUCCESS) {
565 "sf%d: failed to allocate command/response pool",
571 (void) sprintf(buf, "sf%d_cache", instance);
572 sf->sf_pkt_cache = kmem_cache_create(buf,
577 if (sf->sf_pkt_cache == NULL) {
578 cmn_err(CE_WARN, "sf%d: failed to allocate kmem cache",
584 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->
585 fcal_dmaattr, DDI_DMA_DONTWAIT, NULL, &sf->
588 "sf%d: failed to allocate dma handle for lilp map",
593 if (ddi_dma_mem_alloc(sf->sf_lilp_dmahandle,
594 i, sf->sf_sochandle->
596 (caddr_t *)&sf->sf_lilp_map, &real_size,
597 &sf->sf_lilp_acchandle) != DDI_SUCCESS) {
598 cmn_err(CE_WARN, "sf%d: failed to allocate lilp map",
610 if (ddi_dma_addr_bind_handle(sf->sf_lilp_dmahandle, NULL,
611 (caddr_t)sf->sf_lilp_map, real_size,
613 &sf->sf_lilp_dmacookie, &ccount) != DDI_DMA_MAPPED) {
615 "sf%d: failed to bind dma handle for lilp map",
626 sf->sf_lilp_map = (struct fcal_lilp_map *)(((uintptr_t)sf->
628 sf->sf_lilp_dmacookie.dmac_address = (sf->
632 mutex_init(&sf->sf_mutex, NULL, MUTEX_DRIVER, NULL);
633 mutex_init(&sf->sf_cmd_mutex, NULL, MUTEX_DRIVER, NULL);
634 mutex_init(&sf->sf_cr_mutex, NULL, MUTEX_DRIVER, NULL);
635 mutex_init(&sf->sf_hp_daemon_mutex, NULL, MUTEX_DRIVER, NULL);
636 cv_init(&sf->sf_cr_cv, NULL, CV_DRIVER, NULL);
637 cv_init(&sf->sf_hp_daemon_cv, NULL, CV_DRIVER, NULL);
645 cmn_err(CE_WARN, "sf%d: ddi_create_minor_node failed"
654 cmn_err(CE_WARN, "sf%d: ddi_create_minor_node failed"
663 cmn_err(CE_WARN, "sf%d: scsi_hba_tran_alloc failed",
672 sf->sf_tran = tran;
674 tran->tran_hba_private = sf;
708 sf->sf_event_defs = (ndi_event_definition_t *)
711 bcopy(sf_event_defs, sf->sf_event_defs,
715 &sf->sf_event_hdl, NDI_SLEEP);
717 sf->sf_events.ndi_events_version = NDI_EVENTS_REV1;
718 sf->sf_events.ndi_n_events = SF_N_NDI_EVENTS;
719 sf->sf_events.ndi_event_defs = sf->sf_event_defs;
721 if (ndi_event_bind_set(sf->sf_event_hdl,
722 &sf->sf_events, NDI_SLEEP) != NDI_SUCCESS) {
730 if (scsi_hba_attach_setup(dip, sf->sf_sochandle->
732 cmn_err(CE_WARN, "sf%d: scsi_hba_attach_setup failed",
738 if ((sf->sf_ksp = kstat_create("sf", instance, "statistics",
741 cmn_err(CE_WARN, "sf%d: failed to create kstat",
744 sf->sf_stats.version = 2;
745 (void) sprintf(sf->sf_stats.drvr_name,
747 sf->sf_ksp->ks_data = (void *)&sf->sf_stats;
748 sf->sf_ksp->ks_private = sf;
749 sf->sf_ksp->ks_update = sf_kstat_update;
750 kstat_install(sf->sf_ksp);
754 mutex_enter(&sf->sf_hp_daemon_mutex);
756 (void (*)())sf_hp_daemon, sf, 0, &p0, TS_RUN, minclsyspri);
757 sf->sf_hp_tid = tp->t_did;
758 mutex_exit(&sf->sf_hp_daemon_mutex);
762 sf->sf_next = sf_head;
764 sf_head = sf;
770 if (tsf->sf_socp == sf->sf_socp) {
778 sf->sf_sibling = tsf;
800 tsf->sf_sibling = sf;
817 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
818 sf->sf_state = SF_STATE_OFFLINE;
824 soc_add_ulp(sf->sf_sochandle, sf->sf_socp,
825 sf->sf_sochandle->fcal_portno, TYPE_SCSI_FCP,
826 sf_statec_callback, sf_unsol_els_callback, NULL, sf);
831 (void) soc_force_lip(sf->sf_sochandle, sf->sf_socp,
832 sf->sf_sochandle->fcal_portno, 0, FCAL_NO_LIP);
833 sf->sf_reset_time = ddi_get_lbolt64();
841 cmn_err(CE_WARN, "sf%d: failed to attach", instance);
846 if (sf->sf_event_hdl) {
847 (void) ndi_event_unbind_set(sf->sf_event_hdl,
848 &sf->sf_events, NDI_SLEEP);
849 (void) ndi_event_free_hdl(sf->sf_event_hdl);
852 if (sf->sf_event_defs) {
853 kmem_free(sf->sf_event_defs, sizeof (sf_event_defs));
856 if (sf->sf_tran != NULL) {
857 scsi_hba_tran_free(sf->sf_tran);
859 while (sf->sf_cr_pool != NULL) {
860 sf_crpool_free(sf);
862 if (sf->sf_lilp_dmahandle != NULL) {
864 (void) ddi_dma_unbind_handle(sf->sf_lilp_dmahandle);
866 ddi_dma_free_handle(&sf->sf_lilp_dmahandle);
868 if (sf->sf_pkt_cache != NULL) {
869 kmem_cache_destroy(sf->sf_pkt_cache);
871 if (sf->sf_lilp_map != NULL) {
872 ddi_dma_mem_free(&sf->sf_lilp_acchandle);
874 if (sf->sf_ksp != NULL) {
875 kstat_delete(sf->sf_ksp);
878 mutex_destroy(&sf->sf_mutex);
879 mutex_destroy(&sf->sf_cmd_mutex);
880 mutex_destroy(&sf->sf_cr_mutex);
881 mutex_destroy(&sf->sf_hp_daemon_mutex);
882 cv_destroy(&sf->sf_cr_cv);
883 cv_destroy(&sf->sf_hp_daemon_cv);
913 struct sf *sf;
925 if ((sf = ddi_get_soft_state(sf_state, instance)) == NULL) {
926 cmn_err(CE_WARN, "sf_detach, sf%d: bad soft state", instance);
937 SF_DEBUG(2, (sf, CE_CONT,
938 "sf_detach: DDI_SUSPEND for sf%d\n", instance));
947 soc_remove_ulp(sf->sf_sochandle, sf->sf_socp,
948 sf->sf_sochandle->fcal_portno, TYPE_SCSI_FCP, sf);
954 sf_force_lip(sf);
960 mutex_enter(&sf->sf_mutex);
961 sf->sf_lip_cnt++;
962 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
963 sf->sf_state = (SF_STATE_OFFLINE | SF_STATE_SUSPENDED);
965 target = sf->sf_targets[i];
990 mutex_exit(&sf->sf_mutex);
1011 SF_DEBUG(2, (sf, CE_CONT,
1012 "sf_detach: DDI_DETACH for sf%d\n", instance));
1014 /* remove this "sf" from the list of sf softstates */
1015 sf_softstate_unlink(sf);
1022 mutex_enter(&sf->sf_mutex);
1023 sf->sf_lip_cnt++;
1024 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
1025 sf->sf_state = SF_STATE_OFFLINE;
1027 target = sf->sf_targets[i];
1051 mutex_exit(&sf->sf_mutex);
1054 soc_remove_ulp(sf->sf_sochandle, sf->sf_socp,
1055 sf->sf_sochandle->fcal_portno, TYPE_SCSI_FCP, sf);
1070 mutex_enter(&sf->sf_hp_daemon_mutex);
1071 ASSERT(sf->sf_hp_tid);
1072 sf->sf_hp_exit = 1; /* flag exit */
1073 cv_signal(&sf->sf_hp_daemon_cv);
1074 mutex_exit(&sf->sf_hp_daemon_mutex);
1075 thread_join(sf->sf_hp_tid); /* wait for hotplug to exit */
1080 if (sf->sf_event_hdl) {
1081 (void) ndi_event_unbind_set(sf->sf_event_hdl,
1082 &sf->sf_events, NDI_SLEEP);
1083 (void) ndi_event_free_hdl(sf->sf_event_hdl);
1086 if (sf->sf_event_defs) {
1087 kmem_free(sf->sf_event_defs, sizeof (sf_event_defs));
1092 scsi_hba_tran_free(sf->sf_tran);
1095 if (sf->sf_lilp_map != NULL) {
1096 (void) ddi_dma_unbind_handle(sf->sf_lilp_dmahandle);
1097 if (sf->sf_lilp_dmahandle != NULL) {
1098 ddi_dma_free_handle(&sf->sf_lilp_dmahandle);
1100 ddi_dma_mem_free(&sf->sf_lilp_acchandle);
1112 kmem_cache_destroy(sf->sf_pkt_cache);
1114 SF_DEBUG(2, (sf, CE_CONT,
1117 while (sf->sf_cr_pool != NULL) {
1124 sf->sf_cr_pool->ntot = sf->sf_cr_pool->nfree;
1125 sf_crpool_free(sf);
1132 mutex_destroy(&sf->sf_mutex);
1133 mutex_destroy(&sf->sf_cmd_mutex);
1134 mutex_destroy(&sf->sf_cr_mutex);
1135 mutex_destroy(&sf->sf_hp_daemon_mutex);
1136 cv_destroy(&sf->sf_cr_cv);
1137 cv_destroy(&sf->sf_hp_daemon_cv);
1146 if (sf->sf_ksp != NULL) {
1147 kstat_delete(sf->sf_ksp);
1150 SF_DEBUG(2, (sf, CE_CONT,
1157 SF_DEBUG(2, (sf, CE_CONT, "sf_detach: sf%d unknown cmd %x\n",
1165 * sf_softstate_unlink() - remove an sf instance from the list of softstates
1168 sf_softstate_unlink(struct sf *sf)
1170 struct sf *sf_ptr;
1171 struct sf *sf_found_sibling;
1172 struct sf *sf_reposition = NULL;
1180 if ((sf_found_sibling = sf->sf_sibling) != NULL) {
1190 if (sf == sf_head) {
1192 sf_head = sf->sf_next;
1198 if (sf_ptr == sf) {
1204 ASSERT(sf_ptr == sf);
1218 struct sf *sf;
1220 sf = ddi_get_soft_state(sf_state, ddi_get_instance(parent));
1221 ASSERT(sf);
1224 (ddi_get_lbolt64() - sf->sf_reset_time);
1260 struct sf *sf = (struct sf *)hba_tran->tran_hba_private;
1297 mutex_enter(&sf->sf_mutex);
1298 if ((target = sf_lookup_target(sf, wwn, lun)) == NULL) {
1299 mutex_exit(&sf->sf_mutex);
1304 if ((sf->sf_lip_cnt == lip_cnt) && !(target->sft_state
1316 mutex_exit(&sf->sf_mutex);
1320 mutex_exit(&sf->sf_mutex);
1351 sf_pkt_alloc_extern(struct sf *sf, struct sf_pkt *cmd,
1378 sf_pkt_destroy_extern(sf, cmd);
1388 sf_pkt_destroy_extern(struct sf *sf, struct sf_pkt *cmd)
1408 kmem_cache_free(sf->sf_pkt_cache, (void *)cmd);
1424 struct sf *sf = ADDR2SF(ap);
1447 if ((cmd = kmem_cache_alloc(sf->sf_pkt_cache, kf)) != NULL) {
1489 failure = sf_pkt_alloc_extern(sf, cmd,
1501 if (sf_cr_alloc(sf, cmd, callback) == DDI_FAILURE) {
1502 sf_pkt_destroy_extern(sf, cmd);
1507 fpkt->fcal_pkt_cookie = sf->sf_socp;
1513 sf->sf_sochandle->fcal_portno);
1595 rval = ddi_dma_alloc_handle(sf->sf_dip,
1596 sf->sf_sochandle->fcal_dmaattr, callback, arg,
1609 SF_DEBUG(2, (sf, CE_CONT, "ddi_dma_buf.. failed\n"));
1688 struct sf *sf = ADDR2SF(ap);
1712 kmem_cache_free(sf->sf_pkt_cache, (void *)cmd);
1715 sf_pkt_destroy_extern(sf, cmd);
1753 cmn_err(CE_WARN, "sf: sync pkt failed");
1767 struct sf *sf = ADDR2SF(ap);
1770 &sf->sf_mutex, &sf->sf_reset_notify_listf));
1826 * add to the command/response buffer pool for this sf instance
1829 sf_add_cr_pool(struct sf *sf)
1851 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
1861 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
1881 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
1891 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
1924 ptr->sf = sf;
1949 mutex_enter(&sf->sf_cr_mutex);
1950 ptr->next = sf->sf_cr_pool;
1951 sf->sf_cr_pool = ptr;
1952 sf->sf_cr_pool_cnt++;
1953 mutex_exit(&sf->sf_cr_mutex);
1991 sf_cr_alloc(struct sf *sf, struct sf_pkt *cmd, int (*func)())
1997 mutex_enter(&sf->sf_cr_mutex);
2002 ptr = sf->sf_cr_pool;
2017 mutex_exit(&sf->sf_cr_mutex);
2028 if (sf->sf_cr_pool_cnt < SF_CR_POOL_MAX) {
2030 if (sf->sf_cr_flag) {
2034 cv_wait(&sf->sf_cr_cv, &sf->sf_cr_mutex);
2039 mutex_exit(&sf->sf_cr_mutex);
2040 sf->sf_stats.cralloc_failures++;
2044 sf->sf_cr_flag = 1;
2045 mutex_exit(&sf->sf_cr_mutex);
2047 if (sf_add_cr_pool(sf) != DDI_SUCCESS) {
2049 mutex_enter(&sf->sf_cr_mutex);
2050 sf->sf_cr_flag = 0;
2051 cv_broadcast(&sf->sf_cr_cv);
2052 mutex_exit(&sf->sf_cr_mutex);
2053 sf->sf_stats.cralloc_failures++;
2060 mutex_enter(&sf->sf_cr_mutex);
2061 sf->sf_cr_flag = 0;
2062 cv_broadcast(&sf->sf_cr_cv);
2068 mutex_exit(&sf->sf_cr_mutex);
2069 sf->sf_stats.cralloc_failures++;
2080 struct sf *sf = cp->sf;
2088 mutex_enter(&sf->sf_cr_mutex);
2094 mutex_exit(&sf->sf_cr_mutex);
2102 sf_crpool_free(struct sf *sf)
2107 mutex_enter(&sf->sf_cr_mutex);
2108 cp = sf->sf_cr_pool;
2114 sf->sf_cr_pool = cp->next;
2116 sf->sf_cr_pool_cnt--;
2117 mutex_exit(&sf->sf_cr_mutex);
2131 mutex_exit(&sf->sf_cr_mutex);
2171 struct sf *sf = (struct sf *)arg;
2190 SF_DEBUG(1, (sf, CE_CONT, "sf%d: loop online\n",
2191 ddi_get_instance(sf->sf_dip)));
2192 mutex_enter(&sf->sf_mutex);
2193 sf->sf_lip_cnt++;
2194 sf->sf_state = SF_STATE_ONLINING;
2195 mutex_exit(&sf->sf_mutex);
2199 target = sf->sf_wwn_lists[i];
2219 SF_DEBUG(1, (sf, CE_CONT,
2236 if ((ret = soc_get_lilp_map(sf->sf_sochandle, sf->sf_socp,
2237 sf->sf_sochandle->fcal_portno, (uint32_t)sf->
2240 (void) soc_take_core(sf->sf_sochandle,
2241 sf->sf_socp);
2244 sf_log(sf, CE_WARN,
2246 mutex_enter(&sf->sf_mutex);
2247 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
2248 sf->sf_lip_cnt++;
2249 sf->sf_state = SF_STATE_OFFLINE;
2250 mutex_exit(&sf->sf_mutex);
2255 (void) ddi_dma_sync(sf->sf_lilp_dmahandle, (off_t)0, (size_t)0,
2259 cnt = sf->sf_lilp_map->lilp_length;
2261 sf_log(sf, CE_WARN, "invalid lilp map\n");
2265 mutex_enter(&sf->sf_mutex);
2266 sf->sf_device_count = cnt - 1;
2267 sf->sf_al_pa = sf->sf_lilp_map->lilp_myalpa;
2268 lip_cnt = sf->sf_lip_cnt;
2269 al_pa = sf->sf_al_pa;
2271 SF_DEBUG(1, (sf, CE_CONT,
2278 if (sf->sf_lilp_map->lilp_alpalist[cnt-1] == al_pa) {
2282 if (sf->sf_lilp_map->lilp_magic == FCAL_BADLILP_MAGIC) {
2284 sf->sf_lilp_map->lilp_alpalist[i] =
2287 sf->sf_device_count = cnt - 1;
2289 if (sf->sf_device_count == 0) {
2290 sf_finish_init(sf, lip_cnt);
2291 mutex_exit(&sf->sf_mutex);
2294 mutex_exit(&sf->sf_mutex);
2296 SF_DEBUG(2, (sf, CE_WARN,
2298 sf->sf_device_count));
2302 SF_DEBUG(1, (sf, CE_CONT,
2304 sf->sf_lilp_map->lilp_alpalist[i],
2306 sf->sf_lilp_map->lilp_alpalist[i]]));
2308 if (sf->sf_lilp_map->lilp_alpalist[i] != al_pa) {
2310 if (!sf_login(sf, LA_ELS_PLOGI,
2311 sf->sf_lilp_map->lilp_alpalist[i],
2312 sf->sf_lilp_map->lilp_alpalist[cnt-1],
2315 mutex_enter(&sf->sf_mutex);
2316 if (lip_cnt == sf->sf_lip_cnt) {
2320 sf->sf_device_count--;
2321 ASSERT(sf->sf_device_count
2323 if (sf->sf_device_count == 0) {
2324 sf_finish_init(sf,
2328 mutex_exit(&sf->sf_mutex);
2339 SF_DEBUG(1, (sf, CE_CONT, "sf%d: loop offline\n",
2340 ddi_get_instance(sf->sf_dip)));
2341 mutex_enter(&sf->sf_mutex);
2342 sf->sf_lip_cnt++;
2343 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
2344 if (!sf->sf_online_timer) {
2345 sf->sf_online_timer = sf_watchdog_time +
2353 if (sf->sf_state & SF_STATE_SUSPENDED) {
2354 sf->sf_state |= SF_STATE_OFFLINE;
2355 SF_DEBUG(1, (sf, CE_CONT,
2356 "sf_statec_callback, sf%d: "
2358 ddi_get_instance(sf->sf_dip)));
2360 sf->sf_state = SF_STATE_OFFLINE;
2365 target = sf->sf_targets[i];
2375 mutex_exit(&sf->sf_mutex);
2388 SF_DEBUG(1, (sf, CE_CONT, "!sf%d: soc reset\n",
2389 ddi_get_instance(sf->sf_dip)));
2391 mutex_enter(&sf->sf_mutex);
2392 sf->sf_lip_cnt++;
2393 sf->sf_timer = sf_watchdog_time + SF_RESET_TIMEOUT;
2399 if (sf->sf_state & SF_STATE_SUSPENDED) {
2400 sf->sf_state |= SF_STATE_OFFLINE;
2401 SF_DEBUG(1, (sf, CE_CONT,
2402 "sf_statec_callback, sf%d: "
2404 ddi_get_instance(sf->sf_dip)));
2406 sf->sf_state = SF_STATE_OFFLINE;
2414 target = sf->sf_targets[i];
2419 mutex_exit(&sf->sf_mutex);
2429 sf->sf_event_hdl, target->sft_dip,
2433 sf->sf_event_hdl,
2436 mutex_enter(&sf->sf_mutex);
2446 privp = sf->sf_els_list;
2481 sf->sf_els_list = tmpp2;
2493 mutex_exit(&sf->sf_mutex);
2510 target = sf->sf_targets[i];
2563 mutex_enter(&sf->sf_mutex);
2564 cmd = sf->sf_pkt_head;
2565 sf->sf_pkt_head = NULL;
2566 mutex_exit(&sf->sf_mutex);
2591 sf_login(struct sf *sf, uchar_t els_code, uchar_t dest_id, uint_t arg1,
2598 if (sf_els_alloc(sf, dest_id, sizeof (struct sf_els_hdr),
2601 sf_log(sf, CE_WARN, "Cannot allocate PLOGI for target %x "
2608 bcopy((caddr_t)sf->sf_sochandle->fcal_loginparms,
2611 bcopy((caddr_t)&sf->sf_sochandle->fcal_p_wwn,
2613 bcopy((caddr_t)&sf->sf_sochandle->fcal_n_wwn,
2617 bcopy((caddr_t)&sf->sf_sochandle->fcal_p_wwn,
2632 return (sf_els_transport(sf, privp));
2641 sf_els_transport(struct sf *sf, struct sf_els_hdr *privp)
2649 mutex_enter(&sf->sf_mutex);
2650 privp->next = sf->sf_els_list;
2651 if (sf->sf_els_list != NULL) {
2652 sf->sf_els_list->prev = privp;
2654 sf->sf_els_list = privp;
2655 mutex_exit(&sf->sf_mutex);
2658 if (soc_transport(sf->sf_sochandle, fpkt, FCAL_NOSLEEP,
2660 mutex_enter(&sf->sf_mutex);
2667 if (sf->sf_els_list == privp) {
2668 sf->sf_els_list = privp->next;
2670 mutex_exit(&sf->sf_mutex);
2685 struct sf *sf = privp->sf;
2686 struct sf *tsf;
2700 mutex_enter(&sf->sf_mutex);
2702 mutex_exit(&sf->sf_mutex);
2711 if (sf->sf_els_list == privp) {
2712 sf->sf_els_list = privp->next;
2715 mutex_exit(&sf->sf_mutex);
2720 mutex_enter(&sf->sf_cmd_mutex);
2721 sf->sf_ncmds = ncmds;
2722 mutex_exit(&sf->sf_cmd_mutex);
2741 SF_DEBUG(2, (sf, CE_CONT,
2747 if (!sf_do_prli(sf, privp, ptr)) {
2756 SF_DEBUG(2, (sf, CE_CONT,
2760 if (sf_do_adisc(sf, privp) != 1) {
2770 SF_DEBUG(2, (sf, CE_CONT,
2775 if ((target = sf_create_target(sf, privp,
2788 sf_log(sf, CE_WARN,
2795 mutex_enter(&sf->sf_mutex);
2796 sf_offline_target(sf, target);
2797 mutex_exit(&sf->sf_mutex);
2803 if (!sf_do_reportlun(sf, privp, target)) {
2804 mutex_enter(&sf->sf_mutex);
2805 sf_offline_target(sf, target);
2806 mutex_exit(&sf->sf_mutex);
2812 SF_DEBUG(2, (sf, CE_CONT,
2829 sf->sf_stats.tstats[tgt_id].els_failures++;
2834 tsf = sf->sf_sibling;
2845 mutex_enter(&sf->sf_mutex);
2847 if (privp->lip_cnt == sf->sf_lip_cnt) {
2848 SF_DEBUG(1, (sf, CE_WARN,
2851 privp->next = sf->sf_els_list;
2852 if (sf->sf_els_list != NULL) {
2853 sf->sf_els_list->prev = privp;
2856 sf->sf_els_list = privp;
2858 mutex_exit(&sf->sf_mutex);
2866 if (soc_transport(sf->sf_sochandle, fpkt,
2869 mutex_enter(&sf->sf_mutex);
2878 if (sf->sf_els_list == privp) {
2879 sf->sf_els_list = privp->next;
2881 mutex_exit(&sf->sf_mutex);
2886 mutex_exit(&sf->sf_mutex);
2892 SF_DEBUG(2, (sf, CE_NOTE, "ELS %x to al_pa %x failed",
2895 SF_DEBUG(2, (sf, CE_NOTE,
2898 SF_DEBUG(1, (sf, CE_CONT,
2902 SF_DEBUG(2, (sf, CE_NOTE,
2912 mutex_enter(&sf->sf_mutex);
2913 if (sf->sf_lip_cnt == privp->lip_cnt) {
2914 sf->sf_device_count--;
2915 ASSERT(sf->sf_device_count >= 0);
2916 if (sf->sf_device_count == 0) {
2917 sf_finish_init(sf, privp->lip_cnt);
2920 mutex_exit(&sf->sf_mutex);
2932 sf_do_prli(struct sf *sf, struct sf_els_hdr *privp, struct la_els_logi *ptr)
2967 return (sf_els_transport(sf, privp));
2976 sf_do_adisc(struct sf *sf, struct sf_els_hdr *privp)
2989 bcopy((caddr_t)&sf->sf_sochandle->fcal_p_wwn,
2991 bcopy((caddr_t)&sf->sf_sochandle->fcal_n_wwn,
2993 adisc->nport_id = sf->sf_al_pa;
2996 return (sf_els_transport(sf, privp));
3001 sf_els_alloc(struct sf *sf, uchar_t dest_id, int priv_size, int cmd_size,
3021 SF_DEBUG(1, (sf, CE_WARN,
3028 SF_DEBUG(1, (sf, CE_WARN,
3036 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
3038 SF_DEBUG(1, (sf, CE_WARN,
3044 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
3047 SF_DEBUG(1, (sf, CE_WARN,
3053 SF_DEBUG(1, (sf, CE_WARN,
3061 SF_DEBUG(1, (sf, CE_WARN,
3068 SF_DEBUG(1, (sf, CE_WARN,
3073 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
3075 SF_DEBUG(1, (sf, CE_WARN,
3080 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
3083 SF_DEBUG(1, (sf, CE_WARN,
3089 SF_DEBUG(1, (sf, CE_WARN,
3097 SF_DEBUG(1, (sf, CE_WARN,
3104 SF_DEBUG(1, (sf, CE_WARN,
3110 privp->sf = sf;
3119 fpkt->fcal_pkt_cookie = sf->sf_socp;
3124 (ushort_t)(SOC_FC_HEADER | sf->sf_sochandle->fcal_portno);
3143 hp->s_id = sf->sf_al_pa;
3214 sf_create_target(struct sf *sf, struct sf_els_hdr *privp, int tnum, int64_t lun)
3225 mutex_enter(&sf->sf_mutex);
3226 if (sf->sf_lip_cnt != privp->lip_cnt) {
3227 mutex_exit(&sf->sf_mutex);
3233 target = sf_lookup_target(sf, privp->port_wwn, lun);
3239 if ((ptarget = sf_lookup_target(sf, privp->port_wwn,
3244 mutex_exit(&sf->sf_mutex);
3245 sf_log(sf, CE_WARN, "target 0x%x "
3252 if (target != NULL && ptarget->sft_lip_cnt == sf->sf_lip_cnt &&
3256 sf_offline_target(sf, target);
3257 mutex_exit(&sf->sf_mutex);
3275 mutex_exit(&sf->sf_mutex);
3282 mutex_exit(&sf->sf_mutex);
3302 ntarget->sft_next = sf->sf_wwn_lists[hash];
3303 sf->sf_wwn_lists[hash] = ntarget;
3326 mutex_exit(&sf->sf_mutex);
3330 if (target != NULL && target->sft_lip_cnt == sf->sf_lip_cnt) {
3332 sf_offline_target(sf, target); /* And all the baby targets */
3333 mutex_exit(&sf->sf_mutex);
3334 sf_log(sf, CE_WARN, "target 0x%x, duplicate port wwns\n",
3342 if ((otarget = sf->sf_targets[tnum]) != NULL) {
3345 if (otarget->sft_lip_cnt == sf->sf_lip_cnt) {
3347 sf_offline_target(sf, otarget);
3349 sf_offline_target(sf, target);
3350 mutex_exit(&sf->sf_mutex);
3351 sf_log(sf, CE_WARN,
3360 sf_offline_target(sf, otarget);
3361 mutex_exit(&sf->sf_mutex);
3362 sf_log(sf, CE_WARN, "wwn changed on target 0x%x\n",
3364 bzero((caddr_t)&sf->sf_stats.tstats[tnum],
3366 mutex_enter(&sf->sf_mutex);
3370 sf->sf_targets[tnum] = target;
3371 if ((target = sf->sf_targets[tnum]) == NULL) {
3373 mutex_exit(&sf->sf_mutex);
3390 ntarget->sft_next = sf->sf_wwn_lists[hash];
3391 sf->sf_wwn_lists[hash] = ntarget;
3403 sf->sf_targets[tnum] = target;
3406 mutex_exit(&sf->sf_mutex);
3415 mutex_exit(&sf->sf_mutex);
3424 * find the target for a given sf instance
3429 sf_lookup_target(struct sf *sf, uchar_t *wwn, int lun)
3431 sf_lookup_target(struct sf *sf, uchar_t *wwn, int64_t lun)
3437 ASSERT(mutex_owned(&sf->sf_mutex));
3440 target = sf->sf_wwn_lists[hash];
3465 sf_do_reportlun(struct sf *sf, struct sf_els_hdr *privp,
3480 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
3487 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
3548 if (sf_els_transport(sf, privp) == 1)
3552 sf_log(sf, CE_WARN,
3579 struct sf *sf = privp->sf;
3587 mutex_enter(&sf->sf_mutex);
3590 mutex_exit(&sf->sf_mutex);
3597 if (sf->sf_els_list == privp)
3598 sf->sf_els_list = privp->next;
3600 mutex_exit(&sf->sf_mutex);
3603 mutex_enter(&sf->sf_cmd_mutex);
3604 sf->sf_ncmds = ncmds;
3605 mutex_exit(&sf->sf_cmd_mutex);
3613 SF_DEBUG(1, (sf, CE_CONT,
3631 SF_DEBUG(1, (sf, CE_CONT,
3640 SF_DEBUG(1, (sf, CE_CONT,
3650 SF_DEBUG(1, (sf, CE_CONT,
3654 SF_DEBUG(1, (sf, CE_CONT,
3681 SF_DEBUG(2, (sf, CE_CONT,
3686 sf_log(sf, CE_WARN,
3695 mutex_enter(&sf->sf_mutex);
3696 if (sf->sf_lip_cnt == privp->lip_cnt) {
3697 sf->sf_device_count += ptr->lun_list_len - 1;
3700 mutex_exit(&sf->sf_mutex);
3702 sf->sf_lip_cnt; i++) {
3708 target = sf_create_target(sf,
3714 nfpkt = sf_els_alloc(sf,
3726 (sf_do_inquiry(sf, nprivp, target) ==
3728 mutex_enter(&sf->sf_mutex);
3729 if (sf->sf_lip_cnt == privp->
3731 sf->sf_device_count --;
3733 sf_offline_target(sf, target);
3734 mutex_exit(&sf->sf_mutex);
3740 SF_DEBUG(1, (sf, CE_CONT,
3767 mutex_enter(&sf->sf_mutex);
3768 if (privp->lip_cnt == sf->sf_lip_cnt) {
3770 SF_DEBUG(1, (sf, CE_WARN,
3773 privp->next = sf->sf_els_list;
3774 if (sf->sf_els_list != NULL)
3775 sf->sf_els_list->prev = privp;
3776 sf->sf_els_list = privp;
3777 mutex_exit(&sf->sf_mutex);
3778 if (!delayed_retry && soc_transport(sf->sf_sochandle,
3781 mutex_enter(&sf->sf_mutex);
3786 if (sf->sf_els_list == privp)
3787 sf->sf_els_list = privp->next;
3788 mutex_exit(&sf->sf_mutex);
3793 mutex_exit(&sf->sf_mutex);
3799 if (sf_do_inquiry(sf, privp, target) != 0) {
3804 mutex_enter(&sf->sf_mutex);
3805 if (sf->sf_lip_cnt == privp->lip_cnt) {
3806 sf_log(sf, CE_WARN,
3809 sf_offline_target(sf, target);
3810 sf->sf_device_count--;
3811 ASSERT(sf->sf_device_count >= 0);
3812 if (sf->sf_device_count == 0)
3813 sf_finish_init(sf, privp->lip_cnt);
3815 mutex_exit(&sf->sf_mutex);
3823 sf_do_inquiry(struct sf *sf, struct sf_els_hdr *privp,
3839 if (ddi_dma_alloc_handle(sf->sf_dip, sf->sf_sochandle->fcal_dmaattr,
3846 sf->sf_sochandle->fcal_accattr, DDI_DMA_CONSISTENT,
3899 SF_DEBUG(5, (sf, CE_WARN,
3903 return (sf_els_transport(sf, privp));
3906 sf_log(sf, CE_WARN,
3932 struct sf *sf = privp->sf;
3933 struct sf *tsf;
3940 mutex_enter(&sf->sf_mutex);
3943 mutex_exit(&sf->sf_mutex);
3952 if (sf->sf_els_list == privp) {
3953 sf->sf_els_list = privp->next;
3956 mutex_exit(&sf->sf_mutex);
3959 mutex_enter(&sf->sf_cmd_mutex);
3960 sf->sf_ncmds = ncmds;
3961 mutex_exit(&sf->sf_cmd_mutex);
3969 SF_DEBUG(2, (sf, CE_CONT,
3985 SF_DEBUG(2, (sf, CE_CONT,
3994 mutex_enter(&sf->sf_mutex);
3996 if (sf->sf_lip_cnt == privp->lip_cnt) {
4003 sf->sf_device_count--;
4004 ASSERT(sf->sf_device_count >= 0);
4005 if (sf->sf_device_count == 0) {
4006 sf_finish_init(sf,
4010 mutex_exit(&sf->sf_mutex);
4021 SF_DEBUG(2, (sf, CE_CONT, "!INQUIRY to al_pa %x fc status %x",
4028 tsf = sf->sf_sibling;
4046 mutex_enter(&sf->sf_mutex);
4047 if (privp->lip_cnt == sf->sf_lip_cnt) {
4049 SF_DEBUG(1, (sf, CE_WARN,
4053 privp->next = sf->sf_els_list;
4054 if (sf->sf_els_list != NULL) {
4055 sf->sf_els_list->prev = privp;
4057 sf->sf_els_list = privp;
4058 mutex_exit(&sf->sf_mutex);
4061 (soc_transport(sf->sf_sochandle, fpkt,
4064 mutex_enter(&sf->sf_mutex);
4071 if (sf->sf_els_list == privp) {
4072 sf->sf_els_list = privp->next;
4074 mutex_exit(&sf->sf_mutex);
4079 mutex_exit(&sf->sf_mutex);
4082 mutex_enter(&sf->sf_mutex);
4083 if (sf->sf_lip_cnt == privp->lip_cnt) {
4084 sf_offline_target(sf, target);
4085 sf_log(sf, CE_NOTE,
4091 sf->sf_device_count--;
4092 ASSERT(sf->sf_device_count >= 0);
4093 if (sf->sf_device_count == 0) {
4094 sf_finish_init(sf, privp->lip_cnt);
4097 mutex_exit(&sf->sf_mutex);
4104 sf_finish_init(struct sf *sf, int lip_cnt)
4112 SF_DEBUG(1, (sf, CE_WARN, "!sf_finish_init\n"));
4113 ASSERT(mutex_owned(&sf->sf_mutex));
4117 target = sf->sf_wwn_lists[i];
4139 sf_offline_target(sf, target);
4153 mutex_exit(&sf->sf_mutex);
4160 sf_create_devinfo(sf, target, lip_cnt);
4161 mutex_enter(&sf->sf_mutex);
4171 mutex_enter(&sf->sf_mutex);
4185 mutex_enter(&sf->sf_hp_daemon_mutex);
4186 if (sf->sf_hp_elem_tail != NULL) {
4187 sf->sf_hp_elem_tail->next = elem;
4188 sf->sf_hp_elem_tail = elem;
4191 sf->sf_hp_elem_head =
4192 sf->sf_hp_elem_tail =
4195 cv_signal(&sf->sf_hp_daemon_cv);
4196 mutex_exit(&sf->sf_hp_daemon_mutex);
4202 mutex_enter(&sf->sf_mutex);
4206 if (sf->sf_lip_cnt != lip_cnt) {
4217 sf->sf_state = SF_STATE_ONLINE;
4218 sf->sf_online_timer = 0;
4226 sf_create_devinfo(struct sf *sf, struct sf_target *target, int lip_cnt)
4236 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, sf->sf_dip,
4250 sf_log(sf, CE_WARN, "%s%d: no driver for device "
4253 ddi_driver_name(sf->sf_dip), ddi_get_instance(sf->sf_dip),
4260 sf_log(sf, CE_WARN, "%s%d: no driver for device "
4263 ddi_driver_name(sf->sf_dip), ddi_get_instance(sf->sf_dip),
4274 if (ndi_devi_alloc(sf->sf_dip, nname,
4314 sf_log(sf, CE_WARN, "ndi_devi_free failed\n");
4378 sf_offline_target(struct sf *sf, struct sf_target *target)
4384 ASSERT(mutex_owned(&sf->sf_mutex));
4387 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
4392 sf_log(sf, CE_NOTE,
4400 mutex_exit(&sf->sf_mutex);
4407 sf_abort_all(sf, target, FALSE, sf->sf_lip_cnt, FALSE);
4409 mutex_enter(&sf->sf_mutex);
4414 mutex_exit(&sf->sf_mutex);
4417 (void) ndi_event_retrieve_cookie(sf->sf_event_hdl,
4420 (void) ndi_event_run_callbacks(sf->sf_event_hdl,
4429 mutex_enter(&sf->sf_hp_daemon_mutex);
4430 if (sf->sf_hp_elem_tail != NULL) {
4431 sf->sf_hp_elem_tail->next = elem;
4432 sf->sf_hp_elem_tail = elem;
4434 sf->sf_hp_elem_head =
4435 sf->sf_hp_elem_tail =
4438 cv_signal(&sf->sf_hp_daemon_cv);
4439 mutex_exit(&sf->sf_hp_daemon_mutex);
4443 SF_DEBUG(1, (sf, CE_WARN,
4450 SF_DEBUG(1, (sf, CE_NOTE,
4458 mutex_enter(&sf->sf_mutex);
4482 struct sf *sf = ADDR2SF(ap);
4488 SF_DEBUG(3, (sf, CE_WARN, "sf_commoncap: invalid arg"));
4510 SF_DEBUG(3, (sf, CE_WARN,
4516 SF_DEBUG(4, (sf, CE_NOTE,
4529 rval = sf->sf_al_pa;
4545 SF_DEBUG(4, (sf, CE_WARN,
4550 SF_DEBUG(4, (sf, CE_NOTE,
4586 struct sf *sf = ADDR2SF(ap);
4602 SF_DEBUG(2, (sf, CE_NOTE, "sf_abort packet %p\n",
4605 mutex_enter(&sf->sf_cmd_mutex);
4606 ncmd = sf->sf_pkt_head;
4612 sf->sf_pkt_head = cmd->cmd_next;
4625 mutex_exit(&sf->sf_cmd_mutex);
4633 if (((rval = soc_abort(sf->sf_sochandle,
4634 sf->sf_socp, sf->sf_sochandle->fcal_portno,
4646 SF_DEBUG(1, (sf, CE_NOTE,
4654 SF_DEBUG(2, (sf, CE_NOTE, "sf_abort target\n"));
4655 mutex_enter(&sf->sf_mutex);
4656 lip_cnt = sf->sf_lip_cnt;
4666 mutex_exit(&sf->sf_mutex);
4677 if (sf_prepare_pkt(sf, cmd, target) == TRAN_ACCEPT) {
4685 if (soc_transport_poll(sf->sf_sochandle,
4700 sf_abort_all(sf, target, TRUE,
4708 sf->sf_stats.tstats[tgt_id].
4710 SF_DEBUG(1, (sf, CE_NOTE,
4721 if ((t = soc_abort(sf->sf_sochandle,
4722 sf->sf_socp, sf->sf_sochandle->
4726 sf_log(sf, CE_NOTE,
4729 sf_force_lip(sf);
4745 mutex_enter(&sf->sf_mutex);
4746 if (lip_cnt == sf->sf_lip_cnt) {
4751 mutex_exit(&sf->sf_mutex);
4765 struct sf *sf = ADDR2SF(ap);
4782 SF_DEBUG(2, (sf, CE_NOTE, "sf_reset target\n"));
4783 mutex_enter(&sf->sf_mutex);
4786 target = sf_lookup_target(sf, target->sft_port_wwn, 0);
4792 mutex_exit(&sf->sf_mutex);
4796 lip_cnt = sf->sf_lip_cnt;
4811 mutex_exit(&sf->sf_mutex);
4822 if (sf_prepare_pkt(sf, cmd, target) == TRAN_ACCEPT) {
4825 if ((ret = soc_transport_poll(sf->sf_sochandle,
4840 sf_log(sf, CE_NOTE,
4841 "!sf%d: Target 0x%x Reset "
4844 sf->sf_dip),
4854 sf->sf_stats.tstats[tgt_id].
4856 sf_log(sf, CE_NOTE,
4857 "!sf%d: Target 0x%x "
4862 sf->sf_dip),
4871 sf_log(sf, CE_NOTE, "!sf%d: Target "
4873 ddi_get_instance(sf->sf_dip),
4883 if (((t = soc_abort(sf->sf_sochandle,
4884 sf->sf_socp,
4885 sf->sf_sochandle->fcal_portno,
4889 sf_log(sf, CE_NOTE,
4890 "!sf%d: Target 0x%x Reset "
4894 sf->sf_dip),
4897 sf_force_lip(sf);
4923 cmn_err(CE_WARN, "!sf%d: Target 0x%x Reset Failed. "
4925 ddi_get_instance(sf->sf_dip),
4928 mutex_enter(&sf->sf_mutex);
4929 if ((rval == TRUE) && (lip_cnt == sf->sf_lip_cnt)) {
4934 p->next = sf->sf_reset_list;
4935 sf->sf_reset_list = p;
4936 mutex_exit(&sf->sf_mutex);
4945 if (lip_cnt == sf->sf_lip_cnt) {
4957 mutex_exit(&sf->sf_mutex);
4961 mutex_enter(&sf->sf_mutex);
4962 if ((sf->sf_state == SF_STATE_OFFLINE) &&
4963 (sf_watchdog_time < sf->sf_timer)) {
4968 mutex_exit(&sf->sf_mutex);
4971 mutex_exit(&sf->sf_mutex);
4972 sf_log(sf, CE_NOTE, "!sf:Target driver initiated lip\n");
4973 sf_force_lip(sf);
4987 sf_abort_all(struct sf *sf, struct sf_target *target, int abort, int
5001 mutex_enter(&sf->sf_mutex);
5002 if (lip_cnt == sf->sf_lip_cnt) {
5003 mutex_enter(&sf->sf_cmd_mutex);
5004 cmd = sf->sf_pkt_head;
5012 sf->sf_pkt_head = cmd->cmd_next;
5013 if (sf->sf_pkt_tail == cmd) {
5014 sf->sf_pkt_tail = pcmd;
5033 mutex_exit(&sf->sf_cmd_mutex);
5035 mutex_exit(&sf->sf_mutex);
5076 if (try_abort || sf->sf_state == SF_STATE_OFFLINE) {
5095 rval = soc_abort(sf->sf_sochandle,
5096 sf->sf_socp,
5097 sf->sf_sochandle->fcal_portno,
5115 mutex_enter(&sf->sf_mutex);
5116 if (lip_cnt != sf->sf_lip_cnt) {
5117 mutex_exit(&sf->sf_mutex);
5120 mutex_exit(&sf->sf_mutex);
5139 struct sf *sf = ADDR2SF(ap);
5145 SF_DEBUG(6, (sf, CE_NOTE, "sf_start\n"));
5148 cmn_err(CE_PANIC, "sf: issuing packet twice 0x%p\n",
5153 if ((rval = sf_prepare_pkt(sf, cmd, target)) != TRAN_ACCEPT) {
5164 mutex_enter(&sf->sf_cmd_mutex);
5165 sf->sf_use_lock = TRUE;
5172 return (sf_dopoll(sf, cmd));
5177 if (!sf->sf_use_lock) {
5186 if (soc_transport(sf->sf_sochandle, cmd->cmd_fp_pkt,
5196 mutex_enter(&sf->sf_cmd_mutex);
5197 if ((sf->sf_ncmds >= sf->sf_throttle) ||
5198 (sf->sf_pkt_head != NULL)) {
5205 if (sf->sf_pkt_head != NULL) {
5207 sf->sf_pkt_tail->cmd_next = cmd;
5209 sf->sf_pkt_tail = cmd;
5212 sf->sf_pkt_head = sf->sf_pkt_tail = cmd;
5215 mutex_exit(&sf->sf_cmd_mutex);
5224 return (sf_start_internal(sf, cmd));
5234 sf_start_internal(struct sf *sf, struct sf_pkt *cmd)
5237 sf->sf_ncmds++;
5238 mutex_exit(&sf->sf_cmd_mutex);
5241 SF_DEBUG(6, (sf, CE_NOTE, "sf_start_internal\n"));
5248 if (soc_transport(sf->sf_sochandle, cmd->cmd_fp_pkt, FCAL_NOSLEEP,
5251 mutex_enter(&sf->sf_cmd_mutex);
5252 sf->sf_ncmds--;
5253 mutex_exit(&sf->sf_cmd_mutex);
5264 sf_prepare_pkt(struct sf *sf, struct sf_pkt *cmd, struct sf_target *target)
5310 sf_fill_ids(sf, cmd, target);
5319 sf_fill_ids(struct sf *sf, struct sf_pkt *cmd, struct sf_target *target)
5327 hp->s_id = sf->sf_al_pa;
5337 sf_dopoll(struct sf *sf, struct sf_pkt *cmd)
5343 mutex_enter(&sf->sf_cmd_mutex);
5344 sf->sf_ncmds++;
5345 mutex_exit(&sf->sf_cmd_mutex);
5354 rval = soc_transport_poll(sf->sf_sochandle, cmd->cmd_fp_pkt,
5362 (void) sf_target_timeout(sf, cmd);
5368 mutex_enter(&sf->sf_cmd_mutex);
5369 sf->sf_ncmds--;
5370 mutex_exit(&sf->sf_cmd_mutex);
5396 struct sf *sf = ADDR2SF(&pkt->pkt_address);
5408 cmn_err(CE_PANIC, "sf: completing idle packet 0x%p\n",
5436 (void) soc_take_core(sf->sf_sochandle,
5437 sf->sf_socp);
5513 sf->sf_stats.tstats[tgt_id].
5520 sf->sf_stats.tstats[tgt_id].
5527 sf->sf_stats.tstats[tgt_id].
5563 sf_log(sf, CE_NOTE,
5565 sf_force_lip(sf);
5612 sf_log(sf, CE_NOTE,
5623 sf_log(sf, CE_NOTE,
5651 (void) ndi_event_retrieve_cookie(sf->sf_event_hdl,
5654 (void) ndi_event_run_callbacks(sf->sf_event_hdl,
5661 sf_throttle(sf);
5662 sf->sf_use_lock = TRUE;
5718 (void) soc_take_core(sf->sf_sochandle,
5719 sf->sf_socp);
5746 sf_log(sf, CE_NOTE,
5750 sf_force_lip(sf);
5772 sf_log(sf, CE_WARN,
5779 sf_log(sf, CE_WARN, "!Transport error on target=0x%x: %s\n",
5785 if (ncmds >= (sf->sf_throttle - SF_HI_CMD_DELTA)) {
5787 if (!sf->sf_use_lock) {
5788 SF_DEBUG(4, (sf, CE_NOTE, "use lock flag on\n"));
5791 sf->sf_use_lock = TRUE;
5794 mutex_enter(&sf->sf_cmd_mutex);
5795 sf->sf_ncmds = ncmds;
5796 sf_throttle_start(sf);
5797 mutex_exit(&sf->sf_cmd_mutex);
5800 SF_DEBUG(6, (sf, CE_NOTE, "Completing pkt 0x%p\n",
5815 sf_throttle_start(struct sf *sf)
5822 ASSERT(mutex_owned(&sf->sf_cmd_mutex));
5824 cmd = sf->sf_pkt_head;
5826 (sf->sf_state == SF_STATE_ONLINE) &&
5827 (sf->sf_ncmds < sf->sf_throttle)) {
5845 if (sf->sf_pkt_head == cmd) {
5847 sf->sf_pkt_head = cmd->cmd_next;
5848 } else if (sf->sf_pkt_tail == cmd) {
5850 sf->sf_pkt_tail = prev_cmd;
5862 mutex_exit(&sf->sf_cmd_mutex);
5868 sf_fill_ids(sf, cmd, target);
5869 if (sf_start_internal(sf, cmd) != TRAN_ACCEPT) {
5876 mutex_enter(&sf->sf_cmd_mutex);
5877 cmd = sf->sf_pkt_head;
5887 sf_throttle(struct sf *sf)
5889 int cmdmax = sf->sf_sochandle->fcal_cmdmax;
5892 mutex_enter(&sf->sf_cmd_mutex);
5894 sf->sf_flag = TRUE;
5896 if (sf->sf_ncmds > (cmdmax / 2)) {
5897 sf->sf_throttle = cmdmax / 2;
5899 if (sf->sf_ncmds > SF_DECR_DELTA) {
5900 sf->sf_throttle = sf->sf_ncmds - SF_DECR_DELTA;
5906 sf->sf_throttle = SF_DECR_DELTA;
5909 mutex_exit(&sf->sf_cmd_mutex);
5911 sf = sf->sf_sibling;
5912 if (sf != NULL) {
5913 mutex_enter(&sf->sf_cmd_mutex);
5914 sf->sf_flag = TRUE;
5915 if (sf->sf_ncmds >= (cmdmax / 2)) {
5916 sf->sf_throttle = cmdmax / 2;
5918 if (sf->sf_ncmds > SF_DECR_DELTA) {
5919 sf->sf_throttle = sf->sf_ncmds - SF_DECR_DELTA;
5921 sf->sf_throttle = SF_DECR_DELTA;
5925 mutex_exit(&sf->sf_cmd_mutex);
5931 * sf watchdog routine, called for a timeout
5937 struct sf *sf;
5950 for (sf = sf_head; sf != NULL; sf = sf->sf_next) {
5955 mutex_enter(&sf->sf_mutex);
5956 if (sf->sf_state & SF_STATE_SUSPENDED) {
5957 mutex_exit(&sf->sf_mutex);
5958 SF_DEBUG(1, (sf, CE_CONT,
5959 "sf_watch, sf%d:throttle disabled "
5961 ddi_get_instance(sf->sf_dip)));
5965 mutex_exit(&sf->sf_mutex);
5967 cmdmax = sf->sf_sochandle->fcal_cmdmax;
5969 if (sf->sf_take_core) {
5970 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
5973 mutex_enter(&sf->sf_cmd_mutex);
5975 if (!sf->sf_flag) {
5976 if (sf->sf_throttle < (cmdmax / 2)) {
5977 sf->sf_throttle = cmdmax / 2;
5978 } else if ((sf->sf_throttle += SF_INCR_DELTA) >
5980 sf->sf_throttle = cmdmax;
5983 sf->sf_flag = FALSE;
5986 sf->sf_ncmds_exp_avg = (sf->sf_ncmds + sf->sf_ncmds_exp_avg)
5988 if ((sf->sf_ncmds <= (sf->sf_throttle - SF_LO_CMD_DELTA)) &&
5989 (sf->sf_pkt_head == NULL)) {
5991 if (sf->sf_use_lock) {
5992 SF_DEBUG(4, (sf, CE_NOTE,
5996 sf->sf_use_lock = FALSE;
5999 if (sf->sf_state == SF_STATE_ONLINE && sf->sf_pkt_head &&
6000 sf->sf_ncmds < sf->sf_throttle) {
6001 sf_throttle_start(sf);
6004 mutex_exit(&sf->sf_cmd_mutex);
6007 if (sf->sf_ncmds_exp_avg < (sf->sf_cr_pool_cnt <<
6009 sf_crpool_free(sf);
6012 mutex_enter(&sf->sf_mutex);
6014 privp = sf->sf_els_list;
6018 privp = sf_els_timeout(sf, privp);
6020 (privp->lip_cnt != sf->sf_lip_cnt)) {
6024 if (sf->sf_els_list == privp) {
6025 sf->sf_els_list = privp->next;
6030 mutex_exit(&sf->sf_mutex);
6032 mutex_enter(&sf->sf_mutex);
6033 privp = sf->sf_els_list;
6039 if (sf->sf_online_timer && sf->sf_online_timer <
6042 target = sf->sf_targets[i];
6046 sf_log(sf, CE_WARN, "!Loop "
6054 sf_finish_init(sf, sf->sf_lip_cnt);
6055 sf->sf_state = SF_STATE_INIT;
6056 sf->sf_online_timer = 0;
6059 if (sf->sf_state == SF_STATE_ONLINE) {
6060 mutex_exit(&sf->sf_mutex);
6062 sf_check_targets(sf);
6064 } else if ((sf->sf_state == SF_STATE_OFFLINE) &&
6065 (sf->sf_timer < sf_watchdog_time)) {
6067 target = sf->sf_targets[i];
6071 sf_log(sf, CE_WARN,
6076 sf->sf_sochandle,
6077 sf->sf_socp);
6083 sf_finish_init(sf, sf->sf_lip_cnt);
6084 sf->sf_state = SF_STATE_INIT;
6085 mutex_exit(&sf->sf_mutex);
6087 mutex_exit(&sf->sf_mutex);
6114 sf_check_targets(struct sf *sf)
6122 mutex_enter(&sf->sf_mutex);
6123 lip_cnt = sf->sf_lip_cnt;
6124 mutex_exit(&sf->sf_mutex);
6128 target = sf->sf_targets[i];
6156 sf->sf_stats.tstats[i].timeouts++;
6157 if (sf_target_timeout(sf, cmd))
6160 if (lip_cnt != sf->sf_lip_cnt) {
6181 SF_DEBUG(1, (sf, CE_NOTE,
6232 sf_target_timeout(struct sf *sf, struct sf_pkt *cmd)
6241 SF_DEBUG(1, (sf, CE_NOTE, "Command 0x%p to target %x timed out\n",
6250 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6255 rval = soc_abort(sf->sf_sochandle, sf->sf_socp,
6256 sf->sf_sochandle->fcal_portno, fpkt, 1);
6260 SF_DEBUG(1, (sf, CE_NOTE, "Command Abort succeeded\n"));
6271 SF_DEBUG(1, (sf, CE_NOTE, "Command Abort failed at target\n"));
6277 sf->sf_stats.tstats[tgt_id].abts_failures++;
6287 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6290 SF_DEBUG(1, (sf, CE_NOTE, "Command Abort bad abort\n"));
6302 sf_log(sf, CE_WARN,
6307 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6310 sf_force_lip(sf);
6324 sf_els_timeout(struct sf *sf, struct sf_els_hdr *privp)
6337 mutex_exit(&sf->sf_mutex);
6354 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6362 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6372 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6384 SF_DEBUG(2, (sf, CE_CONT,
6385 "!sf%d: %s to target %x delayed retry\n",
6386 ddi_get_instance(sf->sf_dip), what,
6392 sf_log(sf, CE_NOTE, "!%s to target 0x%x alpa 0x%x timed out\n",
6396 rval = soc_abort(sf->sf_sochandle, sf->sf_socp, sf->sf_sochandle
6399 SF_DEBUG(1, (sf, CE_NOTE, "!%s abort to al_pa %x succeeded\n",
6403 mutex_enter(&sf->sf_mutex);
6407 if (sf->sf_els_list == privp) {
6408 sf->sf_els_list = privp->next;
6414 if (lip_cnt == sf->sf_lip_cnt) {
6418 mutex_exit(&sf->sf_mutex);
6419 sf_log(sf, CE_NOTE,
6423 if (sf_els_transport(sf, privp) == 1) {
6424 mutex_enter(&sf->sf_mutex);
6425 return (sf->sf_els_list); /* success */
6427 mutex_enter(&sf->sf_mutex);
6430 if ((lip_cnt == sf->sf_lip_cnt) &&
6433 sf_offline_target(sf, target);
6435 if (sf->sf_lip_cnt == lip_cnt) {
6436 sf->sf_device_count--;
6437 ASSERT(sf->sf_device_count >= 0);
6438 if (sf->sf_device_count == 0) {
6439 sf_finish_init(sf,
6440 sf->sf_lip_cnt);
6444 privp = sf->sf_els_list;
6445 mutex_exit(&sf->sf_mutex);
6450 mutex_exit(&sf->sf_mutex);
6459 (void) soc_take_core(sf->sf_sochandle, sf->sf_socp);
6462 sf_log(sf, CE_NOTE, "%s abort to target 0x%x failed. "
6466 if (sf->sf_lip_cnt == lip_cnt) {
6467 sf_force_lip(sf);
6471 mutex_enter(&sf->sf_mutex);
6483 struct sf *sf;
6495 for (sf = sf_head; sf != NULL; sf = sf->sf_next) {
6498 mutex_enter(&sf->sf_mutex);
6501 tp = (struct sf_reset_list *)&sf->sf_reset_list;
6503 rp = sf->sf_reset_list;
6506 (rp->lip_cnt == sf->sf_lip_cnt)) {
6508 mutex_exit(&sf->sf_mutex);
6514 sf_abort_all(sf, target, FALSE,
6517 if (lip_cnt == sf->sf_lip_cnt) {
6524 mutex_enter(&sf->sf_mutex);
6526 &sf->sf_reset_list;
6527 rp = sf->sf_reset_list;
6529 } else if (rp->lip_cnt != sf->sf_lip_cnt) {
6539 mutex_exit(&sf->sf_mutex);
6557 sf_force_lip(struct sf *sf)
6564 mutex_enter(&sf->sf_mutex);
6565 if (sf->sf_state & SF_STATE_SUSPENDED) {
6566 mutex_exit(&sf->sf_mutex);
6567 SF_DEBUG(1, (sf, CE_CONT,
6568 "sf_force_lip, sf%d: lip restart disabled "
6570 ddi_get_instance(sf->sf_dip)));
6574 sf_log(sf, CE_NOTE, "Forcing lip\n");
6577 target = sf->sf_targets[i];
6587 sf->sf_lip_cnt++;
6588 sf->sf_timer = sf_watchdog_time + SF_OFFLINE_TIMEOUT;
6589 sf->sf_state = SF_STATE_OFFLINE;
6590 mutex_exit(&sf->sf_mutex);
6591 sf->sf_stats.lip_count++; /* no mutex for this? */
6598 if (((i = soc_force_lip(sf->sf_sochandle, sf->sf_socp,
6599 sf->sf_sochandle->fcal_portno, 1,
6604 (void) soc_take_core(sf->sf_sochandle,
6605 sf->sf_socp);
6613 sf_log(sf, CE_NOTE,
6617 soc_force_reset(sf->sf_sochandle, sf->sf_socp,
6618 sf->sf_sochandle->fcal_portno, 1);
6635 struct sf *sf = (struct sf *)arg;
6662 sf->sf_stats.tstats[tgt_id].logouts_recvd++;
6663 sf_log(sf, CE_NOTE, "!LOGO recvd from target %x, %s\n",
6667 sf_force_lip(sf);
6677 sf_log(sf, CE_NOTE, "!ELS 0x%x recvd from target 0x%x\n",
6682 if (sf_els_alloc(sf, dest_id, sizeof (struct sf_els_hdr),
6712 (void) sf_els_transport(sf, privp);
6724 sf_log(struct sf *sf, int level, const char *fmt, ...)
6730 if (sf != NULL) {
6731 dip = sf->sf_dip;
6739 scsi_log(dip, "sf", level, buf);
6744 * called to get some sf kstats -- return 0 on success else return errno
6749 struct sf *sf;
6756 sf = ksp->ks_private;
6757 sf->sf_stats.ncmds = sf->sf_ncmds;
6758 sf->sf_stats.throttle_limit = sf->sf_throttle;
6759 sf->sf_stats.cr_pool_size = sf->sf_cr_pool_cnt;
6777 struct sf *sf;
6781 sf = ddi_get_soft_state(sf_state, SF_MINOR2INST(getminor(dev)));
6782 if (sf == NULL) {
6786 ++(sf->sf_check_n_close);
6799 struct sf *sf;
6801 sf = ddi_get_soft_state(sf_state, SF_MINOR2INST(getminor(dev)));
6802 if (sf == NULL) {
6806 if (!sf->sf_check_n_close) { /* if this flag is zero */
6807 cmn_err(CE_WARN, "sf%d: trying to close unopened instance",
6811 --(sf->sf_check_n_close);
6818 * driver entry point for sf ioctl commands
6825 struct sf *sf;
6837 sf = ddi_get_soft_state(sf_state, SF_MINOR2INST(getminor(dev)));
6838 if (sf == NULL) {
6852 return (ndi_devctl_ioctl(sf->sf_dip, cmd, arg, mode, 0));
6858 if ((sf->sf_lilp_map->lilp_magic != FCAL_LILP_MAGIC &&
6859 sf->sf_lilp_map->lilp_magic != FCAL_BADLILP_MAGIC) ||
6860 sf->sf_state != SF_STATE_ONLINE) {
6864 mutex_enter(&sf->sf_mutex);
6865 if (sf->sf_lilp_map->lilp_magic == FCAL_BADLILP_MAGIC) {
6870 if (sf->sf_targets[i])
6871 sf->sf_lilp_map->lilp_alpalist[j++] =
6872 sf->sf_targets[i]->
6875 sf->sf_lilp_map->lilp_length = (uchar_t)j;
6877 cnt = sf->sf_lilp_map->lilp_length;
6879 bcopy((caddr_t)&sf->sf_sochandle->fcal_n_wwn,
6882 bcopy((caddr_t)&sf->sf_sochandle->fcal_p_wwn,
6885 map.sf_hba_addr.sf_al_pa = sf->sf_al_pa;
6889 al_pa = sf->sf_lilp_map->lilp_alpalist[i];
6891 if (al_pa == sf->sf_al_pa) {
6892 (void) bcopy((caddr_t)&sf->sf_sochandle
6896 (void) bcopy((caddr_t)&sf->sf_sochandle
6906 target = sf->sf_targets[sf_alpa_to_switch[
6941 mutex_exit(&sf->sf_mutex);
6963 cdip = ndi_devi_find(sf->sf_dip,
6972 if ((target = sf_get_target_from_dip(sf, cdip)) == NULL) {
7004 sf_force_lip(sf);
7023 sf_get_target_from_dip(struct sf *sf, dev_info_t *dip)
7031 target = sf->sf_wwn_lists[i];
7050 struct sf *sf;
7052 sf = ddi_get_soft_state(sf_state, ddi_get_instance(dip));
7053 if (sf == NULL) {
7058 return (ndi_event_retrieve_cookie(sf->sf_event_hdl, rdip, name,
7073 struct sf *sf;
7075 sf = ddi_get_soft_state(sf_state, ddi_get_instance(dip));
7076 if (sf == NULL) {
7081 return (ndi_event_add_callback(sf->sf_event_hdl, rdip,
7093 struct sf *sf;
7095 sf = ddi_get_soft_state(sf_state, ddi_get_instance(devi));
7096 if (sf == NULL) {
7101 return (ndi_event_remove_callback(sf->sf_event_hdl, cb_id));
7115 struct sf *sf = ddi_get_soft_state(sf_state, ddi_get_instance(dip));
7116 remove_cookie = ndi_event_tag_to_cookie(sf->sf_event_hdl,
7124 if (sf == NULL) {
7125 /* no sf instance for this device */
7130 if ((target = sf_get_target_from_dip(sf, rdip)) != NULL) {
7157 * the sf hotplug daemon, one thread per sf instance
7162 struct sf *sf = (struct sf *)arg;
7168 CALLB_CPR_INIT(&cprinfo, &sf->sf_hp_daemon_mutex,
7171 mutex_enter(&sf->sf_hp_daemon_mutex);
7174 while (sf->sf_hp_elem_head != NULL) {
7177 elem = sf->sf_hp_elem_head;
7180 if (sf->sf_hp_elem_head == sf->sf_hp_elem_tail) {
7182 sf->sf_hp_elem_head = NULL;
7183 sf->sf_hp_elem_tail = NULL;
7186 sf->sf_hp_elem_head = sf->sf_hp_elem_head->next;
7189 mutex_exit(&sf->sf_hp_daemon_mutex);
7197 sf->sf_event_hdl,
7200 (void) ndi_event_run_callbacks(sf->sf_event_hdl,
7210 SF_DEBUG(1, (sf, CE_WARN, "target %x, "
7213 SF_DEBUG(1, (sf, CE_NOTE, "target %x, "
7220 mutex_enter(&sf->sf_hp_daemon_mutex);
7224 if (sf->sf_hp_exit == 0) {
7227 cv_wait(&sf->sf_hp_daemon_cv, &sf->sf_hp_daemon_mutex);
7228 CALLB_CPR_SAFE_END(&cprinfo, &sf->sf_hp_daemon_mutex);
7230 } while (sf->sf_hp_exit == 0);