Browse Source

s390/cio: collect format 1 channel-path description data

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>
Peter Oberparleiter 12 years ago
parent
commit
cce0eacc22
4 changed files with 31 additions and 9 deletions
  1. 21 1
      drivers/s390/cio/chp.c
  2. 2 0
      drivers/s390/cio/chp.h
  3. 6 5
      drivers/s390/cio/chsc.c
  4. 2 3
      drivers/s390/cio/css.c

+ 21 - 1
drivers/s390/cio/chp.c

@@ -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) {

+ 2 - 0
drivers/s390/cio/chp.h

@@ -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);

+ 6 - 5
drivers/s390/cio/chsc.c

@@ -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;
 }
 

+ 2 - 3
drivers/s390/cio/css.c

@@ -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);
 	}
 }