📄 c-4.3upgrade3.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html><head><link rel="STYLESHEET" type="text/css" href="wrs.css"><title> Upgrading 4.3 BSD Network Drivers </title></head><body bgcolor="FFFFFF"><p class="navbar" align="right"><a href="index.html"><img border="0" alt="[Contents]" src="icons/contents.gif"></a><a href="c-4.3upgrade.html"><img border="0" alt="[Index]" src="icons/index.gif"></a><a href="c-4.3upgrade.html"><img border="0" alt="[Top]" src="icons/top.gif"></a><a href="c-4.3upgrade2.html"><img border="0" alt="[Prev]" src="icons/prev.gif"></a><a href="netguideIX.html"><img border="0" alt="[Next]" src="icons/next.gif"></a></p><font face="Helvetica, sans-serif" class="sans"><h3 class="H2"><i><a name="84389">14.3 Upgrading to 4.4 BSD </a></i></h3></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84390"> </a>To upgrade a driver from 4.3 BSD to 4.4 BSD you must change how the driver uses <b class="routine"><i class="routine">ether_attach</i></b><b>( )</b>. This routine is almost always called from the driver's own <b class="routine"><i class="routine">xxattach</i></b><b>( )</b>routine and is responsible for placing the driver's entry points, listed in <a href="c-4.3upgrade2.html#84260">Table 14-1</a>, into the <b class="symbol_lc">ifnet</b> structure that the TCP/IP protocol to track drivers. Consider the call to <b class="routine"><i class="routine">ether_attach</i></b><b>( )</b> shown below: </p><dl class="margin"><dd><pre class="Code2"><b><a name="84396">ether_attach( (IFNET *) & pDrvCtrl->idr, unit, "xx", (FUNCPTR) NULL, (FUNCPTR) xxIoctl, (FUNCPTR) xxOutput, (FUNCPTR) xxReset );</a></b></pre></dl><dd><p class="Body"><a name="84397"> </a>As arguments, this routine expects an Interface Data Record (<b class="symbol_lc">idr</b>), a unit number, and a quoted string that is the name of the device, in this case, "xx". The next four arguments are the function pointers to relevant driver routines. </p><dd><p class="Body"><a name="84398"> </a>The first function pointer references this driver's <b class="routine"><i class="routine">init</i></b><b>( )</b>routine, which this driver does not need or have. The second function pointer references the driver's <b class="routine"><i class="routine">ioctl</i></b><b>( )</b>interface, which allows the upper layer to manipulate the device state. The third function pointer references the routine that outputs packets on the physical medium. The last function pointer references a routine that can reset the device if the TCP/IP stack decides that this needs to be done. </p><dd><p class="Body"><a name="84400"> </a>In 4.4 BSD, there is a generic output routine called <b class="routine"><i class="routine">ether_output</i></b><b>( )</b>that all Ethernet device drivers can use. Thus, to convert the above <b class="routine"><i class="routine">ether_attach</i></b><b>( )</b> call to a 4.4-style call, you would call <b class="routine"><i class="routine">ether_attach</i></b><b>( )</b> as follows: </p><dl class="margin"><dd><pre class="Code2"><b><a name="84401">ether_attach( (IFNET *) & pDrvCtrl->idr, unit, "xx", (FUNCPTR) NULL, (FUNCPTR) xxIoctl, (FUNCPTR) ether_output, /* generic ether_output */ (FUNCPTR) xxReset ); pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)xxTxStartup;</a></b></pre></dl><dd><p class="Body"><a name="84402"> </a>This time, there is an extra line following the call to <b class="routine"><i class="routine">ether_attach</i></b><b>( )</b>. This line of code adds a transmit startup routine to the Interface Data Record. The transmit startup routine is called by the TCP/IP stack after the generic <b class="routine"><i class="routine">ether_output</i></b><b>( )</b> routine is called. This extra line of code assumes that the driver already has a transmit startup routine. If a driver lacks a separate transmit startup routine, you must write one. See the template in <a href="c-4.3upgrade3.html#84427"><i class="title">14.3.4 Creating a Transmit Startup Routine</i></a>. </p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84406">14.3.1 Removing the xxOutput Routine</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84407"> </a>If a 4.3 BSD driver has an <b class="routine"><i class="routine">xxOutput</i></b><b>( )</b> routine, it probably looks something like the following:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84408">static int xxOutput ( IDR * pIDR, MBUF * pMbuf, SOCK * pDestAddr ) { return (ether_output ((IFNET *)pIDR, pMbuf, pDestAddr, (FUNCPTR) xxTxStartup, pIDR)); }</a></b></pre></dl><dd><p class="Body"><a name="84409"> </a>Internally, this routine calls the <b class="routine"><i class="routine">ether_output</i></b><b>( )</b>routine, which expects a pointer to the startup routine as one of its arguments. However, in the 4.4 BSD model, all that work that is now handled in the TCP/IP stack. Thus, in a 4.4 BSD driver, this code is unnecessary and should be removed.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84410">14.3.2 Changing the Transmit Startup Routine</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84411"> </a>Under 4.3 BSD, the function prototype for a transmit startup routine is as follows:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84412">static void xxTxStartup (int unit);</a></b></pre></dl><dd><p class="Body"><a name="84413"> </a>Under 4.4 BSD, the prototype has changed to the following:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84414">static void xxTxStartup (struct ifnet * pDrvCtrl);</a></b></pre></dl><dd><p class="Body"><a name="84415"> </a>The 4.4 BSD version expects a pointer to a driver control structure. This change eases the burden on the startup routine. Instead of having to find its own driver control<b class="symbol_UC"> </b>structure, it receives a pointer to a driver control structure as input. </p><dd><p class="Body"><a name="84416"> </a>If the driver uses <b class="routine"><i class="routine">netJobAdd</i></b><b>( )</b>to schedule the transmit startup routine for task-level execution, edit the <b class="routine"><i class="routine">netJobAdd</i></b><b>( )</b>call to pass in a <b class="symbol_UC">DRV_CTRL</b> structure pointer instead of a unit number. </p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84417">14.3.3 Changes in Receiving Packets</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84419"> </a>Under 4.3 BSD, the driver calls <b class="routine"><i class="routine">do_protocol_with_type</i></b><b>( )</b>. For example: </p><dl class="margin"><dd><pre class="Code2"><b><a name="84420">do_protocol_with_type (etherType, pMbuf, &pDrvCtrl->idr, len);</a></b></pre></dl><dd><p class="Body"><a name="84421"> </a>This call expects an <i class="textVariable">etherType</i><b class="symbol_lc"> </b>(which the driver had to discover previously), a pointer to an mbuf containing the packet data, the Interface Data Record, and the length of the data. </p><dd><p class="Body"><a name="84423"> </a>Under 4.4 BSD, replace the call above with a call to <b class="routine"><i class="routine">do_protocol</i></b><b>( )</b>. For example:</p><dl class="margin"><dd><pre class="Code2"><b><a name="84424">do_protocol (pEh, pMbuf, &pDrvCtrl->idr, len);</a></b></pre></dl><dd><p class="Body"><a name="84425"> </a>The first parameter is a pointer to the very beginning of the packet (including the link level header). All the other parameters remain the same. The driver no longer needs to figure out the <i class="textVariable">etherType</i> for the protocol.</p></dl></dl><font face="Helvetica, sans-serif" class="sans"><h4 class="H3"><i><a name="84427">14.3.4 Creating a Transmit Startup Routine</a></i></h4></font><dl class="margin"><dl class="margin"><dd><p class="Body"><a name="84428"> </a>Some 4.3 BSD drivers did not have a transmit startup routine. For such a driver, you must create one. The template is as follows:</p></dl><dl class="margin"><dd><pre class="Code"><b><a name="84429">void templateStartup ( DRV_CTRL *pDrvCtrl ) { MBUF * pMbuf; int length; TFD * pTfd; /* Loop until there are no more packets ready to send or we * have insufficient resources left to send another one. */ while (pDrvCtrl->idr.ac_if.if_snd.ifq_head) { /* Deque a packet from the send queue. */ IF_DEQUEUE (&pDrvCtrl->idr.ac_if.if_snd, pMbuf); /* Device specific code to get transmit resources, such as a * transmit descriptor, goes here. */ if (Insufficient Resources) { m_freem (pMbuf); /* Make sure to free the packet. */ return; } /* pData below is really the place in your descriptor, * transmit descriptor, or equivalent, where the data is * to be placed. */ copy_from_mbufs (pData, pMbuf, length); if ((etherOutputHookRtn != NULL) && (* etherOutputHookRtn) (&pDrvCtrl->idr, (ETH_HDR *)pTfd->enetHdr, length)) continue; /* Do hardware manipulation to set appropriate bits * and other stuff to get the packet to actually go. */ /* * Update the counter that determines the number of * packets that have been output. */ pDrvCtrl->idr.ac_if.if_opackets++; } /* End of while loop. */ } /* End of transmit routine. */</a></b></pre></dl></dl><a name="foot"><hr></a><p class="navbar" align="right"><a href="index.html"><img border="0" alt="[Contents]" src="icons/contents.gif"></a><a href="c-4.3upgrade.html"><img border="0" alt="[Index]" src="icons/index.gif"></a><a href="c-4.3upgrade.html"><img border="0" alt="[Top]" src="icons/top.gif"></a><a href="c-4.3upgrade2.html"><img border="0" alt="[Prev]" src="icons/prev.gif"></a><a href="netguideIX.html"><img border="0" alt="[Next]" src="icons/next.gif"></a></p></body></html><!---by WRS Documentation (), Wind River Systems, Inc. conversion tool: Quadralay WebWorks Publisher 4.0.11 template: CSS Template, Jan 1998 - Jefro --->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -