/** * chp_cfg_cancel_deconfigure - cancel chpid deconfiguration request * @chpid - channel-path ID * * Cancel an active channel-path deconfiguration request if it has not yet * been performed. */ void chp_cfg_cancel_deconfigure(struct chp_id chpid) { CIO_MSG_EVENT(2, "chp_cfg_cancel:%x.%02x\n", chpid.cssid, chpid.id); mutex_lock(&cfg_lock); if (cfg_get_task(chpid) == cfg_deconfigure) cfg_set_task(chpid, cfg_none); mutex_unlock(&cfg_lock); }
/** * chp_cfg_schedule - schedule chpid configuration request * @chpid - channel-path ID * @configure - Non-zero for configure, zero for deconfigure * * Schedule a channel-path configuration/deconfiguration request. */ void chp_cfg_schedule(struct chp_id chpid, int configure) { CIO_MSG_EVENT(2, "chp_cfg_sched%x.%02x=%d\n", chpid.cssid, chpid.id, configure); mutex_lock(&cfg_lock); cfg_set_task(chpid, configure ? cfg_configure : cfg_deconfigure); cfg_busy = 1; mutex_unlock(&cfg_lock); queue_work(chp_wq, &cfg_work); }
/* Perform one configure/deconfigure request. Reschedule work function until * last request. */ static void cfg_func(struct work_struct *work) { struct chp_id chpid; enum cfg_task_t t; int rc; mutex_lock(&cfg_lock); t = cfg_none; chp_id_for_each(&chpid) { t = cfg_get_task(chpid); if (t != cfg_none) { cfg_set_task(chpid, cfg_none); break; } } mutex_unlock(&cfg_lock); switch (t) { case cfg_configure: rc = sclp_chp_configure(chpid); if (rc) CIO_MSG_EVENT(2, "chp: sclp_chp_configure(%x.%02x)=" "%d\n", chpid.cssid, chpid.id, rc); else { info_expire(); chsc_chp_online(chpid); } break; case cfg_deconfigure: rc = sclp_chp_deconfigure(chpid); if (rc) CIO_MSG_EVENT(2, "chp: sclp_chp_deconfigure(%x.%02x)=" "%d\n", chpid.cssid, chpid.id, rc); else { info_expire(); chsc_chp_offline(chpid); } break; case cfg_none: /* Get updated information after last change. */ info_update(); mutex_lock(&cfg_lock); cfg_busy = 0; mutex_unlock(&cfg_lock); wake_up_interruptible(&cfg_wait_queue); return; } queue_work(chp_wq, &cfg_work); }
/* Perform one configure/deconfigure request. Reschedule work function until * last request. */ static void cfg_func(void *data) { struct chp_id chpid; enum cfg_task_t t; mutex_lock(&cfg_lock); t = cfg_none; chp_id_for_each(&chpid) { t = cfg_get_task(chpid); if (t != cfg_none) { cfg_set_task(chpid, cfg_none); break; } } mutex_unlock(&cfg_lock); switch (t) { case cfg_configure: sclp_chp_configure(chpid); info_expire(); chsc_chp_online(chpid); break; case cfg_deconfigure: sclp_chp_deconfigure(chpid); info_expire(); chsc_chp_offline(chpid); break; case cfg_none: /* Get updated information after last change. */ info_update(); mutex_lock(&cfg_lock); cfg_busy = 0; mutex_unlock(&cfg_lock); wake_up_interruptible(&cfg_wait_queue); return; } queue_work(chp_wq, &cfg_work); }