mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-20 00:11:22 +00:00
[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: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
39f5360b3d
commit
9679baaf85
@ -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)
|
||||
|
@ -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 *);
|
||||
|
@ -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] = {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user