]> git.neil.brown.name Git - history.git/commitdiff
IBM PCI Hotplug driver: polling thread locking cleanup
authorGreg Kroah-Hartman <greg@kroah.com>
Fri, 7 Jun 2002 06:27:01 +0000 (23:27 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 7 Jun 2002 06:27:01 +0000 (23:27 -0700)
removed a lot of bizzare polling locking logic, causing the driver to not sleep
for 2 seconds with some locks held.  This improves userspace interaction by
a few orders of magnitude :)

drivers/hotplug/ibmphp_core.c
drivers/hotplug/ibmphp_hpc.c

index e25dba075f0efdfa4d0fc3e529c60662ee4f4bbc..a377aef55f30d7c2efeb0c5a3f45ef4912d9fa15 100644 (file)
@@ -44,7 +44,7 @@
 #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
 #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
 
-#define DRIVER_VERSION "0.2"
+#define DRIVER_VERSION "0.3"
 #define DRIVER_DESC    "IBM Hot Plug PCI Controller Driver"
 
 int ibmphp_debug;
index a4338b48af1e75483e665c745f985e70671726f9..b3150aea49ffe9111625808f38c6be86a9374ad1 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Written By: Jyoti Shah, IBM Corporation
  *
- * Copyright (c) 2001,2001 IBM Corp.
+ * Copyright (c) 2001-2002 IBM Corp.
  *
  * All rights reserved.
  *
@@ -27,7 +27,6 @@
  *
  */
 
-//#include <linux/delay.h>
 #include <linux/wait.h>
 #include <linux/time.h>
 #include <linux/module.h>
@@ -35,9 +34,6 @@
 #include <linux/smp_lock.h>
 #include "ibmphp.h"
 
-#define POLL_NO                0x01
-#define POLL_YES       0x00
-
 static int to_debug = FALSE;
 #define debug_polling(fmt, arg...)     do { if (to_debug) debug (fmt, arg); } while (0)
 
@@ -98,19 +94,15 @@ static int to_debug = FALSE;
 // if bits 20,22,25,26,27,29,30 are OFF return TRUE
 #define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? FALSE : TRUE))
 
-// return code 0:poll slots, 1-POLL_LATCH_CNT:poll latch register
-#define INCREMENT_POLLCNT(i)   ((i < POLL_LATCH_CNT) ? i++ : (i=0))
 //----------------------------------------------------------------------------
 // global variables
 //----------------------------------------------------------------------------
 static int ibmphp_shutdown;
 static int tid_poll;
-static int stop_polling;               // 2 values: poll, don't poll
 static struct semaphore sem_hpcaccess; // lock access to HPC
 static struct semaphore semOperations; // lock all operations and
                                        // access to data structures
 static struct semaphore sem_exit;      // make sure polling thread goes away
-static struct semaphore sem_poll;      // make sure poll is idle 
 //----------------------------------------------------------------------------
 // local function prototypes
 //----------------------------------------------------------------------------
@@ -141,8 +133,6 @@ void ibmphp_hpc_initvars (void)
        init_MUTEX (&sem_hpcaccess);
        init_MUTEX (&semOperations);
        init_MUTEX_LOCKED (&sem_exit);
-       init_MUTEX_LOCKED (&sem_poll);
-       stop_polling = POLL_YES;
        to_debug = FALSE;
        ibmphp_shutdown = FALSE;
        tid_poll = 0;
@@ -710,11 +700,6 @@ void free_hpc_access (void)
 void ibmphp_lock_operations (void)
 {
        down (&semOperations);
-       stop_polling = POLL_NO;
-       to_debug = TRUE;
-
-       /* waiting for polling to actually stop */
-       down (&sem_poll);
 }
 
 /*----------------------------------------------------------------------
@@ -723,8 +708,6 @@ void ibmphp_lock_operations (void)
 void ibmphp_unlock_operations (void)
 {
        debug ("%s - Entry\n", __FUNCTION__);
-       stop_polling = POLL_YES;
-       to_debug = FALSE;
        up (&semOperations);
        debug ("%s - Exit\n", __FUNCTION__);
 }
@@ -732,34 +715,30 @@ void ibmphp_unlock_operations (void)
 /*----------------------------------------------------------------------
 * Name:    poll_hpc()
 *---------------------------------------------------------------------*/
