version 1.1.1.1, 2012/02/21 16:32:16
|
version 1.1.1.2, 2012/10/09 09:36:45
|
Line 3
|
Line 3
|
* |
* |
* Home page of code is: http://smartmontools.sourceforge.net |
* Home page of code is: http://smartmontools.sourceforge.net |
* |
* |
* Copyright (C) 2006-10 Douglas Gilbert <dgilbert@interlog.com> | * Copyright (C) 2006-12 Douglas Gilbert <dgilbert@interlog.com> |
* Copyright (C) 2009-10 Christian Franke <smartmontools-support@lists.sourceforge.net> | * Copyright (C) 2009-12 Christian Franke <smartmontools-support@lists.sourceforge.net> |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
Line 114 class sat_device
|
Line 114 class sat_device
|
: public tunnelled_device< |
: public tunnelled_device< |
/*implements*/ ata_device |
/*implements*/ ata_device |
/*by tunnelling through a*/, scsi_device |
/*by tunnelling through a*/, scsi_device |
> | >, |
| virtual public /*implements*/ scsi_device |
{ |
{ |
public: |
public: |
sat_device(smart_interface * intf, scsi_device * scsidev, |
sat_device(smart_interface * intf, scsi_device * scsidev, |
const char * req_type, int passthrulen = 0); | const char * req_type, int passthrulen = 0, bool enable_auto = false); |
|
|
virtual ~sat_device() throw(); |
virtual ~sat_device() throw(); |
|
|
|
virtual smart_device * autodetect_open(); |
|
|
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); |
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out); |
|
|
|
virtual bool scsi_pass_through(scsi_cmnd_io * iop); |
|
|
private: |
private: |
int m_passthrulen; |
int m_passthrulen; |
|
bool m_enable_auto; |
}; |
}; |
|
|
|
|
sat_device::sat_device(smart_interface * intf, scsi_device * scsidev, |
sat_device::sat_device(smart_interface * intf, scsi_device * scsidev, |
const char * req_type, int passthrulen /*= 0*/) | const char * req_type, int passthrulen /* = 0 */, bool enable_auto /* = false */) |
: smart_device(intf, scsidev->get_dev_name(), "sat", req_type), | : smart_device(intf, scsidev->get_dev_name(), |
| (enable_auto ? "sat,auto" : "sat"), req_type), |
tunnelled_device<ata_device, scsi_device>(scsidev), |
tunnelled_device<ata_device, scsi_device>(scsidev), |
m_passthrulen(passthrulen) | m_passthrulen(passthrulen), |
| m_enable_auto(enable_auto) |
{ |
{ |
set_info().info_name = strprintf("%s [SAT]", scsidev->get_info_name()); | if (enable_auto) |
| hide_ata(); // Start as SCSI, switch to ATA in autodetect_open() |
| else |
| hide_scsi(); // ATA always |
| |
| set_info().info_name = strprintf("%s [%sSAT]", scsidev->get_info_name(), |
| (enable_auto ? "SCSI/" : "")); |
} |
} |
|
|
sat_device::~sat_device() throw() |
sat_device::~sat_device() throw() |
Line 421 bool sat_device::ata_pass_through(const ata_cmd_in & i
|
Line 435 bool sat_device::ata_pass_through(const ata_cmd_in & i
|
return true; |
return true; |
} |
} |
|
|
|
bool sat_device::scsi_pass_through(scsi_cmnd_io * iop) |
|
{ |
|
scsi_device * scsidev = get_tunnel_dev(); |
|
if (!scsidev->scsi_pass_through(iop)) { |
|
set_err(scsidev->get_err()); |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
smart_device * sat_device::autodetect_open() |
|
{ |
|
if (!open() || !m_enable_auto) |
|
return this; |
|
|
|
scsi_device * scsidev = get_tunnel_dev(); |
|
|
|
unsigned char inqdata[36] = {0, }; |
|
if (scsiStdInquiry(scsidev, inqdata, sizeof(inqdata))) { |
|
smart_device::error_info err = scsidev->get_err(); |
|
close(); |
|
set_err(err.no, "INQUIRY [SAT]: %s", err.msg.c_str()); |
|
return this; |
|
} |
|
|
|
// Check for SAT "VENDOR" |
|
int inqsize = inqdata[4] + 5; |
|
bool sat = (inqsize >= 36 && !memcmp(inqdata + 8, "ATA ", 8)); |
|
|
|
// Change interface |
|
hide_ata(!sat); |
|
hide_scsi(sat); |
|
|
|
set_info().dev_type = (sat ? "sat" : scsidev->get_dev_type()); |
|
set_info().info_name = strprintf("%s [%s]", scsidev->get_info_name(), |
|
(sat ? "SAT" : "SCSI")); |
|
return this; |
|
} |
|
|
} // namespace |
} // namespace |
|
|
///////////////////////////////////////////////////////////////////////////// |
///////////////////////////////////////////////////////////////////////////// |
Line 1244 using namespace sat;
|
Line 1297 using namespace sat;
|
ata_device * smart_interface::get_sat_device(const char * type, scsi_device * scsidev) |
ata_device * smart_interface::get_sat_device(const char * type, scsi_device * scsidev) |
{ |
{ |
if (!strncmp(type, "sat", 3)) { |
if (!strncmp(type, "sat", 3)) { |
int ptlen = 0, n1 = -1, n2 = -1; | const char * t = type + 3; |
if (!(((sscanf(type, "sat%n,%d%n", &n1, &ptlen, &n2) == 1 && n2 == (int)strlen(type)) || n1 == (int)strlen(type)) | bool enable_auto = false; |
&& (ptlen == 0 || ptlen == 12 || ptlen == 16))) { | if (!strncmp(t, ",auto", 5)) { |
set_err(EINVAL, "Option '-d sat,<n>' requires <n> to be 0, 12 or 16"); | t += 5; |
| enable_auto = true; |
| } |
| int ptlen = 0, n = -1; |
| if (*t && !(sscanf(t, ",%d%n", &ptlen, &n) == 1 && n == (int)strlen(t) |
| && (ptlen == 0 || ptlen == 12 || ptlen == 16))) { |
| set_err(EINVAL, "Option '-d sat[,auto][,N]' requires N to be 0, 12 or 16"); |
return 0; |
return 0; |
} |
} |
return new sat_device(this, scsidev, type, ptlen); | return new sat_device(this, scsidev, type, ptlen, enable_auto); |
} |
} |
|
|
else if (!strncmp(type, "usbcypress", 10)) { |
else if (!strncmp(type, "usbcypress", 10)) { |