summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-02-10 21:45:42 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-02-10 21:45:42 +0000
commit09a2ff51b5828572f0e19cfdaa8b69cb6a6ff4c0 (patch)
treea775b627eedd69dcfd6da75044448513d7cf793c /sys/dev
parentbd5c3bbd6c5540e95267d39fc4ec4baaed36b9c1 (diff)
Fix LBA48 access for ServerWorks SATA.
ok grange@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ic/wdc.c30
-rw-r--r--sys/dev/ic/wdcvar.h9
-rw-r--r--sys/dev/pci/pciide.c14
-rw-r--r--sys/dev/pci/pciide_pdc202xx_reg.h3
-rw-r--r--sys/dev/pci/pciide_sii3112_reg.h3
-rw-r--r--sys/dev/pci/pciide_svwsata_reg.h4
6 files changed, 48 insertions, 15 deletions
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c
index 62599e113bf..4a19590d8f6 100644
--- a/sys/dev/ic/wdc.c
+++ b/sys/dev/ic/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.88 2005/11/09 19:05:48 uwe Exp $ */
+/* $OpenBSD: wdc.c,v 1.89 2006/02/10 21:45:41 kettenis Exp $ */
/* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
@@ -140,6 +140,7 @@ int wdc_ata_present(struct channel_softc *, int);
struct channel_softc_vtbl wdc_default_vtbl = {
wdc_default_read_reg,
wdc_default_write_reg,
+ wdc_default_lba48_write_reg,
wdc_default_read_raw_multi_2,
wdc_default_write_raw_multi_2,
wdc_default_read_raw_multi_4,
@@ -334,6 +335,16 @@ wdc_default_write_reg(chp, reg, val)
reg & _WDC_REGMASK, val);
}
+void
+wdc_default_lba48_write_reg(chp, reg, val)
+ struct channel_softc *chp;
+ enum wdc_regs reg;
+ u_int16_t val;
+{
+ /* All registers are two byte deep FIFOs. */
+ CHP_WRITE_REG(chp, reg, val >> 8);
+ CHP_WRITE_REG(chp, reg, val);
+}
void
wdc_default_read_raw_multi_2(chp, data, nbytes)
@@ -1956,15 +1967,14 @@ wdccommandext(chp, drive, command, blkno, count)
/* Select drive and LBA mode. */
CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_LBA);
- /* Load parameters. All registers are two byte deep FIFOs. */
- CHP_WRITE_REG(chp, wdr_lba_hi, blkno >> 40);
- CHP_WRITE_REG(chp, wdr_lba_hi, blkno >> 16);
- CHP_WRITE_REG(chp, wdr_lba_mi, blkno >> 32);
- CHP_WRITE_REG(chp, wdr_lba_mi, blkno >> 8);
- CHP_WRITE_REG(chp, wdr_lba_lo, blkno >> 24);
- CHP_WRITE_REG(chp, wdr_lba_lo, blkno);
- CHP_WRITE_REG(chp, wdr_seccnt, count >> 8);
- CHP_WRITE_REG(chp, wdr_seccnt, count);
+ /* Load parameters. */
+ CHP_LBA48_WRITE_REG(chp, wdr_lba_hi,
+ ((blkno >> 32) & 0xff00) | ((blkno >> 16) & 0xff));
+ CHP_LBA48_WRITE_REG(chp, wdr_lba_mi,
+ ((blkno >> 24) & 0xff00) | ((blkno >> 8) & 0xff));
+ CHP_LBA48_WRITE_REG(chp, wdr_lba_lo,
+ ((blkno >> 16) & 0xff00) | (blkno & 0xff));
+ CHP_LBA48_WRITE_REG(chp, wdr_seccnt, count);
/* Send command. */
CHP_WRITE_REG(chp, wdr_command, command);
diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h
index d87e15a16a7..9b8d4ef6fbb 100644
--- a/sys/dev/ic/wdcvar.h
+++ b/sys/dev/ic/wdcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdcvar.h,v 1.37 2004/10/17 17:50:48 grange Exp $ */
+/* $OpenBSD: wdcvar.h,v 1.38 2006/02/10 21:45:41 kettenis Exp $ */
/* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */
/*-
@@ -121,6 +121,8 @@ struct channel_softc_vtbl {
u_int8_t (*read_reg)(struct channel_softc *, enum wdc_regs reg);
void (*write_reg)(struct channel_softc *, enum wdc_regs reg,
u_int8_t var);
+ void (*lba48_write_reg)(struct channel_softc *, enum wdc_regs reg,
+ u_int16_t var);
void (*read_raw_multi_2)(struct channel_softc *,
void *data, unsigned int nbytes);
@@ -136,6 +138,9 @@ struct channel_softc_vtbl {
#define CHP_READ_REG(chp, a) ((chp)->_vtbl->read_reg)(chp, a)
#define CHP_WRITE_REG(chp, a, b) ((chp)->_vtbl->write_reg)(chp, a, b)
+#define CHP_LBA48_WRITE_REG(chp, a, b) \
+ ((chp)->_vtbl->lba48_write_reg)(chp, a, b)
+
#define CHP_READ_RAW_MULTI_2(chp, a, b) \
((chp)->_vtbl->read_raw_multi_2)(chp, a, b)
#define CHP_WRITE_RAW_MULTI_2(chp, a, b) \
@@ -316,6 +321,8 @@ u_int8_t wdc_default_read_reg(struct channel_softc *,
enum wdc_regs);
void wdc_default_write_reg(struct channel_softc *,
enum wdc_regs, u_int8_t);
+void wdc_default_lba48_write_reg(struct channel_softc *,
+ enum wdc_regs, u_int16_t);
void wdc_default_read_raw_multi_2(struct channel_softc *,
void *, unsigned int);
void wdc_default_write_raw_multi_2(struct channel_softc *,
diff --git a/sys/dev/pci/pciide.c b/sys/dev/pci/pciide.c
index 560fec4e5f9..d5bfab452e6 100644
--- a/sys/dev/pci/pciide.c
+++ b/sys/dev/pci/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.224 2006/02/03 11:50:34 brad Exp $ */
+/* $OpenBSD: pciide.c,v 1.225 2006/02/10 21:45:41 kettenis Exp $ */
/* $NetBSD: pciide.c,v 1.127 2001/08/03 01:31:08 tsutsui Exp $ */
/*
@@ -7184,6 +7184,18 @@ svwsata_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int8_t val)
}
}
+void
+svwsata_lba48_write_reg(struct channel_softc *chp, enum wdc_regs reg, u_int16_t val)
+{
+ if (reg & _WDC_AUX) {
+ bus_space_write_4(chp->ctl_iot, chp->ctl_ioh,
+ (reg & _WDC_REGMASK) << 2, val);
+ } else {
+ bus_space_write_4(chp->cmd_iot, chp->cmd_ioh,
+ (reg & _WDC_REGMASK) << 2, val);
+ }
+}
+
#define ACARD_IS_850(sc) \
((sc)->sc_pp->ide_product == PCI_PRODUCT_ACARD_ATP850U)
diff --git a/sys/dev/pci/pciide_pdc202xx_reg.h b/sys/dev/pci/pciide_pdc202xx_reg.h
index f207a5e6021..bd8d82e5708 100644
--- a/sys/dev/pci/pciide_pdc202xx_reg.h
+++ b/sys/dev/pci/pciide_pdc202xx_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_pdc202xx_reg.h,v 1.12 2005/06/15 04:45:49 fgsch Exp $ */
+/* $OpenBSD: pciide_pdc202xx_reg.h,v 1.13 2006/02/10 21:45:41 kettenis Exp $ */
/* $NetBSD: pciide_pdc202xx_reg.h,v 1.5 2001/07/05 08:38:27 toshii Exp $ */
/*
@@ -154,6 +154,7 @@ void pdc203xx_write_reg(struct channel_softc *, enum wdc_regs, u_int8_t);
struct channel_softc_vtbl wdc_pdc203xx_vtbl = {
pdc203xx_read_reg,
pdc203xx_write_reg,
+ wdc_default_lba48_write_reg,
wdc_default_read_raw_multi_2,
wdc_default_write_raw_multi_2,
wdc_default_read_raw_multi_4,
diff --git a/sys/dev/pci/pciide_sii3112_reg.h b/sys/dev/pci/pciide_sii3112_reg.h
index 03c602b8839..dfcd6fe4ece 100644
--- a/sys/dev/pci/pciide_sii3112_reg.h
+++ b/sys/dev/pci/pciide_sii3112_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_sii3112_reg.h,v 1.4 2005/11/14 13:00:29 mickey Exp $ */
+/* $OpenBSD: pciide_sii3112_reg.h,v 1.5 2006/02/10 21:45:41 kettenis Exp $ */
/* $NetBSD: pciide_sii3112_reg.h,v 1.1 2003/03/20 04:22:50 thorpej Exp $ */
/*
@@ -396,6 +396,7 @@ void sii3114_write_reg(struct channel_softc *, enum wdc_regs, u_int8_t);
struct channel_softc_vtbl wdc_sii3114_vtbl = {
sii3114_read_reg,
sii3114_write_reg,
+ wdc_default_lba48_write_reg,
wdc_default_read_raw_multi_2,
wdc_default_write_raw_multi_2,
wdc_default_read_raw_multi_4,
diff --git a/sys/dev/pci/pciide_svwsata_reg.h b/sys/dev/pci/pciide_svwsata_reg.h
index dfa2f5d1f8c..86a7e24b2f8 100644
--- a/sys/dev/pci/pciide_svwsata_reg.h
+++ b/sys/dev/pci/pciide_svwsata_reg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide_svwsata_reg.h,v 1.3 2005/10/21 10:52:32 grange Exp $ */
+/* $OpenBSD: pciide_svwsata_reg.h,v 1.4 2006/02/10 21:45:41 kettenis Exp $ */
/*
* Copyright (c) 2005 Mark Kettenis
@@ -39,10 +39,12 @@ struct pciide_svwsata {
u_int8_t svwsata_read_reg(struct channel_softc *, enum wdc_regs);
void svwsata_write_reg(struct channel_softc *, enum wdc_regs, u_int8_t);
+void svwsata_lba48_write_reg(struct channel_softc *, enum wdc_regs, u_int16_t);
struct channel_softc_vtbl wdc_svwsata_vtbl = {
svwsata_read_reg,
svwsata_write_reg,
+ svwsata_lba48_write_reg,
wdc_default_read_raw_multi_2,
wdc_default_write_raw_multi_2,
wdc_default_read_raw_multi_4,