[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