Module Name: src Committed By: macallan Date: Fri Jun 1 18:13:30 UTC 2018
Modified Files: src/sys/dev/ata: ata_wdc.c atavar.h Log Message: 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 To generate a diff of this commit: cvs rdiff -u -r1.109 -r1.110 src/sys/dev/ata/ata_wdc.c cvs rdiff -u -r1.96 -r1.97 src/sys/dev/ata/atavar.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/dev/ata/ata_wdc.c diff -u src/sys/dev/ata/ata_wdc.c:1.109 src/sys/dev/ata/ata_wdc.c:1.110 --- src/sys/dev/ata/ata_wdc.c:1.109 Tue Oct 17 18:52:50 2017 +++ src/sys/dev/ata/ata_wdc.c Fri Jun 1 18:13:30 2018 @@ -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 *c 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 *c 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) Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.96 src/sys/dev/ata/atavar.h:1.97 --- src/sys/dev/ata/atavar.h:1.96 Mon Apr 16 22:33:28 2018 +++ src/sys/dev/ata/atavar.h Fri Jun 1 18:13:30 2018 @@ -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;