Suspend issue on macbook air 6.2

If you feel like giving it one last shot try this:

Systemd resume unit file:

/etc/systemd/system/usb-on.service

Systemd resume service file contents:

#/etc/systemd/system/usb-on.service
#sudo systemctl enable usb-on.service
#sudo systemctl start usb-on.service
#sudo systemctl status usb-on.service
#sudo systemctl daemon-reload
[Unit]
Description=Enable USB upon resume
After=suspend.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/local/sbin/usb_on.sh
ExecStart=/usr/bin/rmmod hid_apple
ExecStart=/usr/bin/sleep 3
ExecStop=/usr/bin/modprobe hid_apple

[Install]
WantedBy=suspend.target

As the keyboard module commands threw no errors, it’s possible this version may restart your keyboard after resuming.

Good luck.

On the Arch forums I found two different service files to fix suspend problems on Macs.

One of these may work for you:

[Unit]
Description=Disable USB wakeup triggers in /proc/acpi/wakeup

[Service]
Type=oneshot
ExecStart=/bin/sh -c "echo EHC1 > /proc/acpi/wakeup; echo EHC2 > /proc/acpi/wakeup; echo XHC > /proc/acpi/wakeup"
ExecStop=/bin/sh -c "echo EHC1 > /proc/acpi/wakeup; echo EHC2 > /proc/acpi/wakeup; echo XHC > /proc/acpi/wakeup"
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

https://bbs.archlinux.org/viewtopic.php?pid=1575617#p1575617

[Unit]
Description=Configure LID-only device events for linux-macbook
ConditionPathExists=/proc/acpi/wakeup
After=suspend.target

[Service]
Type=oneshot
ExecStart=/bin/sh -c "awk '$1 !~ /^LID/ && $3 ~ /enabled/ {print $1}' /proc/acpi/wakeup | xargs -I{} echo '{}' > /proc/acpi/wakeup"
ExecStart=/bin/sh -c "awk '$1 ~ /^LID/ && $3 ~ /disabled/ {print $1}' /proc/acpi/wakeup | xargs -I{} echo '{}' > /proc/acpi/wakeup"
RemainAfterExit=yes
TimeoutSec=0

[Install]
WantedBy=multi-user.target sleep.target

@tbg Thank you so much :-). I will try all the scripts when I come back from a travel. I will report back soon.

1 Like

@tbg I tried all 3 scripts and same issue. Still no luck.

But thank you so much for all your help and your time :slight_smile:

I will rewrite the first set of units for you, as they looked like a very promising solution.

I reviewed the earlier units that were partially successful. I found where the error was occurring, and have hopefully corrected the issue. It’s certainly worth giving these modified units a try.

Revised units.

Systemd suspend unit file:

/etc/systemd/system/usb-off.service

Systemd suspend service file contents:

#/etc/systemd/system/usb-off.service
#sudo systemctl enable usb-off.service
#sudo systemctl start usb-off.service
#sudo systemctl status usb-off.service
#sudo systemctl daemon-reload
[Unit]
Description=Disable USB upon suspend
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/bin/rmmod hid_apple
ExecStart=/usr/local/sbin/usb_off.sh

[Install]
WantedBy=sleep.target

Corresponding script that is to be executed before suspending:

Suspend script:

/usr/local/sbin/usb_off.sh

Suspend script contents:

#sudo nano /usr/local/sbin/usb_off.sh
#sudo chmod +x /usr/local/sbin/usb_off.sh
#!/bin/bash
#reset all of USB1/2/3 ports
for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
  [ -e "$i" ] || continue
  echo "${i##*/}" > "${i%/*}/unbind"
done

Systemd resume unit file:

/etc/systemd/system/usb-on.service

Systemd resume service file contents:

#/etc/systemd/system/usb-on.service
#sudo systemctl enable usb-on.service
#sudo systemctl start usb-on.service
#sudo systemctl status usb-on.service
#sudo systemctl daemon-reload
[Unit]
Description=Enable USB upon resume
After=suspend.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/usr/local/sbin/usb_on.sh
ExecStart=/usr/bin/modprobe hid_apple
StandardError=syslog

