diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG
index 82144f0b7cfc697897c66d0c6470f32433863721..e3e5154dece8eacf74f1060fa64663a7338e479f 100644
--- a/sm5/CHANGELOG
+++ b/sm5/CHANGELOG
@@ -1,6 +1,6 @@
 CHANGELOG for smartmontools
 
-$Id: CHANGELOG,v 1.786 2009/03/13 18:09:31 chrfranke Exp $
+$Id: CHANGELOG,v 1.787 2009/03/14 13:49:49 chrfranke Exp $
 
 The most recent version of this file is:
 http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
@@ -41,6 +41,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] Enhance USB device type autodetection, use bcdDevice if known.
+       Add Cypress CY7C68300B/C (AT2LP) to the table.
+
   [CF] Linux: Add experimental USB device type autodetection.
        Uses USB ID info found through symlink "/sys/block/sdX/device".
 
diff --git a/sm5/scsiata.cpp b/sm5/scsiata.cpp
index 02c441e6fee6875fb4572dce2b4e08123654ffe1..68319c5ccf4817e96a8d613c577ba57c3a4a682f 100644
--- a/sm5/scsiata.cpp
+++ b/sm5/scsiata.cpp
@@ -51,7 +51,7 @@
 #include "dev_ata_cmd_set.h" // ata_device_with_command_set
 #include "dev_tunnelled.h" // tunnelled_device<>
 
-const char *scsiata_c_cvsid="$Id: scsiata.cpp,v 1.25 2009/03/12 20:31:12 chrfranke Exp $"
+const char *scsiata_c_cvsid="$Id: scsiata.cpp,v 1.26 2009/03/14 13:49:49 chrfranke Exp $"
 CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID;
 
 /* for passing global control variables */
@@ -1145,12 +1145,13 @@ struct usb_id_entry {
 const char d_sat[]     = "sat";
 const char d_jmicron[] = "usbjmicron";
 const char d_cypress[] = "usbcypress";
-const int  d_unsup = 0;
+const char d_unsup[]   = "unsupported";
 
 // Map USB IDs -> '-d type' string
 const usb_id_entry usb_ids[] = {
-  { 0x04b4, 0x6830, 0x0001, d_unsup   }, // Cypress CY7C68300A
-//{ 0x04b4,     -1,     -1, d_cypress }, // Cypress CY7C68300B/C ?
+  { 0x04b4, 0x6830, 0x0001, d_unsup   }, // Cypress CY7C68300A (AT2)
+  { 0x04b4, 0x6830, 0x0240, d_cypress }, // Cypress CY7C68300B/C (AT2LP)
+//{ 0x04b4, 0x6831,     -1, d_cypress }, // Cypress CY7C68310 (ISD-300LP)
   { 0x0c0b, 0xb159, 0x0103, d_unsup   }, // Dura Micro ?
   { 0x0d49, 0x7310, 0x0125, d_sat     }, // Maxtor OneTouch 4
 //{ 0x0d49,     -1,     -1, d_sat     }, // Maxtor Basics Desktop
@@ -1165,22 +1166,55 @@ const usb_id_entry usb_ids[] = {
 const unsigned num_usb_ids = sizeof(usb_ids)/sizeof(usb_ids[0]);
 
 
+// Format USB ID for error messages
+static std::string format_usb_id(int vendor_id, int product_id, int version)
+{
+  if (version >= 0)
+    return strprintf("[0x%04x:0x%04x (0x%03x)]", vendor_id, product_id, version);
+  else
+    return strprintf("[0x%04x:0x%04x]", vendor_id, product_id);
+}
+
 // Get type name for USB device with known VENDOR:PRODUCT ID.
 // Version not checked yet.
 const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
-                                                     int /*version = -1*/)
+                                                     int version /*= -1*/)
 {
+  const usb_id_entry * entry = 0;
+  bool state = false;
+
   for (unsigned i = 0; i < num_usb_ids; i++) {
     const usb_id_entry & e = usb_ids[i];
-    if (vendor_id == e.vendor_id && product_id == e.product_id) {
-      if (e.type == d_unsup) {
-        set_err(ENOSYS, "Unsupported USB bridge (0x%04x:0x%04x)", vendor_id, product_id);
-        return 0;
+    if (!(vendor_id == e.vendor_id && product_id == e.product_id))
+      continue;
+
+    // If two entries with same vendor:product ID have different
+    // types, use version (if provided by OS) to select entry.
+    bool s = (version >= 0 && version == e.version);
+    if (entry) {
+      if (s <= state) {
+        if (s == state && e.type != entry->type) {
+          set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
+                  format_usb_id(vendor_id, product_id, version).c_str(),
+                  e.type, entry->type);
+          return 0;
+        }
+        continue;
       }
-      return e.type;
     }
+    state = s;
+    entry = &e;
   }
 
-  set_err(EINVAL, "Unknown USB bridge (0x%04x:0x%04x)", vendor_id, product_id);
-  return 0;
+  if (!entry) {
+    set_err(EINVAL, "Unknown USB bridge %s",
+            format_usb_id(vendor_id, product_id, version).c_str());
+    return 0;
+  }
+  if (entry->type == d_unsup) {
+    set_err(ENOSYS, "Unsupported USB bridge %s",
+            format_usb_id(vendor_id, product_id, version).c_str());
+    return 0;
+  }
+  return entry->type;
 }