mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 10:07:38 -04:00
There are numerous sub-commands, this makes it possible to call the others. Also in this patch is the ability for the "default" ATA driver to query smart data too Change-Id: Ie3aaf9e0b2d7a5d25d09dea34e4f10ee29047e1b
244 lines
8.1 KiB
C
244 lines
8.1 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2002 by Alan Korr
|
|
*
|
|
* 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 the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#ifndef __ATA_H__
|
|
#define __ATA_H__
|
|
|
|
#include <stdbool.h>
|
|
#include "config.h" /* for HAVE_MULTIVOLUME or not */
|
|
#include "mv.h" /* for IF_MV() and friends */
|
|
|
|
#ifdef HAVE_ATA_SMART
|
|
/* S.M.A.R.T. headers from smartmontools-5.42 */
|
|
#define NUMBER_ATA_SMART_ATTRIBUTES 30
|
|
|
|
struct ata_smart_attribute {
|
|
unsigned char id;
|
|
/* meaning of flag bits: see MACROS just below */
|
|
/* WARNING: MISALIGNED! */
|
|
unsigned short flags;
|
|
unsigned char current;
|
|
unsigned char worst;
|
|
unsigned char raw[6];
|
|
unsigned char reserv;
|
|
} __attribute__((packed));
|
|
|
|
/* MACROS to interpret the flags bits in the previous structure. */
|
|
/* These have not been implemented using bitflags and a union, to make */
|
|
/* it portable across bit/little endian and different platforms. */
|
|
|
|
/* 0: Prefailure bit */
|
|
|
|
/* From SFF 8035i Revision 2 page 19: Bit 0 (pre-failure/advisory bit) */
|
|
/* - If the value of this bit equals zero, an attribute value less */
|
|
/* than or equal to its corresponding attribute threshold indicates an */
|
|
/* advisory condition where the usage or age of the device has */
|
|
/* exceeded its intended design life period. If the value of this bit */
|
|
/* equals one, an attribute value less than or equal to its */
|
|
/* corresponding attribute threshold indicates a prefailure condition */
|
|
/* where imminent loss of data is being predicted. */
|
|
#define ATTRIBUTE_FLAGS_PREFAILURE(x) (x & 0x01)
|
|
|
|
/* 1: Online bit */
|
|
|
|
/* From SFF 8035i Revision 2 page 19: Bit 1 (on-line data collection */
|
|
/* bit) - If the value of this bit equals zero, then the attribute */
|
|
/* value is updated only during off-line data collection */
|
|
/* activities. If the value of this bit equals one, then the attribute */
|
|
/* value is updated during normal operation of the device or during */
|
|
/* both normal operation and off-line testing. */
|
|
#define ATTRIBUTE_FLAGS_ONLINE(x) (x & 0x02)
|
|
|
|
/* The following are (probably) IBM's, Maxtors and Quantum's definitions for the */
|
|
/* vendor-specific bits: */
|
|
/* 2: Performance type bit */
|
|
#define ATTRIBUTE_FLAGS_PERFORMANCE(x) (x & 0x04)
|
|
|
|
/* 3: Errorrate type bit */
|
|
#define ATTRIBUTE_FLAGS_ERRORRATE(x) (x & 0x08)
|
|
|
|
/* 4: Eventcount bit */
|
|
#define ATTRIBUTE_FLAGS_EVENTCOUNT(x) (x & 0x10)
|
|
|
|
/* 5: Selfpereserving bit */
|
|
#define ATTRIBUTE_FLAGS_SELFPRESERVING(x) (x & 0x20)
|
|
|
|
/* 6-15: Reserved for future use */
|
|
#define ATTRIBUTE_FLAGS_OTHER(x) ((x) & 0xffc0)
|
|
|
|
#define ATA_SMART_READ_DATA 0xD0
|
|
|
|
struct ata_smart_values
|
|
{
|
|
unsigned short int revnumber;
|
|
struct ata_smart_attribute vendor_attributes [NUMBER_ATA_SMART_ATTRIBUTES];
|
|
unsigned char offline_data_collection_status;
|
|
unsigned char self_test_exec_status;
|
|
unsigned short int total_time_to_complete_off_line;
|
|
unsigned char vendor_specific_366;
|
|
unsigned char offline_data_collection_capability;
|
|
unsigned short int smart_capability;
|
|
unsigned char errorlog_capability;
|
|
unsigned char vendor_specific_371;
|
|
unsigned char short_test_completion_time;
|
|
unsigned char extend_test_completion_time;
|
|
unsigned char conveyance_test_completion_time;
|
|
unsigned char reserved_375_385[11];
|
|
unsigned char vendor_specific_386_510[125];
|
|
unsigned char chksum;
|
|
} __attribute__((packed)) __attribute__((aligned(2)));
|
|
|
|
/* Raw attribute value print formats */
|
|
enum ata_attr_raw_format
|
|
{
|
|
RAWFMT_DEFAULT,
|
|
RAWFMT_RAW8,
|
|
RAWFMT_RAW16,
|
|
RAWFMT_RAW48,
|
|
RAWFMT_HEX48,
|
|
RAWFMT_RAW64,
|
|
RAWFMT_HEX64,
|
|
RAWFMT_RAW16_OPT_RAW16,
|
|
RAWFMT_RAW16_OPT_AVG16,
|
|
RAWFMT_RAW24_DIV_RAW24,
|
|
RAWFMT_RAW24_DIV_RAW32,
|
|
RAWFMT_SEC2HOUR,
|
|
RAWFMT_MIN2HOUR,
|
|
RAWFMT_HALFMIN2HOUR,
|
|
RAWFMT_MSEC24_HOUR32,
|
|
RAWFMT_TEMPMINMAX,
|
|
RAWFMT_TEMP10X,
|
|
};
|
|
#endif /* HAVE_ATA_SMART */
|
|
|
|
struct storage_info;
|
|
|
|
void ata_enable(bool on);
|
|
void ata_spindown(int seconds);
|
|
void ata_sleep(void);
|
|
void ata_sleepnow(void);
|
|
/* NOTE: DO NOT use this to poll for disk activity.
|
|
If you are waiting for the disk to become active before
|
|
doing something use ata_idle_notify.h
|
|
*/
|
|
bool ata_disk_is_active(void);
|
|
int ata_soft_reset(void);
|
|
int ata_init(void) STORAGE_INIT_ATTR;
|
|
void ata_close(void);
|
|
int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
|
|
int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
|
|
void ata_spin(void);
|
|
#if (CONFIG_LED == LED_REAL)
|
|
void ata_set_led_enabled(bool enabled);
|
|
#endif
|
|
unsigned short* ata_get_identify(void);
|
|
|
|
#ifdef STORAGE_GET_INFO
|
|
void ata_get_info(IF_MD(int drive,) struct storage_info *info);
|
|
#endif
|
|
#ifdef HAVE_HOTSWAP
|
|
bool ata_removable(IF_MD_NONVOID(int drive));
|
|
bool ata_present(IF_MD_NONVOID(int drive));
|
|
#endif
|
|
|
|
|
|
#ifdef CONFIG_STORAGE_MULTI
|
|
int ata_num_drives(int first_drive);
|
|
#endif
|
|
|
|
|
|
long ata_last_disk_activity(void);
|
|
int ata_spinup_time(void); /* ticks */
|
|
|
|
/* Returns 1 if drive is solid-state */
|
|
static inline int ata_disk_isssd(void)
|
|
{
|
|
unsigned short *identify_info = ata_get_identify();
|
|
/*
|
|
Offset 217 is "Nominal Rotation rate"
|
|
0x0000 == Not reported
|
|
0x0001 == Solid State
|
|
0x0401 -> 0xffe == RPM
|
|
All others reserved
|
|
|
|
However, this is a relatively recent change, and we can't rely on it,
|
|
especially for the FC1307A CF->SD adapters!
|
|
|
|
Offset 168 is "Nominal Form Factor"
|
|
all values >= 0x06 are guaranteed to be Solid State (mSATA, m.2, etc)
|
|
|
|
Offset 169 b0 is set to show device implements TRIM.
|
|
|
|
Unreliable mechanisms:
|
|
|
|
Offset 83 b2 shows device implements CFA commands.
|
|
However microdrives pose a problem as they support CFA but are not
|
|
SSD.
|
|
|
|
Offset 163 shows CF Advanced timing modes; microdrives all seems to
|
|
report 0, but all others (including iFlash) report higher! This
|
|
is often present even when the "CFA supported" bit is 0.
|
|
|
|
Offset 160 b15 indicates support for CF+ power level 1, if not set
|
|
then device is standard flash CF. However this is not foolproof
|
|
as newer CF cards (and those CF->SD adapters) may report this.
|
|
|
|
*/
|
|
return ( (identify_info[217] == 0x0001) /* "Solid state" rotational rate */
|
|
|| ((identify_info[168] & 0x0f) >= 0x06) /* Explicit SSD form factors */
|
|
|| (identify_info[169] & (1<<0)) /* TRIM supported */
|
|
|| (identify_info[163] > 0) /* CF Advanced timing modes */
|
|
|| ((identify_info[83] & (1<<2)) && /* CFA compliant */
|
|
((identify_info[160] & (1<<15)) == 0)) /* CF power level 0 */
|
|
);
|
|
}
|
|
|
|
/* Returns 1 if the drive supports power management commands */
|
|
static inline int ata_disk_can_sleep(void)
|
|
{
|
|
unsigned short *identify_info = ata_get_identify();
|
|
/* Only devices that claim to support PM can be safely powered off.
|
|
This notably excludes the various SD adapters! */
|
|
return (identify_info[82] & (1<<3) && identify_info[85] & (1<<3));
|
|
}
|
|
|
|
int ata_flush(void);
|
|
|
|
#ifdef HAVE_ATA_DMA
|
|
/* Returns current DMA mode */
|
|
int ata_get_dma_mode(void);
|
|
#endif /* HAVE_ATA_DMA */
|
|
|
|
#ifdef HAVE_ATA_SMART
|
|
/* Returns current S.M.A.R.T. data */
|
|
int ata_read_smart(struct ata_smart_values*, uint8_t cmd);
|
|
#endif
|
|
|
|
#ifdef BOOTLOADER
|
|
#define STORAGE_CLOSE
|
|
#endif
|
|
|
|
#define ATA_IDENTIFY_WORDS 256
|
|
|
|
#ifdef MAX_PHYS_SECTOR_SIZE
|
|
void ata_set_phys_sector_mult(unsigned int mult);
|
|
#endif
|
|
|
|
#endif /* __ATA_H__ */
|