Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 4221
b: refs/heads/master
c: 837dcfa
h: refs/heads/master
i:
  4219: 386cc55
v: v3
  • Loading branch information
Milton Miller authored and Linus Torvalds committed Jul 8, 2005
1 parent 2a47bd3 commit 1bee64f
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 143 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5cee73fa04758f52b7404b93a02edf74649370ab
refs/heads/master: 837dcfaf46d147f1d2c64cbbecb832dd9075c39d
284 changes: 142 additions & 142 deletions trunk/drivers/char/hvc_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,21 @@
*/
#define HVC_ALLOC_TTY_ADAPTERS 8

static struct tty_driver *hvc_driver;
#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif

#define N_OUTBUF 16
#define N_INBUF 16

#define __ALIGNED__ __attribute__((__aligned__(8)))

static struct tty_driver *hvc_driver;
static struct task_struct *hvc_task;

/* Picks up late kicks after list walk but before schedule() */
static int hvc_kicked;

#ifdef CONFIG_MAGIC_SYSRQ
static int sysrq_pressed;
#endif

struct hvc_struct {
spinlock_t lock;
int index;
Expand All @@ -96,6 +101,41 @@ static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs);
*/
static DEFINE_SPINLOCK(hvc_structs_lock);

/*
* This value is used to associate a tty->index value to a hvc_struct based
* upon order of exposure via hvc_probe().
*/
static int hvc_count = -1;

/*
* Do not call this function with either the hvc_strucst_lock or the hvc_struct
* lock held. If successful, this function increments the kobject reference
* count against the target hvc_struct so it should be released when finished.
*/
struct hvc_struct *hvc_get_by_index(int index)
{
struct hvc_struct *hp;
unsigned long flags;

spin_lock(&hvc_structs_lock);

list_for_each_entry(hp, &hvc_structs, next) {
spin_lock_irqsave(&hp->lock, flags);
if (hp->index == index) {
kobject_get(&hp->kobj);
spin_unlock_irqrestore(&hp->lock, flags);
spin_unlock(&hvc_structs_lock);
return hp;
}
spin_unlock_irqrestore(&hp->lock, flags);
}
hp = NULL;

spin_unlock(&hvc_structs_lock);
return hp;
}


/*
* Initial console vtermnos for console API usage prior to full console
* initialization. Any vty adapter outside this range will not have usable
Expand All @@ -107,16 +147,98 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES];
/* Used for accounting purposes */
static int num_vterms = 0;

static struct task_struct *hvc_task;
/*
* Console APIs, NOT TTY. These APIs are available immediately when
* hvc_console_setup() finds adapters.
*/

void hvc_console_print(struct console *co, const char *b, unsigned count)
{
char c[16] __ALIGNED__;
unsigned i = 0, n = 0;
int r, donecr = 0;

/* Console access attempt outside of acceptable console range. */
if (co->index >= MAX_NR_HVC_CONSOLES)
return;

/* This console adapter was removed so it is not useable. */
if (vtermnos[co->index] < 0)
return;

while (count > 0 || i > 0) {
if (count > 0 && i < sizeof(c)) {
if (b[n] == '\n' && !donecr) {
c[i++] = '\r';
donecr = 1;
} else {
c[i++] = b[n++];
donecr = 0;
--count;
}
} else {
r = hvc_put_chars(vtermnos[co->index], c, i);
if (r < 0) {
/* throw away chars on error */
i = 0;
} else if (r > 0) {
i -= r;
if (i > 0)
memmove(c, c+r, i);
}
}
}
}

static struct tty_driver *hvc_console_device(struct console *c, int *index)
{
*index = c->index;
return hvc_driver;
}

static int __init hvc_console_setup(struct console *co, char *options)
{
return 0;
}

struct console hvc_con_driver = {
.name = "hvc",
.write = hvc_console_print,
.device = hvc_console_device,
.setup = hvc_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};

/* Early console initialization. Preceeds driver initialization. */
static int __init hvc_console_init(void)
{
int i;

for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
vtermnos[i] = -1;
num_vterms = hvc_find_vtys();
register_console(&hvc_con_driver);
return 0;
}
console_initcall(hvc_console_init);

/*
* This value is used to associate a tty->index value to a hvc_struct based
* upon order of exposure via hvc_probe().
* hvc_instantiate() is an early console discovery method which locates consoles
* prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT
* get an hvc_instantiate() callback since the appear after early console init.
*/
static int hvc_count = -1;
int hvc_instantiate(uint32_t vtermno, int index)
{
if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
return -1;

/* Picks up late kicks after list walk but before schedule() */
static int hvc_kicked;
if (vtermnos[index] != -1)
return -1;

vtermnos[index] = vtermno;
return 0;
}

