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

📄 sd.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$OpenBSD: sd.c,v 1.32 1998/10/04 01:37:55 millert Exp $	*//*	$NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $	*//* * Copyright (c) 1994, 1995, 1997 Charles M. Hannum.  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 Charles M. Hannum. * 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. *//* * Originally written by Julian Elischer (julian@dialix.oz.au) * for TRW Financial Systems for use under the MACH(2.5) operating system. * * TRW Financial Systems, in accordance with their agreement with Carnegie * Mellon University, makes this software available to CMU to distribute * or use in any manner that they see fit as long as this message is kept with * the software. For this reason TFS also grants any other persons or * organisations permission to use or modify this software. * * TFS supplies this software to be publicly redistributed * on the understanding that TFS is not responsible for the correct * functioning of this software in any circumstances. * * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 */#include <sys/types.h>#include <sys/param.h>#include <sys/systm.h>#include <sys/kernel.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/ioctl.h>#if 0#include <sys/mtio.h>#endif#include "queue.h"#include <sys/buf.h>#include <sys/uio.h>#include <sys/malloc.h>#include <sys/errno.h>#if 0#include <sys/disklabel.h>#include <sys/disk.h>#include <sys/device.h>#include <sys/conf.h>#else#include <sys/proc.h>#include <sys/device.h>#endif#include <sys/scsiio.h>#include "scsi_all.h"#include "scsi_disk.h"#include "scsiconf.h"extern void disksort __P((struct buf *, struct buf *));#define	SDOUTSTANDING	4#define	SDRETRIES	4#define	SDUNIT(dev)			(dev & 0xff)struct sd_softc {	struct device sc_dev;	struct disk {		char	*dk_name;		int	dk_openmask;		int	dk_copenmask;		int	dk_bopenmask;	} sc_dk;	int flags;#define	SDF_LOCKED	0x01#define	SDF_WANTED	0x02#define	SDF_WLABEL	0x04		/* label is writable */#define	SDF_LABELLING	0x08		/* writing label */#define	SDF_ANCIENT	0x10		/* disk is ancient; for minphys */	struct scsi_link *sc_link;	/* contains our targ, lun, etc. */	struct disk_parms {		u_char heads;		/* number of heads */		u_short cyls;		/* number of cylinders */		u_char sectors;		/* number of sectors/track */		int blksize;		/* number of bytes/sector */		u_long disksize;	/* total number sectors */	} params;#define sd_secsize params.blksize	struct disk_name {		char vendor[9];		/* disk vendor/manufacturer */		char product[17];	/* disk product model */		char revision[5];	/* drive/firmware revision */	} name;	struct buf buf_queue;	u_int8_t type;};struct scsi_mode_sense_data {	struct scsi_mode_header header;	struct scsi_blk_desc blk_desc;	union disk_pages pages;};int sdopen __P((dev_t dev, int flags, int mode, struct proc *));int sdread __P((dev_t dev, struct uio *uio, int flag));int sdwrite __P((dev_t dev, struct uio *uio, int flag));int sdclose __P((dev_t dev, int flag, int mode, struct proc *)); void sdstrategy __P((struct buf *));int	sdmatch __P((struct device *, void *, void *));void	sdattach __P((struct device *, struct device *, void *));void	sdstart __P((void *));void	sddone __P((struct scsi_xfer *));int	sd_get_optparms __P((struct sd_softc *, int, struct disk_parms *));int	sd_get_parms __P((struct sd_softc *, int));static	int sd_mode_sense __P((struct sd_softc *, struct scsi_mode_sense_data *,			      int, int));void	viscpy __P((u_char *, u_char *, int));struct cfattach sd_ca = {        sizeof(struct sd_softc), sdmatch, sdattach};struct cfdriver sd_cd = {        NULL, "sd", DV_DISK}; struct scsi_device sd_switch = {	NULL,			/* Use default error handler */	sdstart,		/* have a queue, served by this */	NULL,			/* have no async handler */	sddone,			/* deal with stats at interrupt time */};struct scsi_inquiry_pattern sd_patterns[] = {	{T_DIRECT, T_FIXED,	 "",         "",                 ""},	{T_DIRECT, T_REMOV,	 "",         "",                 ""},	{T_OPTICAL, T_FIXED,	 "",         "",                 ""},	{T_OPTICAL, T_REMOV,	 "",         "",                 ""},};intsdmatch(parent, match, aux)	struct device *parent;	void *match, *aux;{	struct scsibus_attach_args *sa = aux;	int priority;	(void)scsi_inqmatch(sa->sa_inqbuf,	    (caddr_t)sd_patterns, sizeof(sd_patterns)/sizeof(sd_patterns[0]),	    sizeof(sd_patterns[0]), &priority);	return (priority);}/* * The routine called by the low level scsi routine when it discovers * a device suitable for this driver. */voidsdattach(parent, self, aux)	struct device *parent, *self;	void *aux;{	int error;	struct sd_softc *sd = (void *)self;	struct disk_parms *dp = &sd->params;	struct scsibus_attach_args *sa = aux;	struct scsi_link *sc_link = sa->sa_sc_link;	SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: "));	/*	 * Store information needed to contact our base driver	 */	sd->sc_link = sc_link;	sd->type = (sa->sa_inqbuf->device & SID_TYPE);	sc_link->device = &sd_switch;	sc_link->device_softc = sd;	if (sc_link->openings > SDOUTSTANDING)		sc_link->openings = SDOUTSTANDING;	/*	 * Initialize and attach the disk structure.	 */	sd->sc_dk.dk_name = sd->sc_dev.dv_xname;	/*	 * Use the subdriver to request information regarding	 * the drive. We cannot use interrupts yet, so the	 * request must specify this.	 */	printf("\n");	printf("%s: ", sd->sc_dev.dv_xname);	if ((sd->sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {		error = scsi_start(sd->sc_link, SSS_START,				   SCSI_AUTOCONF | SCSI_IGNORE_ILLEGAL_REQUEST |				   SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);	} else		error = 0;	/* Fill in name struct for spoofed label */	viscpy(sd->name.vendor, sa->sa_inqbuf->vendor, 8);	viscpy(sd->name.product, sa->sa_inqbuf->product, 16);	viscpy(sd->name.revision, sa->sa_inqbuf->revision, 4);	if (error || sd_get_parms(sd, SCSI_AUTOCONF) != 0)		printf("drive offline\n");	else	        printf("%ldMB, %d cyl, %d head, %d sec, %d bytes/sec, %ld sec total\n",		    dp->disksize / (1048576 / dp->blksize), dp->cyls,		    dp->heads, dp->sectors, dp->blksize, dp->disksize);}/* * open the device. Make sure the partition info is a up-to-date as can be. */intsdopen(dev, flag, fmt, p)	dev_t dev;	int flag, fmt;	struct proc *p;{	struct sd_softc *sd;	struct scsi_link *sc_link;	int unit, part;	int error;	unit = SDUNIT(dev);	if (unit >= sd_cd.cd_ndevs)		return ENXIO;	sd = sd_cd.cd_devs[unit];	if (!sd)		return ENXIO;	sc_link = sd->sc_link;	if (sd->sc_dk.dk_openmask != 0) {		/*		 * If any partition is open, but the disk has been invalidated,		 * disallow further opens.		 */		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {			error = EIO;			goto bad3;		}	} else {		/* Check that it is still responding and ok. */		error = scsi_test_unit_ready(sc_link,					     SCSI_IGNORE_ILLEGAL_REQUEST |					     SCSI_IGNORE_MEDIA_CHANGE |					     SCSI_IGNORE_NOT_READY);		if (error)			goto bad3;		/* Start the pack spinning if necessary. */		if ((sc_link->quirks & SDEV_NOSTARTUNIT) == 0) {			error = scsi_start(sc_link, SSS_START,					   SCSI_IGNORE_ILLEGAL_REQUEST |					   SCSI_IGNORE_MEDIA_CHANGE |					   SCSI_SILENT);			if (error)				goto bad3;		}		sc_link->flags |= SDEV_OPEN;		/* Lock the pack in. */		error = scsi_prevent(sc_link, PR_PREVENT,				     SCSI_IGNORE_ILLEGAL_REQUEST |				     SCSI_IGNORE_MEDIA_CHANGE);		if (error)			goto bad;		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {			sc_link->flags |= SDEV_MEDIA_LOADED;			/* Load the physical device parameters. */			if (sd_get_parms(sd, 0) != 0) {				error = ENXIO;				goto bad2;			}			SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));		}	}	/* Insure only one open at a time. */	switch (fmt) {	case S_IFCHR:		sd->sc_dk.dk_copenmask |= (1 << part);		break;	case S_IFBLK:		sd->sc_dk.dk_bopenmask |= (1 << part);		break;	}	sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask;	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));	return 0;bad2:	sc_link->flags &= ~SDEV_MEDIA_LOADED;bad:	if (sd->sc_dk.dk_openmask == 0) {		scsi_prevent(sc_link, PR_ALLOW,		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);		sc_link->flags &= ~SDEV_OPEN;	}bad3:	return error;}/* * close the device.. only called if we are the LAST occurence of an open * device.  Convenient now but usually a pain. */int sdclose(dev, flag, fmt, p)	dev_t dev;	int flag, fmt;	struct proc *p;{	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(dev)];	int part = 0;	switch (fmt) {	case S_IFCHR:		sd->sc_dk.dk_copenmask &= ~(1 << part);		break;	case S_IFBLK:		sd->sc_dk.dk_bopenmask &= ~(1 << part);		break;	}	sd->sc_dk.dk_openmask = sd->sc_dk.dk_copenmask | sd->sc_dk.dk_bopenmask;	if (sd->sc_dk.dk_openmask == 0) {		/* XXX Must wait for I/O to complete! */		scsi_prevent(sd->sc_link, PR_ALLOW,		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);		sd->sc_link->flags &= ~(SDEV_OPEN|SDEV_MEDIA_LOADED);		if (sd->sc_link->flags & SDEV_EJECTING) {		    scsi_start(sd->sc_link, SSS_STOP|SSS_LOEJ, 0);		    sd->sc_link->flags &= ~SDEV_EJECTING;		}	}	return 0;}/* * Actually translate the requested transfer into one the physical driver * can understand.  The transfer is described by a buf and will include * only one physical transfer. */voidsdstrategy(bp)	struct buf *bp;{	struct sd_softc *sd = sd_cd.cd_devs[SDUNIT(bp->b_dev)];

⌨️ 快捷键说明

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