Commit ed3cb6f0 authored by Richard Hitt's avatar Richard Hitt Committed by Linus Torvalds

[PATCH] s390: 3270 fullscreen view

      Martin Schwidefsky <schwidefsky@de.ibm.com>

Fix fullscreen view of the 3270 device driver.
Signed-off-by: default avatarRichard Hitt <rbh00@utsglobal.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d89ea9b8
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#include <asm/dasd.h> #include <asm/dasd.h>
#include <asm/cmb.h> #include <asm/cmb.h>
#include <asm/tape390.h> #include <asm/tape390.h>
#include <asm/ccwdev.h>
#include "../../../drivers/s390/char/raw3270.h"
static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd, static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
unsigned long arg, struct file *f) unsigned long arg, struct file *f)
...@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE) ...@@ -62,6 +64,13 @@ COMPATIBLE_IOCTL(BIODASDCMFENABLE)
COMPATIBLE_IOCTL(BIODASDCMFDISABLE) COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
COMPATIBLE_IOCTL(BIODASDREADALLCMB) COMPATIBLE_IOCTL(BIODASDREADALLCMB)
COMPATIBLE_IOCTL(TUBICMD)
COMPATIBLE_IOCTL(TUBOCMD)
COMPATIBLE_IOCTL(TUBGETI)
COMPATIBLE_IOCTL(TUBGETO)
COMPATIBLE_IOCTL(TUBSETMOD)
COMPATIBLE_IOCTL(TUBGETMOD)
COMPATIBLE_IOCTL(TAPE390_DISPLAY) COMPATIBLE_IOCTL(TAPE390_DISPLAY)
/* s390 doesn't need handlers here */ /* s390 doesn't need handlers here */
......
...@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp) ...@@ -213,6 +213,9 @@ con3270_update(struct con3270 *cp)
struct string *s, *n; struct string *s, *n;
int rc; int rc;
if (cp->view.dev)
raw3270_activate_view(&cp->view);
wrq = xchg(&cp->write, 0); wrq = xchg(&cp->write, 0);
if (!wrq) { if (!wrq) {
con3270_set_timer(cp, 1); con3270_set_timer(cp, 1);
...@@ -489,8 +492,6 @@ con3270_write(struct console *co, const char *str, unsigned int count) ...@@ -489,8 +492,6 @@ con3270_write(struct console *co, const char *str, unsigned int count)
unsigned char c; unsigned char c;
cp = condev; cp = condev;
if (cp->view.dev)
raw3270_activate_view(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags); spin_lock_irqsave(&cp->view.lock, flags);
while (count-- > 0) { while (count-- > 0) {
c = *str++; c = *str++;
...@@ -620,7 +621,7 @@ con3270_init(void) ...@@ -620,7 +621,7 @@ con3270_init(void)
(void (*)(unsigned long)) con3270_read_tasklet, (void (*)(unsigned long)) con3270_read_tasklet,
(unsigned long) condev->read); (unsigned long) condev->read);
raw3270_add_view(&condev->view, &con3270_fn, 0); raw3270_add_view(&condev->view, &con3270_fn, 1);
INIT_LIST_HEAD(&condev->freemem); INIT_LIST_HEAD(&condev->freemem);
for (i = 0; i < CON3270_STRING_PAGES; i++) { for (i = 0; i < CON3270_STRING_PAGES; i++) {
......
This diff is collapsed.
...@@ -25,6 +25,12 @@ ...@@ -25,6 +25,12 @@
#include "raw3270.h" #include "raw3270.h"
#include <linux/major.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
struct class *class3270;
/* The main 3270 data structure. */ /* The main 3270 data structure. */
struct raw3270 { struct raw3270 {
struct list_head list; struct list_head list;
...@@ -41,6 +47,8 @@ struct raw3270 { ...@@ -41,6 +47,8 @@ struct raw3270 {
struct timer_list timer; /* Device timer. */ struct timer_list timer; /* Device timer. */
unsigned char *ascebc; /* ascii -> ebcdic table */ unsigned char *ascebc; /* ascii -> ebcdic table */
struct class_device *clttydev; /* 3270-class tty device ptr */
struct class_device *cltubdev; /* 3270-class tub device ptr */
}; };
/* raw3270->flags */ /* raw3270->flags */
...@@ -316,6 +324,22 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq) ...@@ -316,6 +324,22 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
return rc; return rc;
} }
int
raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
{
struct raw3270 *rp;
int rc;
rp = view->dev;
if (!rp || rp->view != view)
rc = -EACCES;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
else
rc = __raw3270_start(rp, view, rq);
return rc;
}
int int
raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq) raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
{ {
...@@ -744,6 +768,22 @@ raw3270_reset_device(struct raw3270 *rp) ...@@ -744,6 +768,22 @@ raw3270_reset_device(struct raw3270 *rp)
return rc; return rc;
} }
int
raw3270_reset(struct raw3270_view *view)
{
struct raw3270 *rp;
int rc;
rp = view->dev;
if (!rp || rp->view != view)
rc = -EACCES;
else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
rc = -ENODEV;
else
rc = raw3270_reset_device(view->dev);
return rc;
}
/* /*
* Setup new 3270 device. * Setup new 3270 device.
*/ */
...@@ -774,11 +814,12 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) ...@@ -774,11 +814,12 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
/* /*
* Add device to list and find the smallest unused minor * Add device to list and find the smallest unused minor
* number for it. * number for it. Note: there is no device with minor 0,
* see special case for fs3270.c:fs3270_open().
*/ */
down(&raw3270_sem); down(&raw3270_sem);
/* Keep the list sorted. */ /* Keep the list sorted. */
minor = 0; minor = RAW3270_FIRSTMINOR;
rp->minor = -1; rp->minor = -1;
list_for_each(l, &raw3270_devices) { list_for_each(l, &raw3270_devices) {
tmp = list_entry(l, struct raw3270, list); tmp = list_entry(l, struct raw3270, list);
...@@ -789,7 +830,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc) ...@@ -789,7 +830,7 @@ raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc)
} }
minor++; minor++;
} }
if (rp->minor == -1 && minor < RAW3270_MAXDEVS) { if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
rp->minor = minor; rp->minor = minor;
list_add_tail(&rp->list, &raw3270_devices); list_add_tail(&rp->list, &raw3270_devices);
} }
...@@ -941,11 +982,12 @@ raw3270_deactivate_view(struct raw3270_view *view) ...@@ -941,11 +982,12 @@ raw3270_deactivate_view(struct raw3270_view *view)
list_add_tail(&view->list, &rp->view_list); list_add_tail(&view->list, &rp->view_list);
/* Try to activate another view. */ /* Try to activate another view. */
if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) { if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
list_for_each_entry(view, &rp->view_list, list) list_for_each_entry(view, &rp->view_list, list) {
if (view->fn->activate(view) == 0) { rp->view = view;
rp->view = view; if (view->fn->activate(view) == 0)
break; break;
} rp->view = 0;
}
} }
} }
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
...@@ -961,6 +1003,8 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) ...@@ -961,6 +1003,8 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
struct raw3270 *rp; struct raw3270 *rp;
int rc; int rc;
if (minor <= 0)
return -ENODEV;
down(&raw3270_sem); down(&raw3270_sem);
rc = -ENODEV; rc = -ENODEV;
list_for_each_entry(rp, &raw3270_devices, list) { list_for_each_entry(rp, &raw3270_devices, list) {
...@@ -976,7 +1020,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor) ...@@ -976,7 +1020,7 @@ raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor)
view->cols = rp->cols; view->cols = rp->cols;
view->ascebc = rp->ascebc; view->ascebc = rp->ascebc;
spin_lock_init(&view->lock); spin_lock_init(&view->lock);
list_add_tail(&view->list, &rp->view_list); list_add(&view->list, &rp->view_list);
rc = 0; rc = 0;
} }
spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
...@@ -1039,7 +1083,7 @@ raw3270_del_view(struct raw3270_view *view) ...@@ -1039,7 +1083,7 @@ raw3270_del_view(struct raw3270_view *view)
if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) { if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {
/* Try to activate another view. */ /* Try to activate another view. */
list_for_each_entry(nv, &rp->view_list, list) { list_for_each_entry(nv, &rp->view_list, list) {
if (nv->fn->activate(view) == 0) { if (nv->fn->activate(nv) == 0) {
rp->view = nv; rp->view = nv;
break; break;
} }
...@@ -1063,6 +1107,12 @@ raw3270_delete_device(struct raw3270 *rp) ...@@ -1063,6 +1107,12 @@ raw3270_delete_device(struct raw3270 *rp)
/* Remove from device chain. */ /* Remove from device chain. */
down(&raw3270_sem); down(&raw3270_sem);
if (rp->clttydev)
class_device_destroy(class3270,
MKDEV(IBM_TTY3270_MAJOR, rp->minor));
if (rp->cltubdev)
class_device_destroy(class3270,
MKDEV(IBM_FS3270_MAJOR, rp->minor));
list_del_init(&rp->list); list_del_init(&rp->list);
up(&raw3270_sem); up(&raw3270_sem);
...@@ -1129,6 +1179,16 @@ raw3270_create_attributes(struct raw3270 *rp) ...@@ -1129,6 +1179,16 @@ raw3270_create_attributes(struct raw3270 *rp)
{ {
//FIXME: check return code //FIXME: check return code
sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
rp->clttydev =
class_device_create(class3270,
MKDEV(IBM_TTY3270_MAJOR, rp->minor),
&rp->cdev->dev, "tty%s",
rp->cdev->dev.bus_id);
rp->cltubdev =
class_device_create(class3270,
MKDEV(IBM_FS3270_MAJOR, rp->minor),
&rp->cdev->dev, "tub%s",
rp->cdev->dev.bus_id);
} }
/* /*
...@@ -1189,13 +1249,13 @@ raw3270_set_online (struct ccw_device *cdev) ...@@ -1189,13 +1249,13 @@ raw3270_set_online (struct ccw_device *cdev)
return PTR_ERR(rp); return PTR_ERR(rp);
rc = raw3270_reset_device(rp); rc = raw3270_reset_device(rp);
if (rc) if (rc)
return rc; goto failure;
rc = raw3270_size_device(rp); rc = raw3270_size_device(rp);
if (rc) if (rc)
return rc; goto failure;
rc = raw3270_reset_device(rp); rc = raw3270_reset_device(rp);
if (rc) if (rc)
return rc; goto failure;
raw3270_create_attributes(rp); raw3270_create_attributes(rp);
set_bit(RAW3270_FLAGS_READY, &rp->flags); set_bit(RAW3270_FLAGS_READY, &rp->flags);
down(&raw3270_sem); down(&raw3270_sem);
...@@ -1203,6 +1263,10 @@ raw3270_set_online (struct ccw_device *cdev) ...@@ -1203,6 +1263,10 @@ raw3270_set_online (struct ccw_device *cdev)
np->notifier(rp->minor, 1); np->notifier(rp->minor, 1);
up(&raw3270_sem); up(&raw3270_sem);
return 0; return 0;
failure:
raw3270_delete_device(rp);
return rc;
} }
/* /*
...@@ -1217,6 +1281,14 @@ raw3270_remove (struct ccw_device *cdev) ...@@ -1217,6 +1281,14 @@ raw3270_remove (struct ccw_device *cdev)
struct raw3270_notifier *np; struct raw3270_notifier *np;
rp = cdev->dev.driver_data; rp = cdev->dev.driver_data;
/*
* _remove is the opposite of _probe; it's probe that
* should set up rp. raw3270_remove gets entered for
* devices even if they haven't been varied online.
* Thus, rp may validly be NULL here.
*/
if (rp == NULL)
return;
clear_bit(RAW3270_FLAGS_READY, &rp->flags); clear_bit(RAW3270_FLAGS_READY, &rp->flags);
sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group); sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
...@@ -1301,6 +1373,7 @@ raw3270_init(void) ...@@ -1301,6 +1373,7 @@ raw3270_init(void)
if (rc == 0) { if (rc == 0) {
/* Create attributes for early (= console) device. */ /* Create attributes for early (= console) device. */
down(&raw3270_sem); down(&raw3270_sem);
class3270 = class_create(THIS_MODULE, "3270");
list_for_each_entry(rp, &raw3270_devices, list) { list_for_each_entry(rp, &raw3270_devices, list) {
get_device(&rp->cdev->dev); get_device(&rp->cdev->dev);
raw3270_create_attributes(rp); raw3270_create_attributes(rp);
...@@ -1314,6 +1387,7 @@ static void ...@@ -1314,6 +1387,7 @@ static void
raw3270_exit(void) raw3270_exit(void)
{ {
ccw_driver_unregister(&raw3270_ccw_driver); ccw_driver_unregister(&raw3270_ccw_driver);
class_destroy(class3270);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -1335,7 +1409,9 @@ EXPORT_SYMBOL(raw3270_find_view); ...@@ -1335,7 +1409,9 @@ EXPORT_SYMBOL(raw3270_find_view);
EXPORT_SYMBOL(raw3270_activate_view); EXPORT_SYMBOL(raw3270_activate_view);
EXPORT_SYMBOL(raw3270_deactivate_view); EXPORT_SYMBOL(raw3270_deactivate_view);
EXPORT_SYMBOL(raw3270_start); EXPORT_SYMBOL(raw3270_start);
EXPORT_SYMBOL(raw3270_start_locked);
EXPORT_SYMBOL(raw3270_start_irq); EXPORT_SYMBOL(raw3270_start_irq);
EXPORT_SYMBOL(raw3270_reset);
EXPORT_SYMBOL(raw3270_register_notifier); EXPORT_SYMBOL(raw3270_register_notifier);
EXPORT_SYMBOL(raw3270_unregister_notifier); EXPORT_SYMBOL(raw3270_unregister_notifier);
EXPORT_SYMBOL(raw3270_wait_queue); EXPORT_SYMBOL(raw3270_wait_queue);
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/* Local Channel Commands */ /* Local Channel Commands */
#define TC_WRITE 0x01 /* Write */ #define TC_WRITE 0x01 /* Write */
#define TC_RDBUF 0x02 /* Read Buffer */
#define TC_EWRITE 0x05 /* Erase write */ #define TC_EWRITE 0x05 /* Erase write */
#define TC_READMOD 0x06 /* Read modified */ #define TC_READMOD 0x06 /* Read modified */
#define TC_EWRITEA 0x0d /* Erase write alternate */ #define TC_EWRITEA 0x0d /* Erase write alternate */
...@@ -76,7 +77,8 @@ ...@@ -76,7 +77,8 @@
#define TW_KR 0xc2 /* Keyboard restore */ #define TW_KR 0xc2 /* Keyboard restore */
#define TW_PLUSALARM 0x04 /* Add this bit for alarm */ #define TW_PLUSALARM 0x04 /* Add this bit for alarm */
#define RAW3270_MAXDEVS 256 #define RAW3270_FIRSTMINOR 1 /* First minor number */
#define RAW3270_MAXDEVS 255 /* Max number of 3270 devices */
/* For TUBGETMOD and TUBSETMOD. Should include. */ /* For TUBGETMOD and TUBSETMOD. Should include. */
struct raw3270_iocb { struct raw3270_iocb {
...@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_view *); ...@@ -166,7 +168,10 @@ void raw3270_del_view(struct raw3270_view *);
void raw3270_deactivate_view(struct raw3270_view *); void raw3270_deactivate_view(struct raw3270_view *);
struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int); struct raw3270_view *raw3270_find_view(struct raw3270_fn *, int);
int raw3270_start(struct raw3270_view *, struct raw3270_request *); int raw3270_start(struct raw3270_view *, struct raw3270_request *);
int raw3270_start_locked(struct raw3270_view *, struct raw3270_request *);
int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *); int raw3270_start_irq(struct raw3270_view *, struct raw3270_request *);
int raw3270_reset(struct raw3270_view *);
struct raw3270_view *raw3270_view(struct raw3270_view *);
/* Reference count inliner for view structures. */ /* Reference count inliner for view structures. */
static inline void static inline void
......
...@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *view) ...@@ -653,18 +653,12 @@ tty3270_activate(struct raw3270_view *view)
tp->update_flags = TTY_UPDATE_ALL; tp->update_flags = TTY_UPDATE_ALL;
tty3270_set_timer(tp, 1); tty3270_set_timer(tp, 1);
spin_unlock_irqrestore(&tp->view.lock, flags); spin_unlock_irqrestore(&tp->view.lock, flags);
start_tty(tp->tty);
return 0; return 0;
} }
static void static void
tty3270_deactivate(struct raw3270_view *view) tty3270_deactivate(struct raw3270_view *view)
{ {
struct tty3270 *tp;
tp = (struct tty3270 *) view;
if (tp && tp->tty)
stop_tty(tp->tty);
} }
static int static int
...@@ -716,13 +710,13 @@ tty3270_alloc_view(void) ...@@ -716,13 +710,13 @@ tty3270_alloc_view(void)
tp->freemem_pages[pages], PAGE_SIZE); tp->freemem_pages[pages], PAGE_SIZE);
} }
tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE); tp->write = raw3270_request_alloc(TTY3270_OUTPUT_BUFFER_SIZE);
if (!tp->write) if (IS_ERR(tp->write))
goto out_pages; goto out_pages;
tp->read = raw3270_request_alloc(0); tp->read = raw3270_request_alloc(0);
if (!tp->read) if (IS_ERR(tp->read))
goto out_write; goto out_write;
tp->kreset = raw3270_request_alloc(1); tp->kreset = raw3270_request_alloc(1);
if (!tp->kreset) if (IS_ERR(tp->kreset))
goto out_read; goto out_read;
tp->kbd = kbd_alloc(); tp->kbd = kbd_alloc();
if (!tp->kbd) if (!tp->kbd)
...@@ -845,7 +839,8 @@ tty3270_del_views(void) ...@@ -845,7 +839,8 @@ tty3270_del_views(void)
int i; int i;
for (i = 0; i < tty3270_max_index; i++) { for (i = 0; i < tty3270_max_index; i++) {
tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, i); tp = (struct tty3270 *)
raw3270_find_view(&tty3270_fn, i + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp)) if (!IS_ERR(tp))
raw3270_del_view(&tp->view); raw3270_del_view(&tp->view);
} }
...@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, struct file * filp) ...@@ -871,7 +866,9 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
if (tty->count > 1) if (tty->count > 1)
return 0; return 0;
/* Check if the tty3270 is already there. */ /* Check if the tty3270 is already there. */
tp = (struct tty3270 *) raw3270_find_view(&tty3270_fn, tty->index); tp = (struct tty3270 *)
raw3270_find_view(&tty3270_fn,
tty->index + RAW3270_FIRSTMINOR);
if (!IS_ERR(tp)) { if (!IS_ERR(tp)) {
tty->driver_data = tp; tty->driver_data = tp;
tty->winsize.ws_row = tp->view.rows - 2; tty->winsize.ws_row = tp->view.rows - 2;
...@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp) ...@@ -903,7 +900,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
(void (*)(unsigned long)) tty3270_read_tasklet, (void (*)(unsigned long)) tty3270_read_tasklet,
(unsigned long) tp->read); (unsigned long) tp->read);
rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index); rc = raw3270_add_view(&tp->view, &tty3270_fn,
tty->index + RAW3270_FIRSTMINOR);
if (rc) { if (rc) {
tty3270_free_view(tp); tty3270_free_view(tp);
return rc; return rc;
...@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp) ...@@ -911,8 +909,8 @@ tty3270_open(struct tty_struct *tty, struct file * filp)
rc = tty3270_alloc_screen(tp); rc = tty3270_alloc_screen(tp);
if (rc) { if (rc) {
raw3270_del_view(&tp->view);
raw3270_put_view(&tp->view); raw3270_put_view(&tp->view);
raw3270_del_view(&tp->view);
return rc; return rc;
} }
...@@ -1780,7 +1778,7 @@ tty3270_init(void) ...@@ -1780,7 +1778,7 @@ tty3270_init(void)
struct tty_driver *driver; struct tty_driver *driver;
int ret; int ret;
driver = alloc_tty_driver(256); driver = alloc_tty_driver(RAW3270_MAXDEVS);
if (!driver) if (!driver)
return -ENOMEM; return -ENOMEM;
...@@ -1794,6 +1792,7 @@ tty3270_init(void) ...@@ -1794,6 +1792,7 @@ tty3270_init(void)
driver->driver_name = "ttyTUB"; driver->driver_name = "ttyTUB";
driver->name = "ttyTUB"; driver->name = "ttyTUB";
driver->major = IBM_TTY3270_MAJOR; driver->major = IBM_TTY3270_MAJOR;
driver->minor_start = RAW3270_FIRSTMINOR;
driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->type = TTY_DRIVER_TYPE_SYSTEM;
driver->subtype = SYSTEM_TYPE_TTY; driver->subtype = SYSTEM_TYPE_TTY;
driver->init_termios = tty_std_termios; driver->init_termios = tty_std_termios;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment