entry();
}
+static int
+diskready(void)
+{
+ uchar status = inb(IDE_DATA_PRIMARY+IDE_REG_STATUS);
+ return (status & (IDE_BSY|IDE_DRDY)) == IDE_DRDY;
+}
+
void
waitdisk(void)
{
// Wait for disk ready.
- while((inb(IDE_DATA_PRIMARY+IDE_REG_STATUS) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
+ while(!diskready())
;
}
outb(IDE_DATA_PRIMARY+IDE_REG_LBA0, offset & 0xff);
outb(IDE_DATA_PRIMARY+IDE_REG_LBA1, (offset >> 8) & 0xff);
outb(IDE_DATA_PRIMARY+IDE_REG_LBA2, (offset >> 16) & 0xff);
- outb(IDE_DATA_PRIMARY+IDE_REG_DISK, ((offset >> 24) & 0x0f) | IDE_DISK_LBA);
+ outb(IDE_DATA_PRIMARY+IDE_REG_DISK,
+ ((offset >> 24) & 0x0f) | IDE_DISK_LBA);
outb(IDE_DATA_PRIMARY+IDE_REG_COMMAND, IDE_CMD_READ);
// Read data.
// + Directories: inode with special contents (list of other inodes!)
// + Names: paths like /usr/rtm/xv6/fs.c for convenient naming.
//
-// This file contains the low-level file system manipulation
+// This file contains the low-level file system manipulation
// routines. The (higher-level) system call implementations
// are in sysfile.c.
#define min(a, b) ((a) < (b) ? (a) : (b))
static void itrunc(struct inode*);
-struct superblock sb; // there should be one per dev, but we run with one dev
+
+// there should be one per dev, but we run with one dev
+struct superblock sb;
// Read the super block.
void
readsb(int dev, struct superblock *sb)
{
struct buf *bp;
-
+
bp = bread(dev, 1);
memmove(sb, bp->data, sizeof(*sb));
brelse(bp);
bzero(int dev, int bno)
{
struct buf *bp;
-
+
bp = bread(dev, bno);
memset(bp->data, 0, BSIZE);
log_write(bp);
brelse(bp);
}
-// Blocks.
+// Blocks.
// Allocate a zeroed disk block.
static uint
{
initlock(&icache.lock, "icache");
readsb(dev, &sb);
- cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d inodestart %d bmap start %d\n", sb.size,
- sb.nblocks, sb.ninodes, sb.nlog, sb.logstart, sb.inodestart, sb.bmapstart);
+ cprintf(
+ "sb: size %d nblocks %d ninodes %d nlog %d logstart %d "
+ "inodestart %d bmap start %d\n", sb.size, sb.nblocks, sb.ninodes,
+ sb.nlog, sb.logstart, sb.inodestart, sb.bmapstart);
}
static struct inode* iget(uint dev, uint inum);
//
// The content (data) associated with each inode is stored
// in blocks on the disk. The first NDIRECT block numbers
-// are listed in ip->addrs[]. The next NINDIRECT blocks are
+// are listed in ip->addrs[]. The next NINDIRECT blocks are
// listed in block ip->addrs[NDIRECT].
// Return the disk block address of the nth block in inode ip.
ip->addrs[i] = 0;
}
}
-
+
if(ip->addrs[NDIRECT]){
bp = bread(ip->dev, ip->addrs[NDIRECT]);
a = (uint*)bp->data;
de.inum = inum;
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
panic("dirlink");
-
+
return 0;
}
-// On-disk file system format.
+// On-disk file system format.
// Both the kernel and user programs use this header file.
-
#define ROOTINO 1 // root i-number
#define BSIZE 512 // block size
// Disk layout:
-// [ boot block | super block | log | inode blocks | free bit map | data blocks ]
+// [ boot block | super block | log | inode blocks | free bit map
+// | data blocks ]
//
-// mkfs computes the super block and builds an initial file system. The super describes
-// the disk layout:
+// mkfs computes the super block and builds an initial file system.
+// The super describes the disk layout:
struct superblock {
uint size; // Size of file system image (blocks)
uint nblocks; // Number of data blocks
static int havedisk1;
static void idestart(struct buf*);
+static int
+diskready(int *status)
+{
+ *status = inb(IDE_DATA_PRIMARY+IDE_REG_STATUS);
+ return (*status & (IDE_BSY|IDE_DRDY)) == IDE_DRDY;
+}
+
// Wait for IDE disk to become ready.
static int
idewait(int checkerr)
{
int r;
- while(((r = inb(IDE_DATA_PRIMARY+IDE_REG_STATUS)) & (IDE_BSY|IDE_DRDY)) != IDE_DRDY)
+ while(!diskready(&r))
;
if(checkerr && (r & (IDE_DF|IDE_ERR)) != 0)
return -1;
idewait(0);
outb(IDE_CTRL_PRIMARY+IDE_REG_CTRL, 0); // generate interrupt
- outb(IDE_DATA_PRIMARY+IDE_REG_SECTORS, sector_per_block); // number of sectors
+ outb(IDE_DATA_PRIMARY+IDE_REG_SECTORS, sector_per_block);
outb(IDE_DATA_PRIMARY+IDE_REG_LBA0, sector & 0xff);
outb(IDE_DATA_PRIMARY+IDE_REG_LBA1, (sector >> 8) & 0xff);
outb(IDE_DATA_PRIMARY+IDE_REG_LBA2, (sector >> 16) & 0xff);
- outb(IDE_DATA_PRIMARY+IDE_REG_DISK, IDE_DISK_LBA | ((b->dev&1)<<4) | ((sector>>24)&0x0f));
+ outb(IDE_DATA_PRIMARY+IDE_REG_DISK,
+ IDE_DISK_LBA | ((b->dev&1)<<4) | ((sector>>24)&0x0f));
if(b->flags & B_DIRTY){
outb(IDE_DATA_PRIMARY+IDE_REG_COMMAND, IDE_CMD_WRITE);
outsl(IDE_DATA_PRIMARY+IDE_REG_DATA, b->data, BSIZE/4);
uartputc(*p);
}
+static int
+cantransmit(void)
+{
+ return inb(COM1+UART_LINE_STATUS) & UART_TRANSMIT_READY;
+}
+
+static int
+hasreceived(void)
+{
+ return inb(COM1+UART_LINE_STATUS) & UART_RECEIVE_READY;
+}
+
void
uartputc(int c)
{
if(!uart)
return;
- for(i = 0; i < 128 && !(inb(COM1+UART_LINE_STATUS) & UART_TRANSMIT_READY); i++)
+ for(i = 0; i < 128 && !cantransmit(); i++)
microdelay(10);
outb(COM1+UART_TRANSMIT_BUFFER, c);
}
{
if(!uart)
return -1;
- if(!(inb(COM1+UART_LINE_STATUS) & UART_RECEIVE_READY))
+ if(!hasreceived())
return -1;
return inb(COM1+UART_RECEIVE_BUFFER);
}