/** * cio_enable_subchannel - enable a subchannel. * @sch: subchannel to be enabled * @intparm: interruption parameter to set */ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) { int ret; CIO_TRACE_EVENT(2, "ensch"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); if (sch_is_pseudo_sch(sch)) return -EINVAL; if (cio_update_schib(sch)) return -ENODEV; sch->config.ena = 1; sch->config.isc = sch->isc; sch->config.intparm = intparm; ret = cio_commit_config(sch); if (ret == -EIO) { /* * Got a program check in msch. Try without * the concurrent sense bit the next time. */ sch->config.csense = 0; ret = cio_commit_config(sch); } CIO_HEX_EVENT(2, &ret, sizeof(ret)); return ret; }
/* * Function: cio_cancel * Issues a "Cancel Subchannel" on the specified subchannel * Note: We don't need any fancy intparms and flags here * since xsch is executed synchronously. * Only for common I/O internal use as for now. */ int cio_cancel (struct subchannel *sch) { int ccode; if (!sch) return -ENODEV; CIO_TRACE_EVENT(2, "cancelIO"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); ccode = xsch (sch->schid); CIO_HEX_EVENT(2, &ccode, sizeof(ccode)); switch (ccode) { case 0: /* success */ /* Update information in scsw. */ if (cio_update_schib(sch)) return -ENODEV; return 0; case 1: /* status pending */ return -EBUSY; case 2: /* not applicable */ return -EINVAL; default: /* not oper */ return -ENODEV; } }
/** * cio_disable_subchannel - disable a subchannel. * @sch: subchannel to disable */ int cio_disable_subchannel(struct subchannel *sch) { int retry; int ret; CIO_TRACE_EVENT(2, "dissch"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); if (sch_is_pseudo_sch(sch)) return 0; if (cio_update_schib(sch)) return -ENODEV; sch->config.ena = 0; for (retry = 0; retry < 3; retry++) { ret = cio_commit_config(sch); if (ret == -EBUSY) { struct irb irb; if (tsch(sch->schid, &irb) != 0) break; } else break; } CIO_HEX_EVENT(2, &ret, sizeof(ret)); return ret; }
int cio_enable_subchannel(struct subchannel *sch, u32 intparm) { int retry; int ret; CIO_TRACE_EVENT(2, "ensch"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); if (sch_is_pseudo_sch(sch)) return -EINVAL; if (cio_update_schib(sch)) return -ENODEV; sch->config.ena = 1; sch->config.isc = sch->isc; sch->config.intparm = intparm; for (retry = 0; retry < 3; retry++) { ret = cio_commit_config(sch); if (ret == -EIO) { sch->config.csense = 0; } else if (ret == -EBUSY) { struct irb irb; if (tsch(sch->schid, &irb) != 0) break; } else break; } CIO_HEX_EVENT(2, &ret, sizeof(ret)); return ret; }
int cio_cancel (struct subchannel *sch) { int ccode; if (!sch) return -ENODEV; CIO_TRACE_EVENT(2, "cancelIO"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); ccode = xsch (sch->schid); CIO_HEX_EVENT(2, &ccode, sizeof(ccode)); switch (ccode) { case 0: if (cio_update_schib(sch)) return -ENODEV; return 0; case 1: return -EBUSY; case 2: return -EINVAL; default: return -ENODEV; } }
/** * cio_disable_subchannel - disable a subchannel. * @sch: subchannel to disable */ int cio_disable_subchannel(struct subchannel *sch) { int ret; CIO_TRACE_EVENT(2, "dissch"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); if (sch_is_pseudo_sch(sch)) return 0; if (cio_update_schib(sch)) return -ENODEV; sch->config.ena = 0; ret = cio_commit_config(sch); CIO_HEX_EVENT(2, &ret, sizeof(ret)); return ret; }
static int cio_start_handle_notoper(struct subchannel *sch, __u8 lpm) { char dbf_text[15]; if (lpm != 0) sch->lpm &= ~lpm; else sch->lpm = 0; CIO_MSG_EVENT(2, "cio_start: 'not oper' status for " "subchannel 0.%x.%04x!\n", sch->schid.ssid, sch->schid.sch_no); if (cio_update_schib(sch)) return -ENODEV; sprintf(dbf_text, "no%s", dev_name(&sch->dev)); CIO_TRACE_EVENT(0, dbf_text); CIO_HEX_EVENT(0, &sch->schib, sizeof (struct schib)); return (sch->lpm ? -EACCES : -ENODEV); }
/** * cio_enable_subchannel - enable a subchannel. * @sch: subchannel to be enabled * @intparm: interruption parameter to set */ int cio_enable_subchannel(struct subchannel *sch, u32 intparm) { char dbf_txt[15]; int retry; int ret; CIO_TRACE_EVENT (2, "ensch"); CIO_TRACE_EVENT(2, dev_name(&sch->dev)); if (sch_is_pseudo_sch(sch)) return -EINVAL; if (cio_update_schib(sch)) return -ENODEV; sch->config.ena = 1; sch->config.isc = sch->isc; sch->config.intparm = intparm; for (retry = 0; retry < 3; retry++) { ret = cio_commit_config(sch); if (ret == -EIO) { /* * Got a program check in msch. Try without * the concurrent sense bit the next time. */ sch->config.csense = 0; } else if (ret == -EBUSY) { struct irb irb; if (tsch(sch->schid, &irb) != 0) break; } else break; } sprintf (dbf_txt, "ret:%d", ret); CIO_TRACE_EVENT (2, dbf_txt); return ret; }