drivers/s390/scsi/zfcp_qdio.c
Source file repositories/reference/linux-study-clean/drivers/s390/scsi/zfcp_qdio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/s390/scsi/zfcp_qdio.c- Extension
.c- Size
- 16635 bytes
- Lines
- 598
- 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/lockdep.hlinux/slab.hlinux/module.hzfcp_ext.hzfcp_qdio.h
Detected Declarations
function zfcp_qdio_handler_errorfunction zfcp_qdio_zero_sbalsfunction zfcp_qdio_accountfunction zfcp_qdio_int_reqfunction zfcp_qdio_request_taskletfunction zfcp_qdio_request_timerfunction zfcp_qdio_int_respfunction zfcp_qdio_irq_taskletfunction zfcp_qdio_pollfunction zfcp_qdio_sbal_chainfunction zfcp_qdio_sbale_nextfunction zfcp_qdio_sbals_from_sgfunction zfcp_qdio_sbal_checkfunction zfcp_qdio_sbal_getfunction zfcp_qdio_sendfunction zfcp_qdio_allocatefunction zfcp_qdio_closefunction zfcp_qdio_shost_updatefunction zfcp_qdio_openfunction zfcp_qdio_destroyfunction zfcp_qdio_setupfunction zfcp_qdio_siosl
Annotated Snippet
if (error) {
zfcp_qdio_handler_error(qdio, "qdreqt1", error);
} else {
/* cleanup all SBALs being program-owned now */
zfcp_qdio_zero_sbals(qdio->req_q, start, completed);
spin_lock_irq(&qdio->stat_lock);
zfcp_qdio_account(qdio);
spin_unlock_irq(&qdio->stat_lock);
atomic_add(completed, &qdio->req_q_free);
wake_up(&qdio->req_q_wq);
}
}
if (atomic_read(&qdio->req_q_free) < QDIO_MAX_BUFFERS_PER_Q)
timer_reduce(&qdio->request_timer,
jiffies + msecs_to_jiffies(ZFCP_QDIO_REQUEST_RESCAN_MSECS));
}
static void zfcp_qdio_request_timer(struct timer_list *timer)
{
struct zfcp_qdio *qdio = timer_container_of(qdio, timer,
request_timer);
tasklet_schedule(&qdio->request_tasklet);
}
static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
int queue_no, int idx, int count,
unsigned long parm)
{
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
struct zfcp_adapter *adapter = qdio->adapter;
int sbal_no, sbal_idx;
if (unlikely(qdio_err)) {
if (zfcp_adapter_multi_buffer_active(adapter)) {
void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
struct qdio_buffer_element *sbale;
u64 req_id;
u8 scount;
memset(pl, 0,
ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
sbale = qdio->res_q[idx]->element;
req_id = dma64_to_u64(sbale->addr);
scount = min(sbale->scount + 1,
ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
/* incl. signaling SBAL */
for (sbal_no = 0; sbal_no < scount; sbal_no++) {
sbal_idx = (idx + sbal_no) %
QDIO_MAX_BUFFERS_PER_Q;
pl[sbal_no] = qdio->res_q[sbal_idx];
}
zfcp_dbf_hba_def_err(adapter, req_id, scount, pl);
}
zfcp_qdio_handler_error(qdio, "qdires1", qdio_err);
return;
}
/*
* go through all SBALs from input queue currently
* returned by QDIO layer
*/
for (sbal_no = 0; sbal_no < count; sbal_no++) {
sbal_idx = (idx + sbal_no) % QDIO_MAX_BUFFERS_PER_Q;
/* go through all SBALEs of SBAL */
zfcp_fsf_reqid_check(qdio, sbal_idx);
}
/*
* put SBALs back to response queue
*/
if (qdio_add_bufs_to_input_queue(cdev, 0, idx, count))
zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
}
static void zfcp_qdio_irq_tasklet(struct tasklet_struct *tasklet)
{
struct zfcp_qdio *qdio = from_tasklet(qdio, tasklet, irq_tasklet);
struct ccw_device *cdev = qdio->adapter->ccw_device;
unsigned int start, error;
int completed;
if (atomic_read(&qdio->req_q_free) < QDIO_MAX_BUFFERS_PER_Q)
tasklet_schedule(&qdio->request_tasklet);
/* Check the Response Queue: */
completed = qdio_inspect_input_queue(cdev, 0, &start, &error);
Annotation
- Immediate include surface: `linux/lockdep.h`, `linux/slab.h`, `linux/module.h`, `zfcp_ext.h`, `zfcp_qdio.h`.
- Detected declarations: `function zfcp_qdio_handler_error`, `function zfcp_qdio_zero_sbals`, `function zfcp_qdio_account`, `function zfcp_qdio_int_req`, `function zfcp_qdio_request_tasklet`, `function zfcp_qdio_request_timer`, `function zfcp_qdio_int_resp`, `function zfcp_qdio_irq_tasklet`, `function zfcp_qdio_poll`, `function zfcp_qdio_sbal_chain`.
- 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.