Beispiel #1
0
BOOL hangup_call(COM_HANDLE com_handle)
{
	time_t	start;
	int		attempt;
	int		mdm_status;

	if(!carrier_detect(com_handle))/* DCD already low */
		return TRUE;

	lprintf(LOG_DEBUG,"Waiting for transmit buffer to empty");
	SLEEP(dtr_delay);
	for(attempt=0; attempt<hangup_attempts; attempt++) {
		lprintf(LOG_INFO,"Dropping DTR (attempt #%d)", attempt+1);
		if(!comLowerDTR(com_handle)) {
			lprintf(LOG_ERR,"ERROR %u lowering DTR", COM_ERROR);
			continue;
		}
		lprintf(LOG_DEBUG,"Waiting for loss of Carrier Detect (DCD)");
		start=time(NULL);
		while(time(NULL)-start <= dcd_timeout) {
			if(((mdm_status=modem_status(com_handle))&COM_DCD)==0)
				return TRUE;
			SLEEP(1000); 
		}
		lprintf(LOG_ERR,"TIMEOUT waiting for DCD to drop (attempt #%d of %d)"
			,attempt+1, hangup_attempts);
		lprintf(LOG_DEBUG,"Modem status: 0x%lX", mdm_status);
	}

	return FALSE;
}
Beispiel #2
0
static void
uart_reset(struct uart_softc *sc)
{
	uint16_t divisor;

	divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16;
	sc->dll = divisor;
	sc->dlh = divisor >> 16;
	sc->msr = modem_status(sc->mcr);

	rxfifo_reset(sc, 1);	/* no fifo until enabled by software */
}
Beispiel #3
0
/* Returns TRUE if DCD (Data Carrier Detect) is high */
BOOL carrier_detect(COM_HANDLE com_handle)
{
	return (modem_status(com_handle)&COM_DCD) ? TRUE:FALSE;
}
Beispiel #4
0
void
uart_write(struct uart_softc *sc, int offset, uint8_t value)
{
	int fifosz;
	uint8_t msr;

	pthread_mutex_lock(&sc->mtx);

	/*
	 * Take care of the special case DLAB accesses first
	 */
	if ((sc->lcr & LCR_DLAB) != 0) {
		if (offset == REG_DLL) {
			sc->dll = value;
			goto done;
		}
		
		if (offset == REG_DLH) {
			sc->dlh = value;
			goto done;
		}
	}

        switch (offset) {
	case REG_DATA:
		if (sc->mcr & MCR_LOOPBACK) {
			if (rxfifo_putchar(sc, value) != 0)
				sc->lsr |= LSR_OE;
		} else if (sc->tty.opened) {
			ttywrite(&sc->tty, value);
		} /* else drop on floor */
		sc->thre_int_pending = true;
		break;
	case REG_IER:
		/*
		 * Apply mask so that bits 4-7 are 0
		 * Also enables bits 0-3 only if they're 1
		 */
		sc->ier = value & 0x0F;
		break;
		case REG_FCR:
			/*
			 * When moving from FIFO and 16450 mode and vice versa,
			 * the FIFO contents are reset.
			 */
			if ((sc->fcr & FCR_ENABLE) ^ (value & FCR_ENABLE)) {
				fifosz = (value & FCR_ENABLE) ? FIFOSZ : 1;
				rxfifo_reset(sc, fifosz);
			}

			/*
			 * The FCR_ENABLE bit must be '1' for the programming
			 * of other FCR bits to be effective.
			 */
			if ((value & FCR_ENABLE) == 0) {
				sc->fcr = 0;
			} else {
				if ((value & FCR_RCV_RST) != 0)
					rxfifo_reset(sc, FIFOSZ);

				sc->fcr = value &
					 (FCR_ENABLE | FCR_DMA | FCR_RX_MASK);
			}
			break;
		case REG_LCR:
			sc->lcr = value;
			break;
		case REG_MCR:
			/* Apply mask so that bits 5-7 are 0 */
			sc->mcr = value & 0x1F;
			msr = modem_status(sc->mcr);

			/*
			 * Detect if there has been any change between the
			 * previous and the new value of MSR. If there is
			 * then assert the appropriate MSR delta bit.
			 */
			if ((msr & MSR_CTS) ^ (sc->msr & MSR_CTS))
				sc->msr |= MSR_DCTS;
			if ((msr & MSR_DSR) ^ (sc->msr & MSR_DSR))
				sc->msr |= MSR_DDSR;
			if ((msr & MSR_DCD) ^ (sc->msr & MSR_DCD))
				sc->msr |= MSR_DDCD;
			if ((sc->msr & MSR_RI) != 0 && (msr & MSR_RI) == 0)
				sc->msr |= MSR_TERI;

			/*
			 * Update the value of MSR while retaining the delta
			 * bits.
			 */
			sc->msr &= MSR_DELTA_MASK;
			sc->msr |= msr;
			break;
		case REG_LSR:
			/*
			 * Line status register is not meant to be written to
			 * during normal operation.
			 */
			break;
		case REG_MSR:
			/*
			 * As far as I can tell MSR is a read-only register.
			 */
			break;
		case REG_SCR:
			sc->scr = value;
			break;
		default:
			break;
	}

done:
	uart_toggle_intr(sc);
	pthread_mutex_unlock(&sc->mtx);
}