All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/3] grub EFI disk device enumberating
@ 2006-10-24  7:19 bibo,mao
  2006-10-24 13:11 ` Johan Rydberg
  0 siblings, 1 reply; 4+ messages in thread
From: bibo,mao @ 2006-10-24  7:19 UTC (permalink / raw)
  To: grub-devel

Hi,
  On EFI platform, every partition is regarded as one block device and
responding EFI device path. EFI device patch has the same hierarchical
relationship with the partition. This patch will search root EFI device
path by current device patch, but not parent device path.
  Original grub can not find efi disk when grub.efi is executed on
logical partition.

  Previously I posted this patch, now I repost again.
  Any suggestion is welcome.

thanks
bibo,mao

diff -Nruap grub2.org/disk/efi/efidisk.c grub2/disk/efi/efidisk.c
--- grub2.org/disk/efi/efidisk.c	2006-10-24 13:23:42.000000000 +0800
+++ grub2/disk/efi/efidisk.c	2006-10-24 14:10:32.000000000 +0800
@@ -87,6 +87,52 @@ find_last_device_path (const grub_efi_de
   return p;
 }
 
+static int compare_ancestor_path(const grub_efi_device_path_t *parent,
+                const grub_efi_device_path_t *dp2)
+{
+  /* Return non-zero.  */
+  if (! parent || ! dp2)
+    return 1;
+
+  while (1)
+    {
+      grub_efi_uint8_t type1, type2;
+      grub_efi_uint8_t subtype1, subtype2;
+      grub_efi_uint16_t len1, len2;
+      int ret;
+
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH(parent))
+	break;
+
+      type1 = GRUB_EFI_DEVICE_PATH_TYPE (parent);
+      type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
+
+      if (type1 != type2)
+	return (int) type2 - (int) type1;
+
+      subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (parent);
+      subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
+
+      if (subtype1 != subtype2)
+	return (int) subtype1 - (int) subtype2;
+
+      len1 = GRUB_EFI_DEVICE_PATH_LENGTH (parent);
+      len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
+
+      if (len1 != len2)
+	return (int) len1 - (int) len2;
+
+      ret = grub_memcmp (parent, dp2, len1);
+      if (ret != 0)
+	return ret;
+
+      parent = (grub_efi_device_path_t *) ((char *) parent + len1);
+      dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
+    }
+
+  return 0;
+}
+
 /* Compare device paths.  */
 static int
 compare_device_paths (const grub_efi_device_path_t *dp1,
@@ -197,44 +243,6 @@ make_devices (void)
   return devices;
 }
 
-/* Find the parent device.  */
-static struct grub_efidisk_data *
-find_parent_device (struct grub_efidisk_data *devices,
-		    struct grub_efidisk_data *d)
-{
-  grub_efi_device_path_t *dp, *ldp;
-  struct grub_efidisk_data *parent;
-  
-  dp = duplicate_device_path (d->device_path);
-  if (! dp)
-    return 0;
-
-  ldp = find_last_device_path (dp);
-  ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-  ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-  ldp->length[0] = sizeof (*ldp);
-  ldp->length[1] = 0;
-
-  for (parent = devices; parent; parent = parent->next)
-    {
-      /* Ignore itself.  */
-      if (parent == d)
-	continue;
-      
-      if (compare_device_paths (parent->device_path, dp) == 0)
-	{
-	  /* Found.  */
-	  if (! parent->last_device_path)
-	    parent = 0;
-	  
-	  break;
-	}
-    }
-
-  grub_free (dp);
-  return parent;
-}
-
 static int
 iterate_child_devices (struct grub_efidisk_data *devices,
 		       struct grub_efidisk_data *d,
@@ -301,107 +309,36 @@ add_device (struct grub_efidisk_data **d
 }
 
 /* Name the devices.  */
-static void
-name_devices (struct grub_efidisk_data *devices)
-{
+static void name_devices (struct grub_efidisk_data *devices){
   struct grub_efidisk_data *d;
-  
-  /* First, identify devices by media device paths.  */
-  for (d = devices; d; d = d->next)
-    {
-      grub_efi_device_path_t *dp;
-
-      dp = d->last_device_path;
-      if (! dp)
-	continue;
-      
-      if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
-	{
-	  int is_hard_drive = 0;
-	  
-	  switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
-	    {
-	    case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
-	      is_hard_drive = 1;
-	      /* Fall through by intention.  */
-	    case GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE:
-	      {
-		struct grub_efidisk_data *parent;
-
-		parent = find_parent_device (devices, d);
-		if (parent)
-		  {
-		    if (is_hard_drive)
-		      {
-#if 0
-			grub_printf ("adding a hard drive by a partition: ");
-			grub_print_device_path (parent->device_path);
-#endif
-			add_device (&hd_devices, parent);
-		      }
-		    else
-		      {
-#if 0
-			grub_printf ("adding a cdrom by a partition: ");
-			grub_print_device_path (parent->device_path);
-#endif
-			add_device (&cd_devices, parent);
-		      }
-		    
-		    /* Mark the parent as used.  */
-		    parent->last_device_path = 0;
-		  }
-	      }
-	      /* Mark itself as used.  */
-	      d->last_device_path = 0;
-	      break;
-
-	    default:
-	      /* For now, ignore the others.  */
-	      break;
-	    }
-	}
-    }
 
   /* Let's see what can be added more.  */
   for (d = devices; d; d = d->next)
     {
       grub_efi_device_path_t *dp;
       grub_efi_block_io_media_t *m;
-      
+
       dp = d->last_device_path;
       if (! dp)
 	continue;
 
       m = d->block_io->media;
-      if (m->logical_partition)
+      if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE)
 	{
-	  /* Only one partition in a non-media device. Assume that this
-	     is a floppy drive.  */
-#if 0
-	  grub_printf ("adding a floppy by guessing: ");
-	  grub_print_device_path (d->device_path);
-#endif
-	  add_device (&fd_devices, d);
-	}
-      else if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
-	{
-	  /* This check is too heuristic, but assume that this is a
-	     CDROM drive.  */
-#if 0
-	  grub_printf ("adding a cdrom by guessing: ");
-	  grub_print_device_path (d->device_path);
-#endif
-	  add_device (&cd_devices, d);
+	  if (m->read_only && m->block_size > GRUB_DISK_SECTOR_SIZE)
+	    {
+	      grub_printf("adding a cd by guessing\n");
+	      add_device (&cd_devices, d);
+	    } else
+	    {
+	      grub_printf("adding a hd by guessing\n");
+	      add_device (&hd_devices, d);
+	    }
 	}
-      else
+      if (GRUB_EFI_DEVICE_PATH_TYPE(dp) == GRUB_EFI_ACPI_DEVICE_PATH_TYPE)
 	{
-	  /* The default is a hard drive.  */
-#if 0
-	  grub_printf ("adding a hard drive by guessing: ");
-	  grub_print_device_path (d->device_path);
-#endif
-	  add_device (&hd_devices, d);
+	  grub_printf ("adding a floppy by guessing\n");
+	  add_device (&fd_devices, d);
 	}
     }
 }
@@ -734,7 +671,6 @@ grub_efidisk_get_device_name (grub_efi_h
       grub_disk_t parent = 0;
       char *partition_name = 0;
       char *device_name;
-      grub_efi_device_path_t *dup_dp, *dup_ldp;
       grub_efi_hard_drive_device_path_t hd;
       auto int find_parent_disk (const char *name);
       auto int find_partition (grub_disk_t disk, const grub_partition_t part);
@@ -753,7 +689,7 @@ grub_efidisk_get_device_name (grub_efi_h
 	      struct grub_efidisk_data *d;
 	      
 	      d = disk->data;
-	      if (compare_device_paths (d->device_path, dup_dp) == 0)
+	      if (compare_ancestor_path(d->device_path, dp) == 0)
 		{
 		  parent = disk;
 		  return 1;
@@ -778,20 +714,7 @@ grub_efidisk_get_device_name (grub_efi_h
 	  return 0;
 	}
 
-      /* It is necessary to duplicate the device path so that GRUB
-	 can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
-      if (! dup_dp)
-	return 0;
-
-      dup_ldp = find_last_device_path (dup_dp);
-      dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
-      dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
-      dup_ldp->length[0] = sizeof (*dup_ldp);
-      dup_ldp->length[1] = 0;
-
       grub_efidisk_iterate (find_parent_disk);
-      grub_free (dup_dp);
 
       if (! parent)
 	return 0;



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-10-25  5:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-24  7:19 [PATCH 3/3] grub EFI disk device enumberating bibo,mao
2006-10-24 13:11 ` Johan Rydberg
2006-10-24 14:05   ` Johan Rydberg
2006-10-25  5:43     ` bibo,mao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.