usb 對命令進行處理時,不是我們的命令,需要發空包

smilestone322發表於2017-10-11

轉自: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裝置了。

 

水平有限 ,如有錯誤請指出。

相關文章