Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/cobalt/stand/boot Add support for LBA48 read comman...



details:   https://anonhg.NetBSD.org/src/rev/df86e412ee49
branches:  trunk
changeset: 750680:df86e412ee49
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sun Jan 10 16:20:45 2010 +0000

description:
Add support for LBA48 read command to standalone wdc/wd driver.
Thanks to bouyer@ for comments about LBA48 boundary checks.

Tested on:
> Cobalt Qube 2700
> wd0 at atabus0 drive 0: <Hitachi HDS721616PLA380>
> wd0: 153 GB, 319120 cyl, 16 head, 63 sec, 512 bytes/sect x 321672960 sectors
via SATA-IDE converter, and NetBSD partition allocated at:
> 1: NetBSD (sysid 169)
>     start 293603940, size 28069020 (13706 MB, Cyls 18276-20023/54/63)

Also bump version.

diffstat:

 sys/arch/cobalt/stand/boot/version |   3 +-
 sys/arch/cobalt/stand/boot/wd.c    |  45 ++++++++++++++++++++++++++++++-------
 sys/arch/cobalt/stand/boot/wdc.c   |  41 ++++++++++++++++++++++++----------
 sys/arch/cobalt/stand/boot/wdvar.h |   5 ++-
 4 files changed, 70 insertions(+), 24 deletions(-)

diffs (198 lines):

diff -r c92f4e91a71f -r df86e412ee49 sys/arch/cobalt/stand/boot/version
--- a/sys/arch/cobalt/stand/boot/version        Sun Jan 10 16:04:25 2010 +0000
+++ b/sys/arch/cobalt/stand/boot/version        Sun Jan 10 16:20:45 2010 +0000
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.10 2008/05/28 14:04:07 tsutsui Exp $
+$NetBSD: version,v 1.11 2010/01/10 16:20:45 tsutsui Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -14,3 +14,4 @@
 0.7:   Add support for netboot via 21041 on Qube2700
 0.8:   Add support for optional Z85C30 serial console on Qube2700
 0.9:   Print banner and a loading kernel name onto LCD
+1.0:   Add support for LBA48 read command
diff -r c92f4e91a71f -r df86e412ee49 sys/arch/cobalt/stand/boot/wd.c
--- a/sys/arch/cobalt/stand/boot/wd.c   Sun Jan 10 16:04:25 2010 +0000
+++ b/sys/arch/cobalt/stand/boot/wd.c   Sun Jan 10 16:20:45 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.10 2008/04/28 20:23:16 martin Exp $   */
+/*     $NetBSD: wd.c,v 1.11 2010/01/10 16:20:45 tsutsui Exp $  */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -61,18 +61,45 @@
        wd->sc_params = *(struct ataparams *)buf;
 
        /* 48-bit LBA addressing */
-       if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0) {
-               DPRINTF(("Drive supports LBA48.\n"));
-#if defined(_ENABLE_LBA48)
+       if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0)
                wd->sc_flags |= WDF_LBA48;
-#endif
-       }
 
        /* Prior to ATA-4, LBA was optional. */
-       if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0) {
+       if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
+               wd->sc_flags |= WDF_LBA;
+       
+       if ((wd->sc_flags & WDF_LBA48) != 0) {
+               DPRINTF(("Drive supports LBA48.\n"));
+               wd->sc_capacity =
+                   ((uint64_t)wd->sc_params.atap_max_lba[3] << 48) |
+                   ((uint64_t)wd->sc_params.atap_max_lba[2] << 32) |
+                   ((uint64_t)wd->sc_params.atap_max_lba[1] << 16) |
+                   ((uint64_t)wd->sc_params.atap_max_lba[0] <<  0);
+               DPRINTF(("atap_max_lba = (0x%x, 0x%x, 0x%x, 0x%x)\n",
+                   wd->sc_params.atap_max_lba[3],
+                   wd->sc_params.atap_max_lba[2],
+                   wd->sc_params.atap_max_lba[1],
+                   wd->sc_params.atap_max_lba[0]));
+               wd->sc_capacity28 =
+                   ((uint32_t)wd->sc_params.atap_capacity[1] << 16) |
+                   ((uint32_t)wd->sc_params.atap_capacity[0] <<  0);
+               DPRINTF(("atap_capacity = (0x%x, 0x%x)\n",
+                   wd->sc_params.atap_capacity[1],
+                   wd->sc_params.atap_capacity[0]));
+       } else if ((wd->sc_flags & WDF_LBA) != 0) {
                DPRINTF(("Drive supports LBA.\n"));
-               wd->sc_flags |= WDF_LBA;
+               wd->sc_capacity = wd->sc_capacity28 =
+                   ((uint32_t)wd->sc_params.atap_capacity[1] << 16) |
+                   ((uint32_t)wd->sc_params.atap_capacity[0] <<  0);
+       } else {
+               DPRINTF(("Drive doesn't support LBA; using CHS.\n"));
+               wd->sc_capacity = wd->sc_capacity28 =
+                   wd->sc_params.atap_cylinders *
+                   wd->sc_params.atap_heads *
+                   wd->sc_params.atap_sectors;
        }
+       DPRINTF(("wd->sc_capacity = %ld, wd->sc_capacity28 = %d.\n",
+           (u_long)wd->sc_capacity, wd->sc_capacity28));
 
        return 0;
 }
