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

📄 hddev.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 CC
字号:
#include <lib/config.h>#include <lib/root.h>#include <lib/string.h>#include <init/ctor.h>#include <asm/io.h>#include <asm/irq.h>#include "hddev.h"#include "hdreg.h"#include "parttab.h"#undef trace #define trace(...)#define LBA 1#define DEFAULTMULTSECT 4#define MAXHD 2static int multcount[MAXHD];static hddev_t hddev;static inline int whichdrv(dev_t dev){	return minor(dev)/PARTPERHD; }hddev_t::hddev_t(){	curisr = &hddev_t::nullisr;	allocirq(&hddev_t::isr, this, HDIRQ);	/* bochs doesn't work if lack the following line,	   see bochs/iodev/harddrv.cc */	outbp(0,0x3f6);}hddev_t::~hddev_t(){}__ctor(PRIDEV, SUBANY, harddisk){	construct(&hddev);	blkdevvec[HDMAJOR] = &hddev;}extern int readlatch();static inline void readsect(char * buf){	insw(HDDATA, buf, SECTSIZE/2);}static inline void writesect(char * buf){	outsw(HDDATA, buf, SECTSIZE/2);}static char * string[] = {"err","idx","ecc","drq","seek","werr","rdy","bsy"};static void showstat(){	int stat = inbp(HDSTAT);	for (int i = 0; i < 8; i++, stat >>= 1)		printf("%s:%s ", string[i], (stat & 1) ? "ON" : "__"); 	printf("\n");}static int ioerror(){	int mask = BSYSTAT | RDYSTAT | SEEKSTAT | ERRSTAT;	int good = RDYSTAT | SEEKSTAT;	int num = 1024;	while (num--)		if ((inbp(HDSTAT) & mask) == good)			return 0;	showstat();	return 1;}static void waitdrq(){	for(int i = 0; i < 1000; i++)		if (inbp(HDSTAT) & DRQSTAT)			return;	showstat();	warn("waitdrq failed\n");}static void waitrdy(){	int retry = 1024;	while (retry--) {		int stat = inbp(HDSTAT);		if (!stat) return;		if ((stat & (BSYSTAT|RDYSTAT)) == RDYSTAT) return;	}	showstat();	warn("waitrdy failed\n");	}/* sector start from 1 not 0 */void hddev_t::rwsect(int cmd, int drv, int s, int n){	trace("hdrw: drv:%d startsect:%d nsect:%d\n", drv, s, n);	waitrdy();	outbp(s&0xff, HD0700);	outbp((s>>8)&0xff, HD1508);	outbp((s>>16)&0xff, HD2316);	outbp(0xE0|(drv<<4)|((s>>24)&0x0f), HDDRV2724);	outbp(n, HDNSECT);	outbp(cmd, HDCMD);}void hddev_t::isr(int irqno){	(*curisr)(this, irqno);}void hddev_t::nullisr(int irqno){	warn("unexpected isr\n");}static int mmm = 1;/* IO INT RD */ void hddev_t::readisr(int irqno){	trace("readisr\n");	assert(curreq && curreq->cmd == BREAD);	if (ioerror()) {		curreq->error(mmm);		return;	}	waitdrq();	char * sect;	foreachsect(sect, curreq, mmm) {		readsect(sect);	}	curreq->advance(mmm);	if (!curreq->more()) {		curisr = &hddev_t::nullisr;		endcurreq();	}}/* WR IO INT */void hddev_t::writeisr(int irqno){	trace("writeisr\n");	assert(curreq && curreq->cmd == BWRITE);	if (ioerror()) {		curreq->error(mmm);		return;	}	curreq->advance(mmm);	if (!curreq->more()) {		curisr = &hddev_t::nullisr;		endcurreq();		return;	}	waitdrq();	char * sect;	foreachsect(sect, curreq, mmm)		writesect(sect);}void hddev_t::setmultisr(int irqno){	int stat = inbp(HDSTAT);	if (stat & (BSYSTAT | ERRSTAT)) {		printf("harddisk set multiple mode failed\n");		return;	}	int dev = 0;	printf("hd%c enabled %d-sector multiple mode\n", 		dev+'a', multcount[dev]);}void hddev_t::docurreq(){	int cmd, drv, s, n;	parttab_t * p;	if (curreq->cmd == BREAD) {		cmd = WINREAD;		curisr = &hddev_t::readisr;	} else {		cmd = WINWRITE;		curisr = &hddev_t::writeisr;	}	dev_t dev = curreq->dev;	if (minor(dev) >= MAXHD * PARTPERHD) {		warn("invalid dev:%x\n", dev);		goto error;	}	p = parttab + minor(dev);	drv = whichdrv(dev);	s = curreq->startsect + p->startsect;	n = curreq->nsect;	allege(n <= 255);	if ((s < p->startsect) || (p->startsect + p->nsect < s + n)) {		warn("start:%d,nsect:%d out of range on dev %x start:%ld,"		"nsect:%ld)\n", s, n, curreq->dev, p->startsect, p->nsect);		goto error;	}        rwsect(cmd, drv, s, n);	if (cmd == WINWRITE) {		waitdrq();		char * sect;		foreachsect(sect, curreq, mmm)			writesect(sect);	}	return;error:  curreq->error();	endcurreq();	curisr = &hddev_t::nullisr;}int hddev_t::ioctl(dev_t dev, int req, ulong arg){	return -1;}ulong hddev_t::getsize(dev_t dev){	if (minor(dev) > hdnum * PARTPERHD)		return 0;	return parttab[minor(dev)].nsect << SECTBITS;}

⌨️ 快捷键说明

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