diff options
| author | macallan <macallan@NetBSD.org> | 2018-06-01 18:13:30 +0000 |
|---|---|---|
| committer | macallan <macallan@NetBSD.org> | 2018-06-01 18:13:30 +0000 |
| commit | 580d57335d61a35b006dbd200b4fa7ea4d233e67 (patch) | |
| tree | 9cb9f5f4bf7e2a5169a817fc6f70a7426d8ca9be /sys/dev/ata | |
| parent | 84e3c8175e917c6d66beba15be57ebb7d381b91c (diff) | |
add a flag to start DMA before issuing commands - needed to work around a bug
in some SATA chips which get confused if the disk responds too fast
Mostly for K2 SATA / svwsata found in G5 Macs
adapted from OpenBSD
Diffstat (limited to 'sys/dev/ata')
| -rw-r--r-- | sys/dev/ata/ata_wdc.c | 15 | ||||
| -rw-r--r-- | sys/dev/ata/atavar.h | 3 |
2 files changed, 12 insertions, 6 deletions
diff --git a/sys/dev/ata/ata_wdc.c b/sys/dev/ata/ata_wdc.c index c0715f43e75..57ff3b1eb4b 100644 --- a/sys/dev/ata/ata_wdc.c +++ b/sys/dev/ata/ata_wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: ata_wdc.c,v 1.109 2017/10/17 18:52:50 jdolecek Exp $ */ +/* $NetBSD: ata_wdc.c,v 1.110 2018/06/01 18:13:30 macallan Exp $ */ /* * Copyright (c) 1998, 2001, 2003 Manuel Bouyer. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.109 2017/10/17 18:52:50 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata_wdc.c,v 1.110 2018/06/01 18:13:30 macallan Exp $"); #include "opt_ata.h" #include "opt_wdc.h" @@ -455,6 +455,10 @@ _wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) case WDCWAIT_THR: return ATASTART_TH; } + /* start the DMA channel before */ + if ((chp->ch_flags & ATACH_DMA_BEFORE_CMD) != 0) + (*wdc->dma_start)(wdc->dma_arg, + chp->ch_channel, xfer->c_drive); if (ata_bio->flags & ATA_LBA48) { uint8_t device = WDSD_LBA; cmd = atacmd_to48(cmd); @@ -468,9 +472,10 @@ _wdc_ata_bio_start(struct ata_channel *chp, struct ata_xfer *xfer) wdccommand(chp, xfer->c_drive, cmd, cyl, head, sect, count, features); } - /* start the DMA channel */ - (*wdc->dma_start)(wdc->dma_arg, - chp->ch_channel, xfer->c_drive); + /* start the DMA channel after */ + if ((chp->ch_flags & ATACH_DMA_BEFORE_CMD) == 0) + (*wdc->dma_start)(wdc->dma_arg, + chp->ch_channel, xfer->c_drive); chp->ch_flags |= ATACH_DMA_WAIT; /* start timeout machinery */ if ((xfer->c_flags & C_POLL) == 0) diff --git a/sys/dev/ata/atavar.h b/sys/dev/ata/atavar.h index bd6e219997a..fa5535de914 100644 --- a/sys/dev/ata/atavar.h +++ b/sys/dev/ata/atavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.96 2018/04/16 22:33:28 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.97 2018/06/01 18:13:30 macallan Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -407,6 +407,7 @@ struct ata_channel { #define ATACH_TH_RESET 0x200 /* someone ask the thread to reset */ #define ATACH_TH_RESCAN 0x400 /* rescan requested */ #define ATACH_NCQ 0x800 /* channel executing NCQ commands */ +#define ATACH_DMA_BEFORE_CMD 0x1000 /* start DMA first */ /* for the reset callback */ int ch_reset_flags; |
