maltalinux-cvs-patches
[Top] [All Lists]

CVS Update@linux-mips.org: malta

To: maltalinux-cvs-patches@linux-mips.org
Subject: CVS Update@linux-mips.org: malta
From: beth@linux-mips.org
Date: Fri, 02 Sep 2005 18:02:56 +0100
Reply-to: linux-mips@linux-mips.org
Sender: maltalinux-cvs-patches-bounce@linux-mips.org
CVSROOT:        /home/cvs
Module name:    malta
Changes by:     beth@ftp.linux-mips.org 05/09/02 18:02:54

Modified files:
        linux/arch/mips/kernel: Tag: MaltaRef_2_6 kspd.c rtlx.c vpe.c 

Log message:
        * arch/mips/kernel/kspd.c: Stop KSPD from trying to read from the
        syscall channel if we are stopping.
        
        * arch/mips/kernel/rtlx.c: Fix bug where multiple process could
        open /dev/rt? and sit on the wait queue for SP to set up the
        shared structure.
        
        * arch/mips/kernel/vpe.c: Fix loading of fully linked SP images.
        __start symbol wasn't found so the TC's restart address was incorrect.

diff -urN malta/linux/arch/mips/kernel/kspd.c 
malta/linux/arch/mips/kernel/kspd.c
--- malta/linux/arch/mips/kernel/Attic/kspd.c   2005/08/19 13:47:36     
1.1.1000.4
+++ malta/linux/arch/mips/kernel/Attic/kspd.c   2005/09/02 17:02:54     
1.1.1000.5
@@ -113,7 +113,6 @@
        register long int _arg1  __asm__ ("$5") = arg1;
        register long int _arg2  __asm__ ("$6") = arg2;
        register long int _arg3  __asm__ ("$7") = arg3;
-//     register long int eflag  __asm__ ("$7") = 1;
 
        mm_segment_t old_fs;
 
@@ -286,8 +285,10 @@
        } else {
                /* wait for some data, allow it to sleep */
                rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);
-
-               sp_work_handle_request();
+               
+               /* Check we haven't been woken because we are stopping */
+               if (!sp_stopping)
+                       sp_work_handle_request();
        }
 
        if (!sp_stopping)
diff -urN malta/linux/arch/mips/kernel/rtlx.c 
malta/linux/arch/mips/kernel/rtlx.c
--- malta/linux/arch/mips/kernel/rtlx.c 2005/08/19 13:47:36     1.1.1000.5
+++ malta/linux/arch/mips/kernel/rtlx.c 2005/09/02 17:02:54     1.1.1000.6
@@ -52,6 +52,7 @@
 static struct chan_waitqueues {
        wait_queue_head_t rt_queue;
        wait_queue_head_t lx_queue;
+       int in_open;
 } channel_wqs[RTLX_CHANNELS];
 
 static struct irqaction irq;
@@ -61,7 +62,6 @@
 
 extern void *vpe_get_shared(int index);
 static int rtlx_init(struct rtlx_info *rtlxi);
