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

Commit 9679baaf authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Martin Schwidefsky
Browse files

[S390] cio: use ccw request infrastructure for pgid



Use the newly introduced ccw request infrastructure to implement
pgid related operations: sense pgid, set pgid and disband pg.

Signed-off-by: default avatarPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 39f5360b
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -957,9 +957,6 @@ void io_subchannel_init_config(struct subchannel *sch)
{
	memset(&sch->config, 0, sizeof(sch->config));
	sch->config.csense = 1;
	/* Use subchannel mp mode when there is more than 1 installed CHPID. */
	if ((sch->schib.pmcw.pim & (sch->schib.pmcw.pim - 1)) != 0)
		sch->config.mp = 1;
}

static void io_subchannel_init_fields(struct subchannel *sch)
+0 −3
Original line number Diff line number Diff line
@@ -112,15 +112,12 @@ void ccw_device_sense_id_done(struct ccw_device *, int);

/* Function prototypes for path grouping stuff. */
void ccw_device_sense_pgid_start(struct ccw_device *);
void ccw_device_sense_pgid_irq(struct ccw_device *, enum dev_event);
void ccw_device_sense_pgid_done(struct ccw_device *, int);

void ccw_device_verify_start(struct ccw_device *);
void ccw_device_verify_irq(struct ccw_device *, enum dev_event);
void ccw_device_verify_done(struct ccw_device *, int);

void ccw_device_disband_start(struct ccw_device *);
void ccw_device_disband_irq(struct ccw_device *, enum dev_event);
void ccw_device_disband_done(struct ccw_device *, int);

int ccw_device_call_handler(struct ccw_device *);
+9 −91
Original line number Diff line number Diff line
@@ -394,58 +394,6 @@ ccw_device_done(struct ccw_device *cdev, int state)
	wake_up(&cdev->private->wait_q);
}

static int cmp_pgid(struct pgid *p1, struct pgid *p2)
{
	char *c1;
	char *c2;

	c1 = (char *)p1;
	c2 = (char *)p2;

	return memcmp(c1 + 1, c2 + 1, sizeof(struct pgid) - 1);
}

static void __ccw_device_get_common_pgid(struct ccw_device *cdev)
{
	int i;
	int last;

	last = 0;
	for (i = 0; i < 8; i++) {
		if (cdev->private->pgid[i].inf.ps.state1 == SNID_STATE1_RESET)
			/* No PGID yet */
			continue;
		if (cdev->private->pgid[last].inf.ps.state1 ==
		    SNID_STATE1_RESET) {
			/* First non-zero PGID */
			last = i;
			continue;
		}
		if (cmp_pgid(&cdev->private->pgid[i],
			     &cdev->private->pgid[last]) == 0)
			/* Non-conflicting PGIDs */
			continue;

		/* PGID mismatch, can't pathgroup. */
		CIO_MSG_EVENT(0, "SNID - pgid mismatch for device "
			      "0.%x.%04x, can't pathgroup\n",
			      cdev->private->dev_id.ssid,
			      cdev->private->dev_id.devno);
		cdev->private->options.pgroup = 0;
		return;
	}
	if (cdev->private->pgid[last].inf.ps.state1 ==
	    SNID_STATE1_RESET)
		/* No previous pgid found */
		memcpy(&cdev->private->pgid[0],
		       &channel_subsystems[0]->global_pgid,
		       sizeof(struct pgid));
	else
		/* Use existing pgid */
		memcpy(&cdev->private->pgid[0], &cdev->private->pgid[last],
		       sizeof(struct pgid));
}

/*
 * Function called from device_pgid.c after sense path ground has completed.
 */
@@ -457,12 +405,8 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
	sch = to_subchannel(cdev->dev.parent);
	switch (err) {
	case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */
		cdev->private->options.pgroup = 0;
		break;
	case 0: /* success */
	case -EACCES: /* partial success, some paths not operational */
		/* Check if all pgids are equal or 0. */
		__ccw_device_get_common_pgid(cdev);
		break;
	case -ETIME:		/* Sense path group id stopped by timeout. */
	case -EUSERS:		/* device is reserved for someone else. */
@@ -474,7 +418,6 @@ ccw_device_sense_pgid_done(struct ccw_device *cdev, int err)
	}
	/* Start Path Group verification. */
	cdev->private->state = DEV_STATE_VERIFY;
	cdev->private->flags.doverify = 0;
	ccw_device_verify_start(cdev);
}

