drivers/s390/cio/device.c
Source file repositories/reference/linux-study-clean/drivers/s390/cio/device.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/s390/cio/device.c- Extension
.c- Size
- 50019 bytes
- Lines
- 1934
- Domain
- Driver Families
- Bucket
- drivers/s390
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/export.hlinux/init.hlinux/spinlock.hlinux/errno.hlinux/err.hlinux/slab.hlinux/list.hlinux/device.hlinux/workqueue.hlinux/delay.hlinux/timer.hlinux/kernel_stat.hlinux/sched/signal.hlinux/dma-mapping.hasm/ccwdev.hasm/cio.hasm/param.hasm/cmb.hasm/isc.hchp.hcio.hcio_debug.hcss.hdevice.hioasm.hio_sch.hblacklist.hchsc.h
Detected Declarations
enum io_sch_actionfunction ccw_bus_matchfunction snprint_aliasfunction ccw_ueventfunction io_subchannel_settlefunction io_subchannel_initfunction devtype_showfunction cutype_showfunction modalias_showfunction online_showfunction ccw_device_is_orphanfunction ccw_device_unregisterfunction ccw_device_set_offlinefunction ccw_device_set_onlinefunction online_store_handle_offlinefunction online_store_recog_and_onlinefunction online_store_handle_onlinefunction online_storefunction available_showfunction initiate_loggingfunction vpm_showfunction match_dev_idfunction ccw_device_do_unbind_bindfunction ccw_device_releasefunction io_subchannel_allocate_devfunction io_subchannel_initialize_devfunction io_subchannel_create_ccwdevfunction sch_create_and_recog_new_devicefunction io_subchannel_registerfunction io_subchannel_recog_donefunction io_subchannel_recogfunction ccw_device_move_to_schfunction ccw_device_move_to_orphfunction io_subchannel_irqfunction io_subchannel_init_configfunction io_subchannel_init_fieldsfunction io_subchannel_probefunction io_subchannel_removefunction io_subchannel_verifyfunction io_subchannel_terminate_pathfunction io_subchannel_chp_eventfunction io_subchannel_quiescefunction io_subchannel_shutdownfunction device_is_disconnectedfunction recovery_checkfunction recovery_work_funcfunction recovery_funcfunction ccw_device_schedule_recovery
Annotated Snippet
static const struct bus_type ccw_bus_type;
/******************* bus type handling ***********************/
/* The Linux driver model distinguishes between a bus type and
* the bus itself. Of course we only have one channel
* subsystem driver and one channel system per machine, but
* we still use the abstraction. T.R. says it's a good idea. */
static int
ccw_bus_match (struct device * dev, const struct device_driver * drv)
{
struct ccw_device *cdev = to_ccwdev(dev);
const struct ccw_driver *cdrv = to_ccwdrv(drv);
const struct ccw_device_id *ids = cdrv->ids, *found;
if (!ids)
return 0;
found = ccw_device_id_match(ids, &cdev->id);
if (!found)
return 0;
cdev->id.driver_info = found->driver_info;
return 1;
}
/* Store modalias string delimited by prefix/suffix string into buffer with
* specified size. Return length of resulting string (excluding trailing '\0')
* even if string doesn't fit buffer (snprintf semantics). */
static int snprint_alias(char *buf, size_t size,
const struct ccw_device_id *id, const char *suffix)
{
int len;
len = snprintf(buf, size, "ccw:t%04Xm%02X", id->cu_type, id->cu_model);
if (len > size)
return len;
buf += len;
size -= len;
if (id->dev_type != 0)
len += snprintf(buf, size, "dt%04Xdm%02X%s", id->dev_type,
id->dev_model, suffix);
else
len += snprintf(buf, size, "dtdm%s", suffix);
return len;
}
/* Set up environment variables for ccw device uevent. Return 0 on success,
* non-zero otherwise. */
static int ccw_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
const struct ccw_device *cdev = to_ccwdev(dev);
const struct ccw_device_id *id = &(cdev->id);
int ret;
char modalias_buf[30];
/* CU_TYPE= */
ret = add_uevent_var(env, "CU_TYPE=%04X", id->cu_type);
if (ret)
return ret;
/* CU_MODEL= */
ret = add_uevent_var(env, "CU_MODEL=%02X", id->cu_model);
if (ret)
return ret;
/* The next two can be zero, that's ok for us */
/* DEV_TYPE= */
ret = add_uevent_var(env, "DEV_TYPE=%04X", id->dev_type);
if (ret)
return ret;
/* DEV_MODEL= */
ret = add_uevent_var(env, "DEV_MODEL=%02X", id->dev_model);
if (ret)
return ret;
/* MODALIAS= */
snprint_alias(modalias_buf, sizeof(modalias_buf), id, "");
ret = add_uevent_var(env, "MODALIAS=%s", modalias_buf);
return ret;
}
static void io_subchannel_irq(struct subchannel *);
static int io_subchannel_probe(struct subchannel *);
static void io_subchannel_remove(struct subchannel *);
static void io_subchannel_shutdown(struct subchannel *);
Annotation
- Immediate include surface: `linux/export.h`, `linux/init.h`, `linux/spinlock.h`, `linux/errno.h`, `linux/err.h`, `linux/slab.h`, `linux/list.h`, `linux/device.h`.
- Detected declarations: `enum io_sch_action`, `function ccw_bus_match`, `function snprint_alias`, `function ccw_uevent`, `function io_subchannel_settle`, `function io_subchannel_init`, `function devtype_show`, `function cutype_show`, `function modalias_show`, `function online_show`.
- Atlas domain: Driver Families / drivers/s390.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.