Windows system >> Windowsの知識 >  >> Linuxシステムチュートリアル >> Linuxチュートリアル >> プロトコルスタックのLinuxのリンク層上でのデータ送信 - データ送信

プロトコルスタックのLinuxのリンク層上でのデータ送信 - データ送信

  

伝達関数にデータを送信する前に、我々は最初e100_up()ルック - > e100_alloc_cbs機能:静的INT e100_alloc_cbs(構造体NIC * NIC) {構造体CB * CB; unsigned int型I、カウント= nic-> params.cbs.count; nic-> cuc_cmd = cuc_start; nic-> cb_to_use = nic-> cb_to_send = nic-> cb_to_clean = NULL; nic-> cbs_avail = 0;

の仮想アドレスは、CPUが使用するために戻される//DMA線形マッピング、nic-> CBS = pci_alloc_consistent(nic-> PDEV、はsizeof(構造体CB) *カウント、&#038; nic-> cbs_dma_addr); IF(nic->! CBS)-ENOMEMを返す; //環状を確立するための送信バッファ(CB = nic-> CBS、I = 0; I<。カウント; CB ++、iは++){CB->次=(I + 1<カウント)CB + 1:?? nic-> CBS; CB-> PREV =(I == 0)nic-> CBS +カウント - 1:CB - 1; CB-> DMA_ADDR = nic-> cbs_dma_addr + iは(構造体CB)はsizeof *; CB->リンク= cpu_to_le32(nic-> cbs_dma_addr +((I + 1)%カウント)*はsizeofは(構造体CB)); CB-> SKB = NULL;} //ポインタの初期化を指すように初期位置nic->バッファ; cb_to_use = nic-> cb_to_send = nic-> cb_to_clean = nic-> CBS; nic-> cbs_availは=カウント0を返す;}コードのこのセクションでは、送信の準備が完了仕事、送信リングバッファの確立。送信プレイの数限り、データバッファへのデータの最終呼にはDEV->場合、hard_start_xmit機能。 E100コードで、即ちe100_xmit_frame()内部に見; int型のERRを、IF(nic->静的INT e100_xmit_frame(構造体sk_buff *のSKB、構造体net_device * NETDEV){構造体NIC * NIC = netdev_priv(NETDEV)。フラグ&#038; ich_10h_workaround){e100_exec_cmd(NIC、cuc_nop、0); udelay(1);} ERR = e100_exec_cb(NIC、SKB、e100_xmit_prepare);スイッチ(ERR){ケース-ENOSPC:/*我々は、SKBをキューに入れられたが、今.. /*これはハードエラーである - * /DPRINTK(TX_ERR、DEBUG、"それをログに記録し、送信資源のうち、SKBの\\を返すN"破る;ケース-ENOMEM我々は* /netif_stop_queue(NETDEV)スペースの外にしています;); netif_stop_queue(NETDEV); trans_start = jiffy単位; netdev->}; 1戻り0を返す;} NIC、SKB、e100_xmit_prepare)(e100_exec_cbに追跡し続け、静的インラインINT e100_exec_cb(構造体NIC * NIC、構造体sk_buffの*のSKBボイド(* cb_prepare)(構造体NIC *、構造体CB *、構造体sk_buff *)){構造体CB * CB; unsigned long型フラグ; INT ERR = 0; spin_lock_irqsave(&#038; nic-> cb_lock、フラグ); IF(低い(nic->! cbs_avail)){ERR = -ENOMEM;後藤err_unlock;}

//SKB環状送信バッファへ//cb_to_use:現在のバッファ使用位置を送信CB = nic-> cb_to_use; nic-> cb_to_use = CB->次、nic-> cbs_avail -; CB-> SKB = SKB。 cb_prepare(NIC、CB、SKB); ERR = -ENOSPC;(!cbs_avail)そう(nic->)場合/*順序が重要であるそうでない場合は、我々はH /Wでレースになるだろう:中*集合Sビット現在、以前の* /CB->の最初の、そして明確なS-ビット;コマンド|。 = Cpu_to_le16(cb_s); WMB(); CB-> prev->コマンド&#038; = cpu_to_le16(〜cb_s); //空ではないデータを送信します。残りの送信の全てながら再生回数(nic-> cb_to_send = nic->! Cb_to_use){IF(低い(e100_exec_cmd(NIC、nic-> cuc_cmd、nic-> cb_to_send-> DMA_ADDR))){/物事がスティッキー取得する場所コントローラがビジー状態であるため、。* [OK]を、ここではそれは* *私たちは、コマンドをスケジュールすることはできません可能性がありますですので、*}ちょうどコマンドをキューに入れ、別のコマンドが* /ブレーク;.予定されているとき*もう一度試してみましょう他{nic-> cuc_cmd = cuc_resume; nic-> cb_to_send = nic-> cb_to_send->次;}} err_unlock:spin_unlock_irqrestore(&#038; nic-> cb_lock、フラグ);戻りERR;}ここでデータ・プロセスは、主にe100_exec_cmdによって行われる送信を参照してください。私はunsigned int型;静的インラインINT e100_exec_cmd(構造体NIC * NIC、U8 CMD、dma_addr_t DMA_ADDR){unsigned long型フラグに追跡INT ERR = 0。

Copyright © Windowsの知識 All Rights Reserved