Storport SD Controller 架构(二):工作线程与 Storport 请求交互机制
日期: 2026-03-21
系列: Storport SD Controller 架构解析
适用: Windows 驱动开发者、存储系统工程师
1. 概述
1.1 工作线程设计理念
BHTSDDR 驱动的核心设计之一是多工作线程架构:
- 主工作线程 (thread_main): 卡初始化、事件处理、电源管理
- 标签队列线程: 高效处理并发 I/O 请求
- 线程间同步: 使用事件对象和 DPC 实现异步通信
1.2 线程层次架构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| ┌─────────────────────────────────────────────────────────────────────┐ │ 工作线程层次架构 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ Windows Kernel (NTOS) │ │ │ │ │ │ │ │ 系统工作线程 (ExpWorkerThread) │ │ │ │ │ │ │ │ │ └── PnP Device Action Worker │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ Storport.sys (Windows Storage Framework) │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ │ │ I/O Request Flow: │ │ │ │ │ │ │ │ │ │ │ │ 文件系统 → Class Driver → Storage Stack → Storport │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ SRB (SCSI Request Block) │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ BHTSDDR Miniport Driver │ │ │ │ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ │ │ HwStartIo() ★ 主入口 │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ scsi_execute() → req_tag_io_add() │ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ tagqueue_add() → DPC 调度 │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ │ │ Work Threads (工作线程) │ │ │ │ │ │ │ │ │ │ │ │ thread_main() ←─── 主工作线程 │ │ │ │ │ │ │ │ │ │ │ │ │ ├── card_init_thread() ←─── 卡初始化线程 │ │ │ │ │ │ └── card_event_thread() ←─── 卡事件线程 │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ │ │ └───────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
2. 主工作线程 (thread_main)
2.1 线程创建
1 2 3 4 5 6
|
os_create_thread(pdx, &pdx->os.thread[0], pdx, thread_main);
|
2.2 线程入口函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| void thread_main(void *param) { bht_dev_ext_t *pdx = (bht_dev_ext_t *)param;
DbgInfo(MODULE_OS_ENTRY, FEATURE_THREAD_TRACE, NOT_TO_RAM, "thread_main start\n");
os_set_thread_priority(pdx, THREAD_PRIORITY_NORMAL);
while(!os_thread_should_terminate(pdx)) { e_event_t event = os_wait_event(pdx, &pdx->os);
switch(event) { case EVENT_TASK_OCCUR: thread_handle_task(pdx); break;
default: os_sleep(pdx, 10); break; } }
DbgInfo(MODULE_OS_ENTRY, FEATURE_THREAD_TRACE, NOT_TO_RAM, "thread_main exit\n"); }
|
2.3 线程事件类型
1 2 3 4 5 6 7 8 9 10
| typedef enum { EVENT_NONE = 0, EVENT_TASK_OCCUR, EVENT_CARD_INIT, EVENT_CARD_REMOVE, EVENT_RTD3_REQUEST, EVENT_RTD3_COMPLETE, } e_event_t;
|
3. 标签队列 (Tag Queue) 机制
3.1 Tag Queue 设计理念
为什么需要 Tag Queue?
- SD Host Controller 有硬件队列深度限制 (通常 32 或 64)
- Storport 可能有多个并发 I/O 请求
- Tag Queue 负责请求分发和资源管理
3.2 标签队列结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| typedef struct tag_queue_s { u32 max_queue_depth;
volatile u32 used_cnt; volatile u32 pending_cnt;
node_t *nodes[MAX_TAG];
node_t *free_head; node_t *free_tail;
os_lock_t lock; os_event_t queue_event; } tag_queue_t;
typedef struct node_s { u16 tag; u8 status; u8 reserved;
srb_ext_t *srb_ext;
dma_buf_t data_buf; trans_context_t trans_ctx;
struct node_s *next; } node_t;
|
3.3 标签状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| ┌─────────────────────────────────────────────────────────────────────┐ │ Tag 状态机 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ tag_alloc() │ │ │ │ │ ▼ │ │ ┌─────────┐ tag_build_io() ┌─────────────┐ tag_start_io() │ │ │ FREE │ ────────────────────► │ BUILT │ ──────────────► │ │ │ (空闲) │ │ (已构建) │ │ │ └─────────┘ └─────────────┘ │ │ ▲ │ │ │ │ │ │ │ │ tag_free() tag_complete() │ │ │ │ │ │ │ ┌────────────────────────┘ │ │ │ ▼ │ │ │ ┌─────────────┐ tag_cleanup() │ │ └──│ COMPLETED │ ◄────────────────────────────────────── │ │ │ (已完成) │ │ │ └─────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────────┐ │ │ │ 状态说明: │ │ │ │ │ │ │ │ FREE ← 空闲状态,可分配给新请求 │ │ │ │ BUILT ← 已构建 DMA 传输,硬件可处理 │ │ │ │ EXECUTING ← 正在执行 │ │ │ │ COMPLETED ← 传输完成,待释放 │ │ │ │ │ │ │ └─────────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
4. SRB 到 Tag Queue 的请求流程
4.1 请求入口: scsi_execute()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
static BOOLEAN scsi_execute( bht_dev_ext_t *pdx, PSCSI_REQUEST_BLOCK Srb, bool *pending_io ) { srb_ext_t *srb_ext = (srb_ext_t *)Srb->SrbExtension;
DbgInfo(MODULE_OS_ENTRY, FEATURE_SCSICMD_TRACE, NOT_TO_RAM, "scsi_execute: CDB[0]=0x%02X LBA=%lld Len=%d\n", Srb->Cdb[0], get_lba_from_cdb(Srb), get_len_from_cdb(Srb));
switch(Srb->Cdb[0]) { case SCSIOP_READ: case SCSIOP_WRITE: return req_tag_io_add(pdx, srb_ext, Srb, pending_io);
case SCSIOP_INQUIRY: return scsi_inquiry(pdx, srb_ext, Srb);
case SCSIOP_TEST_UNIT_READY: return scsi_test_unit_ready(pdx, srb_ext, Srb);
case SCSIOP_REQUEST_SENSE: return scsi_request_sense(pdx, srb_ext, Srb);
default: Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST; return TRUE; } }
|
4.2 请求添加到 Tag Queue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| e_req_result req_tag_io_add( bht_dev_ext_t *pdx, srb_ext_t *srb_ext, PSCSI_REQUEST_BLOCK Srb, bool *pending_io ) { e_req_result result = REQ_SUCCESS;
node_t *node = tag_alloc(&pdx->tag_queue); if(node == NULL) { DbgErr("tag_alloc failed!\n"); Srb->SrbStatus = SRB_STATUS_BUSY; *pending_io = FALSE; return REQ_TAG_FULL; }
node_init(node, srb_ext);
srb_ext->node = node; node->srb_ext = srb_ext;
if(!IS_DEVICE_READY(pdx)) { os_set_event(pdx, &pdx->os, EVENT_CARD_INIT); tag_free(&pdx->tag_queue, node); Srb->SrbStatus = SRB_STATUS_BUSY; *pending_io = TRUE; return REQ_DEVICE_NOT_READY; }
result = tag_build_io(pdx, node); if(result != REQ_SUCCESS) { tag_free(&pdx->tag_queue, node); Srb->SrbStatus = SRB_STATUS_ERROR; return result; }
result = tag_start_io(pdx, node); if(result == REQ_PENDING) { *pending_io = TRUE; } else if(result == REQ_SUCCESS) { *pending_io = FALSE; }
return result; }
|
4.3 请求处理时序图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| ┌─────────────────────────────────────────────────────────────────────┐ │ SRB → Tag Queue 请求处理时序 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ [Storport] [HwStartIO] [req_tag_io_add] [tagqueue] │ │ │ │ │ │ │ │ │ SRB下发 │ │ │ │ │ │──────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ scsi_execute() │ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ tag_alloc() │ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ ◄─ 分配空闲 Tag │ │ │ │ │ │ │ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ │ │ tag_build_io() │ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ ◄─ 构建DMA描述符 │ │ │ │ │ │ │ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ │ │ tag_start_io() │ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ ◄─ 启动DMA传输 │ │ │ │ │ │ │ │ │ │ │◄──────────────│ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ │ SRB_PENDING │ │ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ │ │ │ [中断处理] │ │ │ │ │ │ │ │ │ │ │ │ │◄──────│───────│ │ │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ │ tag_complete()│ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │ │ tag_free() │ │ │ │ │ │───────────────►│ │ │ │ │ │ │ │ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ SRB完成通知 │ │ │ │ │ │◄──────────────│ │ │ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
5. 中断与 DPC 处理
5.1 中断处理入口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| BOOLEAN scsi_HwInterrupt(IN PVOID DeviceExtension) { return sdhci_irq((bht_dev_ext_t *)DeviceExtension); }
BOOLEAN sdhci_irq(bht_dev_ext_t *pdx) { u32 int_status = sdhci_readl(&pdx->host, SDHCI_INT_STATUS); u32 int_enable = sdhci_readl(&pdx->host, SDHCI_INT_ENABLE);
sdhci_writel(&pdx->host, SDHCI_INT_STATUS, int_status);
if(int_status & SDHCI_INT_TRANSFER_COMPLETE) { os_issue_dpc(pdx, trans_done_dpc, NULL); return TRUE; }
if(int_status & SDHCI_INT_CMD_COMPLETE) { os_issue_dpc(pdx, cmd_done_dpc, NULL); return TRUE; }
if(int_status & (SDHCI_INT_ERROR | SDHCI_INT_CMD_TIMEOUT)) { os_issue_dpc(pdx, error_dpc, NULL); return TRUE; }
return FALSE; }
|
5.2 DPC (Deferred Procedure Call) 完成处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| void trans_done_dpc( bht_dev_ext_t *pdx, PVOID DeviceExtension, PVOID SystemArgument1, PVOID SystemArgument2 ) { node_t *node = (node_t *)SystemArgument1;
DbgInfo(MODULE_OS_ENTRY, FEATURE_TRANS_TRACE, NOT_TO_RAM, "trans_done_dpc: tag=%d\n", node->tag);
tag_complete(&pdx->tag_queue, node);
if(node->trans_dir == DATA_DIR_IN) { copy_data_to_srb(pdx, node); }
node->status = NODE_STATUS_COMPLETED;
complete_srb(pdx, node->srb_ext, SRB_STATUS_SUCCESS);
tag_free(&pdx->tag_queue, node); }
|
5.3 SRB 完成通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| void complete_srb( bht_dev_ext_t *pdx, srb_ext_t *srb_ext, UCHAR SrbStatus ) { PSCSI_REQUEST_BLOCK Srb = srb_ext->psrb;
Srb->SrbStatus = SrbStatus;
if(SrbStatus != SRB_STATUS_SUCCESS) { srb_ext->sense_data.Valid = TRUE; srb_ext->sense_data.SenseKey = ...; srb_ext->sense_data.AddSenseCode = ...; }
StorPortNotification(RequestComplete, pdx, Srb); }
|
6. 传输模式 (SDMA / ADMA2 / ADMA3)
6.1 传输模式选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| e_trans_type select_transfer_mode( bht_dev_ext_t *pdx, srb_ext_t *srb_ext ) { if(!pdx->host.feature.adma2_supp) return TRANS_SDMA;
u32 len = srb_ext->req.tag_req_t.sec_cnt * 512; if(len > MAX_SDMA_LENGTH) return TRANS_ADMA2;
if(srb_ext->req.srb_sg_len == 1) return TRANS_ADMA2; else return TRANS_SDMA;
if(pdx->pm_state.current_state == PM_STATE_D3) return TRANS_PIO; }
|
6.2 传输模式对比
| 模式 |
描述 |
优点 |
缺点 |
适用场景 |
| SDMA |
单次 DMA,直接指定数据地址 |
简单,低延迟 |
需要连续物理内存 |
小块传输 (<4KB) |
| ADMA2 |
高级 DMA,使用描述符表 |
支持 Scatter-Gather |
描述符需要 IOVA |
中等大小传输 |
| ADMA3 |
ADMA2 增强,支持双缓冲区 |
高性能,低功耗 |
配置复杂 |
大块传输 |
| PIO |
程序化 I/O,CPU 直接访问 |
兼容性好 |
CPU 占用高 |
低功耗/错误恢复 |
6.3 ADMA2 描述符表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| ┌─────────────────────────────────────────────────────────────────────┐ │ ADMA2 描述符表格式 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ Descriptor Entry (64-bit) │ │ │ │ ┌────────────────┬────────────────┬───────┬───────┐ │ │ │ │ │ Address [63:32] │ Length [15:0] │ Type │ Attr │ │ │ │ │ └────────────────┴────────────────┴───────┴───────┘ │ │ │ │ │ │ │ │ Type: │ │ │ │ - 00b: FDS (Fetch Descriptor) │ │ │ │ - 01b: Tran (Data Transfer) │ │ │ │ - 10b: Link (Link to next descriptor table) │ │ │ │ - 11b: Nop (No Operation) │ │ │ │ │ │ │ │ Attr: │ │ │ │ - Valid: 描述符有效 │ │ │ │ - End: 描述符链结束 │ │ │ │ - Int: 产生中断 │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ 示例: 传输 3 个非连续数据块 │ │ │ │ │ │ │ │ ┌─────────┬──────┬────┬─────┐ │ │ │ │ │ Addr0 │ Len0 │ 01 │ V │ ───► Data Block 0 │ │ │ │ ├─────────┼──────┼────┼─────┤ │ │ │ │ │ Addr1 │ Len1 │ 01 │ V │ ───► Data Block 1 │ │ │ │ ├─────────┼──────┼────┼─────┤ │ │ │ │ │ Addr2 │ Len2 │ 01 │ VE │ ───► Data Block 2 (End) │ │ │ │ └─────────┴──────┴────┴─────┘ │ │ │ │ V=Valid, VE=Valid+End │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
7. 工作线程与请求的同步机制
7.1 事件同步对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| typedef struct { PSTOR_EVENT pStorEvent;
volatile BOOLEAN signaled; } win_evt_t;
typedef struct { u32 evt_cnt; PVOID pevt_array[MAX_EVENTS]; } evt_mgr_t;
|
7.2 线程等待模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| e_event_t os_wait_event(void *pdx, os_struct *os) { evt_mgr_t *mgr = &os->evt_mgr; NTSTATUS ret;
ret = StorPortWaitForSingleObject( (bht_dev_ext_t*)pdx, mgr->pevt_array[EVENT_TASK_OCCUR], FALSE, NULL );
if(ret == STATUS_SUCCESS) return EVENT_TASK_OCCUR;
return EVENT_NONE; }
|
7.3 跨线程通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| ┌─────────────────────────────────────────────────────────────────────┐ │ 跨线程通信机制 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ [HwStartIO 上下文] [工作线程上下文] │ │ │ │ │ │ │ │ os_wait_event() │ │ │ │ ◄── 阻塞等待 ── │ │ │ │ │ │ │ tag_build_io() │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ os_set_event() │ │ │ │ │ │ │ │ │ │ 唤醒 │ │ │ │ ├────────────────────►│ │ │ │ │ │ │ │ │ │ │ thread_handle_task() │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ 处理工作项 │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ │ │ │ 返回等待状态 │ │ │ │ │ │ ▼ ▼ │ │ │ │ 同步点: │ │ - Tag Queue 锁保护共享数据 │ │ - 事件对象协调线程唤醒 │ │ - DPC 串行化中断处理 │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
8. 卡初始化线程
8.1 卡初始化流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| void card_init_thread(void *param) { bht_dev_ext_t *pdx = (bht_dev_ext_t *)param; card_init_result_t result;
DbgInfo(MODULE_OS_ENTRY, FEATURE_THREAD_TRACE, NOT_TO_RAM, "card_init_thread start\n");
while(!os_thread_should_terminate(pdx)) { os_wait_for_event(&pdx->os.evt_card_init);
if(IS_DEVICE_REMOVED(pdx)) { DbgInfo(..., "card removed, skip init\n"); continue; }
result = card_init_full(&pdx->card, 3);
if(result == CARD_INIT_SUCCESS) { DbgInfo(..., "card init success\n"); StorPortNotification(BusChangeDetected, pdx); } else { DbgErr("card init failed: %d\n", result); } } }
|
8.2 卡初始化状态机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| ┌─────────────────────────────────────────────────────────────────────┐ │ 卡初始化状态机 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ │ │ │ NO_CARD │ ←─── 卡物理移除 │ │ │ (无卡) │ │ │ └──────────────┘ │ │ │ │ │ │ card_inserted() │ │ ▼ │ │ ┌──────────────┐ │ │ │ INIT_START │ ←─── 收到卡插入中断 │ │ │ (开始初始化) │ │ │ └──────────────┘ │ │ │ │ │ │ card_identify() │ │ ▼ │ │ ┌──────────────┐ │ │ │ IDENTIFY │ ←─── 识别卡类型 │ │ │ (识别中) │ (SD/MMC/UHS2) │ │ └──────────────┘ │ │ │ │ │ │ card_init_csd() │ │ ▼ │ │ ┌──────────────┐ │ │ │ INIT_CSD │ ←─── 读取 CSD 寄存器 │ │ │ (读取参数) │ │ │ └──────────────┘ │ │ │ │ │ │ card_switch() │ │ ▼ │ │ ┌──────────────┐ │ │ │ SWITCH │ ←─── 切换到高速模式 │ │ │ (模式切换) │ (UHS-I / HS200 / HS400) │ │ └──────────────┘ │ │ │ │ │ │ card_ready() │ │ ▼ │ │ ┌──────────────┐ │ │ │ READY ★ │ ←─── 卡就绪,可接受读写 │ │ │ (就绪) │ │ │ └──────────────┘ │ │ │ │ 错误路径: │ │ INIT_START ──timeout──► ERROR ──card_remove──► NO_CARD │ │ │ └─────────────────────────────────────────────────────────────────────┘
|
9. 电源状态与请求处理
9.1 电源状态对请求的影响
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| e_req_result req_check_power_state( bht_dev_ext_t *pdx, srb_ext_t *srb_ext ) { switch(pdx->pm_state.current_state) { case PM_STATE_D0: return REQ_SUCCESS;
case PM_STATE_RTD3: if(IS_WAKE_REQUEST(srb_ext)) return REQ_SUCCESS; else return REQ_PENDING;
case PM_STATE_D3: return REQ_PENDING;
default: return REQ_ERROR; } }
|
9.2 D3 进入流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| void req_enter_d3(bht_dev_ext_t *pdx) { DbgInfo(MODULE_OS_ENTRY, FEATURE_PM_TRACE, NOT_TO_RAM, "req_enter_d3 enter\n");
pdx->pm_state.current_state = PM_STATE_D3; pdx->pm_state.d3_entered = TRUE;
req_cancel_all_io(pdx);
host_set_clock(&pdx->host, 0);
card_power_off(&pdx->card, TRUE);
DbgInfo(MODULE_OS_ENTRY, FEATURE_PM_TRACE, NOT_TO_RAM, "req_enter_d3 exit\n"); }
|
10. 总结
10.1 请求处理关键路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| SRB 到达 → scsi_execute() → req_tag_io_add() │ ▼ tag_alloc() (分配 Tag) │ ▼ tag_build_io() (构建 DMA) │ ▼ tag_start_io() (启动传输) │ ┌─────────────────┴─────────────────┐ │ │ 同步完成 异步完成 │ │ ▼ ▼ StorPortNotification() 中断触发 (RequestComplete) │ │ ▼ │ DPC: trans_done_dpc() │ │ ▼ ▼ SRB 完成 tag_complete()
|
10.2 设计要点
| 要点 |
实现 |
| Tag 管理 |
静态数组 + 空闲链表 |
| 异步处理 |
DPC + 事件同步 |
| 错误处理 |
错误恢复流程 + SRB Sense Data |
| 电源管理 |
状态检查 + 请求拦截 |
| 并发控制 |
自旋锁 + 原子操作 |
文档生成日期: 2026-03-21
驱动版本: BHTSDDR