1/*-
2 * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 11 unchanged lines hidden (view full) ---
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/ata/ata-dma.c 71335 2001-01-21 16:13:03Z sos $
29 */
30
31#include "pci.h"
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/bio.h>
35#include <sys/malloc.h>
36#include <sys/bus.h>
37#include <sys/disk.h>
38#include <sys/devicestat.h>
39#include <vm/vm.h>
40#include <vm/pmap.h>
41#if NPCI > 0
42#include <pci/pcivar.h>
43#endif
44#include <machine/bus.h>
45#include <dev/ata/ata-all.h>
46
47#if NPCI > 0
48
49/* prototypes */
50static void cyrix_timing(struct ata_softc *, int, int);
51static void promise_timing(struct ata_softc *, int, int);
52static void hpt_timing(struct ata_softc *, int, int);
--- 26 unchanged lines hidden (view full) ---
79{
80 device_t parent = device_get_parent(scp->dev);
81 int devno = (scp->channel << 1) + ATA_DEV(device);
82 int error;
83
84 /* set our most pessimistic default mode */
85 scp->mode[ATA_DEV(device)] = ATA_PIO;
86
87 if (!scp->bmaddr)
88 return;
89
90 /* if simplex controller, only allow DMA on primary channel */
91 if (scp->channel == 1) {
92 outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) &
93 (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
94 if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) {
95 ata_printf(scp, device, "simplex device, DMA on primary only\n");
96 return;
97 }
98 }
99
100 /* DMA engine address alignment is usually 1 word (2 bytes) */
101 scp->alignment = 0x1;
102
--- 715 unchanged lines hidden (view full) ---
818 /* better not try generic DMA on ATAPI devices it almost never works */
819 if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
820 (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
821 break;
822
823 /* if controller says its setup for DMA take the easy way out */
824 /* the downside is we dont know what DMA mode we are in */
825 if ((udmamode >= 0 || wdmamode > 1) &&
826 (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
827 ((device==ATA_MASTER) ?
828 ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
829 scp->mode[ATA_DEV(device)] = ATA_DMA;
830 return;
831 }
832
833 /* well, we have no support for this, but try anyways */
834 if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
835 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
836 ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
837 if (bootverbose)
838 ata_printf(scp, device,
839 "%s setting WDMA2 on generic chip\n",
840 (error) ? "failed" : "success");
841 if (!error) {
842 scp->mode[ATA_DEV(device)] = ATA_WDMA2;
--- 55 unchanged lines hidden (view full) ---
898 return 0;
899}
900
901void
902ata_dmastart(struct ata_softc *scp, int device,
903 struct ata_dmaentry *dmatab, int dir)
904{
905 scp->flags |= ATA_DMA_ACTIVE;
906 outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
907 outb(scp->bmaddr + ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
908 outb(scp->bmaddr + ATA_BMSTAT_PORT,
909 (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
910 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
911 outb(scp->bmaddr + ATA_BMCMD_PORT,
912 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
913}
914
915int
916ata_dmadone(struct ata_softc *scp)
917{
918 outb(scp->bmaddr + ATA_BMCMD_PORT,
919 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
920 scp->flags &= ~ATA_DMA_ACTIVE;
921 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
922}
923
924int
925ata_dmastatus(struct ata_softc *scp)
926{
927 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
928}
929
930static void
931cyrix_timing(struct ata_softc *scp, int devno, int mode)
932{
933 u_int32_t reg20 = 0x0000e132;
934 u_int32_t reg24 = 0x00017771;
935
936 switch (mode) {
937 case ATA_PIO0: reg20 = 0x0000e132; break;
938 case ATA_PIO1: reg20 = 0x00018121; break;
939 case ATA_PIO2: reg20 = 0x00024020; break;
940 case ATA_PIO3: reg20 = 0x00032010; break;
941 case ATA_PIO4: reg20 = 0x00040010; break;
942 case ATA_WDMA2: reg24 = 0x00002020; break;
943 case ATA_UDMA2: reg24 = 0x00911030; break;
944 }
945 outl(scp->bmaddr + (devno << 3) + 0x20, reg20);
946 outl(scp->bmaddr + (devno << 3) + 0x24, reg24);
947}
948
949static void
950promise_timing(struct ata_softc *scp, int devno, int mode)
951{
952 u_int32_t timing = 0;
953 struct promise_timing {
954 u_int8_t pa:4;
--- 161 unchanged lines hidden ---
2 * Copyright (c) 1998,1999,2000,2001 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
--- 11 unchanged lines hidden (view full) ---
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/ata/ata-dma.c 71335 2001-01-21 16:13:03Z sos $
29 */
30
31#include "pci.h"
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/bio.h>
35#include <sys/malloc.h>
36#include <sys/bus.h>
37#include <sys/disk.h>
38#include <sys/devicestat.h>
39#include <vm/vm.h>
40#include <vm/pmap.h>
41#if NPCI > 0
42#include <pci/pcivar.h>
43#endif
44#include <machine/bus.h>
45#include <dev/ata/ata-all.h>
46
47#if NPCI > 0
48
49/* prototypes */
50static void cyrix_timing(struct ata_softc *, int, int);
51static void promise_timing(struct ata_softc *, int, int);
52static void hpt_timing(struct ata_softc *, int, int);
--- 26 unchanged lines hidden (view full) ---
79{
80 device_t parent = device_get_parent(scp->dev);
81 int devno = (scp->channel << 1) + ATA_DEV(device);
82 int error;
83
84 /* set our most pessimistic default mode */
85 scp->mode[ATA_DEV(device)] = ATA_PIO;
86
87 if (!scp->bmaddr)
88 return;
89
90 /* if simplex controller, only allow DMA on primary channel */
91 if (scp->channel == 1) {
92 outb(scp->bmaddr + ATA_BMSTAT_PORT, inb(scp->bmaddr + ATA_BMSTAT_PORT) &
93 (ATA_BMSTAT_DMA_MASTER | ATA_BMSTAT_DMA_SLAVE));
94 if (inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_DMA_SIMPLEX) {
95 ata_printf(scp, device, "simplex device, DMA on primary only\n");
96 return;
97 }
98 }
99
100 /* DMA engine address alignment is usually 1 word (2 bytes) */
101 scp->alignment = 0x1;
102
--- 715 unchanged lines hidden (view full) ---
818 /* better not try generic DMA on ATAPI devices it almost never works */
819 if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
820 (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
821 break;
822
823 /* if controller says its setup for DMA take the easy way out */
824 /* the downside is we dont know what DMA mode we are in */
825 if ((udmamode >= 0 || wdmamode > 1) &&
826 (inb(scp->bmaddr + ATA_BMSTAT_PORT) &
827 ((device==ATA_MASTER) ?
828 ATA_BMSTAT_DMA_MASTER : ATA_BMSTAT_DMA_SLAVE))) {
829 scp->mode[ATA_DEV(device)] = ATA_DMA;
830 return;
831 }
832
833 /* well, we have no support for this, but try anyways */
834 if ((wdmamode >= 2 && apiomode >= 4) && scp->bmaddr) {
835 error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
836 ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
837 if (bootverbose)
838 ata_printf(scp, device,
839 "%s setting WDMA2 on generic chip\n",
840 (error) ? "failed" : "success");
841 if (!error) {
842 scp->mode[ATA_DEV(device)] = ATA_WDMA2;
--- 55 unchanged lines hidden (view full) ---
898 return 0;
899}
900
901void
902ata_dmastart(struct ata_softc *scp, int device,
903 struct ata_dmaentry *dmatab, int dir)
904{
905 scp->flags |= ATA_DMA_ACTIVE;
906 outl(scp->bmaddr + ATA_BMDTP_PORT, vtophys(dmatab));
907 outb(scp->bmaddr + ATA_BMCMD_PORT, dir ? ATA_BMCMD_WRITE_READ : 0);
908 outb(scp->bmaddr + ATA_BMSTAT_PORT,
909 (inb(scp->bmaddr + ATA_BMSTAT_PORT) |
910 (ATA_BMSTAT_INTERRUPT | ATA_BMSTAT_ERROR)));
911 outb(scp->bmaddr + ATA_BMCMD_PORT,
912 inb(scp->bmaddr + ATA_BMCMD_PORT) | ATA_BMCMD_START_STOP);
913}
914
915int
916ata_dmadone(struct ata_softc *scp)
917{
918 outb(scp->bmaddr + ATA_BMCMD_PORT,
919 inb(scp->bmaddr + ATA_BMCMD_PORT) & ~ATA_BMCMD_START_STOP);
920 scp->flags &= ~ATA_DMA_ACTIVE;
921 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
922}
923
924int
925ata_dmastatus(struct ata_softc *scp)
926{
927 return inb(scp->bmaddr + ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
928}
929
930static void
931cyrix_timing(struct ata_softc *scp, int devno, int mode)
932{
933 u_int32_t reg20 = 0x0000e132;
934 u_int32_t reg24 = 0x00017771;
935
936 switch (mode) {
937 case ATA_PIO0: reg20 = 0x0000e132; break;
938 case ATA_PIO1: reg20 = 0x00018121; break;
939 case ATA_PIO2: reg20 = 0x00024020; break;
940 case ATA_PIO3: reg20 = 0x00032010; break;
941 case ATA_PIO4: reg20 = 0x00040010; break;
942 case ATA_WDMA2: reg24 = 0x00002020; break;
943 case ATA_UDMA2: reg24 = 0x00911030; break;
944 }
945 outl(scp->bmaddr + (devno << 3) + 0x20, reg20);
946 outl(scp->bmaddr + (devno << 3) + 0x24, reg24);
947}
948
949static void
950promise_timing(struct ata_softc *scp, int devno, int mode)
951{
952 u_int32_t timing = 0;
953 struct promise_timing {
954 u_int8_t pa:4;
--- 161 unchanged lines hidden ---