aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 14:15:23 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-07 14:15:23 -0500
commit3f00d3e8fb963968a922d821a9a53b503b687e81 (patch)
treedfac1c73ae63f8d48340f3bbb77ee53b322c59e9 /arch/mips/kernel
parent407cf84f956ee4b52da5508d5357b8ae212ff77c (diff)
parenta637a114f36b94a1ad8b9867f43bac0414958420 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/irixsig.c3
-rw-r--r--arch/mips/kernel/rtlx.c197
-rw-r--r--arch/mips/kernel/signal.c3
-rw-r--r--arch/mips/kernel/signal32.c13
-rw-r--r--arch/mips/kernel/vpe.c100
5 files changed, 146 insertions, 170 deletions
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 908e63684208..dd118c60bcd0 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -502,8 +502,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
502 while(1) { 502 while(1) {
503 long tmp = 0; 503 long tmp = 0;
504 504
505 current->state = TASK_INTERRUPTIBLE; 505 expire = schedule_timeout_interruptible(expire);
506 expire = schedule_timeout(expire);
507 506
508 for (i=0; i<=4; i++) 507 for (i=0; i<=4; i++)
509 tmp |= (current->pending.signal.sig[i] & kset.sig[i]); 508 tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 8c81f3cb4e2d..1d855112bac2 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -20,42 +20,42 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <asm/uaccess.h>
24#include <linux/slab.h>
25#include <linux/list.h>
26#include <linux/vmalloc.h>
27#include <linux/elf.h>
28#include <linux/seq_file.h>
29#include <linux/syscalls.h>
30#include <linux/moduleloader.h>
31#include <linux/interrupt.h>
32#include <linux/poll.h> 23#include <linux/poll.h>
33#include <linux/sched.h> 24#include <linux/sched.h>
34#include <linux/wait.h> 25#include <linux/wait.h>
35#include <asm/mipsmtregs.h> 26#include <asm/mipsmtregs.h>
36#include <asm/cacheflush.h> 27#include <asm/bitops.h>
37#include <asm/atomic.h>
38#include <asm/cpu.h> 28#include <asm/cpu.h>
39#include <asm/processor.h> 29#include <asm/processor.h>
40#include <asm/system.h>
41#include <asm/rtlx.h> 30#include <asm/rtlx.h>
31#include <asm/uaccess.h>
42 32
43#define RTLX_MAJOR 64
44#define RTLX_TARG_VPE 1 33#define RTLX_TARG_VPE 1
45 34
46struct rtlx_info *rtlx; 35static struct rtlx_info *rtlx;
47static int major; 36static int major;
48static char module_name[] = "rtlx"; 37static char module_name[] = "rtlx";
49static inline int spacefree(int read, int write, int size); 38static struct irqaction irq;
39static int irq_num;
40
41static inline int spacefree(int read, int write, int size)
42{
43 if (read == write) {
44 /*
45 * never fill the buffer completely, so indexes are always
46 * equal if empty and only empty, or !equal if data available
47 */
48 return size - 1;
49 }
50
51 return ((read + size - write) % size) - 1;
52}
50 53
51static struct chan_waitqueues { 54static struct chan_waitqueues {
52 wait_queue_head_t rt_queue; 55 wait_queue_head_t rt_queue;
53 wait_queue_head_t lx_queue; 56 wait_queue_head_t lx_queue;
54} channel_wqs[RTLX_CHANNELS]; 57} channel_wqs[RTLX_CHANNELS];
55 58
56static struct irqaction irq;
57static int irq_num;
58
59extern void *vpe_get_shared(int index); 59extern void *vpe_get_shared(int index);
60 60
61static void rtlx_dispatch(struct pt_regs *regs) 61static void rtlx_dispatch(struct pt_regs *regs)
@@ -63,9 +63,8 @@ static void rtlx_dispatch(struct pt_regs *regs)
63 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); 63 do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs);
64} 64}
65 65
66irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) 66static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
67{ 67{
68 irqreturn_t r = IRQ_HANDLED;
69 int i; 68 int i;
70 69
71 for (i = 0; i < RTLX_CHANNELS; i++) { 70 for (i = 0; i < RTLX_CHANNELS; i++) {
@@ -75,30 +74,7 @@ irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
75 wake_up_interruptible(&channel_wqs[i].lx_queue); 74 wake_up_interruptible(&channel_wqs[i].lx_queue);
76 } 75 }
77 76
78 return r; 77 return IRQ_HANDLED;
79}
80
81void dump_rtlx(void)
82{
83 int i;
84
85 printk("id 0x%lx state %d\n", rtlx->id, rtlx->state);
86
87 for (i = 0; i < RTLX_CHANNELS; i++) {
88 struct rtlx_channel *chan = &rtlx->channel[i];
89
90 printk(" rt_state %d lx_state %d buffer_size %d\n",
91 chan->rt_state, chan->lx_state, chan->buffer_size);
92
93 printk(" rt_read %d rt_write %d\n",
94 chan->rt_read, chan->rt_write);
95
96 printk(" lx_read %d lx_write %d\n",
97 chan->lx_read, chan->lx_write);
98
99 printk(" rt_buffer <%s>\n", chan->rt_buffer);
100 printk(" lx_buffer <%s>\n", chan->lx_buffer);
101 }
102} 78}
103 79
104/* call when we have the address of the shared structure from the SP side. */ 80/* call when we have the address of the shared structure from the SP side. */
@@ -108,7 +84,7 @@ static int rtlx_init(struct rtlx_info *rtlxi)
108 84
109 if (rtlxi->id != RTLX_ID) { 85 if (rtlxi->id != RTLX_ID) {
110 printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi); 86 printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi);
111 return (-ENOEXEC); 87 return -ENOEXEC;
112 } 88 }
113 89
114 /* initialise the wait queues */ 90 /* initialise the wait queues */
@@ -120,9 +96,8 @@ static int rtlx_init(struct rtlx_info *rtlxi)
120 /* set up for interrupt handling */ 96 /* set up for interrupt handling */
121 memset(&irq, 0, sizeof(struct irqaction)); 97 memset(&irq, 0, sizeof(struct irqaction));
122 98
123 if (cpu_has_vint) { 99 if (cpu_has_vint)
124 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); 100 set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch);
125 }
126 101
127 irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; 102 irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ;
128 irq.handler = rtlx_interrupt; 103 irq.handler = rtlx_interrupt;
@@ -132,7 +107,8 @@ static int rtlx_init(struct rtlx_info *rtlxi)
132 setup_irq(irq_num, &irq); 107 setup_irq(irq_num, &irq);
133 108
134 rtlx = rtlxi; 109 rtlx = rtlxi;
135 return (0); 110
111 return 0;
136} 112}
137 113
138/* only allow one open process at a time to open each channel */ 114/* only allow one open process at a time to open each channel */
@@ -147,36 +123,36 @@ static int rtlx_open(struct inode *inode, struct file *filp)
147 if (rtlx == NULL) { 123 if (rtlx == NULL) {
148 struct rtlx_info **p; 124 struct rtlx_info **p;
149 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { 125 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
150 printk(" vpe_get_shared is NULL. Has an SP program been loaded?\n"); 126 printk(KERN_ERR "vpe_get_shared is NULL. "
151 return (-EFAULT); 127 "Has an SP program been loaded?\n");
128 return -EFAULT;
152 } 129 }
153 130
154 if (*p == NULL) { 131 if (*p == NULL) {
155 printk(" vpe_shared %p %p\n", p, *p); 132 printk(KERN_ERR "vpe_shared %p %p\n", p, *p);
156 return (-EFAULT); 133 return -EFAULT;
157 } 134 }
158 135
159 if ((ret = rtlx_init(*p)) < 0) 136 if ((ret = rtlx_init(*p)) < 0)
160 return (ret); 137 return ret;
161 } 138 }
162 139
163 chan = &rtlx->channel[minor]; 140 chan = &rtlx->channel[minor];
164 141
165 /* already open? */ 142 if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state))
166 if (chan->lx_state == RTLX_STATE_OPENED) 143 return -EBUSY;
167 return (-EBUSY);
168 144
169 chan->lx_state = RTLX_STATE_OPENED; 145 return 0;
170 return (0);
171} 146}
172 147
173static int rtlx_release(struct inode *inode, struct file *filp) 148static int rtlx_release(struct inode *inode, struct file *filp)
174{ 149{
175 int minor; 150 int minor = MINOR(inode->i_rdev);
176 151
177 minor = MINOR(inode->i_rdev); 152 clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state);
178 rtlx->channel[minor].lx_state = RTLX_STATE_UNUSED; 153 smp_mb__after_clear_bit();
179 return (0); 154
155 return 0;
180} 156}
181 157
182static unsigned int rtlx_poll(struct file *file, poll_table * wait) 158static unsigned int rtlx_poll(struct file *file, poll_table * wait)
@@ -199,12 +175,13 @@ static unsigned int rtlx_poll(struct file *file, poll_table * wait)
199 if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size)) 175 if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size))
200 mask |= POLLOUT | POLLWRNORM; 176 mask |= POLLOUT | POLLWRNORM;
201 177
202 return (mask); 178 return mask;
203} 179}
204 180
205static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count, 181static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
206 loff_t * ppos) 182 loff_t * ppos)
207{ 183{
184 unsigned long failed;
208 size_t fl = 0L; 185 size_t fl = 0L;
209 int minor; 186 int minor;
210 struct rtlx_channel *lx; 187 struct rtlx_channel *lx;
@@ -216,7 +193,7 @@ static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
216 /* data available? */ 193 /* data available? */
217 if (lx->lx_write == lx->lx_read) { 194 if (lx->lx_write == lx->lx_read) {
218 if (file->f_flags & O_NONBLOCK) 195 if (file->f_flags & O_NONBLOCK)
219 return (0); // -EAGAIN makes cat whinge 196 return 0; /* -EAGAIN makes cat whinge */
220 197
221 /* go to sleep */ 198 /* go to sleep */
222 add_wait_queue(&channel_wqs[minor].lx_queue, &wait); 199 add_wait_queue(&channel_wqs[minor].lx_queue, &wait);
@@ -232,39 +209,39 @@ static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count,
232 } 209 }
233 210
234 /* find out how much in total */ 211 /* find out how much in total */
235 count = min( count, 212 count = min(count,
236 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); 213 (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size);
237 214
238 /* then how much from the read pointer onwards */ 215 /* then how much from the read pointer onwards */
239 fl = min( count, (size_t)lx->buffer_size - lx->lx_read); 216 fl = min(count, (size_t)lx->buffer_size - lx->lx_read);
240 217
241 copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl); 218 failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl);
219 if (failed) {
220 count = fl - failed;
221 goto out;
222 }
242 223
243 /* and if there is anything left at the beginning of the buffer */ 224 /* and if there is anything left at the beginning of the buffer */
244 if ( count - fl ) 225 if (count - fl) {
245 copy_to_user (buffer + fl, lx->lx_buffer, count - fl); 226 failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl);
227 if (failed) {
228 count -= failed;
229 goto out;
230 }
231 }
246 232
233out:
247 /* update the index */ 234 /* update the index */
248 lx->lx_read += count; 235 lx->lx_read += count;
249 lx->lx_read %= lx->buffer_size; 236 lx->lx_read %= lx->buffer_size;
250 237
251 return (count); 238 return count;
252}
253
254static inline int spacefree(int read, int write, int size)
255{
256 if (read == write) {
257 /* never fill the buffer completely, so indexes are always equal if empty
258 and only empty, or !equal if data available */
259 return (size - 1);
260 }
261
262 return ((read + size - write) % size) - 1;
263} 239}
264 240
265static ssize_t rtlx_write(struct file *file, const char __user * buffer, 241static ssize_t rtlx_write(struct file *file, const char __user * buffer,
266 size_t count, loff_t * ppos) 242 size_t count, loff_t * ppos)
267{ 243{
244 unsigned long failed;
268 int minor; 245 int minor;
269 struct rtlx_channel *rt; 246 struct rtlx_channel *rt;
270 size_t fl; 247 size_t fl;
@@ -277,7 +254,7 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer,
277 if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) { 254 if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) {
278 255
279 if (file->f_flags & O_NONBLOCK) 256 if (file->f_flags & O_NONBLOCK)
280 return (-EAGAIN); 257 return -EAGAIN;
281 258
282 add_wait_queue(&channel_wqs[minor].rt_queue, &wait); 259 add_wait_queue(&channel_wqs[minor].rt_queue, &wait);
283 set_current_state(TASK_INTERRUPTIBLE); 260 set_current_state(TASK_INTERRUPTIBLE);
@@ -290,52 +267,64 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer,
290 } 267 }
291 268
292 /* total number of bytes to copy */ 269 /* total number of bytes to copy */
293 count = min( count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) ); 270 count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) );
294 271
295 /* first bit from write pointer to the end of the buffer, or count */ 272 /* first bit from write pointer to the end of the buffer, or count */
296 fl = min(count, (size_t) rt->buffer_size - rt->rt_write); 273 fl = min(count, (size_t) rt->buffer_size - rt->rt_write);
297 274
298 copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl); 275 failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl);
276 if (failed) {
277 count = fl - failed;
278 goto out;
279 }
299 280
300 /* if there's any left copy to the beginning of the buffer */ 281 /* if there's any left copy to the beginning of the buffer */
301 if( count - fl ) 282 if (count - fl) {
302 copy_from_user(rt->rt_buffer, buffer + fl, count - fl); 283 failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl);
284 if (failed) {
285 count -= failed;
286 goto out;
287 }
288 }
303 289
290out:
304 rt->rt_write += count; 291 rt->rt_write += count;
305 rt->rt_write %= rt->buffer_size; 292 rt->rt_write %= rt->buffer_size;
306 293
307 return(count); 294 return count;
308} 295}
309 296
310static struct file_operations rtlx_fops = { 297static struct file_operations rtlx_fops = {
311 .owner = THIS_MODULE, 298 .owner = THIS_MODULE,
312 .open = rtlx_open, 299 .open = rtlx_open,
313 .release = rtlx_release, 300 .release = rtlx_release,
314 .write = rtlx_write, 301 .write = rtlx_write,
315 .read = rtlx_read, 302 .read = rtlx_read,
316 .poll = rtlx_poll 303 .poll = rtlx_poll
317}; 304};
318 305
319static int rtlx_module_init(void) 306static char register_chrdev_failed[] __initdata =
307 KERN_ERR "rtlx_module_init: unable to register device\n";
308
309static int __init rtlx_module_init(void)
320{ 310{
321 if ((major = register_chrdev(RTLX_MAJOR, module_name, &rtlx_fops)) < 0) { 311 major = register_chrdev(0, module_name, &rtlx_fops);
322 printk("rtlx_module_init: unable to register device\n"); 312 if (major < 0) {
323 return (-EBUSY); 313 printk(register_chrdev_failed);
314 return major;
324 } 315 }
325 316
326 if (major == 0) 317 return 0;
327 major = RTLX_MAJOR;
328
329 return (0);
330} 318}
331 319
332static void rtlx_module_exit(void) 320static void __exit rtlx_module_exit(void)
333{ 321{
334 unregister_chrdev(major, module_name); 322 unregister_chrdev(major, module_name);
335} 323}
336 324
337module_init(rtlx_module_init); 325module_init(rtlx_module_init);
338module_exit(rtlx_module_exit); 326module_exit(rtlx_module_exit);
327
339MODULE_DESCRIPTION("MIPS RTLX"); 328MODULE_DESCRIPTION("MIPS RTLX");
340MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc"); 329MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc.");
341MODULE_LICENSE("GPL"); 330MODULE_LICENSE("GPL");
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 9202a17db8f7..05e09eedabff 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -384,9 +384,6 @@ give_sigsegv:
384 return 0; 384 return 0;
385} 385}
386 386
387extern void setup_rt_frame_n32(struct k_sigaction * ka,
388 struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info);
389
390static inline int handle_signal(unsigned long sig, siginfo_t *info, 387static inline int handle_signal(unsigned long sig, siginfo_t *info,
391 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs) 388 struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
392{ 389{
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index dbe821303125..e315d3f6aa6e 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -647,8 +647,8 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
647 return (void *)((sp - frame_size) & ALMASK); 647 return (void *)((sp - frame_size) & ALMASK);
648} 648}
649 649
650void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, 650int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
651 int signr, sigset_t *set) 651 int signr, sigset_t *set)
652{ 652{
653 struct sigframe *frame; 653 struct sigframe *frame;
654 int err = 0; 654 int err = 0;
@@ -694,13 +694,15 @@ void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
694 current->comm, current->pid, 694 current->comm, current->pid,
695 frame, regs->cp0_epc, frame->sf_code); 695 frame, regs->cp0_epc, frame->sf_code);
696#endif 696#endif
697 return; 697 return 1;
698 698
699give_sigsegv: 699give_sigsegv:
700 force_sigsegv(signr, current); 700 force_sigsegv(signr, current);
701 return 0;
701} 702}
702 703
703void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) 704int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
705 int signr, sigset_t *set, siginfo_t *info)
704{ 706{
705 struct rt_sigframe32 *frame; 707 struct rt_sigframe32 *frame;
706 int err = 0; 708 int err = 0;
@@ -763,10 +765,11 @@ void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr,
763 current->comm, current->pid, 765 current->comm, current->pid,
764 frame, regs->cp0_epc, frame->rs_code); 766 frame, regs->cp0_epc, frame->rs_code);
765#endif 767#endif
766 return; 768 return 1;
767 769
768give_sigsegv: 770give_sigsegv:
769 force_sigsegv(signr, current); 771 force_sigsegv(signr, current);
772 return 0;
770} 773}
771 774
772static inline int handle_signal(unsigned long sig, siginfo_t *info, 775static inline int handle_signal(unsigned long sig, siginfo_t *info,
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 97fefcc9dbe7..06be405be399 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -58,10 +58,6 @@
58 58
59typedef void *vpe_handle; 59typedef void *vpe_handle;
60 60
61// defined here because the kernel module loader doesn't have
62// anything to do with it.
63#define SHN_MIPS_SCOMMON 0xff03
64
65#ifndef ARCH_SHF_SMALL 61#ifndef ARCH_SHF_SMALL
66#define ARCH_SHF_SMALL 0 62#define ARCH_SHF_SMALL 0
67#endif 63#endif
@@ -69,11 +65,8 @@ typedef void *vpe_handle;
69/* If this is set, the section belongs in the init part of the module */ 65/* If this is set, the section belongs in the init part of the module */
70#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1)) 66#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))
71 67
72// temp number,
73#define VPE_MAJOR 63
74
75static char module_name[] = "vpe"; 68static char module_name[] = "vpe";
76static int major = 0; 69static int major;
77 70
78/* grab the likely amount of memory we will need. */ 71/* grab the likely amount of memory we will need. */
79#ifdef CONFIG_MIPS_VPE_LOADER_TOM 72#ifdef CONFIG_MIPS_VPE_LOADER_TOM
@@ -98,22 +91,7 @@ enum tc_state {
98 TC_STATE_DYNAMIC 91 TC_STATE_DYNAMIC
99}; 92};
100 93
101struct vpe; 94struct vpe {
102typedef struct tc {
103 enum tc_state state;
104 int index;
105
106 /* parent VPE */
107 struct vpe *pvpe;
108
109 /* The list of TC's with this VPE */
110 struct list_head tc;
111
112 /* The global list of tc's */
113 struct list_head list;
114} tc_t;
115
116typedef struct vpe {
117 enum vpe_state state; 95 enum vpe_state state;
118 96
119 /* (device) minor associated with this vpe */ 97 /* (device) minor associated with this vpe */
@@ -135,7 +113,21 @@ typedef struct vpe {
135 113
136 /* shared symbol address */ 114 /* shared symbol address */
137 void *shared_ptr; 115 void *shared_ptr;
138} vpe_t; 116};
117
118struct tc {
119 enum tc_state state;
120 int index;
121
122 /* parent VPE */
123 struct vpe *pvpe;
124
125 /* The list of TC's with this VPE */
126 struct list_head tc;
127
128 /* The global list of tc's */
129 struct list_head list;
130};
139 131
140struct vpecontrol_ { 132struct vpecontrol_ {
141 /* Virtual processing elements */ 133 /* Virtual processing elements */
@@ -146,7 +138,7 @@ struct vpecontrol_ {
146} vpecontrol; 138} vpecontrol;
147 139
148static void release_progmem(void *ptr); 140static void release_progmem(void *ptr);
149static void dump_vpe(vpe_t * v); 141static void dump_vpe(struct vpe * v);
150extern void save_gp_address(unsigned int secbase, unsigned int rel); 142extern void save_gp_address(unsigned int secbase, unsigned int rel);
151 143
152/* get the vpe associated with this minor */ 144/* get the vpe associated with this minor */
@@ -197,13 +189,11 @@ struct vpe *alloc_vpe(int minor)
197{ 189{
198 struct vpe *v; 190 struct vpe *v;
199 191
200 if ((v = kmalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { 192 if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
201 printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); 193 printk(KERN_WARNING "VPE: alloc_vpe no mem\n");
202 return NULL; 194 return NULL;
203 } 195 }
204 196
205 memset(v, 0, sizeof(struct vpe));
206
207 INIT_LIST_HEAD(&v->tc); 197 INIT_LIST_HEAD(&v->tc);
208 list_add_tail(&v->list, &vpecontrol.vpe_list); 198 list_add_tail(&v->list, &vpecontrol.vpe_list);
209 199
@@ -216,13 +206,11 @@ struct tc *alloc_tc(int index)
216{ 206{
217 struct tc *t; 207 struct tc *t;
218 208
219 if ((t = kmalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { 209 if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) {
220 printk(KERN_WARNING "VPE: alloc_tc no mem\n"); 210 printk(KERN_WARNING "VPE: alloc_tc no mem\n");
221 return NULL; 211 return NULL;
222 } 212 }
223 213
224 memset(t, 0, sizeof(struct tc));
225
226 INIT_LIST_HEAD(&t->tc); 214 INIT_LIST_HEAD(&t->tc);
227 list_add_tail(&t->list, &vpecontrol.tc_list); 215 list_add_tail(&t->list, &vpecontrol.tc_list);
228 216
@@ -412,16 +400,17 @@ static int apply_r_mips_26(struct module *me, uint32_t *location,
412 return -ENOEXEC; 400 return -ENOEXEC;
413 } 401 }
414 402
415/* Not desperately convinced this is a good check of an overflow condition 403/*
416 anyway. But it gets in the way of handling undefined weak symbols which 404 * Not desperately convinced this is a good check of an overflow condition
417 we want to set to zero. 405 * anyway. But it gets in the way of handling undefined weak symbols which
418 if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) { 406 * we want to set to zero.
419 printk(KERN_ERR 407 * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
420 "module %s: relocation overflow\n", 408 * printk(KERN_ERR
421 me->name); 409 * "module %s: relocation overflow\n",
422 return -ENOEXEC; 410 * me->name);
423 } 411 * return -ENOEXEC;
424*/ 412 * }
413 */
425 414
426 *location = (*location & ~0x03ffffff) | 415 *location = (*location & ~0x03ffffff) |
427 ((*location + (v >> 2)) & 0x03ffffff); 416 ((*location + (v >> 2)) & 0x03ffffff);
@@ -681,7 +670,7 @@ static void dump_tclist(void)
681} 670}
682 671
683/* We are prepared so configure and start the VPE... */ 672/* We are prepared so configure and start the VPE... */
684int vpe_run(vpe_t * v) 673int vpe_run(struct vpe * v)
685{ 674{
686 unsigned long val; 675 unsigned long val;
687 struct tc *t; 676 struct tc *t;
@@ -772,7 +761,7 @@ int vpe_run(vpe_t * v)
772 return 0; 761 return 0;
773} 762}
774 763
775static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs, 764static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
776 unsigned int symindex, const char *strtab, 765 unsigned int symindex, const char *strtab,
777 struct module *mod) 766 struct module *mod)
778{ 767{
@@ -792,10 +781,12 @@ static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
792 return 0; 781 return 0;
793} 782}
794 783
795/* Allocates a VPE with some program code space(the load address), copies the contents 784/*
796 of the program (p)buffer performing relocatations/etc, free's it when finished. 785 * Allocates a VPE with some program code space(the load address), copies
786 * the contents of the program (p)buffer performing relocatations/etc,
787 * free's it when finished.
797*/ 788*/
798int vpe_elfload(vpe_t * v) 789int vpe_elfload(struct vpe * v)
799{ 790{
800 Elf_Ehdr *hdr; 791 Elf_Ehdr *hdr;
801 Elf_Shdr *sechdrs; 792 Elf_Shdr *sechdrs;
@@ -931,7 +922,7 @@ cleanup:
931 return err; 922 return err;
932} 923}
933 924
934static void dump_vpe(vpe_t * v) 925static void dump_vpe(struct vpe * v)
935{ 926{
936 struct tc *t; 927 struct tc *t;
937 928
@@ -947,7 +938,7 @@ static void dump_vpe(vpe_t * v)
947static int vpe_open(struct inode *inode, struct file *filp) 938static int vpe_open(struct inode *inode, struct file *filp)
948{ 939{
949 int minor; 940 int minor;
950 vpe_t *v; 941 struct vpe *v;
951 942
952 /* assume only 1 device at the mo. */ 943 /* assume only 1 device at the mo. */
953 if ((minor = MINOR(inode->i_rdev)) != 1) { 944 if ((minor = MINOR(inode->i_rdev)) != 1) {
@@ -1001,7 +992,7 @@ static int vpe_open(struct inode *inode, struct file *filp)
1001static int vpe_release(struct inode *inode, struct file *filp) 992static int vpe_release(struct inode *inode, struct file *filp)
1002{ 993{
1003 int minor, ret = 0; 994 int minor, ret = 0;
1004 vpe_t *v; 995 struct vpe *v;
1005 Elf_Ehdr *hdr; 996 Elf_Ehdr *hdr;
1006 997
1007 minor = MINOR(inode->i_rdev); 998 minor = MINOR(inode->i_rdev);
@@ -1035,7 +1026,7 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer,
1035{ 1026{
1036 int minor; 1027 int minor;
1037 size_t ret = count; 1028 size_t ret = count;
1038 vpe_t *v; 1029 struct vpe *v;
1039 1030
1040 minor = MINOR(file->f_dentry->d_inode->i_rdev); 1031 minor = MINOR(file->f_dentry->d_inode->i_rdev);
1041 if ((v = get_vpe(minor)) == NULL) 1032 if ((v = get_vpe(minor)) == NULL)
@@ -1180,14 +1171,11 @@ static int __init vpe_module_init(void)
1180 return -ENODEV; 1171 return -ENODEV;
1181 } 1172 }
1182 1173
1183 if ((major = register_chrdev(VPE_MAJOR, module_name, &vpe_fops) < 0)) { 1174 if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) {
1184 printk("VPE loader: unable to register character device\n"); 1175 printk("VPE loader: unable to register character device\n");
1185 return -EBUSY; 1176 return major;
1186 } 1177 }
1187 1178
1188 if (major == 0)
1189 major = VPE_MAJOR;
1190
1191 dmt(); 1179 dmt();
1192 dvpe(); 1180 dvpe();
1193 1181