Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2539
b: refs/heads/master
c: 278d72a
h: refs/heads/master
i:
  2537: ea15d2d
  2535: 31f0951
v: v3
  • Loading branch information
Max Asbock authored and Linus Torvalds committed Jun 22, 2005
1 parent addeddf commit 3f3b56b
Show file tree
Hide file tree
Showing 7 changed files with 450 additions and 270 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: b8acb808468a88a188d7c5aba3681c583a5785f9
refs/heads/master: 278d72ae8803ffcd16070c95fe1d53f4466dc741
65 changes: 24 additions & 41 deletions trunk/drivers/misc/ibmasm/ibmasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,31 @@
#include <linux/version.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/input.h>

/* Driver identification */
#define DRIVER_NAME "ibmasm"
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Max Asbock"
#define DRIVER_VERSION "1.0"
#define DRIVER_AUTHOR "Max Asbock <masbock@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
#define DRIVER_DESC "IBM ASM Service Processor Driver"

#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)

extern int ibmasm_debug;
#define dbg(STR, ARGS...) \
do { \
if (ibmasm_debug) \
printk(KERN_DEBUG STR , ##ARGS); \
} while (0)

static inline char *get_timestamp(char *buf)
{
struct timeval now;
do_gettimeofday(&now);
sprintf(buf, "%lu.%lu", now.tv_sec, now.tv_usec);
return buf;
}

#define IBMASM_CMD_PENDING 0
#define IBMASM_CMD_COMPLETE 1
Expand Down Expand Up @@ -121,41 +136,11 @@ struct reverse_heartbeat {
unsigned int stopped;
};


/* remote console events */
struct mouse_event {
long x;
long y;
unsigned char buttons;
unsigned char transitions;
struct ibmasm_remote {
struct input_dev keybd_dev;
struct input_dev mouse_dev;
};

struct keyboard_event {
unsigned long key_code;
unsigned char key_down;
};

struct remote_event {
unsigned long type;
union {
struct mouse_event mouse;
struct keyboard_event keyboard;
} data;
};

#define DRIVER_REMOTE_QUEUE_SIZE 240

struct remote_queue {
struct remote_event *start;
struct remote_event *end;
struct remote_event *reader;
struct remote_event *writer;
unsigned int size;
int open;
wait_queue_head_t wait;
};


struct service_processor {
struct list_head node;
spinlock_t lock;
Expand All @@ -168,7 +153,7 @@ struct service_processor {
char dirname[IBMASM_NAME_SIZE];
char devname[IBMASM_NAME_SIZE];
unsigned int number;
struct remote_queue remote_queue;
struct ibmasm_remote *remote;
int serial_line;
struct device *dev;
};
Expand Down Expand Up @@ -210,11 +195,9 @@ extern int ibmasm_send_i2o_message(struct service_processor *sp);
extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs);

/* remote console */
extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
extern int ibmasm_init_remote_queue(struct service_processor *sp);
extern void ibmasm_free_remote_queue(struct service_processor *sp);
extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n);
extern size_t ibmasm_events_available(struct remote_queue *q);
extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp, struct pt_regs *regs);
extern int ibmasm_init_remote_input_dev(struct service_processor *sp);
extern void ibmasm_free_remote_input_dev(struct service_processor *sp);

/* file system */
extern int ibmasmfs_register(void);
Expand Down
89 changes: 0 additions & 89 deletions trunk/drivers/misc/ibmasm/ibmasmfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
* | |-- event
* | |-- reverse_heartbeat
* | `-- remote_video
* | |-- connected
* | |-- depth
* | |-- events
* | |-- height
* | `-- width
* .
Expand All @@ -50,9 +48,7 @@
* |-- event
* |-- reverse_heartbeat
* `-- remote_video
* |-- connected
* |-- depth
* |-- events
* |-- height
* `-- width
*
Expand All @@ -75,14 +71,6 @@
* remote_video/width: control remote display settings
* write: set value
* read: read value
*
* remote_video/connected
* read: return "1" if web browser VNC java applet is connected,
* "0" otherwise
*
* remote_video/events
* read: sleep until a remote mouse or keyboard event occurs, then return
* then event.
*/

