《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 其他 > Linux設(shè)備驅(qū)動程序架構(gòu)分析之MMC/SD(九)

Linux設(shè)備驅(qū)動程序架構(gòu)分析之MMC/SD(九)

2015-04-29
關(guān)鍵詞: structmmc_host

1204行,由structmmc_host得到struct s3cmci_host。

1205行,從host->mrq取出mmc_request以便使用。

1206行,因為host->cmd_is_stop被設(shè)置為0,所以cmd被設(shè)置為mrq->cmd。

1214-1216行,清空SDICmdSta寄存器、SDIDatSta寄存器和SDIFSTA寄存器。

1216-1245行,如果cmd->data不為0,即當(dāng)前command帶有要處理的數(shù)據(jù),則執(zhí)行這個if語句塊,進(jìn)行數(shù)據(jù)處理的準(zhǔn)備工作。

1219行,調(diào)用s3cmci_setup_data(host,cmd->data),該函數(shù)定義在drivers/mmc/host/s3cmci.c文件中:

捕獲.PNG

捕獲.PNG

捕獲.PNG

1054-1057行,如果命令數(shù)據(jù)為空,則清零SDIDatCon寄存器。

1059-1067行,根據(jù)Datasheet的描述,如果在多模塊下必須分配字大小,即BlkSize[1:0]=00,所以這里“與”3來判斷是不是單模塊。如果在單模塊處理的情況下,模塊數(shù)大于1,則出錯退出。

1069-1082行,循環(huán)判斷是否有數(shù)據(jù)正在發(fā)送或接收,如果有,則停止傳輸,并復(fù)位時鐘。最多循環(huán)3次。

1086-1087行,如果使用DMA傳輸,則使能SDIDatCon寄存器的第15位DMA功能。

1089-1090行,如果數(shù)據(jù)總線寬度為4線,則使能SDIDatCon寄存器的第16位寬總線WideBus功能。

1092-1093行,配置SDIDatCon寄存器的第17位,數(shù)據(jù)傳輸模式為塊傳輸模式。

1095-1098行,如果是寫數(shù)據(jù),配置SDIDatCon寄存器的第20位,收到回應(yīng)后開始寫數(shù)據(jù)。然后配置SDIDatCon寄存器的第12、13位,設(shè)置為寫模式。

1100-1103行,如果是讀數(shù)據(jù),配置SDIDatCon寄存器的第19位,命令發(fā)送后開始讀數(shù)據(jù)。

然后配置SDIDatCon寄存器的第12、13位,設(shè)置為讀模式。

1105-1108行,如果是S3C2440,配置SDIDatCon寄存器的第22、23位為10,即傳輸單位為word。然后配置SDIDatCon寄存器的第14位,開始數(shù)據(jù)傳輸。

1110行,將dcon寫入SDIDatCon寄存器。

1114行,將data->blksz寫入SDIBSize寄存器。

1117-1118行,設(shè)置出現(xiàn)FIFO失敗SDI中斷使能;數(shù)據(jù)接收CRC錯誤SDI中斷使能;數(shù)據(jù)接收超時SDI中斷使能;數(shù)據(jù)計時為0SDI中斷使能。

1120行,調(diào)用enable_imask使能設(shè)置的中斷。

1124-1132行,設(shè)置SDIDTimer寄存器。

回到s3cmci_send_request函數(shù):

1223-1230行,如果s3cmci_setup_data出錯,則打印信息并退出。

1232-1233行,如果使用DMA,則調(diào)用s3cmci_prepare_dma函數(shù),該函數(shù)定義在drivers/mmc/host/s3cmci.c文件中,關(guān)于DMA相關(guān)的函數(shù),我們不再詳細(xì)跟蹤了。

1235行,如果沒有使用DMA數(shù)據(jù)傳輸方式,則調(diào)用s3cmci_prepare_pio函數(shù),即使用FIFO數(shù)據(jù)傳輸方式,具體來說,就是調(diào)用 do_pio_write向FIFO中填充數(shù)據(jù),當(dāng)64字節(jié)的FIFO少于33字節(jié)時就會產(chǎn)生中斷;或者從SD讀數(shù)據(jù),則先使能中斷,當(dāng)FIFO多于31 字節(jié)時,則會調(diào)用中斷服務(wù)程序,中斷服務(wù)程序會調(diào)用do_pio_read讀出FIFO的數(shù)據(jù)。

s3cmci_prepare_pio函數(shù)定義在drivers/mmc/host/s3cmci.c文件中:

捕獲.PNG

1141行,根據(jù)data->flags確定是讀還是寫。

1151行,如果是寫,則調(diào)用do_pio_write函數(shù)。do_pio_write函數(shù)定義在drivers/mmc/host/s3cmci.c文件中:

捕獲.PNG

捕獲.PNG

527行,取得SDIDAT寄存器的物理地址保存在to_ptr變量中。

529行,調(diào)用fifo_free(host)函數(shù)取得FIFO的剩余可用空間的字節(jié)數(shù)保存在fifo變量中,這里,fifo變量代表這次while循環(huán)最多可寫的字節(jié)個數(shù)。如果剩余空間大于3個字節(jié),即最小寫一個字,則循環(huán)條件成立。

530-532行,如果host->pio_bytes為0,則調(diào)用get_data_buffer從分散聚集列表中取得保存要寫的數(shù)據(jù)的緩 沖區(qū),緩沖區(qū)的長度和起始地址分別保存在get_data_buffer的2個參數(shù)host->pio_bytes和第3個參數(shù) host->pio_ptr中。

533-539行,如果get_data_buffer出錯,打印信息退出。

551-552行,如果fifo大于等于host->pio_bytes,即FIFO的可用空間大于等于保存要寫數(shù)據(jù)的緩沖區(qū)長度,則將fifo設(shè)置為host->pio_bytes。

554行,如果fifo小于host->pio_bytes,即FIFO的可用空間小于要寫數(shù)據(jù)的緩沖區(qū)長度,則將fifo設(shè)置為fifo – (fifo & 3)。從注釋可以看到,這是為了保證以字為單位進(jìn)行寫操作。

556行,host->pio_bytes-= fifo,保存這次寫操作后,剩余的要寫的字節(jié)數(shù)。

557行,host->pio_count+= fifo,保存已經(jīng)寫了多少個字節(jié)。

559行,將字節(jié)數(shù)轉(zhuǎn)化為字?jǐn)?shù)。

561-562行,寫數(shù)據(jù)到SDIDAT寄存器。

563行,host->pio_ptr= ptr,保存當(dāng)前還剩余要寫數(shù)據(jù)的位置。 

564行,結(jié)束這次while循環(huán),回到529行重新執(zhí)行上述過程。     

566行,使能SDIIntMsk第4位,如果Tx FIFO填充滿一半,就產(chǎn)生中斷。

回到s3cmci_prepare_pio函數(shù)中:

1152行,使能SDIIntMsk第4位,如果Tx FIFO填充滿一半,就產(chǎn)生中斷。

1154行,使能SDIIntMsk第0位,如果Rx FIFO填充滿一半,就生產(chǎn)中斷。

1155行,使能SDIIntMsk第2位,如果Rx FIFO讀取了最后的數(shù)據(jù),就產(chǎn)生中斷。

回到s3cmci_send_request函數(shù):

1248行,調(diào)用s3cmci_send_command(host,cmd)發(fā)送命令。

該函數(shù)定義在drivers/mmc/host/s3cmci.c文件中:

捕獲.PNG

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。