wdbNetromPktDrv.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

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