/** * chsc_chp_vary - propagate channel-path vary operation to subchannels * @chpid: channl-path ID * @on: non-zero for vary online, zero for vary offline */ int chsc_chp_vary(struct chp_id chpid, int on) { struct channel_path *chp = chpid_to_chp(chpid); /* Wait until previous actions have settled. */ css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ if (on) { /* Try to update the channel path descritor. */ chsc_determine_base_channel_path_desc(chpid, &chp->desc); for_each_subchannel_staged(s390_subchannel_vary_chpid_on, __s390_vary_chpid_on, &chpid); } else for_each_subchannel_staged(s390_subchannel_vary_chpid_off, NULL, &chpid); return 0; }
/** * chsc_chp_vary - propagate channel-path vary operation to subchannels * @chpid: channl-path ID * @on: non-zero for vary online, zero for vary offline */ int chsc_chp_vary(struct chp_id chpid, int on) { struct channel_path *chp = chpid_to_chp(chpid); /* Wait until previous actions have settled. */ css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ if (on) { /* Try to update the channel path description. */ chp_update_desc(chp); for_each_subchannel_staged(s390_subchannel_vary_chpid_on, NULL, &chpid); css_schedule_reprobe(); } else for_each_subchannel_staged(s390_subchannel_vary_chpid_off, NULL, &chpid); return 0; }
/** * chsc_chp_vary - propagate channel-path vary operation to subchannels * @chpid: channl-path ID * @on: non-zero for vary online, zero for vary offline */ int chsc_chp_vary(struct chp_id chpid, int on) { struct chp_link link; memset(&link, 0, sizeof(struct chp_link)); link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); /* * Redo PathVerification on the devices the chpid connects to */ if (on) for_each_subchannel_staged(s390_subchannel_vary_chpid_on, __s390_vary_chpid_on, &link); else for_each_subchannel_staged(s390_subchannel_vary_chpid_off, NULL, &link); return 0; }
static void css_slow_path_func(struct work_struct *unused) { unsigned long flags; CIO_TRACE_EVENT(4, "slowpath"); for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, NULL); spin_lock_irqsave(&slow_subchannel_lock, flags); if (idset_is_empty(slow_subchannel_set)) { atomic_set(&css_eval_scheduled, 0); wake_up(&css_eval_wq); } spin_unlock_irqrestore(&slow_subchannel_lock, flags); }
void chsc_chp_offline(struct chp_id chpid) { char dbf_txt[15]; struct chp_link link; sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) <= 0) return; memset(&link, 0, sizeof(struct chp_link)); link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link); }
void chsc_chp_online(struct chp_id chpid) { char dbf_txt[15]; struct chp_link link; sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); if (chp_get_status(chpid) != 0) { memset(&link, 0, sizeof(struct chp_link)); link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); for_each_subchannel_staged(__s390_process_res_acc, NULL, &link); } }
static void s390_process_res_acc(struct chp_link *link) { char dbf_txt[15]; sprintf(dbf_txt, "accpr%x.%02x", link->chpid.cssid, link->chpid.id); CIO_TRACE_EVENT( 2, dbf_txt); if (link->fla != 0) { sprintf(dbf_txt, "fla%x", link->fla); CIO_TRACE_EVENT( 2, dbf_txt); } /* Wait until previous actions have settled. */ css_wait_for_slow_path(); /* * I/O resources may have become accessible. * Scan through all subchannels that may be concerned and * do a validation on those. * The more information we have (info), the less scanning * will we have to do. */ for_each_subchannel_staged(__s390_process_res_acc, s390_process_res_acc_new_sch, link); }