#include <linux/fs.h>
Expand Down Expand Up @@ -593,75 +581,6 @@ static ssize_t remote_settings_file_write(struct file *file, const char __user *
return count;
}

static int remote_event_file_open(struct inode *inode, struct file *file)
{
struct service_processor *sp;
unsigned long flags;
struct remote_queue *q;

file->private_data = inode->u.generic_ip;
sp = file->private_data;
q = &sp->remote_queue;

/* allow only one event reader */
spin_lock_irqsave(&sp->lock, flags);
if (q->open) {
spin_unlock_irqrestore(&sp->lock, flags);
return -EBUSY;
}
q->open = 1;
spin_unlock_irqrestore(&sp->lock, flags);

enable_mouse_interrupts(sp);

return 0;
}

static int remote_event_file_close(struct inode *inode, struct file *file)
{
struct service_processor *sp = file->private_data;

disable_mouse_interrupts(sp);
wake_up_interruptible(&sp->remote_queue.wait);
sp->remote_queue.open = 0;

return 0;
}

static ssize_t remote_event_file_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct service_processor *sp = file->private_data;
struct remote_queue *q = &sp->remote_queue;
size_t data_size;
struct remote_event *reader = q->reader;
size_t num_events;

if (*offset < 0)
return -EINVAL;
if (count == 0 || count > 1024)
return 0;
if (*offset != 0)
return 0;

if (wait_event_interruptible(q->wait, q->reader != q->writer))
return -ERESTARTSYS;

/* only get multiples of struct remote_event */
num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
if (!num_events)
return 0;

data_size = num_events * sizeof(struct remote_event);

if (copy_to_user(buf, reader, data_size))
return -EFAULT;

ibmasm_advance_reader(q, num_events);

return data_size;
}


static struct file_operations command_fops = {
.open = command_file_open,
.release = command_file_close,
Expand Down Expand Up @@ -690,12 +609,6 @@ static struct file_operations remote_settings_fops = {
.write = remote_settings_file_write,
};

static struct file_operations remote_event_fops = {
.open = remote_event_file_open,
.release = remote_event_file_close,
.read = remote_event_file_read,
};


static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
{
Expand All @@ -721,7 +634,5 @@ static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);
ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);
}
}
18 changes: 11 additions & 7 deletions trunk/drivers/misc/ibmasm/lowlevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ int ibmasm_send_i2o_message(struct service_processor *sp)

message = get_i2o_message(sp->base_address, mfa);

memcpy(&message->header, &header, sizeof(struct i2o_header));
memcpy(&message->data, command->buffer, command_size);
memcpy_toio(&message->header, &header, sizeof(struct i2o_header));
memcpy_toio(&message->data, command->buffer, command_size);

set_mfa_inbound(sp->base_address, mfa);

Expand All @@ -59,23 +59,27 @@ irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *reg
u32 mfa;
struct service_processor *sp = (struct service_processor *)dev_id;
void __iomem *base_address = sp->base_address;
char tsbuf[32];

if (!sp_interrupt_pending(base_address))
return IRQ_NONE;

dbg("respond to interrupt at %s\n", get_timestamp(tsbuf));

if (mouse_interrupt_pending(sp)) {
ibmasm_handle_mouse_interrupt(sp);
mfa = get_mfa_outbound(base_address);
ibmasm_handle_mouse_interrupt(sp, regs);
clear_mouse_interrupt(sp);
set_mfa_outbound(base_address, mfa);
return IRQ_HANDLED;
}

mfa = get_mfa_outbound(base_address);
if (valid_mfa(mfa)) {
struct i2o_message *msg = get_i2o_message(base_address, mfa);
ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
}
} else
dbg("didn't get a valid MFA\n");

set_mfa_outbound(base_address, mfa);
dbg("finished interrupt at %s\n", get_timestamp(tsbuf));

return IRQ_HANDLED;
}
Loading

0 comments on commit 3f3b56b

Please sign in to comment.