[tlinux-users:08143] Re: New release of omnibook module soon: testing welcome

Mathieu Bérard <[email protected]>
Newsgroups gmane.linux.hardware.toshiba
Message-ID <[email protected]>
Holger Nelson a écrit :
> Just another typo-fix:
>
>
>   
One word: Thanks
One more fix like that an you have SVN commit access.

Could you please try this and check it doesn't introduce
any regression:
(it's against r166)

--- trunk/nbsmi.c    2006-09-12 03:09:09.450999561 +0200
+++ exp/nbsmi.c    2006-09-12 03:08:27.410413116 +0200
@@ -77,48 +77,93 @@
 extern const struct pci_device_id lpc_bridge_table[];
 
 /*
- * Since we are going to trigger an SMI, all registers may be mangled 
in the
- * process. So we save and restore all registers and eflags in the stack.
+ * Since we are going to trigger an SMI, all registers (I assume this 
does not
+ * include esp and maybe ebp) and eflags may be mangled in the
+ * process.
+ * So we save and restore all registers and eflags using the stack.
  * We also disable preemtion and IRQs upon SMI call.
+ * FIXME: To be sorted out:
+ * -> Can we reliably use spin_lock_irqsave/restore and remove the 
pushf/popf ?
+ * -> Can we remove the pusha/popa and add eax ebx ecx edx esi edi to 
clobber list ?
  */
 
-static inline void ati_do_smi_call(int *retval, u16 function)
+static inline void ati_do_smi_call(u32 *retval, u16 function)
 {
-    // Call to SMI
     spin_lock_irq(&smi_spinlock);
+   
+/*
+ * Equivalent pseudocode:
+ *
+ * save_all_regs_eflags;
+ * eax = function; [non null]
+ * outw(eax, ATI_SMI_PORT); <- This Trigger an SMI
+ * if( eax == 0 ) [success if eax has been cleared]
+ *     goto out;
+ * if( inb(ATI_SMI_PORT + 1) == 0) [if not in eax, success maybe be 
stored here]
+ *    goto out;
+ * retval = -EIO; [too bad]
+ * out:
+ * restore_all_regs_eflags;
+ */
+
     __asm__ __volatile__("pushf;    \
                   pusha;    \
-                  out %w0,%w1;    \
+                  outw %w1,%2;    \
+                  cmpw $0, %%ax;    \
+                  jz 1f;        \
+                  inw %3,%%ax;    \
+                  cmpw $0, %%ax;    \
+                  jz 1f;        \
+                  movl %4, %0;    \
+                  1:;    \
                   popa;    \
                   popf"
-                 :
-                 : "a"(function), "Nd"(ATI_SMI_PORT)
-                 : "esp");
-    /*    outw( function, ATI_SMI_PORT ); Call to SMI */
-    *retval = inw(ATI_SMI_PORT + 1);
+                 : "=m" (retval)
+                 : "a"(function), "N"(ATI_SMI_PORT), 
"N"(ATI_SMI_PORT+1), "i"(EIO)
+                 );
     spin_unlock_irq(&smi_spinlock);   
 }
 
-static inline void intel_do_smi_call(int *retval, u16 function, u32 sci_en)
+static inline void intel_do_smi_call(u32 *retval, u16 function)
 {
-    u32 state;
-   
+    u32 state, sci_en;
     spin_lock_irq(&smi_spinlock);
+
+/*
+ * We get the PMBASE offset ( bits 15:7 at 0x40 offset of PCI config 
space )
+ * And we access offset 2c (GPE0_EN), save the state, disable all SCI
+ * and restore the state after the SMI call
+ */           
+    pci_read_config_dword(lpc_bridge, INTEL_PMBASE, &sci_en);
+    sci_en = sci_en & 0xff80; /* Keep bits 15:7 */
+    sci_en += INTEL_GPE0_EN;  /* GPEO_EN offset */
     state = inl(sci_en);
-    outl( 0, sci_en );
 
-    /* Success/Failure is saved in eax so don't save is on stack */
-   
+/*
+ * Equivalent pseudocode:
+ *
+ * save_all_regs_eflags;
+ * eax = function; [non null]
+ * outw(eax, INTEL_SMI_PORT); <- This Trigger an SMI
+ * if( eax == 0 ) [success if eax has been cleared]
+ *     goto out;
+ * retval = -EIO; [too bad]
+ * out:
+ * restore_all_regs_eflags;
+ */
     __asm__ __volatile__("pushf;    \
-                  push %%ecx;push %%edx;push %%ebx;push %%esi;push 
%%edi; push %%ebp;    \
-                  out %w0,%w1;    \
-                  pop %%ebp; pop %%edi; pop %%esi; pop %%ebx; pop 
%%edx; pop %%ecx;     \
-                  popf;     \
-                  movl %%eax, (%2)"
-                 :
-                 : "a"(function), "Nd"(INTEL_SMI_PORT), "b"(retval)
-                 : "ecx", "edx", "esi", "edi", "esp");
-   
+                  pusha;    \
+                  outw %w1,%2;    \
+                  cmpw $0, %%ax;    \
+                  jz 1f;        \
+                  movl %3, %0;    \
+                  1:;    \
+                  popa;    \
+                  popf"
+                 : "=m" (retval)
+                 : "a"(function), "N"(INTEL_SMI_PORT), "i"(-EIO)
+                 );
+
     outl( state, sci_en );
     spin_unlock_irq(&smi_spinlock);   
 }
@@ -126,8 +171,7 @@
 
 static int nbsmi_smi_command(u16 function,const u8 *inputbuffer, u8 
*outputbuffer)
 {
-    u32 retval;
-    u32 sci_en;
+    u32 retval = 0;
     int count;
    
     for(count = 0; count < BUFFER_SIZE; count++) {
@@ -146,15 +190,7 @@
 
     switch (lpc_bridge->vendor) {
         case PCI_VENDOR_ID_INTEL:
-/*
- * We get the PMBASE offset ( bits 15:7 at 0x40 offset of PCI config 
space )
- * And we access offset 2c (GPE0_EN), save the state, disable all SCI
- * and restore the state in intel_do_smi_call function
- */
-            pci_read_config_dword(lpc_bridge, INTEL_PMBASE, &sci_en);
-            sci_en = sci_en & 0xff80; /* Keep bits 15:7 */
-            sci_en += INTEL_GPE0_EN;  /* GPEO_EN offset */
-            intel_do_smi_call(&retval,function,sci_en);
+            intel_do_smi_call(&retval,function);
             break;
         case PCI_VENDOR_ID_ATI:
             ati_do_smi_call(&retval,function);
@@ -432,7 +468,7 @@
     if((retval = nbsmi_smi_read_command(&aerial_op, &data)))
         goto out;
    
-    *state = data ? KILLSWITCH : 0; /* Make it 1 or 0 */
+    *state = data ? KILLSWITCH : 0;
 
     aerial_op.read_addr = SMI_GET_AERIAL;
 
-- 
Mathieu
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.