Suspend/resume was broken on my 15" MBP (vanilla 2.6.18 with
mactel-linux patches)
1) The quirk that re-enabled 'SCI_EN' was only selected on the MacBook.
I added MacBookPro to the list.
2) On my MBP (and from postings I saw, others experience the same problem)
suspend seems to freeze.
I found that this is actually not the case but the machine is
waiting for
the IDE BUSY signal to go clear during suspend. Eventually this
times out
and I get 'hda: drive not ready for command' messages.
It seems that ACPI 'prepare for suspend' does something to the IDE
port/bus
so that it always asserts BUSY [maybe something is powered off].
==> the patch adds a test for 'drive->blocked' and omits the
ide_wait_stat() if
'blocked'. This should be OK since in the 'blocked' state no real
(hw) commands
are issued but only PM related 'pseudo' commands.
3) Even with 2) fixed there is another problem: The BUSY assertion of
the IDE bus
is only reversed by a real suspend/resume cycle but not if the
suspend operation
is rejected by anything. In this case, BUSY remains asserted and
leaves the
IDE interface dead (and you have to suffer through endless
retries/timeouts).
I found that ACPI 'prepare for suspend' changes ICH7 GPIO pin [14]
which is
configured as an output and wiggling that bit is directly related
with IDE BUSY
(i.e., clearing GPIO[14] -> inb(0x1f7) == 0x80, setting GPIO[14] ->
inb(0x1f7) == 0x00)
==> the patch adds a new ich7_quirk which whacks GPIO[14] from 'finish'
NOTES
- 3) is only enabled for MacbookPro since I can't test on another
platform
- Safety of 2) should be reviewed by somebody else
- attached patch to be applied over mactel-2.6.18 patch
HTH
-- Till
PS:
- I observed two more suspend/resume issues [not IDE related though
but just
for the record]:
a) proprietary fglrx kernel driver 8.29.6-1 deadlocked on
suspend. I discovered
that the proprietary firegl_pci_save_state() routine corrupts
memory. A patch
I posted today on the mactel-linux-users list replacing the
proprietary routines by
generic linux' pci_save_state/pci_save_restore fixes this (a
peek under the hood
shows that the proprietary routine doesn't do anything
special apart from
messing up pointers - they really should use the generic ones).
b) if I load the bluetooth stack from /etc/init.d (debian etch)
then I sometimes experience
suspend rejections; these seem to be caused by the 'device
firmware update' interface
which is not claimed by any driver. The generic code seems to
behave incorrectly
under some circumstances and reject the suspend.
Strangely, if I start bluetooth after everything is up then
suspend/resume work OK.
diff -rcN linux-2.6.18.orig/drivers/acpi/sleep/main.c linux-2.6.18/drivers/acpi/sleep/main.c
*** linux-2.6.18.orig/drivers/acpi/sleep/main.c 2006-10-12 10:58:22.000000000 -0700
--- linux-2.6.18/drivers/acpi/sleep/main.c 2006-10-11 12:27:27.000000000 -0700
***************
*** 35,41 ****
};
static int init_8259A_after_S1;
! static int ich7_sci_en_quirk_enabled;
/**
* acpi_pm_prepare - Do preliminary suspend work.
--- 35,41 ----
};
static int init_8259A_after_S1;
! static int ich7_quirks;
/**
* acpi_pm_prepare - Do preliminary suspend work.
***************
*** 95,102 ****
case PM_SUSPEND_MEM:
do_suspend_lowlevel();
! if (ich7_sci_en_quirk_enabled)
{
int pm1c = inw(0x404);
pm1c |= 0x01; /* SCI_EN */
outw (pm1c, 0x404);
--- 95,103 ----
case PM_SUSPEND_MEM:
do_suspend_lowlevel();
! if (ich7_quirks & 1)
{
+ /* ICH7 comes out of sleep with SCI_EN off; must whack */
int pm1c = inw(0x404);
pm1c |= 0x01; /* SCI_EN */
outw (pm1c, 0x404);
***************
*** 155,160 ****
--- 156,169 ----
/* reset firmware waking vector */
acpi_set_firmware_waking_vector((acpi_physical_address) 0);
+ if ( 2 & ich7_quirks ) {
+ /* if sleep was rejected we need to re-set GPIO bit 14
+ *
+ * FIXME: this ugly - we should look up the port number!
+ */
+ outl(inl(0x50c) | (1<<14), 0x50c);
+ }
+
if (init_8259A_after_S1) {
printk("Broken toshiba laptop -> kicking interrupts\n");
init_8259A(0);
***************
*** 202,216 ****
}
/*
! * Apple Macbook comes back from sleep with the SCI_EN bit disabled
! * causing a flood of unacknowledged IRQ9s. We need to set SCI_EN
! * as soon as we come back
*/
! static int __init init_ich7_sci_en_quirk(struct dmi_system_id *d)
{
! printk(KERN_WARNING "%s detected (ICH7 SCI_EN quirk enabled)\n",
! d->ident);
! ich7_sci_en_quirk_enabled = 1;
return 0;
}
--- 211,247 ----
}
/*
! * Apple Macbook (Pro, too) comes back from sleep with the SCI_EN bit
! * disabled causing a flood of unacknowledged IRQ9s.
! * We need to set SCI_EN as soon as we come back.
! *
! * Apple Macbook Pro (non-pro unknown) has IDE (cdrom) BUSY
! * all the time after acpi_sleep_prepare() returns. This state
! * is cleared after a 'real' resume but not if sleep is rejected
! * by any party.
! * I (Till Straumann <[EMAIL PROTECTED]>) found that
! * GPIO bit 14 (which is normally set) is cleared by acpi_sleep_prepare()
! * and that setting it makes IDE operational again.
! * Hence I added a quirk to whack the bit from the 'finish' method
! * if we didn't really sleep.
*/
! static int __init init_ich7_quirks(struct dmi_system_id *d)
{
! int quirks = (int)d->driver_data;
! char *sep = "";
!
! ich7_quirks = quirks;
!
! printk(KERN_WARNING "%s detected (quirks: ",d->ident);
! if ( 1 & quirks ) {
! printk("ICH7 SCI_EN");
! sep = ", ";
! }
! if ( 2 & quirks ) {
! printk("%sGPIO[14]_EN", sep);
! sep = ", ";
! }
! printk(" enabled)\n");
return 0;
}
***************
*** 222,232 ****
.matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
},
{
! .callback = init_ich7_sci_en_quirk,
.ident = "Apple MacBook",
.matches = {DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),},
},
! {},
};
static int __init acpi_sleep_init(void)
--- 253,270 ----
.matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
},
{
! .callback = init_ich7_quirks,
.ident = "Apple MacBook",
.matches = {DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),},
+ .driver_data = (void*) 1,
+ },
+ {
+ .callback = init_ich7_quirks,
+ .ident = "Apple MacBookPro",
+ .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),},
+ .driver_data = (void*) 3,
},
! {},
};
static int __init acpi_sleep_init(void)
*** linux-2.6.18.orig/drivers/ide/ide-io.c 2006-10-12 10:58:22.000000000 -0700
--- linux-2.6.18/drivers/ide/ide-io.c 2006-10-07 01:47:58.000000000 -0700
***************
*** 424,430 ****
struct request_pm_state *pm = rq->end_io_data;
#ifdef DEBUG_PM
printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n",
! drive->name, rq->pm->pm_step, stat, err);
#endif
ide_complete_power_step(drive, rq, stat, err);
if (pm->pm_step == ide_pm_state_completed)
--- 426,432 ----
struct request_pm_state *pm = rq->end_io_data;
#ifdef DEBUG_PM
printk("%s: complete_power_step(step: %d, stat: %x, err: %x)\n",
! drive->name, pm->pm_step, stat, err);
#endif
ide_complete_power_step(drive, rq, stat, err);
if (pm->pm_step == ide_pm_state_completed)
***************
*** 1006,1012 ****
ide_check_pm_state(drive, rq);
SELECT_DRIVE(drive);
! if (ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
return startstop;
}
--- 1008,1015 ----
ide_check_pm_state(drive, rq);
SELECT_DRIVE(drive);
! /* Don't wait if we are going to sleep; ACPI seems to mark the channel busy; T.S, 2006/09 */
! if ( !drive->blocked && ide_wait_stat(&startstop, drive, drive->ready_stat, BUSY_STAT|DRQ_STAT, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
return startstop;
}
***************
*** 1021,1027 ****
struct request_pm_state *pm = rq->end_io_data;
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
! drive->name, rq->pm->pm_step);
#endif
startstop = ide_start_power_step(drive, rq);
if (startstop == ide_stopped &&
--- 1024,1030 ----
struct request_pm_state *pm = rq->end_io_data;
#ifdef DEBUG_PM
printk("%s: start_power_step(step: %d)\n",
! drive->name, pm->pm_step);
#endif
startstop = ide_start_power_step(drive, rq);
if (startstop == ide_stopped &&
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Mactel-linux-devel mailing list
Mactel-linux-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mactel-linux-devel