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; }