/** * ccw_request_cancel - cancel running I/O request * @cdev: ccw device * * Cancel the I/O request specified by cdev->req. Return non-zero if request * has already finished, zero otherwise. */ int ccw_request_cancel(struct ccw_device *cdev) { struct subchannel *sch = to_subchannel(cdev->dev.parent); struct ccw_request *req = &cdev->private->req; int rc; if (req->done) return 1; req->cancel = 1; rc = cio_clear(sch); if (rc) ccwreq_stop(cdev, rc); return 0; }
/* * (Re-)Start the operation until retries and paths are exhausted. */ static void ccwreq_do(struct ccw_device *cdev) { struct ccw_request *req = &cdev->private->req; struct subchannel *sch = to_subchannel(cdev->dev.parent); struct ccw1 *cp = req->cp; int rc = -EACCES; while (req->mask) { if (req->retries-- == 0) { /* Retries exhausted, try next path. */ ccwreq_next_path(cdev); continue; } /* Perform start function. */ memset(&cdev->private->irb, 0, sizeof(struct irb)); rc = cio_start(sch, cp, (u8) req->mask); if (rc == 0) { /* I/O started successfully. */ ccw_device_set_timeout(cdev, req->timeout); return; } if (rc == -ENODEV) { /* Permanent device error. */ break; } if (rc == -EACCES) { /* Permant path error. */ ccwreq_next_path(cdev); continue; } /* Temporary improper status. */ rc = cio_clear(sch); if (rc) break; return; } ccwreq_stop(cdev, rc); }
static void ccwreq_do(struct ccw_device *cdev) { struct ccw_request *req = &cdev->private->req; struct subchannel *sch = to_subchannel(cdev->dev.parent); struct ccw1 *cp = req->cp; int rc = -EACCES; while (req->mask) { if (req->retries-- == 0) { ccwreq_next_path(cdev); continue; } memset(&cdev->private->irb, 0, sizeof(struct irb)); rc = cio_start(sch, cp, (u8) req->mask); if (rc == 0) { ccw_device_set_timeout(cdev, req->timeout); return; } if (rc == -ENODEV) { break; } if (rc == -EACCES) { ccwreq_next_path(cdev); continue; } rc = cio_clear(sch); if (rc) break; return; } ccwreq_stop(cdev, rc); }
/** * ccw_request_start - perform I/O request * @cdev: ccw device * * Perform the I/O request specified by cdev->req. */ void ccw_request_start(struct ccw_device *cdev) { struct ccw_request *req = &cdev->private->req; if (req->singlepath) { /* Try all paths twice to counter link flapping. */ req->mask = 0x8080; } else req->mask = req->lpm; req->retries = req->maxretries; req->mask = lpm_adjust(req->mask, req->lpm); req->drc = 0; req->done = 0; req->cancel = 0; if (!req->mask) goto out_nopath; ccwreq_do(cdev); return; out_nopath: ccwreq_stop(cdev, -EACCES); }