+#define POLL_LATCH_REGISTER    0
+#define POLL_SLOTS             1
+#define POLL_SLEEP             2
 static void poll_hpc (void)
 {
-       struct slot myslot, *pslot = NULL;
+       struct slot myslot;
+       struct slot *pslot = NULL;
        struct list_head *pslotlist;
        int rc;
+       int poll_state = POLL_LATCH_REGISTER;
        u8 oldlatchlow = 0x00;
        u8 curlatchlow = 0x00;
-       int pollcnt = 0;
+       int poll_count = 0;
        u8 ctrl_count = 0x00;
 
-       debug ("poll_hpc - Entry\n");
+       debug ("%s - Entry\n", __FUNCTION__);
 
        while (!ibmphp_shutdown) {
-               if (stop_polling) {
-                       debug ("poll_hpc - stop_polling\n");
-                       up (&sem_poll); 
-                       /* to prevent deadlock */
-                       if (ibmphp_shutdown)
-                               break;
-                       /* to make the thread sleep */
-                       down (&semOperations);
-                       up (&semOperations);
-                       debug ("poll_hpc - after stop_polling sleep\n");
-               } else {
-                       if (pollcnt) {
-                               // only poll the latch register
-                               oldlatchlow = curlatchlow;
+               /* try to get the lock to do some kind of harware access */
+               down (&semOperations);
 
+               switch (poll_state) {
+                       case POLL_LATCH_REGISTER:
+                               oldlatchlow = curlatchlow;
                                ctrl_count = 0x00;
                                list_for_each (pslotlist, &ibmphp_slot_head) {
                                        if (ctrl_count >= ibmphp_get_total_controllers())
@@ -773,14 +752,16 @@ static void poll_hpc (void)
                                                                                  &curlatchlow);
                                                        if (oldlatchlow != curlatchlow)
                                                                process_changeinlatch (oldlatchlow,
-                                                                                       curlatchlow, pslot->ctrl);
+                                                                                      curlatchlow,
+                                                                                      pslot->ctrl);
                                                }
                                        }
                                }
-                       } else {
+                               poll_state = POLL_SLOTS;
+                               break;
+
+                       case POLL_SLOTS:
                                list_for_each (pslotlist, &ibmphp_slot_head) {
-                                       if (stop_polling)
-                                               break;
                                        pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
                                        // make a copy of the old status
                                        memcpy ((void *) &myslot, (void *) pslot,
@@ -791,31 +772,45 @@ static void poll_hpc (void)
                                                process_changeinstatus (pslot, &myslot);
                                }
 
-                               if (!stop_polling) {
-                                       ctrl_count = 0x00;
-                                       list_for_each (pslotlist, &ibmphp_slot_head) {
-                                               if (ctrl_count >= ibmphp_get_total_controllers())
-                                                       break;
-                                               pslot =
-                                                   list_entry (pslotlist, struct slot,
-                                                               ibm_slot_list);
-                                               if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
-                                                       ctrl_count++;
-                                                       if (READ_SLOT_LATCH (pslot->ctrl))
-                                                               rc = ibmphp_hpc_readslot (pslot,
-                                                                                         READ_SLOTLATCHLOWREG,
-                                                                                         &curlatchlow);
-                                               }
+                               ctrl_count = 0x00;
+                               list_for_each (pslotlist, &ibmphp_slot_head) {
+                                       if (ctrl_count >= ibmphp_get_total_controllers())
+                                               break;
+                                       pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
+                                       if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
+                                               ctrl_count++;
+                                               if (READ_SLOT_LATCH (pslot->ctrl))
+                                                       rc = ibmphp_hpc_readslot (pslot,
+                                                                                 READ_SLOTLATCHLOWREG,
+                                                                                 &curlatchlow);
                                        }
                                }
-                       }
-                       INCREMENT_POLLCNT (pollcnt);
-                       long_delay (POLL_INTERVAL_SEC * HZ);    // snooze
+                               ++poll_count;
+                               if (poll_count >= POLL_LATCH_CNT) {
+                                       poll_count = 0;
+                                       poll_state = POLL_SLEEP;
+                               }
+                               break;
+
+                       case POLL_SLEEP:
+                               /* don't sleep with a lock on the hardware */
+                               up (&semOperations);
+                               long_delay (POLL_INTERVAL_SEC * HZ);
+                               down (&semOperations);
+                               poll_state = POLL_LATCH_REGISTER;
+                               break;
                }
+
+               /* give up the harware semaphore */
+               up (&semOperations);
+
+               /* sleep for a short time just for good measure */
+               set_current_state (TASK_INTERRUPTIBLE);
+               schedule_timeout (HZ/10);
        }
-       up (&sem_poll);
+
        up (&sem_exit);
-       debug ("poll_hpc - Exit\n");
+       debug ("%s - Exit\n", __FUNCTION__);
 }
 
 
@@ -1083,7 +1078,6 @@ void ibmphp_hpc_stop_poll_thread (void)
        // cleanup
        free_hpc_access ();
        ibmphp_unlock_operations ();
-       up (&sem_poll);
        up (&sem_exit);
 
        debug ("ibmphp_hpc_stop_poll_thread - Exit\n");