*/
#include <linux/module.h>
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/string.h>
if (cdev->private->iretry) {
cdev->private->iretry--;
ret = cio_halt(sch);
- if (ret != -EBUSY)
- return (ret == 0) ? -EBUSY : ret;
+ return (ret == 0) ? -EBUSY : ret;
}
/* halt io unsuccessful. */
cdev->private->iretry = 255; /* 255 clear retries. */
notify = 1;
}
/* fill out sense information */
- cdev->id.cu_type = cdev->private->senseid.cu_type;
- cdev->id.cu_model = cdev->private->senseid.cu_model;
- cdev->id.dev_type = cdev->private->senseid.dev_type;
- cdev->id.dev_model = cdev->private->senseid.dev_model;
+ cdev->id = (struct ccw_device_id) {
+ .cu_type = cdev->private->senseid.cu_type,
+ .cu_model = cdev->private->senseid.cu_model,
+ .dev_type = cdev->private->senseid.dev_type,
+ .dev_model = cdev->private->senseid.dev_model,
+ };
if (notify) {
cdev->private->state = DEV_STATE_OFFLINE;
if (same_dev) {
if (!ret)
/* Driver doesn't want device back. */
ccw_device_do_unreg_rereg((void *)cdev);
- else {
- /* Reenable channel measurements, if needed. */
- cmf_reenable(cdev);
+ else
wake_up(&cdev->private->wait_q);
- }
}
/*
put_device (&cdev->dev);
}
-static inline 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->ssid, cdev->private->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], &css[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.
*/
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);
+ case 0:
+ /* Start Path Group verification. */
+ sch->vpm = 0; /* Start with no path groups set. */
+ cdev->private->state = DEV_STATE_VERIFY;
+ ccw_device_verify_start(cdev);
break;
case -ETIME: /* Sense path group id stopped by timeout. */
case -EUSERS: /* device is reserved for someone else. */
ccw_device_done(cdev, DEV_STATE_BOXED);
- return;
+ break;
+ case -EOPNOTSUPP: /* path grouping not supported, just set online. */
+ cdev->private->options.pgroup = 0;
+ ccw_device_done(cdev, DEV_STATE_ONLINE);
+ break;
default:
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
- return;
+ break;
}
- /* Start Path Group verification. */
- sch->vpm = 0; /* Start with no path groups set. */
- cdev->private->state = DEV_STATE_VERIFY;
- ccw_device_verify_start(cdev);
}
/*
/* Deliver fake irb to device driver, if needed. */
if (cdev->private->flags.fake_irb) {
memset(&cdev->private->irb, 0, sizeof(struct irb));
- cdev->private->irb.scsw.cc = 1;
- cdev->private->irb.scsw.fctl = SCSW_FCTL_START_FUNC;
- cdev->private->irb.scsw.actl = SCSW_ACTL_START_PEND;
- cdev->private->irb.scsw.stctl = SCSW_STCTL_STATUS_PEND;
+ cdev->private->irb.scsw = (struct scsw) {
+ .cc = 1,
+ .fctl = SCSW_FCTL_START_FUNC,
+ .actl = SCSW_ACTL_START_PEND,
+ .stctl = SCSW_STCTL_STATUS_PEND,
+ };
cdev->private->flags.fake_irb = 0;
if (cdev->handler)
cdev->handler(cdev, cdev->private->intparm,
}
/* Do we want to do path grouping? */
if (!cdev->private->options.pgroup) {
- /* Start initial path verification. */
- cdev->private->state = DEV_STATE_VERIFY;
- ccw_device_verify_start(cdev);
+ /* No, set state online immediately. */
+ ccw_device_done(cdev, DEV_STATE_ONLINE);
return 0;
}
/* Do a SensePGID first. */
/* Are we doing path grouping? */
if (!cdev->private->options.pgroup) {
/* No, set state offline immediately. */
- sch->vpm = 0;
ccw_device_done(cdev, DEV_STATE_OFFLINE);
return 0;
}
{
struct subchannel *sch;
+ if (!cdev->private->options.pgroup)
+ return;
if (cdev->private->state == DEV_STATE_W4SENSE) {
cdev->private->flags.doverify = 1;
return;
stsch(sch->schid, &sch->schib);
if (sch->schib.scsw.actl != 0 ||
- (sch->schib.scsw.stctl & SCSW_STCTL_STATUS_PEND) ||
(cdev->private->irb.scsw.stctl & SCSW_STCTL_STATUS_PEND)) {
/*
* No final status yet or final status not yet delivered
irb = (struct irb *) __LC_IRB;
/* Accumulate status. We don't do basic sense. */
ccw_device_accumulate_irb(cdev, irb);
- /* Remember to clear irb to avoid residuals. */
- memset(&cdev->private->irb, 0, sizeof(struct irb));
/* Try to start delayed device verification. */
ccw_device_online_verify(cdev, 0);
/* Note: Don't call handler for cio initiated clear! */
ccw_device_wait4io_verify(struct ccw_device *cdev, enum dev_event dev_event)
{
/* When the I/O has terminated, we have to start verification. */
- cdev->private->flags.doverify = 1;
+ if (cdev->private->options.pgroup)
+ cdev->private->flags.doverify = 1;
}
static void
dev_fsm_event(cdev, dev_event);
}
-static void ccw_device_update_cmfblock(struct ccw_device *cdev,
- enum dev_event dev_event)
-{
- cmf_retry_copy_block(cdev);
- cdev->private->state = DEV_STATE_ONLINE;
- dev_fsm_event(cdev, dev_event);
-}
static void
ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
[DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate,
[DEV_EVENT_VERIFY] = ccw_device_change_cmfstate,
},
- [DEV_STATE_CMFUPDATE] = {
- [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock,
- [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock,
- [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock,
- [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock,
- },
};
/*