Re: [PATCH] dynamic addition of virtual disks on PPC64 iSeries

From: Stephen Rothwell
Date: Mon May 24 2004 - 06:51:39 EST


Hi Andrew, Linus,

Second attempt.

This patch allows us to dynamically add virtual disks to an iSeries
partition. It works like this: after you have created the virtual disk
file on OS/400 and attached it to the Linux partition, you need to write
to /sys/bus/vio/drivers/viodasd/probe (it doesn't matter what you write).
This will do the probe. It calls add_disk() for each new disk, so we get
hotplug events as a side effect.

This was the nicest way I could think of doing this as the interface to
the hypervisor is polled ...

Please apply.
--
Cheers,
Stephen Rothwell sfr@xxxxxxxxxxxxxxxx
http://www.canb.auug.org.au/~sfr/

diff -ruN 2.6.7-rc1/drivers/block/viodasd.c 2.6.7-rc1.dyndasd.1/drivers/block/viodasd.c
--- 2.6.7-rc1/drivers/block/viodasd.c 2004-05-24 16:29:46.000000000 +1000
+++ 2.6.7-rc1.dyndasd.1/drivers/block/viodasd.c 2004-05-24 21:17:24.000000000 +1000
@@ -40,8 +40,11 @@
#include <linux/string.h>
#include <linux/dma-mapping.h>
#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/kernel.h>

#include <asm/uaccess.h>
+#include <asm/vio.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvLpConfig.h>
@@ -519,13 +522,6 @@
"bad rc sending event to OS/400 %d\n", (int)hvrc);
return;
}
- printk(VIOD_KERN_INFO "disk %d: %lu sectors (%lu MB) "
- "CHS=%d/%d/%d sector size %d%s\n",
- dev_no, (unsigned long)(d->size >> 9),
- (unsigned long)(d->size >> 20),
- (int)d->cylinders, (int)d->tracks,
- (int)d->sectors, (int)d->bytes_per_sector,
- d->read_only ? " (RO)" : "");
/* create the request queue for the disk */
spin_lock_init(&d->q_lock);
q = blk_init_queue(do_viodasd_request, &d->q_lock);
@@ -563,6 +559,14 @@
g->private_data = d;
set_capacity(g, d->size >> 9);

+ printk(VIOD_KERN_INFO "disk %d: %lu sectors (%lu MB) "
+ "CHS=%d/%d/%d sector size %d%s\n",
+ dev_no, (unsigned long)(d->size >> 9),
+ (unsigned long)(d->size >> 20),
+ (int)d->cylinders, (int)d->tracks,
+ (int)d->sectors, (int)d->bytes_per_sector,
+ d->read_only ? " (RO)" : "");
+
/* register us in the global list */
add_disk(g);
}
@@ -725,6 +729,26 @@
}

/*
+ * Get the driver to reprobe for more disks.
+ */
+static ssize_t probe_disks(struct device_driver *drv, const char *buf,
+ size_t count)
+{
+ struct viodasd_device *d;
+
+ for (d = viodasd_devices; d < &viodasd_devices[MAX_DISKNO]; d++) {
+ if (d->disk == NULL)
+ probe_disk(d);
+ }
+ return count;
+}
+static DRIVER_ATTR(probe, S_IWUSR, NULL, probe_disks)
+
+static struct vio_driver viodasd_driver = {
+ .name = "viodasd"
+};
+
+/*
* Initialize the whole device driver. Handle module and non-module
* versions
*/
@@ -767,6 +791,9 @@
for (i = 0; i < MAX_DISKNO; i++)
probe_disk(&viodasd_devices[i]);

+ vio_register_driver(&viodasd_driver); /* FIX ME - error checking */
+ driver_create_file(&viodasd_driver.driver, &driver_attr_probe);
+
return 0;
}
module_init(viodasd_init);
@@ -776,6 +803,9 @@
int i;
struct viodasd_device *d;

+ driver_remove_file(&viodasd_driver.driver, &driver_attr_probe);
+ vio_unregister_driver(&viodasd_driver);
+
for (i = 0; i < MAX_DISKNO; i++) {
d = &viodasd_devices[i];
if (d->disk) {

Attachment: pgp00000.pgp
Description: PGP signature