s390/cio: collect format 1 channel-path description data
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Mon, 11 Mar 2013 11:58:18 +0000 (12:58 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 17 Apr 2013 12:07:26 +0000 (14:07 +0200)
Collect format 1 channel-path description data for each CHPID
and update the information in one place.

Reviewed-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/cio/chp.c
drivers/s390/cio/chp.h
drivers/s390/cio/chsc.c
drivers/s390/cio/css.c

index 50ad5fdd815dca03e53f62c1c0798738d375f9e0..21fabc6d5a9c83bac80fda8d78495c26f9febe64 100644 (file)
@@ -376,6 +376,26 @@ static void chp_release(struct device *dev)
        kfree(cp);
 }
 
+/**
+ * chp_update_desc - update channel-path description
+ * @chp - channel-path
+ *
+ * Update the channel-path description of the specified channel-path.
+ * Return zero on success, non-zero otherwise.
+ */
+int chp_update_desc(struct channel_path *chp)
+{
+       int rc;
+
+       rc = chsc_determine_base_channel_path_desc(chp->chpid, &chp->desc);
+       if (rc)
+               return rc;
+
+       rc = chsc_determine_fmt1_channel_path_desc(chp->chpid, &chp->desc_fmt1);
+
+       return rc;
+}
+
 /**
  * chp_new - register a new channel-path
  * @chpid - channel-path ID
@@ -403,7 +423,7 @@ int chp_new(struct chp_id chpid)
        mutex_init(&chp->lock);
 
        /* Obtain channel path description and fill it in. */
-       ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
+       ret = chp_update_desc(chp);
        if (ret)
                goto out_free;
        if ((chp->desc.flags & 0x80) == 0) {
index e1399dbee83430510ff6266e0bb02957916848cf..9284b785a06ff05bcb172f3916d09b999c43270f 100644 (file)
@@ -44,6 +44,7 @@ struct channel_path {
        struct mutex lock; /* Serialize access to below members. */
        int state;
        struct channel_path_desc desc;
+       struct channel_path_desc_fmt1 desc_fmt1;
        /* Channel-measurement related stuff: */
        int cmg;
        int shared;
@@ -62,6 +63,7 @@ int chp_is_registered(struct chp_id chpid);
 void *chp_get_chp_desc(struct chp_id chpid);
 void chp_remove_cmg_attr(struct channel_path *chp);
 int chp_add_cmg_attr(struct channel_path *chp);
+int chp_update_desc(struct channel_path *chp);
 int chp_new(struct chp_id chpid);
 void chp_cfg_schedule(struct chp_id chpid, int configure);
 void chp_cfg_cancel_deconfigure(struct chp_id chpid);
index e16c553f65561f453c4eed2a97eb4cda8a539231..8ea7d9b2c671a3555c7c5d2c57b505d9f338033c 100644 (file)
@@ -376,7 +376,7 @@ static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area)
                        continue;
                }
                mutex_lock(&chp->lock);
-               chsc_determine_base_channel_path_desc(chpid, &chp->desc);
+               chp_update_desc(chp);
                mutex_unlock(&chp->lock);
        }
 }
@@ -631,8 +631,8 @@ int chsc_chp_vary(struct chp_id chpid, int on)
         * Redo PathVerification on the devices the chpid connects to
         */
        if (on) {
-               /* Try to update the channel path descritor. */
-               chsc_determine_base_channel_path_desc(chpid, &chp->desc);
+               /* Try to update the channel path description. */
+               chp_update_desc(chp);
                for_each_subchannel_staged(s390_subchannel_vary_chpid_on,
                                           __s390_vary_chpid_on, &chpid);
        } else
@@ -825,9 +825,10 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
 {
        struct chsc_response_struct *chsc_resp;
        struct chsc_scpd *scpd_area;
+       unsigned long flags;
        int ret;
 
-       spin_lock_irq(&chsc_page_lock);
+       spin_lock_irqsave(&chsc_page_lock, flags);
        scpd_area = chsc_page;
        ret = chsc_determine_channel_path_desc(chpid, 0, 0, 1, 0, scpd_area);
        if (ret)
@@ -835,7 +836,7 @@ int chsc_determine_fmt1_channel_path_desc(struct chp_id chpid,
        chsc_resp = (void *)&scpd_area->response;
        memcpy(desc, &chsc_resp->data, sizeof(*desc));
 out:
-       spin_unlock_irq(&chsc_page_lock);
+       spin_unlock_irqrestore(&chsc_page_lock, flags);
        return ret;
 }
 
index a239237d43f3e7bc4d5262bb3ca34ccd067f65dd..658d9349c837f766aef93bde8874786c78d9f973 100644 (file)
@@ -1065,9 +1065,8 @@ void channel_subsystem_reinit(void)
        chsc_enable_facility(CHSC_SDA_OC_MSS);
        chp_id_for_each(&chpid) {
                chp = chpid_to_chp(chpid);
-               if (!chp)
-                       continue;
-               chsc_determine_base_channel_path_desc(chpid, &chp->desc);
+               if (chp)
+                       chp_update_desc(chp);
        }
 }