[Install]
WantedBy=suspend.target

Corresponding script that is to be executed upon resume:

Resume script:

/usr/local/sbin/usb_on.sh

Resume script contents:

#sudo nano /usr/local/sbin/usb_on.sh
#sudo chmod +x /usr/local/sbin/usb_on.sh
#!/bin/bash
#reset all of USB1/2/3 ports
for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
  [ -e "$i" ] || continue
  echo "${i##*/}" > "${i%/*}/unbind"
  echo "${i##*/}" > "${i%/*}/bind"
done

Ensure both scripts are executable and enable both services.

sudo systemctl enable usb-off.service
sudo chmod +x /usr/local/sbin/usb_off.sh
sudo systemctl enable usb-on.service
sudo chmod +x /usr/local/sbin/usb_on.sh

Then restart.

2 Likes

Thank you @tbg :-). I’m gonna try your changes soon.

I saw that others have the exact same problem:

https://bugzilla.kernel.org/show_bug.cgi?id=201997

Do you know how to disable sd card reader in manjaro? Someone on the bugzilla kernel thread says it fixes the issue.

If I can find the correct module we could unload/load the driver at suspend using the service file method. Otherwise if you simply want it disabled, that can be done via blacklisting its driver. To find that info you need to post:

lsmod
Module                  Size  Used by
fuse                  118784  3
snd_hda_codec_hdmi     57344  1
intel_rapl             24576  0
x86_pkg_temp_thermal    16384  0
intel_powerclamp       16384  0
coretemp               16384  0
kvm_intel             237568  0
kvm                   737280  1 kvm_intel
btusb                  53248  0
wl                   6463488  0
btrtl                  16384  1 btusb
btbcm                  16384  1 btusb
btintel                24576  1 btusb
ofpart                 16384  0
cmdlinepart            16384  0
bluetooth             638976  5 btrtl,btintel,btbcm,btusb
joydev                 24576  0
intel_spi_platform     16384  0
intel_spi              20480  1 intel_spi_platform
irqbypass              16384  1 kvm
spi_nor                36864  1 intel_spi
crct10dif_pclmul       16384  0
crc32_pclmul           16384  0
ghash_clmulni_intel    16384  0
pcbc                   16384  0
mtd                    69632  5 cmdlinepart,intel_spi,ofpart
iTCO_wdt               16384  0
iTCO_vendor_support    16384  1 iTCO_wdt
aesni_intel           200704  0
i915                 2072576  18
aes_x86_64             20480  1 aesni_intel
applesmc               24576  0
input_polldev          16384  1 applesmc
crypto_simd            16384  1 aesni_intel
cryptd                 28672  3 crypto_simd,ghash_clmulni_intel,aesni_intel
glue_helper            16384  1 aesni_intel
intel_cstate           16384  0
intel_uncore          135168  0
intel_rapl_perf        16384  0
mousedev               24576  0
ecdh_generic           24576  1 bluetooth
cfg80211              782336  1 wl
i2c_algo_bit           16384  1 i915
drm_kms_helper        200704  1 i915
uas                    28672  0
input_leds             16384  0
led_class              16384  2 input_leds,applesmc
bcm5974                20480  0
snd_hda_codec_cirrus    20480  1
pcspkr                 16384  0
snd_hda_codec_generic    86016  1 snd_hda_codec_cirrus
thunderbolt           143360  0
snd_hda_intel          45056  9
drm                   479232  7 drm_kms_helper,i915
snd_hda_codec         151552  4 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec_cirrus
rfkill                 28672  6 bluetooth,cfg80211
snd_hda_core           94208  5 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_codec_cirrus
intel_gtt              24576  1 i915
snd_hwdep              16384  1 snd_hda_codec
acpi_als               16384  0
sbs                    20480  0
mei_me                 45056  0
agpgart                49152  2 intel_gtt,drm
snd_pcm               131072  4 snd_hda_codec_hdmi,snd_hda_intel,snd_hda_codec,snd_hda_core
kfifo_buf              16384  1 acpi_als
sbshc                  16384  1 sbs
industrialio           81920  2 acpi_als,kfifo_buf
syscopyarea            16384  1 drm_kms_helper
spi_pxa2xx_platform    28672  0
bdc_pci                16384  0
snd_timer              36864  1 snd_pcm
sysfillrect            16384  1 drm_kms_helper
evdev                  24576  18
apple_bl               16384  0
ac                     16384  0
sysimgblt              16384  1 drm_kms_helper
mac_hid                16384  0
mei                   106496  1 mei_me
fb_sys_fops            16384  1 drm_kms_helper
snd                    98304  26 snd_hda_codec_generic,snd_hda_codec_hdmi,snd_hwdep,snd_hda_intel,snd_hda_codec,snd_timer,snd_hda_codec_cirrus,snd_pcm
lpc_ich                28672  0
soundcore              16384  1 snd
i2c_i801               32768  0
pcc_cpufreq            16384  0
uinput                 20480  0
crypto_user            16384  0
ip_tables              28672  0
x_tables               45056  1 ip_tables
hid_apple              16384  0
hid_generic            16384  0
usbhid                 57344  0
hid                   139264  3 usbhid,hid_apple,hid_generic
ext4                  737280  1
crc32c_generic         16384  0
crc16                  16384  2 bluetooth,ext4
mbcache                16384  1 ext4
jbd2                  126976  1 ext4
fscrypto               32768  1 ext4
sd_mod                 61440  3
usb_storage            69632  1 uas
ahci                   40960  2
libahci                40960  1 ahci
libata                278528  2 libahci,ahci
scsi_mod              258048  4 sd_mod,usb_storage,uas,libata
xhci_pci               16384  0
crc32c_intel           24576  2
xhci_hcd              266240  1 xhci_pci

