diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index eafcdba3f43e533c31822394c64583b147253915..2a89f82ea3d4315ac2452268855d547328e684cc 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.771 2009/02/09 21:48:52 chrfranke Exp $ +$Id: CHANGELOG,v 1.772 2009/02/11 21:36:00 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] Windows: Add a workaround for missing multi-sector support + for ATA READ LOG EXT command. + [CF] Fix Extended Comprehensive Error Log index base. Add workaround for Samsung disks using reserved byte as index. diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index 28cad395a09ffa79f8ffe781560b451fe341e032..9403d336c021b0074d8f7bf1005408d09f7e2644 100644 --- a/sm5/atacmds.cpp +++ b/sm5/atacmds.cpp @@ -3,7 +3,7 @@ * * Home page of code is: http://smartmontools.sourceforge.net * - * Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> + * Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * @@ -39,7 +39,7 @@ #include <algorithm> // std::sort -const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.211 2009/02/06 22:33:05 chrfranke Exp $" +const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.212 2009/02/11 21:36:00 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID; // for passing global control variables @@ -1062,10 +1062,22 @@ bool ataReadLogExt(ata_device * device, unsigned char logaddr, in.in_regs.lba_mid_16 = page; if (!device->ata_pass_through(in)) { // TODO: Debug output - pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n", - logaddr, features, page, nsectors, device->get_errmsg()); - return false; + if (nsectors <= 1) { + pout("ATA_READ_LOG_EXT (addr=0x%02x:0x%02x, page=%u, n=%u) failed: %s\n", + logaddr, features, page, nsectors, device->get_errmsg()); + return false; + } + + // Recurse to retry with single sectors, + // multi-sector reads may not be supported by ioctl. + for (unsigned i = 0; i < nsectors; i++) { + if (!ataReadLogExt(device, logaddr, + features, page + i, + (char *)data + 512*i, 1)) + return false; + } } + return true; } @@ -1385,14 +1397,8 @@ int ataReadErrorLog (ata_device * device, struct ata_smart_errorlog *data){ bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log, unsigned nsectors) { - if (!ataReadLogExt(device, 0x03, 0x00, 0, log, nsectors)) { - // Retry with single sectors, some disks (Samsung HD301LJ), - // don't support multi sector reads of this log. - for (unsigned i = 0; i < nsectors; i++) { - if (!ataReadLogExt(device, 0x03, 0x00, i, log+i, 1)) - return false; - } - } + if (!ataReadLogExt(device, 0x03, 0x00, 0, log, nsectors)) + return false; for (unsigned i = 0; i < nsectors; i++) { if (checksum((const unsigned char *)(log + 1))) diff --git a/sm5/os_win32.cpp b/sm5/os_win32.cpp index 2c2ed93f6e7d5cfa3e5de87879687a46dc9453a3..ab514660134689ced48fe5c14ec5d5d8d2a9b28b 100644 --- a/sm5/os_win32.cpp +++ b/sm5/os_win32.cpp @@ -3,7 +3,7 @@ * * Home page of code is: http://smartmontools.sourceforge.net * - * Copyright (C) 2004-8 Christian Franke <smartmontools-support@lists.sourceforge.net> + * Copyright (C) 2004-9 Christian Franke <smartmontools-support@lists.sourceforge.net> * * 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 @@ -48,7 +48,7 @@ extern smartmonctrl * con; // con->permissive,reportataioctl // Needed by '-V' option (CVS versioning) of smartd/smartctl -const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.70 2009/01/25 18:43:01 chrfranke Exp $" +const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.71 2009/02/11 21:36:00 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; @@ -903,10 +903,21 @@ ASSERT_SIZEOF(ATA_PASS_THROUGH_EX, 40); #define ATA_FLAGS_DATA_IN 0x02 #define ATA_FLAGS_DATA_OUT 0x04 #define ATA_FLAGS_48BIT_COMMAND 0x08 +#define ATA_FLAGS_USE_DMA 0x10 +#define ATA_FLAGS_NO_MULTIPLE 0x20 // Vista ///////////////////////////////////////////////////////////////////////////// +// Warning: +// IOCTL_ATA_PASS_THROUGH[_DIRECT] can only handle one interrupt/DRQ data +// transfer per command. Therefore, multi-sector transfers are only supported +// for the READ/WRITE MULTIPLE [EXT] commands. Other commands like READ/WRITE SECTORS +// or READ/WRITE LOG EXT work only with single sector transfers. +// The latter are supported on Vista (only) through new ATA_FLAGS_NO_MULTIPLE. +// See: +// http://social.msdn.microsoft.com/Forums/en-US/storageplatformata/thread/eb408507-f221-455b-9bbb-d1069b29c4da + static int ata_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, IDEREGS * prev_regs, char * data, int datasize) { const int max_sectors = 32; // TODO: Allocate dynamic buffer @@ -976,7 +987,7 @@ static int ata_pass_through_ioctl(HANDLE hdevice, IDEREGS * regs, IDEREGS * prev } // Check ATA status - if (ctfregs->bCommandReg/*Status*/ & 0x01) { + if (ctfregs->bCommandReg/*Status*/ & (0x01/*Err*/|0x08/*DRQ*/)) { if (con->reportataioctl) { pout(" IOCTL_ATA_PASS_THROUGH command failed:\n"); print_ide_regs_io(regs, ctfregs); @@ -2324,9 +2335,11 @@ bool winnt_smart_interface::ata_scan(smart_device_list & devlist) // Interface to ATA devices bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) { + // No multi-sector support for now, see above + // warning about IOCTL_ATA_PASS_THROUGH if (!ata_cmd_is_ok(in, true, // data_out_support - true, // multi_sector_support + false, // !multi_sector_support true) // ata_48bit_support ) return false;