Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e560814 authored by Cornelia Huck's avatar Cornelia Huck Committed by Martin Schwidefsky
Browse files

[S390] path grouping and path verifications fixes.



1. Multipath devices for which SetPGID is not supported are not handled well.
   Use NOP ccws for path verification (sans path grouping) when SetPGID is not
   supported.
2. Check for PGIDs already set with SensePGID on _all_ paths (not just the
   first one) and try to find a common one. Moan if no common PGID can be
   found (and use NOP verification). If no PGIDs have been set, use the css
   global PGID (as before). (Rationale: SetPGID will get a command reject if
   the PGID it tries to set does not match the already set PGID.)
3. Immediately before reboot, issue RESET CHANNEL PATH (rcp) on all chpids. This
   will remove the old PGIDs. rcp will generate solicited CRWs which can be
   savely ignored by the machine check handler (all other actions create
   unsolicited CRWs).

Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 5c898ba9
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ NORET_TYPE void
machine_kexec(struct kimage *image)
{
	clear_all_subchannels();
	cio_reset_channel_paths();

	/* Disable lowcore protection */
	ctl_clear_bit(0,28);
+34 −0
Original line number Diff line number Diff line
@@ -1464,6 +1464,40 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no)
	return desc;
}

static int reset_channel_path(struct channel_path *chp)
{
	int cc;

	cc = rchp(chp->id);
	switch (cc) {
	case 0:
		return 0;
	case 2:
		return -EBUSY;
	default:
		return -ENODEV;
	}
}

static void reset_channel_paths_css(struct channel_subsystem *css)
{
	int i;

	for (i = 0; i <= __MAX_CHPID; i++) {
		if (css->chps[i])
			reset_channel_path(css->chps[i]);
	}
}

void cio_reset_channel_paths(void)
{
	int i;

	for (i = 0; i <= __MAX_CSSID; i++) {
		if (css[i] && css[i]->valid)
			reset_channel_paths_css(css[i]);
	}
}

static int __init
chsc_alloc_sei_area(void)
+1 −0
Original line number Diff line number Diff line
@@ -876,5 +876,6 @@ void
reipl(unsigned long devno)
{
	clear_all_subchannels();
	cio_reset_channel_paths();
	do_reipl(devno);
}
+9 −3
Original line number Diff line number Diff line
@@ -623,9 +623,13 @@ init_channel_subsystem (void)
		ret = device_register(&css[i]->device);
		if (ret)
			goto out_free;
		if (css_characteristics_avail && css_chsc_characteristics.secm)
			device_create_file(&css[i]->device,
		if (css_characteristics_avail &&
		    css_chsc_characteristics.secm) {
			ret = device_create_file(&css[i]->device,
						 &dev_attr_cm_enable);
			if (ret)
				goto out_device;
		}
	}
	css_init_done = 1;

@@ -633,6 +637,8 @@ init_channel_subsystem (void)

	for_each_subchannel(__init_channel_subsystem, NULL);
	return 0;
out_device:
	device_unregister(&css[i]->device);
out_free:
	kfree(css[i]);
out_unregister:
+1 −1
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ struct ccw_device_private {
	struct qdio_irq *qdio_data;
	struct irb irb;		/* device status */
	struct senseid senseid;	/* SenseID info */
	struct pgid pgid;	/* path group ID */
	struct pgid pgid[8];	/* path group IDs per chpid*/
	struct ccw1 iccws[2];	/* ccws for SNID/SID/SPGID commands */
	struct work_struct kick_work;
	wait_queue_head_t wait_q;
Loading