/* 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); }