-DECLARE_MUTEX(wq_mutex);
 
 static void rtlx_dispatch(struct pt_regs *regs)
 {
@@ -111,7 +111,7 @@
 static int rtlx_init(struct rtlx_info *rtlxi)
 {
        if (rtlxi->id != RTLX_ID) {
-               printk(KERN_ERR "no valid RTLX id at 0x%p found 0x%x should be 
0x%x\n", 
+               printk(KERN_ERR "no valid RTLX id at 0x%p found 0x%lx should be 
0x%x\n", 
                       rtlxi, rtlxi->id, RTLX_ID);
                return -ENOEXEC;
        }
@@ -149,6 +149,18 @@
        int ret;
        struct rtlx_channel *chan;
        volatile struct rtlx_info **p;
+       
+       if (index >= RTLX_CHANNELS) {
+               printk(KERN_DEBUG "rtlx_open index out of range\n");
+               return -ENOSYS;
+       }
+
+       if (channel_wqs[index].in_open) {
+               printk(KERN_DEBUG "rtlx_open channel %d already opened\n", 
index);
+               return -EBUSY;
+       }
+
+       channel_wqs[index].in_open++;
 
        if (rtlx == NULL) {
                if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {
@@ -171,6 +183,7 @@
                        } else {
                                printk( KERN_DEBUG "No SP program loaded, and 
device "
                                        "opened with O_NONBLOCK\n");
+                               channel_wqs[index].in_open = 0;
                                return -ENOSYS;
                        }
                }
@@ -186,12 +199,7 @@
                                while (*p == NULL) {
                                        schedule();
 
-                                       /* reset task state to interruptable 
otherwise
-                                          we'll whizz round here like a very 
fast loopy 
-                                          thing. schedule() appears to return 
with state
-                                          set to TASK_RUNNING. 
-
-                                          If the loaded SP program, for 
whatever reason, 
+                                       /* If the loaded SP program, for 
whatever reason, 
                                           doesn't set up the shared structure 
*p will never
                                           become true. So whoever connected to 
either /dev/rt?
                                           or if it was kspd, will then take up 
rather a lot of 
@@ -209,6 +217,7 @@
                        else {
                                printk(" *vpe_get_shared is NULL. "
                                       "Has an SP program been loaded?\n");
+                               channel_wqs[index].in_open = 0;
                                return -ENOSYS;
                        }
                }
@@ -216,20 +225,26 @@
                if ((unsigned int)*p < KSEG0) {
                        printk(KERN_WARNING "vpe_get_shared returned an invalid 
pointer "
                               "maybe an error code %d\n", (int)*p);
+                       channel_wqs[index].in_open = 0;
                        return -ENOSYS;
                }
                
-               if ((ret = rtlx_init(*p)) < 0)
+               if ((ret = rtlx_init(*p)) < 0) {
+                       channel_wqs[index].in_open = 0;
                        return ret;
+               }
        }
-       
+
        chan = &rtlx->channel[index];
        
        /* already open? */
-       if (chan->lx_state == RTLX_STATE_OPENED)
+       if (chan->lx_state == RTLX_STATE_OPENED) {
+               channel_wqs[index].in_open = 0;
                return -EBUSY;
+       }
 
        chan->lx_state = RTLX_STATE_OPENED;
+       channel_wqs[index].in_open = 0;
        return 0;
 }      
 
@@ -478,6 +493,7 @@
        for (i = 0; i < RTLX_CHANNELS; i++) {
                init_waitqueue_head(&channel_wqs[i].rt_queue);
                init_waitqueue_head(&channel_wqs[i].lx_queue);
+               channel_wqs[i].in_open = 0;
        }
 
        /* set up notifiers */
diff -urN malta/linux/arch/mips/kernel/vpe.c malta/linux/arch/mips/kernel/vpe.c
--- malta/linux/arch/mips/kernel/vpe.c  2005/08/19 13:47:36     1.1.1000.4
+++ malta/linux/arch/mips/kernel/vpe.c  2005/09/02 17:02:54     1.1.1000.5
@@ -164,8 +164,10 @@
 } vpecontrol;
 
 static void release_progmem(void *ptr);
-static void dump_vpe(vpe_t * v);
 extern void save_gp_address(unsigned int secbase, unsigned int rel);
+#ifdef VPE_DEBUG
+static void dump_vpe(vpe_t * v);
+#endif
 
 /* get the vpe associated with this minor */
 struct vpe *get_vpe(int minor)
@@ -741,9 +743,6 @@
        /* disable MT (using dvpe) */
        dvpe();
 
-       /* Put MVPE's into 'configuration state' */
-       write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_VPC);
-
        if (!list_empty(&v->tc)) {
                if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
                        printk(KERN_WARNING "VPE: TC %d is already in use.\n",
@@ -756,6 +755,9 @@
                return -ENOEXEC;
        }
 
+       /* Put MVPE's into 'configuration state' */
+       write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_VPC);
+
        settc(t->index);
 
        /* should check it is halted, and not activated */
@@ -773,10 +775,8 @@
 
        /* Write the address we want it to start running from in the TCPC 
register. */
        write_tc_c0_tcrestart((unsigned long)v->__start);
-
        write_tc_c0_tccontext((unsigned long)0);
 
-
        /* mark the TC as activated, not interrupt exempt and not dynamically 
           allocatable */
        val = read_tc_c0_tcstatus();
@@ -823,7 +823,7 @@
        return 0;
 }
 
