aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-10-11 00:59:54 -0400
committerPaul Mackerras <paulus@samba.org>2007-10-11 06:40:48 -0400
commit8251b4c481bca72568e9c1042ea11189838e5f6d (patch)
tree41991f93aec12592885ac33a5312dcf4024ebe5f
parent7465ce0db310d2fa29f721da7e3aacd1dad7090f (diff)
[POWERPC] iSeries: Move viodasd probing
This way we only have entries in the device tree for disks that actually exist. A slight complication is that disks may be attached to LPARs at runtime. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/iseries/dt.c6
-rw-r--r--arch/powerpc/platforms/iseries/vio.c301
-rw-r--r--drivers/block/viodasd.c77
-rw-r--r--include/asm-powerpc/iseries/vio.h47
4 files changed, 282 insertions, 149 deletions
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 2e4ad6b34506..4543c4bc3a56 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -72,7 +72,6 @@ static char __initdata device_type_cpu[] = "cpu";
72static char __initdata device_type_memory[] = "memory"; 72static char __initdata device_type_memory[] = "memory";
73static char __initdata device_type_serial[] = "serial"; 73static char __initdata device_type_serial[] = "serial";
74static char __initdata device_type_network[] = "network"; 74static char __initdata device_type_network[] = "network";
75static char __initdata device_type_block[] = "block";
76static char __initdata device_type_pci[] = "pci"; 75static char __initdata device_type_pci[] = "pci";
77static char __initdata device_type_vdevice[] = "vdevice"; 76static char __initdata device_type_vdevice[] = "vdevice";
78static char __initdata device_type_vscsi[] = "vscsi"; 77static char __initdata device_type_vscsi[] = "vscsi";
@@ -374,11 +373,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
374 373
375 dt_end_node(dt); 374 dt_end_node(dt);
376 } 375 }
377 reg += HVMAXARCHITECTEDVIRTUALLANS;
378
379 for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
380 dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
381 "IBM,iSeries-viodasd", 1);
382 376
383 dt_end_node(dt); 377 dt_end_node(dt);
384} 378}
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index a4cc990a26a0..910b00b4703e 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -25,8 +25,10 @@
25#include <linux/gfp.h> 25#include <linux/gfp.h>
26#include <linux/completion.h> 26#include <linux/completion.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/module.h>
28 29
29#include <asm/firmware.h> 30#include <asm/firmware.h>
31#include <asm/vio.h>
30#include <asm/iseries/vio.h> 32#include <asm/iseries/vio.h>
31#include <asm/iseries/iommu.h> 33#include <asm/iseries/iommu.h>
32#include <asm/iseries/hv_types.h> 34#include <asm/iseries/hv_types.h>
@@ -57,7 +59,7 @@ struct vio_resource {
57 char model[3]; 59 char model[3];
58}; 60};
59 61
60static struct property * __init new_property(const char *name, int length, 62static struct property *new_property(const char *name, int length,
61 const void *value) 63 const void *value)
62{ 64{
63 struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length, 65 struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
@@ -78,7 +80,7 @@ static void __init free_property(struct property *np)
78 kfree(np); 80 kfree(np);
79} 81}
80 82
81static struct device_node * __init new_node(const char *path, 83static struct device_node *new_node(const char *path,
82 struct device_node *parent) 84 struct device_node *parent)
83{ 85{
84 struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL); 86 struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
@@ -97,7 +99,7 @@ static struct device_node * __init new_node(const char *path,
97 return np; 99 return np;
98} 100}
99 101
100static void __init free_node(struct device_node *np) 102static void free_node(struct device_node *np)
101{ 103{
102 struct property *next; 104 struct property *next;
103 struct property *prop; 105 struct property *prop;
@@ -113,7 +115,7 @@ static void __init free_node(struct device_node *np)
113 kfree(np); 115 kfree(np);
114} 116}
115 117
116static int __init add_string_property(struct device_node *np, const char *name, 118static int add_string_property(struct device_node *np, const char *name,
117 const char *value) 119 const char *value)
118{ 120{
119 struct property *nprop = new_property(name, strlen(value) + 1, value); 121 struct property *nprop = new_property(name, strlen(value) + 1, value);
@@ -124,7 +126,7 @@ static int __init add_string_property(struct device_node *np, const char *name,
124 return 1; 126 return 1;
125} 127}
126 128
127static int __init add_raw_property(struct device_node *np, const char *name, 129static int add_raw_property(struct device_node *np, const char *name,
128 int length, const void *value) 130 int length, const void *value)
129{ 131{
130 struct property *nprop = new_property(name, length, value); 132 struct property *nprop = new_property(name, length, value);
@@ -135,6 +137,201 @@ static int __init add_raw_property(struct device_node *np, const char *name,
135 return 1; 137 return 1;
136} 138}
137 139
140static struct device_node *do_device_node(struct device_node *parent,
141 const char *name, u32 reg, u32 unit, const char *type,
142 const char *compat, struct vio_resource *res)
143{
144 struct device_node *np;
145 char path[32];
146
147 snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg);
148 np = new_node(path, parent);
149 if (!np)
150 return NULL;
151 if (!add_string_property(np, "name", name) ||
152 !add_string_property(np, "device_type", type) ||
153 !add_string_property(np, "compatible", compat) ||
154 !add_raw_property(np, "reg", sizeof(reg), &reg) ||
155 !add_raw_property(np, "linux,unit_address",
156 sizeof(unit), &unit)) {
157 goto node_free;
158 }
159 if (res) {
160 if (!add_raw_property(np, "linux,vio_rsrcname",
161 sizeof(res->rsrcname), res->rsrcname) ||
162 !add_raw_property(np, "linux,vio_type",
163 sizeof(res->type), res->type) ||
164 !add_raw_property(np, "linux,vio_model",
165 sizeof(res->model), res->model))
166 goto node_free;
167 }
168 np->name = of_get_property(np, "name", NULL);
169 np->type = of_get_property(np, "device_type", NULL);
170 of_attach_node(np);
171#ifdef CONFIG_PROC_DEVICETREE
172 if (parent->pde) {
173 struct proc_dir_entry *ent;
174
175 ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde);
176 if (ent)
177 proc_device_tree_add_node(np, ent);
178 }
179#endif
180 return np;
181
182 node_free:
183 free_node(np);
184 return NULL;
185}
186
187/*
188 * This is here so that we can dynamically add viodasd
189 * devices without exposing all the above infrastructure.
190 */
191struct vio_dev *vio_create_viodasd(u32 unit)
192{
193 struct device_node *vio_root;
194 struct device_node *np;
195 struct vio_dev *vdev = NULL;
196
197 vio_root = of_find_node_by_path("/vdevice");
198 if (!vio_root)
199 return NULL;
200 np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
201 "block", "IBM,iSeries-viodasd", NULL);
202 of_node_put(vio_root);
203 if (np) {
204 vdev = vio_register_device_node(np);
205 if (!vdev)
206 free_node(np);
207 }
208 return vdev;
209}
210EXPORT_SYMBOL_GPL(vio_create_viodasd);
211
212static void __init handle_block_event(struct HvLpEvent *event)
213{
214 struct vioblocklpevent *bevent = (struct vioblocklpevent *)event;
215 struct vio_waitevent *pwe;
216
217 if (event == NULL)
218 /* Notification that a partition went away! */
219 return;
220 /* First, we should NEVER get an int here...only acks */
221 if (hvlpevent_is_int(event)) {
222 printk(KERN_WARNING "handle_viod_request: "
223 "Yikes! got an int in viodasd event handler!\n");
224 if (hvlpevent_need_ack(event)) {
225 event->xRc = HvLpEvent_Rc_InvalidSubtype;
226 HvCallEvent_ackLpEvent(event);
227 }
228 return;
229 }
230
231 switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
232 case vioblockopen:
233 /*
234 * Handle a response to an open request. We get all the
235 * disk information in the response, so update it. The
236 * correlation token contains a pointer to a waitevent
237 * structure that has a completion in it. update the
238 * return code in the waitevent structure and post the
239 * completion to wake up the guy who sent the request
240 */
241 pwe = (struct vio_waitevent *)event->xCorrelationToken;
242 pwe->rc = event->xRc;
243 pwe->sub_result = bevent->sub_result;
244 complete(&pwe->com);
245 break;
246 case vioblockclose:
247 break;
248 default:
249 printk(KERN_WARNING "handle_viod_request: unexpected subtype!");
250 if (hvlpevent_need_ack(event)) {
251 event->xRc = HvLpEvent_Rc_InvalidSubtype;
252 HvCallEvent_ackLpEvent(event);
253 }
254 }
255}
256
257static void __init probe_disk(struct device_node *vio_root, u32 unit)
258{
259 HvLpEvent_Rc hvrc;
260 struct vio_waitevent we;
261 u16 flags = 0;
262
263retry:
264 init_completion(&we.com);
265
266 /* Send the open event to OS/400 */
267 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
268 HvLpEvent_Type_VirtualIo,
269 viomajorsubtype_blockio | vioblockopen,
270 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
271 viopath_sourceinst(viopath_hostLp),
272 viopath_targetinst(viopath_hostLp),
273 (u64)(unsigned long)&we, VIOVERSION << 16,
274 ((u64)unit << 48) | ((u64)flags<< 32),
275 0, 0, 0);
276 if (hvrc != 0) {
277 printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n",
278 (int)hvrc);
279 return;
280 }
281
282 wait_for_completion(&we.com);
283
284 if (we.rc != 0) {
285 if (flags != 0)
286 return;
287 /* try again with read only flag set */
288 flags = vioblockflags_ro;
289 goto retry;
290 }
291
292 /* Send the close event to OS/400. We DON'T expect a response */
293 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
294 HvLpEvent_Type_VirtualIo,
295 viomajorsubtype_blockio | vioblockclose,
296 HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
297 viopath_sourceinst(viopath_hostLp),
298 viopath_targetinst(viopath_hostLp),
299 0, VIOVERSION << 16,
300 ((u64)unit << 48) | ((u64)flags << 32),
301 0, 0, 0);
302 if (hvrc != 0) {
303 printk(KERN_WARNING "probe_disk: "
304 "bad rc sending event to OS/400 %d\n", (int)hvrc);
305 return;
306 }
307
308 do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
309 "block", "IBM,iSeries-viodasd", NULL);
310}
311
312static void __init get_viodasd_info(struct device_node *vio_root)
313{
314 int rc;
315 u32 unit;
316
317 rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2);
318 if (rc) {
319 printk(KERN_WARNING "get_viodasd_info: "
320 "error opening path to host partition %d\n",
321 viopath_hostLp);
322 return;
323 }
324
325 /* Initialize our request handler */
326 vio_setHandler(viomajorsubtype_blockio, handle_block_event);
327
328 for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++)
329 probe_disk(vio_root, unit);
330
331 vio_clearHandler(viomajorsubtype_blockio);
332 viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2);
333}
334
138static void __init handle_cd_event(struct HvLpEvent *event) 335static void __init handle_cd_event(struct HvLpEvent *event)
139{ 336{
140 struct viocdlpevent *bevent; 337 struct viocdlpevent *bevent;
@@ -233,49 +430,9 @@ static void __init get_viocd_info(struct device_node *vio_root)
233 430
234 for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) && 431 for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
235 unitinfo[unit].rsrcname[0]; unit++) { 432 unitinfo[unit].rsrcname[0]; unit++) {
236 struct device_node *np; 433 if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit,
237 char name[64]; 434 "block", "IBM,iSeries-viocd", &unitinfo[unit]))
238 u32 reg = FIRST_VIOCD + unit; 435 break;
239
240 snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
241 np = new_node(name, vio_root);
242 if (!np)
243 goto hv_free;
244 if (!add_string_property(np, "name", "viocd") ||
245 !add_string_property(np, "device_type", "block") ||
246 !add_string_property(np, "compatible",
247 "IBM,iSeries-viocd") ||
248 !add_raw_property(np, "reg", sizeof(reg), &reg) ||
249 !add_raw_property(np, "linux,unit_address",
250 sizeof(unit), &unit) ||
251 !add_raw_property(np, "linux,vio_rsrcname",
252 sizeof(unitinfo[unit].rsrcname),
253 unitinfo[unit].rsrcname) ||
254 !add_raw_property(np, "linux,vio_type",
255 sizeof(unitinfo[unit].type),
256 unitinfo[unit].type) ||
257 !add_raw_property(np, "linux,vio_model",
258 sizeof(unitinfo[unit].model),
259 unitinfo[unit].model))
260 goto node_free;
261 np->name = of_get_property(np, "name", NULL);
262 np->type = of_get_property(np, "device_type", NULL);
263 of_attach_node(np);
264#ifdef CONFIG_PROC_DEVICETREE
265 if (vio_root->pde) {
266 struct proc_dir_entry *ent;
267
268 ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
269 vio_root->pde);
270 if (ent)
271 proc_device_tree_add_node(np, ent);
272 }
273#endif
274 continue;
275
276 node_free:
277 free_node(np);
278 break;
279 } 436 }
280 437
281 hv_free: 438 hv_free:
@@ -350,49 +507,10 @@ static void __init get_viotape_info(struct device_node *vio_root)
350 507
351 for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) && 508 for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
352 unitinfo[unit].rsrcname[0]; unit++) { 509 unitinfo[unit].rsrcname[0]; unit++) {
353 struct device_node *np; 510 if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit,
354 char name[64]; 511 unit, "byte", "IBM,iSeries-viotape",
355 u32 reg = FIRST_VIOTAPE + unit; 512 &unitinfo[unit]))
356 513 break;
357 snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
358 np = new_node(name, vio_root);
359 if (!np)
360 goto hv_free;
361 if (!add_string_property(np, "name", "viotape") ||
362 !add_string_property(np, "device_type", "byte") ||
363 !add_string_property(np, "compatible",
364 "IBM,iSeries-viotape") ||
365 !add_raw_property(np, "reg", sizeof(reg), &reg) ||
366 !add_raw_property(np, "linux,unit_address",
367 sizeof(unit), &unit) ||
368 !add_raw_property(np, "linux,vio_rsrcname",
369 sizeof(unitinfo[unit].rsrcname),
370 unitinfo[unit].rsrcname) ||
371 !add_raw_property(np, "linux,vio_type",
372 sizeof(unitinfo[unit].type),
373 unitinfo[unit].type) ||
374 !add_raw_property(np, "linux,vio_model",
375 sizeof(unitinfo[unit].model),
376 unitinfo[unit].model))
377 goto node_free;
378 np->name = of_get_property(np, "name", NULL);
379 np->type = of_get_property(np, "device_type", NULL);
380 of_attach_node(np);
381#ifdef CONFIG_PROC_DEVICETREE
382 if (vio_root->pde) {
383 struct proc_dir_entry *ent;
384
385 ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
386 vio_root->pde);
387 if (ent)
388 proc_device_tree_add_node(np, ent);
389 }
390#endif
391 continue;
392
393 node_free:
394 free_node(np);
395 break;
396 } 514 }
397 515
398 hv_free: 516 hv_free:
@@ -422,6 +540,7 @@ static int __init iseries_vio_init(void)
422 goto put_node; 540 goto put_node;
423 } 541 }
424 542
543 get_viodasd_info(vio_root);
425 get_viocd_info(vio_root); 544 get_viocd_info(vio_root);
426 get_viotape_info(vio_root); 545 get_viotape_info(vio_root);
427 546
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index af3969a9c963..e824b672e05a 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -74,53 +74,9 @@ enum {
74static DEFINE_SPINLOCK(viodasd_spinlock); 74static DEFINE_SPINLOCK(viodasd_spinlock);
75 75
76#define VIOMAXREQ 16 76#define VIOMAXREQ 16
77#define VIOMAXBLOCKDMA 12
78 77
79#define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) 78#define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0])
80 79
81struct open_data {
82 u64 disk_size;
83 u16 max_disk;
84 u16 cylinders;
85 u16 tracks;
86 u16 sectors;
87 u16 bytes_per_sector;
88};
89
90struct rw_data {
91 u64 offset;
92 struct {
93 u32 token;
94 u32 reserved;
95 u64 len;
96 } dma_info[VIOMAXBLOCKDMA];
97};
98
99struct vioblocklpevent {
100 struct HvLpEvent event;
101 u32 reserved;
102 u16 version;
103 u16 sub_result;
104 u16 disk;
105 u16 flags;
106 union {
107 struct open_data open_data;
108 struct rw_data rw_data;
109 u64 changed;
110 } u;
111};
112
113#define vioblockflags_ro 0x0001
114
115enum vioblocksubtype {
116 vioblockopen = 0x0001,
117 vioblockclose = 0x0002,
118 vioblockread = 0x0003,
119 vioblockwrite = 0x0004,
120 vioblockflush = 0x0005,
121 vioblockcheck = 0x0007
122};
123
124struct viodasd_waitevent { 80struct viodasd_waitevent {
125 struct completion com; 81 struct completion com;
126 int rc; 82 int rc;
@@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q)
429 * Probe a single disk and fill in the viodasd_device structure 385 * Probe a single disk and fill in the viodasd_device structure
430 * for it. 386 * for it.
431 */ 387 */
432static void probe_disk(struct viodasd_device *d) 388static int probe_disk(struct viodasd_device *d)
433{ 389{
434 HvLpEvent_Rc hvrc; 390 HvLpEvent_Rc hvrc;
435 struct viodasd_waitevent we; 391 struct viodasd_waitevent we;
@@ -453,14 +409,14 @@ retry:
453 0, 0, 0); 409 0, 0, 0);
454 if (hvrc != 0) { 410 if (hvrc != 0) {
455 printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); 411 printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
456 return; 412 return 0;
457 } 413 }
458 414
459 wait_for_completion(&we.com); 415 wait_for_completion(&we.com);
460 416
461 if (we.rc != 0) { 417 if (we.rc != 0) {
462 if (flags != 0) 418 if (flags != 0)
463 return; 419 return 0;
464 /* try again with read only flag set */ 420 /* try again with read only flag set */
465 flags = vioblockflags_ro; 421 flags = vioblockflags_ro;
466 goto retry; 422 goto retry;
@@ -490,15 +446,32 @@ retry:
490 if (hvrc != 0) { 446 if (hvrc != 0) {
491 printk(VIOD_KERN_WARNING 447 printk(VIOD_KERN_WARNING
492 "bad rc sending event to OS/400 %d\n", (int)hvrc); 448 "bad rc sending event to OS/400 %d\n", (int)hvrc);
493 return; 449 return 0;
494 } 450 }
451
452 if (d->dev == NULL) {
453 /* this is when we reprobe for new disks */
454 if (vio_create_viodasd(dev_no) == NULL) {
455 printk(VIOD_KERN_WARNING
456 "cannot allocate virtual device for disk %d\n",
457 dev_no);
458 return 0;
459 }
460 /*
461 * The vio_create_viodasd will have recursed into this
462 * routine with d->dev set to the new vio device and
463 * will finish the setup of the disk below.
464 */
465 return 1;
466 }
467
495 /* create the request queue for the disk */ 468 /* create the request queue for the disk */
496 spin_lock_init(&d->q_lock); 469 spin_lock_init(&d->q_lock);
497 q = blk_init_queue(do_viodasd_request, &d->q_lock); 470 q = blk_init_queue(do_viodasd_request, &d->q_lock);
498 if (q == NULL) { 471 if (q == NULL) {
499 printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", 472 printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
500 dev_no); 473 dev_no);
501 return; 474 return 0;
502 } 475 }
503 g = alloc_disk(1 << PARTITION_SHIFT); 476 g = alloc_disk(1 << PARTITION_SHIFT);
504 if (g == NULL) { 477 if (g == NULL) {
@@ -506,7 +479,7 @@ retry:
506 "cannot allocate disk structure for disk %d\n", 479 "cannot allocate disk structure for disk %d\n",
507 dev_no); 480 dev_no);
508 blk_cleanup_queue(q); 481 blk_cleanup_queue(q);
509 return; 482 return 0;
510 } 483 }
511 484
512 d->disk = g; 485 d->disk = g;
@@ -538,6 +511,7 @@ retry:
538 511
539 /* register us in the global list */ 512 /* register us in the global list */
540 add_disk(g); 513 add_disk(g);
514 return 1;
541} 515}
542 516
543/* returns the total number of scatterlist elements converted */ 517/* returns the total number of scatterlist elements converted */
@@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
718 struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; 692 struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
719 693
720 d->dev = &vdev->dev; 694 d->dev = &vdev->dev;
721 probe_disk(d); 695 if (!probe_disk(d))
722 if (d->disk == NULL)
723 return -ENODEV; 696 return -ENODEV;
724 return 0; 697 return 0;
725} 698}
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 2555dfd6fac6..f9ac0d00b951 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,51 @@
51 */ 51 */
52#define VIO_MAX_SUBTYPES 8 52#define VIO_MAX_SUBTYPES 8
53 53
54#define VIOMAXBLOCKDMA 12
55
56struct open_data {
57 u64 disk_size;
58 u16 max_disk;
59 u16 cylinders;
60 u16 tracks;
61 u16 sectors;
62 u16 bytes_per_sector;
63};
64
65struct rw_data {
66 u64 offset;
67 struct {
68 u32 token;
69 u32 reserved;
70 u64 len;
71 } dma_info[VIOMAXBLOCKDMA];
72};
73
74struct vioblocklpevent {
75 struct HvLpEvent event;
76 u32 reserved;
77 u16 version;
78 u16 sub_result;
79 u16 disk;
80 u16 flags;
81 union {
82 struct open_data open_data;
83 struct rw_data rw_data;
84 u64 changed;
85 } u;
86};
87
88#define vioblockflags_ro 0x0001
89
90enum vioblocksubtype {
91 vioblockopen = 0x0001,
92 vioblockclose = 0x0002,
93 vioblockread = 0x0003,
94 vioblockwrite = 0x0004,
95 vioblockflush = 0x0005,
96 vioblockcheck = 0x0007
97};
98
54struct viocdlpevent { 99struct viocdlpevent {
55 struct HvLpEvent event; 100 struct HvLpEvent event;
56 u32 reserved; 101 u32 reserved;
@@ -133,6 +178,8 @@ extern void vio_set_hostlp(void);
133extern void *vio_get_event_buffer(int subtype); 178extern void *vio_get_event_buffer(int subtype);
134extern void vio_free_event_buffer(int subtype, void *buffer); 179extern void vio_free_event_buffer(int subtype, void *buffer);
135 180
181extern struct vio_dev *vio_create_viodasd(u32 unit);
182
136extern HvLpIndex viopath_hostLp; 183extern HvLpIndex viopath_hostLp;
137extern HvLpIndex viopath_ourLp; 184extern HvLpIndex viopath_ourLp;
138 185