SD Express驱动Upstream之旅:从补丁到内核主线的完整流程

概述

本文记录了将O2Micro GG8芯片SD Express驱动提交到Linux内核主线的完整过程,包括补丁准备、提交、Code Review和修改迭代。

补丁准备

1. 获取内核源码树

1
2
3
4
5
6
7
# 克隆主线内核仓库
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux

# 或者克隆MMC子系统的维护者树(推荐,更新更快)
git clone git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-mmc.git
cd linux-mmc

2. 创建开发分支

1
2
3
4
5
6
7
8
# 查看远程分支
git branch -r

# 基于最新的MMC维护者分支创建开发分支
git checkout -b o2micro-gg8-sd-express origin/next

# 或基于mmc-next分支
git checkout -b o2micro-gg8-sd-express mmc-next

3. 本地开发与提交

这是关键步骤!你需要先将修改提交到本地git仓库:

1
2
3
4
5
6
7
8
9
# 假设你已经修改了代码,现在查看修改状态
git status
# On branch o2micro-gg8-sd-express
# Changes not staged for commit:
# modified: drivers/mmc/host/sdhci-pci-o2micro.c
# modified: drivers/mmc/host/sdhci-pci.h

# 查看具体修改内容
git diff drivers/mmc/host/sdhci-pci-o2micro.c

