wdbNetromPktDrv.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* wdbNetromPktDrv.c - NETROM packet driver for the WDB agent */
  2.  /* Copyright 1995-2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01i,18oct01,jhw  Fixed documentation build errors.
  8. 01h,25jul96,ms   more debug support.
  9. 01g,29feb96,ms   call config_dpram first in init code (SPR 5759).
  10. 01f,24oct95,ms   changed to udpscrmode. Allowed start before kernel.
  11. 01e,14oct95,jdi  doc: cleanup.
  12. 01d,09oct95,ms   made it work with an external mode agent (SPR #4494).
  13. 01c,26sep95,ms   docs.
  14. 01b,27jun95,ms  modified for tornado.
  15.    + tpr added pollDelay variable in wdbNetromPollTask() and
  16.  wdbNetromPktDevInit()
  17. 01a,06Jun95,sub  written.
  18. */
  19. /*
  20. DESCRIPTION
  21. This is a lightweight NETROM driver that interfaces with the WDB agent's
  22. UDP/IP interpreter.  It allows the WDB agent to communicate with the host
  23. using the NETROM ROM emulator.  It uses the emulator's read-only protocol
  24. for bi-directional communication.
  25. It requires that NetROM's udpsrcmode option is on.
  26. */
  27. #include "vxWorks.h"
  28. #include "wdb/wdbLib.h"
  29. #include "wdb/wdbCommIfLib.h"
  30. #include "wdb/wdbMbufLib.h"
  31. #include "drv/wdb/wdbNetromPktDrv.h"
  32. #include "netinet/in_systm.h"
  33. #include "netinet/in.h"
  34. #include "netinet/ip.h"
  35. #include "netinet/udp.h"
  36. #include "intLib.h"
  37. #include "sysLib.h"
  38. #include "taskLib.h"
  39. #include "private/funcBindP.h"
  40. #include "wdb/dptarget.c"
  41. /* some handy macros */
  42. #undef  DBG_PUT
  43. #define DBG_PUT if (wdbIsNowTasking() && wdbNetromDebug && _func_printErr) 
  44.      _func_printErr
  45. #define RESET_INPUT(pDev) {pDev->bytesRead=UDP_IP_HDR_SIZE-UDPSRC_HDR_SIZE; 
  46.      pDev->inBufFull=FALSE;}
  47. #define IP_HDR_SIZE     20
  48. #define UDP_HDR_SIZE    8
  49. #define UDP_IP_HDR_SIZE IP_HDR_SIZE + UDP_HDR_SIZE
  50. #define UDPSRC_HDR_SIZE 6
  51. /* forward static declarations */
  52. static STATUS wdbNetromPoll (void *pDev);
  53. static STATUS wdbNetromPktTx (void *pDev, struct mbuf * pMbuf);
  54. static STATUS wdbNetromModeSet (void *pDev, uint_t newMode);
  55. /* user configurable variables */
  56. int wdbNetromPollPri = 200;
  57. int wdbNetromDebug = 0; /* print debug message to the console
  58.  * for all NetROM I/O packets */
  59. int wdbNetromTest = 0; /* print "WDB NetROM communication ready" to
  60.  * NetROM's debug port during initialization.
  61.  * To see this message, you must telnet to
  62.  * the NetROM's debug port:
  63.  * telnet netromIp 1235
  64.  * Note: VxWorks initialization will halt
  65.  * until you have connected to the debug port!
  66.  * If you don't see this message, then the
  67.  * NetROM connection is no good.
  68.  */
  69. /******************************************************************************
  70. *
  71. * wdbNetromPollTask - fake an input ISR when a packet arrives
  72. */ 
  73. static void wdbNetromPollTask
  74.     (
  75.     void * pDev,
  76.     int pollDelay
  77.     )
  78.     {
  79.     int key;
  80.     for (;;)
  81. {
  82. taskDelay (pollDelay);
  83. key = intLock ();
  84. wdbNetromPoll (pDev);
  85. intUnlock (key);
  86. }
  87.     }
  88. /******************************************************************************
  89. *
  90. * wdbNetromPktDevInit - initialize a NETROM packet device for the WDB agent
  91. *
  92. * This routine initializes a NETROM packet device.  It is typically
  93. * called from usrWdb.c when the WDB agents NETROM communication path
  94. * is selected.
  95. * The <dpBase> parameter is the address of NetROM's dualport RAM.
  96. * The <width> parameter is the width of a word in ROM space, and can be
  97. * 1, 2, or 4 to select 8-bit, 16-bit, or 32-bit width
  98. * respectivly (use the macro WDB_NETROM_WIDTH in configAll.h
  99. * for this parameter).
  100. * The <index> parameter refers to which byte of the ROM contains pod zero.
  101. * The <numAccess> parameter should be set to the number of accesses to POD
  102. * zero that are required to read a byte. It is typically one, but some boards
  103. * actually read a word at a time.
  104. * This routine spawns a task which polls the NetROM for incomming
  105. * packets every <pollDelay> clock ticks.
  106. *
  107. * RETURNS: N/A
  108. */ 
  109. void wdbNetromPktDevInit
  110.     (
  111.     WDB_NETROM_PKT_DEV *pPktDev, /* packet device to initialize */
  112.     caddr_t  dpBase, /* address of dualport memory */
  113.     int width, /* number of bytes in a ROM word */
  114.     int index, /* pod zero's index in a ROM word */
  115.     int numAccess, /* to pod zero per byte read */
  116.     void (*stackRcv)(), /* callback when packet arrives */
  117.     int pollDelay /* poll task delay */
  118.     )
  119.     {
  120.     pPktDev->wdbDrvIf.mode      = WDB_COMM_MODE_POLL | WDB_COMM_MODE_INT;
  121.     pPktDev->wdbDrvIf.mtu       = NETROM_MTU;
  122.     pPktDev->wdbDrvIf.stackRcv  = stackRcv;
  123.     pPktDev->wdbDrvIf.devId     = (void *)pPktDev;
  124.     pPktDev->wdbDrvIf.pollRtn   = wdbNetromPoll;
  125.     pPktDev->wdbDrvIf.pktTxRtn  = wdbNetromPktTx;
  126.     pPktDev->wdbDrvIf.modeSetRtn = wdbNetromModeSet;
  127.     RESET_INPUT (pPktDev);
  128.     DBG_PUT ("calling config_dpram with dpBase = 0x%x, width = %d,n"
  129.  "index = %d, numAccess = %dn", dpBase, width, index, numAccess);
  130.     config_dpram (dpBase, width, index, DPF_READONLY_TGT, numAccess);
  131.     DBG_PUT ("calling set_dp_blockion");
  132.     set_dp_blockio (0, 0); /* non-blocking I/O */
  133.     DBG_PUT ("calling ra_resyncn");
  134.     ra_resync();
  135.     if (wdbNetromTest)
  136. {
  137. char * msg = "nWDB NetROM communication readyn";
  138. DBG_PUT ("calling ra_putmsgn");
  139. ra_putmsg (msg, strlen(msg));
  140. }
  141.     DBG_PUT ("spawning tNetromPolln");
  142.     if (taskIdCurrent && (pollDelay != -1))
  143. taskSpawn ("tNetromPoll", wdbNetromPollPri, 0, 5000,
  144. (int (*)()) wdbNetromPollTask,
  145. (int)pPktDev, pollDelay,0,0,0,0,0,0,0,0);
  146.     }
  147. /******************************************************************************
  148. *
  149. * wdbNetromPktFree - clear a receive packet
  150. */ 
  151. static void wdbNetromPktFree
  152.     (
  153.     WDB_NETROM_PKT_DEV * pDev
  154.     )
  155.     {
  156.     RESET_INPUT (pDev);
  157.     }
  158. /******************************************************************************
  159. *
  160. * wdbNetromPoll - poll device for data
  161. *
  162. * NOMANUAL
  163. */ 
  164. STATUS wdbNetromPoll
  165.     (
  166.     void * devId
  167.     )
  168.     {
  169.     WDB_NETROM_PKT_DEV * pDev = (WDB_NETROM_PKT_DEV *)devId;
  170.     struct mbuf *  pMbuf;
  171.     int    numBytes;
  172.     struct udphdr *     pUdpHdr;
  173.     struct ip *         pIpHdr;
  174.     char * pUdpsrcHdr;
  175.     if (pDev->inBufFull)
  176. {
  177. DBG_PUT ("netrom: multiple packets recieved - dropping last packetn");
  178. return (ERROR);
  179. }
  180.     switch (ra_getmsg(pDev->inBuf + pDev->bytesRead,
  181. NETROM_MTU - pDev->bytesRead, &numBytes))
  182. {
  183. case GM_NODATA:
  184.     return (ERROR);
  185. case GM_MSGCOMPLETE:
  186.     pDev->bytesRead += numBytes;
  187.     /* convert the NETROM udpsrcmode header into a UDP/IP header */
  188.     pUdpsrcHdr = (char *)pDev->inBuf + UDP_IP_HDR_SIZE
  189. - UDPSRC_HDR_SIZE;
  190.     pIpHdr = (struct ip *)pDev->inBuf;
  191.     pUdpHdr = (struct udphdr *)((int)pIpHdr + IP_HDR_SIZE);
  192.     bcopy (pUdpsrcHdr, (char *)&pIpHdr->ip_src, 4);
  193.     pUdpHdr->uh_sport = *(short *)(pUdpsrcHdr + 4);
  194.     pIpHdr->ip_p = IPPROTO_UDP;
  195.     pUdpHdr->uh_dport = htons(WDBPORT);
  196.     DBG_PUT ("ra_getmsg: %d byte packet from IP 0x%x port 0x%xn",
  197. pDev->bytesRead, pIpHdr->ip_src, pUdpHdr->uh_sport);
  198.     pMbuf = wdbMbufAlloc();
  199.     if (pMbuf == NULL)
  200. {
  201. return (ERROR);
  202. }
  203.     wdbMbufClusterInit (pMbuf, pDev->inBuf, pDev->bytesRead,
  204. (int (*)())wdbNetromPktFree, (int)pDev);
  205.     pDev->inBufFull = TRUE;
  206.     (*pDev->wdbDrvIf.stackRcv) (pMbuf);
  207.     return (OK);
  208. case GM_NOTDONE:
  209.     DBG_PUT ("ra_getmsg: partial readn");
  210.     pDev->bytesRead += numBytes;
  211.     return (OK);
  212. case GM_MSGOVERFLOW:
  213.     DBG_PUT ("ra_getmsg: input buffer overflow ignoredn");
  214.     RESET_INPUT (pDev);
  215.     return (ERROR);
  216. default:
  217.     DBG_PUT ("ra_getmsg: unknown return valuen");
  218.     RESET_INPUT (pDev);
  219.     return (ERROR);
  220. }
  221.     return (OK);
  222.     }
  223. /******************************************************************************
  224. *
  225. * wdbNetromModeSet - set device mode
  226. */ 
  227. static STATUS wdbNetromModeSet
  228.     (
  229.     void * pDev,
  230.     uint_t newMode
  231.     )
  232.     {
  233.     WDB_NETROM_PKT_DEV * pPktDev = (WDB_NETROM_PKT_DEV *)pDev;
  234.     RESET_INPUT(pPktDev);
  235.     return (OK);
  236.     }
  237. /******************************************************************************
  238. *
  239. * wdbNetromPktTx - transmit a packet
  240. */ 
  241. static STATUS wdbNetromPktTx
  242.     (
  243.     void *pDev,
  244.     struct mbuf * pMbuf
  245.     )
  246.     {
  247.     struct udphdr *     pUdpHdr;
  248.     struct ip *         pIpHdr;
  249.     struct mbuf *       pFirstMbuf = pMbuf;
  250.     char data [NETROM_MTU];
  251.     int len = 0;
  252.     /* convert the UDP/IP header into a NETROM udpsrcmode header */
  253.     /* XXX - assume UDP/IP header is in first mbuf */
  254.     pIpHdr = mtod (pMbuf, struct ip *);
  255.     pUdpHdr = (struct udphdr *)((int)pIpHdr + IP_HDR_SIZE);
  256.     bcopy ((char *)&pIpHdr->ip_dst, &data[0], 4);
  257.     bcopy ((char *)&pUdpHdr->uh_dport, &data[4], 2);
  258.     len = 6;
  259.     pMbuf = pMbuf->m_next;
  260.     while (pMbuf != NULL)
  261.         {
  262. if (len + pMbuf->m_len > NETROM_MTU)
  263.     break;
  264.         bcopy (mtod (pMbuf, char *), &data[len], pMbuf->m_len);
  265.         len += pMbuf->m_len;
  266.         pMbuf = pMbuf->m_next;
  267.         }
  268.     wdbMbufChainFree (pFirstMbuf);
  269.     DBG_PUT ("packet to IP 0x%x port 0x%xn", pIpHdr->ip_dst,
  270. pUdpHdr->uh_dport);
  271.     ra_putmsg (data, len);
  272.     return (OK);
  273.     }