usb 對命令進行處理時,不是我們的命令,需要發空包
轉自:http://www.cnblogs.com/snake-hand/p/3181667.html
s3c6410 linux gadget hid驅動調了我一個多星期了今天終於搞定了,來跟大家分享下.
上一個星期糾結了一個星期的暫存器,試了N次,不管把3.1和3.7的hid驅動移植過來也是一樣的情況,所以這星期直接從問題本身著手一個個找,一個個對比,終於解決了。
我用的核心是linux2.6.38的,最開始的時候開發板是可以當U盤用的,而使用hid功能的時候出現如下問題:
g_hid gadget: hid_setup crtl_request : bRequestType:0x21 bRequest:0xa Value:0x0
g_hid gadget: Unknown request 0xa
s3c-hsotg s3c-hsotg: writen DxEPCTL=0x04228000 to 00000900 (DxEPCTL=0x00208000)
s3c-hsotg s3c-hsotg: s3c_hsotg_rx_data: FIFO 8 bytes on ep0 but no req (DxEPCTl=0x00028000)
s3c-hsotg s3c-hsotg: s3c_hsotg_rx_data: FIFO 8 bytes on ep0 but no req (DxEPCTl=0x00028000)
s3c-hsotg s3c-hsotg: s3c_hsotg_rx_data: FIFO 8 bytes on ep0 but no req (DxEPCTl=0x00028000)
s3c-hsotg s3c-hsotg: S3C_GINTSTS_USBSusp
這個是我把debug資訊開啟後列印出來的資訊,前面一直以為是device的時鐘沒有設定對,device的時鐘應該設定為48M,但是結果不是這裡的問題,怎麼修改時鐘效果都是一樣,所以上個星期一個暫存器一個暫存器的對,修改完後發現還是一樣的問題。所以開始研究這個:Unknown request 0xa
hid的大致流程是s3c_hsotg.c->composite.c->f_hid.c具體流程網上有很多這裡我就不作說明了。
資料:
http://blog.csdn.net/wuyuwei45/article/details/8930830
http://blog.csdn.net/fanqipin/article/details/8450694
糾結了一個星期後,中間花了幾個小時把2416的hid調好的,最後沒辦法所以決定一步步對.
6410的當host傳送請求0xa時就直接出現了上面的錯誤,但是2416當host傳送0xa時也會出現-95的錯誤但是host端會繼續傳送0x06和0x09請求,請檢視usb協議這裡就不多說了。
6410與2416在接收到0xa請求時的操作基本一樣,不同的是2416在接收到0xa後,會忽略這個請求然後向host傳送一個空包,這樣host會繼續傳送其它的請求,而6410在接收到0xa後忽略了,但是沒有向host端傳送任何資料,所以導致後面的操作無法進行.
所以現在的工作就是當device收到0xa後,向host端傳送一個空包,讓列舉繼續下去.
主要修改就在s3c_hsotg.c裡面的s3c_hsotg_process_control函式,整個過程我就不在這分析了,我也不是很懂,哈哈。
/* as a fallback, try delivering it to the driver to deal with */
if (ret == 0 && hsotg->driver) {
ret = hsotg->driver->setup(&hsotg->gadget, ctrl);
if (ret < 0)
dev_dbg(hsotg->dev, "driver->setup() ret %d\n", ret);
}
這裡是接收到請求後由composite.c裡面的composite_setup進行處理,當接收到0xa後這裡會返回-95的錯誤,我們接著往下看:
/* the request is either unhandlable, or is not formatted correctly
* so respond with a STALL for the status stage to indicate failure.
*/
if (ret < 0) {
u32 reg;
u32 ctrl;
dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in);
reg = (ep0->dir_in) ? S3C_DIEPCTL0 : S3C_DOEPCTL0;
/* S3C_DxEPCTL_Stall will be cleared by EP once it has
* taken effect, so no need to clear later. */
ctrl = readl(hsotg->regs + reg);
ctrl |= S3C_DxEPCTL_Stall;
ctrl |= S3C_DxEPCTL_CNAK;
writel(ctrl, hsotg->regs + reg);
dev_dbg(hsotg->dev,
"writen DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n",
ctrl, reg, readl(hsotg->regs + reg));
/* don't belive we need to anything more to get the EP
* to reply with a STALL packet */
}
當返回-95後只對DIEPCTL0進行了相關操作,具體設定請檢視6410 datasheet
所以我們要在這加上發一個空包的過程,看s3c_hsotg.c你會發現,裡面有這樣一個函式:s3c_hsotg_send_zlp
這個函式的功能就是向host傳送一個空包的過程,當然不能全部copy過來,全部copy過來是會有問題的,所以我的修改如下:
/* the request is either unhandlable, or is not formatted correctly
* so respond with a STALL for the status stage to indicate failure.
*/
if (ret < 0) {
u32 reg;
u32 ctrl;
dev_dbg(hsotg->dev, "ep0 stall (dir=%d)\n", ep0->dir_in);
reg = (ep0->dir_in) ? S3C_DIEPCTL0 : S3C_DOEPCTL0;
/* S3C_DxEPCTL_Stall will be cleared by EP once it has
* taken effect, so no need to clear later. */
if(ret != -95) {
ctrl = readl(hsotg->regs + reg);
ctrl |= S3C_DxEPCTL_Stall;
ctrl |= S3C_DxEPCTL_CNAK;
writel(ctrl, hsotg->regs + reg);
}
else {
/* issue a zero-sized packet to terminate this */
writel(S3C_DxEPTSIZ_MC(1) | S3C_DxEPTSIZ_PktCnt(1) |
S3C_DxEPTSIZ_XferSize(0), hsotg->regs + S3C_DIEPTSIZ(0));
ctrl = readl(hsotg->regs + reg);
ctrl |= S3C_DxEPCTL_CNAK; /* clear NAK set by core */
ctrl |= S3C_DxEPCTL_EPEna; /* ensure ep enabled */
ctrl |= S3C_DxEPCTL_USBActEp;
writel(ctrl, hsotg->regs + reg);
}
dev_dbg(hsotg->dev,
"writen DxEPCTL=0x%08x to %08x (DxEPCTL=0x%08x)\n",
ctrl, reg, readl(hsotg->regs + reg));
/* don't belive we need to anything more to get the EP
* to reply with a STALL packet */
}
當if(ret < 0)裡改為如下,同時保留原來的設定,以勉後面出現問題,這樣修改後當host傳送0xa給device device會回一個空包給host 這樣host會繼續後面的操作,這樣你就可以在你的電腦硬體管理裡面看到你的hid裝置了。
水平有限 ,如有錯誤請指出。
相關文章
- 'telnet' 不是內部或外部命令,也不是可執行的程式 或批處理檔案。
- ‘javac‘ 不是內部或外部命令,也不是可執行的程式 或批處理檔案。Java
- 批處理命令之tree命令
- ‘NODE_OPTIONS‘ 不是內部或外部命令,也不是可執行的程式或批處理檔案
- NODE_ENV 不是內部或外部命令,也不是可執行的程式,或者批處理檔案
- (已解決)'ng' 不是內部或外部命令,也不是可執行的程式或批處理檔案
- Linux文字處理命令Linux
- 目錄處理命令
- 一個命令對文字進行高效排序排序
- 執行 kratos 一直沒這個命令,提示 'kratos' 不是內部或外部命令,也不是可執行的程式,需要配置go-binGo
- Jenkins 提示'pytest' 不是內部或外部命令,也不是可執行的程式或批處理檔案的解決方法Jenkins
- Python錯誤集錦:”‘python’ 不是內部或外部命令,也不是可執行的程式 或批處理檔案。”Python
- 程式設計師需要懂點的批處理命令之bat(1.0)程式設計師BAT
- 10 文字分析處理命令
- 實用處理字串的linux命令字串Linux
- 擴充套件我們的分析處理服務(Smartly.io):使用 Citus 對 PostgreSQL 資料庫進行分片套件SQL資料庫
- 如何在批處理模式下執行 top 命令模式
- defrag" 命令的幫助資訊,該命令用於對磁碟進行碎片整理操作
- 巧用watch命令執行迴圈操作,來解放我們的雙手
- ‘cnpm' 不是內部或外部命令,也不是可執行的程式NPM
- anaconda中執行pip命令顯示不是內部或外部命令
- 「補課」進行時:設計模式(8)——命令模式設計模式
- 【原始碼】Redis命令處理過程原始碼Redis
- win10電腦執行telnet命令時提示“telnet不是內部或外部命令”如何解決Win10
- 進擊的WebRTC:我們為什麼需要它?Web
- mysql不是內部命令MySql
- 不是,哥們,誰教你這樣處理生產問題的?
- 使用matlab對影像進行二值化處理Matlab
- SAP Hybris使用recipe進行安裝時,是如何執行ant命令的?
- 那些年,我們處理過的SQL問題SQL
- BAT批處理判斷服務是否正常執行(批處理命令綜合應用)BAT
- pytorch中’tensorboard‘不是內部或外部命令,也不是可執行的程式PyTorchORB
- Windows 批處理之DATE命令的使用方法Windows
- 【BLOCK】Oracle壞塊處理命令參考BloCOracle
- linux 中awk命令實現按照 指定的字元對文字進行排序Linux字元排序
- Linux命令列:對內容進行大小寫字元轉換 Linux命令列字元
- 如何使用diff 和 patch 命令對檔案進行協作?
- Java中對時間的處理Java
- 何時需要對 async/await 進行異常捕獲AI