Uart driver: on close, wait for output queue to drain.
This commit is contained in:
@@ -211,6 +211,11 @@ int ttyselect (struct tty *tp, int rw);
|
||||
*/
|
||||
void ttyflush (struct tty *tp, int rw);
|
||||
|
||||
/*
|
||||
* Wait for output to drain, and flush input.
|
||||
*/
|
||||
void ttywflush (struct tty *tp);
|
||||
|
||||
#endif /* KERNEL */
|
||||
|
||||
/* internal state bits */
|
||||
|
||||
792
sys/pic32/uart.c
792
sys/pic32/uart.c
@@ -38,12 +38,12 @@ unsigned int uart_major = 0;
|
||||
#endif
|
||||
|
||||
const struct uart_irq uirq[NUART] = {
|
||||
{ PIC32_IRQ_U1E, PIC32_IRQ_U1RX, PIC32_IRQ_U1TX },
|
||||
{ PIC32_IRQ_U2E, PIC32_IRQ_U2RX, PIC32_IRQ_U2TX },
|
||||
{ PIC32_IRQ_U3E, PIC32_IRQ_U3RX, PIC32_IRQ_U3TX },
|
||||
{ PIC32_IRQ_U4E, PIC32_IRQ_U4RX, PIC32_IRQ_U4TX },
|
||||
{ PIC32_IRQ_U5E, PIC32_IRQ_U5RX, PIC32_IRQ_U5TX },
|
||||
{ PIC32_IRQ_U6E, PIC32_IRQ_U6RX, PIC32_IRQ_U6TX },
|
||||
{ PIC32_IRQ_U1E, PIC32_IRQ_U1RX, PIC32_IRQ_U1TX },
|
||||
{ PIC32_IRQ_U2E, PIC32_IRQ_U2RX, PIC32_IRQ_U2TX },
|
||||
{ PIC32_IRQ_U3E, PIC32_IRQ_U3RX, PIC32_IRQ_U3TX },
|
||||
{ PIC32_IRQ_U4E, PIC32_IRQ_U4RX, PIC32_IRQ_U4TX },
|
||||
{ PIC32_IRQ_U5E, PIC32_IRQ_U5RX, PIC32_IRQ_U5TX },
|
||||
{ PIC32_IRQ_U6E, PIC32_IRQ_U6RX, PIC32_IRQ_U6TX },
|
||||
};
|
||||
|
||||
struct tty uartttys[NUART];
|
||||
@@ -66,18 +66,19 @@ const struct devspec uartdevs[] = {
|
||||
};
|
||||
|
||||
void cnstart (struct tty *tp);
|
||||
|
||||
struct uartreg *uart[NUART] = {
|
||||
(struct uartreg*) &U1MODE,
|
||||
(struct uartreg*) &U2MODE,
|
||||
(struct uartreg*) &U3MODE,
|
||||
(struct uartreg*) &U4MODE,
|
||||
(struct uartreg*) &U5MODE,
|
||||
(struct uartreg*) &U6MODE
|
||||
(struct uartreg*) &U1MODE,
|
||||
(struct uartreg*) &U2MODE,
|
||||
(struct uartreg*) &U3MODE,
|
||||
(struct uartreg*) &U4MODE,
|
||||
(struct uartreg*) &U5MODE,
|
||||
(struct uartreg*) &U6MODE
|
||||
};
|
||||
|
||||
void uartinit()
|
||||
{
|
||||
unsigned char unit;
|
||||
unsigned char unit;
|
||||
int i;
|
||||
|
||||
// Our first task is to find out what our major
|
||||
@@ -89,17 +90,11 @@ void uartinit()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup UART registers.
|
||||
* Compute the divisor for 115.2 kbaud.
|
||||
*/
|
||||
for(unit=0; unit<NUART; unit++)
|
||||
{
|
||||
|
||||
// SPI2 is U3/U6 (2/5)
|
||||
// SPI3 is U1/U4 (0/3)
|
||||
// SPI4 is U2/U5 (1/4)
|
||||
|
||||
/*
|
||||
* Setup UART registers.
|
||||
* Compute the divisor for 115.2 kbaud.
|
||||
*/
|
||||
for (unit=0; unit<NUART; unit++) {
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
continue;
|
||||
@@ -125,492 +120,394 @@ void uartinit()
|
||||
continue;
|
||||
#endif
|
||||
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
continue;
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
continue;
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
continue;
|
||||
// SPI2 is U3/U6 (2/5)
|
||||
if (SD0_PORT == 2 && (unit==2 || unit==5))
|
||||
continue;
|
||||
|
||||
switch(unit)
|
||||
{
|
||||
case 0:
|
||||
// SPI3 is U1/U4 (0/3)
|
||||
if (SD0_PORT == 3 && (unit==0 || unit==3))
|
||||
continue;
|
||||
|
||||
// SPI4 is U2/U5 (1/4)
|
||||
if (SD0_PORT == 4 && (unit==1 || unit==4))
|
||||
continue;
|
||||
|
||||
switch(unit) {
|
||||
case 0:
|
||||
#ifdef UART1_ENA_PORT
|
||||
/* Enable UART1 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART1_ENA_PORT) = 1 << UART1_ENA_PIN;
|
||||
LAT_CLR(UART1_ENA_PORT) = 1 << UART1_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART1 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART1_ENA_PORT) = 1 << UART1_ENA_PIN;
|
||||
LAT_CLR(UART1_ENA_PORT) = 1 << UART1_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART1_BAUD);
|
||||
break;
|
||||
case 1:
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART1_BAUD);
|
||||
break;
|
||||
case 1:
|
||||
#ifdef UART2_ENA_PORT
|
||||
/* Enable UART2 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN;
|
||||
LAT_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART2 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN;
|
||||
LAT_CLR(UART2_ENA_PORT) = 1 << UART2_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART2_BAUD);
|
||||
break;
|
||||
case 2:
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART2_BAUD);
|
||||
break;
|
||||
case 2:
|
||||
#ifdef UART3_ENA_PORT
|
||||
/* Enable UART3 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN;
|
||||
LAT_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART3 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN;
|
||||
LAT_CLR(UART3_ENA_PORT) = 1 << UART3_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART3_BAUD);
|
||||
break;
|
||||
case 3:
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART3_BAUD);
|
||||
break;
|
||||
case 3:
|
||||
#ifdef UART4_ENA_PORT
|
||||
/* Enable UART4 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN;
|
||||
LAT_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART4 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN;
|
||||
LAT_CLR(UART4_ENA_PORT) = 1 << UART4_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART4_BAUD);
|
||||
break;
|
||||
case 4:
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART4_BAUD);
|
||||
break;
|
||||
case 4:
|
||||
#ifdef UART5_ENA_PORT
|
||||
/* Enable UART5 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN;
|
||||
LAT_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART5 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN;
|
||||
LAT_CLR(UART5_ENA_PORT) = 1 << UART5_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART5_BAUD);
|
||||
break;
|
||||
case 5:
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART5_BAUD);
|
||||
break;
|
||||
case 5:
|
||||
#ifdef UART6_ENA_PORT
|
||||
/* Enable UART6 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN;
|
||||
LAT_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN;
|
||||
udelay(2500);
|
||||
/* Enable UART6 phy - pin is assumed to be active low */
|
||||
TRIS_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN;
|
||||
LAT_CLR(UART6_ENA_PORT) = 1 << UART6_ENA_PIN;
|
||||
udelay(2500);
|
||||
#endif
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART6_BAUD);
|
||||
break;
|
||||
uart[unit]->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, UART6_BAUD);
|
||||
break;
|
||||
}
|
||||
|
||||
uart[unit]->sta = 0;
|
||||
uart[unit]->mode = PIC32_UMODE_PDSEL_8NPAR | /* 8-bit data, no parity */
|
||||
PIC32_UMODE_ON; /* UART Enable */
|
||||
uart[unit]->staset = PIC32_USTA_URXEN | /* Receiver Enable */
|
||||
PIC32_USTA_UTXEN; /* Transmit Enable */
|
||||
}
|
||||
uart[unit]->sta = 0;
|
||||
uart[unit]->mode =
|
||||
PIC32_UMODE_PDSEL_8NPAR | /* 8-bit data, no parity */
|
||||
PIC32_UMODE_ON; /* UART Enable */
|
||||
uart[unit]->staset =
|
||||
PIC32_USTA_URXEN | /* Receiver Enable */
|
||||
PIC32_USTA_UTXEN; /* Transmit Enable */
|
||||
}
|
||||
}
|
||||
|
||||
int uartopen(dev_t dev, int flag, int mode)
|
||||
{
|
||||
register struct uartreg *reg;
|
||||
register struct tty *tp;
|
||||
register int unit = minor(dev);
|
||||
register struct uartreg *reg;
|
||||
register struct tty *tp;
|
||||
register int unit = minor(dev);
|
||||
|
||||
if (unit >= NUART)
|
||||
return (ENXIO);
|
||||
if (unit >= NUART)
|
||||
return (ENXIO);
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
tp = &uartttys[unit];
|
||||
if (! tp->t_addr) {
|
||||
switch (unit) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
tp->t_addr = (caddr_t) uart[unit];
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
tp = &uartttys[unit];
|
||||
if (! tp->t_addr) {
|
||||
switch (unit) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
tp->t_addr = (caddr_t) uart[unit];
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
reg = (struct uartreg*) tp->t_addr;
|
||||
tp->t_oproc = uartstart;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
if (tp->t_ispeed == 0) {
|
||||
switch(unit)
|
||||
{
|
||||
case 0:
|
||||
tp->t_ispeed = BBAUD(UART1_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART1_BAUD);
|
||||
break;
|
||||
case 1:
|
||||
tp->t_ispeed = BBAUD(UART2_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART2_BAUD);
|
||||
break;
|
||||
case 2:
|
||||
tp->t_ispeed = BBAUD(UART3_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART3_BAUD);
|
||||
break;
|
||||
case 3:
|
||||
tp->t_ispeed = BBAUD(UART4_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART4_BAUD);
|
||||
break;
|
||||
case 4:
|
||||
tp->t_ispeed = BBAUD(UART5_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART5_BAUD);
|
||||
break;
|
||||
case 5:
|
||||
tp->t_ispeed = BBAUD(UART6_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART6_BAUD);
|
||||
break;
|
||||
}
|
||||
reg = (struct uartreg*) tp->t_addr;
|
||||
tp->t_oproc = uartstart;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
if (tp->t_ispeed == 0) {
|
||||
switch(unit) {
|
||||
case 0:
|
||||
tp->t_ispeed = BBAUD(UART1_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART1_BAUD);
|
||||
break;
|
||||
case 1:
|
||||
tp->t_ispeed = BBAUD(UART2_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART2_BAUD);
|
||||
break;
|
||||
case 2:
|
||||
tp->t_ispeed = BBAUD(UART3_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART3_BAUD);
|
||||
break;
|
||||
case 3:
|
||||
tp->t_ispeed = BBAUD(UART4_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART4_BAUD);
|
||||
break;
|
||||
case 4:
|
||||
tp->t_ispeed = BBAUD(UART5_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART5_BAUD);
|
||||
break;
|
||||
case 5:
|
||||
tp->t_ispeed = BBAUD(UART6_BAUD);
|
||||
tp->t_ospeed = BBAUD(UART6_BAUD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ttychars(tp);
|
||||
tp->t_state = TS_ISOPEN | TS_CARR_ON;
|
||||
tp->t_flags = ECHO | XTABS | CRMOD | CRTBS | CRTERA | CTLECH | CRTKIL;
|
||||
}
|
||||
if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0)
|
||||
return (EBUSY);
|
||||
}
|
||||
ttychars(tp);
|
||||
tp->t_state = TS_ISOPEN | TS_CARR_ON;
|
||||
tp->t_flags = ECHO | XTABS | CRMOD | CRTBS | CRTERA | CTLECH | CRTKIL;
|
||||
}
|
||||
if ((tp->t_state & TS_XCLUDE) && u.u_uid != 0)
|
||||
return (EBUSY);
|
||||
|
||||
reg->sta = 0;
|
||||
reg->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, speed_bps [tp->t_ospeed]);
|
||||
reg->mode = PIC32_UMODE_PDSEL_8NPAR |
|
||||
PIC32_UMODE_ON;
|
||||
reg->staset = PIC32_USTA_URXEN | PIC32_USTA_UTXEN;
|
||||
reg->sta = 0;
|
||||
reg->brg = PIC32_BRG_BAUD (BUS_KHZ * 1000, speed_bps [tp->t_ospeed]);
|
||||
reg->mode = PIC32_UMODE_PDSEL_8NPAR |
|
||||
PIC32_UMODE_ON;
|
||||
reg->staset = PIC32_USTA_URXEN | PIC32_USTA_UTXEN;
|
||||
|
||||
/* Enable receive interrupt. */
|
||||
if (uirq[unit].rx < 32)
|
||||
{
|
||||
IECSET(0) = 1 << uirq[unit].rx;
|
||||
} else if (uirq[unit].rx < 64)
|
||||
{
|
||||
IECSET(1) = 1 << (uirq[unit].rx-32);
|
||||
} else {
|
||||
IECSET(2) = 1 << (uirq[unit].rx-64);
|
||||
}
|
||||
return ttyopen(dev, tp);
|
||||
/* Enable receive interrupt. */
|
||||
if (uirq[unit].rx < 32) {
|
||||
IECSET(0) = 1 << uirq[unit].rx;
|
||||
} else if (uirq[unit].rx < 64) {
|
||||
IECSET(1) = 1 << (uirq[unit].rx-32);
|
||||
} else {
|
||||
IECSET(2) = 1 << (uirq[unit].rx-64);
|
||||
}
|
||||
return ttyopen(dev, tp);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
uartclose (dev, flag, mode)
|
||||
dev_t dev;
|
||||
uartclose (dev_t dev, int flag, int mode)
|
||||
{
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
ttyclose(tp);
|
||||
return(0);
|
||||
ttywflush(tp);
|
||||
ttyclose(tp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
uartread (dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
return ttread(tp, uio, flag);
|
||||
return ttread(tp, uio, flag);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
uartwrite (dev, uio, flag)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int flag;
|
||||
{
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
return ttwrite(tp, uio, flag);
|
||||
return ttwrite(tp, uio, flag);
|
||||
}
|
||||
|
||||
int
|
||||
uartselect (dev, rw)
|
||||
register dev_t dev;
|
||||
int rw;
|
||||
register dev_t dev;
|
||||
int rw;
|
||||
{
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
return (ttyselect (tp, rw));
|
||||
return (ttyselect (tp, rw));
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
uartioctl (dev, cmd, addr, flag)
|
||||
dev_t dev;
|
||||
register u_int cmd;
|
||||
caddr_t addr;
|
||||
dev_t dev;
|
||||
register u_int cmd;
|
||||
caddr_t addr;
|
||||
{
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int error;
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register int error;
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
if (unit==0)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
if (unit==1)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
if (unit==2)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
if (unit==3)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
if (unit==4)
|
||||
return ENODEV;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
if (unit==5)
|
||||
return ENODEV;
|
||||
#endif
|
||||
if ((SD0_PORT == 2) && (unit==2 || unit==5))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 3) && (unit==0 || unit==3))
|
||||
return (ENODEV);
|
||||
if ((SD0_PORT == 4) && (unit==1 || unit==4))
|
||||
return (ENODEV);
|
||||
|
||||
error = ttioctl(tp, cmd, addr, flag);
|
||||
if (error < 0)
|
||||
error = ENOTTY;
|
||||
return (error);
|
||||
error = ttioctl(tp, cmd, addr, flag);
|
||||
if (error < 0)
|
||||
error = ENOTTY;
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
uartintr (dev)
|
||||
dev_t dev;
|
||||
dev_t dev;
|
||||
{
|
||||
register int c;
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register struct uartreg *reg = (struct uartreg *)tp->t_addr;
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return;
|
||||
#endif
|
||||
/* Receive */
|
||||
while (reg->sta & PIC32_USTA_URXDA) {
|
||||
c = reg->rxreg;
|
||||
ttyinput(c, tp);
|
||||
}
|
||||
if (reg->sta & PIC32_USTA_OERR)
|
||||
reg->staclr = PIC32_USTA_OERR;
|
||||
|
||||
if (uirq[unit].rx < 32)
|
||||
{
|
||||
IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er);
|
||||
} else if (uirq[unit].rx < 64)
|
||||
{
|
||||
IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32));
|
||||
} else {
|
||||
IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64));
|
||||
}
|
||||
|
||||
/* Transmit */
|
||||
if (reg->sta & PIC32_USTA_TRMT) {
|
||||
led_control (LED_TTY, 0);
|
||||
|
||||
if (uirq[unit].tx < 32)
|
||||
{
|
||||
IECCLR(0) = 1 << uirq[unit].tx;
|
||||
IFSCLR(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
IFSCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
IFSCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
ttstart(tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uartstart (register struct tty *tp)
|
||||
{
|
||||
register struct uartreg *reg = (struct uartreg*) tp->t_addr;
|
||||
register int c, s;
|
||||
register int unit = minor(tp->t_dev);
|
||||
register int c;
|
||||
register int unit = minor(dev);
|
||||
register struct tty *tp = &uartttys[unit];
|
||||
register struct uartreg *reg = (struct uartreg *)tp->t_addr;
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
@@ -636,31 +533,101 @@ void uartstart (register struct tty *tp)
|
||||
if (unit==5)
|
||||
return;
|
||||
#endif
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
|
||||
out: /* Disable transmit_interrupt. */
|
||||
led_control (LED_TTY, 0);
|
||||
splx (s);
|
||||
return;
|
||||
}
|
||||
ttyowake(tp);
|
||||
if (tp->t_outq.c_cc == 0)
|
||||
goto out;
|
||||
if (reg->sta & PIC32_USTA_TRMT) {
|
||||
c = getc(&tp->t_outq);
|
||||
reg->txreg = c & 0xff;
|
||||
tp->t_state |= TS_BUSY;
|
||||
}
|
||||
/* Enable transmit interrupt. */
|
||||
if (uirq[unit].tx < 32) {
|
||||
IECSET(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECSET(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECSET(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
led_control (LED_TTY, 1);
|
||||
splx (s);
|
||||
/* Receive */
|
||||
while (reg->sta & PIC32_USTA_URXDA) {
|
||||
c = reg->rxreg;
|
||||
ttyinput(c, tp);
|
||||
}
|
||||
if (reg->sta & PIC32_USTA_OERR)
|
||||
reg->staclr = PIC32_USTA_OERR;
|
||||
|
||||
if (uirq[unit].rx < 32) {
|
||||
IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er);
|
||||
} else if (uirq[unit].rx < 64) {
|
||||
IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32));
|
||||
} else {
|
||||
IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64));
|
||||
}
|
||||
|
||||
/* Transmit */
|
||||
if (reg->sta & PIC32_USTA_TRMT) {
|
||||
led_control (LED_TTY, 0);
|
||||
|
||||
if (uirq[unit].tx < 32) {
|
||||
IECCLR(0) = 1 << uirq[unit].tx;
|
||||
IFSCLR(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
IFSCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
IFSCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
ttstart(tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uartstart (register struct tty *tp)
|
||||
{
|
||||
register struct uartreg *reg = (struct uartreg*) tp->t_addr;
|
||||
register int c, s;
|
||||
register int unit = minor(tp->t_dev);
|
||||
|
||||
#ifndef UART1_ENABLED
|
||||
if (unit==0)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART2_ENABLED
|
||||
if (unit==1)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART3_ENABLED
|
||||
if (unit==2)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART4_ENABLED
|
||||
if (unit==3)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART5_ENABLED
|
||||
if (unit==4)
|
||||
return;
|
||||
#endif
|
||||
#ifndef UART6_ENABLED
|
||||
if (unit==5)
|
||||
return;
|
||||
#endif
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) {
|
||||
out: /* Disable transmit_interrupt. */
|
||||
led_control (LED_TTY, 0);
|
||||
splx (s);
|
||||
return;
|
||||
}
|
||||
ttyowake(tp);
|
||||
if (tp->t_outq.c_cc == 0)
|
||||
goto out;
|
||||
|
||||
if (reg->sta & PIC32_USTA_TRMT) {
|
||||
c = getc(&tp->t_outq);
|
||||
reg->txreg = c & 0xff;
|
||||
tp->t_state |= TS_BUSY;
|
||||
}
|
||||
|
||||
/* Enable transmit interrupt. */
|
||||
if (uirq[unit].tx < 32) {
|
||||
IECSET(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECSET(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECSET(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
led_control (LED_TTY, 1);
|
||||
splx (s);
|
||||
}
|
||||
|
||||
void uartputc(dev_t dev, char c)
|
||||
@@ -704,9 +671,10 @@ again:
|
||||
while ((reg->sta & PIC32_USTA_TRMT) == 0)
|
||||
if (--timo == 0)
|
||||
break;
|
||||
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
uartintr (dev);
|
||||
goto again;
|
||||
uartintr (dev);
|
||||
goto again;
|
||||
}
|
||||
led_control (LED_TTY, 1);
|
||||
reg->txreg = c;
|
||||
@@ -717,18 +685,17 @@ again:
|
||||
break;
|
||||
|
||||
/* Clear TX interrupt. */
|
||||
if (uirq[unit].tx < 32) {
|
||||
IECCLR(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
if (uirq[unit].tx < 32) {
|
||||
IECCLR(0) = 1 << uirq[unit].tx;
|
||||
} else if (uirq[unit].tx < 64) {
|
||||
IECCLR(1) = 1 << (uirq[unit].tx - 32);
|
||||
} else {
|
||||
IECCLR(2) = 1 << (uirq[unit].tx - 64);
|
||||
}
|
||||
led_control(LED_TTY, 0);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
char uartgetc(dev_t dev)
|
||||
{
|
||||
int unit = minor(dev);
|
||||
@@ -767,13 +734,14 @@ char uartgetc(dev_t dev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (uirq[unit].rx < 32) {
|
||||
IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er);
|
||||
} else if (uirq[unit].rx < 64) {
|
||||
IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32));
|
||||
} else {
|
||||
IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64));
|
||||
}
|
||||
|
||||
if (uirq[unit].rx < 32) {
|
||||
IFSCLR(0) = (1 << uirq[unit].rx) | (1 << uirq[unit].er);
|
||||
} else if (uirq[unit].rx < 64) {
|
||||
IFSCLR(1) = (1 << (uirq[unit].rx-32)) | (1 << (uirq[unit].er-32));
|
||||
} else {
|
||||
IFSCLR(2) = (1 << (uirq[unit].rx-64)) | (1 << (uirq[unit].er-64));
|
||||
}
|
||||
splx(s);
|
||||
return (unsigned char) c;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user