Thank you.

I will also need this output to be sure of where the MMC is located on the USB bus.

for device in $(ls /sys/bus/usb/devices/*/product); do echo $device;cat $device;done

@tbg thank you so much for helping me out :-).

/sys/bus/usb/devices/1-3.3/product
Bluetooth USB Host Controller
/sys/bus/usb/devices/1-3/product
BRCM20702 Hub
/sys/bus/usb/devices/1-5/product
Apple Internal Keyboard / Trackpad
/sys/bus/usb/devices/usb1/product
xHCI Host Controller
/sys/bus/usb/devices/usb2/product
xHCI Host Controller

Please post:

lsusb
lsusb -t

I need to find the bus address. It seems to be hiding on me. Sorry, but I need more info.

~ $ lsusb                                                                                                                                               master
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 05ac:0291 Apple, Inc. 
Bus 001 Device 006: ID 05ac:828f Apple, Inc. 
Bus 001 Device 002: ID 0a5c:4500 Broadcom Corp. BCM2046B1 USB 2.0 Hub (part of BCM2046 Bluetooth)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
~ $ lsusb -t                                                                                                                                            master
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/0p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/9p, 480M
    |__ Port 3: Dev 2, If 0, Class=Hub, Driver=hub/3p, 12M
        |__ Port 3: Dev 6, If 2, Class=Vendor Specific Class, Driver=btusb, 12M
        |__ Port 3: Dev 6, If 0, Class=Vendor Specific Class, Driver=btusb, 12M
        |__ Port 3: Dev 6, If 3, Class=Application Specific Interface, Driver=, 12M
        |__ Port 3: Dev 6, If 1, Class=Wireless, Driver=btusb, 12M
    |__ Port 5: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 5: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M
    |__ Port 5: Dev 3, If 2, Class=Human Interface Device, Driver=bcm5974, 12M
~ $

I just wanted to let you know I haven’t given up on your issue. Far from it, I’ve been working feverishly on finding a systemd solution to the suspend/resume issues that plague Linux.

I’m pretty sure I’ve made a major breakthrough on this issue. The problem is not unloading the problematic devices prior to suspend, but getting them reloaded into the users environment properly after resuming.

I have not exhaustively tested my new method, but the first trials seem to be working well. Of course I do not have a Mac, so there’s no predicting if it is going to work on your setup. I think there’s a very high chance it will work though.

When I finish all my testing and get everything properly documented I will be posting a hopefully final solution to this. Check back in a day or so.

I’ve been trying to crack this nut for a while, so I hope this is the real deal this time.

3 Likes

No rush :-).

Thank you for all your help :-).

I have spent a lot of time working on this service and the associated scripts. I am hoping this will solve not just your problem, but a lot of other related suspend issues. This should solve most any suspend issue related to components on the USB bus. Hopefully this will resolve issues with Bluetooth, USB WiFi adapters, keyboards, USB/Bluetooth mice, and trackpads that prevent resuming successfully. In my limited testing the service has performed flawlessly.

I hope this works for you and I think it should.

Systemd Combined Disable/Enable USB Service File:

With a text editor create:

/etc/systemd/system/usb-restart.service

Systemd combined service file contents:

You must substitute your username in place of “user” in both “ExecStart/Post” lines below:

#/etc/systemd/system/usb-restart.service
#sudo systemctl enable usb-restart.service
#sudo systemctl start usb-restart.service
#systemctl list-unit-files --state=enabled
#sudo systemctl stop usb-restart.service
#sudo systemctl disable usb-restart.service
#systemctl status usb-restart.service
#sudo systemctl daemon-reload

[Unit]
Description=Disable, then restart USB
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/sudo -E  /home/user/.config/bin/disable_usb.sh
ExecStartPost=/usr/bin/sudo -E  /home/user/.config/bin/enable_usb.sh

[Install]
WantedBy=sleep.target

Suspend Script

Create the script that is to be executed before suspending:

You will first need to create a bin directory within the hidden .config directory of your users home folder.

mkdir -p ~/.config/bin

Then, with a text editor create:

~/.config/bin/disable_usb.sh

Suspend script contents:

#!/bin/bash
#Disable all USB devices
set -euo pipefail
IFS=$'\n\t'

VENDOR="****"
PRODUCT="****"

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
  fi
done

Save the file, and exit the text editor.

Resume Script

Create the script that is to be executed after coming out of suspension.

With a text editor create:

~/.config/bin/enable_usb.sh

Resume script contents:

#Enable all USB devices
set -euo pipefail
IFS=$'\n\t'

VENDOR="****"
PRODUCT="****"

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 1 > $DIR/authorized
  fi
done

Enable the service.

sudo systemctl enable usb-restart.service

Then, ensure both scripts are executable:

chmod +x ~/.config/bin/disable_usb.sh
chmod +x ~/.config/bin/enable_usb.sh

Before testing the service, test that both scripts are working properly.

Save all open documents, eject all USB drives, and close all open programs.

In the terminal, su to root:

su

Enter the root password.

Substitute your username in place of “user” in the command below:

sudo -E /bin/bash -lc  'home/user/.config/bin/disable_usb.sh; sleep 20; home/user/.config/bin/enable_usb.sh'

After running the command, all USB devices should shut down for 20 seconds, (then restart).

The following steps are not essential, but it are important for security,

Running user scripts with root privileges could be a security hazard if your system is compromised. Ensuring the scripts cannot be tampered with will make your system more secure. Therefore, we are going to make both scripts immutable.

Write protect the scripts as follows:

sudo chattr +i ~/.config/bin/disable_usb.sh
sudo chattr +i ~/.config/bin/enable_usb.sh

The immutable “+i” attribute write protects the files so that no one can modify them, (not even the root user).

If you need to remove the immutable attribute use “-i”, as in the following commands:

sudo chattr -i ~/.config/bin/disable_usb.sh
sudo chattr -i ~/.config/bin/enable_usb.sh

Then restart.

2 Likes

@tbg: I tried your scripts and they work perfectly :D. Now it suspends. This has been a problem since 2013.

Your instructions are perfectly clear :-). Thank you so much for all your help!!

I’m glad to help. I enjoy learning from writing new service methods to fix suspend problems.

So happy to hear it helped.

4 Likes

Hehe … nice to see this very long thread solved. Great job !!!

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

Forum kindly sponsored by Bytemark