diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG
index ee4dfed4a12082913970c739272fe3530d8f35fa..8bdd5c7496f40bf95d30394b1acdbbee6b1c47fd 100644
--- a/smartmontools/CHANGELOG
+++ b/smartmontools/CHANGELOG
@@ -43,6 +43,10 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [AS] Use malloc() to ensure that the read buffer lands on a single
+       page.  This avoids some bugs seen on LSI controlers under
+       FreeBSD.
+
   [CF] Add missing help text for '-d usb*' options.
 
   [CF] Linux: Dereference '/dev/disk/by-*/*' symlink before device type
diff --git a/smartmontools/scsiata.cpp b/smartmontools/scsiata.cpp
index 0b61c93e7ab551f8916cc61d9b3be9a6e8b823a7..ee0676512a9367f4a0dd487dd8ec0f37bf247c83 100644
--- a/smartmontools/scsiata.cpp
+++ b/smartmontools/scsiata.cpp
@@ -48,6 +48,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 #include <ctype.h>
 
 #include "config.h"
@@ -432,11 +433,16 @@ bool sat_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
 
 static bool has_sat_pass_through(ata_device * dev, bool packet_interface = false)
 {
+    /* Note:  malloc() ensures the read buffer lands on a single
+       page.  This avoids some bugs seen on LSI controlers under
+       FreeBSD */
+    char *data = (char *)malloc(512);
     ata_cmd_in in;
     in.in_regs.command = (packet_interface ? ATA_IDENTIFY_PACKET_DEVICE : ATA_IDENTIFY_DEVICE);
-    char data[512];
     in.set_data_in(data, 1);
-    return dev->ata_pass_through(in);
+    bool ret = dev->ata_pass_through(in);
+    free(data);
+    return ret;
 }
 
 /////////////////////////////////////////////////////////////////////////////