disk.h 7.25 KB
Newer Older
okuji's avatar
okuji committed
1
/*
2
 *  GRUB  --  GRand Unified Bootloader
3
 *  Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Free Software Foundation, Inc.
okuji's avatar
okuji committed
4
 *
5
 *  GRUB is free software: you can redistribute it and/or modify
okuji's avatar
okuji committed
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation, either version 3 of the License, or
okuji's avatar
okuji committed
8 9
 *  (at your option) any later version.
 *
10
 *  GRUB is distributed in the hope that it will be useful,
okuji's avatar
okuji committed
11 12 13 14 15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
okuji's avatar
okuji committed
17 18
 */

19 20
#ifndef GRUB_DISK_HEADER
#define GRUB_DISK_HEADER	1
okuji's avatar
okuji committed
21

22 23
#include <config.h>

24 25 26 27
#include <grub/symbol.h>
#include <grub/err.h>
#include <grub/types.h>
#include <grub/device.h>
28 29
/* For NULL.  */
#include <grub/mm.h>
okuji's avatar
okuji committed
30

31 32 33 34 35 36
/* These are used to set a device id. When you add a new disk device,
   you must define a new id for it here.  */
enum grub_disk_dev_id
  {
    GRUB_DISK_DEVICE_BIOSDISK_ID,
    GRUB_DISK_DEVICE_OFDISK_ID,
37
    GRUB_DISK_DEVICE_LOOPBACK_ID,
38
    GRUB_DISK_DEVICE_EFIDISK_ID,
39
    GRUB_DISK_DEVICE_DISKFILTER_ID,
40
    GRUB_DISK_DEVICE_HOST_ID,
41 42
    GRUB_DISK_DEVICE_ATA_ID,
    GRUB_DISK_DEVICE_MEMDISK_ID,
43
    GRUB_DISK_DEVICE_NAND_ID,
44
    GRUB_DISK_DEVICE_SCSI_ID,
45
    GRUB_DISK_DEVICE_CRYPTODISK_ID,
46
    GRUB_DISK_DEVICE_ARCDISK_ID,
47
    GRUB_DISK_DEVICE_HOSTDISK_ID,
48
    GRUB_DISK_DEVICE_PROCFS_ID,
49
    GRUB_DISK_DEVICE_CBFSDISK_ID,
50
    GRUB_DISK_DEVICE_UBOOTDISK_ID,
51
    GRUB_DISK_DEVICE_XEN,
52 53
  };

54
struct grub_disk;
55 56 57
#ifdef GRUB_UTIL
struct grub_disk_memberlist;
#endif
okuji's avatar
okuji committed
58

59 60 61 62 63 64 65 66
typedef enum
  { 
    GRUB_DISK_PULL_NONE,
    GRUB_DISK_PULL_REMOVABLE,
    GRUB_DISK_PULL_RESCAN,
    GRUB_DISK_PULL_MAX
  } grub_disk_pull_t;

67 68
typedef int (*grub_disk_dev_iterate_hook_t) (const char *name, void *data);

okuji's avatar
okuji committed
69
/* Disk device.  */
70
struct grub_disk_dev
okuji's avatar
okuji committed
71 72 73 74
{
  /* The device name.  */
  const char *name;

75
  /* The device id used by the cache manager.  */
76
  enum grub_disk_dev_id id;
77

okuji's avatar
okuji committed
78
  /* Call HOOK with each device name, until HOOK returns non-zero.  */
79
  int (*iterate) (grub_disk_dev_iterate_hook_t hook, void *hook_data,
80
		  grub_disk_pull_t pull);
okuji's avatar
okuji committed
81 82

  /* Open the device named NAME, and set up DISK.  */
83
  grub_err_t (*open) (const char *name, struct grub_disk *disk);
okuji's avatar
okuji committed
84 85

  /* Close the disk DISK.  */
86
  void (*close) (struct grub_disk *disk);
okuji's avatar
okuji committed
87 88

  /* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF.  */
89 90
  grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector,
		      grub_size_t size, char *buf);
okuji's avatar
okuji committed
91 92

  /* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK.  */
93 94
  grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector,
		       grub_size_t size, const char *buf);
okuji's avatar
okuji committed
95

96 97
#ifdef GRUB_UTIL
  struct grub_disk_memberlist *(*memberlist) (struct grub_disk *disk);
98
  const char * (*raidname) (struct grub_disk *disk);
99 100
#endif

okuji's avatar
okuji committed
101
  /* The next disk device.  */
102
  struct grub_disk_dev *next;
okuji's avatar
okuji committed
103
};
104
typedef struct grub_disk_dev *grub_disk_dev_t;
okuji's avatar
okuji committed
105

106 107
extern grub_disk_dev_t EXPORT_VAR (grub_disk_dev_list);

108
struct grub_partition;
okuji's avatar
okuji committed
109

110 111 112 113
typedef void (*grub_disk_read_hook_t) (grub_disk_addr_t sector,
				       unsigned offset, unsigned length,
				       void *data);

