BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / 639da90adc2a255284d6ce32dfbbec5bd20e1db3

// Related

Nucleus

Barry ATA driver read function 639da90 (3 years, 2 months ago)
diff --git a/drivers/storage/ata.c b/drivers/storage/ata.c
index d0ff1e8..bf56afc 100644
--- a/drivers/storage/ata.c
+++ b/drivers/storage/ata.c
@@ -4,11 +4,13 @@
  * actual hardware.
  */
 
+#include <stdio.h>
 #include <stdint.h>
+#include <string.h>
 #include <sys/stat.h>
+#include <errno.h>
 #include <io.h>
 #include <nucleus/driver.h>
-#include <nucleus/panic.h>
 #include <nucleus/vfs.h>
 #include "ide.h"
 
@@ -25,11 +27,14 @@ struct Partition {
 size_t ata_dev_read(File *file, char *buf, size_t size, off_t offset);
 size_t ata_dev_write(File *file, char *buf, size_t size, off_t offset);
 
+/* File Operations for the ATA device nodes */
 FileOps ataFileOps = {
 	.read = ata_dev_read,
 	.write = ata_dev_write,
 };
 
+static void *ataDmaArea = NULL;
+
 /* Access an ATA drive */
 static uint8_t
 ata_access(int write, struct IDEDevice *dev, uint32_t lba, uint8_t sectors,
@@ -168,21 +173,18 @@ void
 ata_init(struct IDEDevice *dev)
 {
 	static int drive = 0;
-	static void *ataDmaArea = NULL;
-	if (!ataDmaArea)
-		ataDmaArea = (void *) alloc_frame();
 	static int ataMajor = 0;
 	if (!ataMajor)
 		ataMajor = register_driver(1, &ataFileOps);
 
+	if (!ataDmaArea)
+		ataDmaArea = (void *) alloc_frame();
 
 	/* Create device node */
 	char name[16];
 	int minor = drive * 16;
 	sprintf(name, "/dev/hd%d", drive);
 	mknod(name, S_IFBLK | 0600, MKDEV(ataMajor, minor));
-	kprintf("  ATA drive [%s] (%d MB) %s", name,
-	        dev->size / 1024 / 2, dev->model);
 
 	/* Attempt to read partition table */
 	int i;
@@ -194,8 +196,6 @@ ata_init(struct IDEDevice *dev)
 			continue;
 		sprintf(name, "/dev/hd%dp%d", drive, i);
 		mknod(name, S_IFBLK | 0600, MKDEV(ataMajor, minor + i + 1));
-		kprintf("    Partition [%s] %#.8x - %#.8x", name,
-		        part[i].lba*512, (part[i].lba + part[i].size) * 512);
 	}
 
 	drive++;
@@ -205,7 +205,42 @@ ata_init(struct IDEDevice *dev)
 size_t
 ata_dev_read(File *file, char *buf, size_t size, off_t offset)
 {
-	
+	uint16_t min, bufOffset = offset % 512;
+	size_t count = 0;
+	uint16_t parti = MINOR(file->inode->dev) % 16;
+	uint32_t lba;
+	struct Partition *part;
+
+	struct IDEDevice *dev = &ideDevices[MINOR(file->inode->dev) / 16];
+
+	if (parti) {
+		ata_read(dev, 0, 1, ataDmaArea);
+		part = (void *) ataDmaArea + 446
+		     + ((parti - 1) * sizeof(struct Partition));
+		if (offset > part->size * 512)
+			return 0;
+		if (offset + size > part->size * 512)
+			size = (part->size * 512) - offset;
+	} else {
+		if (offset > dev->size * 512)
+			return 0;
+		if (offset + size > dev->size * 512)
+			size = (dev->size * 512) - offset;
+	}
+
+	while (size + bufOffset) {
+		min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
+		lba = (parti ? part->lba : 0) + ((offset + count) / 512);
+		ata_read(dev, lba, PAGE_SIZE / 512, ataDmaArea);
+		memcpy((void *) (buf + count),
+		       (void *) ataDmaArea + bufOffset,
+		       min);
+		size -= min;
+		count += min;
+		bufOffset = 0;
+	}
+
+	return count;
 }
 
 /* Write to an ATA drive */
@@ -214,3 +249,15 @@ ata_dev_write(File *file, char *buf, size_t size, off_t offset)
 {
 	
 }
+
+/* Open an ATA drive */
+int
+ata_dev_open(File *file)
+{
+	struct IDEDevice *dev = &ideDevices[MINOR(file->inode->dev) / 16];
+	if (!dev->reserved)
+		return -ENODEV;
+	if (dev->type != 0)
+		return -EINVAL;
+	return 0;
+}