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


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));
     }
 }
_______________________________________________
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to