51ef84df3dfb2682c4eb0dfb7a19328e4f02b0eb
[linux-2.6.git] / include / linux / dumpdev.h
1 /*
2  * Generic dump device interfaces for flexible system dump 
3  * (Enables variation of dump target types e.g disk, network, memory)
4  *
5  * These interfaces have evolved based on discussions on lkcd-devel. 
6  * Eventually the intent is to support primary and secondary or 
7  * alternate targets registered at the same time, with scope for 
8  * situation based failover or multiple dump devices used for parallel 
9  * dump i/o.
10  *
11  * Started: Oct 2002 - Suparna Bhattacharya (suparna@in.ibm.com)
12  *
13  * Copyright (C) 2001 - 2002 Matt D. Robinson.  All rights reserved.
14  * Copyright (C) 2002 International Business Machines Corp. 
15  *
16  * This code is released under version 2 of the GNU GPL.
17  */
18
19 #ifndef _LINUX_DUMPDEV_H
20 #define _LINUX_DUMPDEV_H
21
22 #include <linux/kernel.h>
23 #include <linux/wait.h>
24 #include <linux/bio.h>
25
26 /* Determined by the dump target (device) type */
27
28 struct dump_dev;
29
30 struct dump_dev_ops {
31         int (*open)(struct dump_dev *, unsigned long); /* configure */
32         int (*release)(struct dump_dev *); /* unconfigure */
33         int (*silence)(struct dump_dev *); /* when dump starts */
34         int (*resume)(struct dump_dev *); /* when dump is over */
35         int (*seek)(struct dump_dev *, loff_t);
36         /* trigger a write (async in nature typically) */
37         int (*write)(struct dump_dev *, void *, unsigned long);
38         /* not usually used during dump, but option available */
39         int (*read)(struct dump_dev *, void *, unsigned long);
40         /* use to poll for completion */
41         int (*ready)(struct dump_dev *, void *); 
42         int (*ioctl)(struct dump_dev *, unsigned int, unsigned long);
43 };
44
45 struct dump_dev {
46         char type_name[32]; /* block, net-poll etc */
47         unsigned long device_id; /* interpreted differently for various types */
48         struct dump_dev_ops *ops;
49         struct list_head list;
50         loff_t curr_offset;
51 };
52
53 /*
54  * dump_dev type variations: 
55  */
56
57 /* block */
58 struct dump_blockdev {
59         struct dump_dev ddev;
60         dev_t dev_id;
61         struct block_device *bdev;
62         struct bio *bio;
63         loff_t start_offset;
64         loff_t limit;
65         int err;
66 };
67
68 static inline struct dump_blockdev *DUMP_BDEV(struct dump_dev *dev)
69 {
70         return container_of(dev, struct dump_blockdev, ddev);
71 }
72
73
74 /* mem  - for internal use by soft-boot based dumper */
75 struct dump_memdev {
76         struct dump_dev ddev;
77         unsigned long indirect_map_root;
78         unsigned long nr_free;
79         struct page *curr_page;
80         unsigned long *curr_map;
81         unsigned long curr_map_offset;
82         unsigned long last_offset;
83         unsigned long last_used_offset;
84         unsigned long last_bs_offset;
85 };      
86
87 static inline struct dump_memdev *DUMP_MDEV(struct dump_dev *dev)
88 {
89         return container_of(dev, struct dump_memdev, ddev);
90 }
91
92 /* Todo/future - meant for raw dedicated interfaces e.g. mini-ide driver */
93 struct dump_rdev {
94         struct dump_dev ddev;
95         char name[32];
96         int (*reset)(struct dump_rdev *, unsigned int, 
97                 unsigned long);
98         /* ... to do ... */
99 };
100
101 /* just to get the size right when saving config across a soft-reboot */
102 struct dump_anydev {
103         union {
104                 struct dump_blockdev bddev;
105                 /* .. add other types here .. */
106         };
107 };
108
109
110
111 /* Dump device / target operation wrappers */
112 /* These assume that dump_dev is initiatized to dump_config.dumper->dev */
113
114 extern struct dump_dev *dump_dev;
115
116 static inline int dump_dev_open(unsigned long arg)
117 {
118         return dump_dev->ops->open(dump_dev, arg);
119 }
120
121 static inline int dump_dev_release(void)
122 {
123         return dump_dev->ops->release(dump_dev);
124 }
125
126 static inline int dump_dev_silence(void)
127 {
128         return dump_dev->ops->silence(dump_dev);
129 }
130
131 static inline int dump_dev_resume(void)
132 {
133         return dump_dev->ops->resume(dump_dev);
134 }
135
136 static inline int dump_dev_seek(loff_t offset)
137 {
138         return dump_dev->ops->seek(dump_dev, offset);
139 }
140
141 static inline int dump_dev_write(void *buf, unsigned long len)
142 {
143         return dump_dev->ops->write(dump_dev, buf, len);
144 }
145
146 static inline int dump_dev_ready(void *buf)
147 {
148         return dump_dev->ops->ready(dump_dev, buf);
149 }
150
151 static inline int dump_dev_ioctl(unsigned int cmd, unsigned long arg)
152 {
153         if (!dump_dev || !dump_dev->ops->ioctl)
154                 return -EINVAL;
155         return dump_dev->ops->ioctl(dump_dev, cmd, arg);
156 }
157
158 extern int dump_register_device(struct dump_dev *);
159 extern void dump_unregister_device(struct dump_dev *);
160
161 #endif /*  _LINUX_DUMPDEV_H */