summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/dms/dms_subr.c35
-rw-r--r--src/sys/include/dms/dms.h7
-rw-r--r--src/sys/io/ic/ahci.c1
3 files changed, 40 insertions, 3 deletions
diff --git a/src/sys/dms/dms_subr.c b/src/sys/dms/dms_subr.c
index 240449a..085633b 100644
--- a/src/sys/dms/dms_subr.c
+++ b/src/sys/dms/dms_subr.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/queue.h>
+#include <sys/param.h>
#include <os/kalloc.h>
#include <dms/dms.h>
#include <string.h>
@@ -100,6 +101,9 @@ dms_get(disk_id_t disk_id)
ssize_t
dms_write(struct dms_disk *dp, void *p, off_t off, size_t len)
{
+ void *buf;
+ size_t real_len;
+ int error;
struct dms_ops *ops;
if (dp == NULL || p == NULL) {
@@ -114,13 +118,25 @@ dms_write(struct dms_disk *dp, void *p, off_t off, size_t len)
return -ENOTSUP;
}
- return ops->write(dp, p, off, len);
+ real_len = ALIGN_UP(len, dp->bsize);
+ if ((buf = kalloc(real_len)) == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, real_len);
+ memcpy(buf, p, len);
+ error = ops->write(dp, buf, off, real_len);
+ kfree(buf);
+ return error;
}
ssize_t
dms_read(struct dms_disk *dp, void *p, off_t off, size_t len)
{
+ void *buf;
struct dms_ops *ops;
+ size_t real_len;
+ int error;
if (dp == NULL || p == NULL) {
return -EINVAL;
@@ -134,5 +150,20 @@ dms_read(struct dms_disk *dp, void *p, off_t off, size_t len)
return -ENOTSUP;
}
- return ops->read(dp, p, off, len);
+ /* Allocate a real sized buffer */
+ real_len = ALIGN_UP(len, dp->bsize);
+ if ((buf = kalloc(real_len)) == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, real_len);
+ error = ops->read(dp, buf, off, real_len);
+ if (error < 0) {
+ kfree(buf);
+ return error;
+ }
+
+ memcpy(p, buf, len);
+ kfree(buf);
+ return 0;
}
diff --git a/src/sys/include/dms/dms.h b/src/sys/include/dms/dms.h
index fca40b4..06e78ac 100644
--- a/src/sys/include/dms/dms.h
+++ b/src/sys/include/dms/dms.h
@@ -74,14 +74,19 @@ struct dms_ops {
*
* @name: Name of this device
* @ops: Operations that can be performed
- * @data: Driver specific data
+ * @data: Driver specific data [set by driver]
+ * @bsize: Disk block size [set by driver]
* @id: ID of the disk
* @link: Internal queue link
+ *
+ * XXX: The `data' and `bsize' fields must be set by
+ * the driver
*/
struct dms_disk {
char name[DISKNAME_MAX];
struct dms_ops *ops;
void *data;
+ uint16_t bsize;
disk_id_t id;
TAILQ_ENTRY(dms_disk) link;
};
diff --git a/src/sys/io/ic/ahci.c b/src/sys/io/ic/ahci.c
index 9aa19b4..48560a8 100644
--- a/src/sys/io/ic/ahci.c
+++ b/src/sys/io/ic/ahci.c
@@ -236,6 +236,7 @@ ahci_register(struct ata_identity *identity, struct ahci_port *port)
return error;
}
+ dp->bsize = port->bsize;
dp->data = (void *)port;
return 0;
}