Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (36 commits) serial: apbuart: Fixup apbuart_console_init() TTY: Add tty ioctl to figure device node of the system console. tty: add 'active' sysfs attribute to tty0 and console device drivers: serial: apbuart: Handle OF failures gracefully Serial: Avoid unbalanced IRQ wake disable during resume tty: fix typos/errors in tty_driver.h comments pch_uart : fix warnings for 64bit compile 8250: fix uninitialized FIFOs ip2: fix compiler warning on ip2main_pci_tbl specialix: fix compiler warning on specialix_pci_tbl rocket: fix compiler warning on rocket_pci_ids 8250: add a UPIO_DWAPB32 for 32 bit accesses 8250: use container_of() instead of casting serial: omap-serial: Add support for kernel debugger serial: fix pch_uart kconfig & build drivers: char: hvc: add arm JTAG DCC console support RS485 documentation: add 16C950 UART description serial: ifx6x60: fix memory leak serial: ifx6x60: free IRQ on error Serial: EG20T: add PCH_UART driver ... Fixed up conflicts in drivers/serial/apbuart.c with evil merge that makes the code look fairly sane (unlike either side).
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
*
|
||||
* TO DO:
|
||||
* Mostly done: ioctls for setting modes/timing
|
||||
* Partly done: hooks so you can pull off frames to non tty devs
|
||||
* Partly done: hooks so you can pull off frames to non tty devs
|
||||
* Restart DLCI 0 when it closes ?
|
||||
* Test basic encoding
|
||||
* Improve the tx engine
|
||||
@@ -73,8 +73,10 @@ module_param(debug, int, 0600);
|
||||
#define T2 (2 * HZ)
|
||||
#endif
|
||||
|
||||
/* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
|
||||
limits so this is plenty */
|
||||
/*
|
||||
* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
|
||||
* limits so this is plenty
|
||||
*/
|
||||
#define MAX_MRU 512
|
||||
#define MAX_MTU 512
|
||||
|
||||
@@ -184,6 +186,9 @@ struct gsm_mux {
|
||||
#define GSM_DATA 5
|
||||
#define GSM_FCS 6
|
||||
#define GSM_OVERRUN 7
|
||||
#define GSM_LEN0 8
|
||||
#define GSM_LEN1 9
|
||||
#define GSM_SSOF 10
|
||||
unsigned int len;
|
||||
unsigned int address;
|
||||
unsigned int count;
|
||||
@@ -191,6 +196,7 @@ struct gsm_mux {
|
||||
int encoding;
|
||||
u8 control;
|
||||
u8 fcs;
|
||||
u8 received_fcs;
|
||||
u8 *txframe; /* TX framing buffer */
|
||||
|
||||
/* Methods for the receiver side */
|
||||
@@ -286,7 +292,7 @@ static spinlock_t gsm_mux_lock;
|
||||
#define MDM_DV 0x40
|
||||
|
||||
#define GSM0_SOF 0xF9
|
||||
#define GSM1_SOF 0x7E
|
||||
#define GSM1_SOF 0x7E
|
||||
#define GSM1_ESCAPE 0x7D
|
||||
#define GSM1_ESCAPE_BITS 0x20
|
||||
#define XON 0x11
|
||||
@@ -429,61 +435,63 @@ static void gsm_print_packet(const char *hdr, int addr, int cr,
|
||||
if (!(debug & 1))
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
|
||||
pr_info("%s %d) %c: ", hdr, addr, "RC"[cr]);
|
||||
|
||||
switch (control & ~PF) {
|
||||
case SABM:
|
||||
printk(KERN_CONT "SABM");
|
||||
pr_cont("SABM");
|
||||
break;
|
||||
case UA:
|
||||
printk(KERN_CONT "UA");
|
||||
pr_cont("UA");
|
||||
break;
|
||||
case DISC:
|
||||
printk(KERN_CONT "DISC");
|
||||
pr_cont("DISC");
|
||||
break;
|
||||
case DM:
|
||||
printk(KERN_CONT "DM");
|
||||
pr_cont("DM");
|
||||
break;
|
||||
case UI:
|
||||
printk(KERN_CONT "UI");
|
||||
pr_cont("UI");
|
||||
break;
|
||||
case UIH:
|
||||
printk(KERN_CONT "UIH");
|
||||
pr_cont("UIH");
|
||||
break;
|
||||
default:
|
||||
if (!(control & 0x01)) {
|
||||
printk(KERN_CONT "I N(S)%d N(R)%d",
|
||||
(control & 0x0E) >> 1, (control & 0xE)>> 5);
|
||||
pr_cont("I N(S)%d N(R)%d",
|
||||
(control & 0x0E) >> 1, (control & 0xE) >> 5);
|
||||
} else switch (control & 0x0F) {
|
||||
case RR:
|
||||
printk("RR(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
case RNR:
|
||||
printk("RNR(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
case REJ:
|
||||
printk("REJ(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_CONT "[%02X]", control);
|
||||
case RR:
|
||||
pr_cont("RR(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
case RNR:
|
||||
pr_cont("RNR(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
case REJ:
|
||||
pr_cont("REJ(%d)", (control & 0xE0) >> 5);
|
||||
break;
|
||||
default:
|
||||
pr_cont("[%02X]", control);
|
||||
}
|
||||
}
|
||||
|
||||
if (control & PF)
|
||||
printk(KERN_CONT "(P)");
|
||||
pr_cont("(P)");
|
||||
else
|
||||
printk(KERN_CONT "(F)");
|
||||
pr_cont("(F)");
|
||||
|
||||
if (dlen) {
|
||||
int ct = 0;
|
||||
while (dlen--) {
|
||||
if (ct % 8 == 0)
|
||||
printk(KERN_CONT "\n ");
|
||||
printk(KERN_CONT "%02X ", *data++);
|
||||
if (ct % 8 == 0) {
|
||||
pr_cont("\n");
|
||||
pr_debug(" ");
|
||||
}
|
||||
pr_cont("%02X ", *data++);
|
||||
ct++;
|
||||
}
|
||||
}
|
||||
printk(KERN_CONT "\n");
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -522,11 +530,13 @@ static void hex_packet(const unsigned char *p, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i && (i % 16) == 0)
|
||||
printk("\n");
|
||||
printk("%02X ", *p++);
|
||||
if (i && (i % 16) == 0) {
|
||||
pr_cont("\n");
|
||||
pr_debug("");
|
||||
}
|
||||
pr_cont("%02X ", *p++);
|
||||
}
|
||||
printk("\n");
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -676,7 +686,7 @@ static void gsm_data_kick(struct gsm_mux *gsm)
|
||||
}
|
||||
|
||||
if (debug & 4) {
|
||||
printk("gsm_data_kick: \n");
|
||||
pr_debug("gsm_data_kick:\n");
|
||||
hex_packet(gsm->txframe, len);
|
||||
}
|
||||
|
||||
@@ -1231,7 +1241,7 @@ static void gsm_control_response(struct gsm_mux *gsm, unsigned int command,
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_control_transmit - send control packet
|
||||
* gsm_control_transmit - send control packet
|
||||
* @gsm: gsm mux
|
||||
* @ctrl: frame to send
|
||||
*
|
||||
@@ -1361,7 +1371,7 @@ static void gsm_dlci_close(struct gsm_dlci *dlci)
|
||||
{
|
||||
del_timer(&dlci->t1);
|
||||
if (debug & 8)
|
||||
printk("DLCI %d goes closed.\n", dlci->addr);
|
||||
pr_debug("DLCI %d goes closed.\n", dlci->addr);
|
||||
dlci->state = DLCI_CLOSED;
|
||||
if (dlci->addr != 0) {
|
||||
struct tty_struct *tty = tty_port_tty_get(&dlci->port);
|
||||
@@ -1392,7 +1402,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
|
||||
/* This will let a tty open continue */
|
||||
dlci->state = DLCI_OPEN;
|
||||
if (debug & 8)
|
||||
printk("DLCI %d goes open.\n", dlci->addr);
|
||||
pr_debug("DLCI %d goes open.\n", dlci->addr);
|
||||
wake_up(&dlci->gsm->event);
|
||||
}
|
||||
|
||||
@@ -1494,29 +1504,29 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
|
||||
unsigned int modem = 0;
|
||||
|
||||
if (debug & 16)
|
||||
printk("%d bytes for tty %p\n", len, tty);
|
||||
pr_debug("%d bytes for tty %p\n", len, tty);
|
||||
if (tty) {
|
||||
switch (dlci->adaption) {
|
||||
/* Unsupported types */
|
||||
/* Packetised interruptible data */
|
||||
case 4:
|
||||
break;
|
||||
/* Packetised uininterruptible voice/data */
|
||||
case 3:
|
||||
break;
|
||||
/* Asynchronous serial with line state in each frame */
|
||||
case 2:
|
||||
while (gsm_read_ea(&modem, *data++) == 0) {
|
||||
len--;
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
gsm_process_modem(tty, dlci, modem);
|
||||
/* Line state will go via DLCI 0 controls only */
|
||||
case 1:
|
||||
default:
|
||||
tty_insert_flip_string(tty, data, len);
|
||||
tty_flip_buffer_push(tty);
|
||||
/* Unsupported types */
|
||||
/* Packetised interruptible data */
|
||||
case 4:
|
||||
break;
|
||||
/* Packetised uininterruptible voice/data */
|
||||
case 3:
|
||||
break;
|
||||
/* Asynchronous serial with line state in each frame */
|
||||
case 2:
|
||||
while (gsm_read_ea(&modem, *data++) == 0) {
|
||||
len--;
|
||||
if (len == 0)
|
||||
return;
|
||||
}
|
||||
gsm_process_modem(tty, dlci, modem);
|
||||
/* Line state will go via DLCI 0 controls only */
|
||||
case 1:
|
||||
default:
|
||||
tty_insert_flip_string(tty, data, len);
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
tty_kref_put(tty);
|
||||
}
|
||||
@@ -1625,7 +1635,6 @@ static void gsm_dlci_free(struct gsm_dlci *dlci)
|
||||
kfree(dlci);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LAPBish link layer logic
|
||||
*/
|
||||
@@ -1650,10 +1659,12 @@ static void gsm_queue(struct gsm_mux *gsm)
|
||||
|
||||
if ((gsm->control & ~PF) == UI)
|
||||
gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
|
||||
/* generate final CRC with received FCS */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs);
|
||||
if (gsm->fcs != GOOD_FCS) {
|
||||
gsm->bad_fcs++;
|
||||
if (debug & 4)
|
||||
printk("BAD FCS %02x\n", gsm->fcs);
|
||||
pr_debug("BAD FCS %02x\n", gsm->fcs);
|
||||
return;
|
||||
}
|
||||
address = gsm->address >> 1;
|
||||
@@ -1748,6 +1759,8 @@ invalid:
|
||||
|
||||
static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
{
|
||||
unsigned int len;
|
||||
|
||||
switch (gsm->state) {
|
||||
case GSM_SEARCH: /* SOF marker */
|
||||
if (c == GSM0_SOF) {
|
||||
@@ -1756,8 +1769,8 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
gsm->len = 0;
|
||||
gsm->fcs = INIT_FCS;
|
||||
}
|
||||
break; /* Address EA */
|
||||
case GSM_ADDRESS:
|
||||
break;
|
||||
case GSM_ADDRESS: /* Address EA */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
|
||||
if (gsm_read_ea(&gsm->address, c))
|
||||
gsm->state = GSM_CONTROL;
|
||||
@@ -1765,9 +1778,9 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
case GSM_CONTROL: /* Control Byte */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
|
||||
gsm->control = c;
|
||||
gsm->state = GSM_LEN;
|
||||
gsm->state = GSM_LEN0;
|
||||
break;
|
||||
case GSM_LEN: /* Length EA */
|
||||
case GSM_LEN0: /* Length EA */
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
|
||||
if (gsm_read_ea(&gsm->len, c)) {
|
||||
if (gsm->len > gsm->mru) {
|
||||
@@ -1776,8 +1789,28 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
break;
|
||||
}
|
||||
gsm->count = 0;
|
||||
gsm->state = GSM_DATA;
|
||||
if (!gsm->len)
|
||||
gsm->state = GSM_FCS;
|
||||
else
|
||||
gsm->state = GSM_DATA;
|
||||
break;
|
||||
}
|
||||
gsm->state = GSM_LEN1;
|
||||
break;
|
||||
case GSM_LEN1:
|
||||
gsm->fcs = gsm_fcs_add(gsm->fcs, c);
|
||||
len = c;
|
||||
gsm->len |= len << 7;
|
||||
if (gsm->len > gsm->mru) {
|
||||
gsm->bad_size++;
|
||||
gsm->state = GSM_SEARCH;
|
||||
break;
|
||||
}
|
||||
gsm->count = 0;
|
||||
if (!gsm->len)
|
||||
gsm->state = GSM_FCS;
|
||||
else
|
||||
gsm->state = GSM_DATA;
|
||||
break;
|
||||
case GSM_DATA: /* Data */
|
||||
gsm->buf[gsm->count++] = c;
|
||||
@@ -1785,16 +1818,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
gsm->state = GSM_FCS;
|
||||
break;
|
||||
case GSM_FCS: /* FCS follows the packet */
|
||||
gsm->fcs = c;
|
||||
gsm->received_fcs = c;
|
||||
if (c == GSM0_SOF) {
|
||||
gsm->state = GSM_SEARCH;
|
||||
break;
|
||||
}
|
||||
gsm_queue(gsm);
|
||||
/* And then back for the next frame */
|
||||
gsm->state = GSM_SEARCH;
|
||||
gsm->state = GSM_SSOF;
|
||||
break;
|
||||
case GSM_SSOF:
|
||||
if (c == GSM0_SOF) {
|
||||
gsm->state = GSM_SEARCH;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm0_receive - perform processing for non-transparency
|
||||
* gsm1_receive - perform processing for non-transparency
|
||||
* @gsm: gsm data for this ldisc instance
|
||||
* @c: character
|
||||
*
|
||||
@@ -1856,7 +1898,7 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
|
||||
gsm->state = GSM_DATA;
|
||||
break;
|
||||
case GSM_DATA: /* Data */
|
||||
if (gsm->count > gsm->mru ) { /* Allow one for the FCS */
|
||||
if (gsm->count > gsm->mru) { /* Allow one for the FCS */
|
||||
gsm->state = GSM_OVERRUN;
|
||||
gsm->bad_size++;
|
||||
} else
|
||||
@@ -2034,9 +2076,6 @@ struct gsm_mux *gsm_alloc_mux(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gsm_alloc_mux);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* gsmld_output - write to link
|
||||
* @gsm: our mux
|
||||
@@ -2054,7 +2093,7 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
|
||||
return -ENOSPC;
|
||||
}
|
||||
if (debug & 4) {
|
||||
printk("-->%d bytes out\n", len);
|
||||
pr_debug("-->%d bytes out\n", len);
|
||||
hex_packet(data, len);
|
||||
}
|
||||
gsm->tty->ops->write(gsm->tty, data, len);
|
||||
@@ -2111,7 +2150,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char flags;
|
||||
|
||||
if (debug & 4) {
|
||||
printk("Inbytes %dd\n", count);
|
||||
pr_debug("Inbytes %dd\n", count);
|
||||
hex_packet(cp, count);
|
||||
}
|
||||
|
||||
@@ -2128,7 +2167,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
gsm->error(gsm, *dp, flags);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: unknown flag %d\n",
|
||||
WARN_ONCE("%s: unknown flag %d\n",
|
||||
tty_name(tty, buf), flags);
|
||||
break;
|
||||
}
|
||||
@@ -2323,7 +2362,7 @@ static int gsmld_config(struct tty_struct *tty, struct gsm_mux *gsm,
|
||||
int need_restart = 0;
|
||||
|
||||
/* Stuff we don't support yet - UI or I frame transport, windowing */
|
||||
if ((c->adaption !=1 && c->adaption != 2) || c->k)
|
||||
if ((c->adaption != 1 && c->adaption != 2) || c->k)
|
||||
return -EOPNOTSUPP;
|
||||
/* Check the MRU/MTU range looks sane */
|
||||
if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
|
||||
@@ -2418,7 +2457,7 @@ static int gsmld_ioctl(struct tty_struct *tty, struct file *file,
|
||||
c.i = 1;
|
||||
else
|
||||
c.i = 2;
|
||||
printk("Ftype %d i %d\n", gsm->ftype, c.i);
|
||||
pr_debug("Ftype %d i %d\n", gsm->ftype, c.i);
|
||||
c.mru = gsm->mru;
|
||||
c.mtu = gsm->mtu;
|
||||
c.k = 0;
|
||||
@@ -2712,14 +2751,15 @@ static int __init gsm_init(void)
|
||||
/* Fill in our line protocol discipline, and register it */
|
||||
int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet);
|
||||
if (status != 0) {
|
||||
printk(KERN_ERR "n_gsm: can't register line discipline (err = %d)\n", status);
|
||||
pr_err("n_gsm: can't register line discipline (err = %d)\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
gsm_tty_driver = alloc_tty_driver(256);
|
||||
if (!gsm_tty_driver) {
|
||||
tty_unregister_ldisc(N_GSM0710);
|
||||
printk(KERN_ERR "gsm_init: tty allocation failed.\n");
|
||||
pr_err("gsm_init: tty allocation failed.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
gsm_tty_driver->owner = THIS_MODULE;
|
||||
@@ -2730,7 +2770,7 @@ static int __init gsm_init(void)
|
||||
gsm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
|
||||
gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
|
||||
gsm_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
|
||||
| TTY_DRIVER_HARDWARE_BREAK;
|
||||
| TTY_DRIVER_HARDWARE_BREAK;
|
||||
gsm_tty_driver->init_termios = tty_std_termios;
|
||||
/* Fixme */
|
||||
gsm_tty_driver->init_termios.c_lflag &= ~ECHO;
|
||||
@@ -2741,10 +2781,11 @@ static int __init gsm_init(void)
|
||||
if (tty_register_driver(gsm_tty_driver)) {
|
||||
put_tty_driver(gsm_tty_driver);
|
||||
tty_unregister_ldisc(N_GSM0710);
|
||||
printk(KERN_ERR "gsm_init: tty registration failed.\n");
|
||||
pr_err("gsm_init: tty registration failed.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
printk(KERN_INFO "gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start);
|
||||
pr_debug("gsm_init: loaded as %d,%d.\n",
|
||||
gsm_tty_driver->major, gsm_tty_driver->minor_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2752,10 +2793,10 @@ static void __exit gsm_exit(void)
|
||||
{
|
||||
int status = tty_unregister_ldisc(N_GSM0710);
|
||||
if (status != 0)
|
||||
printk(KERN_ERR "n_gsm: can't unregister line discipline (err = %d)\n", status);
|
||||
pr_err("n_gsm: can't unregister line discipline (err = %d)\n",
|
||||
status);
|
||||
tty_unregister_driver(gsm_tty_driver);
|
||||
put_tty_driver(gsm_tty_driver);
|
||||
printk(KERN_INFO "gsm_init: unloaded.\n");
|
||||
}
|
||||
|
||||
module_init(gsm_init);
|
||||
|
Reference in New Issue
Block a user