-static unsigned long find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
+static int find_vpe_symbols(vpe_t * v, Elf_Shdr * sechdrs,
                                      unsigned int symindex, const char *strtab,
                                      struct module *mod)
 {
@@ -840,6 +840,9 @@
                }
        }
 
+       if ( (v->__start == 0) || (v->shared_ptr == NULL))
+               return -1;
+
        return 0;
 }
 
@@ -974,6 +977,19 @@
                }
        } else {
                for (i = 0; i < hdr->e_shnum; i++) {
+
+                       /* Internal symbols and strings. */
+                       if (sechdrs[i].sh_type == SHT_SYMTAB) {
+                               symindex = i;
+                               strindex = sechdrs[i].sh_link;
+                               strtab = (char *)hdr + 
sechdrs[strindex].sh_offset;
+
+                               /* mark the symtab's address for when we try to 
find the 
+                                  magic symbols */
+                               sechdrs[i].sh_addr = (size_t) hdr + 
sechdrs[i].sh_offset;
+                       }
+
+                       /* filter sections we dont want in the final image */
                        if (!(sechdrs[i].sh_flags & SHF_ALLOC) || 
                            (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) {
                                printk( KERN_DEBUG " ignoring section, "
@@ -992,12 +1008,13 @@
                                return -ENOEXEC;
                        }
 
-                       printk(KERN_DEBUG " copying section sh_name %s, sh_addr 
0x%x size 0x%x\n", 
+                       printk(KERN_DEBUG " copying section sh_name %s, sh_addr 
0x%x "
+                              "size 0x%x0 from x%p\n", 
                               secstrings + sechdrs[i].sh_name, 
sechdrs[i].sh_addr,
-                              sechdrs[i].sh_size);
+                              sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset);
 
                        if (sechdrs[i].sh_type != SHT_NOBITS)
-                               memcpy((void *)sechdrs[i].sh_addr, v->pbuffer + 
sechdrs[i].sh_offset,
+                               memcpy((void *)sechdrs[i].sh_addr, (char *)hdr 
+ sechdrs[i].sh_offset,
                                        sechdrs[i].sh_size);
                        else
                                memset((void *)sechdrs[i].sh_addr, 0, 
sechdrs[i].sh_size);
@@ -1022,6 +1039,7 @@
        return err;
 }
 
+#ifdef VPE_DEBUG
 static void dump_vpe(vpe_t * v)
 {
        struct tc *t;
@@ -1035,6 +1053,7 @@
                dump_tc(t);
        }
 }
+#endif
 
 static void cleanup_tc(struct tc *tc)
 {
@@ -1129,6 +1148,8 @@
                printk("VPE: open, getcwd returned %d\n", ret);
        }
 
+       v->shared_ptr = NULL;
+       v->__start = 0;
        return 0;
 }
 
@@ -1157,14 +1178,6 @@
                ret = -ENOEXEC;
        }
 
-       /* It's good to be able to run the SP and if it chokes have a look at
-          the /dev/rt?. But if we reset the pointer to the shared struct we 
-          loose what has happened. So perhaps if garbage is sent to the vpe 
-          device, use it as a trigger for the reset. Hopefully a nice 
-          executable will be along shortly. */
-       if (ret < 0)
-               v->shared_ptr = NULL;
-
        // cleanup any temp buffers
        if (v->pbuffer)
                vfree(v->pbuffer);

<Prev in Thread] Current Thread [Next in Thread>