⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wd.c

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*	$OpenBSD: wd.c,v 1.12 2000/04/10 07:06:16 csapuntz Exp $ *//*	$NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ *//* * Copyright (c) 1998 Manuel Bouyer.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *	notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *	notice, this list of conditions and the following disclaimer in the *	documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *	must display the following acknowledgement: *  This product includes software developed by Manuel Bouyer. * 4. The name of the author may not be used to endorse or promote products *	derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR 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. *//*- * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Charles M. Hannum and by Onno van der Linden. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *        This product includes software developed by the NetBSD *        Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its *    contributors may be used to endorse or promote products derived *    from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS * 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. */#if 0#include "rnd.h"#endif#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/conf.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/buf.h>#include <sys/uio.h>#include <sys/malloc.h>#include <sys/device.h>#include <sys/disklabel.h>#include <sys/disk.h>#include <sys/syslog.h>#include <sys/proc.h>#if NRND > 0#include <sys/rnd.h>#endif#include <sys/vnode.h>#include <vm/vm.h>#include <machine/intr.h>#include <machine/bus.h>#include <dev/ata/atareg.h>#include <dev/ata/atavar.h>#include <dev/ata/wdvar.h>#include <dev/ic/wdcreg.h>#include <sys/ataio.h>#if 0#include "locators.h"#endif#define	WAITTIME	(4 * hz)	/* time to wait for a completion */#define	WDIORETRIES_SINGLE 4	/* number of retries before single-sector */#define	WDIORETRIES	5	/* number of retries before giving up */#define	RECOVERYTIME hz/2	/* time to wait before retrying a cmd */#define	WDUNIT(dev)		DISKUNIT(dev)#ifndef PMON#define	WDPART(dev)		DISKPART(dev)#else#define	WDPART(dev)		RAW_PART#endif#define WDMINOR(unit, part)     DISKMINOR(unit, part)#define	MAKEWDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)#define	WDLABELDEV(dev)	(MAKEWDDEV(major(dev), WDUNIT(dev), RAW_PART))#define DEBUG_INTR   0x01#define DEBUG_XFERS  0x02#define DEBUG_STATUS 0x04#define DEBUG_FUNCS  0x08#define DEBUG_PROBE  0x10#ifdef WDCDEBUGextern int wdcdebug_wd_mask; /* init'ed in ata_wdc.c */#define WDCDEBUG_PRINT(args, level) \	if (wdcdebug_wd_mask & (level)) \		printf args#else#define WDCDEBUG_PRINT(args, level)#endif#ifdef PMON#define device_unref(x)#define readdisklabel(x1, x2, x3, x4, x5) "no label"#endifstruct wd_softc {	/* General disk infos */	struct device sc_dev;	struct disk sc_dk;	struct buf sc_q;	/* IDE disk soft states */	struct ata_bio sc_wdc_bio; /* current transfer */	struct buf *sc_bp; /* buf being transfered */	struct ata_drive_datas *drvp; /* Our controller's infos */	int openings;	struct ataparams sc_params;/* drive characteistics found */	int sc_flags;	  #define WDF_LOCKED	  0x01#define WDF_WANTED	  0x02#define WDF_WLABEL	  0x04 /* label is writable */#define WDF_LABELLING   0x08 /* writing label *//* * XXX Nothing resets this yet, but disk change sensing will when ATA-4 is * more fully implemented. */#define WDF_LOADED	  0x10 /* parameters loaded */#define WDF_WAIT	0x20 /* waiting for resources */#define WDF_LBA	 0x40 /* using LBA mode */	int sc_capacity;	int cyl; /* actual drive parameters */	int heads;	int sectors;	int retries; /* number of xfer retry */#if NRND > 0	rndsource_element_t	rnd_source;#endif	void *sc_sdhook;};#define sc_drive sc_wdc_bio.drive#define sc_mode sc_wdc_bio.mode#define sc_multi sc_wdc_bio.multi#define sc_badsect sc_wdc_bio.badsect#ifndef __OpenBSD__int	wdprobe		__P((struct device *, struct cfdata *, void *));#elseint	wdprobe		__P((struct device *, void *, void *));#endifvoid	wdattach	__P((struct device *, struct device *, void *));#ifndef PMONint     wddetach __P((struct device *, int));int     wdactivate __P((struct device *, enum devact));void    wdzeroref __P((struct device *));#endifint	wdprint	__P((void *, char *));struct cfattach wd_ca = {	sizeof(struct wd_softc), wdprobe, wdattach,#ifndef PMON	wddetach, wdactivate, wdzeroref#endif};#ifdef __OpenBSD__struct cfdriver wd_cd = {	NULL, "wd", DV_DISK};#elseextern struct cfdriver wd_cd;#endif/* * Glue necessary to hook WDCIOCCOMMAND into physio */struct wd_ioctl {	LIST_ENTRY(wd_ioctl) wi_list;	struct buf wi_bp;	struct uio wi_uio;	struct iovec wi_iov;	atareq_t wi_atareq;	struct wd_softc *wi_softc;};LIST_HEAD(, wd_ioctl) wi_head;struct	wd_ioctl *wi_find __P((struct buf *));void	wi_free __P((struct wd_ioctl *));struct	wd_ioctl *wi_get __P((void));void	wdioctlstrategy __P((struct buf *));void  wdgetdefaultlabel __P((struct wd_softc *, struct disklabel *));void  wdgetdisklabel __P((dev_t dev, struct wd_softc *, 				 struct disklabel *,				 struct cpu_disklabel *, int));void  wdstrategy	__P((struct buf *));void  wdstart	__P((void *));void  __wdstart	__P((struct wd_softc*, struct buf *));void  wdrestart __P((void*));int   wd_get_params __P((struct wd_softc *, u_int8_t, struct ataparams *));void  wd_flushcache __P((struct wd_softc *, int));void  wd_shutdown __P((void*));struct dkdriver wddkdriver = { wdstrategy };/* XXX: these should go elsewhere */cdev_decl(wd);bdev_decl(wd);#ifdef DKBADvoid	bad144intern __P((struct wd_softc *));#endif#ifndef PMON#define wdlock(wd)  disk_lock(&(wd)->sc_dk)#define wdunlock(wd)  disk_unlock(&(wd)->sc_dk)#else#define wdlock(wd)  (0)#define wdunlock(wd)#endif#define wdlookup(unit) (struct wd_softc *)device_lookup(&wd_cd, (unit))intwdprobe(parent, match_, aux)	struct device *parent;#ifndef __OpenBSD__	struct cfdata *match;#else	void *match_;#endif	void *aux;{	struct ata_atapi_attach *aa_link = aux;	struct cfdata *match = match_;	if (aa_link == NULL)		return 0;	if (aa_link->aa_type != T_ATA)		return 0;#ifndef __OpenBSD__	if (match->cf_loc[ATACF_CHANNEL] != ATACF_CHANNEL_DEFAULT &&	    match->cf_loc[ATACF_CHANNEL] != aa_link->aa_channel)		return 0;	if (match->cf_loc[ATACF_DRIVE] != ATACF_DRIVE_DEFAULT &&	    match->cf_loc[ATACF_DRIVE] != aa_link->aa_drv_data->drive)		return 0;#else	if (match->cf_loc[0] != -1 &&	    match->cf_loc[0] != aa_link->aa_channel)		return 0;	if (match->cf_loc[1] != -1 &&	    match->cf_loc[1] != aa_link->aa_drv_data->drive)		return 0;#endif	return 1;}voidwdattach(parent, self, aux)	struct device *parent, *self;	void *aux;{	struct wd_softc *wd = (void *)self;	struct ata_atapi_attach *aa_link= aux;	int i, blank;	char buf[41], c, *p, *q;	WDCDEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);	wd->openings = aa_link->aa_openings;	wd->drvp = aa_link->aa_drv_data;	strncpy(wd->drvp->drive_name, wd->sc_dev.dv_xname, 		sizeof(wd->drvp->drive_name) - 1);	wd->drvp->cf_flags = wd->sc_dev.dv_cfdata->cf_flags;	/* read our drive info */	if (wd_get_params(wd, at_poll, &wd->sc_params) != 0) {		printf("%s: IDENTIFY failed\n", wd->sc_dev.dv_xname);		return;	}	for (blank = 0, p = wd->sc_params.atap_model, q = buf, i = 0;	    i < sizeof(wd->sc_params.atap_model); i++) {		c = *p++;		if (c == '\0')			break;		if (c != ' ') {			if (blank) {				*q++ = ' ';				blank = 0;			}			*q++ = c;		} else			blank = 1;		}	*q++ = '\0';	printf(": <%s>\n", buf);	wdc_probe_caps(wd->drvp, &wd->sc_params);	wdc_print_caps(wd->drvp);	if ((wd->sc_params.atap_multi & 0xff) > 1) {		wd->sc_multi = wd->sc_params.atap_multi & 0xff;	} else {		wd->sc_multi = 1;	}	printf("%s: %d-sector PIO,", wd->sc_dev.dv_xname, wd->sc_multi);	/* Prior to ATA-4, LBA was optional. */	if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)		wd->sc_flags |= WDF_LBA;#if 0	/* ATA-4 requires LBA. */	if (wd->sc_params.atap_ataversion != 0xffff &&	    wd->sc_params.atap_ataversion >= WDC_VER_ATA4)		wd->sc_flags |= WDF_LBA;#endif	if ((wd->sc_flags & WDF_LBA) != 0) {		wd->sc_capacity =		    (wd->sc_params.atap_capacity[1] << 16) |		    wd->sc_params.atap_capacity[0];		printf(" LBA, %dMB, %d cyl, %d head, %d sec, %d sectors\n",		    wd->sc_capacity / (1048576 / DEV_BSIZE),		    wd->sc_params.atap_cylinders,		    wd->sc_params.atap_heads,		    wd->sc_params.atap_sectors,		    wd->sc_capacity);	} else {		wd->sc_capacity =		    wd->sc_params.atap_cylinders *		    wd->sc_params.atap_heads *		    wd->sc_params.atap_sectors;		printf(" CHS, %dMB, %d cyl, %d head, %d sec, %d sectors\n",		    wd->sc_capacity / (1048576 / DEV_BSIZE),		    wd->sc_params.atap_cylinders,		    wd->sc_params.atap_heads,		    wd->sc_params.atap_sectors,		    wd->sc_capacity);	}	WDCDEBUG_PRINT(("%s: atap_dmatiming_mimi=%d, atap_dmatiming_recom=%d\n",	    self->dv_xname, wd->sc_params.atap_dmatiming_mimi,	    wd->sc_params.atap_dmatiming_recom), DEBUG_PROBE);	/*	 * Initialize and attach the disk structure.	 */	wd->sc_dk.dk_driver = &wddkdriver;	wd->sc_dk.dk_name = wd->sc_dev.dv_xname;#ifndef PMON	disk_attach(&wd->sc_dk);#endif	wd->sc_wdc_bio.lp = wd->sc_dk.dk_label;	wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);	if (wd->sc_sdhook == NULL)		printf("%s: WARNING: unable to establish shutdown hook\n",		    wd->sc_dev.dv_xname); #if NRND > 0	rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,			  RND_TYPE_DISK, 0);#endif}#ifndef PMONintwdactivate(self, act)        struct device *self;        enum devact act;{        int rv = 0;        switch (act) {        case DVACT_ACTIVATE:                break;        case DVACT_DEACTIVATE:                /*                 * Nothing to do; we key off the device's DVF_ACTIVATE.                 */                break;        }        return (rv);}intwddetach(self, flags)        struct device *self;        int flags;{        struct wd_softc *sc = (struct wd_softc *)self;        struct buf *dp, *bp;        int s, bmaj, cmaj, mn;	/* Remove unprocessed buffers from queue */	s = splbio();	for (dp = &sc->sc_q; (bp = dp->b_actf) != NULL; ) {		dp->b_actf = bp->b_actf;				bp->b_error = ENXIO;		bp->b_flags |= B_ERROR;		biodone(bp);	}	splx(s);        /* locate the major number */        mn = WDMINOR(self->dv_unit, 0);        for (bmaj = 0; bmaj < nblkdev; bmaj++)                if (bdevsw[bmaj].d_open == wdopen)			vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);        for (cmaj = 0; cmaj < nchrdev; cmaj++)                if (cdevsw[cmaj].d_open == wdopen)			vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);	/* Get rid of the shutdown hook. */	if (sc->sc_sdhook != NULL)		shutdownhook_disestablish(sc->sc_sdhook);#if NRND > 0        /* Unhook the entropy source. */        rnd_detach_source(&sc->rnd_source);#endif        return (0);}voidwdzeroref(self)        struct device *self;{        struct wd_softc *sc = (struct wd_softc *)self;        /* Detach disk. */        disk_detach(&sc->sc_dk);}#endif /* PMON *//* * Read/write routine for a buffer.  Validates the arguments and schedules the * transfer.  Does not wait for the transfer to complete. */voidwdstrategy(bp)	struct buf *bp;{	struct wd_softc *wd;	int s;	wd = wdlookup(WDUNIT(bp->b_dev));	if (wd == NULL) {		bp->b_error = ENXIO;		goto bad;	}	WDCDEBUG_PRINT(("wdstrategy (%s)\n", wd->sc_dev.dv_xname),	    DEBUG_XFERS);		/* Valid request?  */	if (bp->b_blkno < 0 ||	    (bp->b_bcount % wd->sc_dk.dk_label->d_secsize) != 0 ||	    (bp->b_bcount / wd->sc_dk.dk_label->d_secsize) >= (1 << NBBY)) {		bp->b_error = EINVAL;		goto bad;	}		/* If device invalidated (e.g. media change, door open), error. */	if ((wd->sc_flags & WDF_LOADED) == 0) {		bp->b_error = EIO;		goto bad;	}	/* If it's a null transfer, return immediately. */	if (bp->b_bcount == 0)		goto done;	/*	 * Do bounds checking, adjust transfer. if error, process.	 * If end of partition, just return.	 */#ifndef PMON	if (WDPART(bp->b_dev) != RAW_PART &&	    bounds_check_with_label(bp, wd->sc_dk.dk_label, wd->sc_dk.dk_cpulabel,	    (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)		goto done;#endif	/* Queue transfer on drive, activate drive and controller if idle. */	s = splbio();	disksort(&wd->sc_q, bp);	wdstart(wd);	splx(s);	device_unref(&wd->sc_dev);	return;bad:	bp->b_flags |= B_ERROR;done:	/* Toss transfer; we're done early. */	bp->b_resid = bp->b_bcount;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -