diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-02-10 21:45:42 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-02-10 21:45:42 +0000 |
commit | 09a2ff51b5828572f0e19cfdaa8b69cb6a6ff4c0 (patch) | |
tree | a775b627eedd69dcfd6da75044448513d7cf793c /sys/dev | |
parent | bd5c3bbd6c5540e95267d39fc4ec4baaed36b9c1 (diff) |
Fix LBA48 access for ServerWorks SATA.
ok grange@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ic/wdc.c | 30 | ||||
-rw-r--r-- | sys/dev/ic/wdcvar.h | 9 | ||||
-rw-r--r-- | sys/dev/pci/pciide.c | 14 | ||||
-rw-r--r-- | sys/dev/pci/pciide_pdc202xx_reg.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/pciide_sii3112_reg.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/pciide_svwsata_reg.h | 4 |
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, |