drivers/scsi/aic94xx/aic94xx_task.c
Source file repositories/reference/linux-study-clean/drivers/scsi/aic94xx/aic94xx_task.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/scsi/aic94xx/aic94xx_task.c- Extension
.c- Size
- 15946 bytes
- Lines
- 612
- Domain
- Driver Families
- Bucket
- drivers/scsi
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/spinlock.haic94xx.haic94xx_sas.haic94xx_hwi.h
Detected Declarations
struct tc_resp_sb_structfunction asd_can_dequeuefunction asd_map_scatterlistfunction for_each_sgfunction for_each_sgfunction for_each_sgfunction asd_unmap_scatterlistfunction asd_get_response_taskletfunction asd_task_tasklet_completefunction asd_build_ata_ascbfunction asd_unbuild_ata_ascbfunction asd_build_smp_ascbfunction asd_unbuild_smp_ascbfunction asd_build_ssp_ascbfunction asd_unbuild_ssp_ascbfunction asd_can_queuefunction asd_execute_taskfunction list_for_each_entry
Annotated Snippet
struct tc_resp_sb_struct {
__le16 index_escb;
u8 len_lsb;
u8 flags;
} __attribute__ ((packed)) *resp_sb = (void *) dl->status_block;
/* int size = ((resp_sb->flags & 7) << 8) | resp_sb->len_lsb; */
int edb_id = ((resp_sb->flags & 0x70) >> 4)-1;
struct asd_ascb *escb;
struct asd_dma_tok *edb;
void *r;
spin_lock_irqsave(&asd_ha->seq.tc_index_lock, flags);
escb = asd_tc_index_find(&asd_ha->seq,
(int)le16_to_cpu(resp_sb->index_escb));
spin_unlock_irqrestore(&asd_ha->seq.tc_index_lock, flags);
if (!escb) {
ASD_DPRINTK("Uh-oh! No escb for this dl?!\n");
return;
}
ts->buf_valid_size = 0;
edb = asd_ha->seq.edb_arr[edb_id + escb->edb_index];
r = edb->vaddr;
if (task->task_proto == SAS_PROTOCOL_SSP) {
struct ssp_response_iu *iu =
r + 16 + sizeof(struct ssp_frame_hdr);
ts->residual = le32_to_cpu(*(__le32 *)r);
sas_ssp_task_response(&asd_ha->pcidev->dev, task, iu);
} else {
struct ata_task_resp *resp = (void *) &ts->buf[0];
ts->residual = le32_to_cpu(*(__le32 *)r);
if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE);
ts->buf_valid_size = sizeof(*resp);
}
}
asd_invalidate_edb(escb, edb_id);
}
static void asd_task_tasklet_complete(struct asd_ascb *ascb,
struct done_list_struct *dl)
{
struct sas_task *task = ascb->uldd_task;
struct task_status_struct *ts = &task->task_status;
unsigned long flags;
u8 opcode = dl->opcode;
asd_can_dequeue(ascb->ha, 1);
Again:
switch (opcode) {
case TC_NO_ERROR:
ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_SAM_STAT_GOOD;
break;
case TC_UNDERRUN:
ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DATA_UNDERRUN;
ts->residual = le32_to_cpu(*(__le32 *)dl->status_block);
break;
case TC_OVERRUN:
ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_DATA_OVERRUN;
ts->residual = 0;
break;
case TC_SSP_RESP:
case TC_ATA_RESP:
ts->resp = SAS_TASK_COMPLETE;
ts->stat = SAS_PROTO_RESPONSE;
asd_get_response_tasklet(ascb, dl);
break;
case TF_OPEN_REJECT:
ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_OPEN_REJECT;
if (dl->status_block[1] & 2)
ts->open_rej_reason = 1 + dl->status_block[2];
else if (dl->status_block[1] & 1)
ts->open_rej_reason = (dl->status_block[2] >> 4)+10;
else
ts->open_rej_reason = SAS_OREJ_UNKNOWN;
break;
case TF_OPEN_TO:
Annotation
- Immediate include surface: `linux/spinlock.h`, `aic94xx.h`, `aic94xx_sas.h`, `aic94xx_hwi.h`.
- Detected declarations: `struct tc_resp_sb_struct`, `function asd_can_dequeue`, `function asd_map_scatterlist`, `function for_each_sg`, `function for_each_sg`, `function for_each_sg`, `function asd_unmap_scatterlist`, `function asd_get_response_tasklet`, `function asd_task_tasklet_complete`, `function asd_build_ata_ascb`.
- Atlas domain: Driver Families / drivers/scsi.
- Implementation status: source 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.