]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 27 Jun 2011 08:12:35 +0000 (10:12 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 27 Jun 2011 08:12:35 +0000 (10:12 +0200)
because of underlying system restrictions.

ChangeLog
grub-core/disk/scsi.c

index ca4145e332c58071259b74679235ffe5652b8afb..36084227960f97b77f56dd6f67d2303149a2060b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-06-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/disk/scsi.c (grub_scsi_read): Limit SCSI reads to 32K
+       because of underlying system restrictions.
+
 2011-06-27  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-mkrescue.in: Rename "ata" to "pata" and add ahci when
index 35b8525c215074eda218c9e73985b4386d0b279a..90256416401acfbecc3b88d3823830636530b7c4 100644 (file)
@@ -524,17 +524,36 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
 
   scsi = disk->data;
 
-  /* Depending on the type, select a read function.  */
-  switch (scsi->devtype)
+  while (size)
     {
-    case grub_scsi_devtype_direct:
-      return grub_scsi_read10 (disk, sector, size, buf);
-
-    case grub_scsi_devtype_cdrom:
-      return grub_scsi_read12 (disk, sector, size, buf);
+      /* 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_read10 (disk, sector, len, buf);
+         if (err)
+           return err;
+         break;
+
+       case grub_scsi_devtype_cdrom:
+         err = grub_scsi_read12 (disk, sector, len, buf);
+         if (err)
+           return err;
+         break;
+       }
+      size -= len;
+      sector += len;
+      buf += len << disk->log_sector_size;
     }
 
-  /* XXX: Never reached.  */
   return GRUB_ERR_NONE;
 
 #if 0 /* Workaround - it works - but very slowly, from some reason