drivers/s390/block/dasd_alias.c
Source file repositories/reference/linux-study-clean/drivers/s390/block/dasd_alias.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/s390/block/dasd_alias.c- Extension
.c- Size
- 28249 bytes
- Lines
- 973
- 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/list.hlinux/slab.hasm/ebcdic.hdasd_int.hdasd_eckd.h
Detected Declarations
function _free_serverfunction _free_lcufunction wrongfunction dasd_alias_disconnect_device_from_lcufunction list_emptyfunction _add_device_to_lcufunction _remove_device_from_lcufunction suborder_not_supportedfunction read_unit_address_configurationfunction _lcu_updatefunction list_for_each_entry_safefunction list_for_each_entry_safefunction list_for_each_entry_safefunction lcu_update_workfunction _schedule_lcu_updatefunction dasd_alias_add_devicefunction dasd_alias_update_add_devicefunction dasd_alias_remove_devicefunction reset_summary_unit_checkfunction _restart_all_base_devices_on_lcufunction list_for_each_entryfunction flush_all_alias_devices_on_lcufunction list_for_each_entryfunction _stop_all_devices_on_lcufunction list_for_each_entryfunction list_for_each_entryfunction list_for_each_entryfunction _unstop_all_devices_on_lcufunction list_for_each_entryfunction list_for_each_entryfunction list_for_each_entryfunction summary_unit_check_handling_workfunction dasd_alias_handle_summary_unit_check
Annotated Snippet
if (!server) {
list_add(&newserver->server, &aliastree.serverlist);
server = newserver;
} else {
/* someone was faster */
_free_server(newserver);
}
}
lcu = _find_lcu(server, &uid);
if (!lcu) {
spin_unlock_irqrestore(&aliastree.lock, flags);
newlcu = _allocate_lcu(&uid);
if (IS_ERR(newlcu))
return PTR_ERR(newlcu);
spin_lock_irqsave(&aliastree.lock, flags);
lcu = _find_lcu(server, &uid);
if (!lcu) {
list_add(&newlcu->lcu, &server->lculist);
lcu = newlcu;
} else {
/* someone was faster */
_free_lcu(newlcu);
}
}
spin_lock(&lcu->lock);
list_add(&device->alias_list, &lcu->inactive_devices);
private->lcu = lcu;
spin_unlock(&lcu->lock);
spin_unlock_irqrestore(&aliastree.lock, flags);
return 0;
}
/*
* This function removes a device from the scope of alias management.
* The complicated part is to make sure that it is not in use by
* any of the workers. If necessary cancel the work.
*/
void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
{
struct dasd_eckd_private *private = device->private;
unsigned long flags;
struct alias_lcu *lcu;
struct alias_server *server;
int was_pending;
struct dasd_uid uid;
lcu = private->lcu;
/* nothing to do if already disconnected */
if (!lcu)
return;
device->discipline->get_uid(device, &uid);
spin_lock_irqsave(&lcu->lock, flags);
/* make sure that the workers don't use this device */
if (device == lcu->suc_data.device) {
spin_unlock_irqrestore(&lcu->lock, flags);
cancel_work_sync(&lcu->suc_data.worker);
spin_lock_irqsave(&lcu->lock, flags);
if (device == lcu->suc_data.device) {
dasd_put_device(device);
lcu->suc_data.device = NULL;
}
}
was_pending = 0;
if (device == lcu->ruac_data.device) {
spin_unlock_irqrestore(&lcu->lock, flags);
was_pending = 1;
cancel_delayed_work_sync(&lcu->ruac_data.dwork);
spin_lock_irqsave(&lcu->lock, flags);
if (device == lcu->ruac_data.device) {
dasd_put_device(device);
lcu->ruac_data.device = NULL;
}
}
private->lcu = NULL;
spin_unlock_irqrestore(&lcu->lock, flags);
spin_lock_irqsave(&aliastree.lock, flags);
spin_lock(&lcu->lock);
list_del_init(&device->alias_list);
if (list_empty(&lcu->grouplist) &&
list_empty(&lcu->active_devices) &&
list_empty(&lcu->inactive_devices)) {
list_del(&lcu->lcu);
spin_unlock(&lcu->lock);
_free_lcu(lcu);
lcu = NULL;
} else {
if (was_pending)
Annotation
- Immediate include surface: `linux/list.h`, `linux/slab.h`, `asm/ebcdic.h`, `dasd_int.h`, `dasd_eckd.h`.
- Detected declarations: `function _free_server`, `function _free_lcu`, `function wrong`, `function dasd_alias_disconnect_device_from_lcu`, `function list_empty`, `function _add_device_to_lcu`, `function _remove_device_from_lcu`, `function suborder_not_supported`, `function read_unit_address_configuration`, `function _lcu_update`.
- 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.