Date: Sun, 11 Apr 2004 23:00:15 +0400 From: Roman Kurakin <rik@cronyx.ru> To: freebsd-current@freebsd.org, freebsd-hackers@freebsd.org Cc: Roman Kurakin <rik@cronyx.ru> Subject: ATA/CHS problem (path + new information) Message-ID: <407995BF.7060504@cronyx.ru> References: <4061E207.8070406@cronyx.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------040803000505040604040808 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hi, You can find history of my previous postings below. I didn't moved far since that time, because lack of time. But any way I have some new information and one patch I want to share. This patch didn't solve any of my problems. Soren, please review it. This time it is comlete. I hope this patch would allow to track down similar problems I have. I remind you that now I have two problems. First one that FreeBSD uses wrong assumption about which device should be CHS and which LBA: if (!ad_version(atadev->param->version_major) || !(atadev->param->atavalid & ATA_FLAG_54_58) || !lbasize) atadev->flags |= ATA_D_USE_CHS; True ATA device may not have ATA_FLAG_54_58 valid bit, and also due to last ATA standard this bit is obsoleted. I also want to know why ata driver doesn't check LBA support from word 49? May be this one check could solve my problems and didn't breake code for non-ATA devices. Second one, that only 20G part of my hard disk works with CHS. This is other side of the same problem. Device should work in CHS mode. And it works witch ICH5 controller. But with ICH2 it doesn't with out hack. I've checked standard again and I sew command 91h (Initialize drive parameters). YES, this command solved my problem witch CHS. But. But the life is no so easy :-) This command fails itself with abort code. But as I said I can access sectors that was previously NOT FOUND after it. (ata_controlcmd (atadev,0x91, 0, 0xfUL << 24, 63); I've put it just after Identify driver command in ata_getparam function) Any comments and suggestions very very appreciated. And please do not suggest how to fix this problem only for me. I already know a few variant that can't be commited. I realy want to crush this bug. rik Roman Kurakin wrote: > Hi, > > (Was "HDD question" on hackers@, posted also here cause this is also > CURRENT problem) > > History: > >> I have some problems with my HDD (ST380021A). The problem was > >> checked on 5.2, 5.2.1, and some > >> 5.Current (cvsuped about week or two). >> >> At first I got this problem while system installation. I get trap > >> and message from ata after I start a commit: > >> FAILURE READ_DMA status=51 <READY, DSC, ERROR> error=10 > >> <NID_NOT_FOUND> LBA=245529601 > >> >> I started to hack sysinstall and finally came to simple program > >> that could lead > >> to the same message from ata: >> >> fd = open ("/dev/ata0", O_RDWR); >> read_block (fd, (daddr_t)41929650, 512); // this one could be changed > >> // to pair calls lseek and read, > >> // so this is not libdisk problem > >> >> I checked the same code with /dev/ata1 which is twice as little, but > >> I didn't get any messages. >> I don't have any ideas where my read call goes, which drivers to look > >> to catch this bug. > >> >> So I need a help from some gurus in this area. > > > What I've found since that time: > > This is not an LBA request. ATA driver thinks that I have 80G CHS > device, cause it's ATA_FLAG_54_58 > is zero. (This decision is incorrect, we shouldn't relay on this > flag). I've checked another seagate 80G drive in > CHS mode(by driver hacking), and problematic one with LBA mode. I get > the same behavior on both with CHS. > And both work fine in LBA mode. It also should be mentioned that I get > this problem on machine with > ICH2 controller, and it seems that I don't have such problem on other > machine with ICH5. > > PS. If you have any ideas, or if you have any materials (standards for > example) about ATA/ATAPI and you > can share them with me, please let me know. I am not ata developer, so > this is a bit difficalt for me to > dig this problem. > > rik --------------040803000505040604040808 Content-Type: text/plain; name="ata3.pch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ata3.pch" diff -ubr ata-orig/ata-disk.c ata/ata-disk.c --- ata-orig/ata-disk.c Wed Mar 10 20:05:56 2004 +++ ata/ata-disk.c Sun Apr 11 12:26:02 2004 @@ -388,13 +388,14 @@ (adp->heads * adp->sectors)), adp->heads, adp->sectors, DEV_BSIZE); - ata_prtdev(adp->device, "%d secs/int, %d depth queue, %s%s\n", + ata_prtdev(adp->device, "%d secs/int, %d depth queue, %s%s%s\n", adp->max_iosize / DEV_BSIZE, adp->num_tags + 1, (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(adp->device->mode)); + ata_mode2str(adp->device->mode), + (adp->device->flags & ATA_D_USE_CHS) ? "(CHS mode)": ""); } else - ata_prtdev(adp->device,"%lluMB <%.40s> [%lld/%d/%d] at ata%d-%s %s%s\n", + ata_prtdev(adp->device,"%lluMB <%.40s> [%lld/%d/%d] at ata%d-%s %s%s%s\n", (unsigned long long)(adp->total_secs / ((1024L * 1024L) / DEV_BSIZE)), adp->device->param->model, @@ -404,7 +405,8 @@ device_get_unit(adp->device->channel->dev), (adp->device->unit == ATA_MASTER) ? "master" : "slave", (adp->flags & AD_F_TAG_ENABLED) ? "tagged " : "", - ata_mode2str(adp->device->mode)); + ata_mode2str(adp->device->mode), + (adp->device->flags & ATA_D_USE_CHS) ? " (CHS mode)": ""); } static int diff -ubr ata-orig/ata-queue.c ata/ata-queue.c --- ata-orig/ata-queue.c Tue Mar 23 20:39:22 2004 +++ ata/ata-queue.c Sun Apr 11 19:00:05 2004 @@ -47,6 +47,7 @@ /* prototypes */ static void ata_completed(void *, int); static void ata_timeout(struct ata_request *); +static void ata_print_lba (u_int64_t lba, int non_lba_mode); static char *ata_skey2str(u_int8_t); void @@ -278,7 +279,8 @@ "WARNING - %s soft error (ECC corrected)", ata_cmd2str(request)); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); } @@ -289,7 +291,8 @@ "WARNING - %s UDMA ICRC error (retrying request)", ata_cmd2str(request)); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); request->flags |= (ATA_R_IMMEDIATE | ATA_R_REQUEUE); ata_queue_request(request); @@ -316,7 +319,8 @@ (request->dmastat & ATA_BMSTAT_ERROR)) printf(" dma=0x%02x", request->dmastat); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); } @@ -420,7 +424,8 @@ "WARNING - %s interrupt was seen but timeout fired", ata_cmd2str(request)); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); /* re-arm timeout */ @@ -435,7 +440,8 @@ "WARNING - %s interrupt was seen but taskqueue stalled", ata_cmd2str(request)); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); ata_completed(request, 0); } @@ -449,7 +455,8 @@ ata_cmd2str(request), request->retries, request->retries == 1 ? "y" : "ies"); if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL))) - printf(" LBA=%llu", (unsigned long long)request->u.ata.lba); + ata_print_lba (request->u.ata.lba, + request->device->flags & ATA_D_USE_CHS); printf("\n"); } @@ -618,5 +625,18 @@ case 0x0e: return ("MISCOMPARE"); case 0x0f: return ("RESERVED"); default: return("UNKNOWN"); + } +} + +static void +ata_print_lba (u_int64_t lba, int non_lba_mode) +{ + if (!non_lba_mode) { + printf(" LBA=%llu", (unsigned long long)lba); + } else { + printf(" CHS=%u/%u/%u", + (unsigned int)((lba >> 8) & 0xffff), + (unsigned int)((lba >> 24) & 0xf), + (unsigned int)(lba & 0xff)); } } --------------040803000505040604040808--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?407995BF.7060504>