drivers/s390/cio/device_pgid.c
Source file repositories/reference/linux-study-clean/drivers/s390/cio/device_pgid.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/s390/cio/device_pgid.c- Extension
.c- Size
- 18011 bytes
- Lines
- 728
- Domain
- Driver Families
- Bucket
- drivers/s390
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/string.hlinux/bitops.hlinux/types.hlinux/errno.hlinux/slab.hlinux/io.hasm/ccwdev.hasm/cio.hcio.hcio_debug.hdevice.hio_sch.h
Detected Declarations
struct stlck_datafunction verify_donefunction nop_build_cpfunction nop_dofunction nop_filterfunction nop_callbackfunction spid_build_cpfunction pgid_wipeout_callbackfunction pgid_wipeout_startfunction spid_dofunction spid_callbackfunction spid_startfunction pgid_is_resetfunction pgid_cmpfunction pgid_analyzefunction pgid_to_donepmfunction pgid_fillfunction snid_donefunction snid_build_cpfunction snid_dofunction snid_callbackfunction verify_startfunction ccw_device_verify_startfunction disband_callbackfunction ccw_device_disband_startfunction stlck_build_cpfunction stlck_callbackfunction ccw_device_stlck_startfunction ccw_device_stlck
Annotated Snippet
struct stlck_data {
struct completion done;
int rc;
};
static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
{
struct ccw_request *req = &cdev->private->req;
struct ccw1 *cp = cdev->private->dma_area->iccws;
cp[0].cmd_code = CCW_CMD_STLCK;
cp[0].cda = virt_to_dma32(buf1);
cp[0].count = 32;
cp[0].flags = CCW_FLAG_CC;
cp[1].cmd_code = CCW_CMD_RELEASE;
cp[1].cda = virt_to_dma32(buf2);
cp[1].count = 32;
cp[1].flags = 0;
req->cp = cp;
}
static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
{
struct stlck_data *sdata = data;
sdata->rc = rc;
complete(&sdata->done);
}
/**
* ccw_device_stlck_start - perform unconditional release
* @cdev: ccw device
* @data: data pointer to be passed to ccw_device_stlck_done
* @buf1: data pointer used in channel program
* @buf2: data pointer used in channel program
*
* Execute a channel program on @cdev to release an existing PGID reservation.
*/
static void ccw_device_stlck_start(struct ccw_device *cdev, void *data,
void *buf1, void *buf2)
{
struct subchannel *sch = to_subchannel(cdev->dev.parent);
struct ccw_request *req = &cdev->private->req;
CIO_TRACE_EVENT(4, "stlck");
CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
/* Request setup. */
memset(req, 0, sizeof(*req));
req->timeout = PGID_TIMEOUT;
req->maxretries = PGID_RETRIES;
req->lpm = sch->schib.pmcw.pam & sch->opm;
req->data = data;
req->callback = stlck_callback;
stlck_build_cp(cdev, buf1, buf2);
ccw_request_start(cdev);
}
/*
* Perform unconditional reserve + release.
*/
int ccw_device_stlck(struct ccw_device *cdev)
{
struct subchannel *sch = to_subchannel(cdev->dev.parent);
struct stlck_data data;
u8 *buffer;
int rc;
/* Check if steal lock operation is valid for this device. */
if (cdev->drv) {
if (!cdev->private->options.force)
return -EINVAL;
}
buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
if (!buffer)
return -ENOMEM;
init_completion(&data.done);
data.rc = -EIO;
spin_lock_irq(&sch->lock);
rc = cio_enable_subchannel(sch, (u32)virt_to_phys(sch));
if (rc)
goto out_unlock;
/* Perform operation. */
cdev->private->state = DEV_STATE_STEAL_LOCK;
ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
spin_unlock_irq(&sch->lock);
/* Wait for operation to finish. */
if (wait_for_completion_interruptible(&data.done)) {
/* Got a signal. */
spin_lock_irq(&sch->lock);
ccw_request_cancel(cdev);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/string.h`, `linux/bitops.h`, `linux/types.h`, `linux/errno.h`, `linux/slab.h`, `linux/io.h`, `asm/ccwdev.h`.
- Detected declarations: `struct stlck_data`, `function verify_done`, `function nop_build_cp`, `function nop_do`, `function nop_filter`, `function nop_callback`, `function spid_build_cp`, `function pgid_wipeout_callback`, `function pgid_wipeout_start`, `function spid_do`.
- Atlas domain: Driver Families / drivers/s390.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.