@@ -173,7 +200,7 @@
        }
 
        DPRINTF(("label info: d_secsize %d, d_nsectors %d, d_ncylinders %d,"
-           "d_ntracks %d, d_secpercyl %d\n",
+           " d_ntracks %d, d_secpercyl %d\n",
            wd->sc_label.d_secsize,
            wd->sc_label.d_nsectors,
            wd->sc_label.d_ncylinders,
diff -r c92f4e91a71f -r df86e412ee49 sys/arch/cobalt/stand/boot/wdc.c
--- a/sys/arch/cobalt/stand/boot/wdc.c  Sun Jan 10 16:04:25 2010 +0000
+++ b/sys/arch/cobalt/stand/boot/wdc.c  Sun Jan 10 16:20:45 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdc.c,v 1.11 2008/04/28 20:23:16 martin Exp $  */
+/*     $NetBSD: wdc.c,v 1.12 2010/01/10 16:20:45 tsutsui Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -229,7 +229,7 @@
            wd_c->r_precomp));
 #endif
 
-       WDC_WRITE_REG(chp, wd_precomp, wd_c->r_precomp);
+       WDC_WRITE_REG(chp, wd_features, wd_c->r_features);
        WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count);
        WDC_WRITE_REG(chp, wd_sector, wd_c->r_sector);
        WDC_WRITE_REG(chp, wd_cyl_lo, wd_c->r_cyl);
@@ -258,6 +258,12 @@
 {
        struct wdc_channel *chp = &wd->sc_channel;
 
+#if 0
+       DPRINTF(("%s(%d, %x, %ld, %d)\n", __func__,
+           wd_c->drive, wd_c->r_command,
+           (u_long)wd_c->r_blkno, wd_c->r_count));
+#endif
+
        /* Select drive, head, and addressing mode. */
        WDC_WRITE_REG(chp, wd_sdh, (wd_c->drive << 4) | WDSD_LBA);
 
@@ -320,20 +326,37 @@
 {
        int error;
        struct wdc_command wd_c;
+       bool lba, lba48;
 
        memset(&wd_c, 0, sizeof(wd_c));
+       lba   = false;
+       lba48 = false;
 
-       if (wd->sc_flags & WDF_LBA48) {
+       wd_c.data = data;
+       wd_c.r_count = 1;
+       wd_c.r_features = 0;
+       wd_c.drive = wd->sc_unit;
+       wd_c.bcount = wd->sc_label.d_secsize;
+
+       if ((wd->sc_flags & WDF_LBA48) != 0 && blkno > wd->sc_capacity28)
+               lba48 = true;
+       else if ((wd->sc_flags & WDF_LBA) != 0)
+               lba = true;
+
+       if (lba48) {
                /* LBA48 */
+               wd_c.r_command = atacmd_to48(cmd);
                wd_c.r_blkno = blkno;
-       } else if (wd->sc_flags & WDF_LBA) {
+       } else if (lba) {
                /* LBA */
+               wd_c.r_command = cmd;
                wd_c.r_sector = (blkno >> 0) & 0xff;
                wd_c.r_cyl = (blkno >> 8) & 0xffff;
                wd_c.r_head = (blkno >> 24) & 0x0f;
                wd_c.r_head |= WDSD_LBA;
        } else {
-               /* LHS */
+               /* CHS */
+               wd_c.r_command = cmd;
                wd_c.r_sector = blkno % wd->sc_label.d_nsectors;
                wd_c.r_sector++;    /* Sectors begin with 1, not 0. */
                blkno /= wd->sc_label.d_nsectors;
@@ -343,13 +366,7 @@
                wd_c.r_head |= WDSD_CHS;
        }
 
-       wd_c.data = data;
-       wd_c.r_count = 1;
-       wd_c.drive = wd->sc_unit;
-       wd_c.r_command = cmd;
-       wd_c.bcount = wd->sc_label.d_secsize;
-
-       if (wd->sc_flags & WDF_LBA48)
+       if (lba48)
                error = wdccommandext(wd, &wd_c);
        else
                error = wdccommand(wd, &wd_c);
diff -r c92f4e91a71f -r df86e412ee49 sys/arch/cobalt/stand/boot/wdvar.h
--- a/sys/arch/cobalt/stand/boot/wdvar.h        Sun Jan 10 16:04:25 2010 +0000
+++ b/sys/arch/cobalt/stand/boot/wdvar.h        Sun Jan 10 16:20:45 2010 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wdvar.h,v 1.8 2007/10/17 19:54:10 garbled Exp $        */
+/*     $NetBSD: wdvar.h,v 1.9 2010/01/10 16:20:45 tsutsui Exp $        */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -72,6 +72,7 @@
        u_int sc_unit;
 
        uint64_t sc_capacity;
+       uint32_t sc_capacity28;
 
        struct ataparams sc_params;
        struct disklabel sc_label;
@@ -86,7 +87,7 @@
        uint16_t r_cyl;
        uint8_t r_sector;
        uint8_t r_count;
-       uint8_t r_precomp;
+       uint8_t r_features;
 
        uint16_t bcount;
        void *data;



Home | Main Index | Thread Index | Old Index