Patch for my RHEL3 driver set.  Please review.  Other distro patches
to follow.

-- 
Matt Domsch
Software Architect
Dell Linux Solutions linux.dell.com & www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com

diff -urNp --exclude-from=/home/mdomsch/excludes --minimal 
linux-2.4.21-32.EL.openipmi.startup/drivers/char/ipmi/ipmi_msghandler.c 
linux-2.4.21-32.EL.openipmi/drivers/char/ipmi/ipmi_msghandler.c
--- linux-2.4.21-32.EL.openipmi.startup/drivers/char/ipmi/ipmi_msghandler.c     
Tue Mar 28 22:40:44 2006
+++ linux-2.4.21-32.EL.openipmi/drivers/char/ipmi/ipmi_msghandler.c     Tue Mar 
28 23:12:16 2006
@@ -1701,8 +1701,7 @@ void ipmi_poll_interface(ipmi_user_t use
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                      void                     *send_info,
                      unsigned char            version_major,
-                     unsigned char            version_minor,
-                     ipmi_smi_t               *intf)
+                     unsigned char            version_minor)
 {
        int              i, j;
        int              rv;
@@ -1766,7 +1765,6 @@ int ipmi_register_smi(struct ipmi_smi_ha
                        spin_unlock_irqrestore(&interfaces_lock, flags);
 
                        rv = 0;
-                       *intf = new_intf;
                        break;
                }
        }
