-2

I've got a couple of late 2009 Mac Minis running Mavericks. I recently replaced their hard drives with SSDs. Everything seems to work fine, however, I don't always get SATA II speeds. The computer often negotiates down to SATA I speeds. If I restart the computer enough times, it will eventually register at SATA II speeds and I'm good to go.

I don't think there's an elegant solution to the problem, but is there a script available, or that someone could write, that on start-up would check my negotiated SATA link Speed, and if it's less than 3.0GBPS it would automatically restart the computer and loop until it reads out the appropriate speed?

Thanks! Any help would be appreciated

dcmichael
  • 3
  • 1
  • Consider investing in some decent cables! – Mark Setchell Oct 02 '17 at 13:02
  • The drives are connected directly to the mother board. These are Mac Minis. It's an issue with the outdated SATA controllers the MOBO uses. – dcmichael Oct 02 '17 at 16:45
  • Try running the following command in Terminal when booted at slow negotiated speed and again at high negotiated speed to see if there is a difference a script could potentially discern... `system_profiler SPSerialATADataType` – Mark Setchell Oct 02 '17 at 17:32
  • I've updated the answer as I had an extra `com` in `com.sata.snls.com.plist`. It's just supposed to be: `com.sata.snls.plist` The names are arbitrary and would't matter accept for keeping proper form. – user3439894 Oct 02 '17 at 23:46

2 Answers2

2

If I found myself in the situation you've described, and could not replace the hardware, I'd set up a bash script to check the SATA Negotiated Link Speed of the SSD and if it's less than 3, reboot until it's not less then 3.

Here is an example of what I'd do:

Notes:

  • This was tested under a clean install of macOS Sierra 10.12.6, where, by default, /usr/local/bin does not exist, so the target directory needs to be created first.
  • The bash script is named snls, standing for: SATA Negotiated Link Speed
  • As coded, this assumes you have only one SATA SSD and no other SATA devices connected. If you have more than one, the awk command will need to be modified as necessary.
  • The only difference in the code presented herein and what was tested is -lt 3 was set to -lt 7, because on my system 6 is the normal value of the output to the command on the left side of the -lt operator, and by setting it to 7 it rebooted until the expression was modified from Recovery Mode to enable a normal boot, where I changed it to -lt 6 so it would then boot normally. Having no issue with my system, this was the only way to test this.

In Terminal, execute the following commands to setup the bash script and Launch Daemon that will check the SATA Negotiated Link Speed of the SSD:

sudo mkdir -p /usr/local/bin
sudo touch /usr/local/bin/snls
sudo nano /usr/local/bin/snls

In nano, either type or copy and paste the following:

#!/bin/bash

[[ $(system_profiler SPSerialATADataType | awk '/Negotiated Link Speed:/{print int($4)}') -lt 3 ]] && shutdown -r now

Save the changes and exit nano by pressing the following key sequences:
ControlX
Y
Enter

Still in Terminal:

Make snls executable, only to root:

sudo chmod 744  /usr/local/bin/snls

Create the Launch Daemon .plist file for snls:

sudo touch /Library/LaunchDaemons/com.sata.snls.plist
sudo nano /Library/LaunchDaemons/com.sata.snls.plist

Copy and paste the following into nano:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.sata.nls.com</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/snls</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Save the changes and exit nano by pressing the following key sequences:
ControlX
Y
Enter

Load the Launch Daemon:

sudo launchctl load /Library/LaunchDaemons/com.sata.snls.plist

With this set, each time you boot and the SATA Negotiated Link Speed of the SSD is less than 3, it's going to reboot until it's 3, however many times it takes.


WARNING: Do not undertake this process unless you know how to boot to Recovery Mode and that Recovery Mode is working on your system, or have an alternate method to access and modify the filesystem on the SSD. Also, you are comfortable in Recovery Mode Terminal to navigate to either target file created and delete them so you can reboot normally if something is not working, e.g. stuck in an endless reboot loop, with this method on your system.

Have a look at: About macOS Recovery

Note that when booted to macOS Recovery and you start Terminal, it's not like when you open Terminal in a normal boot. You are not by default in your normal Home directory, and typing cd / doesn't take you to the root of the e.g. Macintosh HD, you'd be in the root of OS X Base System. Also, nano is not in the PATH used by Terminal in macOS Recovery, although it's available if you type the proper path filename.

When you open Terminal under macOS Recovery the PWD is /private/var/root, so to get to e.g. Macintosh HD, you type: cd /Volumes/Macintosh\ HD

Again, if you have an issue with this method, deleting either snsl or com.sata.snls.plist from macOS Recovery will allow the system to boot normally, whatever normally is for you.

user3439894
  • 7,266
  • 3
  • 17
  • 28
  • I think you'll need `/sbin` in your `PATH` for `shutdown` and `/usr/sbin` in your `PATH` for `system_profiler` - both in the `/usr/local/bin/snls` script. – Mark Setchell Oct 03 '17 at 12:08
  • @Mark Setchell, Aside from the fact that the answer I posted was already tested under macOS 10.12.6 (and OS X 10.8.5) and works as is (or I wouldn't have posted it as is), both `/sbin` and `/usr/sbin` are part of the default macOS `PATH` in a `bash` _shell_, which is `/usr/bin:/bin:/usr/sbin:/sbin:`, and therefore no need to use fully qualified pathnames for either `system_profiler` or `shutdown` in the `/usr/local/bin/snls` _script_. This is of course assuming default settings are in play and if one has modified their system not using macOS defaults then appropriate changes may be necessary. – user3439894 Oct 03 '17 at 12:46
  • Thanks so much! Booting into recovery mode doesn't seem to want to work on my macs, any idea why? If I ran into problems, would I be able to delete the script using another mac and accessing the computer via Target Disk Mode? Or Safe Mode? – dcmichael Oct 03 '17 at 15:31
  • @dcmichael, In regards to "... would I be able to delete the script using another mac and accessing the computer via Target Disk Mode? Or Safe Mode?"... In theory yes, however make sure you can before applying this workaround solution. – user3439894 Oct 03 '17 at 16:34
  • so, at first I was getting a floating point error (or what seemed to be a floating point error - invalid arithmetic operator (error token is ".5 1.5")) since SATA I speeds return as 1.5. So I included a regular expression just to return the first digit "1". and I get "syntax error in expression (error token is "1") – dcmichael Oct 03 '17 at 19:49
  • @dcmichael, In the `awk` portion of the _command_, try changing `{print $4}` to `{print int($4)}`. I hope you're testing just the `system_profiler SPSerialATADataType | awk '/Negotiated Link Speed:/{print $4}'` portion of the _command_ in Terminal first, to see what the normal _value_ is going to be before actually running the entire _script_!? And alway test again a whole number as it's the easiest way to do it. So adding the `int()` _function_ to the `awk` _command_ should do the trick. :) I've added it to the answer! – user3439894 Oct 03 '17 at 20:10
  • I applied your change, but it still wasn't working. I changed `-lt` to `<` and it worked flawlessly! Thanks again! – dcmichael Oct 03 '17 at 22:04
-1

This is not possible with only AppleScript, since it requires some terminal code execution. Therefore it is best to create a script that utilizes the terminal. Whether that's from an AppleScript or a bash script doesn't matter, although the quickest way would be a bash script.

An example command can be found here.