diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/blacklist.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/ccwreq.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/chp.c | 21 | ||||
-rw-r--r-- | drivers/s390/cio/chp.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.c | 43 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 23 |
7 files changed, 54 insertions, 59 deletions
diff --git a/drivers/s390/cio/blacklist.c b/drivers/s390/cio/blacklist.c index 20314aad7ab7..9082476b51db 100644 --- a/drivers/s390/cio/blacklist.c +++ b/drivers/s390/cio/blacklist.c @@ -51,9 +51,8 @@ static int blacklist_range(range_action action, unsigned int from_ssid, { if ((from_ssid > to_ssid) || ((from_ssid == to_ssid) && (from > to))) { if (msgtrigger) - pr_warning("0.%x.%04x to 0.%x.%04x is not a valid " - "range for cio_ignore\n", from_ssid, from, - to_ssid, to); + pr_warn("0.%x.%04x to 0.%x.%04x is not a valid range for cio_ignore\n", + from_ssid, from, to_ssid, to); return 1; } @@ -140,8 +139,8 @@ static int parse_busid(char *str, unsigned int *cssid, unsigned int *ssid, rc = 0; out: if (rc && msgtrigger) - pr_warning("%s is not a valid device for the cio_ignore " - "kernel parameter\n", str); + pr_warn("%s is not a valid device for the cio_ignore kernel parameter\n", + str); return rc; } diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 79f59915f71b..2782100b2c07 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c @@ -333,13 +333,12 @@ void ccw_request_timeout(struct ccw_device *cdev) for (chp = 0; chp < 8; chp++) { if ((0x80 >> chp) & sch->schib.pmcw.lpum) - pr_warning("%s: No interrupt was received within %lus " - "(CS=%02x, DS=%02x, CHPID=%x.%02x)\n", - dev_name(&cdev->dev), req->timeout / HZ, - scsw_cstat(&sch->schib.scsw), - scsw_dstat(&sch->schib.scsw), - sch->schid.cssid, - sch->schib.pmcw.chpid[chp]); + pr_warn("%s: No interrupt was received within %lus (CS=%02x, DS=%02x, CHPID=%x.%02x)\n", + dev_name(&cdev->dev), req->timeout / HZ, + scsw_cstat(&sch->schib.scsw), + scsw_dstat(&sch->schib.scsw), + sch->schid.cssid, + sch->schib.pmcw.chpid[chp]); } if (!ccwreq_next_path(cdev)) { diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index c692dfebd0ba..50597f9522fe 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -139,11 +139,11 @@ static ssize_t chp_measurement_chars_read(struct file *filp, device = container_of(kobj, struct device, kobj); chp = to_channelpath(device); - if (!chp->cmg_chars) + if (chp->cmg == -1) return 0; - return memory_read_from_buffer(buf, count, &off, - chp->cmg_chars, sizeof(struct cmg_chars)); + return memory_read_from_buffer(buf, count, &off, &chp->cmg_chars, + sizeof(chp->cmg_chars)); } static struct bin_attribute chp_measurement_chars_attr = { @@ -416,7 +416,8 @@ static void chp_release(struct device *dev) * chp_update_desc - update channel-path description * @chp - channel-path * - * Update the channel-path description of the specified channel-path. + * Update the channel-path description of the specified channel-path + * including channel measurement related information. * Return zero on success, non-zero otherwise. */ int chp_update_desc(struct channel_path *chp) @@ -428,8 +429,10 @@ int chp_update_desc(struct channel_path *chp) return rc; rc = chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1); + if (rc) + return rc; - return rc; + return chsc_get_channel_measurement_chars(chp); } /** @@ -466,14 +469,6 @@ int chp_new(struct chp_id chpid) ret = -ENODEV; goto out_free; } - /* Get channel-measurement characteristics. */ - if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) { - ret = chsc_get_channel_measurement_chars(chp); - if (ret) - goto out_free; - } else { - chp->cmg = -1; - } dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id); /* make it known to the system */ diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h index 4efd5b867cc3..af0232290dc4 100644 --- a/drivers/s390/cio/chp.h +++ b/drivers/s390/cio/chp.h @@ -48,7 +48,7 @@ struct channel_path { /* Channel-measurement related stuff: */ int cmg; int shared; - void *cmg_chars; + struct cmg_chars cmg_chars; }; /* Return channel_path struct for given chpid. */ diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index a831d18596a5..c424c0c7367e 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/mutex.h> #include <linux/pci.h> #include <asm/cio.h> @@ -224,8 +225,9 @@ out_unreg: void chsc_chp_offline(struct chp_id chpid) { - char dbf_txt[15]; + struct channel_path *chp = chpid_to_chp(chpid); struct chp_link link; + char dbf_txt[15]; sprintf(dbf_txt, "chpr%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); @@ -236,6 +238,11 @@ void chsc_chp_offline(struct chp_id chpid) link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); + + mutex_lock(&chp->lock); + chp_update_desc(chp); + mutex_unlock(&chp->lock); + for_each_subchannel_staged(s390_subchannel_remove_chpid, NULL, &link); } @@ -690,8 +697,9 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) void chsc_chp_online(struct chp_id chpid) { - char dbf_txt[15]; + struct channel_path *chp = chpid_to_chp(chpid); struct chp_link link; + char dbf_txt[15]; sprintf(dbf_txt, "cadd%x.%02x", chpid.cssid, chpid.id); CIO_TRACE_EVENT(2, dbf_txt); @@ -701,6 +709,11 @@ void chsc_chp_online(struct chp_id chpid) link.chpid = chpid; /* Wait until previous actions have settled. */ css_wait_for_slow_path(); + + mutex_lock(&chp->lock); + chp_update_desc(chp); + mutex_unlock(&chp->lock); + for_each_subchannel_staged(__s390_process_res_acc, NULL, &link); css_schedule_reprobe(); @@ -967,22 +980,19 @@ static void chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv, struct cmg_chars *chars) { - struct cmg_chars *cmg_chars; int i, mask; - cmg_chars = chp->cmg_chars; for (i = 0; i < NR_MEASUREMENT_CHARS; i++) { mask = 0x80 >> (i + 3); if (cmcv & mask) - cmg_chars->values[i] = chars->values[i]; + chp->cmg_chars.values[i] = chars->values[i]; else - cmg_chars->values[i] = 0; + chp->cmg_chars.values[i] = 0; } } int chsc_get_channel_measurement_chars(struct channel_path *chp) { - struct cmg_chars *cmg_chars; int ccode, ret; struct { @@ -1006,10 +1016,11 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) u32 data[NR_MEASUREMENT_CHARS]; } __attribute__ ((packed)) *scmc_area; - chp->cmg_chars = NULL; - cmg_chars = kmalloc(sizeof(*cmg_chars), GFP_KERNEL); - if (!cmg_chars) - return -ENOMEM; + chp->shared = -1; + chp->cmg = -1; + + if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm) + return 0; spin_lock_irq(&chsc_page_lock); memset(chsc_page, 0, PAGE_SIZE); @@ -1031,25 +1042,19 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp) scmc_area->response.code); goto out; } - if (scmc_area->not_valid) { - chp->cmg = -1; - chp->shared = -1; + if (scmc_area->not_valid) goto out; - } + chp->cmg = scmc_area->cmg; chp->shared = scmc_area->shared; if (chp->cmg != 2 && chp->cmg != 3) { /* No cmg-dependent data. */ goto out; } - chp->cmg_chars = cmg_chars; chsc_initialize_cmg_chars(chp, scmc_area->cmcv, (struct cmg_chars *) &scmc_area->data); out: spin_unlock_irq(&chsc_page_lock); - if (!chp->cmg_chars) - kfree(cmg_chars); - return ret; } diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 39a8ae54e9c1..de6fccc13124 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -656,7 +656,7 @@ struct subchannel *cio_probe_console(void) sch_no = cio_get_console_sch_no(); if (sch_no == -1) { - pr_warning("No CCW console was found\n"); + pr_warn("No CCW console was found\n"); return ERR_PTR(-ENODEV); } init_subchannel_id(&schid); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 6aae68412802..7ada078ffdd0 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -364,11 +364,11 @@ int ccw_device_set_offline(struct ccw_device *cdev) cdev->private->state == DEV_STATE_DISCONNECTED)); /* Inform the user if set offline failed. */ if (cdev->private->state == DEV_STATE_BOXED) { - pr_warning("%s: The device entered boxed state while " - "being set offline\n", dev_name(&cdev->dev)); + pr_warn("%s: The device entered boxed state while being set offline\n", + dev_name(&cdev->dev)); } else if (cdev->private->state == DEV_STATE_NOT_OPER) { - pr_warning("%s: The device stopped operating while " - "being set offline\n", dev_name(&cdev->dev)); + pr_warn("%s: The device stopped operating while being set offline\n", + dev_name(&cdev->dev)); } /* Give up reference from ccw_device_set_online(). */ put_device(&cdev->dev); @@ -429,13 +429,11 @@ int ccw_device_set_online(struct ccw_device *cdev) spin_unlock_irq(cdev->ccwlock); /* Inform the user that set online failed. */ if (cdev->private->state == DEV_STATE_BOXED) { - pr_warning("%s: Setting the device online failed " - "because it is boxed\n", - dev_name(&cdev->dev)); + pr_warn("%s: Setting the device online failed because it is boxed\n", + dev_name(&cdev->dev)); } else if (cdev->private->state == DEV_STATE_NOT_OPER) { - pr_warning("%s: Setting the device online failed " - "because it is not operational\n", - dev_name(&cdev->dev)); + pr_warn("%s: Setting the device online failed because it is not operational\n", + dev_name(&cdev->dev)); } /* Give up online reference since onlining failed. */ put_device(&cdev->dev); @@ -619,9 +617,8 @@ initiate_logging(struct device *dev, struct device_attribute *attr, rc = chsc_siosl(sch->schid); if (rc < 0) { - pr_warning("Logging for subchannel 0.%x.%04x failed with " - "errno=%d\n", - sch->schid.ssid, sch->schid.sch_no, rc); + pr_warn("Logging for subchannel 0.%x.%04x failed with errno=%d\n", + sch->schid.ssid, sch->schid.sch_no, rc); return rc; } pr_notice("Logging for subchannel 0.%x.%04x was triggered\n", |