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

VxWorks

开发平台:

C/C++

  1. /* ppc555SciSio.c - MPC555 SCI serial driver */
  2. /* Copyright 1984-1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01c,27apr99,zl   fixed mode set to allow switch between polled and intr mode
  7. 01b,19apr99,zl   added support for queued mode, set default baud rate
  8. 01a,22mar99,zl   written based on m68332Sio.c
  9. */
  10. /*
  11. DESCRIPTION
  12. This is the driver for SCIs of the QSMC the the Motorola PPC555.  The SMC has 
  13. two SCI channels. Both channels are compatible with earlier SCI devices from
  14. Motorola (eg. MC68332), with enhancements to allow external baud clock source
  15. and queued operation fro the first SCI channel. 
  16. .SH DATA STRUCTURES
  17. An PPC555SCI_CHAN data structure is used to describe each channel, this
  18. structure is described in h/drv/sio/ppc555SciSio.h. Based on the "options" 
  19. field of this structure, the driver can work in queued or non-queued mode.
  20. Only the first SCI of the QSMC on the PowerPC 555 provides queued mode
  21. operation.
  22. .SH CALLBACKS
  23. Servicing a "transmitter ready" interrupt involves making a callback to
  24. a higher level library in order to get a character to transmit.  By
  25. default, this driver installs dummy callback routines which do nothing.
  26. A higher layer library that wants to use this driver (e.g. ttyDrv)
  27. will install its own callback routine using the SIO_INSTALL_CALLBACK
  28. ioctl command.  Likewise, a receiver interrupt handler makes a callback
  29. to pass the character to the higher layer library.
  30.  
  31. .SH MODES
  32. This driver supports both polled and interrupt modes.
  33. .SH USAGE
  34. The BSP's sysHwInit() routine typically calls sysSerialHwInit(),
  35. which initializes all the values in the PPC555SCI_CHAN structure (except
  36. the SIO_DRV_FUNCS) before calling m68332DevInit().
  37. The BSP's sysHwInit2() routine typically calls sysSerialHwInit2(), which
  38. connects the chips interrupt (m68332Int) via intConnect().
  39. .SH INCLUDE FILES:
  40. drv/sio/ppc555SciSio.h sioLib.h
  41. .SH SEE ALSO:
  42. .I "Section 14 QUEUED SERIAL MULTI-CHANNEL MODULE, MPC555 User抯 Manual"
  43. */
  44. #include "vxWorks.h"
  45. #include "sioLib.h"
  46. #include "intLib.h"
  47. #include "errno.h"
  48. #include "drv/sio/ppc555SciSio.h"
  49. #define PPC555SCI_BAUD_MIN 75
  50. #define PPC555SCI_BAUD_MAX 115200
  51. #ifndef PPC555SCI_DEFAULT_BAUD
  52. #    define PPC555SCI_DEFAULT_BAUD 9600
  53. #endif
  54. /* Hardware abstraction macros */
  55. #ifndef PPC555SCI_REG_READ
  56. #   define PPC555SCI_REG_READ(pChan, reg, result) 
  57. ((result) = *(pChan->reg))
  58. #endif /*PPC555SCI_REG_READ*/
  59. #ifndef PPC555SCI_REG_WRITE
  60. #   define PPC555SCI_REG_WRITE(pChan, reg, data) 
  61. (*(pChan->reg) = data)
  62. #endif /*PPC555SCI_REG_WRITE*/
  63. #ifndef PPC555SCI_SCTQ
  64. #   define PPC555SCI_SCTQ(pChan) 
  65. (pChan->sctq)
  66. #endif /*PPC555SCI_SCTQ*/
  67. #ifndef PPC555SCI_SCRQ
  68. #   define PPC555SCI_SCRQ(pChan) 
  69. (pChan->scrq)
  70. #endif /*PPC555SCI_SCRQ*/
  71. /* forward declarations */
  72. LOCAL STATUS  dummyCallback (void);
  73. LOCAL int ppc555SciIoctl (SIO_CHAN *pSioChan, int request, void *arg);
  74. LOCAL int ppc555SciTxStartup (SIO_CHAN * pSioChan);
  75. LOCAL int ppc555SciCallbackInstall (SIO_CHAN *pSioChan, int callbackType,
  76.     STATUS (*callback)(), void *callbackArg);
  77. LOCAL int ppc555SciPollOutput (SIO_CHAN *pSioChan, char outChar);
  78. LOCAL int ppc555SciPollInput (SIO_CHAN *pSioChan, char *thisChar);
  79. LOCAL void  ppc555SciIntQueued (PPC555SCI_CHAN * pChan);
  80. LOCAL void  ppc555SciIntNotQueued (PPC555SCI_CHAN * pChan);
  81. /* local variables */
  82. LOCAL SIO_DRV_FUNCS ppc555SciSioDrvFuncs =
  83.     {
  84.     ppc555SciIoctl,
  85.     ppc555SciTxStartup,
  86.     ppc555SciCallbackInstall,
  87.     ppc555SciPollInput,
  88.     ppc555SciPollOutput
  89.     };
  90. LOCAL BOOL ppc555SciIntrMode = FALSE; /* interrupt mode allowed flag */
  91. /******************************************************************************
  92. *
  93. * ppc555SciDevInit - initialize a PPC555SCI channel
  94. *
  95. * This routine initializes the driver
  96. * function pointers and then resets the chip in a quiescent state.
  97. * The BSP must have already initialized all the device addresses and the
  98. * baudFreq fields in the PPC555SCI_CHAN structure before passing it to
  99. * this routine.
  100. *
  101. * RETURNS: N/A
  102. */
  103. void ppc555SciDevInit
  104.     (
  105.     PPC555SCI_CHAN * pChan
  106.     )
  107.     {
  108.     /* initialize the channel's driver function pointers */
  109.     pChan->sio.pDrvFuncs = &ppc555SciSioDrvFuncs;
  110.     /* install dummy driver callbacks */
  111.     pChan->getTxChar    = dummyCallback;
  112.     pChan->putRcvChar = dummyCallback;
  113.     ppc555SciIoctl ((SIO_CHAN *) pChan, SIO_BAUD_SET, 
  114.                     (void *) PPC555SCI_DEFAULT_BAUD);
  115.     /* set interrupt level */
  116.     PPC555SCI_REG_WRITE (pChan, scilr, (pChan->intLevel) << QSM_QILR_SCI_SHIFT);
  117.     /* clear control registers 0 and 1 */
  118.     PPC555SCI_REG_WRITE(pChan, sccr0, 0);
  119.     PPC555SCI_REG_WRITE(pChan, sccr1, 0);
  120.     }
  121. /******************************************************************************
  122. *
  123. * ppc555SciDevInit2 - initialize a PPC555SCI, part 2
  124. *
  125. * This routine is called by the BSP after interrupts have been connected.
  126. * The driver can now operate in interrupt mode.  Before this routine is
  127. * called only polled mode operations should be allowed.
  128. *
  129. * RETURNS: N/A
  130. */
  131. void ppc555SciDevInit2
  132.     (
  133.     PPC555SCI_CHAN * pChan /* device to initialize */
  134.     )
  135.     {
  136.     /* Interrupt mode is allowed */
  137.     ppc555SciIntrMode = TRUE;
  138.     }
  139. /******************************************************************************
  140. *
  141. * ppc555SciInt - handle a channel's interrupt
  142. *
  143. * RETURNS: N/A
  144. */ 
  145. void ppc555SciInt
  146.     (
  147.     PPC555SCI_CHAN * pChan /* channel generating the interrupt */
  148.     )
  149.     {
  150.     if (pChan->options & QUEUED)
  151. ppc555SciIntQueued(pChan);
  152.     else
  153. ppc555SciIntNotQueued(pChan);
  154.     }
  155. /******************************************************************************
  156. *
  157. * ppc555SciIntNotQueued - handle a channel's interrupt in not queued mode
  158. *
  159. * RETURNS: N/A
  160. */ 
  161. LOCAL void ppc555SciIntNotQueued
  162.     (
  163.     PPC555SCI_CHAN * pChan /* channel generating the interrupt */
  164.     )
  165.     {
  166.     char ioChar;
  167.     FAST UINT16 status;
  168.     FAST UINT16 temp;
  169.     /* Check for receive */
  170.     PPC555SCI_REG_READ(pChan, scsr, status);
  171.     if (status & QSM_SCSR_RDRF)
  172.         {
  173. PPC555SCI_REG_READ(pChan, scdr, ioChar);
  174.         (*pChan->putRcvChar) (pChan->putRcvArg, ioChar);
  175.         }
  176.  
  177.     /* Check for error conditions and clear them with dummy read */
  178.     if (status & (QSM_SCSR_OR | QSM_SCSR_NF | QSM_SCSR_FE | QSM_SCSR_PF))
  179. {
  180. PPC555SCI_REG_READ(pChan, scdr, ioChar);
  181. }
  182.     /* Check for transmit */
  183.     if (status & QSM_SCSR_TDRE)
  184. {
  185. /* check if there is more to send */
  186. if ((*pChan->getTxChar) (pChan->getTxArg, &ioChar) == OK)
  187.     {
  188.     PPC555SCI_REG_WRITE(pChan, scdr, ioChar);
  189.     }
  190. else
  191.     {
  192.             /* disable transmit interrupts */
  193.     PPC555SCI_REG_READ(pChan, sccr1, temp);
  194.     temp &= ~QSM_SCCR1_TIE;
  195.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  196.     }
  197.         }
  198.     }
  199. /******************************************************************************
  200. *
  201. * ppc555SciIntQueued - handle a channel's interrupt in queued mode
  202. *
  203. * RETURNS: N/A
  204. */ 
  205. LOCAL void ppc555SciIntQueued
  206.     (
  207.     PPC555SCI_CHAN * pChan /* channel generating the interrupt */
  208.     )
  209.     {
  210.     char ioChar;
  211.     FAST UINT16 scsrVal;
  212.     FAST UINT16 qscsrVal;
  213.     FAST UINT16 temp;
  214.     FAST UINT16 byteCount;
  215.     /* read SCI status registers */
  216.     PPC555SCI_REG_READ(pChan, qscsr, qscsrVal);
  217.     PPC555SCI_REG_READ(pChan, scsr,  scsrVal);
  218.     /* check for receive top half */
  219.     if (qscsrVal & QSM_QSCSR_QTHF)
  220.         {
  221. /* read data from queue */
  222. for (byteCount=0; byteCount < 8; byteCount++)
  223.     {
  224.     ioChar = PPC555SCI_SCRQ(pChan)[byteCount];
  225.     (*pChan->putRcvChar) (pChan->putRcvArg, ioChar);
  226.     }
  227. /* clear "top half full" */
  228. qscsrVal &= ~QSM_QSCSR_QTHF;
  229. }
  230.     /* check for receive bottom half */
  231.     else if (qscsrVal & QSM_QSCSR_QBHF)
  232.         {
  233. /* read data from queue */
  234. for (byteCount=0; byteCount < 8; byteCount++)
  235.     {
  236.     ioChar = PPC555SCI_SCRQ(pChan)[byteCount + 8];
  237.     (*pChan->putRcvChar) (pChan->putRcvArg, ioChar);
  238.     }
  239. /* clear "bottom half full" */
  240. qscsrVal &= ~QSM_QSCSR_QBHF;
  241. }
  242.     /* Check for idle */
  243.     if (scsrVal & QSM_SCSR_IDLE)
  244.         {
  245. /* read data from queue */
  246. temp = (qscsrVal & QSM_QSCSR_QRPNT_MSK) >> 4;
  247. if ((temp == 0) || (temp == 8))
  248.     {
  249.     /* need a dummy read to clear IDLE */
  250.     
  251.     ioChar = PPC555SCI_SCRQ(pChan)[0];
  252.     }
  253. else if (temp < 8)
  254.     {
  255.     /* read top half only */
  256.     for (byteCount=0; byteCount < temp; byteCount++)
  257. {
  258. ioChar = PPC555SCI_SCRQ(pChan)[byteCount];
  259. (*pChan->putRcvChar) (pChan->putRcvArg, ioChar);
  260. }
  261.     }
  262. else 
  263.     {
  264.     /* read bottom half only */
  265.     for (byteCount=8; byteCount < temp; byteCount++)
  266. {
  267. ioChar = PPC555SCI_SCRQ(pChan)[byteCount];
  268. (*pChan->putRcvChar) (pChan->putRcvArg, ioChar);
  269. }
  270.     }
  271. /* temporarily disable receive */
  272. PPC555SCI_REG_READ(pChan, sccr1, temp);
  273. temp &= ~QSM_SCCR1_RE;
  274. PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  275. }
  276.     /* check for transmit complete */
  277.     if ((scsrVal & QSM_SCSR_TC) && (qscsrVal & QSM_QSCSR_QTHE) && 
  278.         (qscsrVal & QSM_QSCSR_QBHE))
  279. {
  280. /* check if there is more to send */
  281. for (byteCount=0; byteCount < 16; byteCount++)
  282.     {
  283.     if ((*pChan->getTxChar) (pChan->getTxArg, &ioChar) == OK)
  284. PPC555SCI_SCTQ(pChan)[byteCount] = ioChar;
  285.     else
  286. break;
  287.     }
  288. if (byteCount > 0)
  289.     {
  290.     /* Temporarily disable transmission */
  291.     
  292.     PPC555SCI_REG_READ(pChan, sccr1, temp);
  293.     temp &= ~QSM_SCCR1_TE;
  294.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  295.     /* set QTE bit and queue size */
  296.     
  297.     PPC555SCI_REG_READ(pChan, qsccr, temp);
  298.     temp &= ~QSM_QSCCR_QTSZ_MSK;
  299.     temp |= QSM_QSCCR_QTE;
  300.     temp |= (byteCount-1);
  301.     PPC555SCI_REG_WRITE(pChan, qsccr, temp);
  302.     /* clear top half empty and bottom half empty if needed */
  303.     if (byteCount > 8)
  304. qscsrVal &= ~(QSM_QSCSR_QTHE | QSM_QSCSR_QBHE);
  305.     else
  306.         qscsrVal &= ~QSM_QSCSR_QTHE;
  307.     }
  308. else
  309.     {
  310.     /* disable transmit interrupts */
  311.     PPC555SCI_REG_READ(pChan, sccr1, temp);
  312.     temp &= ~QSM_SCCR1_TCIE;
  313.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  314.     }
  315. }
  316.     /* update queued SCI status register. Clear overrun, just in case */
  317.     qscsrVal &= ~QSM_QSCSR_QOR;
  318.     PPC555SCI_REG_WRITE(pChan, qscsr, qscsrVal);
  319.     /* clear error conditions with dummy reads */
  320.     PPC555SCI_REG_READ(pChan, scsr,  scsrVal);
  321.     if (scsrVal & (QSM_SCSR_OR | QSM_SCSR_NF | QSM_SCSR_FE | QSM_SCSR_PF))
  322. {
  323. PPC555SCI_REG_READ(pChan,  scdr,  temp);
  324. ioChar = PPC555SCI_SCRQ(pChan)[0];
  325. }
  326.     /* 
  327.      * Make sure receive is enabled because error conditions and idle line
  328.      * clear these; re-enable transmit.
  329.      */
  330.     PPC555SCI_REG_READ(pChan, qsccr, temp);
  331.     temp |= QSM_QSCCR_QRE;
  332.     PPC555SCI_REG_WRITE(pChan, qsccr, temp);
  333.     PPC555SCI_REG_READ(pChan, sccr1, temp);
  334.     temp |= (QSM_SCCR1_RE | QSM_SCCR1_TE);
  335.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  336.     }
  337. /******************************************************************************
  338. *
  339. * ppc555SciTxStartup - start the interrupt transmitter
  340. *
  341. * RETURNS: OK on success, ENOSYS if the device is polled-only.
  342. */
  343. LOCAL int ppc555SciTxStartup
  344.     (
  345.     SIO_CHAN * pSioChan                 /* channel to start */
  346.     )
  347.     {
  348.     PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan;
  349.     char outChar;
  350.     FAST UINT16 status;
  351.     FAST UINT16 temp;
  352.     if (pChan->mode == SIO_MODE_INT)
  353. {
  354. if (pChan->options & QUEUED)
  355.     {
  356.     PPC555SCI_REG_READ(pChan, sccr1, temp);
  357.     temp |= QSM_SCCR1_TCIE;
  358.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  359.     }
  360. else
  361.     {
  362.     PPC555SCI_REG_READ(pChan, scsr, status);
  363.     /* send if transmit register empty and have character to send */
  364.     if ((status & QSM_SCSR_TDRE) &&
  365.         ((*pChan->getTxChar) (pChan->getTxArg, &outChar) == OK))
  366. {
  367.         PPC555SCI_REG_WRITE(pChan, scdr, outChar);
  368.          /* enable transmit interrupts */
  369. PPC555SCI_REG_READ(pChan, sccr1, temp);
  370. temp |= QSM_SCCR1_TIE;
  371. PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  372. }
  373.     }
  374. return (OK);
  375. }
  376.     else
  377. return (ENOSYS);
  378.     }
  379. /******************************************************************************
  380. *
  381. * ppc555SciCallbackInstall - install ISR callbacks to get/put chars
  382. *
  383. * This driver allows interrupt callbacks for transmitting characters
  384. * and receiving characters. In general, drivers may support other
  385. * types of callbacks too.
  386. *
  387. * RETURNS: OK on success, or ENOSYS for an unsupported callback type.
  388. */ 
  389. LOCAL int ppc555SciCallbackInstall
  390.     (
  391.     SIO_CHAN * pSioChan,               /* channel */
  392.     int callbackType,           /* type of callback */
  393.     STATUS (*callback)(),          /* callback */
  394.     void *      callbackArg             /* parameter to callback */
  395.     )
  396.     {
  397.     PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan;
  398.     switch (callbackType)
  399. {
  400. case SIO_CALLBACK_GET_TX_CHAR:
  401.     pChan->getTxChar = callback;
  402.     pChan->getTxArg = callbackArg;
  403.     return (OK);
  404. case SIO_CALLBACK_PUT_RCV_CHAR:
  405.     pChan->putRcvChar = callback;
  406.     pChan->putRcvArg = callbackArg;
  407.     return (OK);
  408. default:
  409.     return (ENOSYS);
  410. }
  411.     }
  412. /*******************************************************************************
  413. *
  414. * ppc555SciPollOutput - output a character in polled mode
  415. *
  416. * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
  417. * if the output buffer if full. ENOSYS if the device is
  418. * interrupt-only.
  419. */
  420. LOCAL int ppc555SciPollOutput
  421.     (
  422.     SIO_CHAN * pSioChan,
  423.     char outChar
  424.     )
  425.     {
  426.     PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan;
  427.     UINT16 status;
  428.     /* is the transmitter ready to accept a character? */
  429.     PPC555SCI_REG_READ(pChan, scsr, status);
  430.     if ((status & QSM_SCSR_TDRE) == 0x00)
  431. return (EAGAIN);
  432.     /* write out the character */
  433.     PPC555SCI_REG_WRITE(pChan, scdr, outChar);
  434.     return (OK);
  435.     }
  436. /******************************************************************************
  437. *
  438. * ppc555SciPollInput - poll the device for input
  439. *
  440. * RETURNS: OK if a character arrived, EIO on device error, EAGAIN
  441. * if the input buffer if empty, ENOSYS if the device is
  442. * interrupt-only.
  443. */
  444. LOCAL int ppc555SciPollInput
  445.     (
  446.     SIO_CHAN * pSioChan,
  447.     char * thisChar
  448.     )
  449.     {
  450.     PPC555SCI_CHAN * pChan = (PPC555SCI_CHAN *)pSioChan;
  451.     UINT16 status;
  452.     PPC555SCI_REG_READ(pChan, scsr, status);
  453.     if ((status & QSM_SCSR_RDRF) == 0x00)
  454. return (EAGAIN); /* no input available at this time */
  455.     /* got a character */
  456.     PPC555SCI_REG_READ(pChan, scdr, *thisChar);
  457.     return (OK);
  458.     }
  459. /******************************************************************************
  460. *
  461. * ppc555SciModeSet - toggle between interrupt and polled mode
  462. *
  463. * RETURNS: OK on success, EIO on unsupported mode.
  464. */
  465. LOCAL int ppc555SciModeSet
  466.     (
  467.     PPC555SCI_CHAN * pChan, /* channel */
  468.     uint_t     newMode /* new mode */
  469.     )
  470.     {
  471.     FAST UINT16 temp;
  472.     FAST int oldlevel; /* current interrupt level mask */
  473.     if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT))
  474. return (EIO);
  475.     /* Don't enter interrupt mode unless it is allowed. */
  476.     if ((newMode == SIO_MODE_INT) && (!ppc555SciIntrMode))
  477. return (EIO);
  478.     oldlevel = intLock();
  479.     /* set the new mode */
  480.     pChan->mode = newMode;
  481.     if (pChan->mode == SIO_MODE_INT)
  482. if (pChan->options & QUEUED)
  483.     {
  484.     /* enable SCI in queued mode */
  485.     temp = (QSM_QSCCR_QTHFI | QSM_QSCCR_QBHFI | 
  486.             QSM_QSCCR_QTE   | QSM_QSCCR_QRE);
  487.     PPC555SCI_REG_WRITE(pChan, qsccr, temp);
  488.     /* enable Rx, Tx and enable idle line detection int */
  489.     temp = (QSM_SCCR1_RE   | QSM_SCCR1_TE | QSM_SCCR1_TCIE |
  490.             QSM_SCCR1_ILIE | QSM_SCCR1_ILT);
  491.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  492.     }
  493. else
  494.     {
  495.     /* enable SCI receive interrupts */
  496.     temp = QSM_SCCR1_RE | QSM_SCCR1_TE | QSM_SCCR1_RIE;
  497.     PPC555SCI_REG_WRITE(pChan, sccr1, temp);
  498.     }
  499.     else /* polled mode */
  500. if (pChan->options & QUEUED)
  501.     {
  502.     /* polled mode is not queued */
  503.     PPC555SCI_REG_WRITE(pChan, qsccr, 0);
  504.     PPC555SCI_REG_WRITE(pChan, sccr1, (QSM_SCCR1_RE | QSM_SCCR1_TE));
  505.     }
  506. else
  507.     {
  508.     /* enable rx and tx without interrupts */
  509.     PPC555SCI_REG_WRITE(pChan, sccr1, (QSM_SCCR1_RE | QSM_SCCR1_TE));
  510.     }
  511.     intUnlock(oldlevel);
  512.     return (OK);
  513.     }
  514. /*******************************************************************************
  515. *
  516. * ppc555SciIoctl - special device control
  517. *
  518. * This routine handles the IOCTL messages from the user. It supports commands 
  519. * to get/set baud rate, mode(INT,POLL).
  520. *
  521. * RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed
  522. * request.
  523. */
  524. LOCAL int ppc555SciIoctl
  525.     (
  526.     SIO_CHAN * pSioChan, /* device to control */
  527.     int request, /* request code */
  528.     void * someArg /* some argument */
  529.     )
  530.     {
  531.     PPC555SCI_CHAN *pChan = (PPC555SCI_CHAN *) pSioChan;
  532.     int baudScratch;
  533.     int arg = (int)someArg;
  534.     FAST int     oldlevel; /* current interrupt level mask */
  535.     switch (request)
  536. {
  537. case SIO_BAUD_SET:
  538.     if (arg < PPC555SCI_BAUD_MIN || arg > PPC555SCI_BAUD_MAX)
  539.         {
  540. return (EIO);
  541.         }
  542.     baudScratch = (pChan->clockRate + 16 * arg) / (32 * arg);
  543.     if ((baudScratch < 1) && (baudScratch > 8191))
  544.         {
  545. return (EIO);
  546.         }
  547.     oldlevel = intLock();
  548.     PPC555SCI_REG_WRITE(pChan, sccr0, baudScratch);
  549.     intUnlock (oldlevel);
  550.     pChan->baudRate = arg;
  551.     
  552.             return (OK);
  553. case SIO_BAUD_GET:
  554.     *(int *)arg = pChan->baudRate;
  555.             return (OK);
  556. case SIO_MODE_SET:
  557.     /*
  558.      * Set the mode (e.g., to interrupt or polled). Return OK
  559.      * or EIO for an unknown or unsupported mode.
  560.      */
  561.     return (ppc555SciModeSet (pChan, arg));
  562. case SIO_MODE_GET:
  563.     /* Get the current mode and return OK.  */
  564.     *(int *)arg = pChan->mode;
  565.     return (OK);
  566. case SIO_AVAIL_MODES_GET:
  567.     /* Get the available modes and return OK.  */
  568.     *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
  569.     return (OK);
  570. default:
  571.     return (ENOSYS);
  572. }
  573.     }
  574. /*******************************************************************************
  575. *
  576. * dummyCallback - dummy callback routine
  577. *
  578. * RETURNS: ERROR.
  579. */
  580. LOCAL STATUS dummyCallback (void)
  581.     {
  582.     return (ERROR);
  583.     }