Date: Wed, 5 Mar 2014 04:15:16 GMT From: Ravi Pokala <rpokala@panasas.com> To: freebsd-gnats-submit@FreeBSD.org Subject: misc/187269: AF-4Kn SATA drives have mis-interpreted sector sizes Message-ID: <201403050415.s254FGpu056393@cgiserv.freebsd.org> Resent-Message-ID: <201403050420.s254K0Q1021037@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 187269 >Category: misc >Synopsis: AF-4Kn SATA drives have mis-interpreted sector sizes >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Mar 05 04:20:00 UTC 2014 >Closed-Date: >Last-Modified: >Originator: Ravi Pokala >Release: 10-STABLE r262757 >Organization: Panasas, Inc. >Environment: FreeBSD mau-kennedy-1a 10.0-STABLE FreeBSD 10.0-STABLE #0 r262757M: Tue Mar 4 17:24:53 PST 2014 root@mau-kennedy-1a:/usr/obj/usr/src/sys/GENERIC amd64 >Description: AF-4Kn SATA drives (4KB logical sector size, 4KB physical sector size) are being identified as having 2KB logical sectors and 512-byte physical sectors. This leads to data access timing out, the GPT being unreadable, and general uselessness. The drive that I was using when I discovered this problem is an engineering sample under NDA, so I have obscured the model/firmware/serial/WWN; sorry about that. The label states that the capacity is 5.0TB and that there are 1220942646 LBAs. /var/run/dmesg.boot (comments indented): ---------------------------------------------------------------- ada0 at ahcich0 bus 0 scbus0 target 0 lun 0 ada0: <DRIVE-MODEL DRIVE-FW> ATA-9 SATA 3.x device ada0: Serial Number DRIVE-SERIAL-NUMBER ada0: 600.000MB/s transfers (SATA 3.x, UDMA6, PIO 4096bytes) ada0: Command Queueing enabled ada0: 2384653MB (1220942646 2048 byte sectors: 16H 63S/T 16383C) Incorrect capacity Correct number of logical sectors, but incorrect sector size ada0: Previously was known as ad4 (ada0:ahcich0:0:0:0): READ_DMA48. ACB: 25 00 f7 1a c6 40 48 00 00 00 04 00 (ada0:ahcich0:0:0:0): CAM status: CCB request was invalid (ada0:ahcich0:0:0:0): Error 22, Unretryable error (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 01 34 1b c6 40 48 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: CCB request was invalid (ada0:ahcich0:0:0:0): Error 22, Unretryable error (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 01 34 1b c6 40 48 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: CCB request was invalid (ada0:ahcich0:0:0:0): Error 22, Unretryable error GEOM: ada0: corrupt or invalid GPT detected. GEOM: ada0: GPT rejected -- may not be recoverable. (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 20 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 20 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 04 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 04 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 00 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 00 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 80 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 80 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 20 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 20 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 04 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 04 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 00 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 00 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 80 00 00 40 00 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 80 00 00 00 00 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 04 f7 1a c6 40 48 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: ATA Status Error (ada0:ahcich0:0:0:0): ATA status: 41 (DRDY ERR), error: 84 (ICRC ABRT ) (ada0:ahcich0:0:0:0): RES: 41 84 f7 1a c6 00 48 00 00 00 00 5 attempts (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 01 34 1b c6 40 48 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: CCB request was invalid (ada0:ahcich0:0:0:0): Error 22, Unretryable error (ada0:ahcich0:0:0:0): READ_FPDMA_QUEUED. ACB: 60 01 34 1b c6 40 48 00 00 00 00 00 (ada0:ahcich0:0:0:0): CAM status: CCB request was invalid (ada0:ahcich0:0:0:0): Error 22, Unretryable error ---------------------------------------------------------------- `camcontrol identify ada0' (comments indented): ---------------------------------------------------------------- pass0: <DRIVE-MODEL DRIVE-FW> ATA-9 SATA 3.x device pass0: 600.000MB/s transfers (SATA 3.x, UDMA6, PIO 4096bytes) protocol ATA/ATAPI-9 SATA 3.x device model DRIVE-MODEL firmware revision DRIVE-FW serial number DRIVE-SERIAL-NUMBER WWN DRIVE-WWN cylinders 16383 heads 16 sectors/track 63 sector size logical 2048, physical 512, offset 0 Incorrect sector sizes LBA supported 268435455 sectors LBA48 supported 1220942646 sectors PIO supported PIO4 DMA supported WDMA2 UDMA6 media RPM 7200 Feature Support Enabled Value Vendor read ahead yes yes write cache yes yes flush cache yes yes overlap no Tagged Command Queuing (TCQ) no no Native Command Queuing (NCQ) yes 32 tags SMART yes yes microcode download yes yes security yes no power management yes yes advanced power management yes yes 128/0x80 automatic acoustic management no no media status notification no no power-up in Standby yes no write-read-verify no no unload no no free-fall no no Data Set Management (DSM/TRIM) no Host Protected Area (HPA) no ---------------------------------------------------------------- I looked at the code, and discovered two issues: (1) sys/cam/ata/ata_all.c::ata_logical_sector_size() The function returns the LSS in bytes. If IDENTIFY_DEVICE word 'pss' indicates that the LSS is larger than 512 bytes, it concatenates words 'lss_1' and 'lss_2' into a 'u_int32_t' and returns it. However, the ATA specs define that value as the number of *words* in a logical sector, not the number of bytes. Thus, it returns 2048 instead of 4096 as the LSS. ---------------------------------------------------------------- (2) sys/cam/ata/ata_all.c::ata_physical_sector_size() The function returns the PSS in bytes. If IDENTIFY_DEVICE word 'pss' indicates that there are multiple logical sectors per physical sector, it extracts the scaling factor, multiplies it by the LSS, and returns the result; otherwise, it returns a PSS of 512 bytes. The problem here is that, if there is only one logical sector per physical sector, the logical sector size is completely ignored. >How-To-Repeat: Boot with an AF-4Kn SATA drive attached. >Fix: The attached patch fixes both of the problems (I also took the liberty of replacing a few magic constants (a bitmask and value used for validation) with '#define's.) (1) sys/cam/ata/ata_all.c::ata_logical_sector_size() After concatenating 'lss_1' and 'lss_2', convert from words to bytes by left-shifting one bit. ---------------------------------------------------------------- (2) sys/cam/ata/ata_all.c::ata_physical_sector_size() If there is only a single logical sector per physical sector, then the physical sector size is equal to the logical sector size, so return that value. ---------------------------------------------------------------- /var/run/dmesg.boot (comments indented): ---------------------------------------------------------------- ada0 at ahcich0 bus 0 scbus0 target 0 lun 0 ada0: <DRIVE-MODEL DRIVE-FW> ATA-9 SATA 3.x device ada0: Serial Number DRIVE-SERIAL-NUMBER ada0: 600.000MB/s transfers (SATA 3.x, UDMA6, PIO 8192bytes) ada0: Command Queueing enabled ada0: 4769307MB (1220942646 4096 byte sectors: 16H 63S/T 16383C) Correct capacity Correct number of logical sectors, and correct sector size ada0: Previously was known as ad4 No errors; GPT was read and parsed correctly ---------------------------------------------------------------- `gpart show ada0': ---------------------------------------------------------------- => 6 1220942635 ada0 GPT (4.5T) 6 3969000 2 freebsd-ufs (15G) 3969006 1216973635 - free - (4.5T) ---------------------------------------------------------------- `camcontrol identify ada0' (comments indented): ---------------------------------------------------------------- pass0: <DRIVE-MODEL DRIVE-FW> ATA-9 SATA 3.x device pass0: 600.000MB/s transfers (SATA 3.x, UDMA6, PIO 8192bytes) protocol ATA/ATAPI-9 SATA 3.x device model DRIVE-MODEL firmware revision DRIVE-FW serial number DRIVE-SERIAL-NUMBER WWN DRIVE-WWN cylinders 16383 heads 16 sectors/track 63 sector size logical 4096, physical 4096, offset 0 Correct sector sizes LBA supported 268435455 sectors LBA48 supported 1220942646 sectors PIO supported PIO4 DMA supported WDMA2 UDMA6 media RPM 7200 Feature Support Enabled Value Vendor read ahead yes yes write cache yes yes flush cache yes yes overlap no Tagged Command Queuing (TCQ) no no Native Command Queuing (NCQ) yes 32 tags SMART yes yes microcode download yes yes security yes no power management yes yes advanced power management yes yes 128/0x80 automatic acoustic management no no media status notification no no power-up in Standby yes no write-read-verify no no unload no no free-fall no no Data Set Management (DSM/TRIM) no Host Protected Area (HPA) no ---------------------------------------------------------------- Patch attached with submission follows: Index: sys/cam/ata/ata_all.c =================================================================== --- sys/cam/ata/ata_all.c (revision 262757) +++ sys/cam/ata/ata_all.c (working copy) @@ -338,10 +338,10 @@ uint32_t ata_logical_sector_size(struct ata_params *ident_data) { - if ((ident_data->pss & 0xc000) == 0x4000 && + if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE && (ident_data->pss & ATA_PSS_LSSABOVE512)) { - return ((u_int32_t)ident_data->lss_1 | - ((u_int32_t)ident_data->lss_2 << 16)); + return (u_int32_t) (((u_int32_t)ident_data->lss_1 | + ((u_int32_t)ident_data->lss_2 << 16)) << 1); } return (512); } @@ -349,10 +349,13 @@ uint64_t ata_physical_sector_size(struct ata_params *ident_data) { - if ((ident_data->pss & 0xc000) == 0x4000 && - (ident_data->pss & ATA_PSS_MULTLS)) { - return ((uint64_t)ata_logical_sector_size(ident_data) * - (1 << (ident_data->pss & ATA_PSS_LSPPS))); + if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE) { + if (ident_data->pss & ATA_PSS_MULTLS) { + return ((uint64_t)ata_logical_sector_size(ident_data) * + (1 << (ident_data->pss & ATA_PSS_LSPPS))); + } else { + return (uint64_t)ata_logical_sector_size(ident_data); + } } return (512); } Index: sys/sys/ata.h =================================================================== --- sys/sys/ata.h (revision 262757) +++ sys/sys/ata.h (working copy) @@ -211,6 +211,8 @@ u_int16_t reserved104; /*105*/ u_int16_t max_dsm_blocks; /*106*/ u_int16_t pss; +#define ATA_PSS_VALID_MASK 0xC000 +#define ATA_PSS_VALID_VALUE 0x4000 #define ATA_PSS_LSPPS 0x000F #define ATA_PSS_LSSABOVE512 0x1000 #define ATA_PSS_MULTLS 0x2000 >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403050415.s254FGpu056393>