11 #include <linux/export.h>
12 #include <linux/sched.h>
15 #include <linux/wait.h>
17 #include <linux/errno.h>
18 #include <linux/slab.h>
19 #include <asm/chpid.h>
29 #define to_channelpath(device) container_of(device, struct channel_path, dev)
30 #define CHP_INFO_UPDATE_INTERVAL 1*HZ
48 static unsigned long chp_info_expires;
60 chpid_to_chp(chpid)->state =
onoff;
67 return (chpid_to_chp(chpid) ? chpid_to_chp(chpid)->
state : -
ENODEV);
85 for (i = 0; i < 8; i++) {
104 return chpid_to_chp(chpid) !=
NULL;
111 static int s390_vary_chpid(
struct chp_id chpid,
int on)
116 sprintf(dbf_text, on?
"varyon%x.%02x":
"varyoff%x.%02x", chpid.
cssid,
124 set_chp_logically_online(chpid, on);
132 static ssize_t chp_measurement_chars_read(
struct file *filp,
135 char *
buf, loff_t off,
size_t count)
151 .name =
"measurement_chars",
155 .
read = chp_measurement_chars_read,
158 static void chp_measurement_copy_block(
struct cmg_entry *buf,
166 if (chpid.
id < 128) {
171 idx = chpid.
id - 128;
173 entry = area + (idx *
sizeof(
struct cmg_entry));
175 memcpy(buf, entry,
sizeof(*entry));
176 memcpy(&reference_buf, entry,
sizeof(*entry));
182 char *buf, loff_t off,
size_t count)
186 struct device *device;
196 if (off || count < size)
198 chp_measurement_copy_block((
struct cmg_entry *)buf, css, chp->
chpid);
205 .name =
"measurement",
209 .
read = chp_measurement_read,
234 static ssize_t chp_status_show(
struct device *
dev,
244 return status ?
sprintf(buf,
"online\n") : sprintf(buf,
"offline\n");
247 static ssize_t chp_status_write(
struct device *dev,
249 const char *buf,
size_t count)
256 num_args =
sscanf(buf,
"%5s", cmd);
262 error = s390_vary_chpid(cp->
chpid, 1);
266 error = s390_vary_chpid(cp->
chpid, 0);
271 return error < 0 ? error :
count;
274 static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
276 static ssize_t chp_configure_show(
struct device *dev,
290 static int cfg_wait_idle(
void);
292 static ssize_t chp_configure_write(
struct device *dev,
294 const char *buf,
size_t count)
300 if (
sscanf(buf,
"%d %c", &val, &delim) != 1)
302 if (val != 0 && val != 1)
311 static DEVICE_ATTR(configure, 0644, chp_configure_show, chp_configure_write);
320 type = chp->
desc.desc;
322 return sprintf(buf,
"%x\n", type);
335 return sprintf(buf,
"unknown\n");
341 static ssize_t chp_shared_show(
struct device *dev,
349 return sprintf(buf,
"unknown\n");
356 &dev_attr_status.attr,
357 &dev_attr_configure.attr,
360 &dev_attr_shared.attr,
371 static void chp_release(
struct device *dev)
401 chp->
dev.groups = chp_attr_groups;
402 chp->
dev.release = chp_release;
409 if ((chp->
desc.flags & 0x80) == 0) {
461 chp = chpid_to_chp(chpid);
483 static void chp_process_crw(
struct crw *crw0,
struct crw *crw1,
493 "chn=%d, rsc=%X, anc=%d, erc=%X, rsid=%X\n",
503 "channel path %02X\n", crw0->
rsid);
529 for (i = 0; i < 8; i++) {
533 if (!chp_id_is_equal(&ssd->
chpid[i], &link->
chpid))
544 static inline int info_bit_num(
struct chp_id id)
550 static void info_expire(
void)
553 chp_info_expires =
jiffies - 1;
558 static int info_update(
void)
590 bit = info_bit_num(chpid);
592 if (!chp_test_bit(chp_info.recognized, bit))
594 else if (chp_test_bit(chp_info.configured, bit))
596 else if (chp_test_bit(chp_info.standby, bit))
608 return chp_cfg_task[chpid.
cssid][chpid.
id];
628 t = cfg_get_task(chpid);
641 "%d\n", chpid.
cssid, chpid.
id, rc);
651 "%d\n", chpid.
cssid, chpid.
id, rc);
703 static int cfg_wait_idle(
void)
710 static int __init chp_init(
void)