cregit-Linux how code gets into the kernel

Release 4.18 drivers/s390/char/sclp_config.c

// SPDX-License-Identifier: GPL-2.0
/*
 *    Copyright IBM Corp. 2007
 *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
 */


#define KMSG_COMPONENT "sclp_config"

#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/cpu.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <asm/smp.h>

#include "sclp.h"


struct conf_mgm_data {
	
u8 reserved;
	
u8 ev_qualifier;
} __attribute__((packed));


#define OFB_DATA_MAX 64


struct sclp_ofb_evbuf {
	
struct evbuf_header header;
	
struct conf_mgm_data cm_data;
	
char ev_data[OFB_DATA_MAX];

} __packed;


struct sclp_ofb_sccb {
	
struct sccb_header header;
	
struct sclp_ofb_evbuf ofb_evbuf;

} __packed;


#define EV_QUAL_CPU_CHANGE	1

#define EV_QUAL_CAP_CHANGE	3

#define EV_QUAL_OPEN4BUSINESS	5


static struct work_struct sclp_cpu_capability_work;

static struct work_struct sclp_cpu_change_work;


static void sclp_cpu_capability_notify(struct work_struct *work) { int cpu; struct device *dev; s390_update_cpu_mhz(); pr_info("CPU capability may have changed\n"); get_online_cpus(); for_each_online_cpu(cpu) { dev = get_cpu_device(cpu); kobject_uevent(&dev->kobj, KOBJ_CHANGE); } put_online_cpus(); }

Contributors

PersonTokensPropCommitsCommitProp
Heiko Carstens4885.71%457.14%
Kay Sievers58.93%114.29%
Gautham R. Shenoy23.57%114.29%
Martin Schwidefsky11.79%114.29%
Total56100.00%7100.00%


static void __ref sclp_cpu_change_notify(struct work_struct *work) { smp_rescan_cpus(); }

Contributors

PersonTokensPropCommitsCommitProp
Heiko Carstens15100.00%3100.00%
Total15100.00%3100.00%


static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) { struct conf_mgm_data *cdata; cdata = (struct conf_mgm_data *)(evbuf + 1); switch (cdata->ev_qualifier) { case EV_QUAL_CPU_CHANGE: schedule_work(&sclp_cpu_change_work); break; case EV_QUAL_CAP_CHANGE: schedule_work(&sclp_cpu_capability_work); break; } }

Contributors

PersonTokensPropCommitsCommitProp
Heiko Carstens57100.00%2100.00%
Total57100.00%2100.00%

static struct sclp_register sclp_conf_register = { #ifdef CONFIG_SCLP_OFB .send_mask = EVTYP_CONFMGMDATA_MASK, #endif .receive_mask = EVTYP_CONFMGMDATA_MASK, .receiver_fn = sclp_conf_receiver_fn, }; #ifdef CONFIG_SCLP_OFB
static int sclp_ofb_send_req(char *ev_data, size_t len) { static DEFINE_MUTEX(send_mutex); struct sclp_ofb_sccb *sccb; int rc, response; if (len > OFB_DATA_MAX) return -EINVAL; sccb = (struct sclp_ofb_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!sccb) return -ENOMEM; /* Setup SCCB for Control-Program Identification */ sccb->header.length = sizeof(struct sclp_ofb_sccb); sccb->ofb_evbuf.header.length = sizeof(struct sclp_ofb_evbuf); sccb->ofb_evbuf.header.type = EVTYP_CONFMGMDATA; sccb->ofb_evbuf.cm_data.ev_qualifier = EV_QUAL_OPEN4BUSINESS; memcpy(sccb->ofb_evbuf.ev_data, ev_data, len); if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) pr_warn("SCLP receiver did not register to receive " "Configuration Management Data Events.\n"); mutex_lock(&send_mutex); rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb); mutex_unlock(&send_mutex); if (rc) goto out; response = sccb->header.response_code; if (response != 0x0020) { pr_err("Open for Business request failed with response code " "0x%04x\n", response); rc = -EIO; } out: free_page((unsigned long)sccb); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
Jochen Schweflinghaus210100.00%1100.00%
Total210100.00%1100.00%


static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count) { int rc; rc = sclp_ofb_send_req(buf, count); return rc ?: count; }

Contributors

PersonTokensPropCommitsCommitProp
Jochen Schweflinghaus49100.00%1100.00%
Total49100.00%1100.00%

static const struct bin_attribute ofb_bin_attr = { .attr = { .name = "event_data", .mode = S_IWUSR, }, .write = sysfs_ofb_data_write, }; #endif
static int __init sclp_ofb_setup(void) { #ifdef CONFIG_SCLP_OFB struct kset *ofb_kset; int rc; ofb_kset = kset_create_and_add("ofb", NULL, firmware_kobj); if (!ofb_kset) return -ENOMEM; rc = sysfs_create_bin_file(&ofb_kset->kobj, &ofb_bin_attr); if (rc) { kset_unregister(ofb_kset); return rc; } #endif return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Jochen Schweflinghaus72100.00%1100.00%
Total72100.00%1100.00%


static int __init sclp_conf_init(void) { int rc; INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); rc = sclp_register(&sclp_conf_register); if (rc) return rc; return sclp_ofb_setup(); }

Contributors

PersonTokensPropCommitsCommitProp
Heiko Carstens3165.96%375.00%
Jochen Schweflinghaus1634.04%125.00%
Total47100.00%4100.00%

__initcall(sclp_conf_init);

Overall Contributors

PersonTokensPropCommitsCommitProp
Jochen Schweflinghaus43763.52%16.67%
Heiko Carstens22933.28%960.00%
Martin Schwidefsky121.74%16.67%
Kay Sievers60.87%16.67%
Gautham R. Shenoy20.29%16.67%
Greg Kroah-Hartman10.15%16.67%
Bhumika Goyal10.15%16.67%
Total688100.00%15100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.