]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
SCSI write support (for usbms mainly).
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 30 Jan 2012 11:26:11 +0000 (12:26 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 30 Jan 2012 11:26:11 +0000 (12:26 +0100)
* grub-core/disk/scsi.c (grub_scsi_write10): Uncomment. Make buffer
a const pointer.
(grub_scsi_write): Implement.
* include/grub/scsi.h (grub_scsi_dev): Make write buffer a const pointer

ChangeLog
grub-core/disk/ata.c
grub-core/disk/scsi.c
grub-core/disk/usbms.c
include/grub/scsi.h

index 1055d1ad42344b95ddf2a0d3929d87be834976a2..5641803dc7b973deeaa09bda05903e2f6f1557be 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-01-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       SCSI write support (for usbms mainly).
+
+       * grub-core/disk/scsi.c (grub_scsi_write10): Uncomment. Make buffer
+       a const pointer.
+       (grub_scsi_write): Implement.
+       * include/grub/scsi.h (grub_scsi_dev): Make write buffer a const pointer
+
 2012-01-30  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * grub-core/io/lzopio.c (uncompress_block): Fix use of incorrect
index 6d2ec0c78202419695c1f9c7c7d5d8d6bf5e2cbf..c90e86832ca32b4a7d21107d68e6947b32150eac 100644 (file)
@@ -537,7 +537,7 @@ grub_atapi_write (struct grub_scsi *scsi __attribute__((unused)),
                  grub_size_t cmdsize __attribute__((unused)),
                  char *cmd __attribute__((unused)),
                  grub_size_t size __attribute__((unused)),
-                 char *buf __attribute__((unused)))
+                 const char *buf __attribute__((unused)))
 {
   // XXX: scsi.mod does not use write yet.
   return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "ATAPI write not implemented");
index 610cc4dc5b1df58a55b1579969fee0a897505c2c..b22f651e9eaab6cfd7434814610be57487ed4c9e 100644 (file)
@@ -253,12 +253,11 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
   return err;
 }
 
-#if 0
 /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
    sectors starting with SECTOR.  */
 static grub_err_t
 grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
-                  grub_size_t size, char *buf)
+                  grub_size_t size, const char *buf)
 {
   grub_scsi_t scsi;
   struct grub_scsi_write10 wr;
@@ -287,6 +286,8 @@ grub_scsi_write10 (grub_disk_t disk, grub_disk_addr_t sector,
   return err;
 }
 
+#if 0
+
 /* Send a SCSI request for DISK: write the data stored in BUF to SIZE
    sectors starting with SECTOR.  */
 static grub_err_t
@@ -595,13 +596,38 @@ grub_scsi_write (grub_disk_t disk __attribute((unused)),
                 grub_size_t size __attribute((unused)),
                 const char *buf __attribute((unused)))
 {
-#if 0
-  /* XXX: Not tested yet!  */
+  grub_scsi_t scsi;
 
-  /* XXX: This should depend on the device type?  */
-  return grub_scsi_write10 (disk, sector, size, buf);
-#endif
-  return GRUB_ERR_NOT_IMPLEMENTED_YET;
+  scsi = disk->data;
+
+  if (scsi->devtype == grub_scsi_devtype_cdrom)
+    return grub_error (GRUB_ERR_IO, "no CD burning");
+
+  while (size)
+    {
+      /* PATA doesn't support more than 32K reads.
+        Not sure about AHCI and USB. If it's confirmed that either of
+        them can do bigger reads reliably this value can be moved to 'scsi'
+        structure.  */
+      grub_size_t len = 32768 >> disk->log_sector_size;
+      grub_err_t err;
+      if (len > size)
+       len = size;
+      /* Depending on the type, select a read function.  */
+      switch (scsi->devtype)
+       {
+       case grub_scsi_devtype_direct:
+         err = grub_scsi_write10 (disk, sector, len, buf);
+         if (err)
+           return err;
+         break;
+       }
+      size -= len;
+      sector += len;
+      buf += len << disk->log_sector_size;
+    }
+
+  return GRUB_ERR_NONE;
 }
 
 
index a4c2addf100d7d0e392dea79be2c2967b3cf32ec..e264c464c3f3037402c5f0898c81b2fdfc25885e 100644 (file)
@@ -388,9 +388,9 @@ grub_usbms_read (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
 
 static grub_err_t
 grub_usbms_write (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                 grub_size_t size, char *buf)
+                 grub_size_t size, const char *buf)
 {
-  return grub_usbms_transfer (scsi, cmdsize, cmd, size, buf, 1);
+  return grub_usbms_transfer (scsi, cmdsize, cmd, size, (char *) buf, 1);
 }
 
 static grub_err_t
index dfee69c625c11f54dfe204a88e2d35e39210d301..e10f5e452424ffe2f605d4850a8064c01118049f 100644 (file)
@@ -69,7 +69,7 @@ struct grub_scsi_dev
   /* Write SIZE  bytes from BUF to  the device SCSI  after sending the
      command CMD of size CMDSIZE.  */
   grub_err_t (*write) (struct grub_scsi *scsi, grub_size_t cmdsize, char *cmd,
-                      grub_size_t size, char *buf);
+                      grub_size_t size, const char *buf);
 
   /* The next scsi device.  */
   struct grub_scsi_dev *next;