@@ -537,7 +480,6 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
	sch->lpm = sch->vpm;
	/* Repeat path verification? */
	if (cdev->private->flags.doverify) {
		cdev->private->flags.doverify = 0;
		ccw_device_verify_start(cdev);
		return;
	}
@@ -602,7 +544,6 @@ ccw_device_online(struct ccw_device *cdev)
	if (!cdev->private->options.pgroup) {
		/* Start initial path verification. */
		cdev->private->state = DEV_STATE_VERIFY;
		cdev->private->flags.doverify = 0;
		ccw_device_verify_start(cdev);
		return 0;
	}
@@ -624,7 +565,6 @@ ccw_device_disband_done(struct ccw_device *cdev, int err)
		break;
	default:
		cdev->private->flags.donotify = 0;
		dev_fsm_event(cdev, DEV_EVENT_NOTOPER);
		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
		break;
	}
@@ -672,27 +612,6 @@ ccw_device_offline(struct ccw_device *cdev)
	return 0;
}

/*
 * Handle timeout in device online/offline process.
 */
static void
ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event)
{
	int ret;

	ret = ccw_device_cancel_halt_clear(cdev);
	switch (ret) {
	case 0:
		ccw_device_done(cdev, DEV_STATE_BOXED);
		break;
	case -ENODEV:
		ccw_device_done(cdev, DEV_STATE_NOT_OPER);
		break;
	default:
		ccw_device_set_timeout(cdev, 3*HZ);
	}
}

/*
 * Handle not operational event in non-special state.
 */
@@ -751,7 +670,6 @@ ccw_device_online_verify(struct ccw_device *cdev, enum dev_event dev_event)
	}
	/* Device is idle, we can do the path verification. */
	cdev->private->state = DEV_STATE_VERIFY;
	cdev->private->flags.doverify = 0;
	ccw_device_verify_start(cdev);
}

@@ -1103,9 +1021,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
		[DEV_EVENT_VERIFY]	= ccw_device_nop,
	},
	[DEV_STATE_SENSE_PGID] = {
		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
		[DEV_EVENT_INTERRUPT]	= ccw_device_sense_pgid_irq,
		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
		[DEV_EVENT_VERIFY]	= ccw_device_nop,
	},
	[DEV_STATE_SENSE_ID] = {
@@ -1121,9 +1039,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
		[DEV_EVENT_VERIFY]	= ccw_device_offline_verify,
	},
	[DEV_STATE_VERIFY] = {
		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
		[DEV_EVENT_INTERRUPT]	= ccw_device_verify_irq,
		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
		[DEV_EVENT_VERIFY]	= ccw_device_delay_verify,
	},
	[DEV_STATE_ONLINE] = {
@@ -1139,9 +1057,9 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
		[DEV_EVENT_VERIFY]	= ccw_device_online_verify,
	},
	[DEV_STATE_DISBAND_PGID] = {
		[DEV_EVENT_NOTOPER]	= ccw_device_generic_notoper,
		[DEV_EVENT_INTERRUPT]	= ccw_device_disband_irq,
		[DEV_EVENT_TIMEOUT]	= ccw_device_onoff_timeout,
		[DEV_EVENT_NOTOPER]	= ccw_device_request_event,
		[DEV_EVENT_INTERRUPT]	= ccw_device_request_event,
		[DEV_EVENT_TIMEOUT]	= ccw_device_request_event,
		[DEV_EVENT_VERIFY]	= ccw_device_nop,
	},
	[DEV_STATE_BOXED] = {
+371 −505

File changed.

Preview size limit exceeded, changes collapsed.

+3 −2
Original line number Diff line number Diff line
@@ -149,8 +149,8 @@ struct ccw_device_private {
	struct ccw_dev_id dev_id;	/* device id */
	struct subchannel_id schid;	/* subchannel number */
	struct ccw_request req;		/* internal I/O request */
	u8 imask;		/* lpm mask for SNID/SID/SPGID */
	int iretry;		/* retry counter SNID/SID/SPGID */
	int iretry;
	u8 pgid_valid_mask;		/* mask of valid PGIDs */
	struct {
		unsigned int fast:1;	/* post with "channel end" */
		unsigned int repall:1;	/* report every interrupt status */
@@ -167,6 +167,7 @@ struct ccw_device_private {
		unsigned int fake_irb:1;    /* deliver faked irb */
		unsigned int intretry:1;    /* retry internal operation */
		unsigned int resuming:1;    /* recognition while resume */
		unsigned int pgid_rdy:1;    /* pgids are ready */
	} __attribute__((packed)) flags;
	unsigned long intparm;	/* user interruption parameter */
	struct qdio_irq *qdio_data;