예제 #1
0
파일: chsc.c 프로젝트: jay-caoj/linux-3.9.6
static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area)
{
    struct channel_path *chp;
    struct chp_id chpid;
    u8 *data;
    int num;

    CIO_CRW_EVENT(4, "chsc: channel path availability information\n");
    if (sei_area->rs != 0)
        return;
    data = sei_area->ccdf;
    chp_id_init(&chpid);
    for (num = 0; num <= __MAX_CHPID; num++) {
        if (!chp_test_bit(data, num))
            continue;
        chpid.id = num;

        CIO_CRW_EVENT(4, "Update information for channel path "
                      "%x.%02x\n", chpid.cssid, chpid.id);
        chp = chpid_to_chp(chpid);
        if (!chp) {
            chp_new(chpid);
            continue;
        }
        mutex_lock(&chp->lock);
        chsc_determine_base_channel_path_desc(chpid, &chp->desc);
        mutex_unlock(&chp->lock);
    }
}
예제 #2
0
파일: chp.c 프로젝트: 19Dan01/linux
static int __init chp_init(void)
{
	struct chp_id chpid;
	int ret;

	ret = crw_register_handler(CRW_RSC_CPATH, chp_process_crw);
	if (ret)
		return ret;
	chp_wq = create_singlethread_workqueue("cio_chp");
	if (!chp_wq) {
		crw_unregister_handler(CRW_RSC_CPATH);
		return -ENOMEM;
	}
	INIT_WORK(&cfg_work, cfg_func);
	init_waitqueue_head(&cfg_wait_queue);
	if (info_update())
		return 0;
	/* Register available channel-paths. */
	chp_id_for_each(&chpid) {
		if (chp_info_get_status(chpid) != CHP_STATUS_NOT_RECOGNIZED)
			chp_new(chpid);
	}

	return 0;
}
예제 #3
0
파일: chsc.c 프로젝트: jay-caoj/linux-3.9.6
static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
{
    struct chp_link link;
    struct chp_id chpid;
    int status;

    CIO_CRW_EVENT(4, "chsc: resource accessibility event (rs=%02x, "
                  "rs_id=%04x)\n", sei_area->rs, sei_area->rsid);
    if (sei_area->rs != 4)
        return;
    chp_id_init(&chpid);
    chpid.id = sei_area->rsid;
    /* allocate a new channel path structure, if needed */
    status = chp_get_status(chpid);
    if (status < 0)
        chp_new(chpid);
    else if (!status)
        return;
    memset(&link, 0, sizeof(struct chp_link));
    link.chpid = chpid;
    if ((sei_area->vf & 0xc0) != 0) {
        link.fla = sei_area->fla;
        if ((sei_area->vf & 0xc0) == 0xc0)
            /* full link address */
            link.fla_mask = 0xffff;
        else
            /* link address */
            link.fla_mask = 0xff00;
    }
    s390_process_res_acc(&link);
}
예제 #4
0
파일: css.c 프로젝트: rajat1994/linux
static void ssd_register_chpids(struct chsc_ssd_info *ssd)
{
	int i;
	int mask;

	for (i = 0; i < 8; i++) {
		mask = 0x80 >> i;
		if (ssd->path_mask & mask)
			if (!chp_is_registered(ssd->chpid[i]))
				chp_new(ssd->chpid[i]);
	}
}
예제 #5
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);
}
예제 #6
0
static int __init chp_init(void)
{
	struct chp_id chpid;

	chp_wq = create_singlethread_workqueue("cio_chp");
	if (!chp_wq)
		return -ENOMEM;
	INIT_WORK(&cfg_work, cfg_func, NULL);
	init_waitqueue_head(&cfg_wait_queue);
	if (info_update())
		return 0;
	/* Register available channel-paths. */
	chp_id_for_each(&chpid) {
		if (chp_info_get_status(chpid) != CHP_STATUS_NOT_RECOGNIZED)
			chp_new(chpid);
	}

	return 0;
}
예제 #7
0
파일: chp.c 프로젝트: 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);
	}
}