I don't know if anyone remembers enough of 5.x or 4.x to help with this, but if anyone does and cares to comment....
Prompted by seeing a Linux dmesg saying "Host Protected Area detected", I started trying to teach NetBSD about HPA. (If I can make this work, DCO support is next.) I found a PDF describing the relevant command set up for fetch at http://pdos.csail.mit.edu/6.828/2005/readings/hardware/ATA-d1410r3a.pdf. But I'm fairly sure I'm doing something wrong, because it's returning obviously-garbage results. I have a device whose IDENTIFY DEVICE response indicates HPA support, according to if ( (wd->sc_params.atap_cmd_set1 != 0x0000) && (wd->sc_params.atap_cmd_set1 != 0xffff) && (wd->sc_params.atap_cmd_set1 & WDC_CMD1_HPA) ) But the code I wrote that tries to use the READ NATIVE MAX ADDRESS command doesn't seem to work. (The drive is only some 8G, not large enough to need READ NATIVE MAX ADDRESS EXT - and if it's a much larger drive being HPA-limited for some reason, READ NATIVE MAX ADDRESS is supposed to return 0xfffffff). The usual code reports the drive as having 18039071 sectors, but my attempt to use READ NATIVE MAX ADDRESS returns a size of 4581695 - completely ludicrous in view of IDENTIFY DEVICE returning a number nearly four times as large. Here's the code I added. I based on it sys/dev/ata/wd.c 1.335.2.1.4.1, ie, 4.0.1's, largely because that's what was running on the handiest scratch machine. static void hpa_check(struct device *self) { struct wd_softc *wd; struct ata_command cmd; unsigned int cap; wd = (void *) self; aprint_normal("%s: HPA supported",&self->dv_xname[0]); if (wd->sc_params.atap_cmd1_en & WDC_CMD1_HPA) { aprint_normal(", HPA present"); } else { aprint_normal(", no HPA"); } if (wd->sc_params.atap_cmd_set2 & 0x80) /* XXX no WDC_* bit */ { aprint_normal(", offset supported\n"); } aprint_normal("\n"); bzero(&cmd,sizeof(cmd)); cmd.r_command = 0xf8; /* XXX no WDCC_ define */ cmd.r_st_bmask = 0; cmd.r_st_pmask = 0; cmd.r_features = 0; cmd.r_count = 0; cmd.timeout = 1000; cmd.flags = AT_WAIT | AT_READREG; cmd.data = 0; cmd.bcount = 0; if ((*((struct ata_channel *)wd->drvp->chnl_softc)->ch_atac->atac_bustype_ata->ata_exec_command)(wd->drvp,&cmd) != ATACMD_COMPLETE) { aprint_normal("%s: READ NATIVE MAX ADDRESS failed\n",&self->dv_xname[0]); } else { cap = cmd.r_sector | (cmd.r_cyl * 256) | ((cmd.r_head & 0xf) * 0x1000000); aprint_normal("%s: READ NATIVE MAX ADDRESS returned %u\n",&self->dv_xname[0],cap); } } This is called from wdattach just after printing the addressing method: if ((wd->sc_flags & WDF_LBA48) != 0) { aprint_normal(" LBA48 addressing\n"); [...] } else if ((wd->sc_flags & WDF_LBA) != 0) { aprint_normal(" LBA addressing\n"); [...] } else { aprint_normal(" chs addressing\n"); [...] } if ( (wd->sc_params.atap_cmd_set1 != 0x0000) && (wd->sc_params.atap_cmd_set1 != 0xffff) && (wd->sc_params.atap_cmd_set1 & WDC_CMD1_HPA) ) hpa_check(self); and I'm seeing wd0 at atabus0 drive 0: <QUANTUM FIREBALLP KA9.1> wd0: drive supports 16-sector PIO transfers, LBA addressing wd0: HPA supported, HPA present wd0: READ NATIVE MAX ADDRESS returned 4581695 wd0: 8808 MB, 17895 cyl, 16 head, 63 sec, 512 bytes/sect x 18039071 sectors I notice that I'm not getting zero (which is what I'd expect if it weren't reading back registers), nor am I just losing the top bits, nor am I getting something that (possibly after correcting for missing high bits) is just a little greater than the IDENTIFY-reported capacity. So I assume I'm doing something wrong, and the obvious question is, what? /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B