/* Wake the sleeping khvcd */
static void hvc_kick(void)
Expand All @@ -140,34 +262,6 @@ static void hvc_unthrottle(struct tty_struct *tty)
hvc_kick();
}

/*
* Do not call this function with either the hvc_strucst_lock or the hvc_struct
* lock held. If successful, this function increments the kobject reference
* count against the target hvc_struct so it should be released when finished.
*/
struct hvc_struct *hvc_get_by_index(int index)
{
struct hvc_struct *hp;
unsigned long flags;

spin_lock(&hvc_structs_lock);

list_for_each_entry(hp, &hvc_structs, next) {
spin_lock_irqsave(&hp->lock, flags);
if (hp->index == index) {
kobject_get(&hp->kobj);
spin_unlock_irqrestore(&hp->lock, flags);
spin_unlock(&hvc_structs_lock);
return hp;
}
spin_unlock_irqrestore(&hp->lock, flags);
}
hp = NULL;

spin_unlock(&hvc_structs_lock);
return hp;
}

/*
* The TTY interface won't be used until after the vio layer has exposed the vty
* adapter to the kernel.
Expand Down Expand Up @@ -577,14 +671,6 @@ static struct tty_operations hvc_ops = {
.chars_in_buffer = hvc_chars_in_buffer,
};

char hvc_driver_name[] = "hvc_console";

static struct vio_device_id hvc_driver_table[] __devinitdata= {
{"serial", "hvterm1"},
{ NULL, }
};
MODULE_DEVICE_TABLE(vio, hvc_driver_table);

/* callback when the kboject ref count reaches zero. */
static void destroy_hvc_struct(struct kobject *kobj)
{
Expand Down Expand Up @@ -674,6 +760,14 @@ static int __devexit hvc_remove(struct vio_dev *dev)
return 0;
}

char hvc_driver_name[] = "hvc_console";

static struct vio_device_id hvc_driver_table[] __devinitdata= {
{"serial", "hvterm1"},
{ NULL, }
};
MODULE_DEVICE_TABLE(vio, hvc_driver_table);

static struct vio_driver hvc_vio_driver = {
.name = hvc_driver_name,
.id_table = hvc_driver_table,
Expand Down Expand Up @@ -721,6 +815,7 @@ int __init hvc_init(void)

return rc;
}
module_init(hvc_init);

/* This isn't particularily necessary due to this being a console driver but it
* is nice to be thorough */
Expand All @@ -733,99 +828,4 @@ static void __exit hvc_exit(void)
/* return tty_struct instances allocated in hvc_init(). */
put_tty_driver(hvc_driver);
}

/*
* Console APIs, NOT TTY. These APIs are available immediately when
* hvc_console_setup() finds adapters.
*/

/*
* hvc_instantiate() is an early console discovery method which locates consoles
* prior to the vio subsystem discovering them. Hotplugged vty adapters do NOT
* get an hvc_instantiate() callback since the appear after early console init.
*/
int hvc_instantiate(uint32_t vtermno, int index)
{
if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
return -1;

if (vtermnos[index] != -1)
return -1;

vtermnos[index] = vtermno;
return 0;
}

void hvc_console_print(struct console *co, const char *b, unsigned count)
{
char c[16] __ALIGNED__;
unsigned i = 0, n = 0;
int r, donecr = 0;

/* Console access attempt outside of acceptable console range. */
if (co->index >= MAX_NR_HVC_CONSOLES)
return;

/* This console adapter was removed so it is not useable. */
if (vtermnos[co->index] < 0)
return;

while (count > 0 || i > 0) {
if (count > 0 && i < sizeof(c)) {
if (b[n] == '\n' && !donecr) {
c[i++] = '\r';
donecr = 1;
} else {
c[i++] = b[n++];
donecr = 0;
--count;
}
} else {
r = hvc_put_chars(vtermnos[co->index], c, i);
if (r < 0) {
/* throw away chars on error */
i = 0;
} else if (r > 0) {
i -= r;
if (i > 0)
memmove(c, c+r, i);
}
}
}
}

static struct tty_driver *hvc_console_device(struct console *c, int *index)
{
*index = c->index;
return hvc_driver;
}

static int __init hvc_console_setup(struct console *co, char *options)
{
return 0;
}

struct console hvc_con_driver = {
.name = "hvc",
.write = hvc_console_print,
.device = hvc_console_device,
.setup = hvc_console_setup,
.flags = CON_PRINTBUFFER,
.index = -1,
};

/* Early console initialization. Preceeds driver initialization. */
static int __init hvc_console_init(void)
{
int i;

for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
vtermnos[i] = -1;
num_vterms = hvc_find_vtys();
register_console(&hvc_con_driver);
return 0;
}
console_initcall(hvc_console_init);

module_init(hvc_init);
module_exit(hvc_exit);

0 comments on commit 1bee64f

Please sign in to comment.