1321
1322
/////////////////////////////////////////////////////////////////////////////
1322
1323
// USB device type detection
1324
struct usb_id_entry {
1325
int vendor_id, product_id, version;
1329
const char d_sat[] = "sat";
1330
const char d_cypress[] = "usbcypress";
1331
const char d_jmicron[] = "usbjmicron";
1332
const char d_jmicron_x[] = "usbjmicron,x";
1333
const char d_sunplus[] = "usbsunplus";
1334
const char d_unsup[] = "unsupported";
1336
// Map USB IDs -> '-d type' string
1337
const usb_id_entry usb_ids[] = {
1339
{ 0x04b4, 0x6830, 0x0001, d_unsup }, // Cypress CY7C68300A (AT2)
1340
{ 0x04b4, 0x6830, 0x0240, d_cypress }, // Cypress CY7C68300B/C (AT2LP)
1341
//{ 0x04b4, 0x6831, -1, d_cypress }, // Cypress CY7C68310 (ISD-300LP)
1343
{ 0x04cf, 0x8818, 0xb007, d_unsup }, // Myson Century CS8818
1345
{ 0x04e8, 0x5f06, -1, d_sat }, // Samsung Story Station
1347
{ 0x04fc, 0x0c15, 0xf615, d_sunplus }, // SunPlus SPDIF215
1348
{ 0x04fc, 0x0c25, 0x0103, d_sunplus }, // SunPlus SPDIF225 (USB+SATA->SATA)
1350
{ 0x059b, 0x0272, -1, d_cypress }, // Iomega LPHD080-0
1351
{ 0x059b, 0x0275, 0x0001, d_unsup }, // Iomega MDHD500-U
1353
{ 0x059f, 0x0651, -1, d_unsup }, // LaCie hard disk (FA Porsche design)
1354
{ 0x059f, 0x1018, -1, d_sat }, // LaCie hard disk (Neil Poulton design)
1355
{ 0x059f, 0x1019, -1, d_jmicron }, // LaCie Desktop Hard Drive
1357
{ 0x05ab, 0x0060, 0x1101, d_cypress }, // In-System/Cypress ISD-300A1
1359
{ 0x05e3, 0x0702, -1, d_unsup }, // Genesys Logic GL881E
1360
{ 0x05e3, 0x0718, 0x0041, d_sat }, // Genesys Logic ? (TODO: requires '-T permissive')
1362
{ 0x067b, 0x2507, -1, d_unsup }, // Prolific PL2507 (USB->PATA)
1363
{ 0x067b, 0x3507, 0x0001, d_unsup }, // Prolific PL3507 (USB+IEE1394->PATA)
1365
{ 0x07ab, 0xfc8e, 0x010f, d_sunplus }, // Freecom Hard Drive XS
1367
{ 0x0930, 0x0b03, -1, d_sunplus }, // Toshiba PX1270E-1G16
1368
{ 0x0930, 0x0b09, -1, d_sunplus }, // Toshiba PX1396E-3T01 (similar to Dura Micro 501)
1370
{ 0x0bc2, 0x2000, -1, d_sat }, // Seagate FreeAgent Go
1371
{ 0x0bc2, 0x2100, -1, d_sat }, // Seagate FreeAgent Go
1372
{ 0x0bc2, 0x2101, -1, d_sat }, // Seagate FreeAgent Go
1373
{ 0x0bc2, 0x2200, -1, d_sat }, // Seagate FreeAgent Go FW
1374
{ 0x0bc2, 0x2300, -1, d_sat }, // Seagate Expansion Portable
1375
{ 0x0bc2, 0x3000, -1, d_sat }, // Seagate FreeAgent Desktop
1376
{ 0x0bc2, 0x3001, -1, d_sat }, // Seagate FreeAgent Desk
1378
{ 0x0c0b, 0xb159, 0x0103, d_sunplus }, // Dura Micro 509
1380
{ 0x0d49, 0x7310, 0x0125, d_sat }, // Maxtor OneTouch 4
1381
{ 0x0d49, 0x7350, 0x0125, d_sat }, // Maxtor OneTouch 4 Mini
1382
{ 0x0d49, 0x7410, 0x0122, d_sat }, // Maxtor Basics Desktop
1383
{ 0x0d49, 0x7450, 0x0122, d_sat }, // Maxtor Basics Portable
1385
{ 0x1058, 0x0701, 0x0240, d_cypress }, // WD My Passport (IDE)
1386
{ 0x1058, 0x0702, 0x0102, d_sat }, // WD My Passport Portable
1387
{ 0x1058, 0x0704, 0x0175, d_sat }, // WD My Passport Essential
1388
{ 0x1058, 0x0705, 0x0175, d_sat }, // WD My Passport Elite
1389
{ 0x1058, 0x070a, 0x1028, d_sat }, // WD My Passport 070A
1390
{ 0x1058, 0x0906, 0x0012, d_sat }, // WD My Book ES
1391
{ 0x1058, 0x1001, 0x0104, d_sat }, // WD Elements Desktop
1392
{ 0x1058, 0x1003, 0x0175, d_sat }, // WD Elements Desktop WDE1UBK...
1393
{ 0x1058, 0x1010, 0x0105, d_sat }, // WD Elements
1394
{ 0x1058, 0x1100, 0x0165, d_sat }, // WD My Book Essential
1395
{ 0x1058, 0x1102, 0x1028, d_sat }, // WD My Book
1396
{ 0x1058, 0x1110, 0x1030, d_sat }, // WD My Book Essential
1398
{ 0x13fd, 0x0540, -1, d_unsup }, // Initio 316000
1399
{ 0x13fd, 0x1240, 0x0104, d_sat }, // Initio ? (USB->SATA)
1400
{ 0x13fd, 0x1340, 0x0208, d_sat }, // Initio ? (USB+SATA->SATA)
1402
{ 0x152d, 0x2329, 0x0100, d_jmicron }, // JMicron JM20329 (USB->SATA)
1403
{ 0x152d, 0x2336, 0x0100, d_jmicron_x},// JMicron JM20336 (USB+SATA->SATA, USB->2xSATA)
1404
{ 0x152d, 0x2338, 0x0100, d_jmicron }, // JMicron JM20337/8 (USB->SATA+PATA, USB+SATA->PATA)
1405
{ 0x152d, 0x2339, 0x0100, d_jmicron_x},// JMicron JM20339 (USB->SATA)
1407
{ 0x18a5, 0x0215, 0x0001, d_sat }, // Verbatim FW/USB160 - Oxford OXUF934SSA-LQAG (USB+IEE1394->SATA)
1409
{ 0x1bcf, 0x0c31, -1, d_sunplus }, // SunplusIT
1411
{ 0x55aa, 0x2b00, 0x0100, d_unsup } // OnSpec ? (USB->PATA)
1414
const unsigned num_usb_ids = sizeof(usb_ids)/sizeof(usb_ids[0]);
1417
1325
// Format USB ID for error messages
1418
1326
static std::string format_usb_id(int vendor_id, int product_id, int version)
1427
1335
const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
1428
1336
int version /*= -1*/)
1430
const usb_id_entry * entry = 0;
1433
for (unsigned i = 0; i < num_usb_ids; i++) {
1434
const usb_id_entry & e = usb_ids[i];
1435
if (!(vendor_id == e.vendor_id && product_id == e.product_id))
1438
// If two entries with same vendor:product ID have different
1439
// types, use version (if provided by OS) to select entry.
1440
bool s = (version >= 0 && version == e.version);
1443
if (s == state && e.type != entry->type) {
1444
set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1445
format_usb_id(vendor_id, product_id, version).c_str(),
1446
e.type, entry->type);
1338
usb_dev_info info, info2;
1339
int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
1457
1342
set_err(EINVAL, "Unknown USB bridge %s",
1458
1343
format_usb_id(vendor_id, product_id, version).c_str());
1461
if (entry->type == d_unsup) {
1348
set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
1349
format_usb_id(vendor_id, product_id, version).c_str(),
1350
(!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
1351
(!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
1355
if (info.usb_type.empty()) {
1462
1356
set_err(ENOSYS, "Unsupported USB bridge %s",
1463
1357
format_usb_id(vendor_id, product_id, version).c_str());
1361
// TODO: change return type to std::string
1362
static std::string type;
1363
type = info.usb_type;
1364
return type.c_str();