aboutsummaryrefslogtreecommitdiff
path: root/sys/cam
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2011-05-31 09:22:52 +0000
committerAlexander Motin <mav@FreeBSD.org>2011-05-31 09:22:52 +0000
commitd3a460d36cfad2ab7e6f779bbaf710d6ba607c4f (patch)
tree007b2735f5992d35de0fd591e715eabea9f1dc17 /sys/cam
parent6b436e625295276132a7e08a95eb5dafcde82a62 (diff)
downloadsrc-d3a460d36cfad2ab7e6f779bbaf710d6ba607c4f.tar.gz
src-d3a460d36cfad2ab7e6f779bbaf710d6ba607c4f.zip
Add quirks to hint 4K physical sector (Advanced Format) for ATA disks not
reporting it properly (none? of known disks now). Hitachi and WDC AF disks seem could be identified more or less formally. For Seagate and Samsung enumerate some found models/series. For other disks it can be forced with kern.cam.ada.X.quirks=1 tunable.
Notes
Notes: svn path=/head/; revision=222520
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_da.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 128bb8bcdd4a..7418e1e9a228 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -89,7 +89,8 @@ typedef enum {
} ada_flags;
typedef enum {
- ADA_Q_NONE = 0x00
+ ADA_Q_NONE = 0x00,
+ ADA_Q_4K = 0x01,
} ada_quirks;
typedef enum {
@@ -154,6 +155,86 @@ struct ada_quirk_entry {
static struct ada_quirk_entry ada_quirk_table[] =
{
{
+ /* Hitachi Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "Hitachi H??????????E3*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Samsung Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD204UI*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Barracuda Green Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DL*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Momentus Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500423AS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Momentus Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500424AS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Momentus Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750420AS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Momentus Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750422AS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* Seagate Momentus Thin Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???LT*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Caviar Green Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Caviar Green Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RX*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Caviar Green Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RS*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Caviar Green Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RX*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Scorpio Black Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PKT*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Scorpio Black Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PKT*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Scorpio Blue Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PVT*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
+ /* WDC Scorpio Blue Advanced Format (4k) drives */
+ { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PVT*", "*" },
+ /*quirks*/ADA_Q_4K
+ },
+ {
/* Default */
{
T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
@@ -740,7 +821,7 @@ adaregister(struct cam_periph *periph, void *arg)
struct disk_params *dp;
caddr_t match;
u_int maxio;
- int legacy_id;
+ int legacy_id, quirks;
cgd = (struct ccb_getdev *)arg;
if (periph == NULL) {
@@ -815,6 +896,11 @@ adaregister(struct cam_periph *periph, void *arg)
*/
(void)cam_periph_hold(periph, PRIBIO);
mtx_unlock(periph->sim->mtx);
+ snprintf(announce_buf, sizeof(announce_buf),
+ "kern.cam.ada.%d.quirks", periph->unit_number);
+ quirks = softc->quirks;
+ TUNABLE_INT_FETCH(announce_buf, &quirks);
+ softc->quirks = quirks;
softc->write_cache = -1;
snprintf(announce_buf, sizeof(announce_buf),
"kern.cam.ada.%d.write_cache", periph->unit_number);
@@ -870,6 +956,9 @@ adaregister(struct cam_periph *periph, void *arg)
softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
ata_logical_sector_offset(&cgd->ident_data)) %
softc->disk->d_stripesize;
+ } else if (softc->quirks & ADA_Q_4K) {
+ softc->disk->d_stripesize = 4096;
+ softc->disk->d_stripeoffset = 0;
}
softc->disk->d_fwsectors = softc->params.secs_per_track;
softc->disk->d_fwheads = softc->params.heads;