[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Don't open same disk twice on OpenFirmware.
From: |
Vladimir 'φ-coder/phcoder' Serbinenko |
Subject: |
[PATCH] Don't open same disk twice on OpenFirmware. |
Date: |
Fri, 18 Dec 2009 17:17:13 +0100 |
User-agent: |
Mozilla-Thunderbird 2.0.0.22 (X11/20091109) |
Hello, all. According to David Miller sparc's openboot doesn't support
opening same disk twice. So I implemented handle reusage logic. Tested
on imac g3
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
=== modified file 'disk/ieee1275/ofdisk.c'
--- disk/ieee1275/ofdisk.c 2009-12-07 10:54:25 +0000
+++ disk/ieee1275/ofdisk.c 2009-12-18 16:12:28 +0000
@@ -1,7 +1,7 @@
/* ofdisk.c - Open Firmware disk access. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2006,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -26,6 +26,8 @@
struct ofdisk_hash_ent
{
char *devpath;
+ int refs;
+ grub_ieee1275_ihandle_t dev_ihandle;
struct ofdisk_hash_ent *next;
};
@@ -65,6 +67,8 @@ ofdisk_hash_add (char *devpath)
{
p->devpath = devpath;
p->next = *head;
+ p->refs = 0;
+ p->dev_ihandle = 0;
*head = p;
}
return p;
@@ -170,6 +174,23 @@ grub_ofdisk_open (const char *name, grub
if (!op)
return grub_errno;
+ if (op->dev_ihandle)
+ {
+ op->refs++;
+
+ /* XXX: There is no property to read the number of blocks. There
+ should be a property `#blocks', but it is not there. Perhaps it
+ is possible to use seek for this. */
+ disk->total_sectors = 0xFFFFFFFFUL;
+
+ disk->id = (unsigned long) op;
+
+ /* XXX: Read this, somehow. */
+ disk->has_partitions = 1;
+ disk->data = op;
+ return 0;
+ }
+
grub_dprintf ("disk", "Opening `%s'.\n", op->devpath);
grub_ieee1275_open (op->devpath, &dev_ihandle);
@@ -179,8 +200,8 @@ grub_ofdisk_open (const char *name, grub
goto fail;
}
- grub_dprintf ("disk", "Opened `%s' as handle %p.\n", op->devpath,
- (void *) (unsigned long) dev_ihandle);
+ grub_dprintf ("disk", "Opened `%s' as handle 0x%lx.\n", op->devpath,
+ (unsigned long) dev_ihandle);
if (grub_ieee1275_finddevice (op->devpath, &dev))
{
@@ -201,6 +222,9 @@ grub_ofdisk_open (const char *name, grub
goto fail;
}
+ op->dev_ihandle = dev_ihandle;
+ op->refs++;
+
/* XXX: There is no property to read the number of blocks. There
should be a property `#blocks', but it is not there. Perhaps it
is possible to use seek for this. */
@@ -210,7 +234,7 @@ grub_ofdisk_open (const char *name, grub
/* XXX: Read this, somehow. */
disk->has_partitions = 1;
- disk->data = (void *) (unsigned long) dev_ihandle;
+ disk->data = op;
return 0;
fail:
@@ -222,9 +246,15 @@ grub_ofdisk_open (const char *name, grub
static void
grub_ofdisk_close (grub_disk_t disk)
{
- grub_dprintf ("disk", "Closing handle %p.\n",
- (void *) disk->data);
- grub_ieee1275_close ((grub_ieee1275_ihandle_t) (unsigned long) disk->data);
+ struct ofdisk_hash_ent *data = disk->data;
+
+ data->refs--;
+ if (data->refs)
+ return;
+
+ grub_dprintf ("disk", "Closing handle %p.\n", data);
+ grub_ieee1275_close (data->dev_ihandle);
+ data->dev_ihandle = 0;
}
static grub_err_t
@@ -233,21 +263,21 @@ grub_ofdisk_read (grub_disk_t disk, grub
{
grub_ssize_t status, actual;
unsigned long long pos;
+ struct ofdisk_hash_ent *data = disk->data;
grub_dprintf ("disk",
"Reading handle %p: sector 0x%llx, size 0x%lx, buf %p.\n",
- (void *) disk->data, (long long) sector, (long) size, buf);
+ data, (long long) sector, (long) size, buf);
pos = sector * 512UL;
- grub_ieee1275_seek ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
+ grub_ieee1275_seek (data->dev_ihandle,
(int) (pos >> 32), (int) pos & 0xFFFFFFFFUL, &status);
if (status < 0)
return grub_error (GRUB_ERR_READ_ERROR,
"Seek error, can't seek block %llu",
(long long) sector);
- grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
- buf, size * 512UL, &actual);
+ grub_ieee1275_read (data->dev_ihandle, buf, size * 512UL, &actual);
if (actual != actual)
return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu",
(long long) sector);
signature.asc
Description: OpenPGP digital signature
- [PATCH] Don't open same disk twice on OpenFirmware.,
Vladimir 'φ-coder/phcoder' Serbinenko <=