?? i82550sio.c
字號:
case PARENB: /* enable even parity */ break; case PARODD: /* invalid mode, not normally used. */ break; default: case 0: /* no parity */; break; } if (newOpts & CLOCAL) { /* clocal disables hardware flow control */ hdweFlowCtrl = FALSE; } if ((newOpts & CREAD) == 0) rcvrEnable = FALSE; lvl = intLock (); /* * TODO - Reset the device according to dataBits, stopBits, hdweFlowCtrl, * rcvrEnable, and parity selections. */ intUnlock (lvl); /* * TODO - Be sure that pChan->options reflects the actual * hardware settings. If 5 data bits were requested, but unsupported, * then be sure pChan->options reflects the actual number of data bits * currently selected. */ pChan->options = newOpts; return (OK); }/********************************************************************************* i82550Ioctl - special device control** This routine handles the IOCTL messages from the user. It supports commands * to get/set baud rate, mode(INT,POLL), hardware options(parity, number of * data bits) and modem control(RTS/CTS and DTR/DSR handshakes).* The ioctl commands SIO_HUP and SIO_OPEN are used to implement the HUPCL(hang* up on last close) function.** As on a UNIX system, requesting a baud rate of zero is translated into* a hangup request. The DTR and RTS lines are dropped. This should cause* a connected modem to drop the connection. The SIO_HUP command will only* hangup if the HUPCL option is active. The SIO_OPEN function will raise* DTR and RTS lines whenever it is called. Use the BAUD_RATE=0 function* to hangup when HUPCL is not active.** The CLOCAL option will disable hardware flow control. When selected,* hardware flow control is not used. When not selected hardware flow control* is based on the RTS/CTS signals. CTS is the clear to send input* from the other end. It must be true for this end to begin sending new* characters. In most drivers, the RTS signal will be assumed to be connected* to the opposite end's CTS signal and can be used to control output from* the other end. Raising RTS asserts CTS at the other end and the other end* can send data. Lowering RTS de-asserts CTS and the other end will stop* sending data. (This is non-EIA defined use of RTS).** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed* request.*/LOCAL int i82550Ioctl ( SIO_CHAN * pSioChan, /* device to control */ int request, /* request code */ void * someArg /* some argument */ ) { I82550_CHAN *pChan = (I82550_CHAN *) pSioChan; int oldLevel; /* current interrupt level mask */ int baudConstant; int arg = (int)someArg; I82550_PIPE_FLUSH(pChan); switch (request) { case SIO_BAUD_SET: /* * like unix, a baud request for 0 is really a request to * hangup. */ if (arg == 0) return (i82550Hup (pChan)); /* * Set the baud rate. Return EIO for an invalid baud rate, or * OK on success. */ if (arg < I82550_BAUD_MIN || arg > I82550_BAUD_MAX) { return (EIO); } /* TODO - Calculate the baud rate constant for the new baud rate */ baudConstant = pChan->clkFreq / arg / 16; /* DUMMY CODE */ /* disable interrupts during chip access */ oldLevel = intLock (); I82550_SIO_WRITE8(pChan, I82550_BAUD_ID, baudConstant); intUnlock (oldLevel); pChan->baudFreq = arg; return (OK); case SIO_BAUD_GET: *(int *)someArg = pChan->baudFreq; return (OK); case SIO_MODE_SET: /* * Set the mode (e.g., to interrupt or polled). Return OK * or EIO for an unknown or unsupported mode. */ return (i82550ModeSet (pChan, arg)); case SIO_MODE_GET: /* Get the current mode and return OK. */ *(int *)someArg = pChan->mode; return (OK); case SIO_AVAIL_MODES_GET: /* TODO - set the available modes and return OK. */ *(int *)someArg = SIO_MODE_INT | SIO_MODE_POLL; return (OK); case SIO_HW_OPTS_SET: /* * Optional command to set the hardware options (as defined * in sioLib.h). * Return OK, or ENOSYS if this command is not implemented. * Note: several hardware options are specified at once. * This routine should set as many as it can and then return * OK. The SIO_HW_OPTS_GET is used to find out which options * were actually set. */ return (i82550OptSet (pChan, arg)); case SIO_HW_OPTS_GET: /* * Optional command to get the hardware options (as defined * in sioLib.h). Return OK or ENOSYS if this command is not * implemented. Note: if this command is unimplemented, it * will be assumed that the driver options are CREAD | CS8 * (e.g., eight data bits, one stop bit, no parity, ints enabled). */ *(int *)someArg = pChan->options; return (OK); case SIO_HUP: /* check if hupcl option is enabled */ if (pChan->options & HUPCL) return (i82550Hup (pChan)); return (OK); case SIO_OPEN: return (i82550Open (pChan)); /* always open */#if 1 /* TODO - optional modem control line support */ /* * These new ioctl commands are for monitoring and setting the * state of the modem control lines under user control. The * return values from these calls inform the user about which * control lines are inputs and which are outputs. Basically * this lets the user know if the device is wired for DTE or * DCE configuration. It also informs the user if any signals * are missing altogether. */ case SIO_MSTAT_GET: return i82550MstatGet(pChan); case SIO_MCTRL_BITS_SET: return i82550MstatSetClr (pChan, arg, TRUE); case SIO_MCTRL_BITS_CLR: return i82550MstatSetClr (pChan, arg, FALSE); /* * The ISIG and OSIG masks tell the user which signals are actually * outputs and which aren't. In our case here, we assume the device * is DTE mapped with DTR and RTS as outputs. DSR and CTS as inputs. * This i82550 driver doesn't support RI. */ case SIO_MCTRL_OSIG_MASK: *(int *)someArg = I82550_OSIG_MASK; break; case SIO_MCTRL_ISIG_MASK: *(int *)someArg = I82550_ISIG_MASK; break;#endif /* optional Modem control line support */#if 1 /* TODO - optional keyboard scan code support */ /* * The following new ioctl commands are meant only for keyboard * input devices to use. These allow the user to specify and * examine the type of keyboard character mapping to use. The * possible types are NONE (raw scan codes), ASCII (default ascii * mappings, and UNICODE for standard 16 bit unicode mappings. * * Our i82550 driver supports only raw and ascii modes. */ case SIO_KYBD_MODE_SET: switch (arg) { case SIO_KYBD_MODE_RAW: case SIO_KYBD_MODE_ASCII: break; case SIO_KYBD_MODE_UNICODE: return ENOSYS; /* i82550 doesn't support unicode */ } pChan->scanMode = arg; return OK; case SIO_KYBD_MODE_GET: *(int *)someArg = pChan->scanMode; return OK;#endif /* optional keyboard scan code support */ default: return ENOSYS; } return OK; }/********************************************************************************* dummyTxCallback - dummy Tx callback routine** RETURNS: ERROR.*/LOCAL STATUS dummyTxCallback ( void * callbackArg, /* argument registered with callback */ char * pChara /* ptr to data location */ ) { static BOOL doit = TRUE; /* * TODO - Until an upstream module connects to this device, there * is no data available to send. We should only be concerned * if this callback is being called repeatedly and often. That * could indicate an interrupt servicing problem of some kind. */ if (doit) { printf ("Dummy txCallback: 0x%x 0x%x\n", (int)callbackArg, (int)pChara); doit = FALSE; } return (ERROR); }/********************************************************************************* dummyRxCallback - dummy Rx callback routine** RETURNS: N/A.* ARGSUSED*/LOCAL void dummyRxCallback ( void * callbackArg, /* argument registered with callback */ char data /* receive data */ ) { static BOOL doit = TRUE; /* * TODO - Device is transferring data, but there is no * upstream module connected to receive it. Lets log * a message about incoming data being lost. Buts lets * do this only once we don't want a 'flood' of logged * messages. */ if (doit) { printf ("Dummy rxCallback: 0x%x 0x%x\n", (int)callbackArg, (int)data); doit = FALSE; } return; }/********************************************************************************* dummyErrCallback - dummy Error callback routine** There should be an sioLib module to provide dummyCallbacks for all SIO* drivers to use.** RETURNS: N/A.* ARGSUSED*/LOCAL void dummyErrCallback ( void * callbackArg, /* argument registered with callback */ int errorCode, /* error code */ void * pData, /* ptr to device specific data */ int size /* size of device specific data */ ) { static BOOL doit = TRUE; /* TODO - We could log the reported error (once). */ if (doit) { printf ("Dummy errorCallback: 0x%x 0x%x 0x%x %d\n", (int)callbackArg, errorCode, (int)pData, size); doit = FALSE; } return; }/********************************************************************************* i82550Probe - probe for device ** Try to determine if device is present. Do not reconfigure device if it* is there. This should be a passive probe that does not interfere with* the device.** RETURNS:* Returns OK if device adaptor is there, ERROR if not there.*/LOCAL STATUS i82550Probe ( I82550_CHAN * pChan /* channel to probe */ ) { char testData; /* * TODO - Probe device registers to see if they are there and if they * are the proper type of device. Look for specific bits that are * always 0 or 1. Don't attempt any operations with side effects * that might clear interrupt status or flags. For High Availability * situations, some other CPU may be controlling this device. We do * not want to interfere with those operations. */ I82550_PROBE (pChan, I82550_CSR_ID, VX_READ, 1, &testData); /* TODO - Is this really the right type device ? */ return OK; }/********************************************************************************* i82550Verify - verify i82550 chan structure** Given a pointer to what should be a I82550_CHAN, verify that it really* is a I82550_CHAN structure.** This routine should not be called at every level with every routine. It is* primarily provided for use with the xxxDestroy routine. Performance will be* a problem if every pointer is checked for validity with every use.** RETURNS:* Returns OK if pointer is valid, ERROR if not.*/LOCAL STATUS i82550Verify ( I82550_CHAN * pChan /* pointer to be verified */ ) { /* * TODO - Examine the structure. Look for magic cookies or flag bits. * Anything that would confirm this pointer as being a valid * I82550_CHAN pointer. */ if (pChan == NULL) return ERROR; return OK; }#if 1 /* TODO - Optional modem control line support *//********************************************************************************* i82550MstatGet - read device modem control line status** Read the device modem control lines and map them to the standard* modem signal bits.** RETURNS:* Returns the modem control line status bits.*/LOCAL int i82550MstatGet ( I82550_CHAN *pChan ) { UINT8 rawStatus; int result = 0; I82550_SIO_READ8 (pChan, I82550_MSR_ID, &rawStatus); /* Now map device status bits, to standard status bits */ if (rawStatus & I82550_MSR_CD) result |= SIO_MODEM_CD; if (rawStatus & I82550_MSR_DTR) result |= SIO_MODEM_DTR; if (rawStatus & I82550_MSR_DSR) result |= SIO_MODEM_DSR; if (rawStatus & I82550_MSR_RTS) result |= SIO_MODEM_RTS; if (rawStatus & I82550_MSR_CTS) result |= SIO_MODEM_CTS; return result; }/********************************************************************************* i82550MstatSetClear - set/clear modem control lines** This routine allows the user to set or clear individual modem control* lines. Of course, only the output lines can actually be changed.** RETURNS:* OK, or EIO upon detecting a hardware fault.*/LOCAL int i82550MstatSetClr ( I82550_CHAN *pChan, UINT bits, /* bits to change */ BOOL setFlag /* TRUE = set, FALSE = clear */ ) { UINT8 rawStatus; UINT8 rawMask = 0; /* Read current modem status */ I82550_SIO_READ8 (pChan, I82550_MSR_ID, &rawStatus); /* ignore input only bits */ bits &= I82550_OSIG_MASK; /* Now map standard bits to device specific bits */ if (bits & SIO_MODEM_DTR) rawMask |= I82550_MSR_DTR; if (bits & SIO_MODEM_RTS) rawMask |= I82550_MSR_RTS; /* Update device with new output signals */ if (setFlag) rawStatus |= rawMask; /* set new bits */ else rawStatus &= ~rawMask; /* clear bits */ I82550_SIO_WRITE8 (pChan, I82550_MSR_ID, rawStatus); return OK; }#endif /* optional modem control line support *//*********************************************************************************STATUS i82550Drv(void){ if(i82550DrvNum>0)return (OK); if((i82550DrvNum=iosDrvInstall())==ERROR) return (ERROR); return (OK);}*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -