Module Name: src Committed By: tsutsui Date: Sun Jan 10 16:20:45 UTC 2010
Modified Files: src/sys/arch/cobalt/stand/boot: version wd.c wdc.c wdvar.h Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/cobalt/stand/boot/version \ src/sys/arch/cobalt/stand/boot/wd.c cvs rdiff -u -r1.11 -r1.12 src/sys/arch/cobalt/stand/boot/wdc.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/cobalt/stand/boot/wdvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/cobalt/stand/boot/version diff -u src/sys/arch/cobalt/stand/boot/version:1.10 src/sys/arch/cobalt/stand/boot/version:1.11 --- src/sys/arch/cobalt/stand/boot/version:1.10 Wed May 28 14:04:07 2008 +++ src/sys/arch/cobalt/stand/boot/version Sun Jan 10 16:20:45 2010 @@ -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 Index: src/sys/arch/cobalt/stand/boot/wd.c diff -u src/sys/arch/cobalt/stand/boot/wd.c:1.10 src/sys/arch/cobalt/stand/boot/wd.c:1.11 --- src/sys/arch/cobalt/stand/boot/wd.c:1.10 Mon Apr 28 20:23:16 2008 +++ src/sys/arch/cobalt/stand/boot/wd.c Sun Jan 10 16:20:45 2010 @@ -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) { - DPRINTF(("Drive supports LBA.\n")); + 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_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, Index: src/sys/arch/cobalt/stand/boot/wdc.c diff -u src/sys/arch/cobalt/stand/boot/wdc.c:1.11 src/sys/arch/cobalt/stand/boot/wdc.c:1.12 --- src/sys/arch/cobalt/stand/boot/wdc.c:1.11 Mon Apr 28 20:23:16 2008 +++ src/sys/arch/cobalt/stand/boot/wdc.c Sun Jan 10 16:20:45 2010 @@ -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; + + 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 (wd->sc_flags & WDF_LBA48) { + 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); Index: src/sys/arch/cobalt/stand/boot/wdvar.h diff -u src/sys/arch/cobalt/stand/boot/wdvar.h:1.8 src/sys/arch/cobalt/stand/boot/wdvar.h:1.9 --- src/sys/arch/cobalt/stand/boot/wdvar.h:1.8 Wed Oct 17 19:54:10 2007 +++ src/sys/arch/cobalt/stand/boot/wdvar.h Sun Jan 10 16:20:45 2010 @@ -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;