解決了這個INQUIRY的問題,我們就可以繼續往下走了,372行,這就是真正的批量傳輸的地方,proto_handler()就是正兒八經的處理SCSI命令的函數指標。而usb_stor_control_thread之前的所有代碼就是為了判斷是不是有必要調用函數proto_handler(),比如逾時了,比如模組該卸載了,比如設定斷開flag了,比如要處理的就是這個有問題的INQUIRY等,這些情況都需要先排除了才有必要到達這裡來執行真正的命令。實際上這就是先從宏觀上來控制,保證我們走的是一條正確的道路,而不至於是沿著錯誤的道路走半天。畢竟,在錯誤的路上,就算奔跑也沒有用!
我們倒是先不急著到proto_handler裡邊去看,先把外邊的代碼看完。小時候,我們不都天真地以為,外面的世界很精彩嗎?我們先跳過proto_handler(),把usb_stor_control_thread()中剩下的代碼看完,從而完整地瞭解這個守護進程究竟是如何迴圈的。
385行,只要剛才的命令的結果即srb->result不為DID_ABORT,那麼就是成功執行了。於是我們就調用scsi_done函數。
390行,SkipForAbort,就是一個行標誌,對應前面的goto SkipForAbort語句。繼續說,399行,前面的注釋也說得很清楚了,如果是設定了US_FLIDX_TIMED_OUT那麼就喚醒設這個flag的進程,其實就是喚醒command_abort,後面我們會講command_abort()。這裡之所以判斷這個flag而不是判斷srb->result==DID_ABORT注釋裡說得也很清楚,因為有可能是在usb傳輸結束之後才收到的abort命令,換言之,即便你的srb->result不為DID_ABORT也可能最新又接到了abort的請求,所以這裡就判斷abort請求必然要設定的一個flag來判斷。
408行,如果要斷開了,或者是一個命令執行完了,或者是abort了,那麼最終就是把us->srb置空。剩下兩行的兩把鎖我們已經說過,會到最後統一講。
413行,至此,這個守護進程就算是走了一遍,for迴圈繼續。
最後,只剩下431這行了,程式執行到這一行意味著for迴圈結束了,而從for迴圈的代碼我們不難看出,結束for迴圈的只有一句話,就是break。前面說過,它意味著模組要被卸載了。所以這裡complete_and_exit()就是喚醒別人同時結束自己,於是這一刻,usb_stor_control_thread()也就正式結束了,也許對它來說,結束就是解脫吧。
關於這個守護進程,我們也終於講完了,其中的函數proto_handler()這兩行,因為其重要性,我們單獨挑出來講。