MTD NAND 驅動程式設計介面¶
- 作者:
Thomas Gleixner
簡介¶
通用 NAND 驅動程式支援幾乎所有基於 NAND 和 AG-AND 的晶片,並將它們連線到 Linux 核心的記憶體技術裝置 (MTD) 子系統。
本文件提供給想要實現適用於 NAND 裝置的板級驅動程式或檔案系統驅動程式的開發人員。
已知錯誤和假設¶
無。
文件提示¶
函式和結構文件是自動生成的。每個函式和結構成員都有一個簡短的描述,並標有 [XXX] 識別符號。以下章節解釋了這些識別符號的含義。
函式識別符號 [XXX]¶
這些函式在簡短的註釋中用 [XXX] 識別符號標記。這些識別符號解釋了函式的使用和範圍。使用以下識別符號
[MTD 介面]
這些函式提供了 MTD 核心 API 的介面。它們不可替換,並提供完全獨立於硬體的功能。
[NAND 介面]
這些函式已匯出,並提供 NAND 核心 API 的介面。
[GENERIC]
通用函式不可替換,並提供完全獨立於硬體的功能。
[DEFAULT]
預設函式提供與硬體相關的功能,適用於大多數實現。如果需要,板級驅動程式可以替換這些函式。這些函式透過 NAND 晶片描述結構中的指標呼叫。板級驅動程式可以在呼叫 nand_scan() 之前設定應由板級相關函式替換的函式。如果在進入 nand_scan() 時函式指標為 NULL,則該指標將設定為適用於檢測到的晶片型別的預設函式。
結構成員識別符號 [XXX]¶
結構成員在註釋中用 [XXX] 識別符號標記。這些識別符號解釋了成員的使用和範圍。使用以下識別符號
[INTERN]
這些成員僅供 NAND 驅動程式內部使用,不得修改。這些值中的大多數都是從晶片幾何資訊計算出來的,這些資訊在 nand_scan() 期間進行評估。
[REPLACEABLE]
可替換成員儲存硬體相關函式,這些函式可由板級驅動程式提供。板級驅動程式可以在呼叫 nand_scan() 之前設定應由板級相關函式替換的函式。如果在進入 nand_scan() 時函式指標為 NULL,則該指標將設定為適用於檢測到的晶片型別的預設函式。
[BOARDSPECIFIC]
板級特定成員儲存硬體相關資訊,這些資訊必須由板級驅動程式提供。板級驅動程式必須在呼叫 nand_scan() 之前設定函式指標和資料欄位。
[OPTIONAL]
可選成員可以儲存與板級驅動程式相關的資訊。通用 NAND 驅動程式程式碼不使用此資訊。
基本板級驅動程式¶
對於大多數板,僅提供基本函式並填寫 NAND 晶片描述結構中一些真正與板相關的成員就足夠了。
基本定義¶
至少您必須提供一個 nand_chip 結構和一個用於儲存 ioremap'ed 晶片地址的儲存。您可以使用 kmalloc 分配 nand_chip 結構,也可以靜態分配它。NAND 晶片結構嵌入一個 mtd 結構,該結構將註冊到 MTD 子系統。您可以使用 nand_to_mtd() 助手從 nand_chip 指標中提取指向 mtd 結構的指標。
基於 Kmalloc 的示例
static struct mtd_info *board_mtd;
static void __iomem *baseaddr;
靜態示例
static struct nand_chip board_chip;
static void __iomem *baseaddr;
分割槽定義¶
如果您想將您的裝置劃分為分割槽,請定義一個適合您板的分割槽方案。
#define NUM_PARTITIONS 2
static struct mtd_partition partition_info[] = {
{ .name = "Flash partition 1",
.offset = 0,
.size = 8 * 1024 * 1024 },
{ .name = "Flash partition 2",
.offset = MTDPART_OFS_NEXT,
.size = MTDPART_SIZ_FULL },
};
硬體控制函式¶
硬體控制函式提供對 NAND 晶片控制引腳的訪問。可以透過 GPIO 引腳或地址線完成訪問。如果您使用地址線,請確保滿足時序要求。
基於 GPIO 的示例
static void board_hwcontrol(struct mtd_info *mtd, int cmd)
{
switch(cmd){
case NAND_CTL_SETCLE: /* Set CLE pin high */ break;
case NAND_CTL_CLRCLE: /* Set CLE pin low */ break;
case NAND_CTL_SETALE: /* Set ALE pin high */ break;
case NAND_CTL_CLRALE: /* Set ALE pin low */ break;
case NAND_CTL_SETNCE: /* Set nCE pin low */ break;
case NAND_CTL_CLRNCE: /* Set nCE pin high */ break;
}
}
基於地址線的示例。 假設 nCE 引腳由晶片選擇解碼器驅動。
static void board_hwcontrol(struct mtd_info *mtd, int cmd)
{
struct nand_chip *this = mtd_to_nand(mtd);
switch(cmd){
case NAND_CTL_SETCLE: this->legacy.IO_ADDR_W |= CLE_ADRR_BIT; break;
case NAND_CTL_CLRCLE: this->legacy.IO_ADDR_W &= ~CLE_ADRR_BIT; break;
case NAND_CTL_SETALE: this->legacy.IO_ADDR_W |= ALE_ADRR_BIT; break;
case NAND_CTL_CLRALE: this->legacy.IO_ADDR_W &= ~ALE_ADRR_BIT; break;
}
}
裝置就緒函式¶
如果硬體介面將 NAND 晶片的就緒繁忙引腳連線到 GPIO 或其他可訪問的 I/O 引腳,則使用此函式來讀取引腳的狀態。該函式沒有引數,如果裝置繁忙(R/B 引腳為低電平),則應返回 0,如果裝置就緒(R/B 引腳為高電平),則應返回 1。如果硬體介面無法訪問就緒繁忙引腳,則不得定義該函式,並且函式指標 this->legacy.dev_ready 設定為 NULL。
Init 函式¶
Init 函式分配記憶體並設定所有特定於板的引數和函式指標。當所有設定完成後,將呼叫 nand_scan()。此函式嘗試檢測和識別晶片。如果找到晶片,則會相應地初始化所有內部資料欄位。必須首先將結構清零,然後用有關裝置的必要資訊填充。
static int __init board_init (void)
{
struct nand_chip *this;
int err = 0;
/* Allocate memory for MTD device structure and private data */
this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);
if (!this) {
printk ("Unable to allocate NAND MTD device structure.\n");
err = -ENOMEM;
goto out;
}
board_mtd = nand_to_mtd(this);
/* map physical address */
baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
if (!baseaddr) {
printk("Ioremap to access NAND chip failed\n");
err = -EIO;
goto out_mtd;
}
/* Set address of NAND IO lines */
this->legacy.IO_ADDR_R = baseaddr;
this->legacy.IO_ADDR_W = baseaddr;
/* Reference hardware control function */
this->hwcontrol = board_hwcontrol;
/* Set command delay time, see datasheet for correct value */
this->legacy.chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
/* Assign the device ready function, if available */
this->legacy.dev_ready = board_dev_ready;
this->eccmode = NAND_ECC_SOFT;
/* Scan to find existence of the device */
if (nand_scan (this, 1)) {
err = -ENXIO;
goto out_ior;
}
add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS);
goto out;
out_ior:
iounmap(baseaddr);
out_mtd:
kfree (this);
out:
return err;
}
module_init(board_init);
Exit 函式¶
只有當驅動程式編譯為模組時,才需要退出函式。它釋放晶片驅動程式持有的所有資源,並取消註冊 MTD 層中的分割槽。
#ifdef MODULE
static void __exit board_cleanup (void)
{
/* Unregister device */
WARN_ON(mtd_device_unregister(board_mtd));
/* Release resources */
nand_cleanup(mtd_to_nand(board_mtd));
/* unmap physical address */
iounmap(baseaddr);
/* Free the MTD device structure */
kfree (mtd_to_nand(board_mtd));
}
module_exit(board_cleanup);
#endif
高階板級驅動程式函式¶
本章介紹 NAND 驅動程式的高階功能。有關可由板級驅動程式覆蓋的函式列表,請參閱 nand_chip 結構的文件。
多晶片控制¶
nand 驅動程式可以控制晶片陣列。因此,板級驅動程式必須提供自己的 select_chip 函式。此函式必須(取消)選擇請求的晶片。必須在呼叫 nand_scan() 之前設定 nand_chip 結構中的函式指標。nand_scan() 的 maxchip 引數定義要掃描的最大晶片數。確保 select_chip 函式可以處理請求的晶片數。
nand 驅動程式將晶片連線到一個虛擬晶片,並將此虛擬晶片提供給 MTD 層。
注意:驅動程式只能處理大小相等的晶片的線性晶片陣列。不支援擴充套件匯流排寬度的並行陣列。
基於 GPIO 的示例
static void board_select_chip (struct mtd_info *mtd, int chip)
{
/* Deselect all chips, set all nCE pins high */
GPIO(BOARD_NAND_NCE) |= 0xff;
if (chip >= 0)
GPIO(BOARD_NAND_NCE) &= ~ (1 << chip);
}
基於地址線的示例。 假設 nCE 引腳連線到地址解碼器。
static void board_select_chip (struct mtd_info *mtd, int chip)
{
struct nand_chip *this = mtd_to_nand(mtd);
/* Deselect all chips */
this->legacy.IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
this->legacy.IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
switch (chip) {
case 0:
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
break;
....
case n:
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
break;
}
}
硬體 ECC 支援¶
函式和常量¶
nand 驅動程式支援三種不同型別的硬體 ECC。
NAND_ECC_HW3_256
硬體 ECC 生成器,每 256 位元組提供 3 位元組 ECC。
NAND_ECC_HW3_512
硬體 ECC 生成器,每 512 位元組提供 3 位元組 ECC。
NAND_ECC_HW6_512
硬體 ECC 生成器,每 512 位元組提供 6 位元組 ECC。
NAND_ECC_HW8_512
硬體 ECC 生成器,每 512 位元組提供 8 位元組 ECC。
如果您的硬體生成器具有不同的功能,請將其新增到 nand_base.c 中的適當位置
板級驅動程式必須提供以下函式
enable_hwecc
在讀取/寫入晶片之前呼叫此函式。在此函式中重置或初始化硬體生成器。該函式使用一個引數呼叫,該引數允許您區分讀取和寫入操作。
calculate_ecc
從/向晶片讀取/寫入後呼叫此函式。將 ECC 從硬體傳輸到緩衝區。如果設定了選項 NAND_HWECC_SYNDROME,則僅在寫入時呼叫該函式。見下文。
correct_data
如果發生 ECC 錯誤,則呼叫此函式進行錯誤檢測和糾正。如果可以糾正錯誤,則分別返回 1 或 2。如果錯誤無法糾正,則返回 -1。如果您的硬體生成器與 nand_ecc 軟體生成器的預設演算法匹配,則使用 nand_ecc 提供的糾正函式,而不是實現重複程式碼。
帶有綜合徵計算的硬體 ECC¶
許多硬體 ECC 實現提供 Reed-Solomon 程式碼,並在讀取時計算錯誤綜合徵。在通用 Reed-Solomon 庫中呼叫錯誤糾正程式碼之前,必須將綜合徵轉換為標準 Reed-Solomon 綜合徵。
為了使綜合徵生成器工作,ECC 位元組必須緊隨資料位元組之後。這與軟體 ECC 通常使用的佈局相反。不再可能分離資料和帶外區域。nand 驅動程式程式碼處理此佈局,並且 oob 區域中剩餘的空閒位元組由自動放置程式碼管理。在這種情況下,提供一個匹配的 oob 佈局。有關實現參考,請參閱 rts_from4.c 和 diskonchip.c。在這些情況下,我們還必須在 FLASH 上使用壞塊表,因為 ECC 佈局會干擾壞塊標記位置。有關詳細資訊,請參閱壞塊表支援。
壞塊表支援¶
大多數 NAND 晶片在備用區域中的定義位置標記壞塊。在任何情況下都不得擦除這些塊,因為壞塊資訊將丟失。每次訪問塊時,都可以透過讀取塊中第一頁的備用區域來檢查壞塊標記。這很耗時,因此使用壞塊表。
nand 驅動程式支援各種型別的壞塊表。
每個裝置
壞塊表包含裝置的所有壞塊資訊,該裝置可以由多個晶片組成。
每個晶片
每個晶片使用一個壞塊表,幷包含此特定晶片的壞塊資訊。
固定偏移
壞塊表位於晶片(裝置)中的固定偏移處。這適用於各種 DiskOnChip 裝置。
自動放置
壞塊表自動放置並檢測在晶片(裝置)的末尾或開頭
映象表
壞塊表映象在晶片(裝置)上,以允許在不丟失資料的情況下更新壞塊表。
nand_scan() 呼叫函式 nand_default_bbt()。nand_default_bbt() 根據 nand_scan() 檢索到的晶片資訊選擇合適的預設壞塊表描述符。
標準策略是掃描裝置中的壞塊並構建一個基於 ram 的壞塊表,該表允許比始終檢查快閃記憶體晶片本身的壞塊資訊更快的訪問。
基於快閃記憶體的表¶
可能需要或必須將壞塊表儲存在 FLASH 中。對於 AG-AND 晶片,這是強制性的,因為它們沒有工廠標記的壞塊。它們有工廠標記的好塊。當擦除該塊以重新使用時,標記模式會被擦除。因此,如果在將模式寫回晶片之前斷電,則該塊將丟失並新增到壞塊中。因此,當第一次檢測到晶片時,我們會掃描晶片的好塊,並將此資訊儲存在壞塊表中,然後再擦除任何塊。
儲存表的塊受到保護,防止意外訪問,方法是在記憶體壞塊表中將它們標記為壞塊。壞塊表管理功能允許規避此保護。
啟用基於 FLASH 的壞塊表支援的最簡單方法是在呼叫 nand_scan() 之前在 nand 晶片結構的 bbt_option 欄位中設定選項 NAND_BBT_USE_FLASH。對於 AG-AND 晶片,預設情況下會這樣做。這將啟用 NAND 驅動程式的預設基於 FLASH 的壞塊表功能。預設的壞塊表選項是
儲存每個晶片的壞塊表
每個塊使用 2 位
在晶片末尾自動放置
使用帶有版本號的映象表
在晶片末尾保留 4 個塊
使用者定義的表¶
使用者定義的表是透過填寫 nand_bbt_descr 結構並在呼叫 nand_scan() 之前將指標儲存在 nand_chip 結構成員 bbt_td 中來建立的。如果需要映象表,則必須建立第二個結構,並且指向該結構的指標必須儲存在 nand_chip 結構中的 bbt_md 中。如果 bbt_md 成員設定為 NULL,則僅使用主表,並且不執行映象表的掃描。
nand_bbt_descr 結構中最重要的欄位是 options 欄位。選項定義了大多數表屬性。使用 rawnand.h 中預定義的常量來定義選項。
每個塊的位數
支援的位數是 1、2、4、8。
每個晶片的表
設定常量 NAND_BBT_PERCHIP 選擇為晶片陣列中的每個晶片管理一個壞塊表。如果未設定此選項,則使用每個裝置的壞塊表。
表位置是絕對的
使用選項常量 NAND_BBT_ABSPAGE 並定義壞塊表在 pages 欄位中開始的絕對頁碼。如果您選擇了每個晶片的壞塊表並且您有一個多晶片陣列,則必須為晶片陣列中的每個晶片提供起始頁。注意:不執行表標識模式的掃描,因此欄位 pattern、veroffs、offs、len 可以保持未初始化
表位置是自動檢測的
該表可以位於晶片(裝置)的第一個或最後一個好塊中。設定 NAND_BBT_LASTBLOCK 以將壞塊表放置在晶片(裝置)的末尾。壞塊表透過儲存在儲存壞塊表的塊中第一頁的備用區域中的模式進行標記和標識。將指向模式的指標儲存在 pattern 欄位中。此外,模式的長度必須儲存在 len 中,並且備用區域中的偏移必須在 nand_bbt_descr 結構的 offs 成員中給出。對於映象壞塊表,強制使用不同的模式。
表建立
如果在掃描期間找不到表,則設定選項 NAND_BBT_CREATE 以啟用表建立。通常,如果找到新晶片,則僅執行一次此操作。
表寫入支援
設定選項 NAND_BBT_WRITE 以啟用表寫入支援。這允許在由於磨損而必須將塊標記為壞塊的情況下更新壞塊表。MTD 介面函式 block_markbad 正在呼叫壞塊表的更新函式。如果啟用了寫入支援,則表會在 FLASH 上更新。
注意:僅應為帶有版本控制的映象表啟用寫入支援。
表版本控制
設定選項 NAND_BBT_VERSION 以啟用表版本控制。強烈建議為帶有寫入支援的映象表啟用此功能。它可以確保將丟失壞塊表資訊的風險降低到丟失有關應標記為壞塊的一個磨損塊的資訊。
在寫入時儲存塊內容
如果儲存壞塊表的塊確實包含其他有用資訊,請設定選項 NAND_BBT_SAVECONTENT。寫入壞塊表時,會讀取整個塊,更新壞塊表,擦除塊,然後將所有內容寫回。如果未設定此選項,則僅寫入壞塊表,並且忽略並擦除塊中的所有其他內容。
保留塊數
對於自動放置,必須為壞塊表儲存保留一些塊。保留塊的數量在壞塊表描述結構的 maxblocks 成員中定義。為映象表保留 4 個塊應該是一個合理的數字。這也限制了掃描壞塊表標識模式的塊的數量。
備用區域(自動)放置¶
nand 驅動程式實現了在備用區域中放置檔案系統資料的不同可能性,
由 fs 驅動程式定義的放置
自動放置
預設放置函式是自動放置。nand 驅動程式具有適用於各種晶片型別的內建預設放置方案。如果由於硬體 ECC 功能而導致預設放置不合適,則板級驅動程式可以提供自己的放置方案。
檔案系統驅動程式可以提供自己的放置方案,該方案將代替預設放置方案使用。
放置方案由 nand_oobinfo 結構定義
struct nand_oobinfo {
int useecc;
int eccbytes;
int eccpos[24];
int oobfree[8][2];
};
useecc
useecc 成員控制 ecc 和放置函式。標頭檔案 include/mtd/mtd-abi.h 包含用於選擇 ecc 和放置的常量。MTD_NANDECC_OFF 完全關閉 ecc。不建議這樣做,僅可用於測試和診斷。MTD_NANDECC_PLACE 選擇呼叫方定義的放置,MTD_NANDECC_AUTOPLACE 選擇自動放置。
eccbytes
eccbytes 成員定義每頁的 ecc 位元組數。
eccpos
eccpos 陣列儲存備用區域中放置 ecc 程式碼的位元組偏移量。
oobfree
oobfree 陣列定義備用區域中可用於自動放置的區域。該資訊以 {offset, size} 格式給出。offset 定義了可用區域的開始,size 定義了以位元組為單位的長度。可以定義多個區域。該列表以 {0, 0} 條目終止。
由 fs 驅動程式定義的放置¶
呼叫函式提供指向定義 ecc 放置的 nand_oobinfo 結構的指標。對於寫入,呼叫方必須提供備用區域緩衝區以及資料緩衝區。備用區域緩衝區大小為(頁數)*(備用區域的大小)。對於讀取,緩衝區大小為(頁數)*((備用區域的大小)+(每頁的 ecc 步驟數)* sizeof (int))。驅動程式將每個元組的 ecc 檢查結果儲存在備用緩衝區中。儲存順序是
<spare data page 0><ecc result 0>...<ecc result n>
...
<spare data page n><ecc result 0>...<ecc result n>
這是 YAFFS1 使用的傳統模式。
如果備用區域緩衝區為 NULL,則僅根據 nand_oobinfo 結構中給定的方案進行 ECC 放置。
自動放置¶
自動放置使用內建預設值將 ecc 位元組放置在備用區域中。如果必須將檔案系統資料儲存/讀取到備用區域中,則呼叫函式必須提供緩衝區。每頁的緩衝區大小由 nand_oobinfo 結構中的 oobfree 陣列確定。
如果備用區域緩衝區為 NULL,則僅根據預設的內建方案進行 ECC 放置。
備用區域自動放置預設方案¶
256 位元組頁大小¶
偏移量 |
內容 |
評論 |
|---|---|---|
0x00 |
ECC 位元組 0 |
錯誤糾正程式碼位元組 0 |
0x01 |
ECC 位元組 1 |
錯誤糾正程式碼位元組 1 |
0x02 |
ECC 位元組 2 |
錯誤糾正程式碼位元組 2 |
0x03 |
自動放置 0 |
|
0x04 |
自動放置 1 |
|
0x05 |
壞塊標記 |
如果此位元組中的任何位為零,則此塊為壞塊。這僅適用於塊中的第一頁。在剩餘的頁面中,此位元組保留 |
0x06 |
自動放置 2 |
|
0x07 |
自動放置 3 |
512 位元組頁大小¶
偏移量 |
內容 |
評論 |
|---|---|---|
0x00 |
ECC 位元組 0 |
此頁中較低 256 位元組資料的錯誤糾正程式碼位元組 0 |
0x01 |
ECC 位元組 1 |
此頁中較低 256 位元組資料的錯誤糾正程式碼位元組 1 |
0x02 |
ECC 位元組 2 |
此頁中較低 256 位元組資料的錯誤糾正程式碼位元組 2 |
0x03 |
ECC 位元組 3 |
此頁中較高 256 位元組資料的錯誤糾正程式碼位元組 0 |
0x04 |
已保留 |
已保留 |
0x05 |
壞塊標記 |
如果此位元組中的任何位為零,則此塊為壞塊。這僅適用於塊中的第一頁。在剩餘的頁面中,此位元組保留 |
0x06 |
ECC 位元組 4 |
此頁資料中上面 256 位元組資料的糾錯碼位元組 1 |
0x07 |
ECC 位元組 5 |
此頁資料中上面 256 位元組資料的糾錯碼位元組 2 |
0x08 - 0x0F |
自動放置 0 - 7 |
2048 位元組頁大小¶
偏移量 |
內容 |
評論 |
|---|---|---|
0x00 |
壞塊標記 |
如果此位元組中的任何位為零,則此塊為壞塊。這僅適用於塊中的第一頁。在剩餘的頁面中,此位元組保留 |
0x01 |
保留 |
保留 |
0x02-0x27 |
自動放置 0 - 37 |
|
0x28 |
ECC 位元組 0 |
此頁第一個 256 位元組資料的糾錯碼位元組 0 |
0x29 |
ECC 位元組 1 |
此頁第一個 256 位元組資料的糾錯碼位元組 1 |
0x2A |
ECC 位元組 2 |
此頁第一個 256 位元組資料的糾錯碼位元組 2 |
0x2B |
ECC 位元組 3 |
此頁第二個 256 位元組資料的糾錯碼位元組 0 |
0x2C |
ECC 位元組 4 |
此頁第二個 256 位元組資料的糾錯碼位元組 1 |
0x2D |
ECC 位元組 5 |
此頁第二個 256 位元組資料的糾錯碼位元組 2 |
0x2E |
ECC 位元組 6 |
此頁第三個 256 位元組資料的糾錯碼位元組 0 |
0x2F |
ECC 位元組 7 |
此頁第三個 256 位元組資料的糾錯碼位元組 1 |
0x30 |
ECC 位元組 8 |
此頁第三個 256 位元組資料的糾錯碼位元組 2 |
0x31 |
ECC 位元組 9 |
此頁第四個 256 位元組資料的糾錯碼位元組 0 |
0x32 |
ECC 位元組 10 |
此頁第四個 256 位元組資料的糾錯碼位元組 1 |
0x33 |
ECC 位元組 11 |
此頁第四個 256 位元組資料的糾錯碼位元組 2 |
0x34 |
ECC 位元組 12 |
此頁第五個 256 位元組資料的糾錯碼位元組 0 |
0x35 |
ECC 位元組 13 |
此頁第五個 256 位元組資料的糾錯碼位元組 1 |
0x36 |
ECC 位元組 14 |
此頁第五個 256 位元組資料的糾錯碼位元組 2 |
0x37 |
ECC 位元組 15 |
此頁第六個 256 位元組資料的糾錯碼位元組 0 |
0x38 |
ECC 位元組 16 |
此頁第六個 256 位元組資料的糾錯碼位元組 1 |
0x39 |
ECC 位元組 17 |
此頁第六個 256 位元組資料的糾錯碼位元組 2 |
0x3A |
ECC 位元組 18 |
此頁第七個 256 位元組資料的糾錯碼位元組 0 |
0x3B |
ECC 位元組 19 |
此頁第七個 256 位元組資料的糾錯碼位元組 1 |
0x3C |
ECC 位元組 20 |
此頁第七個 256 位元組資料的糾錯碼位元組 2 |
0x3D |
ECC 位元組 21 |
此頁第八個 256 位元組資料的糾錯碼位元組 0 |
0x3E |
ECC 位元組 22 |
此頁第八個 256 位元組資料的糾錯碼位元組 1 |
0x3F |
ECC 位元組 23 |
此頁第八個 256 位元組資料的糾錯碼位元組 2 |
檔案系統支援¶
NAND 驅動程式透過 MTD 介面提供檔案系統所需的所有功能。
檔案系統必須瞭解 NAND 的特性和限制。 NAND 快閃記憶體的一個主要限制是,您不能像您希望的那樣頻繁地寫入頁面。在再次擦除頁面之前,對頁面的連續寫入限制為 1-3 次寫入,具體取決於製造商的規格。這同樣適用於備用區域。
因此,NAND 感知檔案系統必須以頁面大小的塊寫入,或者儲存一個寫緩衝區來收集較小的寫入,直到它們加起來達到頁面大小。可用的 NAND 感知檔案系統:JFFS2、YAFFS。
用於儲存檔案系統資料的備用區域使用由備用區域放置功能控制,該功能在前面的章節中進行了描述。
工具¶
MTD 專案提供了一些有用的工具來處理 NAND 快閃記憶體。
flasherase、flasheraseall:擦除和格式化 FLASH 分割槽
nandwrite:將檔案系統映像寫入 NAND FLASH
nanddump:轉儲 NAND FLASH 分割槽的內容
這些工具瞭解 NAND 的限制。請使用這些工具,而不是抱怨由非 NAND 感知訪問方法引起的錯誤。
常量¶
本章介紹可能與驅動程式開發人員相關的常量。
晶片選項常量¶
晶片 ID 表的常量¶
這些常量在 rawnand.h 中定義。它們被 OR 在一起以描述晶片功能
/* Buswitdh is 16 bit */
#define NAND_BUSWIDTH_16 0x00000002
/* Device supports partial programming without padding */
#define NAND_NO_PADDING 0x00000004
/* Chip has cache program function */
#define NAND_CACHEPRG 0x00000008
/* Chip has copy back function */
#define NAND_COPYBACK 0x00000010
/* AND Chip which has 4 banks and a confusing page / block
* assignment. See Renesas datasheet for further information */
#define NAND_IS_AND 0x00000020
/* Chip has a array of 4 pages which can be read without
* additional ready /busy waits */
#define NAND_4PAGE_ARRAY 0x00000040
執行時選項的常量¶
這些常量在 rawnand.h 中定義。它們被 OR 在一起以描述功能
/* The hw ecc generator provides a syndrome instead a ecc value on read
* This can only work if we have the ecc bytes directly behind the
* data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
#define NAND_HWECC_SYNDROME 0x00020000
ECC 選擇常量¶
使用這些常量來選擇 ECC 演算法
/* No ECC. Usage is not recommended ! */
#define NAND_ECC_NONE 0
/* Software ECC 3 byte ECC per 256 Byte data */
#define NAND_ECC_SOFT 1
/* Hardware ECC 3 byte ECC per 256 Byte data */
#define NAND_ECC_HW3_256 2
/* Hardware ECC 3 byte ECC per 512 Byte data */
#define NAND_ECC_HW3_512 3
/* Hardware ECC 6 byte ECC per 512 Byte data */
#define NAND_ECC_HW6_512 4
/* Hardware ECC 8 byte ECC per 512 Byte data */
#define NAND_ECC_HW8_512 6
結構¶
本章包含 NAND 驅動程式中使用的結構並且可能與驅動程式開發人員相關的自動生成文件。每個結構成員都有一個簡短的描述,標記有 [XXX] 識別符號。有關說明,請參見“文件提示”一章。
-
struct nand_parameters¶
來自引數頁面的 NAND 通用引數
定義:
struct nand_parameters {
const char *model;
bool supports_set_get_features;
bool supports_read_cache;
unsigned long set_feature_list[BITS_TO_LONGS(ONFI_FEATURE_NUMBER)];
unsigned long get_feature_list[BITS_TO_LONGS(ONFI_FEATURE_NUMBER)];
struct onfi_params *onfi;
};
成員
model型號名稱
supports_set_get_featuresNAND 晶片支援設定/獲取特性
supports_read_cacheNAND 晶片支援讀取快取操作
set_feature_list可以設定的特性的點陣圖
get_feature_list可以獲取的特性的點陣圖
onfiONFI 特定引數
-
struct nand_id¶
NAND ID 結構
定義:
struct nand_id {
u8 data[NAND_MAX_ID_LEN];
int len;
};
成員
data包含 ID 位元組的緩衝區。
lenID 長度。
-
struct nand_ecc_step_info¶
ECC 引擎的 ECC 步資訊
定義:
struct nand_ecc_step_info {
int stepsize;
const int *strengths;
int nstrengths;
};
成員
stepsize每個 ECC 步的資料位元組數
strengths支援的強度陣列
nstrengths支援的強度數
-
struct nand_ecc_caps¶
ECC 引擎的功能
定義:
struct nand_ecc_caps {
const struct nand_ecc_step_info *stepinfos;
int nstepinfos;
int (*calc_ecc_bytes)(int step_size, int strength);
};
成員
stepinfosECC 步資訊陣列
nstepinfosECC 步資訊數
calc_ecc_bytes驅動程式的鉤子,用於計算每個步的 ECC 位元組數
-
struct nand_ecc_ctrl¶
ECC 的控制結構
定義:
struct nand_ecc_ctrl {
enum nand_ecc_engine_type engine_type;
enum nand_ecc_placement placement;
enum nand_ecc_algo algo;
int steps;
int size;
int bytes;
int total;
int strength;
int prepad;
int postpad;
unsigned int options;
u8 *calc_buf;
u8 *code_buf;
void (*hwctl)(struct nand_chip *chip, int mode);
int (*calculate)(struct nand_chip *chip, const uint8_t *dat, uint8_t *ecc_code);
int (*correct)(struct nand_chip *chip, uint8_t *dat, uint8_t *read_ecc, uint8_t *calc_ecc);
int (*read_page_raw)(struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
int (*write_page_raw)(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page);
int (*read_page)(struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
int (*read_subpage)(struct nand_chip *chip, uint32_t offs, uint32_t len, uint8_t *buf, int page);
int (*write_subpage)(struct nand_chip *chip, uint32_t offset,uint32_t data_len, const uint8_t *data_buf, int oob_required, int page);
int (*write_page)(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page);
int (*write_oob_raw)(struct nand_chip *chip, int page);
int (*read_oob_raw)(struct nand_chip *chip, int page);
int (*read_oob)(struct nand_chip *chip, int page);
int (*write_oob)(struct nand_chip *chip, int page);
};
成員
engine_typeECC 引擎型別
placementOOB 位元組放置
algoECC 演算法
steps每頁的 ECC 步數
size每個 ECC 步的資料位元組數
位元組每個步的 ECC 位元組數
total每頁的 ECC 位元組總數
strength每個 ECC 步可糾正的最大位數
prepad基於綜合症的 ECC 生成器的填充資訊
postpad基於綜合症的 ECC 生成器的填充資訊
optionsECC 特定選項(參見上面定義的 NAND_ECC_XXX 標誌)
calc_buf用於計算 ECC 的緩衝區,大小為 oobsize。
code_buf從快閃記憶體讀取的 ECC 緩衝區,大小為 oobsize。
hwctl用於控制硬體 ECC 生成器的函式。僅當硬體 ECC 可用時才必須提供
calculate用於 ECC 計算或從 ECC 硬體回讀的函式
correct用於 ECC 校正的函式,與 ECC 生成器(sw/hw)匹配。如果位翻轉的數量超過 ECC 強度,則應返回表示已校正位翻轉數量的正數,-EBADMSG;如果錯誤與校正沒有直接關係,則返回任何其他錯誤程式碼。如果返回 -EBADMSG,則應保持輸入緩衝區不變。
read_page_raw用於讀取沒有 ECC 的原始頁面的函式。此函式應隱藏 ECC 控制器使用的特定佈局,並始終返回連續的帶內和帶外資料,即使它們沒有連續儲存在 NAND 晶片上(例如,NAND_ECC_PLACEMENT_INTERLEAVED 交錯帶內和帶外資料)。
write_page_raw用於寫入沒有 ECC 的原始頁面的函式。此函式應隱藏 ECC 控制器使用的特定佈局,並將傳遞的資料視為連續的帶內和帶外資料。ECC 控制器負責進行適當的轉換以適應其特定佈局(例如,NAND_ECC_PLACEMENT_INTERLEAVED 交錯帶內和帶外資料)。
read_page用於根據 ECC 生成器要求讀取頁面的函式;返回任何單個 ECC 步中校正的最大位翻轉數,-EIO hw 錯誤
read_subpage用於讀取 ECC 覆蓋的頁面的部分的函式;返回與 read_page() 相同
write_subpage用於寫入 ECC 覆蓋的頁面的部分的函式。
write_page用於根據 ECC 生成器要求寫入頁面的函式。
write_oob_raw用於寫入沒有 ECC 的晶片 OOB 資料的函式
read_oob_raw用於讀取沒有 ECC 的晶片 OOB 資料的函式
read_oob用於讀取晶片 OOB 資料的函式
write_oob用於寫入晶片 OOB 資料的函式
-
struct nand_sdr_timings¶
SDR NAND 晶片時序
定義:
struct nand_sdr_timings {
u64 tBERS_max;
u32 tCCS_min;
u64 tPROG_max;
u64 tR_max;
u32 tALH_min;
u32 tADL_min;
u32 tALS_min;
u32 tAR_min;
u32 tCEA_max;
u32 tCEH_min;
u32 tCH_min;
u32 tCHZ_max;
u32 tCLH_min;
u32 tCLR_min;
u32 tCLS_min;
u32 tCOH_min;
u32 tCS_min;
u32 tDH_min;
u32 tDS_min;
u32 tFEAT_max;
u32 tIR_min;
u32 tITC_max;
u32 tRC_min;
u32 tREA_max;
u32 tREH_min;
u32 tRHOH_min;
u32 tRHW_min;
u32 tRHZ_max;
u32 tRLOH_min;
u32 tRP_min;
u32 tRR_min;
u64 tRST_max;
u32 tWB_max;
u32 tWC_min;
u32 tWH_min;
u32 tWHR_min;
u32 tWP_min;
u32 tWW_min;
};
成員
tBERS_max塊擦除時間
tCCS_min更改列設定時間
tPROG_max頁面程式設計時間
tR_max頁面讀取時間
tALH_minALE 保持時間
tADL_minALE 到資料載入時間
tALS_minALE 設定時間
tAR_minALE 到 RE# 延遲
tCEA_maxCE# 訪問時間
tCEH_minCE# 高電平保持時間
tCH_minCE# 保持時間
tCHZ_maxCE# 高電平到輸出高阻抗
tCLH_minCLE 保持時間
tCLR_minCLE 到 RE# 延遲
tCLS_minCLE 設定時間
tCOH_minCE# 高電平到輸出保持
tCS_minCE# 設定時間
tDH_min資料保持時間
tDS_min資料設定時間
tFEAT_max設定特性和獲取特性的繁忙時間
tIR_min輸出高阻抗到 RE# 低電平
tITC_max介面和時序模式更改時間
tRC_minRE# 週期時間
tREA_maxRE# 訪問時間
tREH_minRE# 高電平保持時間
tRHOH_minRE# 高電平到輸出保持
tRHW_minRE# 高電平到 WE# 低電平
tRHZ_maxRE# 高電平到輸出高阻抗
tRLOH_minRE# 低電平到輸出保持
tRP_minRE# 脈衝寬度
tRR_min就緒到 RE# 低電平(僅限資料)
tRST_max裝置重置時間,從 R/B# 的下降沿到 R/B# 的上升沿測量。
tWB_maxWE# 高電平到 SR[6] 低電平
tWC_minWE# 週期時間
tWH_minWE# 高電平保持時間
tWHR_minWE# 高電平到 RE# 低電平
tWP_minWE# 脈衝寬度
tWW_minWP# 轉換到 WE# 低電平
描述
此結構定義了 SDR NAND 晶片的時序要求。這些資訊可以在每個 NAND 資料表中找到,並且時序含義在 ONFI 規範中描述:https://media-www.micron.com/-/media/client/onfi/specs/onfi_3_1_spec.pdf(第 4.15 章時序引數)
所有這些時序都以皮秒錶示。
-
struct nand_nvddr_timings¶
NV-DDR NAND 晶片時序
定義:
struct nand_nvddr_timings {
u64 tBERS_max;
u32 tCCS_min;
u64 tPROG_max;
u64 tR_max;
u32 tAC_min;
u32 tAC_max;
u32 tADL_min;
u32 tCAD_min;
u32 tCAH_min;
u32 tCALH_min;
u32 tCALS_min;
u32 tCAS_min;
u32 tCEH_min;
u32 tCH_min;
u32 tCK_min;
u32 tCS_min;
u32 tDH_min;
u32 tDQSCK_min;
u32 tDQSCK_max;
u32 tDQSD_min;
u32 tDQSD_max;
u32 tDQSHZ_max;
u32 tDQSQ_max;
u32 tDS_min;
u32 tDSC_min;
u32 tFEAT_max;
u32 tITC_max;
u32 tQHS_max;
u32 tRHW_min;
u32 tRR_min;
u32 tRST_max;
u32 tWB_max;
u32 tWHR_min;
u32 tWRCK_min;
u32 tWW_min;
};
成員
tBERS_max塊擦除時間
tCCS_min更改列設定時間
tPROG_max頁面程式設計時間
tR_max頁面讀取時間
tAC_minDQ[7:0] 從 CLK 的訪問視窗
tAC_maxDQ[7:0] 從 CLK 的訪問視窗
tADL_minALE 到資料載入時間
tCAD_min命令、地址、資料延遲
tCAH_min命令/地址 DQ 保持時間
tCALH_minW/R_n、CLE 和 ALE 保持時間
tCALS_minW/R_n、CLE 和 ALE 設定時間
tCAS_min命令/地址 DQ 設定時間
tCEH_minCE# 高電平保持時間
tCH_minCE# 保持時間
tCK_min平均時鐘週期時間
tCS_minCE# 設定時間
tDH_min資料保持時間
tDQSCK_minDQS 從 CLK 的訪問視窗的開始
tDQSCK_maxDQS 從 CLK 的訪問視窗的結束
tDQSD_min最小 W/R_n 低電平到 DQS/DQ 由裝置驅動
tDQSD_max最大 W/R_n 低電平到 DQS/DQ 由裝置驅動
tDQSHZ_maxW/R_n 高電平到 DQS/DQ 由裝置三態
tDQSQ_maxDQS-DQ 傾斜,DQS 到最後一個 DQ 有效,每次訪問
tDS_min資料設定時間
tDSC_minDQS 週期時間
tFEAT_max設定特性和獲取特性的繁忙時間
tITC_max介面和時序模式更改時間
tQHS_max資料保持傾斜因子
tRHW_min資料輸出週期到命令、地址或資料輸入週期
tRR_min就緒到 RE# 低電平(僅限資料)
tRST_max裝置重置時間,從 R/B# 的下降沿到 R/B# 的上升沿測量。
tWB_maxWE# 高電平到 SR[6] 低電平
tWHR_minWE# 高電平到 RE# 低電平
tWRCK_minW/R_n 低電平到資料輸出週期
tWW_minWP# 轉換到 WE# 低電平
描述
此結構定義了 NV-DDR NAND 資料介面的時序要求。這些資訊可以在每個 NAND 資料表中找到,並且時序含義在 ONFI 規範中描述:https://media-www.micron.com/-/media/client/onfi/specs/onfi_4_1_gold.pdf(第 4.18.2 章 NV-DDR)
所有這些時序都以皮秒錶示。
-
enum nand_interface_type¶
NAND 介面型別
常量
NAND_SDR_IFACE單資料速率介面
NAND_NVDDR_IFACE雙資料速率介面
-
struct nand_interface_config¶
NAND 介面時序
定義:
struct nand_interface_config {
enum nand_interface_type type;
struct nand_timings {
unsigned int mode;
union {
struct nand_sdr_timings sdr;
struct nand_nvddr_timings nvddr;
};
} timings;
};
成員
type時序型別
timings時序資訊
timings.mode規範中定義的時序模式
{unnamed_union}anonymous
timings.sdr當 type 為
NAND_SDR_IFACE時使用它。timings.nvddr當 type 為
NAND_NVDDR_IFACE時使用它。
-
bool nand_interface_is_sdr(const struct nand_interface_config *conf)¶
獲取介面型別
引數
const struct nand_interface_config *conf資料介面
-
bool nand_interface_is_nvddr(const struct nand_interface_config *conf)¶
獲取介面型別
引數
const struct nand_interface_config *conf資料介面
-
const struct nand_sdr_timings *nand_get_sdr_timings(const struct nand_interface_config *conf)¶
從資料介面獲取 SDR 時序
引數
const struct nand_interface_config *conf資料介面
-
const struct nand_nvddr_timings *nand_get_nvddr_timings(const struct nand_interface_config *conf)¶
從資料介面獲取 NV-DDR 時序
引數
const struct nand_interface_config *conf資料介面
-
struct nand_op_cmd_instr¶
命令指令的定義
定義:
struct nand_op_cmd_instr {
u8 opcode;
};
成員
opcode在一個週期內發出的命令
-
struct nand_op_addr_instr¶
地址指令的定義
定義:
struct nand_op_addr_instr {
unsigned int naddrs;
const u8 *addrs;
};
成員
naddrsaddrs 陣列的長度
addrs包含要發出的地址週期的陣列
-
struct nand_op_data_instr¶
資料指令的定義
定義:
struct nand_op_data_instr {
unsigned int len;
union {
void *in;
const void *out;
} buf;
bool force_8bit;
};
成員
len要移動的資料位元組數
buf要填充的緩衝區
buf.in從 NAND 晶片讀取時要填充的緩衝區
buf.out寫入 NAND 晶片時要讀取的緩衝區
force_8bit強制 8 位訪問
描述
請注意,“in”和“out”與 ONFI 規範相反,並且是從控制器的角度來看的,因此“in”是從 NAND 晶片讀取,而“out”是寫入 NAND 晶片。
-
struct nand_op_waitrdy_instr¶
等待就緒指令的定義
定義:
struct nand_op_waitrdy_instr {
unsigned int timeout_ms;
};
成員
timeout_ms等待就緒/忙碌引腳的最長延遲時間,單位為毫秒
-
enum nand_op_instr_type¶
所有指令型別的定義
常量
NAND_OP_CMD_INSTR命令指令
NAND_OP_ADDR_INSTR地址指令
NAND_OP_DATA_IN_INSTR資料輸入指令
NAND_OP_DATA_OUT_INSTR資料輸出指令
NAND_OP_WAITRDY_INSTR等待就緒指令
-
struct nand_op_instr¶
指令物件
定義:
struct nand_op_instr {
enum nand_op_instr_type type;
union {
struct nand_op_cmd_instr cmd;
struct nand_op_addr_instr addr;
struct nand_op_data_instr data;
struct nand_op_waitrdy_instr waitrdy;
} ctx;
unsigned int delay_ns;
};
成員
type指令型別
ctx與指令關聯的額外資料。您必須使用取決於 type 的適當元素
ctx.cmd如果 type 是
NAND_OP_CMD_INSTR,則使用它ctx.addr如果 type 是
NAND_OP_ADDR_INSTR,則使用它ctx.data如果 type 是
NAND_OP_DATA_IN_INSTR或NAND_OP_DATA_OUT_INSTR,則使用它ctx.waitrdy如果 type 是
NAND_OP_WAITRDY_INSTR,則使用它delay_ns控制器在總線上發出指令後應應用的延遲。大多數現代控制器都具有內部時序控制邏輯,在這種情況下,控制器驅動程式可以忽略此欄位。
-
struct nand_subop¶
子操作
定義:
struct nand_subop {
unsigned int cs;
const struct nand_op_instr *instrs;
unsigned int ninstrs;
unsigned int first_instr_start_off;
unsigned int last_instr_end_off;
};
成員
cs要為此 NAND 子操作選擇的 CS 線
instrs指令陣列
ninstrsinstrs 陣列的長度
first_instr_start_off子操作的第一個指令的起始偏移量
last_instr_end_off子操作的最後一個指令的結束偏移量(不包括)
描述
first_instr_start_off 和 last_instr_end_off 都僅適用於資料或地址指令。
當 NAND 控制器無法按原樣處理操作時,解析器會將其拆分為子操作,這些子操作將傳遞給控制器驅動程式。
-
struct nand_op_parser_addr_constraints¶
地址指令的約束
定義:
struct nand_op_parser_addr_constraints {
unsigned int maxcycles;
};
成員
maxcycles控制器在單個步驟中可以發出的最大地址週期數
-
struct nand_op_parser_data_constraints¶
資料指令的約束
定義:
struct nand_op_parser_data_constraints {
unsigned int maxlen;
};
成員
maxlen控制器在單個步驟中可以處理的最大資料長度
-
struct nand_op_parser_pattern_elem¶
模式的一個元素
定義:
struct nand_op_parser_pattern_elem {
enum nand_op_instr_type type;
bool optional;
union {
struct nand_op_parser_addr_constraints addr;
struct nand_op_parser_data_constraints data;
} ctx;
};
成員
type指令型別
optional模式的這個元素是可選的還是強制的
ctx地址或資料約束
ctx.addr地址約束(週期數)
ctx.data資料約束(資料長度)
-
struct nand_op_parser_pattern¶
NAND 子操作模式描述符
定義:
struct nand_op_parser_pattern {
const struct nand_op_parser_pattern_elem *elems;
unsigned int nelems;
int (*exec)(struct nand_chip *chip, const struct nand_subop *subop);
};
成員
elems模式元素陣列
nelemselems 陣列中模式元素的數量
exec將發出子操作的函式
描述
模式是元素的列表,每個元素代表一個帶有其約束的指令。核心使用該模式本身將 NAND 晶片操作與 NAND 控制器操作進行匹配。一旦找到 NAND 控制器操作模式與 NAND 晶片操作(或 NAND 操作的子集)之間的匹配,就會呼叫 pattern ->exec() 鉤子,以便控制器驅動程式可以在總線上發出該操作。
控制器驅動程式應宣告儘可能多的它們支援的模式,並將此模式列表(藉助以下宏建立)傳遞給 nand_op_parser_exec_op() 輔助函式。
-
struct nand_op_parser¶
NAND 控制器操作解析器描述符
定義:
struct nand_op_parser {
const struct nand_op_parser_pattern *patterns;
unsigned int npatterns;
};
成員
patterns支援的模式陣列
npatternspatterns 陣列的長度
描述
解析器描述符只是一個支援的模式陣列,每次 nand_op_parser_exec_op() 嘗試執行 NAND 操作(或嘗試確定是否支援特定操作)時,它都會迭代該陣列。
值得一提的是,將按照宣告順序測試模式,並且將採用第一個匹配項,因此重要的是適當排序模式,以便將簡單/低效的模式放在列表的末尾。通常,這是放置單指令模式的地方。
-
struct nand_operation¶
NAND 操作描述符
定義:
struct nand_operation {
unsigned int cs;
bool deassert_wp;
const struct nand_op_instr *instrs;
unsigned int ninstrs;
};
成員
cs要為此 NAND 操作選擇的 CS 線
deassert_wp當操作需要取消斷言 WP 引腳時設定為 true(ERASE、PROG 等)
instrs要執行的指令陣列
ninstrsinstrs 陣列的長度
描述
將傳遞給 chip->exec_op() 的實際操作結構。
-
struct nand_controller_ops¶
控制器操作
定義:
struct nand_controller_ops {
int (*attach_chip)(struct nand_chip *chip);
void (*detach_chip)(struct nand_chip *chip);
int (*exec_op)(struct nand_chip *chip,const struct nand_operation *op, bool check_only);
int (*setup_interface)(struct nand_chip *chip, int chipnr, const struct nand_interface_config *conf);
};
成員
attach_chip在快閃記憶體 ID 和 MTD 欄位(例如擦除大小、頁面大小和 OOB 大小)設定完畢後,在 NAND 檢測階段之後呼叫此方法。如果 NAND 晶片或裝置樹提供,則 ECC 要求可用。通常用於選擇適當的 ECC 配置並分配關聯的資源。此鉤子是可選的。
detach_chip釋放 nand_controller_ops->attach_chip() 中分配/宣告的所有資源。此鉤子是可選的。
exec_op執行 NAND 操作的控制器特定方法。此方法替換 chip->legacy.cmdfunc()、chip->legacy.{read,write}_{buf,byte,word}()、chip->legacy.dev_ready() 和 chip->legacy.waitfunc()。
setup_interface設定資料介面和時序。如果 chipnr 設定為
NAND_DATA_IFACE_CHECK_ONLY,則表示不應應用配置,而僅應檢查配置。此鉤子是可選的。
-
struct nand_controller¶
用於描述 NAND 控制器的結構
定義:
struct nand_controller {
struct mutex lock;
const struct nand_controller_ops *ops;
struct {
unsigned int data_only_read: 1;
unsigned int cont_read: 1;
} supported_op;
bool controller_wp;
};
成員
lock用於序列化對 NAND 控制器的訪問的鎖
opsNAND 控制器操作。
supported_opNAND 控制器已知支援的操作,僅在初始檢查後可由核心寫入。
supported_op.data_only_read控制器支援從匯流排讀取更多資料,而無需重新啟動整個讀取操作或更改列。
supported_op.cont_read控制器支援順序快取讀取。
controller_wp控制器負責處理 WP 引腳。
-
struct nand_legacy¶
NAND 晶片傳統欄位/鉤子
定義:
struct nand_legacy {
void __iomem *IO_ADDR_R;
void __iomem *IO_ADDR_W;
void (*select_chip)(struct nand_chip *chip, int cs);
u8 (*read_byte)(struct nand_chip *chip);
void (*write_byte)(struct nand_chip *chip, u8 byte);
void (*write_buf)(struct nand_chip *chip, const u8 *buf, int len);
void (*read_buf)(struct nand_chip *chip, u8 *buf, int len);
void (*cmd_ctrl)(struct nand_chip *chip, int dat, unsigned int ctrl);
void (*cmdfunc)(struct nand_chip *chip, unsigned command, int column, int page_addr);
int (*dev_ready)(struct nand_chip *chip);
int (*waitfunc)(struct nand_chip *chip);
int (*block_bad)(struct nand_chip *chip, loff_t ofs);
int (*block_markbad)(struct nand_chip *chip, loff_t ofs);
int (*set_features)(struct nand_chip *chip, int feature_addr, u8 *subfeature_para);
int (*get_features)(struct nand_chip *chip, int feature_addr, u8 *subfeature_para);
int chip_delay;
struct nand_controller dummy_controller;
};
成員
IO_ADDR_R讀取快閃記憶體裝置的 8 條 I/O 線的地址
IO_ADDR_W寫入快閃記憶體裝置的 8 條 I/O 線的地址
select_chip選擇/取消選擇特定的目標/裸片
read_byte從晶片讀取一個位元組
write_byte在低 8 條 I/O 線上向晶片寫入單個位元組
write_buf將資料從緩衝區寫入晶片
read_buf將資料從晶片讀取到緩衝區
cmd_ctrl用於控制 ALE/CLE/nCE 的硬體特定函式。也用於寫入命令和地址
cmdfunc用於將命令寫入晶片的硬體特定函式。
dev_ready用於訪問裝置就緒/忙碌線的硬體特定函式。如果設定為 NULL,則無法訪問就緒/忙碌,並且就緒/忙碌資訊從晶片狀態暫存器讀取。
waitfunc用於等待就緒的硬體特定函式。
block_bad使用 OOB 標記檢查塊是否損壞
block_markbad將塊標記為壞塊
set_features設定 NAND 晶片特性
get_features獲取 NAND 晶片特性
chip_delay晶片相關的延遲,用於將資料從陣列傳輸到讀取暫存器 (tR)。
dummy_controller僅可控制單個晶片的驅動程式的虛擬控制器實現
描述
如果您檢視此結構,您已經錯了。這些欄位/鉤子都已棄用。
-
struct nand_chip_ops¶
NAND 晶片操作
定義:
struct nand_chip_ops {
int (*suspend)(struct nand_chip *chip);
void (*resume)(struct nand_chip *chip);
int (*lock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len);
int (*unlock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len);
int (*setup_read_retry)(struct nand_chip *chip, int retry_mode);
int (*choose_interface_config)(struct nand_chip *chip, struct nand_interface_config *iface);
};
成員
suspend掛起操作
resume恢復操作
lock_area鎖定操作
unlock_area解鎖操作
setup_read_retry設定讀取重試模式(主要用於 MLC NAND)
choose_interface_config選擇最佳介面配置
-
struct nand_manufacturer¶
NAND 製造商結構
定義:
struct nand_manufacturer {
const struct nand_manufacturer_desc *desc;
void *priv;
};
成員
desc製造商描述
priv製造商驅動程式的私有資訊
-
struct nand_secure_region¶
NAND 安全區域結構
定義:
struct nand_secure_region {
u64 offset;
u64 size;
};
成員
offset安全區域起點的偏移量
size安全區域的大小
-
struct nand_chip¶
NAND 私有快閃記憶體晶片資料
定義:
struct nand_chip {
struct nand_device base;
struct nand_id id;
struct nand_parameters parameters;
struct nand_manufacturer manufacturer;
struct nand_chip_ops ops;
struct nand_legacy legacy;
unsigned int options;
const struct nand_interface_config *current_interface_config;
struct nand_interface_config *best_interface_config;
unsigned int bbt_erase_shift;
unsigned int bbt_options;
unsigned int badblockpos;
unsigned int badblockbits;
struct nand_bbt_descr *bbt_td;
struct nand_bbt_descr *bbt_md;
struct nand_bbt_descr *badblock_pattern;
u8 *bbt;
unsigned int page_shift;
unsigned int phys_erase_shift;
unsigned int chip_shift;
unsigned int pagemask;
unsigned int subpagesize;
u8 *data_buf;
u8 *oob_poi;
struct {
unsigned int bitflips;
int page;
} pagecache;
unsigned long buf_align;
struct mutex lock;
unsigned int suspended : 1;
wait_queue_head_t resume_wq;
int cur_cs;
int read_retries;
struct nand_secure_region *secure_regions;
u8 nr_secure_regions;
struct {
bool ongoing;
unsigned int first_page;
unsigned int pause_page;
unsigned int last_page;
} cont_read;
struct nand_controller *controller;
struct nand_ecc_ctrl ecc;
void *priv;
};
成員
base從通用 NAND 裝置繼承
id儲存 NAND ID
parameters以易於閱讀的形式儲存通用引數
manufacturer製造商資訊
opsNAND 晶片操作
legacy所有傳統欄位/鉤子。如果您開發新的驅動程式,請甚至不要嘗試使用這些欄位/鉤子中的任何一個,並且如果您正在修改使用這些欄位/鉤子的現有驅動程式,則應考慮重新設計驅動程式並避免使用它們。
options各種晶片選項。它們可以部分設定為通知 nand_scan 特殊功能。有關進一步說明,請參見定義。
current_interface_config當前使用的 NAND 介面配置
best_interface_config最適合 NAND 晶片和 NAND 控制器約束的最佳 NAND 介面配置。如果未設定,則必須使用預設的重置介面配置。
bbt_erase_shiftbbt 條目中的地址位數
bbt_options壞塊表特定選項。此處使用的所有選項都必須來自 bbm.h。預設情況下,這些選項將複製到適當的 nand_bbt_descr 中。
badblockposoob 區域中的壞塊標記位置
badblockbits好塊的壞塊標記位置中的最小設定位數;即,當 badblockbits = 7 時,BBM = 11110111b 是好塊
bbt_td用於快閃記憶體查詢的壞塊表描述符
bbt_md壞塊表映象描述符
badblock_pattern用於初始壞塊掃描的壞塊掃描模式
bbt壞塊表指標
page_shift頁面中的地址位數(列地址位數)
phys_erase_shift物理擦除塊中的地址位數
chip_shift一個晶片中的地址位數
pagemask頁面號掩碼 = (頁面數 / 晶片數) - 1
subpagesize儲存子頁面大小
data_buf用於資料的緩衝區,大小為 (頁面大小 + oobsize)
oob_poidata_buf 覆蓋的 OOB 區域上的指標
pagecache包含頁面快取相關欄位的結構
pagecache.bitflips快取頁面的位翻轉數
pagecache.page當前在快取中的頁面號。-1 表示當前未快取任何頁面
buf_align平臺所需的最小緩衝區對齊
lock保護掛起欄位的鎖。也用於序列化對 NAND 裝置的訪問
suspended當裝置掛起時設定為 1,未掛起時設定為 0
resume_wq如果 rawnand 處於掛起狀態,則等待睡眠的佇列。
cur_cs當前選定的目標。-1 表示未選擇任何目標,否則我們應始終具有 cur_cs >= 0 && cur_cs < nanddev_ntargets()。NAND 控制器驅動程式不應修改此值,但允許讀取該值。
read_retries支援的讀取重試模式的數量
secure_regions包含安全區域資訊的結構
nr_secure_regions安全區域的數量
cont_read順序頁面讀取內部
cont_read.ongoing是否正在進行連續讀取
cont_read.first_page連續讀取操作的開始
cont_read.pause_page當前順序快取讀取操作的結束
cont_read.last_page連續讀取操作的結束
controller在多個獨立裝置之間共享的硬體控制器結構
eccECC 控制器結構
priv晶片私有資料
-
const struct nand_interface_config *nand_get_interface_config(struct nand_chip *chip)¶
獲取 NAND 晶片的當前介面配置
引數
struct nand_chip *chipNAND 晶片
-
struct nand_flash_dev¶
NAND Flash 裝置 ID 結構體
定義:
struct nand_flash_dev {
char *name;
union {
struct {
uint8_t mfr_id;
uint8_t dev_id;
};
uint8_t id[NAND_MAX_ID_LEN];
};
unsigned int pagesize;
unsigned int chipsize;
unsigned int erasesize;
unsigned int options;
uint16_t id_len;
uint16_t oobsize;
struct {
uint16_t strength_ds;
uint16_t step_ds;
} ecc;
};
成員
nameNAND 晶片的可讀名稱
{unnamed_union}anonymous
{unnamed_struct}anonymous
mfr_id完整晶片 ID 陣列的製造商 ID 部分 (指向與
id[0]相同的記憶體地址)dev_id完整晶片 ID 陣列的裝置 ID 部分 (指向與
id[1]相同的記憶體地址)id完整裝置 ID 陣列
pagesizeNAND 頁的大小,單位為位元組;如果為 0,則實際頁大小(以及擦除塊大小)將從擴充套件 NAND 晶片 ID 陣列中確定
chipsize總晶片大小,單位為 MiB
erasesize擦除塊大小,單位為位元組 (如果為 0,則從擴充套件 ID 確定)
options儲存各種晶片位選項
id_lenid 的有效長度。
oobsizeOOB 大小
ecc來自資料手冊的 ECC 糾錯能力和步長資訊。
ecc.strength_ds來自資料手冊的 ECC 糾錯能力,與 nand_chip{} 中的 ecc_strength_ds 相同。
ecc.step_dsecc.strength_ds 所需的 ECC 步長,與 nand_chip{} 中的 ecc_step_ds 相同,也來自資料手冊。例如,“每個 512Byte 的 4bit ECC”可以使用 NAND_ECC_INFO(4, 512) 設定。
-
int nand_opcode_8bits(unsigned int command)¶
檢查操作碼的地址是否僅應在低 8 位上傳送
引數
unsigned int command要檢查的操作碼
引數
struct nand_chip *chipNAND 晶片物件
描述
返回使快取無效後的預分配頁面緩衝區。驅動程式不希望分配自己的反彈緩衝區,但仍然需要用於特定操作(最常見的是僅讀取 OOB 資料)的緩衝區時,應使用此函式。
小心不要在寫入/write_oob 路徑中呼叫此函式,因為核心可能已將要寫入的資料放置在此緩衝區中。
返回
指向頁面快取緩衝區的指標
提供的公共函式¶
本章包含匯出的 NAND 核心 API 函式的自動生成文件。每個函式都有一個簡短的描述,標記有 [XXX] 識別符號。有關說明,請參見“文件提示”一章。
-
void nand_extract_bits(u8 *dst, unsigned int dst_off, const u8 *src, unsigned int src_off, unsigned int nbits)¶
將未對齊的位從一個緩衝區複製到另一個緩衝區
引數
u8 *dst目標緩衝區
unsigned int dst_off寫入開始的位偏移量
const u8 *src源緩衝區
unsigned int src_off讀取開始的位偏移量
unsigned int nbits要從 src 複製到 dst 的位數
描述
將位從一個記憶體區域複製到另一個記憶體區域(允許重疊)。
引數
struct nand_chip *chipNAND 晶片物件
unsigned int cs要選擇的 CS 線。請注意,此 CS id 始終來自晶片 PoV,而不是控制器 PoV
描述
選擇一個 NAND 目標,以便在 chip 上執行的進一步操作將轉到所選的 NAND 目標。
引數
struct nand_chip *chipNAND 晶片物件
描述
取消選擇當前選擇的 NAND 目標。取消選擇目標後,在 chip 上執行的操作的結果未定義。
-
int nand_soft_waitrdy(struct nand_chip *chip, unsigned long timeout_ms)¶
輪詢 STATUS 暫存器,直到 RDY 位設定為 1
引數
struct nand_chip *chipNAND 晶片結構體
unsigned long timeout_ms超時時間,單位為毫秒
描述
使用 ->exec_op() 輪詢 STATUS 暫存器,直到 RDY 位變為 1。如果在指定的超時時間內未發生這種情況,則返回 -ETIMEDOUT。
當控制器無法訪問 NAND R/B 引腳時,應使用此輔助函式。
請注意,從 ->exec_op() 實現中呼叫此輔助函式意味著 ->exec_op() 必須是可重入的。
如果 NAND 晶片已準備就緒,則返回 0,否則返回負錯誤。
-
int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, unsigned long timeout_ms)¶
輪詢 R/B GPIO 引腳直到就緒
引數
struct nand_chip *chipNAND 晶片結構體
struct gpio_desc *gpiodR/B 引腳的 GPIO 描述符
unsigned long timeout_ms超時時間,單位為毫秒
描述
輪詢 R/B GPIO 引腳,直到它變為就緒。如果在指定的超時時間內未發生這種情況,則返回 -ETIMEDOUT。
當控制器可以透過 GPIO 訪問 NAND R/B 引腳時,應使用此輔助函式。
如果 R/B 引腳指示晶片已準備好,則返回 0,否則返回負錯誤。
-
int nand_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len)¶
執行 READ PAGE 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int page要讀取的頁
unsigned int offset_in_page頁面內的偏移量
void *buf用於儲存資料的緩衝區
unsigned int len緩衝區長度
描述
此函式發出 READ PAGE 操作。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_change_read_column_op(struct nand_chip *chip, unsigned int offset_in_page, void *buf, unsigned int len, bool force_8bit)¶
執行 CHANGE READ COLUMN 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int offset_in_page頁面內的偏移量
void *buf用於儲存資料的緩衝區
unsigned int len緩衝區長度
bool force_8bit強制 8 位匯流排訪問
描述
此函式發出 CHANGE READ COLUMN 操作。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_read_oob_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_oob, void *buf, unsigned int len)¶
執行 READ OOB 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int page要讀取的頁
unsigned int offset_in_oobOOB 區域內的偏移量
void *buf用於儲存資料的緩衝區
unsigned int len緩衝區長度
描述
此函式發出 READ OOB 操作。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_prog_page_begin_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len)¶
開始 PROG PAGE 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int page要寫入的頁
unsigned int offset_in_page頁面內的偏移量
const void *buf包含要寫入頁面的資料的緩衝區
unsigned int len緩衝區長度
描述
此函式發出 PROG PAGE 操作的前半部分。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
描述
此函式發出 PROG PAGE 操作的後半部分。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_prog_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, const void *buf, unsigned int len)¶
執行完整的 PROG PAGE 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int page要寫入的頁
unsigned int offset_in_page頁面內的偏移量
const void *buf包含要寫入頁面的資料的緩衝區
unsigned int len緩衝區長度
描述
此函式發出完整的 PROG PAGE 操作。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_change_write_column_op(struct nand_chip *chip, unsigned int offset_in_page, const void *buf, unsigned int len, bool force_8bit)¶
執行 CHANGE WRITE COLUMN 操作
引數
struct nand_chip *chipNAND 晶片
unsigned int offset_in_page頁面內的偏移量
const void *buf包含要傳送到 NAND 的資料的緩衝區
unsigned int len緩衝區長度
bool force_8bit強制 8 位匯流排訪問
描述
此函式發出 CHANGE WRITE COLUMN 操作。此函式不會選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
u8 addr在READID命令之後要經過的地址週期數
void *buf用於儲存ID的緩衝區
unsigned int len緩衝區長度
描述
此函式傳送READID命令並讀取NAND返回的ID。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
u8 *status用於儲存NAND狀態的輸出變數
描述
此函式傳送STATUS命令並讀取NAND返回的狀態。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
描述
此函式傳送READ0命令以取消STATUS命令的效果,以避免僅讀取狀態,直到傳送新的讀取命令。
此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
unsigned int eraseblock要擦除的塊
描述
此函式傳送ERASE命令並等待NAND準備就緒後返回。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
描述
此函式傳送RESET命令並等待NAND準備就緒後返回。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, bool force_8bit, bool check_only)¶
從NAND讀取資料
引數
struct nand_chip *chipNAND 晶片
void *buf用於儲存資料的緩衝區
unsigned int len緩衝區長度
bool force_8bit強制 8 位匯流排訪問
bool check_only不實際執行命令,僅檢查控制器驅動程式是否支援它
描述
此函式在總線上執行原始資料讀取。通常在啟動另一個NAND操作(如nand_read_page_op())之後使用。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_write_data_op(struct nand_chip *chip, const void *buf, unsigned int len, bool force_8bit)¶
從NAND寫入資料
引數
struct nand_chip *chipNAND 晶片
const void *buf包含要在總線上傳送的資料的緩衝區
unsigned int len緩衝區長度
bool force_8bit強制 8 位匯流排訪問
描述
此函式在總線上執行原始資料寫入。通常在啟動另一個NAND操作(如nand_write_page_begin_op())之後使用。此函式不選擇/取消選擇CS線。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_op_parser_exec_op(struct nand_chip *chip, const struct nand_op_parser *parser, const struct nand_operation *op, bool check_only)¶
exec_op 解析器
引數
struct nand_chip *chipNAND晶片
const struct nand_op_parser *parser控制器驅動程式提供的模式描述
const struct nand_operation *op要定址的NAND操作
bool check_only如果為true,則該函式僅檢查是否可以處理 op,但不執行操作
描述
輔助函式,旨在簡化僅支援有限指令序列的NAND控制器驅動程式的整合。支援的序列在 parser 中描述,如果 check_only 設定為false,則框架負責將 op 分割為多個子操作,並將它們傳遞迴匹配模式的 ->exec() 回撥。
NAND控制器驅動程式應從其自身的 ->exec_op() 實現中呼叫此函式。
成功時返回0,否則返回負錯誤程式碼。失敗可能是由於不支援的操作(沒有支援的模式能夠處理請求的操作),或者是由匹配模式的 ->exec() 掛鉤返回的錯誤引起的。
-
unsigned int nand_subop_get_addr_start_off(const struct nand_subop *subop, unsigned int instr_idx)¶
獲取地址陣列中的起始偏移量
引數
const struct nand_subop *subop整個子操作
unsigned int instr_idx子操作內部指令的索引
描述
在驅動程式開發期間,人們可能會試圖直接使用地址指令的 ->addr.addrs 欄位。這是錯誤的,因為地址指令可能會被分割。
給定一個地址指令,返回要發出的第一個週期的偏移量。
-
unsigned int nand_subop_get_num_addr_cyc(const struct nand_subop *subop, unsigned int instr_idx)¶
獲取要斷言的剩餘地址週期數
引數
const struct nand_subop *subop整個子操作
unsigned int instr_idx子操作內部指令的索引
描述
在驅動程式開發期間,人們可能會試圖直接使用資料指令的 ->addr->naddrs 欄位。這是錯誤的,因為指令可能會被分割。
給定一個地址指令,返回要發出的地址週期數。
-
unsigned int nand_subop_get_data_start_off(const struct nand_subop *subop, unsigned int instr_idx)¶
獲取資料陣列中的起始偏移量
引數
const struct nand_subop *subop整個子操作
unsigned int instr_idx子操作內部指令的索引
描述
在驅動程式開發期間,人們可能會試圖直接使用資料指令的 ->data->buf.{in,out} 欄位。這是錯誤的,因為資料指令可能會被分割。
給定一個數據指令,返回要從其開始的偏移量。
-
unsigned int nand_subop_get_data_len(const struct nand_subop *subop, unsigned int instr_idx)¶
獲取要檢索的位元組數
引數
const struct nand_subop *subop整個子操作
unsigned int instr_idx子操作內部指令的索引
描述
在驅動程式開發期間,人們可能會試圖直接使用資料指令的 ->data->len 欄位。這是錯誤的,因為資料指令可能會被分割。
返回要傳送/接收的資料塊的長度。
引數
struct nand_chip *chipNAND 晶片
int chipnr內部晶片ID
描述
儲存時序資料結構,然後應用SDR時序模式0(有關詳細資訊,請參閱nand_reset_interface),執行重置操作,然後應用回先前的時序。
成功時返回 0,否則返回負錯誤程式碼。
-
int nand_check_erased_ecc_chunk(void *data, int datalen, void *ecc, int ecclen, void *extraoob, int extraooblen, int bitflips_threshold)¶
檢查ECC塊是否包含(幾乎)只有0xff資料
引數
void *data要測試的資料緩衝區
int datalen資料長度
void *eccECC緩衝區
int ecclenECC長度
void *extraoob額外的OOB緩衝區
int extraooblen額外的OOB長度
int bitflips_threshold最大位元翻轉數
描述
檢查資料緩衝區及其關聯的ECC和OOB資料是否僅包含0xff模式,這意味著底層區域已被擦除並且可以進行程式設計。bitflips_threshold指定在認為該區域未被擦除之前的最大位元翻轉數。
返回小於或等於bitflips_threshold的正位元翻轉數,或返回-ERROR_CODE表示超過閾值的位元翻轉數。如果成功,則傳遞的緩衝區將填充0xff。
注意
- 1/ ECC演算法適用於預定義的塊大小,這些塊大小通常
與NAND頁面大小不同。修復位元翻轉時,ECC引擎將報告每個塊的錯誤數,並且NAND核心基礎結構希望您返回整個頁面的最大位元翻轉數。這就是為什麼您應該始終在單個塊上使用此函式,而不是在整個頁面上使用此函式的原因。檢查每個塊後,應相應地更新max_bitflips值。
- 2/ 檢查擦除頁面中的位元翻轉時,您不僅應該檢查
有效負載資料,還應檢查其關聯的ECC資料,因為使用者可能已將幾乎所有位元都程式設計為1,但只有少數幾個。在這種情況下,我們不應將該塊視為已擦除,並且檢查ECC位元組可以防止這種情況發生。
- 3/ extraoob 引數是可選的,如果您的某些OOB
資料受ECC引擎保護,則應使用它。如果您支援子頁面並且想要將一些額外的OOB資料附加到ECC塊,也可以使用它。
-
int nand_read_page_raw(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
[內部] 讀取沒有ecc的原始頁面資料
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
不適用於使用特殊oob佈局的綜合症計算ECC控制器。
-
int nand_monolithic_read_page_raw(struct nand_chip *chip, u8 *buf, int oob_required, int page)¶
原始模式下的整體頁面讀取
引數
struct nand_chip *chipNAND晶片資訊結構
u8 *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
這是一個原始頁面讀取,即沒有任何錯誤檢測/糾正。整體意味著我們請求將所有相關資料(主資料加上最終的OOB)載入到NAND快取中,並在單個操作中透過匯流排傳送(從NAND晶片到NAND控制器)。這是nand_read_page_raw() 的替代方法,後者首先讀取主資料,如果也請求OOB資料,則在總線上讀取更多資料。
-
int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
硬體ECC頁面讀取,從OOB區域讀取ECC資料
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
用於大頁面晶片的硬體ECC,需要從OOB中提取ECC資料,然後再讀取實際資料。
引數
struct nand_chip *chipNAND晶片資訊結構
int page要讀取的頁碼
引數
struct nand_chip *chipNAND晶片資訊結構
int page要寫入的頁碼
-
int nand_write_page_raw(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)¶
[內部] 原始頁寫入函式
引數
struct nand_chip *chipNAND晶片資訊結構
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
描述
不適用於使用特殊oob佈局的綜合症計算ECC控制器。
-
int nand_monolithic_write_page_raw(struct nand_chip *chip, const u8 *buf, int oob_required, int page)¶
原始模式下的整體頁寫入
引數
struct nand_chip *chipNAND晶片資訊結構
const u8 *buf要寫入的資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
描述
這是一個原始頁寫入,即沒有任何錯誤檢測/糾正。 整體表示我們正在請求所有相關資料(主資料和最終OOB)透過匯流排傳送,並以單個操作有效地程式設計到NAND晶片陣列中。 這是nand_write_page_raw()的替代方案,它首先發送主資料,然後最終透過在NAND總線上鎖存更多資料週期來發送OOB資料,最後傳送程式命令以同步NAND晶片快取。
-
int rawnand_dt_parse_gpio_cs(struct device *dev, struct gpio_desc ***cs_array, unsigned int *ncs_array)¶
解析控制器的gpio-cs屬性
引數
struct device *dev將被解析的裝置。 也用於託管分配。
struct gpio_desc ***cs_array成功分配的GPIO描述符指標陣列
unsigned int *ncs_array成功更新的**cs_array**中的條目數。 **返回** 成功時返回0,否則返回錯誤。
-
int nand_ecc_choose_conf(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail)¶
設定ECC強度和ECC步長
引數
struct nand_chip *chipNAND晶片資訊結構
const struct nand_ecc_caps *capsECC引擎能力資訊結構
int oobavailECC引擎可以使用的OOB大小
描述
根據以下邏輯選擇ECC配置。
如果ECC步長和ECC強度都已設定(通常由DT設定),則檢查此控制器是否支援。
如果使用者提供了nand-ecc-maximize屬性,則選擇最大ECC強度。
否則,嘗試使ECC步長和ECC強度最接近晶片的要求。 如果可用的OOB大小不符合晶片的要求,則回退到最大ECC步長和ECC強度。
成功後,將設定所選的ECC設定。
-
int nand_scan_with_ids(struct nand_chip *chip, unsigned int maxchips, struct nand_flash_dev *ids)¶
[NAND介面] 掃描NAND裝置
引數
struct nand_chip *chipNAND 晶片物件
unsigned int maxchips要掃描的晶片數量。
struct nand_flash_dev *ids可選的Flash ID表
描述
這會用預設值填充所有未初始化的函式指標。 讀取Flash ID,並用適當的值填充mtd/chip結構。
引數
struct nand_chip *chipNAND 晶片物件
提供的內部函式¶
本章包含NAND驅動程式內部函式的自動生成文件。 每個函式都有一個簡短的描述,並標有[XXX]識別符號。 有關說明,請參見“文件提示”一章。 標有[DEFAULT]的函式可能與板驅動程式開發人員相關。
引數
struct nand_chip *chipNAND 晶片物件
描述
釋放晶片鎖並喚醒任何等待裝置的人。
引數
struct nand_chip *chipNAND 晶片物件
int page開始檢查壞塊標記使用的第一頁
描述
返回一個整數,該整數對應於塊內的頁偏移量,用於儲存壞塊標記的頁。 如果沒有更多頁面可用,則返回-EINVAL。
引數
struct nand_chip *chipNAND 晶片物件
loff_t ofs從裝置起始位置的偏移量
描述
檢查塊是否損壞。
引數
struct nand_chip *chipNAND 晶片物件
loff_t offset要檢查的區域的偏移量
u64 size要檢查的區域的大小
描述
透過將偏移量和大小與從DT獲得的受保護區域列表進行比較,來檢查該區域是否受保護。 如果該區域受保護,則返回true,否則返回false。
引數
struct nand_chip *chipNAND 晶片結構體
描述
鎖定裝置及其控制器以進行獨佔訪問
引數
struct nand_chip *chipNAND 晶片物件
描述
檢查裝置是否受到防寫。 該函式期望已選擇裝置。
-
uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, struct mtd_oob_ops *ops)¶
[內部] 將客戶端緩衝區傳輸到oob
引數
struct nand_chip *chipNAND 晶片物件
uint8_t *ooboob資料緩衝區
size_t lenoob資料寫入長度
struct mtd_oob_ops *opsoob ops結構
引數
struct nand_chip *chipNAND 晶片物件
loff_t to要寫入的偏移量
struct mtd_oob_ops *opsoob操作描述結構
描述
NAND寫入帶外。
引數
struct nand_chip *chipNAND 晶片物件
loff_t ofs從裝置起始位置的偏移量
描述
這是預設實現,可以由硬體特定的驅動程式覆蓋。 它提供了將壞塊標記寫入塊的詳細資訊。
引數
struct nand_chip *chipNAND 晶片物件
loff_t ofs要標記為壞塊的塊的偏移量
引數
struct nand_chip *chipNAND 晶片物件
loff_t ofs從裝置起始位置的偏移量
描述
此函式執行通用的NAND壞塊標記步驟(即,壞塊表和/或標記)。 我們只允許硬體驅動程式指定如何將壞塊標記寫入OOB(chip->legacy.block_markbad)。
我們按以下順序嘗試操作
擦除受影響的塊,以允許乾淨地寫入OOB標記
將壞塊標記寫入受影響塊的OOB區域(除非存在標誌NAND_BBT_NO_OOB_BBM)
更新BBT
請注意,我們保留在(2)或(3)中遇到的第一個錯誤,完成這些過程,並在最後轉儲該錯誤。
-
int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs)¶
[通用] 檢查塊是否標記為保留。
引數
struct mtd_info *mtdMTD裝置結構
loff_t ofs從裝置起始位置的偏移量
描述
檢查該塊是否標記為保留。
引數
struct nand_chip *chipNAND 晶片物件
loff_t ofs從裝置起始位置的偏移量
int allowbbt1,如果允許訪問 bbt 區域
描述
檢查塊是否損壞。可以透過讀取壞塊表或呼叫掃描函式來檢查。
引數
struct nand_chip *chipNAND 晶片結構體
unsigned long timeo超時
描述
等待命令完成。這是 nand_wait 的輔助函式,用於在中斷上下文中呼叫。當發生 panic 並嘗試透過 mtdoops 寫入 oops 時可能會發生這種情況。
引數
struct nand_chip *chipNAND 晶片
int chipnr內部晶片ID
描述
將資料介面和時序重置為 ONFI 模式 0。
成功返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
int chipnr內部晶片ID
描述
配置晶片和驅動程式報告的最佳資料介面和 NAND 時序。
成功返回 0,否則返回負錯誤程式碼。
-
int nand_choose_best_sdr_timings(struct nand_chip *chip, struct nand_interface_config *iface, struct nand_sdr_timings *spec_timings)¶
選擇 NAND 控制器和 NAND 晶片都支援的最佳 SDR 時序
引數
struct nand_chip *chipNAND晶片
struct nand_interface_config *iface介面配置(最終可以更新)
struct nand_sdr_timings *spec_timings特定時序,當不符合 ONFI 規範時
描述
如果提供了特定時序,則使用它們。否則,從 ONFI 資訊中檢索支援的時序模式。
-
int nand_choose_best_nvddr_timings(struct nand_chip *chip, struct nand_interface_config *iface, struct nand_nvddr_timings *spec_timings)¶
選擇 NAND 控制器和 NAND 晶片都支援的最佳 NVDDR 時序
引數
struct nand_chip *chipNAND晶片
struct nand_interface_config *iface介面配置(最終可以更新)
struct nand_nvddr_timings *spec_timings特定時序,當不符合 ONFI 規範時
描述
如果提供了特定時序,則使用它們。否則,從 ONFI 資訊中檢索支援的時序模式。
-
int nand_choose_best_timings(struct nand_chip *chip, struct nand_interface_config *iface)¶
選擇 NAND 控制器和 NAND 晶片都支援的最佳 NVDDR 或 SDR 時序
引數
struct nand_chip *chipNAND晶片
struct nand_interface_config *iface介面配置(最終可以更新)
描述
如果提供了特定時序,則使用它們。否則,從 ONFI 資訊中檢索支援的時序模式。
引數
struct nand_chip *chipNAND 晶片
描述
查詢晶片和驅動程式支援的最佳資料介面和 NAND 時序。最終讓 NAND 製造商驅動程式提出自己的時序集。
在此函式之後,nand_chip->interface_config 使用可用的最佳時序模式進行初始化。
成功返回 0,否則返回負錯誤程式碼。
-
int nand_fill_column_cycles(struct nand_chip *chip, u8 *addrs, unsigned int offset_in_page)¶
填充地址的列週期
引數
struct nand_chip *chipNAND 晶片
u8 *addrs要填充的地址週期數組
unsigned int offset_in_page頁內偏移量
描述
根據 NAND 匯流排寬度和頁面大小,填充 **addrs** 欄位的第一個或前兩個位元組。
返回編碼列所需的週期數,或者在其中一個引數無效的情況下返回負錯誤程式碼。
-
int nand_read_param_page_op(struct nand_chip *chip, u8 page, void *buf, unsigned int len)¶
執行 READ PARAMETER PAGE 操作
引數
struct nand_chip *chipNAND 晶片
u8 page要讀取的引數頁
void *buf用於儲存資料的緩衝區
unsigned int len緩衝區長度
描述
此函式發出 READ PARAMETER PAGE 操作。此函式不選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
u8 feature功能 ID
const void *data4 位元組資料
描述
此函式傳送 SET FEATURES 命令並等待 NAND 準備就緒後再返回。此函式不選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
引數
struct nand_chip *chipNAND 晶片
u8 feature功能 ID
void *data4 位元組資料
描述
此函式傳送 GET FEATURES 命令並等待 NAND 準備就緒後再返回。此函式不選擇/取消選擇 CS 線。
成功時返回 0,否則返回負錯誤程式碼。
-
struct nand_op_parser_ctx¶
解析器使用的上下文
定義:
struct nand_op_parser_ctx {
const struct nand_op_instr *instrs;
unsigned int ninstrs;
struct nand_subop subop;
};
成員
instrs必須定址的所有指令的陣列
ninstrsinstrs 陣列的長度
子操作要傳遞給 NAND 控制器的子操作
描述
核心使用此結構將 NAND 操作拆分為可由 NAND 控制器處理的子操作。
-
bool nand_op_parser_must_split_instr(const struct nand_op_parser_pattern_elem *pat, const struct nand_op_instr *instr, unsigned int *start_offset)¶
檢查是否必須拆分指令
引數
const struct nand_op_parser_pattern_elem *pat與 **instr** 匹配的解析器模式元素
const struct nand_op_instr *instr指向要檢查的指令的指標
unsigned int *start_offset這是一個輸入/輸出引數。如果 **instr** 已經被拆分,則 **start_offset** 是起始偏移量(地址週期或資料緩衝區中的偏移量)。相反,如果函式返回 true(即,必須拆分 instr),則此引數將更新為指向尚未處理的第一個資料/地址週期。
描述
某些 NAND 控制器受到限制,無法透過唯一操作傳送 X 地址週期,或者無法同時讀取/寫入超過 Y 位元組。在這種情況下,將不適合單個控制器操作的指令拆分為兩個或多個塊。
如果必須拆分指令,則返回 true,否則返回 false。**start_offset** 引數也會更新為下一組指令必須開始的偏移量(如果是地址或資料指令)。
-
bool nand_op_parser_match_pat(const struct nand_op_parser_pattern *pat, struct nand_op_parser_ctx *ctx)¶
檢查模式是否與解析器上下文中剩餘的指令匹配
引數
const struct nand_op_parser_pattern *pat要測試的模式
struct nand_op_parser_ctx *ctx要與模式 **pat** 匹配的解析器上下文結構
描述
檢查 **pat** 是否與 **ctx** 中剩餘的指令集或子集匹配。如果匹配,則返回 true,否則返回 false。當返回 true 時,**ctx->subop** 將更新為要傳遞給控制器驅動程式的指令集。
引數
struct nand_chip *chipNAND晶片資訊結構
int addr功能地址
u8 *subfeature_param子功能引數,一個四位元組陣列
描述
成功返回 0,否則返回負錯誤。如果操作無法處理,則返回 -ENOTSUPP。
引數
struct nand_chip *chipNAND晶片資訊結構
int addr功能地址
u8 *subfeature_param子功能引數,一個四位元組陣列
描述
成功返回 0,否則返回負錯誤。如果操作無法處理,則返回 -ENOTSUPP。
-
int nand_check_erased_buf(void *buf, int len, int bitflips_threshold)¶
檢查緩衝區是否包含(幾乎)只有 0xff 資料
引數
void *buf要測試的緩衝區
int len緩衝區長度
int bitflips_threshold最大位元翻轉數
描述
檢查緩衝區是否僅包含 0xff,這意味著底層區域已被擦除並準備好進行程式設計。bitflips_threshold 指定在認為該區域未擦除之前允許的最大位翻轉次數。返回一個小於或等於 bitflips_threshold 的正數位翻轉次數,或者返回 -ERROR_CODE 表示位翻轉超過閾值。
注意
此函式的邏輯是從 memweight 實現中提取的,只是 nand_check_erased_buf 函式會在位翻轉次數超過 bitflips_threshold 值時在測試整個緩衝區之前退出。
-
int nand_read_page_raw_notsupp(struct nand_chip *chip, u8 *buf, int oob_required, int page)¶
虛擬讀取原始頁面函式
引數
struct nand_chip *chipNAND晶片資訊結構
u8 *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
無條件地返回 -ENOTSUPP。
-
int nand_read_page_raw_syndrome(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
[內部] 讀取沒有ecc的原始頁面資料
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
即使未使用 OOB,我們也需要特殊的 oob 佈局和處理。
-
int nand_read_page_swecc(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
[可替換] 基於軟體 ECC 的頁面讀取函式
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
-
int nand_read_subpage(struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi, int page)¶
[可替換] 基於 ECC 的子頁面讀取函式
引數
struct nand_chip *chipNAND晶片資訊結構
uint32_t data_offs請求的資料在頁面內的偏移量
uint32_t readlen資料長度
uint8_t *bufpoi用於儲存讀取資料的緩衝區
int page要讀取的頁碼
-
int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
[可替換] 基於硬體 ECC 的頁面讀取函式
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
不適用於需要特殊 oob 佈局的 syndrome 計算 ECC 控制器。
-
int nand_read_page_syndrome(struct nand_chip *chip, uint8_t *buf, int oob_required, int page)¶
[可替換] 基於硬體 ECC 校驗位的頁面讀取
引數
struct nand_chip *chipNAND晶片資訊結構
uint8_t *buf用於儲存讀取資料的緩衝區
int oob_required呼叫者需要將OOB資料讀取到chip->oob_poi
int page要讀取的頁碼
描述
硬體生成器自動計算錯誤校驗位。因此,我們需要一個特殊的 oob 佈局和處理。
-
uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, struct mtd_oob_ops *ops, size_t len)¶
[內部] 將 oob 傳輸到客戶端緩衝區
引數
struct nand_chip *chipNAND 晶片物件
uint8_t *ooboob 目標地址
struct mtd_oob_ops *opsoob ops結構
size_t len要傳輸的 oob 的大小
引數
struct nand_chip *chipNAND 晶片物件
int retry_mode要使用的重試模式
描述
一些供應商提供了一個特殊命令來移動 Vt 閾值,當頁面中存在太多位翻轉時(即 ECC 錯誤)使用。設定新閾值後,主機應重試讀取頁面。
-
int nand_do_read_ops(struct nand_chip *chip, loff_t from, struct mtd_oob_ops *ops)¶
[內部] 使用 ECC 讀取資料
引數
struct nand_chip *chipNAND 晶片物件
loff_t from讀取的偏移量
struct mtd_oob_ops *opsoob ops結構
描述
內部函式。在持有 chip 的情況下呼叫。
引數
struct nand_chip *chipNAND晶片資訊結構
int page要讀取的頁碼
-
int nand_write_oob_syndrome(struct nand_chip *chip, int page)¶
[可替換] 用於帶有校驗位的 HW ECC 的 OOB 資料寫入函式 - 僅適用於大頁面快閃記憶體
引數
struct nand_chip *chipNAND晶片資訊結構
int page要寫入的頁碼
-
int nand_do_read_oob(struct nand_chip *chip, loff_t from, struct mtd_oob_ops *ops)¶
[內部] NAND 讀取帶外資料
引數
struct nand_chip *chipNAND 晶片物件
loff_t from讀取的偏移量
struct mtd_oob_ops *opsoob 操作描述結構
描述
從備用區域讀取 NAND 帶外資料。
-
int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)¶
[MTD 介面] NAND 讀取資料和/或帶外資料
引數
struct mtd_info *mtdMTD裝置結構
loff_t from讀取的偏移量
struct mtd_oob_ops *opsoob操作描述結構
描述
NAND 讀取資料和/或帶外資料。
-
int nand_write_page_raw_notsupp(struct nand_chip *chip, const u8 *buf, int oob_required, int page)¶
虛擬原始頁面寫入函式
引數
struct nand_chip *chipNAND晶片資訊結構
const u8 *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
描述
無條件地返回 -ENOTSUPP。
-
int nand_write_page_raw_syndrome(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)¶
[內部] 原始頁寫入函式
引數
struct nand_chip *chipNAND晶片資訊結構
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
描述
即使不檢查 ECC,我們也需要特殊的 oob 佈局和處理。
-
int nand_write_page_swecc(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)¶
[可替換] 基於軟體 ECC 的頁面寫入函式
引數
struct nand_chip *chipNAND晶片資訊結構
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
-
int nand_write_page_hwecc(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)¶
[可替換] 基於硬體 ECC 的頁面寫入函式
引數
struct nand_chip *chipNAND晶片資訊結構
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
-
int nand_write_subpage_hwecc(struct nand_chip *chip, uint32_t offset, uint32_t data_len, const uint8_t *buf, int oob_required, int page)¶
[可替換] 基於硬體 ECC 的子頁面寫入
引數
struct nand_chip *chipNAND晶片資訊結構
uint32_t offset頁面內子頁面的列地址
uint32_t data_len資料長度
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
-
int nand_write_page_syndrome(struct nand_chip *chip, const uint8_t *buf, int oob_required, int page)¶
[可替換] 基於硬體 ECC 校驗位的頁面寫入
引數
struct nand_chip *chipNAND晶片資訊結構
const uint8_t *buf資料緩衝區
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
描述
硬體生成器自動計算錯誤校驗位。因此,我們需要一個特殊的 oob 佈局和處理。
-
int nand_write_page(struct nand_chip *chip, uint32_t offset, int data_len, const uint8_t *buf, int oob_required, int page, int raw)¶
寫入一個頁面
引數
struct nand_chip *chipNAND 晶片描述符
uint32_t offset頁面內的地址偏移量
int data_len要寫入的實際資料的長度
const uint8_t *buf要寫入的資料
int oob_required必須將chip->oob_poi寫入到OOB
int page要寫入的頁碼
int raw使用 write_page 的 _raw 版本
-
int nand_do_write_ops(struct nand_chip *chip, loff_t to, struct mtd_oob_ops *ops)¶
[內部] 使用 ECC 寫入 NAND
引數
struct nand_chip *chipNAND 晶片物件
loff_t to要寫入的偏移量
struct mtd_oob_ops *opsoob 操作描述結構
描述
使用 ECC 寫入 NAND。
-
int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf)¶
[MTD 介面] 使用 ECC 寫入 NAND
引數
struct mtd_info *mtdMTD裝置結構
loff_t to要寫入的偏移量
size_t len要寫入的位元組數
size_t *retlen指向用於儲存寫入位元組數的變數的指標
const uint8_t *buf要寫入的資料
描述
使用 ECC 寫入 NAND。在中斷上下文中執行寫入時使用,例如,當在 panic 狀態下寫入 oops 時,可能會被 mtdoops 呼叫。
-
int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)¶
[MTD 介面] NAND 寫入資料和/或帶外資料
引數
struct mtd_info *mtdMTD裝置結構
loff_t to要寫入的偏移量
struct mtd_oob_ops *opsoob操作描述結構
-
int nand_erase(struct mtd_info *mtd, struct erase_info *instr)¶
[MTD 介面] 擦除塊
引數
struct mtd_info *mtdMTD裝置結構
struct erase_info *instr擦除指令
描述
擦除一個或多個塊。
引數
struct nand_chip *chipNAND 晶片物件
struct erase_info *instr擦除指令
int allowbbt允許擦除 bbt 區域
描述
擦除一個或多個塊。
-
void nand_sync(struct mtd_info *mtd)¶
[MTD 介面] 同步
引數
struct mtd_info *mtdMTD裝置結構
描述
同步實際上是一個等待晶片準備好的函式。
-
int nand_block_isbad(struct mtd_info *mtd, loff_t offs)¶
[MTD 介面] 檢查偏移量處的塊是否損壞
引數
struct mtd_info *mtdMTD裝置結構
loff_t offs相對於 MTD 起始位置的偏移量
-
int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)¶
[MTD 介面] 將給定偏移量處的塊標記為壞塊
引數
struct mtd_info *mtdMTD裝置結構
loff_t ofs相對於 MTD 起始位置的偏移量
-
int nand_suspend(struct mtd_info *mtd)¶
[MTD 介面] 掛起 NAND 快閃記憶體
引數
struct mtd_info *mtdMTD裝置結構
描述
成功返回 0,否則返回負錯誤程式碼。
-
void nand_resume(struct mtd_info *mtd)¶
[MTD 介面] 恢復 NAND 快閃記憶體
引數
struct mtd_info *mtdMTD裝置結構
-
void nand_shutdown(struct mtd_info *mtd)¶
[MTD 介面] 完成當前的 NAND 操作並阻止進一步的操作
引數
struct mtd_info *mtdMTD裝置結構
-
int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)¶
[MTD 介面] 鎖定 NAND 快閃記憶體
引數
struct mtd_info *mtdMTD裝置結構
loff_t ofs偏移位元組地址
uint64_t len要鎖定的位元組數(必須是塊/頁大小的倍數)
-
int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)¶
[MTD 介面] 解鎖 NAND 快閃記憶體
引數
struct mtd_info *mtdMTD裝置結構
loff_t ofs偏移位元組地址
uint64_t len要解鎖的位元組數(必須是塊/頁大小的倍數)
-
int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, struct nand_flash_dev *table)¶
掃描 NAND 裝置
引數
struct nand_chip *chipNAND 晶片物件
unsigned int maxchips要掃描的晶片數量
struct nand_flash_dev *table備用 NAND ID 表
描述
這是普通 nand_scan() 函式的第一階段。它讀取快閃記憶體 ID 並相應地設定 MTD 欄位。
這個輔助函式曾經直接從控制器驅動程式呼叫,這些驅動程式需要在 nand_scan_tail() 之前調整一些與 ECC 相關的引數。 這種分離阻止了在此階段進行動態分配,這很不方便,並且為了 ->init_ecc()/cleanup_ecc() 掛鉤的好處而被禁止。
-
int nand_check_ecc_caps(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail)¶
檢查預設 ECC 設定的合理性
引數
struct nand_chip *chipNAND晶片資訊結構
const struct nand_ecc_caps *capsECC 容量資訊結構
int oobavailECC引擎可以使用的OOB大小
描述
當 ECC 步長大小和強度已經設定時,檢查它們是否受控制器支援,並且計算出的 ECC 位元組是否適合晶片的 OOB。 成功後,設定計算出的 ECC 位元組。
-
int nand_match_ecc_req(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail)¶
以最少的 ECC 位元組滿足晶片的要求
引數
struct nand_chip *chipNAND晶片資訊結構
const struct nand_ecc_caps *capsECC引擎能力資訊結構
int oobavailECC引擎可以使用的OOB大小
描述
如果提供了晶片的 ECC 要求,請嘗試以最少的 ECC 位元組數(即,以最大數量的無 OOB 位元組)來滿足它。 成功後,將設定所選的 ECC 設定。
-
int nand_maximize_ecc(struct nand_chip *chip, const struct nand_ecc_caps *caps, int oobavail)¶
選擇可用的最大 ECC 強度
引數
struct nand_chip *chipNAND晶片資訊結構
const struct nand_ecc_caps *capsECC引擎能力資訊結構
int oobavailECC引擎可以使用的OOB大小
描述
選擇控制器上支援的並且可以容納在晶片 OOB 中的最大 ECC 強度。 成功後,將設定所選的 ECC 設定。
引數
struct nand_chip *chipNAND 晶片物件
描述
這是普通 nand_scan() 函式的第二階段。 它使用預設值填充所有未初始化的函式指標,並掃描壞塊表(如果適用)。
-
int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)¶
[通用] 檢查緩衝區中是否存在模式
引數
uint8_t *buf要搜尋的緩衝區
int len要搜尋的緩衝區的長度
int paglen頁長度
struct nand_bbt_descr *td搜尋模式描述符
描述
檢查給定位置是否存在模式。 用於搜尋壞塊表和好/壞塊識別符號。
-
int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)¶
[通用] 檢查緩衝區中是否存在模式
引數
uint8_t *buf要搜尋的緩衝區
struct nand_bbt_descr *td搜尋模式描述符
描述
檢查給定位置是否存在模式。 用於搜尋壞塊表和好/壞塊識別符號。 與 check_pattern 相同,但沒有可選的空檢查。
-
u32 add_marker_len(struct nand_bbt_descr *td)¶
計算資料區域中標記的長度
引數
struct nand_bbt_descr *td用於計算的 BBT 描述符
描述
如果標記位於 OOB 區域中,則長度將為 0。
-
int read_bbt(struct nand_chip *this, uint8_t *buf, int page, int num, struct nand_bbt_descr *td, int offs)¶
[通用] 從頁面開始讀取壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
int page起始頁面
int num要讀取的 bbt 描述符的數量
struct nand_bbt_descr *tdbbt 描述表
int offs表中塊號偏移量
描述
從頁面開始讀取壞塊表。
-
int read_abs_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, int chip)¶
[通用] 從給定頁面開始讀取壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *td壞塊表的描述符
int chip讀取特定晶片的表,-1 讀取所有晶片; 僅當設定了 NAND_BBT_PERCHIP 選項時才適用
描述
從給定頁面開始讀取所有晶片的壞塊表。 我們假設 bbt 位是連續的。
-
int scan_read_oob(struct nand_chip *this, uint8_t *buf, loff_t offs, size_t len)¶
[通用] 將資料+OOB 區域掃描到緩衝區
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
loff_t offs掃描的偏移量
size_t len要讀取的資料區域的長度
描述
從資料+OOB 掃描讀取資料。 可能會遍歷多個頁面,在 buf 中交錯頁面、OOB、頁面、OOB... 完成傳輸並返回“最強”的 ECC 條件(錯誤或位翻轉)。 可能會在第一個(非 ECC)錯誤時退出。
-
void read_abs_bbts(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)¶
[通用] 從給定頁開始讀取所有晶片的壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *td壞塊表的描述符
struct nand_bbt_descr *md壞塊表映象的描述符
描述
從給定頁開始讀取所有晶片的壞塊表。我們假設壞塊位是連續的。
-
int create_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *bd, int chip)¶
[通用] 透過掃描裝置建立壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *bd好/壞塊搜尋模式的描述符
int chip為特定晶片建立表,-1 讀取所有晶片; 僅當設定了 NAND_BBT_PERCHIP 選項時適用
描述
透過掃描裝置以尋找給定的好/壞塊識別模式來建立壞塊表。
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *td壞塊表的描述符
描述
透過搜尋給定的識別模式來讀取壞塊表。搜尋從裝置開頭向上或從裝置末尾向下執行。搜尋始終從塊的開頭開始。如果給定了 NAND_BBT_PERCHIP 選項,則每個晶片都會搜尋一個包含該晶片壞塊資訊的 bbt。這對於支援某些 DOC 裝置是必要的。
bbt 識別模式位於塊中第一頁的 oob 區域中。
-
void search_read_bbts(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)¶
[通用] 掃描裝置以尋找壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *td壞塊表的描述符
struct nand_bbt_descr *md壞塊表映象的描述符
描述
搜尋並讀取壞塊表。
-
int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chip)¶
獲取適合儲存 BBT 的第一個有效擦除塊
引數
struct nand_chip *thisNAND 裝置
struct nand_bbt_descr *tdBBT 描述
struct nand_bbt_descr *md映象 BBT 描述符
int chipCHIP 選擇器
描述
此函式返回一個正塊號,指向適合儲存 BBT 的有效擦除塊(即在為 BBT 保留的範圍內),或者如果所有塊都已使用或標記為壞塊,則返回 -ENOSPC。如果 td->pages[chip] 已經指向一個有效的塊,我們會重用它,否則我們會搜尋下一個有效的塊。
-
void mark_bbt_block_bad(struct nand_chip *this, struct nand_bbt_descr *td, int chip, int block)¶
將為 BBT 保留的塊之一標記為壞塊
引數
struct nand_chip *thisNAND 裝置
struct nand_bbt_descr *tdBBT 描述
int chipCHIP 選擇器
int block要標記的 BBT 塊
描述
為 BBT 保留的塊可能會變壞。此函式是一個幫助程式,用於將此類塊標記為壞塊。它負責更新記憶體中的 BBT,使用壞塊標記將塊標記為壞塊,並使相關的 td->pages[] 條目無效。
-
int write_bbt(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)¶
[通用] (重新)寫入壞塊表
引數
struct nand_chip *thisNAND 晶片物件
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *td壞塊表的描述符
struct nand_bbt_descr *md壞塊表映象的描述符
int chipsel特定晶片的選擇器,-1 表示全部
描述
(重新)寫入壞塊表。
引數
struct nand_chip *thisNAND 晶片物件
struct nand_bbt_descr *bd好/壞塊搜尋模式的描述符
描述
該函式透過掃描裝置以查詢製造商/軟體標記的好/壞塊來建立基於記憶體的 bbt。
-
int check_create(struct nand_chip *this, uint8_t *buf, struct nand_bbt_descr *bd)¶
[通用] 如果需要,建立並寫入 bbt
引數
struct nand_chip *thisNAND 裝置
uint8_t *buf臨時緩衝區
struct nand_bbt_descr *bd好/壞塊搜尋模式的描述符
描述
該函式檢查先前呼叫 read_bbt 的結果,並在必要時建立/更新 bbt。 如果沒有找到晶片/裝置的 bbt,則需要建立。 如果缺少一個表或一個表的版本號小於另一個表,則需要更新。
引數
struct nand_chip *thisNAND 裝置
loff_t offs新標記的塊的偏移量
描述
該函式更新壞塊表。
引數
struct nand_chip *thisNAND 裝置
struct nand_bbt_descr *td壞塊表描述符
描述
壞塊表區域被標記為“壞”以防止意外擦除/寫入。 這些區域由標記 0x02 標識。
引數
struct nand_chip *thisNAND 裝置
struct nand_bbt_descr *bd要驗證的表
描述
此函式對壞塊描述表執行一些健全性檢查。
引數
struct nand_chip *thisNAND 裝置
struct nand_bbt_descr *bd好/壞塊搜尋模式的描述符
描述
該函式檢查是否已存在壞塊表。 如果沒有,它會掃描裝置以查詢製造商標記的好/壞塊,並將壞塊表寫入選定的位置。
壞塊表記憶體在這裡分配。 必須透過呼叫 nand_free_bbt 函式來釋放它。
引數
struct nand_chip *this要為其建立描述符的 NAND 晶片
描述
此函式基於 **this** 的屬性,分配並初始化一個用於 BBM 檢測的 nand_bbt_descr。 新的描述符儲存在 this->badblock_pattern 中。 因此,傳遞給此函式時,this->badblock_pattern 應為 NULL。
引數
struct nand_chip *thisNAND 晶片物件
loff_t offs裝置中的偏移量
引數
struct nand_chip *thisNAND 晶片物件
loff_t offs裝置中的偏移量
int allowbbt允許訪問壞塊表區域
引數
struct nand_chip *thisNAND 晶片物件
loff_t offs壞塊的偏移量
致謝¶
以下人員為 NAND 驅動程式做出了貢獻
Steven J. Hillsjhill@realitydiluted.com
David Woodhousedwmw2@infradead.org
Thomas Gleixnertglx@linutronix.de
許多使用者提供了錯誤修復,改進和幫助進行測試。非常感謝。
以下人員為本文件做出了貢獻
Thomas Gleixnertglx@linutronix.de