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