Example #1
0
/**
 * chp_process_crw - process channel-path status change
 * @id: channel-path ID number
 * @status: non-zero if channel-path has become available, zero otherwise
 *
 * Handle channel-report-words indicating that the status of a channel-path
 * has changed.
 */
void chp_process_crw(int id, int status)
{
	struct chp_id chpid;

	chp_id_init(&chpid);
	chpid.id = id;
	if (status) {
		if (!chp_is_registered(chpid))
			chp_new(chpid);
		chsc_chp_online(chpid);
	} else
		chsc_chp_offline(chpid);
}
Example #2
0
File: chp.c Project: 19Dan01/linux
/* 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);
}
Example #3
0
File: chp.c Project: 19Dan01/linux
/**
 * chp_process_crw - process channel-path status change
 * @crw0: channel report-word to handler
 * @crw1: second channel-report word (always NULL)
 * @overflow: crw overflow indication
 *
 * Handle channel-report-words indicating that the status of a channel-path
 * has changed.
 */
static void chp_process_crw(struct crw *crw0, struct crw *crw1,
			    int overflow)
{
	struct chp_id chpid;

	if (overflow) {
		css_schedule_eval_all();
		return;
	}
	CIO_CRW_EVENT(2, "CRW reports slct=%d, oflw=%d, "
		      "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
		      crw0->slct, crw0->oflw, crw0->chn, crw0->rsc, crw0->anc,
		      crw0->erc, crw0->rsid);
	/*
	 * Check for solicited machine checks. These are
	 * created by reset channel path and need not be
	 * handled here.
	 */
	if (crw0->slct) {
		CIO_CRW_EVENT(2, "solicited machine check for "
			      "channel path %02X\n", crw0->rsid);
		return;
	}
	chp_id_init(&chpid);
	chpid.id = crw0->rsid;
	switch (crw0->erc) {
	case CRW_ERC_IPARM: /* Path has come. */
		if (!chp_is_registered(chpid))
			chp_new(chpid);
		chsc_chp_online(chpid);
		break;
	case CRW_ERC_PERRI: /* Path has gone. */
	case CRW_ERC_PERRN:
		chsc_chp_offline(chpid);
		break;
	default:
		CIO_CRW_EVENT(2, "Don't know how to handle erc=%x\n",
			      crw0->erc);
	}
}
Example #4
0
/* 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);
}