All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cdrom access patch
@ 2008-03-05  8:49 Bean
  2008-03-07 15:37 ` Vesa Jääskeläinen
  0 siblings, 1 reply; 25+ messages in thread
From: Bean @ 2008-03-05  8:49 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 149 bytes --]

Hi,

This patch use int 13 func 4B01 to detect cdrom. It also change the
name of the cd device to (hdN), where N is the bios drive number.

-- 
Bean

[-- Attachment #2: cd.diff --]
[-- Type: application/octet-stream, Size: 11455 bytes --]

diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c
index ddcc666..26997a0 100644
--- a/disk/i386/pc/biosdisk.c
+++ b/disk/i386/pc/biosdisk.c
@@ -18,6 +18,7 @@
 
 #include <grub/machine/biosdisk.h>
 #include <grub/machine/memory.h>
+#include <grub/machine/kernel.h>
 #include <grub/disk.h>
 #include <grub/dl.h>
 #include <grub/mm.h>
@@ -26,15 +27,12 @@
 #include <grub/err.h>
 #include <grub/term.h>
 
-static int cd_start = GRUB_BIOSDISK_MACHINE_CDROM_START;
-static int cd_count = 0;
-
 static int
 grub_biosdisk_get_drive (const char *name)
 {
   unsigned long drive;
 
-  if ((name[0] != 'f' && name[0] != 'h' && name[0] != 'c') || name[1] != 'd')
+  if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
     goto fail;
     
   drive = grub_strtoul (name + 2, 0, 10);
@@ -43,8 +41,6 @@ grub_biosdisk_get_drive (const char *name)
 
   if (name[0] == 'h')
     drive += 0x80;
-  else if (name[0] == 'c')
-    drive += cd_start;
   
   return (int) drive ;
 
@@ -58,10 +54,7 @@ grub_biosdisk_call_hook (int (*hook) (const char *name), int drive)
 {
   char name[10];
 
-  if (drive >= cd_start)
-    grub_sprintf (name, "cd%d", drive - cd_start);
-  else
-    grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
+  grub_sprintf (name, (drive & 0x80) ? "hd%d" : "fd%d", drive & (~0x80));
   return hook (name);
 }
 
@@ -78,7 +71,8 @@ grub_biosdisk_iterate (int (*hook) (const char *name))
       return 1;
   
   /* For hard disks, attempt to read the MBR.  */
-  for (drive = 0x80; drive < 0x90; drive++)
+  for (drive = 0x80;
+       drive < GRUB_BIOSDISK_MACHINE_CDROM_START;  drive++)
     {
       if (grub_biosdisk_rw_standard (0x02, drive, 0, 0, 1, 1,
 				     GRUB_MEMORY_MACHINE_SCRATCH_SEG) != 0)
@@ -91,9 +85,30 @@ grub_biosdisk_iterate (int (*hook) (const char *name))
 	return 1;
     }
 
-  for (drive = cd_start; drive < cd_start + cd_count; drive++)
-    if (grub_biosdisk_call_hook (hook, drive))
-      return 1;
+  if (grub_boot_drive >= GRUB_BIOSDISK_MACHINE_CDROM_START)
+    for (drive = grub_boot_drive;
+         drive < GRUB_BIOSDISK_MACHINE_CDROM_END; drive++)
+      {
+        struct grub_biosdisk_dap *dap;
+
+        dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+                                            + (4 << GRUB_DISK_SECTOR_BITS));
+
+        dap->length = sizeof (*dap);
+        dap->reserved = 0;
+        dap->blocks = 1;
+        dap->buffer = GRUB_MEMORY_MACHINE_SCRATCH_SEG << 16;
+        dap->block = 0;
+
+        if (grub_biosdisk_rw_int13_extensions (0x42, drive, dap))
+          {
+            grub_dprintf ("disk", "Read error when probing cd 0x%2x\n", drive);
+            break;
+          }
+
+        if (grub_biosdisk_call_hook (hook, drive))
+          return 1;
+      }
 
   return 0;
 }
@@ -109,7 +124,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
   if (drive < 0)
     return grub_errno;
 
-  disk->has_partitions = ((drive & 0x80) && (drive < cd_start));
+  disk->has_partitions = ((drive & 0x80) != 0);
   disk->id = drive;
   
   data = (struct grub_biosdisk_data *) grub_malloc (sizeof (*data));
@@ -119,42 +134,54 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
   data->drive = drive;
   data->flags = 0;
 
-  if (drive >= cd_start)
+  if (drive & 0x80)
     {
-      data->flags = GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM;
-      data->sectors = 32;
-      total_sectors = 9000000;  /* TODO: get the correct size.  */
-    }
-  else if (drive & 0x80)
-    {
-      /* HDD */
-      int version;
-      
-      version = grub_biosdisk_check_int13_extensions (drive);
-      if (version)
-	{
-	  struct grub_biosdisk_drp *drp
-	    = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
-	  /* Clear out the DRP.  */
-	  grub_memset (drp, 0, sizeof (*drp));
-	  drp->size = sizeof (*drp);
-	  if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
-	    {
-	      data->flags = GRUB_BIOSDISK_FLAG_LBA;
-
-	      if (drp->total_sectors)
-		total_sectors = drp->total_sectors;
-	      else
-                /* Some buggy BIOSes doesn't return the total sectors
-                   correctly but returns zero. So if it is zero, compute
-                   it by C/H/S returned by the LBA BIOS call.  */
-                total_sectors = drp->cylinders * drp->heads * drp->sectors;
-	    }
-	}
+      struct grub_biosdisk_cdrp *cdrp
+        = (struct grub_biosdisk_cdrp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+      grub_memset (cdrp, 0, sizeof (*cdrp));
+      cdrp->size = sizeof (*cdrp);
+      if ((! grub_biosdisk_get_cdinfo_int13_extensions (drive, cdrp)) &&
+          (cdrp->drive_no == drive) &&
+          ((cdrp->media_type & GRUB_BIOSDISK_CDTYPE_MASK)
+           == GRUB_BIOSDISK_CDTYPE_NO_EMUL))
+        {
+          disk->has_partitions = 0;
+          data->flags = (GRUB_BIOSDISK_FLAG_LBA | GRUB_BIOSDISK_FLAG_CDROM);
+          data->sectors = 32;
+          total_sectors = 9000000;  /* TODO: get the correct size.  */
+        }
+      else
+        {
+          /* HDD */
+          int version;
+
+          version = grub_biosdisk_check_int13_extensions (drive);
+          if (version)
+            {
+              struct grub_biosdisk_drp *drp
+                    = (struct grub_biosdisk_drp *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
+
+              /* Clear out the DRP.  */
+              grub_memset (drp, 0, sizeof (*drp));
+              drp->size = sizeof (*drp);
+              if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
+                {
+                  data->flags = GRUB_BIOSDISK_FLAG_LBA;
+
+                  if (drp->total_sectors)
+                    total_sectors = drp->total_sectors;
+                  else
+                    /* Some buggy BIOSes doesn't return the total sectors
+                       correctly but returns zero. So if it is zero, compute
+                       it by C/H/S returned by the LBA BIOS call.  */
+                    total_sectors = drp->cylinders * drp->heads * drp->sectors;
+                }
+            }
+        }
     }
 
-  if (drive < cd_start)
+  if (! (data->flags & GRUB_BIOSDISK_FLAG_CDROM))
     {
       if (grub_biosdisk_get_diskinfo_standard (drive,
 					       &data->cylinders,
@@ -364,8 +391,6 @@ grub_disk_biosdisk_fini (void)
 
 GRUB_MOD_INIT(biosdisk)
 {
-  int drive, found = 0;
-
   if (grub_disk_firmware_is_tainted)
     {
       grub_printf ("Firmware is marked as tainted, refusing to initialize.\n");
@@ -374,24 +399,6 @@ GRUB_MOD_INIT(biosdisk)
   grub_disk_firmware_fini = grub_disk_biosdisk_fini;
 
   grub_disk_dev_register (&grub_biosdisk_dev);
-
-  for (drive = GRUB_BIOSDISK_MACHINE_CDROM_START;
-       drive < GRUB_BIOSDISK_MACHINE_CDROM_END; drive++)
-    {
-      if (grub_biosdisk_check_int13_extensions (drive))
-        {
-	  if (! found)
-	    cd_start = drive;
-	  found++;
-	}
-      else
-        {
-	  if (found)
-            break;
-	}
-    }
-
-  cd_count = found;
 }
 
 GRUB_MOD_FINI(biosdisk)
diff --git a/include/grub/i386/pc/biosdisk.h b/include/grub/i386/pc/biosdisk.h
index 770f942..848840e 100644
--- a/include/grub/i386/pc/biosdisk.h
+++ b/include/grub/i386/pc/biosdisk.h
@@ -25,9 +25,18 @@
 #define GRUB_BIOSDISK_FLAG_LBA	1
 #define GRUB_BIOSDISK_FLAG_CDROM 2
 
-#define GRUB_BIOSDISK_MACHINE_CDROM_START	0xe0
+#define GRUB_BIOSDISK_MACHINE_CDROM_START	0x9f
 #define GRUB_BIOSDISK_MACHINE_CDROM_END		0xf0
 
+#define GRUB_BIOSDISK_CDTYPE_NO_EMUL	0
+#define GRUB_BIOSDISK_CDTYPE_1_2_M	1
+#define GRUB_BIOSDISK_CDTYPE_1_44_M	2
+#define GRUB_BIOSDISK_CDTYPE_2_88_M	3
+#define GRUB_BIOSDISK_CDTYPE_2_88_M	3
+#define GRUB_BIOSDISK_CDTYPE_HARDDISK	4
+
+#define GRUB_BIOSDISK_CDTYPE_MASK	0xF
+
 struct grub_biosdisk_data
 {
   int drive;
@@ -74,6 +83,23 @@ struct grub_biosdisk_drp
   grub_uint8_t dummy[16];
 } __attribute__ ((packed));
 
+struct grub_biosdisk_cdrp
+{
+  grub_uint8_t size;
+  grub_uint8_t media_type;
+  grub_uint8_t drive_no;
+  grub_uint8_t controller_no;
+  grub_uint32_t image_lba;
+  grub_uint16_t device_spec;
+  grub_uint16_t cache_seg;
+  grub_uint16_t load_seg;
+  grub_uint16_t length_sec512;
+  grub_uint8_t cylinders;
+  grub_uint8_t sectors;
+  grub_uint8_t heads;
+  grub_uint8_t dummy[16];
+} __attribute__ ((packed));
+
 /* Disk Address Packet.  */
 struct grub_biosdisk_dap
 {
@@ -90,6 +116,8 @@ int EXPORT_FUNC(grub_biosdisk_rw_standard) (int ah, int drive, int coff, int hof
 int EXPORT_FUNC(grub_biosdisk_check_int13_extensions) (int drive);
 int EXPORT_FUNC(grub_biosdisk_get_diskinfo_int13_extensions) (int drive,
            void *drp);
+int EXPORT_FUNC(grub_biosdisk_get_cdinfo_int13_extensions) (int drive,
+           void *cdrp);
 int EXPORT_FUNC(grub_biosdisk_get_diskinfo_standard) (int drive,
 					 unsigned long *cylinders,
 					 unsigned long *heads,
diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h
index 848dad1..43a8d5b 100644
--- a/include/grub/i386/pc/kernel.h
+++ b/include/grub/i386/pc/kernel.h
@@ -71,7 +71,7 @@ extern grub_int32_t grub_memdisk_image_size;
 extern char grub_prefix[];
 
 /* The boot BIOS drive number.  */
-extern grub_int32_t grub_boot_drive;
+extern grub_int32_t EXPORT_VAR(grub_boot_drive);
 
 /* The root BIOS drive number.  */
 extern grub_int32_t grub_root_drive;
diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c
index 7237492..525b667 100644
--- a/kern/i386/pc/init.c
+++ b/kern/i386/pc/init.c
@@ -22,7 +22,6 @@
 #include <grub/machine/memory.h>
 #include <grub/machine/console.h>
 #include <grub/machine/kernel.h>
-#include <grub/machine/biosdisk.h>
 #include <grub/types.h>
 #include <grub/err.h>
 #include <grub/dl.h>
@@ -77,13 +76,8 @@ make_install_device (void)
       if (grub_root_drive == 0xFF)
         grub_root_drive = grub_boot_drive;
       
-      if (grub_root_drive >= GRUB_BIOSDISK_MACHINE_CDROM_START)
-        grub_sprintf (dev, "(cd%u",
-		      grub_root_drive - GRUB_BIOSDISK_MACHINE_CDROM_START);
-      else
-        grub_sprintf (dev, "(%cd%u",
-		      (grub_root_drive & 0x80) ? 'h' : 'f',
-		      grub_root_drive & 0x7f);
+      grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
+                    grub_root_drive & 0x7f);
       
       if (grub_install_dos_part >= 0)
 	grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S
index bf3d4ee..2994ee2 100644
--- a/kern/i386/pc/startup.S
+++ b/kern/i386/pc/startup.S
@@ -780,6 +780,17 @@ FUNCTION(grub_biosdisk_check_int13_extensions)
 
 
 /*
+ *   int grub_biosdisk_get_cdinfo_int13_extensions (int drive, void *cdrp)
+ *
+ *   Return the cdrom information of DRIVE in CDRP. If an error occurs,
+ *   then return non-zero, otherwise zero.
+ */
+
+FUNCTION(grub_biosdisk_get_cdinfo_int13_extensions)
+	movw	$0x4B01, %cx
+	jmp	1f
+
+/*
  *   int grub_biosdisk_get_diskinfo_int13_extensions (int drive, void *drp)
  *
  *   Return the geometry of DRIVE in a drive parameters, DRP. If an error
@@ -787,6 +798,8 @@ FUNCTION(grub_biosdisk_check_int13_extensions)
  */
 
 FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
+	movb	$0x48, %ch
+1:
 	pushl	%ebp
 	pushl	%ebx
 	pushl	%esi
@@ -802,7 +815,7 @@ FUNCTION(grub_biosdisk_get_diskinfo_int13_extensions)
 	call	prot_to_real
 
 	.code16
-	movb	$0x48, %ah
+	movw	%cx, %ax
 	movw	%bx, %ds
 	int	$0x13		/* do the operation */
 	movb	%ah, %bl	/* save return value in %bl */

^ permalink raw reply related	[flat|nested] 25+ messages in thread
* [PATCH] cdrom access patch
@ 2008-03-06 23:58 Kalamatee
  0 siblings, 0 replies; 25+ messages in thread
From: Kalamatee @ 2008-03-06 23:58 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 382 bytes --]

Bean wrote ..
>This patch use int 13 func 4B01 to detect cdrom. It also change the
>name of the cd device to (hdN), where N is the bios drive number.

Ah great .. just tried it and now VMWare detects the cdrom correctly

LS now lists (fd0) (hd0) and (hd31)

though the naming does seem odd

in Qemu it also works and is listed as (hd96)

Thanks for all your great work so far .. =)

[-- Attachment #2: Type: text/html, Size: 536 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: [PATCH] cdrom access patch
@ 2008-03-08 20:16 Kalamatee
  0 siblings, 0 replies; 25+ messages in thread
From: Kalamatee @ 2008-03-08 20:16 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 487 bytes --]

Vesa  wrote ..
>I would prefer that CD's would be counted like (cd0) for first CD-ROM
device, (cd1) for >second CD-ROM device, ... and so on. I think it is OK to
first allocate BIOS devices for >CD's and after that use ATA driver for rest
of them. Ata driver can of course be accessed >with ata name too.

Ahh great .. yes I would prefer that also but would it cause confusion with
ls120 etc drivers?

Those funcs do sound the way to go though .. I hope Been can do something
with it =)

[-- Attachment #2: Type: text/html, Size: 647 bytes --]

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

end of thread, other threads:[~2008-03-24  4:15 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-03-05  8:49 [PATCH] cdrom access patch Bean
2008-03-07 15:37 ` Vesa Jääskeläinen
2008-03-09 15:33   ` Bean
2008-03-10 15:53     ` Bean
2008-03-11 21:10       ` Christian Franke
2008-03-12  5:26         ` Bean
2008-03-12  6:52           ` Christian Franke
2008-03-13 22:59           ` Christian Franke
2008-03-14  5:33             ` Bean
2008-03-14 17:28               ` Pavel Roskin
2008-03-14 19:58                 ` Bean
2008-03-14 20:56                   ` Bean
2008-03-14 20:58                     ` Vesa Jääskeläinen
2008-03-15  7:34                       ` Bean
2008-03-15  8:49                         ` Vesa Jääskeläinen
2008-03-15 10:54                           ` Bean
2008-03-15 19:01                           ` Christian Franke
2008-03-17  4:31                         ` Pavel Roskin
2008-03-17  6:21                           ` Bean
2008-03-19 22:09                             ` Pavel Roskin
2008-03-20  6:06                               ` Bean
2008-03-24  4:15                                 ` Bean
2008-03-14 23:20                     ` Christian Franke
  -- strict thread matches above, loose matches on Subject: below --
2008-03-06 23:58 Kalamatee
2008-03-08 20:16 Kalamatee

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.