diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files.i386 | 4 | ||||
-rw-r--r-- | sys/i386/conf/files.i386 | 4 | ||||
-rw-r--r-- | sys/i386/isa/wd.c | 125 | ||||
-rw-r--r-- | sys/i386/isa/wdreg.h | 104 | ||||
-rw-r--r-- | sys/pci/ide_pci.c | 817 | ||||
-rw-r--r-- | sys/pci/ide_pcireg.h | 63 | ||||
-rw-r--r-- | sys/pci/pcisupport.c | 11 |
7 files changed, 1111 insertions, 17 deletions
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index fe46c28..8a79192 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.167 1997/07/24 23:45:17 fsmp Exp $ +# $Id: files.i386,v 1.168 1997/07/25 11:53:20 phk Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/*.[chyl]" \ @@ -293,4 +293,4 @@ gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate gnu/i386/isa/dgb.c optional dgb device-driver -pci/wd82371.c optional wd device-driver +pci/ide_pci.c optional wd device-driver diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index fe46c28..8a79192 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $Id: files.i386,v 1.167 1997/07/24 23:45:17 fsmp Exp $ +# $Id: files.i386,v 1.168 1997/07/25 11:53:20 phk Exp $ # aic7xxx_asm optional ahc device-driver \ dependency "$S/dev/aic7xxx/*.[chyl]" \ @@ -293,4 +293,4 @@ gnu/i386/fpemul/reg_u_sub.s optional gpl_math_emulate gnu/i386/fpemul/wm_shrx.s optional gpl_math_emulate gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate gnu/i386/isa/dgb.c optional dgb device-driver -pci/wd82371.c optional wd device-driver +pci/ide_pci.c optional wd device-driver diff --git a/sys/i386/isa/wd.c b/sys/i386/isa/wd.c index 09beae0..09231ad 100644 --- a/sys/i386/isa/wd.c +++ b/sys/i386/isa/wd.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)wd.c 7.2 (Berkeley) 5/9/91 - * $Id: wd.c,v 1.131 1997/07/01 00:22:45 bde Exp $ + * $Id: wd.c,v 1.132 1997/07/20 14:10:17 bde Exp $ */ /* TODO: @@ -110,6 +110,7 @@ extern void wdstart(int ctrlr); /* can't handle that in all cases */ #define WDOPT_32BIT 0x8000 #define WDOPT_SLEEPHACK 0x4000 +#define WDOPT_DMA 0x2000 #define WDOPT_FORCEHD(x) (((x)&0x0f00)>>8) #define WDOPT_MULTIMASK 0x00ff @@ -173,12 +174,17 @@ struct disk { #define DKFL_32BIT 0x00100 /* use 32-bit i/o mode */ #define DKFL_MULTI 0x00200 /* use multi-i/o mode */ #define DKFL_BADSCAN 0x00400 /* report all errors */ +#define DKFL_USEDMA 0x00800 /* use DMA for data transfers */ +#define DKFL_DMA 0x01000 /* using DMA on this transfer-- DKFL_SINGLE + * overrides this + */ struct wdparams dk_params; /* ESDI/IDE drive/controller parameters */ int dk_dkunit; /* disk stats unit number */ int dk_multi; /* multi transfers */ int dk_currentiosize; /* current io size */ struct diskgeom dk_dd; /* device configuration data */ struct diskslices *dk_slices; /* virtual drives */ + void *dk_dmacookie; /* handle for DMA services */ }; #define WD_COUNT_RETRIES @@ -215,6 +221,7 @@ static int wdsetctlr(struct disk *du); #if 0 static int wdwsetctlr(struct disk *du); #endif +static int wdsetmode(int mode, void *wdinfo); static int wdgetctlr(struct disk *du); static void wderror(struct buf *bp, struct disk *du, char *mesg); static void wdflushirq(struct disk *du, int old_ipl); @@ -381,6 +388,7 @@ wdattach(struct isa_device *dvp) int unit, lunit; struct isa_device *wdup; struct disk *du; + struct wdparams *wp; if (dvp->id_unit >= NWDC) return (0); @@ -443,6 +451,8 @@ wdattach(struct isa_device *dvp) dvp->id_unit, unit, lunit, sizeof du->dk_params.wdp_model, du->dk_params.wdp_model); + if (du->dk_flags & DKFL_USEDMA) + printf(", DMA"); if (du->dk_flags & DKFL_32BIT) printf(", 32-bit"); if (du->dk_multi > 1) @@ -465,6 +475,17 @@ wdattach(struct isa_device *dvp) du->dk_dd.d_nsectors, du->dk_dd.d_secsize); + if (bootverbose) { + wp = &du->dk_params; + printf( +"wd%d: ATA INQUIRE valid = %04x, dmamword = %04x, apio = %04x, udma = %04x\n", + du->dk_lunit, + wp->wdp_atavalid, + wp->wdp_dmamword, + wp->wdp_eidepiomodes, + wp->wdp_udmamode); + } + /* * Start timeout routine for this drive. * XXX timeout should be per controller. @@ -818,7 +839,19 @@ wdstart(int ctrlr) count = 1; du->dk_currentiosize = 1; } else { - if( (count > 1) && (du->dk_multi > 1)) { + if((du->dk_flags & DKFL_USEDMA) && + wddma.wdd_dmaverify(du->dk_dmacookie, + (void *)((int)bp->b_un.b_addr + + du->dk_skip * DEV_BSIZE), + du->dk_bc, + bp->b_flags & B_READ)) { + du->dk_flags |= DKFL_DMA; + if( bp->b_flags & B_READ) + command = WDCC_READ_DMA; + else + command = WDCC_WRITE_DMA; + du->dk_currentiosize = count; + } else if( (count > 1) && (du->dk_multi > 1)) { du->dk_flags |= DKFL_MULTI; if( bp->b_flags & B_READ) { command = WDCC_READ_MULTI; @@ -854,6 +887,14 @@ wdstart(int ctrlr) if(du->dk_dkunit >= 0) { dk_busy |= 1 << du->dk_dkunit; } + + if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) { + wddma.wdd_dmaprep(du->dk_dmacookie, + (void *)((int)bp->b_un.b_addr + + du->dk_skip * DEV_BSIZE), + du->dk_bc, + bp->b_flags & B_READ); + } while (wdcommand(du, cylin, head, sector, count, command) != 0) { wderror(bp, du, @@ -884,6 +925,12 @@ wdstart(int ctrlr) */ du->dk_timeout = 1 + 3; + /* if this is a DMA op, start DMA and go away until it's done. */ + if ((du->dk_flags & (DKFL_DMA|DKFL_SINGLE)) == DKFL_DMA) { + wddma.wdd_dmastart(du->dk_dmacookie); + return; + } + /* If this is a read operation, just go away until it's done. */ if (bp->b_flags & B_READ) return; @@ -988,6 +1035,15 @@ wdintr(int unit) du = wddrives[dkunit(bp->b_dev)]; du->dk_timeout = 0; + /* finish off DMA. ignore errors if we're not using it. */ + if (du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) { + if ((wddma.wdd_dmadone(du->dk_dmacookie) != WDDS_INTERRUPT) && + !(du->dk_flags & DKFL_USEDMA)) { + wderror(bp, du, "wdintr: DMA failure"); + du->dk_status |= WDCS_ERR; /* XXX totally bogus err */ + } + } + if (wdwait(du, 0, TIMEOUT) < 0) { wderror(bp, du, "wdintr: timeout waiting for status"); du->dk_status |= WDCS_ERR; /* XXX */ @@ -1014,7 +1070,12 @@ oops: * XXX bogus inb() here, register 0 is assumed and intr status * is reset. */ - if( (du->dk_flags & DKFL_MULTI) && (inb(du->dk_port) & WDERR_ABORT)) { + if((du->dk_flags & DKFL_DMA ) && + (inb(du->dk_port) & WDERR_ABORT)) { + wderror(bp, du, "reverting to PIO mode"); + du->dk_flags |= ~DKFL_USEDMA; + } else if((du->dk_flags & DKFL_MULTI) && + (inb(du->dk_port) & WDERR_ABORT)) { wderror(bp, du, "reverting to non-multi sector mode"); du->dk_multi = 1; } @@ -1052,6 +1113,7 @@ oops: * If this was a successful read operation, fetch the data. */ if (((bp->b_flags & (B_READ | B_ERROR)) == B_READ) + && !(du->dk_flags & DKFL_DMA) && wdtab[unit].b_active) { int chk, dummy, multisize; multisize = chk = du->dk_currentiosize * DEV_BSIZE; @@ -1093,6 +1155,20 @@ oops: dk_wds[du->dk_dkunit] += chk >> 6; } + /* final cleanup on DMA */ + if (((bp->b_flags & B_ERROR) == 0) + && (du->dk_flags & DKFL_DMA) + && wdtab[unit].b_active) { + int iosize; + + iosize = du->dk_currentiosize * DEV_BSIZE; + + du->dk_bc -= iosize; + + if (du->dk_dkunit >= 0) + dk_wds[du->dk_dkunit] += iosize >> 6; + } + outt: if (wdtab[unit].b_active) { if ((bp->b_flags & B_ERROR) == 0) { @@ -1124,7 +1200,7 @@ outt: done: ; /* done with this transfer, with or without error */ - du->dk_flags &= ~DKFL_SINGLE; + du->dk_flags &= ~(DKFL_SINGLE|DKFL_DMA); TAILQ_REMOVE(&wdtab[unit].controller_queue, bp, b_act); wdtab[unit].b_errcnt = 0; bp->b_resid = bp->b_bcount - du->dk_skip * DEV_BSIZE; @@ -1441,7 +1517,7 @@ wdcommand(struct disk *du, u_int cylinder, u_int head, u_int sector, outb(wdc + wd_sector, sector + 1); outb(wdc + wd_seccnt, count); } - if (wdwait(du, command == WDCC_DIAGNOSE || command == WDCC_IDC + if (wdwait(du, (command == WDCC_DIAGNOSE || command == WDCC_IDC) ? 0 : WDCS_READY, TIMEOUT) < 0) return (1); outb(wdc + wd_command, command); @@ -1557,6 +1633,25 @@ wdwsetctlr(struct disk *du) #endif /* + * gross little callback function for wdddma interface. returns 1 for + * success, 0 for failure. + */ +static int +wdsetmode(int mode, void *wdinfo) +{ + int i; + struct disk *du; + + du = wdinfo; + if (bootverbose) + printf("wdsetmode() setting transfer mode to %02x\n", mode); + i = wdcommand(du, 0, 0, mode, WDFEA_SETXFER, + WDCC_FEATURES) == 0 && + wdwait(du, WDCS_READY, TIMEOUT) == 0; + return i; +} + +/* * issue READP to drive to ask it what it is. */ static int @@ -1711,6 +1806,21 @@ failed: du->dk_multi = wp->wdp_nsecperint & 0xff; wdsetmulti(du); + du->dk_dmacookie = NULL; + /* + * check drive's DMA capability + */ + /* does user want this? */ + if ((du->cfg_flags & WDOPT_DMA) && + /* have we got a DMA controller? */ + (wddma.wdd_candma && + (du->dk_dmacookie = wddma.wdd_candma(du->dk_port, + du->dk_unit))) && + /* can said drive do DMA? */ + (wddma.wdd_dmainit(du->dk_dmacookie, wp, wdsetmode, du))) + + du->dk_flags |= DKFL_USEDMA; + #ifdef WDDEBUG printf( "\nwd(%d,%d): wdgetctlr: gc %x cyl %d trk %d sec %d type %d sz %d model %s\n", @@ -2061,6 +2171,9 @@ wdreset(struct disk *du) { int wdc, err = 0; + if ((du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) && du->dk_dmacookie) + wddma.wdd_dmadone(du->dk_dmacookie); + wdc = du->dk_port; (void)wdwait(du, 0, TIMEOUT); outb(wdc + wd_ctlr, WDCTL_IDS | WDCTL_RST); @@ -2112,7 +2225,7 @@ wdtimeout(void *cdu) if(timeouts++ == 5) wderror((struct buf *)NULL, du, "Last time I say: interrupt timeout. Probably a portable PC."); - else if(timeouts++ < 5) + else if(timeouts < 5) wderror((struct buf *)NULL, du, "interrupt timeout"); wdunwedge(du); wdflushirq(du, x); diff --git a/sys/i386/isa/wdreg.h b/sys/i386/isa/wdreg.h index 3ad2403..f7dfa488 100644 --- a/sys/i386/isa/wdreg.h +++ b/sys/i386/isa/wdreg.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)wdreg.h 7.1 (Berkeley) 5/9/91 - * $Id$ + * $Id: wdreg.h,v 1.17 1997/02/22 09:37:27 peter Exp $ */ /* @@ -122,6 +122,8 @@ #define WDCC_READ_MULTI 0xC4 /* read multiple */ #define WDCC_WRITE_MULTI 0xC5 /* write multiple */ #define WDCC_SET_MULTI 0xC6 /* set multiple count */ +#define WDCC_READ_DMA 0xC8 /* read using DMA */ +#define WDCC_WRITE_DMA 0xCA /* write using DMA */ #define WDCC_EXTDCMD 0xE0 /* send extended command */ @@ -130,6 +132,7 @@ #define WDFEA_RCACHE 0xAA /* read cache enable */ #define WDFEA_WCACHE 0x02 /* write cache enable */ +#define WDFEA_SETXFER 0x03 /* set transfer mode */ #define WD_STEP 0 /* winchester- default 35us step */ @@ -140,10 +143,14 @@ * read parameters command returns this: */ struct wdparams { + /* + * XXX partly based on DRAFT X3T13/1153D rev 14. + * by the time you read this it will have changed. + */ /* drive info */ short wdp_config; /* general configuration bits */ u_short wdp_cylinders; /* number of cylinders */ - short wdp_reserved; + short wdp_reserved2; u_short wdp_heads; /* number of heads */ short wdp_unfbytespertrk; /* number of unformatted bytes/track */ short wdp_unfbytes; /* number of unformatted bytes/sector */ @@ -159,8 +166,58 @@ struct wdparams { short wdp_necc; /* ecc bytes appended */ char wdp_rev[8]; /* firmware revision */ char wdp_model[40]; /* model name */ - short wdp_nsecperint; /* sectors per interrupt */ + char wdp_nsecperint; /* sectors per interrupt */ + char wdp_vendorunique1; short wdp_usedmovsd; /* can use double word read/write? */ + char wdp_vendorunique2; + char wdp_capability; /* various capability bits */ + short wdp_cap_validate; /* validation for above */ + char wdp_vendorunique3; + char wdp_opiomode; /* PIO modes 0-2 */ + char wdp_vendorunique4; + char wdp_odmamode; /* old DMA modes, not in ATA-3 */ + short wdp_atavalid; /* validation for newer fields */ + short wdp_currcyls; + short wdp_currheads; + short wdp_currsectors; + short wdp_currsize0; + short wdp_currsize1; + char wdp_currmultsect; + char wdp_multsectvalid; + int wdp_lbasize; + short wdp_dmasword; /* obsolete in ATA-3 */ + short wdp_dmamword; /* multiword DMA modes */ + short wdp_eidepiomodes; /* advanced PIO modes */ + short wdp_eidedmamin; /* fastest possible DMA timing */ + short wdp_eidedmanorm; /* recommended DMA timing */ + short wdp_eidepioblind; /* fastest possible blind PIO */ + short wdp_eidepioacked; /* fastest possible IORDY PIO */ + short wdp_reserved69; + short wdp_reserved70; + short wdp_reserved71; + short wdp_reserved72; + short wdp_reserved73; + short wdp_reserved74; + short wdp_queuelen; + short wdp_reserved76; + short wdp_reserved77; + short wdp_reserved78; + short wdp_reserved79; + short wdp_versmaj; + short wdp_versmin; + short wdp_featsupp1; + short wdp_featsupp2; + short wdp_featsupp3; + short wdp_featenab1; + short wdp_featenab2; + short wdp_featenab3; + short wdp_udmamode; /* UltraDMA modes */ + short wdp_erasetime; + short wdp_enherasetime; + short wdp_apmlevel; + short wdp_reserved92[34]; + short wdp_rmvcap; + short wdp_securelevel; }; /* @@ -179,12 +236,18 @@ int wdformat(struct buf *bp); * To use this: * For each drive which you might want to do DMA on, call wdd_candma() * to get a cookie. If it returns a null pointer, then the drive - * can't do DMA. + * can't do DMA. Then call wdd_dmainit() to initialize the controller + * and drive. wdd_dmainit should leave PIO modes operational, though + * perhaps with suboptimal performance. * - * Set up the transfer be calling wdd_dmaprep(). The cookie is what + * Check the transfer by calling wdd_dmaverify(). The cookie is what * you got before; vaddr is the virtual address of the buffer to be * written; len is the length of the buffer; and direction is either - * B_READ or B_WRITE. + * B_READ or B_WRITE. This function verifies that the DMA hardware is + * capable of handling the request you've made. + * + * Setup the transfer by calling wdd_dmaprep(). This takes the same + * paramaters as wdd_dmaverify(). * * Send a read/write DMA command to the drive. * @@ -199,6 +262,8 @@ int wdformat(struct buf *bp); struct wddma { void *(*wdd_candma) /* returns a cookie if can do DMA */ __P((int ctlr, int drive)); + int (*wdd_dmaverify) /* verify that request is DMA-able */ + __P((void *cookie, char *vaddr, u_long len, int direction)); int (*wdd_dmaprep) /* prepare DMA hardware */ __P((void *cookie, char *vaddr, u_long len, int direction)); void (*wdd_dmastart) /* begin DMA transfer */ @@ -207,12 +272,39 @@ struct wddma { __P((void *cookie)); int (*wdd_dmastatus) /* return status of DMA */ __P((void *cookie)); + int (*wdd_dmainit) /* initialize controller and drive */ + __P((void *cookie, + struct wdparams *wp, + int(wdcmd)__P((int mode, void *wdinfo)), + void *wdinfo)); }; +/* logical status bits returned by wdd_dmastatus */ #define WDDS_ACTIVE 0x0001 #define WDDS_ERROR 0x0002 #define WDDS_INTERRUPT 0x0004 +#if 0 +/* XXX are these now useless? */ +/* local defines for ATA timing modes */ +#define WDDMA_GRPMASK 0xf0 +/* flow-controlled PIO modes */ +#define WDDMA_PIO 0x10 +#define WDDMA_PIO3 0x10 +#define WDDMA_PIO4 0x11 +/* multi-word DMA timing modes */ +#define WDDMA_MDMA 0x20 +#define WDDMA_MDMA0 0x20 +#define WDDMA_MDMA1 0x21 +#define WDDMA_MDMA2 0x22 + +/* Ultra DMA timing modes */ +#define WDDMA_UDMA 0x30 +#define WDDMA_UDMA0 0x30 +#define WDDMA_UDMA1 0x31 +#define WDDMA_UDMA2 0x32 +#endif + extern struct wddma wddma; #endif /* KERNEL */ diff --git a/sys/pci/ide_pci.c b/sys/pci/ide_pci.c new file mode 100644 index 0000000..e8e13c7 --- /dev/null +++ b/sys/pci/ide_pci.c @@ -0,0 +1,817 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: wd82371.c,v 1.5.2.1 1996/11/16 21:19:51 phk Exp $ + * $Id$ + */ + +#include "pci.h" +#if NPCI > 0 + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/queue.h> +#include <sys/proc.h> +#include <sys/buf.h> +#include <sys/malloc.h> +#include <sys/kernel.h> +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <machine/pmap.h> /* for vtophys */ + +#include <i386/isa/wdreg.h> + +#include <pci/pcivar.h> +#include <pci/pcireg.h> +#include <pci/ide_pcireg.h> + +struct ide_pci_cookie; /* structs vendor_fns, ide_pci_cookie are recursive */ + +struct vendor_fns { + int (*vendor_dmainit) /* initialize DMA controller and drive */ + (struct ide_pci_cookie *cookie, + struct wdparams *wp, + int(*wdcmd)(int, void *), + void *); + + void (*vendor_status) /* prints off DMA timing info */ + (int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type); +}; + +/* + * XXX the fact that this list keeps all kinds of info on PCI controllers + * is pretty grotty-- much of this should be replaced by a proper integration + * of PCI probes into the wd driver. + * XXX if we're going to support native-PCI controllers, we also need to + * keep the address of the IDE control block register, which is something wd.c + * needs to know, which is why this info is in the wrong place. + */ + +struct ide_pci_cookie { + LIST_ENTRY(ide_pci_cookie) le; + int iobase_wd; + int unit; + int iobase_bm; /* SFF-8038 control registers */ + pcici_t tag; + pcidi_t type; + struct ide_pci_prd *prd; + struct vendor_fns vs; +}; + +struct ide_pci_softc { + LIST_HEAD(, ide_pci_cookie) cookies; +}; + +static int +generic_dmainit(struct ide_pci_cookie *cookie, + struct wdparams *wp, + int(*wdcmd)(int, void *), + void *wdinfo); +static void +generic_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type); +static void +via_571_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type); +static void +intel_piix_dump_drive(char *ctlr, + int sitre, + int word40, + int word44, + int drive); +static void +intel_piix_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type); + +static struct ide_pci_cookie * +mkcookie(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type, + struct vendor_fns *vp); + + + +static void ide_pci_attach(pcici_t tag, int unit); +static void *ide_pci_candma(int, int); +static int ide_pci_dmainit(void *, + struct wdparams *, + int (*)(int, void *), + void *); +static int ide_pci_dmaverify(void *, char *, u_long, int); +static int ide_pci_dmasetup(void *, char *, u_long, int); +static void ide_pci_dmastart(void *); +static int ide_pci_dmadone(void *); +static int ide_pci_status(void *); +static int ide_pci_timing(void *, int); + +static struct ide_pci_softc softc; + +static int ide_pci_softc_cookies_initted = 0; + +/* + * PRD_ALLOC_SIZE should be something that will not be allocated across a 64k + * boundary. + * PRD_MAX_SEGS is defined to be the maximum number of segments required for + * a transfer on an IDE drive, for an xfer that is linear in virtual memory. + * PRD_BUF_SIZE is the size of the buffer needed for a PRD table. + */ +#define PRD_ALLOC_SIZE PAGE_SIZE +#define PRD_MAX_SEGS ((256 * 512 / PAGE_SIZE) + 1) +#define PRD_BUF_SIZE PRD_MAX_SEGS * 8 + +static void *prdbuf = 0; +static void *prdbuf_next = 0; + +/* + * Hardware specific IDE controller code. All vendor-specific code + * for handling IDE timing and other chipset peculiarities should be + * encapsulated here. + */ + +/* Generic busmastering PCI-IDE */ + +static int +generic_dmainit(struct ide_pci_cookie *cookie, + struct wdparams *wp, + int(*wdcmd)(int, void *), + void *wdinfo) +{ + int mode, r; + /* + * XXX punt on the whole timing issue by looking for either a + * drive programmed for both PIO4 and mDMA2 (which use similar + * timing) or a drive in an UltraDMA mode (hopefully all + * controllers have separate timing for UDMA). one hopes that if + * the drive's DMA mode has been configured by the BIOS, the + * controller's has also. this code may eventually be replaced + * by gunk in the hw-specific code to deal with specific + * controllers. + */ + /* XXX way too sick and twisted conditional */ + if (!((((wp->wdp_atavalid & 2) == 2) && + ((wp->wdp_dmamword & 0x404) == 0x404) && + ((wp->wdp_eidepiomodes & 2) == 2)) || + (((wp->wdp_atavalid & 4) == 4) && + (wp->wdp_udmamode == 4)))) + return 0; + +#if 0 + /* + * XXX flesh this out into real code that actually + * does something-- this was just testing gunk. + */ + if (((wp->wdp_atavalid & 0x4) == 0x4) && + (wp->wdp_udmamode == 4)) { + printf("UDMA mode\n"); + mode = 0x42; /* XXX where's the #defines... */ + } + else { + printf("MDMA mode\n"); + mode = 0x24; + } + + r = wdcmd(mode, wdinfo); + printf("dmainit out like we expect\n"); + if (!r) + return 0; +#endif + return 1; +} + +static void +generic_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type) +{ + printf("generic_status: no PCI IDE timing info available\n"); +} + +static struct vendor_fns vs_generic = +{ + generic_dmainit, + generic_status +}; + +/* VIA Technologies "82C571" PCI-IDE controller core */ + +static void +via_571_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type) +{ + unsigned int word40[5]; + int i; + + /* XXX how to handle four calls for one controller? */ + if (iobase_wd != 0x1f0 || unit != 0) + return; + + for (i=0; i<5; i++) { + word40[i] = pci_conf_read(tag, i * 4 + 0x40); + } + + printf("via_571_status: Primary IDE prefetch/postwrite %s/%s\n", + word40[0] & 0x8000 ? "enabled" : "disabled", + word40[0] & 0x4000 ? "enabled" : "disabled"); + printf("via_571_status: Secondary IDE prefetch/postwrite %s/%s\n", + word40[0] & 0x2000 ? "enabled" : "disabled", + word40[0] & 0x1000 ? "enabled" : "disabled"); + + printf("via_571_status: Master %d read/%d write IRDY# wait states\n", + (word40[1] & 0x40) >> 6, + (word40[1] & 0x20) >> 5); + printf("via_571_status: busmaster status read retry %s\n", + (word40[1] & 0x10) ? "enabled" : "disabled"); + + for (i=0; i<4; i++) + printf("via_571_status: %s drive %d setup=%d active=%d recovery=%d\n", + i < 2 ? "primary" : "secondary", + i & 1, + ((word40[3] >> ((3 - i) * 2)) & 3) + 1, + ((word40[2] >> (((3 - i) * 8) + 4)) & 0x0f) + 1, + ((word40[2] >> ((3 - i) * 8)) & 0x0f) + 1); + + + /* XXX could go on and do UDMA status for '586B */ +} + +static struct vendor_fns vs_via_571 = +{ + generic_dmainit, + via_571_status +}; + +/* Intel PIIX, PIIX3, and PIIX4 IDE controller subfunctions */ + +static void +intel_piix_dump_drive(char *ctlr, + int sitre, + int word40, + int word44, + int drive) +{ + char *ms; + + if (!sitre) + ms = "master/slave"; + else if (drive == 0) + ms = "master"; + else + ms = "slave"; + + if (sitre || drive == 0) + printf("intel_piix_status: %s %s sample = %d, %s recovery = %d\n", + ctlr, + ms, + 5 - ((sitre && drive) ? + ((word44 >> 2) & 3) : + ((word40 >> 12) & 3)), + ms, + 4 - ((sitre && drive) ? + ((word44 >> 0) & 3) : + ((word40 >> 8) & 3))); + + word40 >>= (drive * 4); + printf("\ +intel_piix_status: %s %s fastDMAonly %s, pre/post %s,\n\ +intel_piix_status: IORDY sampling %s,\n\ +intel_piix_status: fast PIO %s%s\n", + ctlr, + (drive == 0) ? "master" : "slave", + (word40 & 8) ? "enabled" : "disabled", + (word40 & 4) ? "enabled" : "disabled", + (word40 & 2) ? "enabled" : "disabled", + (word40 & 1) ? "enabled" : "disabled", + ((word40 & 9) == 9) ? " (overridden by fastDMAonly)" : "" ); + + /* XXX extend to dump 82371AB's UltraDMA modes */ +} + +static void +intel_piix_status(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type) +{ + unsigned int word40, word44; + int sitre; + + /* XXX how to handle four calls for one controller? */ + if (iobase_wd != 0x1f0 || unit != 0) + return; + + word40 = pci_conf_read(tag, 0x40); + word44 = pci_conf_read(tag, 0x44); + + sitre = word40 & 0x4000; + + intel_piix_dump_drive("primary", sitre, word40 & 0xffff, word44 & 0x0f, 0); + intel_piix_dump_drive("primary", sitre, word40 & 0xffff, word44 & 0x0f, 1); + intel_piix_dump_drive("secondary", + sitre, + (word40 >> 16) & 0xffff, + (word44 >> 4) & 0x0f,0); + intel_piix_dump_drive("secondary", + sitre, + (word40 >> 16) & 0xffff, + (word44 >> 4) & 0x0f,1); +} + +static struct vendor_fns vs_intel_piix = +{ + generic_dmainit, + intel_piix_status +}; + +/* Generic SFF-8038i code-- all code below here, except for PCI probes, + * more or less conforms to the SFF-8038i spec as extended for PCI. + * There should be no code that goes beyond that feature set below. + */ + +/* XXX mkcookie is overloaded with too many parameters */ + +static struct ide_pci_cookie * +mkcookie(int iobase_wd, + int unit, + int iobase_bm, + pcici_t tag, + pcidi_t type, + struct vendor_fns *vp) +{ + struct ide_pci_cookie *cp; + + cp = malloc(sizeof *cp, M_DEVBUF, M_NOWAIT); + if (!cp) return cp; + + cp->iobase_wd = iobase_wd; + cp->unit = unit; + cp->tag = tag; + cp->type = type; + cp->iobase_bm = iobase_bm; + bcopy(vp, &cp->vs, sizeof(struct vendor_fns)); + + if (!prdbuf) { + prdbuf = malloc(PRD_ALLOC_SIZE, M_DEVBUF, M_NOWAIT); + if (!prdbuf) { + FREE(cp, M_DEVBUF); + return 0; + } + if (((int)prdbuf >> PAGE_SHIFT) ^ + (((int)prdbuf + PRD_ALLOC_SIZE - 1) >> PAGE_SHIFT)) { + printf("ide_pci: prdbuf straddles page boundary, no DMA"); + FREE(cp, M_DEVBUF); + FREE(prdbuf, M_DEVBUF); + return 0; + } + + prdbuf_next = prdbuf; + } + cp->prd = prdbuf_next; + (char *)prdbuf_next += PRD_BUF_SIZE; + + if ((char *)prdbuf_next > ((char *)prdbuf + PRD_ALLOC_SIZE)) + panic("ide_pci: too many prdbufs allocated"); + + if (bootverbose) + printf("ide_pci: mkcookie %04x:%d: PRD vstart = %08x vend = %08x\n", + iobase_wd, unit, (int)cp->prd, ((int)cp->prd)+PRD_BUF_SIZE); + LIST_INSERT_HEAD(&softc.cookies, cp, le); + return cp; +} + +static char * +ide_pci_probe(pcici_t tag, pcidi_t type) +{ + int data = pci_conf_read(tag, PCI_CLASS_REG); + + switch (data & PCI_CLASS_MASK) { + + case PCI_CLASS_MASS_STORAGE: + if ((data & PCI_SUBCLASS_MASK) == 0x00010000) { + if (type == 0x71118086) + return ("Intel PIIX4 Bus-master IDE controller"); + if (type == 0x70108086) + return ("Intel PIIX3 Bus-master IDE controller"); + if (type == 0x12308086) + return ("Intel PIIX Bus-master IDE controller"); + if (type == 0x05711106) + return ("VIA 82C586x (Apollo) Bus-master IDE controller"); + if (data & 0x8000) + return ("PCI IDE controller (busmaster capable)"); +/* + * XXX leave this out for now, to allow CMD640B hack to work. said + * hack should be better integrated, or something. + */ +#if 0 + else + return ("PCI IDE controller (not busmaster capable)"); +#endif + } + }; + return ((char*)0); +} + +static void +ide_pci_attach(pcici_t tag, int unit) +{ + u_long idetm; + int class; + int bmista; + int iobase_wd, iobase_bm; + int cmd; + struct vendor_fns *vp; + pcidi_t type; + + if (unit) return; + + /* is it busmaster capable? bail if not */ + class = pci_conf_read(tag, PCI_CLASS_REG); + if (!(class & 0x8000)) return; + + /* is it enabled and is busmastering turned on? */ + cmd = pci_conf_read(tag, PCI_COMMAND_STATUS_REG); + if ((cmd & 5) != 5) return; + + /* set up vendor-specific stuff */ + type = pci_conf_read(tag, PCI_ID_REG); + + switch (type) { + case 0x71118086: + case 0x70108086: + case 0x12308086: + /* Intel PIIX, PIIX3, PIIX4 */ + vp = &vs_intel_piix; + break; + + case 0x5711106: + /* VIA Apollo chipset family */ + vp = &vs_via_571; + break; + + default: + /* everybody else */ + vp = &vs_generic; + break; + } + + iobase_wd = (class & 0x100) ? + (pci_conf_read(tag, 0x10) & 0xfffc) : + 0x1f0; + iobase_bm = pci_conf_read(tag, 0x20) & 0xfffc; + + if (!ide_pci_softc_cookies_initted) { + LIST_INIT(&softc.cookies); + ide_pci_softc_cookies_initted = 1; + } + + bmista = inb(iobase_bm + BMISTA_PORT); + + if (bootverbose) + printf("ide_pci: busmaster 0 status: %02x from port: %08x\n", + bmista, iobase_bm+BMISTA_PORT); + + if (!(bmista & BMISTA_DMA0CAP)) + printf("ide_pci: warning, ide0:0 not configured for DMA?\n"); + mkcookie(iobase_wd, 0, iobase_bm, tag, type, vp); + if (bootverbose) + vp->vendor_status(iobase_wd, 0, iobase_bm, tag, type); + + if (!(bmista & BMISTA_DMA1CAP)) + printf("ide_pci: warning, ide0:1 not configured for DMA?\n"); + mkcookie(iobase_wd, 1, iobase_bm, tag, type, vp); + if (bootverbose) + vp->vendor_status(iobase_wd, 1, iobase_bm, tag, type); + + if (bmista & BMISTA_SIMPLEX) { + printf("ide_pci: primary is simplex-only, no DMA on secondary\n"); + } else { + iobase_wd = (class & 0x400) ? + (pci_conf_read(tag, 0x10) & 0xfffc) : + 0x170; + iobase_bm += SFF8038_CTLR_1; + bmista = inb(iobase_bm + BMISTA_PORT); + + if (bootverbose) + printf("ide_pci: busmaster 1 status: %02x from port: %08x\n", + bmista, iobase_bm+BMISTA_PORT); + + if (bmista & BMISTA_SIMPLEX) { + printf("ide_pci: secondary is simplex-only, no DMA on secondary\n"); + } else { + if (!(bmista & BMISTA_DMA0CAP)) + printf("ide_pci: warning, ide1:0 not configured for DMA?\n"); + mkcookie(iobase_wd, 0, iobase_bm, tag, type, vp); + if (bootverbose) + vp->vendor_status(iobase_wd, 0, iobase_bm, tag, type); + if (!(bmista & BMISTA_DMA1CAP)) + printf("ide_pci: warning, ide1:1 not configured for DMA?\n"); + mkcookie(iobase_wd, 1, iobase_bm, tag, type, vp); + if (bootverbose) + vp->vendor_status(iobase_wd, 1, iobase_bm, tag, type); + } + } + + wddma.wdd_candma = ide_pci_candma; + wddma.wdd_dmainit = ide_pci_dmainit; + wddma.wdd_dmaverify = ide_pci_dmaverify; + wddma.wdd_dmaprep = ide_pci_dmasetup; + wddma.wdd_dmastart = ide_pci_dmastart; + wddma.wdd_dmadone = ide_pci_dmadone; + wddma.wdd_dmastatus = ide_pci_status; +} + +static u_long ide_pci_count; + +static struct pci_device ide_pci_device = { + "ide_pci", + ide_pci_probe, + ide_pci_attach, + &ide_pci_count, + 0 +}; + +DATA_SET(pcidevice_set, ide_pci_device); + +/* + * Return a cookie if we can do DMA on the specified (iobase_wd, unit). + */ +static void * +ide_pci_candma(int iobase_wd, int unit) +{ + struct ide_pci_cookie *cp; + + cp = softc.cookies.lh_first; + while(cp) { + if (cp->unit == unit && cp->iobase_wd == iobase_wd) + break; + cp = cp->le.le_next; + } + + return cp; +} + +/* + * Initialize controller and drive for DMA operation, including timing modes. + * Uses data passed from the wd driver and a callback function to initialize + * timing modes on the drive. + */ +static int +ide_pci_dmainit(void *cookie, + struct wdparams *wp, + int(*wdcmd)(int, void *), + void *wdinfo) +{ + struct ide_pci_cookie *cp = cookie; + + return(cp->vs.vendor_dmainit(cp, wp, wdcmd, wdinfo)); +} +/* + * Verify that controller can handle a dma request for cp. Should + * not affect any hardware or driver state. + */ +static int +ide_pci_dmaverify(void *xcp, char *vaddr, u_long count, int dir) +{ + int badfu; + + /* + * check for nonaligned or odd-length Stuff + */ + badfu = ((unsigned int)vaddr & 1) || (count & 1); +#if 1 + if (badfu) { + printf("ide_pci: dmaverify odd vaddr or length, "); + printf("vaddr = %08x length = %08x\n", (int)vaddr, count); + } +#endif + /* + * XXX should perhaps be checking that length of generated table + * does not exceed space available, but that Would Be Hairy + */ + return (!badfu); +} + +/* + * Set up DMA for cp. It is the responsibility of the caller + * to ensure that the controller is idle before this routine + * is called. + */ +static int +ide_pci_dmasetup(void *xcp, char *vaddr, u_long count, int dir) +{ + struct ide_pci_cookie *cp = xcp; + struct ide_pci_prd *prd; + int i; + u_long pgresid; + int iobase_bm; + static int trashmore; + static int *trashmore_p = 0; + + + prd = cp->prd; + i = 0; + + iobase_bm = cp->iobase_bm; + /* + * ensure that 0-length transfers get a PRD that won't smash much + */ + if (!trashmore_p) + trashmore_p = (void *)vtophys(&trashmore); + + prd[0].prd_base = (unsigned int)trashmore_p; + prd[0].prd_count = 0x80000002; + + if (count == 0) { + printf("ide_pci: dmasetup 0-length transfer, "); + printf("vaddr = %08x length = %08x\n", (int)vaddr, count); + } + + /* + * XXX the PRD generation code is somewhat ugly and will not + * port easily to big endian systems. + * + * but it works. + */ + + /* + * Deal with transfers that don't start on a page + * boundary. + */ + pgresid = (u_long)vaddr % PAGE_SIZE; + if (pgresid) { + prd[i].prd_base = vtophys(vaddr); + if (count >= (PAGE_SIZE - pgresid)) + prd[i].prd_count = PAGE_SIZE - pgresid; + else + prd[i].prd_count = count; + vaddr += prd[i].prd_count; + count -= prd[i].prd_count; + i++; + } + + /* + * We have now ensured that vaddr is page-aligned, so just + * step through the pages adding each one onto the list. + */ + while(count) { + u_long phys, n; + + phys = vtophys(vaddr); + n = ((count > PAGE_SIZE) ? PAGE_SIZE : count); + /* + * If the current page is physically contiguous with + * whatever we have in the previous PRD, just tack it + * onto the end. + * CAVEAT: due to a hardware deficiency, PRDs + * cannot cross a 64K boundary. + * XXX should we bother with this collapsing? scattered + * pages appear to be the common case anyway. + */ + if (i > 0 + && (phys == prd[i - 1].prd_base + prd[i - 1].prd_count) + && ((prd[i - 1].prd_base & 0xffff) + + prd[i - 1].prd_count + n) <= 65535) { + + prd[i - 1].prd_count += n; + } else { + prd[i].prd_base = phys; + prd[i].prd_count = n; + i++; + if (i >= PRD_MAX_SEGS) + panic("wd82371: too many segments\n"); + } + count -= n; + vaddr += n; + } + + /* put a sign at the edge of the cliff... */ + prd[(i>0) ? (i-1) : 0].prd_count |= PRD_EOT_BIT; + + if (i == 0) + printf("ide_pci: dmasetup 0-length PRD???\n"); + + /* Set up PRD base register */ + outl(iobase_bm + BMIDTP_PORT, vtophys(prd)); + + /* Set direction of transfer */ + if (dir == B_READ) { + outb(iobase_bm + BMICOM_PORT, BMICOM_READ_WRITE); + } else { + outb(iobase_bm + BMICOM_PORT, 0); + } + + /* Clear interrupt and error bits */ + outb(iobase_bm + BMISTA_PORT, + (inb(iobase_bm + BMISTA_PORT) + | (BMISTA_INTERRUPT | BMISTA_DMA_ERROR))); + + /* printf("dma enable: iobase_bm = %08x command/status = %08x pointer = %08x\n", iobase_bm, inl(iobase_bm + BMICOM_PORT), inl(iobase_bm + BMIDTP_PORT)); */ + + /* printf("P"); */ + + return 0; +} + +static void +ide_pci_dmastart(void *xcp) +{ + struct ide_pci_cookie *cp = xcp; + int iobase_bm; + + iobase_bm = cp->iobase_bm; + + outb(iobase_bm + BMICOM_PORT, + inb(iobase_bm + BMICOM_PORT) | BMICOM_STOP_START); + + /* printf("["); */ +} + +static int +ide_pci_dmadone(void *xcp) +{ + struct ide_pci_cookie *cp = xcp; + int iobase_bm, status; + + status = ide_pci_status(xcp); + iobase_bm = cp->iobase_bm; + + outb(iobase_bm + BMICOM_PORT, + inb(iobase_bm + BMICOM_PORT) & ~BMICOM_STOP_START); + + /* printf("]"); */ + + return status; +} + +static int +ide_pci_status(void *xcp) +{ + struct ide_pci_cookie *cp = xcp; + int iobase_bm, status, bmista; + + status = 0; + iobase_bm = cp->iobase_bm; + + bmista = inb(iobase_bm + BMISTA_PORT); + + /* printf("dmastatus: iobase_bm = %08x status = %02x command/status = %08x pointer = %08x\n", iobase_bm, bmista, inl(iobase_bm + BMICOM_PORT), inl(iobase_bm + BMIDTP_PORT)); */ + + if (bmista & BMISTA_INTERRUPT) + status |= WDDS_INTERRUPT; + if (bmista & BMISTA_DMA_ERROR) + status |= WDDS_ERROR; + if (bmista & BMISTA_DMA_ACTIVE) + status |= WDDS_ACTIVE; + + /* printf( (bmista == BMISTA_INTERRUPT)? "?":"!"); */ + + return status; +} + +#endif /* NPCI > 0 */ diff --git a/sys/pci/ide_pcireg.h b/sys/pci/ide_pcireg.h new file mode 100644 index 0000000..769645f --- /dev/null +++ b/sys/pci/ide_pcireg.h @@ -0,0 +1,63 @@ +/* + * Copyright 1996 Massachusetts Institute of Technology + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that both the above copyright notice and this + * permission notice appear in all copies, that both the above + * copyright notice and this permission notice appear in all + * supporting documentation, and that the name of M.I.T. not be used + * in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. M.I.T. makes + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS + * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT + * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * From: wd82371reg.h,v 1.3 1997/02/22 09:44:15 peter Exp $ + * $Id$ + */ + +#ifndef _PCI_IDEPCIREG_H_ +#define _PCI_IDEPCIREG_H_ 1 + +/* Ports are for controller 0. Add SFF8038_CTLR_1 for controller 1. */ +#define SFF8038_CTLR_1 8 + +/* Contents of BMICOM register */ +#define BMICOM_PORT 0 +#define BMICOM_READ_WRITE 0x0008 /* false = read, true = write */ +#define BMICOM_STOP_START 0x0001 /* false = stop, true = start */ + +/* Contents of BMISTA register */ +#define BMISTA_PORT 2 +#define BMISTA_SIMPLEX 0x0080 /* 1 = controller cannot DMA on both + channels simultaneously */ +#define BMISTA_DMA1CAP 0x0040 /* true = drive 1 can DMA */ +#define BMISTA_DMA0CAP 0x0020 /* true = drive 0 can DMA */ +#define BMISTA_INTERRUPT 0x0004 +#define BMISTA_DMA_ERROR 0x0002 +#define BMISTA_DMA_ACTIVE 0x0001 + +#define BMIDTP_PORT 4 /* use outl */ + +struct ide_pci_prd { + u_int32_t prd_base; + u_int32_t prd_count; +}; + +#define PRD_EOT_BIT 0x80000000 + +#endif /* _PCI_IDEPCIREG_H_ */ diff --git a/sys/pci/pcisupport.c b/sys/pci/pcisupport.c index 1108d30..ac78356 100644 --- a/sys/pci/pcisupport.c +++ b/sys/pci/pcisupport.c @@ -1,6 +1,6 @@ /************************************************************************** ** -** $Id: pcisupport.c,v 1.47 1997/05/30 21:01:47 se Exp $ +** $Id: pcisupport.c,v 1.48 1997/07/18 19:47:23 se Exp $ ** ** Device driver for DEC/INTEL PCI chipsets. ** @@ -167,8 +167,11 @@ chipset_probe (pcici_t tag, pcidi_t type) return ("Intel 82437FX PCI cache memory controller"); case 0x122e8086: return ("Intel 82371FB PCI to ISA bridge"); +#if 0 + /* ide_pci takes care of this now */ case 0x12308086: return ("Intel 82371FB IDE interface"); +#endif case 0x12508086: return ("Intel 82439"); case 0x04061039: @@ -179,12 +182,18 @@ chipset_probe (pcici_t tag, pcidi_t type) return ("SiS 85c601"); case 0x70008086: return ("Intel 82371SB PCI to ISA bridge"); +#if 0 + /* ide_pci takes care of this now */ case 0x70108086: return ("Intel 82371SB IDE interface"); +#endif case 0x71108086: return ("Intel 82371AB PCI to ISA bridge"); +#if 0 + /* ide_pci takes care of this now */ case 0x71118086: return ("Intel 82371AB IDE interface"); +#endif case 0x71128086: return ("Intel 82371AB USB host controller"); case 0x71138086: |