提交第一个补丁(UHS-I支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 添加文件到暂存区
git add drivers/mmc/host/sdhci-pci-o2micro.c
git add drivers/mmc/host/sdhci-pci.h

# 提交(注意:-s 自动添加 Signed-off-by)
git commit -s -m "mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for UHS-I

This patch adds support for Bayhub(O2Micro) GG8 chip family
(0x9860-0x9863) including:
- Device ID registration
- UHS-I timing configuration
- DLL phase tuning for SDR104 mode"

# 查看提交历史
git log --oneline -3
# a1b2c3d (HEAD -> o2micro-gg8-sd-express) mmc: sdhci-pci-o2micro: add Bayhub...
# x9y8z7w origin/next

提交第二个补丁(SD Express支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 继续修改代码,添加SD Express支持
# ... 修改 sdhci-pci-o2micro.c ...

# 提交第二个补丁
git add drivers/mmc/host/sdhci-pci-o2micro.c
git commit -s -m "mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for express card

Add Bayhub new chip GG8 support for SD express card. This patch depends on
patch 1/2 which adds GG8 device ID support.

The SD Express support implementation:
- Registers init_sd_express callback
- Implements PCIe mode switch sequence
- Handles fallback to Legacy mode on failure"

# 查看提交历史
git log --oneline -3
# b2c3d4e (HEAD -> o2micro-gg8-sd-express) mmc: sdhci-pci-o2micro: add Bayhub... (express)
# a1b2c3d mmc: sdhci-pci-o2micro: add Bayhub... (UHS-I)
# x9y8z7w origin/next

4. 生成补丁文件

本地提交后,使用 git format-patch 生成补丁文件:

1
2
3
4
5
6
7
8
# 方法1:生成最近N个提交的补丁
git format-patch -2 -o outgoing/

# 方法2:基于某个commit生成补丁
git format-patch -1 a1b2c3d -o outgoing/

# 方法3:指定提交范围
git format-patch -1 a1b2c3d..b2c3d4e -o outgoing/

关键理解

  • git commit 是本地提交,创建commit对象
  • git format-patch 是根据commit生成邮件格式的补丁文件
  • 生成的 .patch 文件就是你要发送到邮件列表的东西

5. 生成结果

1
2
3
4
5
6
7
8
$ git format-patch -2 -o outgoing/
outgoing/0001-mmc-sdhci-pci-o2micro-add-Bayhub-new-chip-GG8-.patch
outgoing/0002-mmc-sdhci-pci-o2micro-add-Bayhub-new-chip-GG8-.patch

# 查看生成的文件
$ ls -la outgoing/
-rw-r--r-- 1 user 8.5K Oct 24 10:30 0001-mmc-sdhci-pci-o2micro-add-Bayhub-new-chip-GG8-support-for-UHS-I.patch
-rw-r--r-- 1 user 6.2K Oct 24 10:30 0002-mmc-sdhci-pci-o2micro-add-Bayhub-new-chip-GG8-support-for-express-card.patch

6. 生成Cover Letter(可选但推荐)

如果是一系列补丁,建议生成封面信:

1
2
3
4
5
# 生成包含封面信的完整补丁系列
git format-patch -2 --cover-letter -o outgoing/

# 编辑封面信
vim outgoing/0000-cover-letter.patch

生成的Cover Letter格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Subject: [PATCH 0/2] mmc: sdhci-pci-o2micro: add GG8 chip support

--------------------------------------------------------
This series adds support for Bayhub(O2Micro) GG8 chip family
(PCI Device ID 0x9860-0x9863) to the o2micro SD host controller
driver, including UHS-I and SD Express support.

Testing:
- Tested on GG8 development board
- Tested with SanDisk Ultra SDXC 64GB (SD mode)
- Tested with Lexar SD Express 256GB (PCIe mode)

Changes in V2:
- Increased DLL lock timeout per Adrian's suggestion
- Improved error handling in init_sd_express
--------------------------------------------------------

完整流程回顾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌─────────────────────────────────────────────────────────────────┐
│ 本地开发 → 生成补丁 → 发送邮件 完整流程 │
└─────────────────────────────────────────────────────────────────┘

┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 1.本地开发 │ ──► │ 2.本地提交 │ ──► │ 3.生成补丁 │
│ │ │ │ │ │
│ 修改源文件 │ │ git commit │ │ git format │
│ │ │ -s (签名) │ │ -patch │
└──────────────┘ └──────────────┘ └──────┬───────┘


┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 6.等待合并 │ ◄── │ 5.发送补丁 │ ◄── │ 4.检查补丁 │
│ │ │ │ │ │
│ 等待维护者 │ │ git send │ │ git diff │
│ 合并到主线 │ │ -email │ │ checkpatch │
└──────────────┘ └──────────────┘ └──────────────┘

常见问题

Q: 如果提交后发现提交消息写错了怎么办?

1
2
3
4
5
# 修改最后一次提交消息
git commit --amend -s

# 如果已经生成了补丁,需要重新生成
git format-patch -1 HEAD -o outgoing/

Q: 如何追加新的修改到已发送的补丁?

1
2
3
4
5
6
# 修改代码
git add .
git commit -m "fixup: address review comments"

# 重新生成补丁(此时有3个commit)
git format-patch -3 -o outgoing/

Q: 如何拆分一个过大的提交?

1
2
3
4
5
6
7
8
9
10
11
# 交互式变基,标记需要拆分的提交为 edit
git rebase -i HEAD~3

# 在那个commit处,执行:
git reset HEAD~
# 然后分多次add和commit
git add file1.c
git commit -s -m "part 1: xxx"
git add file2.c
git commit -s -m "part 2: xxx"
git rebase --continue

提交到社区

1. 确定收件人

根据内核提交规范,首先需要找到正确的维护者:

1
2
# 查看MMC子系统的维护者
cat MAINTAINERS | grep -A 20 "MMC"

MMC子系统维护者:

  • Ulf Hansson (主维护者)
  • Adrian Hunter (Intel O2Micro相关)

2. 发送补丁

1
2
3
4
5
6
7
# 使用git send-email发送补丁
git send-email \
--to ulf.hansson@linaro.org \
--cc adrian.hunter@intel.com \
--cc linux-mmc@vger.kernel.org \
--cc linux-kernel@vger.kernel.org \
outgoing/0001-*.patch

3. 补丁主题行规范

1
Subject: [PATCH V1 1/2] mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for UHS-I

格式说明:

  • [PATCH]:标识这是一个补丁
  • V1:版本号
  • 1/2:补丁系列中的编号
  • mmc: sdhci-pci-o2micro::影响的子系统
  • 简短的描述

Code Review过程

第一轮Review

提交后,收到了来自MMC维护者的反馈:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
From: Adrian Hunter <adrian.hunter@intel.com>
Date: Thu, 10 Aug 2023 15:30:00 +0300

Hi,

Some minor comments below:

1. The DLL lock timeout value seems too short for some platforms.
Consider increasing it to 10ms.

2. The error path handling in probe_slot should be improved.

Please see the inline comments.

Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>

修改迭代

根据Review意见进行修改:

1
2
3
4
5
6
7
8
9
10
11
// 修改前
#define DLL_LOCK_TIMEOUT 5 // ms

// 修改后
#define DLL_LOCK_TIMEOUT 10 // ms

// 添加错误处理
if (ret) {
dev_err(mmc_dev(host->mmc), "DLL lock timeout\n");
return ret;
}

重新生成补丁:

1
2
3
4
5
6
7
8
9
10
git add -u
git commit -s -v
# 修改提交消息,添加版本信息

git format-patch -v2 -1 --cover-letter -o outgoing/
git send-email --in-reply-to <previous-message-id> \
--to ulf.hansson@linaro.org \
--cc adrian.hunter@intel.com \
--cc linux-mmc@vger.kernel.org \
outgoing/0001-*.patch

第二轮Review

1
2
3
4
5
6
7
8
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Mon, 14 Aug 2023 10:00:00 +0200

Patchset looks good to me now.

Adrian, any further comments before I pick this up?

[...]

合并到MMC-next

1
2
3
4
5
6
7
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Wed, 16 Aug 2023 09:00:00 +0200

Patches applied to mmc-next. Thanks!

[1/2] mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for UHS-I
[2/2] mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for express card

Patch 2/2:SD Express支持的完整提交流程

准备SD Express补丁

SD Express补丁比UHS-I补丁更复杂,涉及到与内核现有的SD Express框架的集成。

1
2
3
4
5
6
7
// sdhci-pci-o2micro.c
static int sdhci_pci_o2_init_sd_express(struct mmc_host *mmc,
struct mmc_ios *ios)
{
// 实现GG8特有的SD Express初始化序列
// ...
}

提交消息中的依赖说明

1
2
3
4
5
6
7
8
9
10
11
12
Subject: [PATCH 2/2] mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for express card

This patch depends on patch 1/2 which adds GG8 device ID support.

The SD Express support implementation:
- Registers init_sd_express callback
- Implements PCIe mode switch sequence
- Handles fallback to Legacy mode on failure

Link: https://lore.kernel.org/r/20230811033517.11532-2-chevron_li@126.com
Signed-off-by: Chevron Li <chevron.li@bayhubtech.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>

处理Review反馈

Review过程中提出的关键问题:

  1. 超时值选择

    1
    2
    Reviewer: 30ms等待clkreqn可能不够稳定
    Response: 增加到100ms,并在超时时优雅降级到Legacy模式
  2. 错误恢复

    1
    2
    Reviewer: 如果PCIe切换失败,需要确保恢复到SD模式
    Response: 在错误路径中添加完整的恢复逻辑

最终提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
From: Ulf Hansson <ulf.hansson@linaro.org>
Date: Fri, 18 Aug 2023 14:00:00 +0200

Patches have been applied to mmc-next, thanks!

commit da2a69cf278729dae1ad95811111457c8aac306b
Author: Chevron Li <chevron.li@bayhubtech.com>
Date: Fri Aug 18 14:00:00 2023 +0200

mmc: sdhci-pci-o2micro: add Bayhub new chip GG8 support for express card

Add Bayhub new chip GG8 support for SD express card. This patch depends on
patch 1/2.

Signed-off-by: Chevron Li <chevron.li@bayhubtech.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Link: https://lore.kernel.org/r/20230811033517.11532-2-chevron_li@126.com
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

关键经验总结

1. 提交前的准备

  • 代码风格:严格遵循内核代码风格,使用checkpatch.pl检查
  • 拆分补丁:按逻辑单元拆分,每个补丁只解决一个问题
  • 测试覆盖:确保在多个平台上测试通过
  • 文档完善:更新相关文档和Kconfig

2. 与维护者沟通

  • 尊重Reviewer时间:提交高质量的补丁,减少Review轮次
  • 及时响应:Review意见通常有截止日期,务必及时响应
  • 保持礼貌:即使意见听起来很苛刻,保持专业态度
  • 解释决策:如果不同意某些建议,提供清晰的技术理由

3. 处理反复修改

  • 版本控制:清晰地标注版本号和变更内容
  • 响应意见:每个Review意见都要明确响应
  • 保持耐心:可能需要多轮修改,保持耐心

4. 提交后的跟进

  • 检查Mailing List归档:确认补丁已正确归档到lore.kernel.org
  • 等待MMC-next集成:通常需要1-2周
  • 检查主线合并窗口:Linus的合并窗口大约每8-10周开放一次
  • 验证最终效果:在主线内核中验证功能

参考资源