okuji's avatar
okuji committed
114
/* Disk.  */
115
struct grub_disk
okuji's avatar
okuji committed
116 117 118 119 120
{
  /* The disk name.  */
  const char *name;

  /* The underlying disk device.  */
121
  grub_disk_dev_t dev;
okuji's avatar
okuji committed
122 123

  /* The total number of sectors.  */
124
  grub_uint64_t total_sectors;
okuji's avatar
okuji committed
125

126 127 128
  /* Logarithm of sector size.  */
  unsigned int log_sector_size;

129 130 131
  /* Maximum number of sectors read divided by GRUB_DISK_CACHE_SIZE.  */
  unsigned int max_agglomerate;

okuji's avatar
okuji committed
132 133
  /* The id used by the disk cache manager.  */
  unsigned long id;
134

okuji's avatar
okuji committed
135
  /* The partition information. This is machine-specific.  */
136
  struct grub_partition *partition;
okuji's avatar
okuji committed
137

138 139
  /* Called when a sector was read. OFFSET is between 0 and
     the sector size minus 1, and LENGTH is between 0 and the sector size.  */
140 141 142 143
  grub_disk_read_hook_t read_hook;

  /* Caller-specific data passed to the read hook.  */
  void *read_hook_data;
okuji's avatar
okuji committed
144 145 146 147

  /* Device-specific data.  */
  void *data;
};
148
typedef struct grub_disk *grub_disk_t;
okuji's avatar
okuji committed
149

150 151 152 153 154 155 156 157 158
#ifdef GRUB_UTIL
struct grub_disk_memberlist
{
  grub_disk_t disk;
  struct grub_disk_memberlist *next;
};
typedef struct grub_disk_memberlist *grub_disk_memberlist_t;
#endif

okuji's avatar
okuji committed
159
/* The sector size.  */
160 161
#define GRUB_DISK_SECTOR_SIZE	0x200
#define GRUB_DISK_SECTOR_BITS	9
okuji's avatar
okuji committed
162 163

/* The maximum number of disk caches.  */
164
#define GRUB_DISK_CACHE_NUM	1021
okuji's avatar
okuji committed
165

166 167 168 169
/* The size of a disk cache in 512B units. Must be at least as big as the
   largest supported sector size, currently 16K.  */
#define GRUB_DISK_CACHE_BITS	6
#define GRUB_DISK_CACHE_SIZE	(1 << GRUB_DISK_CACHE_BITS)
okuji's avatar
okuji committed
170

171 172
#define GRUB_DISK_MAX_MAX_AGGLOMERATE ((1 << (30 - GRUB_DISK_CACHE_BITS - GRUB_DISK_SECTOR_BITS)) - 1)

173 174 175
/* Return value of grub_disk_get_size() in case disk size is unknown. */
#define GRUB_DISK_SIZE_UNKNOWN	 0xffffffffffffffffULL

okuji's avatar
okuji committed
176
/* This is called from the memory manager.  */
177
void grub_disk_cache_invalidate_all (void);
okuji's avatar
okuji committed
178

179 180
void EXPORT_FUNC(grub_disk_dev_register) (grub_disk_dev_t dev);
void EXPORT_FUNC(grub_disk_dev_unregister) (grub_disk_dev_t dev);
181
static inline int
182
grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data)
183 184 185 186 187 188
{
  grub_disk_dev_t p;
  grub_disk_pull_t pull;

  for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
    for (p = grub_disk_dev_list; p; p = p->next)
189
      if (p->iterate && (p->iterate) (hook, hook_data, pull))
190 191 192 193
	return 1;

  return 0;
}
okuji's avatar
okuji committed
194

195 196 197
grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name);
void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk);
grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
198 199 200
					grub_disk_addr_t sector,
					grub_off_t offset,
					grub_size_t size,
201
					void *buf);
202 203 204 205 206 207 208 209 210 211 212
grub_err_t grub_disk_write (grub_disk_t disk,
			    grub_disk_addr_t sector,
			    grub_off_t offset,
			    grub_size_t size,
			    const void *buf);
extern grub_err_t (*EXPORT_VAR(grub_disk_write_weak)) (grub_disk_t disk,
						       grub_disk_addr_t sector,
						       grub_off_t offset,
						       grub_size_t size,
						       const void *buf);

okuji's avatar
okuji committed
213

214
grub_uint64_t EXPORT_FUNC(grub_disk_get_size) (grub_disk_t disk);
215

216 217 218 219 220
#if DISK_CACHE_STATS
void
EXPORT_FUNC(grub_disk_cache_get_performance) (unsigned long *hits, unsigned long *misses);
#endif

221 222 223
extern void (* EXPORT_VAR(grub_disk_firmware_fini)) (void);
extern int EXPORT_VAR(grub_disk_firmware_is_tainted);

224 225 226 227 228 229 230 231 232 233 234 235
static inline void
grub_stop_disk_firmware (void)
{
  /* To prevent two drivers operating on the same disks.  */
  grub_disk_firmware_is_tainted = 1;
  if (grub_disk_firmware_fini)
    {
      grub_disk_firmware_fini ();
      grub_disk_firmware_fini = NULL;
    }
}

236 237 238 239 240 241 242 243 244 245 246 247
/* Disk cache.  */
struct grub_disk_cache
{
  enum grub_disk_dev_id dev_id;
  unsigned long disk_id;
  grub_disk_addr_t sector;
  char *data;
  int lock;
};

extern struct grub_disk_cache EXPORT_VAR(grub_disk_cache_table)[GRUB_DISK_CACHE_NUM];

248
#if defined (GRUB_UTIL)
249
void grub_lvm_init (void);
250
void grub_ldm_init (void);
251 252
void grub_mdraid09_init (void);
void grub_mdraid1x_init (void);
253
void grub_diskfilter_init (void);
254
void grub_lvm_fini (void);
255
void grub_ldm_fini (void);
256 257
void grub_mdraid09_fini (void);
void grub_mdraid1x_fini (void);
258
void grub_diskfilter_fini (void);
259 260
#endif

261
#endif /* ! GRUB_DISK_HEADER */