gpllib: Propagate error codes in disk library
authorPierre-Alexandre Meyer <pierre@mouraf.org>
Tue, 21 Apr 2009 16:56:11 +0000 (09:56 -0700)
committerPierre-Alexandre Meyer <pierre@mouraf.org>
Tue, 21 Apr 2009 16:56:11 +0000 (09:56 -0700)
It is worth propagating read/write error codes back to the caller. He can
pass NULL to ignore them, or an int* that will be populated.

To decode it, one can use the get_error function (see disk/error.c).

Signed-off-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
com32/gplinclude/disk/read.h
com32/gplinclude/disk/write.h
com32/gpllib/disk/read.c
com32/gpllib/disk/write.c

index 79c7952..fee10da 100644 (file)
@@ -1,7 +1,10 @@
 #ifndef _READ_H_
 #define _READ_H_
-void *read_mbr(int drive);
-void *dev_read(int drive, unsigned int lba, int sectors);
-void *read_sectors(struct driveinfo* drive_info, const unsigned int lba,
-                  const int sectors);
+
+#include <disk/geom.h>
+
+void *read_mbr(int, int*);
+void *dev_read(int, unsigned int, int, int*);
+void *read_sectors(struct driveinfo*, const unsigned int,
+                  const int, int *);
 #endif /* _READ_H */
index 89ca873..be6494f 100644 (file)
@@ -1,11 +1,14 @@
 #ifndef _WRITE_H_
 #define _WRITE_H_
-int write_sectors(const struct driveinfo* drive_info, const unsigned int lba,
-                 const void *data, const int size);
+
+#include <disk/geom.h>
+
+int write_sectors(const struct driveinfo*, const unsigned int,
+                 const void *, const int, int *);
 int write_verify_sector(struct driveinfo* drive_info,
-                       const unsigned int lba,
-                       const void *data);
-int write_verify_sectors(struct driveinfo* drive_info,
-                        const unsigned int lba,
-                        const void *data, const int size);
+                       const unsigned int,
+                       const void *, int*);
+int write_verify_sectors(struct driveinfo*,
+                        const unsigned int,
+                        const void *, const int, int *);
 #endif
index de4dee9..a5cb120 100644 (file)
@@ -1,6 +1,7 @@
 #include <com32.h>
 #include <stdlib.h>
 #include <string.h>
+
 #include <disk/geom.h>
 #include <disk/read.h>
 #include <disk/util.h>
 /**
  * read_mbr - return a pointer to a malloced buffer containing the mbr
  * @drive:     Drive number
+ * @error:     Return the error code on failure
  **/
-void *read_mbr(int drive)
+void *read_mbr(int drive, int *error)
 {
        struct driveinfo drive_info;
        drive_info.disk = drive;
 
        /* MBR: lba = 0, 1 sector */
-       return read_sectors(&drive_info, 0, 1);
+       return read_sectors(&drive_info, 0, 1, error);
 }
 
 /**
@@ -24,15 +26,16 @@ void *read_mbr(int drive)
  * @drive:     Drive number
  * @lba:       Position to start reading from
  * @sectors:   Number of sectors to read
+ * @error:     Return the error code on failure
  *
  * High-level routine to read from a hard drive.
  **/
-void *dev_read(int drive, unsigned int lba, int sectors)
+void *dev_read(int drive, unsigned int lba, int sectors, int *error)
 {
        struct driveinfo drive_info;
        drive_info.disk = drive;
 
-       return read_sectors(&drive_info, lba, sectors);
+       return read_sectors(&drive_info, lba, sectors, error);
 }
 
 /**
@@ -40,13 +43,14 @@ void *dev_read(int drive, unsigned int lba, int sectors)
  * @drive_info:                driveinfo struct describing the disk
  * @lba:               Position to read
  * @sectors:           Number of sectors to read
+ * @error:             Return the error code on failure
  *
  * Return a pointer to a malloc'ed buffer containing the data.
  **/
 void *read_sectors(struct driveinfo* drive_info, const unsigned int lba,
-                  const int sectors)
+                  const int sectors, int *error)
 {
-       com32sys_t inreg;
+       com32sys_t inreg, outreg;
        struct ebios_dapa *dapa = __com32.cs_bounce;
        void *buf = (char *)__com32.cs_bounce + sectors * SECTOR;
        void *data;
@@ -92,8 +96,14 @@ void *read_sectors(struct driveinfo* drive_info, const unsigned int lba,
        }
 
        /* Perform the read */
-       if (int13_retry(&inreg, NULL))
+       if (int13_retry(&inreg, &outreg)) {
+               if (error)
+                       *error = outreg.eax.b[1];
                return NULL;    /* Give up */
+       } else {
+               if (error)
+                       *error = 0;
+       }
 
        data = malloc(sectors * SECTOR);
        if (data)
index 100f3aa..cd58548 100644 (file)
  * @lba:               Position to write
  * @data:              Buffer to write
  * @size:              Size of the buffer (number of sectors)
+ * @error:             Return the error code on failure
  **/
 int write_sectors(const struct driveinfo* drive_info, const unsigned int lba,
-                 const void *data, const int size)
+                 const void *data, const int size, int *error)
 {
-       com32sys_t inreg;
+       com32sys_t inreg, outreg;
        struct ebios_dapa *dapa = __com32.cs_bounce;
        void *buf = (char *)__com32.cs_bounce + size;
 
@@ -60,10 +61,15 @@ int write_sectors(const struct driveinfo* drive_info, const unsigned int lba,
        }
 
        /* Perform the write */
-       if (int13_retry(&inreg, NULL))
-               return -1;
-       else
+       if (int13_retry(&inreg, &outreg)) {
+               if (error)
+                       *error = outreg.eax.b[1];
+               return -1;      /* Give up */
+       } else {
+               if (error)
+                       *error = 0;
                return 0;
+       }
 }
 
 /**
@@ -74,9 +80,9 @@ int write_sectors(const struct driveinfo* drive_info, const unsigned int lba,
  **/
 int write_verify_sector(struct driveinfo* drive_info,
                        const unsigned int lba,
-                       const void *data)
+                       const void *data, int *error)
 {
-       return write_verify_sectors(drive_info, lba, data, SECTOR);
+       return write_verify_sectors(drive_info, lba, data, SECTOR, error);
 }
 
 /**
@@ -88,16 +94,16 @@ int write_verify_sector(struct driveinfo* drive_info,
  **/
 int write_verify_sectors(struct driveinfo* drive_info,
                         const unsigned int lba,
-                        const void *data, const int size)
+                        const void *data, const int size, int* error)
 {
        char *rb;
        int rv;
 
-       rv = write_sectors(drive_info, lba, data, size);
+       rv = write_sectors(drive_info, lba, data, size, error);
        if (rv)
                return rv;              /* Write failure */
 
-       rb = read_sectors(drive_info, lba, size);
+       rb = read_sectors(drive_info, lba, size, error);
        if (!rb)
                return -1;              /* Readback failure */