aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_pgid.c
diff options
context:
space:
mode:
authorPeter Oberparleiter <peter.oberparleiter@de.ibm.com>2009-12-07 06:51:32 -0500
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2009-12-07 06:51:32 -0500
commitd7d12ef2befac4fed0dccaddff11338b654804df (patch)
tree1563b299e609024844affbc3ebba99c0718db238 /drivers/s390/cio/device_pgid.c
parent52ef0608e3ee4a511725e443c4b572fece22b353 (diff)
[S390] cio: make steal lock procedure more robust
An Unconditional Reserve + Release operation (steal lock) for a boxed device may fail when encountering special error cases (e.g. unit checks or path errors). Fix this by using the more robust ccw_request infrastructure for performing the steal lock CCW program. Signed-off-by: Peter Oberparleiter <peter.oberparleiter@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device_pgid.c')
-rw-r--r--drivers/s390/cio/device_pgid.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 4d54abd82b8c..5bcefeaff744 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -507,3 +507,55 @@ void ccw_device_disband_start(struct ccw_device *cdev)
507 spid_build_cp(cdev, fn); 507 spid_build_cp(cdev, fn);
508 ccw_request_start(cdev); 508 ccw_request_start(cdev);
509} 509}
510
511static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
512{
513 struct ccw_request *req = &cdev->private->req;
514 struct ccw1 *cp = cdev->private->iccws;
515
516 cp[0].cmd_code = CCW_CMD_STLCK;
517 cp[0].cda = (u32) (addr_t) buf1;
518 cp[0].count = 32;
519 cp[0].flags = CCW_FLAG_CC;
520 cp[1].cmd_code = CCW_CMD_RELEASE;
521 cp[1].cda = (u32) (addr_t) buf2;
522 cp[1].count = 32;
523 cp[1].flags = 0;
524 req->cp = cp;
525}
526
527static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
528{
529 ccw_device_stlck_done(cdev, data, rc);
530}
531
532/**
533 * ccw_device_stlck_start - perform unconditional release
534 * @cdev: ccw device
535 * @data: data pointer to be passed to ccw_device_stlck_done
536 * @buf1: data pointer used in channel program
537 * @buf2: data pointer used in channel program
538 *
539 * Execute a channel program on @cdev to release an existing PGID reservation.
540 * When finished, call ccw_device_stlck_done with a return code specifying the
541 * result.
542 */
543void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
544 void *buf2)
545{
546 struct subchannel *sch = to_subchannel(cdev->dev.parent);
547 struct ccw_request *req = &cdev->private->req;
548
549 CIO_TRACE_EVENT(4, "stlck");
550 CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
551 /* Request setup. */
552 memset(req, 0, sizeof(*req));
553 req->timeout = PGID_TIMEOUT;
554 req->maxretries = PGID_RETRIES;
555 req->lpm = sch->schib.pmcw.pam & sch->opm;
556 req->data = data;
557 req->callback = stlck_callback;
558 stlck_build_cp(cdev, buf1, buf2);
559 ccw_request_start(cdev);
560}
561