@@ -1781,8 +1779,14 @@ int ipmi_register_smi(struct ipmi_smi_ha
                /* Well, it went away.  Just return. */
                goto out;
 
+       if (rv == 0) {
+               rv = handlers->start_processing(send_info, new_intf);
+               if (rv)
+                       goto out;
+       }
+
        if (rv == 0)
-               rv = add_proc_entries(*intf, i);
+               rv = add_proc_entries(new_intf, i);
 
        if (rv == 0) {
                if ((version_major > 1)
@@ -1790,16 +1794,16 @@ int ipmi_register_smi(struct ipmi_smi_ha
                {
                        /* Start scanning the channels to see what is
                           available. */
-                       (*intf)->null_user_handler = channel_handler;
-                       (*intf)->curr_channel = 0;
-                       rv = send_channel_info_cmd(*intf, 0);
+                       new_intf->null_user_handler = channel_handler;
+                       new_intf->curr_channel = 0;
+                       rv = send_channel_info_cmd(new_intf, 0);
                        if (rv)
                                goto out;
 
                        /* Wait for the channel info to be read. */
                        up_read(&interfaces_sem);
-                       wait_event((*intf)->waitq,
-                                  ((*intf)->curr_channel>=IPMI_MAX_CHANNELS));
+                       wait_event(new_intf->waitq,
+                                  (new_intf->curr_channel>=IPMI_MAX_CHANNELS));
                        down_read(&interfaces_sem);
 
                        if (ipmi_interfaces[i] != new_intf)
@@ -1807,8 +1811,8 @@ int ipmi_register_smi(struct ipmi_smi_ha
                                goto out;
                } else {
                        /* Assume a single IPMB channel at zero. */
-                       (*intf)->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
-                       (*intf)->channels[0].protocol
+                       new_intf->channels[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
+                       new_intf->channels[0].protocol
                                = IPMI_CHANNEL_PROTOCOL_IPMB;
 
                }
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal 
linux-2.4.21-32.EL.openipmi.startup/drivers/char/ipmi/ipmi_si.c 
linux-2.4.21-32.EL.openipmi/drivers/char/ipmi/ipmi_si.c
--- linux-2.4.21-32.EL.openipmi.startup/drivers/char/ipmi/ipmi_si.c     Tue Mar 
28 22:40:44 2006
+++ linux-2.4.21-32.EL.openipmi/drivers/char/ipmi/ipmi_si.c     Tue Mar 28 
23:09:35 2006
@@ -956,9 +956,37 @@ static void si_irq_handler(int irq, void
        spin_unlock_irqrestore(&(smi_info->si_lock), flags);
 }
 
+static int smi_start_processing(void       *send_info,
+                               ipmi_smi_t intf)
+{
+       struct smi_info *new_smi = send_info;
+       new_smi->intf = intf;
+       /* Set up the timer that drives the interface. */
+       init_timer(&(new_smi->si_timer));
+       new_smi->si_timer.data = (long) new_smi;
+       new_smi->si_timer.function = smi_timeout;
+       new_smi->last_timeout_jiffies = jiffies;
+       new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
+       add_timer(&(new_smi->si_timer));
+
+       if (new_smi->si_type != SI_BT) {
+               init_completion(&(new_smi->exiting));
+               new_smi->thread_pid = kernel_thread(ipmi_thread, new_smi,
+                                                   CLONE_FS|CLONE_FILES|
+                                                   CLONE_SIGHAND);
+               if (new_smi->thread_pid <= 0) {
+                       printk(KERN_NOTICE "ipmi_si: Could not start"
+                              " kernel thread due to error, only using"
+                              " timers to drive the interface\n");
+               }
+       }
+       return 0;
+}
+
 static struct ipmi_smi_handlers handlers =
 {
        sender:                sender,
+       start_processing:      smi_start_processing,
        request_events:        request_events,
        new_user:              new_user,
        user_left:             user_left,
@@ -2174,12 +2202,16 @@ static void setup_xaction_handlers(struc
 
 static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
 {
-       if (smi_info->thread_pid > 0) {
-               /* wake the potentially sleeping thread */
-               kill_proc(smi_info->thread_pid, SIGKILL, 0);
-               wait_for_completion(&(smi_info->exiting));
+       if (smi_info->intf) {
+               /* The timer and thread are only running if the
+                  interface has been started up and registered. */
+               if (smi_info->thread_pid > 0) {
+                       /* wake the potentially sleeping thread */
+                       kill_proc(smi_info->thread_pid, SIGKILL, 0);
+                       wait_for_completion(&(smi_info->exiting));
+               }
+               del_timer_sync(&smi_info->si_timer);
        }
-       del_timer_sync(&smi_info->si_timer);
 }
 
 /* Returns 0 if initialized, or negative on an error. */
@@ -2303,29 +2335,10 @@ static int init_one_smi(int intf_num, st
        if (new_smi->irq)
                new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
 
-       /* The ipmi_register_smi() code does some operations to
-          determine the channel information, so we must be ready to
-          handle operations before it is called.  This means we have
-          to stop the timer if we get an error after this point. */
-       init_timer(&(new_smi->si_timer));
-       new_smi->si_timer.data = (long) new_smi;
-       new_smi->si_timer.function = smi_timeout;
-       new_smi->last_timeout_jiffies = jiffies;
-       new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
-
-       add_timer(&(new_smi->si_timer));
-       if (new_smi->si_type != SI_BT) {
-               init_completion(&(new_smi->exiting));
-               new_smi->thread_pid = kernel_thread(ipmi_thread, new_smi,
-                                                   CLONE_FS|CLONE_FILES|
-                                                   CLONE_SIGHAND);
-       }
-
        rv = ipmi_register_smi(&handlers,
                               new_smi,
                               
ipmi_version_major(new_smi->device_id.ipmi_version),
-                              
ipmi_version_minor(new_smi->device_id.ipmi_version),
-                              &(new_smi->intf));
+                              
ipmi_version_minor(new_smi->device_id.ipmi_version));
        if (rv) {
                printk(KERN_ERR 
                       "ipmi_si: Unable to register device: error %d\n",
diff -urNp --exclude-from=/home/mdomsch/excludes --minimal 
linux-2.4.21-32.EL.openipmi.startup/include/linux/ipmi_smi.h 
linux-2.4.21-32.EL.openipmi/include/linux/ipmi_smi.h
--- linux-2.4.21-32.EL.openipmi.startup/include/linux/ipmi_smi.h        Tue Mar 
28 22:40:44 2006
+++ linux-2.4.21-32.EL.openipmi/include/linux/ipmi_smi.h        Tue Mar 28 
23:06:35 2006
@@ -77,6 +77,13 @@ struct ipmi_smi_msg
 
 struct ipmi_smi_handlers
 {
+       /* The low-level interface cannot start sending messages to
+          the upper layer until this function is called.  This may
+          not be NULL, the lower layer must take the interface from
+          this call. */
+       int (*start_processing)(void       *send_info,
+                               ipmi_smi_t new_intf);
+
        /* Called to enqueue an SMI message to be sent.  This
           operation is not allowed to fail.  If an error occurs, it
           should report back the error in a received message.  It may
@@ -113,12 +120,15 @@ struct ipmi_smi_handlers
        void (*poll)(void *send_info);
 };
 
-/* Add a low-level interface to the IPMI driver. */
+/* Add a low-level interface to the IPMI driver.
+   The low-level interface should not deliver any messages to the
+   upper layer until the start_processing() function in the handlers
+   is called, and the lower layer must get the interface from that
+   call. */
 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
                      void                     *send_info,
                      unsigned char            version_major,
-                     unsigned char            version_minor,
-                     ipmi_smi_t               *intf);
+                     unsigned char            version_minor);
 
 /*
  * Remove a low-level interface from the IPMI driver.  This will


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to