~ubuntu-branches/ubuntu/trusty/grub2/trusty-updates

« back to all changes in this revision

Viewing changes to disk/ieee1275/ofdisk.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2006-01-05 15:20:40 UTC
  • mto: (17.3.1 squeeze) (1.9.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20060105152040-b72i5pq1a82z22yi
Tags: upstream-1.92
ImportĀ upstreamĀ versionĀ 1.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ofdisk.c - Open Firmware disk access.  */
 
2
/*
 
3
 *  GRUB  --  GRand Unified Bootloader
 
4
 *  Copyright (C) 2004  Free Software Foundation, Inc.
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 */
 
20
 
 
21
#include <grub/misc.h>
 
22
#include <grub/disk.h>
 
23
#include <grub/mm.h>
 
24
#include <grub/ieee1275/ieee1275.h>
 
25
#include <grub/ieee1275/ofdisk.h>
 
26
 
 
27
static int
 
28
grub_ofdisk_iterate (int (*hook) (const char *name))
 
29
{
 
30
  auto int dev_iterate (struct grub_ieee1275_devalias *alias);
 
31
  
 
32
  int dev_iterate (struct grub_ieee1275_devalias *alias)
 
33
    {
 
34
      if (! grub_strcmp (alias->type, "block"))
 
35
        hook (alias->name);
 
36
      else if ((! grub_strcmp (alias->type, "scsi"))
 
37
               || (! grub_strcmp (alias->type, "ide"))
 
38
               || (! grub_strcmp (alias->type, "ata")))
 
39
        /* Search for block-type children of these bus controllers.  */
 
40
        grub_children_iterate (alias->name, dev_iterate);
 
41
      return 0;
 
42
    }
 
43
 
 
44
  grub_devalias_iterate (dev_iterate);
 
45
  return 0;
 
46
}
 
47
 
 
48
static grub_err_t
 
49
grub_ofdisk_open (const char *name, grub_disk_t disk)
 
50
{
 
51
  grub_ieee1275_phandle_t dev;
 
52
  grub_ieee1275_ihandle_t dev_ihandle = 0;
 
53
  char *devpath;
 
54
  /* XXX: This should be large enough for any possible case.  */
 
55
  char prop[64];
 
56
  grub_ssize_t actual;
 
57
 
 
58
  devpath = grub_strndup (name, grub_strlen (name) + 2);
 
59
  if (! devpath)
 
60
    return grub_errno;
 
61
 
 
62
  /* To access the complete disk add `:0'.  */
 
63
  if (! grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PARTITION_0))
 
64
    grub_strcat (devpath, ":0");
 
65
 
 
66
  grub_dprintf ("disk", "Opening `%s'.\n", devpath);
 
67
 
 
68
  grub_ieee1275_open (devpath, &dev_ihandle);
 
69
  if (! dev_ihandle)
 
70
    {
 
71
      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
 
72
      goto fail;
 
73
    }
 
74
 
 
75
  grub_dprintf ("disk", "Opened `%s' as handle %p.\n", devpath, (void *) dev_ihandle);
 
76
 
 
77
  if (grub_ieee1275_finddevice (devpath, &dev))
 
78
    {
 
79
      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read device properties");
 
80
      goto fail;
 
81
    }
 
82
 
 
83
  if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop),
 
84
                                  &actual))
 
85
    {
 
86
      grub_error (GRUB_ERR_BAD_DEVICE, "Can't read the device type");
 
87
      goto fail;
 
88
    }
 
89
 
 
90
  if (grub_strcmp (prop, "block"))
 
91
    {
 
92
      grub_error (GRUB_ERR_BAD_DEVICE, "Not a block device");
 
93
      goto fail;
 
94
    }
 
95
 
 
96
  /* XXX: There is no property to read the number of blocks.  There
 
97
     should be a property `#blocks', but it is not there.  Perhaps it
 
98
     is possible to use seek for this.  */
 
99
  disk->total_sectors = 0xFFFFFFFFUL;
 
100
 
 
101
  /* XXX: Is it ok to use this?  Perhaps it is better to use the path
 
102
     or some property.  */
 
103
  disk->id = dev;
 
104
 
 
105
  /* XXX: Read this, somehow.  */
 
106
  disk->has_partitions = 1;
 
107
  disk->data = (void *) dev_ihandle;
 
108
 
 
109
 fail:
 
110
  if (grub_errno && dev_ihandle)
 
111
    grub_ieee1275_close (dev_ihandle);
 
112
  grub_free (devpath);
 
113
  return grub_errno;
 
114
}
 
115
 
 
116
static void
 
117
grub_ofdisk_close (grub_disk_t disk)
 
118
{
 
119
  grub_dprintf ("disk", "Closing handle %p.\n",
 
120
                (void *) disk->data);
 
121
  grub_ieee1275_close ((grub_ieee1275_ihandle_t) disk->data);
 
122
}
 
123
 
 
124
static grub_err_t
 
125
grub_ofdisk_read (grub_disk_t disk, unsigned long sector,
 
126
                  unsigned long size, char *buf)
 
127
{
 
128
  grub_ssize_t status, actual;
 
129
  unsigned long long pos;
 
130
 
 
131
  grub_dprintf ("disk",
 
132
                "Reading handle %p: sector 0x%lx, size 0x%lx, buf %p.\n",
 
133
                (void *) disk->data, sector, size, buf);
 
134
 
 
135
  pos = (unsigned long long) sector * 512UL;
 
136
 
 
137
  grub_ieee1275_seek ((grub_ieee1275_ihandle_t) disk->data, (int) (pos >> 32),
 
138
                      (int) pos & 0xFFFFFFFFUL, &status);
 
139
  if (status != 0)
 
140
    return grub_error (GRUB_ERR_READ_ERROR,
 
141
                       "Seek error, can't seek block %d", sector);
 
142
  grub_ieee1275_read ((grub_ieee1275_ihandle_t) disk->data, buf,
 
143
                      size * 512UL, &actual);
 
144
  if (actual != actual)
 
145
    return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %d", sector);
 
146
    
 
147
  return 0;
 
148
}
 
149
 
 
150
static grub_err_t
 
151
grub_ofdisk_write (grub_disk_t disk __attribute ((unused)),
 
152
                   unsigned long sector __attribute ((unused)),
 
153
                   unsigned long size __attribute ((unused)),
 
154
                   const char *buf __attribute ((unused)))
 
155
{
 
156
  return GRUB_ERR_NOT_IMPLEMENTED_YET;
 
157
}
 
158
 
 
159
static struct grub_disk_dev grub_ofdisk_dev =
 
160
  {
 
161
    .name = "ofdisk",
 
162
    .id = GRUB_DISK_DEVICE_OFDISK_ID,
 
163
    .iterate = grub_ofdisk_iterate,
 
164
    .open = grub_ofdisk_open,
 
165
    .close = grub_ofdisk_close,
 
166
    .read = grub_ofdisk_read,
 
167
    .write = grub_ofdisk_write,
 
168
    .next = 0
 
169
  };
 
170
 
 
171
void
 
172
grub_ofdisk_init (void)
 
173
{
 
174
  grub_disk_dev_register (&grub_ofdisk_dev);
 
175
}
 
176
 
 
177
void
 
178
grub_ofdisk_fini (void)
 
179
{
 
180
  grub_disk_dev_unregister (&grub_ofdisk_dev);
 
181
}