linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] [POWERPC] Clean up vio.h
@ 2007-10-11  4:48 Stephen Rothwell
  2007-10-11  4:50 ` [PATCH 2/7] [POWERPC] iSeries: simplify viocd initialisation Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:48 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

Remove vio_dma_ops declaration (since it no longer exists) and some
unused fields from struct vio_driver.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/vio.c |   11 -----------
 include/asm-powerpc/vio.h |    5 -----
 2 files changed, 0 insertions(+), 16 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 1d7b272..fd631d4 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -168,16 +168,6 @@ static int vio_bus_remove(struct device *dev)
 	return 1;
 }
 
-/* convert from struct device to struct vio_dev and pass to driver. */
-static void vio_bus_shutdown(struct device *dev)
-{
-	struct vio_dev *viodev = to_vio_dev(dev);
-	struct vio_driver *viodrv = to_vio_driver(dev->driver);
-
-	if (dev->driver && viodrv->shutdown)
-		viodrv->shutdown(viodev);
-}
-
 /**
  * vio_register_driver: - Register a new vio driver
  * @drv:	The vio_driver structure to be registered.
@@ -397,7 +387,6 @@ static struct bus_type vio_bus_type = {
 	.match = vio_bus_match,
 	.probe = vio_bus_probe,
 	.remove = vio_bus_remove,
-	.shutdown = vio_bus_shutdown,
 };
 
 /**
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 598d111..9204c15 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -53,17 +53,12 @@ struct vio_dev {
 };
 
 struct vio_driver {
-	struct list_head node;
 	const struct vio_device_id *id_table;
 	int (*probe)(struct vio_dev *dev, const struct vio_device_id *id);
 	int (*remove)(struct vio_dev *dev);
-	void (*shutdown)(struct vio_dev *dev);
-	unsigned long driver_data;
 	struct device_driver driver;
 };
 
-extern struct dma_mapping_ops vio_dma_ops;
-
 extern int vio_register_driver(struct vio_driver *drv);
 extern void vio_unregister_driver(struct vio_driver *drv);
 
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/7] [POWERPC] iSeries: simplify viocd initialisation
  2007-10-11  4:48 [PATCH 1/7] [POWERPC] Clean up vio.h Stephen Rothwell
@ 2007-10-11  4:50 ` Stephen Rothwell
  2007-10-11  4:53   ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:50 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe

We don't need to keep a lump of dma coherent memory around for the life
of the module.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 drivers/cdrom/viocd.c |   37 +++++++++++++------------------------
 1 files changed, 13 insertions(+), 24 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index e51550d..b88fdeb 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -136,17 +136,12 @@ struct cdrom_info {
 	char	type[4];
 	char	model[3];
 };
-/*
- * This needs to be allocated since it is passed to the
- * Hypervisor and we may be a module.
- */
-static struct cdrom_info *viocd_unitinfo;
-static dma_addr_t unitinfo_dmaaddr;
 
 struct disk_info {
 	struct gendisk			*viocd_disk;
 	struct cdrom_device_info	viocd_info;
 	struct device			*dev;
+	struct cdrom_info		unitinfo;
 };
 static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
 
@@ -164,9 +159,9 @@ static int proc_viocd_show(struct seq_file *m, void *v)
 	for (i = 0; i < viocd_numdev; i++) {
 		seq_printf(m, "viocd device %d is iSeries resource %10.10s"
 				"type %4.4s, model %3.3s\n",
-				i, viocd_unitinfo[i].rsrcname,
-				viocd_unitinfo[i].type,
-				viocd_unitinfo[i].model);
+				i, viocd_diskinfo[i].unitinfo.rsrcname,
+				viocd_diskinfo[i].unitinfo.type,
+				viocd_diskinfo[i].unitinfo.model);
 	}
 	return 0;
 }
@@ -222,6 +217,8 @@ static void __init get_viocd_info(void)
 	HvLpEvent_Rc hvrc;
 	int i;
 	struct viocd_waitevent we;
+	struct cdrom_info *viocd_unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
 
 	viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
 			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
@@ -259,16 +256,15 @@ static void __init get_viocd_info(void)
 		goto error_ret;
 	}
 
-	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++)
+	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) {
+		viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i];
 		viocd_numdev++;
+	}
 
 error_ret:
-	if (viocd_numdev == 0) {
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-				viocd_unitinfo, unitinfo_dmaaddr);
-		viocd_unitinfo = NULL;
-	}
+	dma_free_coherent(iSeries_vio_dev,
+			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+			viocd_unitinfo, unitinfo_dmaaddr);
 }
 
 static int viocd_open(struct cdrom_device_info *cdi, int purpose)
@@ -674,7 +670,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 
 	d = &viocd_diskinfo[deviceno];
 	c = &d->viocd_info;
-	ci = &viocd_unitinfo[deviceno];
+	ci = &d->unitinfo;
 
 	c->ops = &viocd_dops;
 	c->speed = 4;
@@ -816,9 +812,6 @@ static int __init viocd_init(void)
 	return 0;
 
 out_free_info:
-	dma_free_coherent(iSeries_vio_dev,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			viocd_unitinfo, unitinfo_dmaaddr);
 	vio_clearHandler(viomajorsubtype_cdio);
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
 out_unregister:
@@ -830,10 +823,6 @@ static void __exit viocd_exit(void)
 {
 	remove_proc_entry("iSeries/viocd", NULL);
 	vio_unregister_driver(&viocd_driver);
-	if (viocd_unitinfo != NULL)
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-				viocd_unitinfo, unitinfo_dmaaddr);
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2);
 	vio_clearHandler(viomajorsubtype_cdio);
 	unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE);
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
  2007-10-11  4:50 ` [PATCH 2/7] [POWERPC] iSeries: simplify viocd initialisation Stephen Rothwell
@ 2007-10-11  4:53   ` Stephen Rothwell
  2007-10-11  4:55     ` [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c Stephen Rothwell
  2007-10-11  5:25     ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Olof Johansson
  0 siblings, 2 replies; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:53 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe

It was only being used to carry around dma_iommu_ops and vio_iommu_table
which we can use directly instead.  This also means that vio_bus_device
doesn't need to refer to them either.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/powerpc/kernel/vio.c                   |    7 +-----
 arch/powerpc/platforms/iseries/iommu.c      |   30 +++++++++++++++++++++++++++
 arch/powerpc/platforms/iseries/mf.c         |   23 ++++++++------------
 arch/powerpc/platforms/iseries/viopath.c    |    6 +---
 drivers/cdrom/viocd.c                       |    5 +--
 drivers/char/viotape.c                      |    7 ++---
 include/asm-powerpc/iseries/hv_call_event.h |   10 +++++++++
 include/asm-powerpc/iseries/vio.h           |    4 ---
 8 files changed, 57 insertions(+), 35 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index fd631d4..eaf7f69 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
 };
 
 #ifdef CONFIG_PPC_ISERIES
-struct device *iSeries_vio_dev = &vio_bus_device.dev;
-EXPORT_SYMBOL(iSeries_vio_dev);
-
 static struct iommu_table veth_iommu_table;
-static struct iommu_table vio_iommu_table;
+struct iommu_table vio_iommu_table;
 
 static void __init iommu_vio_init(void)
 {
@@ -66,8 +63,6 @@ static void __init iommu_vio_init(void)
 		printk("Virtual Bus VETH TCE table failed.\n");
 	if (!iommu_init_table(&vio_iommu_table, -1))
 		printk("Virtual Bus VIO TCE table failed.\n");
-	vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
-	vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
 }
 #else
 static void __init iommu_vio_init(void)
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 3b6a966..3281f10 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -28,6 +28,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/list.h>
 #include <linux/pci.h>
+#include <linux/module.h>
 
 #include <asm/iommu.h>
 #include <asm/tce.h>
@@ -36,6 +37,7 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/iseries/hv_call_xm.h>
+#include <asm/iseries/hv_call_event.h>
 #include <asm/iseries/iommu.h>
 
 static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
@@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
 }
 #endif
 
+extern struct iommu_table vio_iommu_table;
+
+void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
+{
+	return iommu_alloc_coherent(&vio_iommu_table, size, dma_handle,
+				DMA_32BIT_MASK, flag, -1);
+}
+EXPORT_SYMBOL_GPL(iseries_hv_alloc);
+
+void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	iommu_free_coherent(&vio_iommu_table, size, vaddr, dma_handle);
+}
+EXPORT_SYMBOL_GPL(iseries_hv_free);
+
+dma_addr_t iseries_hv_map(void *vaddr, size_t size,
+			enum dma_data_direction direction)
+{
+	return iommu_map_single(&vio_iommu_table, vaddr, size,
+				DMA_32BIT_MASK, direction);
+}
+
+void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction)
+{
+	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
+}
+
 void iommu_init_early_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c
index b1187d9..c0f2433 100644
--- a/arch/powerpc/platforms/iseries/mf.c
+++ b/arch/powerpc/platforms/iseries/mf.c
@@ -39,9 +39,9 @@
 #include <asm/paca.h>
 #include <asm/abs_addr.h>
 #include <asm/firmware.h>
-#include <asm/iseries/vio.h>
 #include <asm/iseries/mf.h>
 #include <asm/iseries/hv_lp_config.h>
+#include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/it_lp_queue.h>
 
 #include "setup.h"
@@ -870,8 +870,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 	if ((off + count) > 256)
 		count = 256 - off;
 
-	dma_addr = dma_map_single(iSeries_vio_dev, page, off + count,
-			DMA_FROM_DEVICE);
+	dma_addr = iseries_hv_map(page, off + count, DMA_FROM_DEVICE);
 	if (dma_mapping_error(dma_addr))
 		return -ENOMEM;
 	memset(page, 0, off + count);
@@ -883,8 +882,7 @@ static int proc_mf_dump_cmdline(char *page, char **start, off_t off,
 	vsp_cmd.sub_data.kern.length = off + count;
 	mb();
 	rc = signal_vsp_instruction(&vsp_cmd);
-	dma_unmap_single(iSeries_vio_dev, dma_addr, off + count,
-			DMA_FROM_DEVICE);
+	iseries_hv_unmap(dma_addr, off + count, DMA_FROM_DEVICE);
 	if (rc)
 		return rc;
 	if (vsp_cmd.result_code != 0)
@@ -919,8 +917,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
 	int len = *size;
 	dma_addr_t dma_addr;
 
-	dma_addr = dma_map_single(iSeries_vio_dev, buffer, len,
-			DMA_FROM_DEVICE);
+	dma_addr = iseries_hv_map(buffer, len, DMA_FROM_DEVICE);
 	memset(buffer, 0, len);
 	memset(&vsp_cmd, 0, sizeof(vsp_cmd));
 	vsp_cmd.cmd = 32;
@@ -938,7 +935,7 @@ static int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side)
 			rc = -ENOMEM;
 	}
 
-	dma_unmap_single(iSeries_vio_dev, dma_addr, len, DMA_FROM_DEVICE);
+	iseries_hv_unmap(dma_addr, len, DMA_FROM_DEVICE);
 
 	return rc;
 }
@@ -1149,8 +1146,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
 		goto out;
 
 	dma_addr = 0;
-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
-			GFP_ATOMIC);
+	page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC);
 	ret = -ENOMEM;
 	if (page == NULL)
 		goto out;
@@ -1170,7 +1166,7 @@ static int proc_mf_change_cmdline(struct file *file, const char __user *buffer,
 	ret = count;
 
 out_free:
-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+	iseries_hv_free(count, page, dma_addr);
 out:
 	return ret;
 }
@@ -1190,8 +1186,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file,
 		goto out;
 
 	dma_addr = 0;
-	page = dma_alloc_coherent(iSeries_vio_dev, count, &dma_addr,
-			GFP_ATOMIC);
+	page = iseries_hv_alloc(count, &dma_addr, GFP_ATOMIC);
 	rc = -ENOMEM;
 	if (page == NULL) {
 		printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
@@ -1219,7 +1214,7 @@ static ssize_t proc_mf_change_vmlinux(struct file *file,
 	*ppos += count;
 	rc = count;
 out_free:
-	dma_free_coherent(iSeries_vio_dev, count, page, dma_addr);
+	iseries_hv_free(count, page, dma_addr);
 out:
 	return rc;
 }
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 45f2fe3..df23331 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -124,8 +124,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
 	if (!buf)
 		return 0;
 
-	handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE,
-				DMA_FROM_DEVICE);
+	handle = iseries_hv_map(buf, HW_PAGE_SIZE, DMA_FROM_DEVICE);
 
 	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
 			HvLpEvent_Type_VirtualIo,
@@ -146,8 +145,7 @@ static int proc_viopath_show(struct seq_file *m, void *v)
 	buf[HW_PAGE_SIZE-1] = '\0';
 	seq_printf(m, "%s", buf);
 
-	dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
-			 DMA_FROM_DEVICE);
+	iseries_hv_unmap(handle, HW_PAGE_SIZE, DMA_FROM_DEVICE);
 	kfree(buf);
 
 	seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index b88fdeb..c081e54 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -220,7 +220,7 @@ static void __init get_viocd_info(void)
 	struct cdrom_info *viocd_unitinfo;
 	dma_addr_t unitinfo_dmaaddr;
 
-	viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev,
+	viocd_unitinfo = iseries_hv_alloc(
 			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
 			&unitinfo_dmaaddr, GFP_ATOMIC);
 	if (viocd_unitinfo == NULL) {
@@ -262,8 +262,7 @@ static void __init get_viocd_info(void)
 	}
 
 error_ret:
-	dma_free_coherent(iSeries_vio_dev,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
+	iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
 			viocd_unitinfo, unitinfo_dmaaddr);
 }
 
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index e12275d..064c091 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -392,8 +392,8 @@ static int get_viotape_info(void)
 	if (op == NULL)
 		return -ENOMEM;
 
-	viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len,
-		&viotape_unitinfo_token, GFP_ATOMIC);
+	viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
+		GFP_ATOMIC);
 	if (viotape_unitinfo == NULL) {
 		free_op_struct(op);
 		return -ENOMEM;
@@ -1103,8 +1103,7 @@ static void __exit viotap_exit(void)
 	class_destroy(tape_class);
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
 	if (viotape_unitinfo)
-		dma_free_coherent(iSeries_vio_dev,
-				sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
+		iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
 				viotape_unitinfo, viotape_unitinfo_token);
 	viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
 	vio_clearHandler(viomajorsubtype_tape);
diff --git a/include/asm-powerpc/iseries/hv_call_event.h b/include/asm-powerpc/iseries/hv_call_event.h
index 4cec476..cc029d3 100644
--- a/include/asm-powerpc/iseries/hv_call_event.h
+++ b/include/asm-powerpc/iseries/hv_call_event.h
@@ -21,6 +21,9 @@
 #ifndef _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
 #define _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H
 
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+
 #include <asm/iseries/hv_call_sc.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/abs_addr.h>
@@ -113,6 +116,13 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
 			eventData3, eventData4, eventData5);
 }
 
+extern void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag);
+extern void iseries_hv_free(size_t size, void *vaddr, dma_addr_t dma_handle);
+extern dma_addr_t iseries_hv_map(void *vaddr, size_t size,
+			enum dma_data_direction direction);
+extern void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
+			enum dma_data_direction direction);
+
 static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
 {
 	return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event));
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 7a95d29..5a5cd0f 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -150,8 +150,4 @@ enum viochar_rc {
 	viochar_rc_ebusy = 1
 };
 
-struct device;
-
-extern struct device *iSeries_vio_dev;
-
 #endif /* _ASM_POWERPC_ISERIES_VIO_H */
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c
  2007-10-11  4:53   ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Stephen Rothwell
@ 2007-10-11  4:55     ` Stephen Rothwell
  2007-10-11  4:57       ` [PATCH 5/7] [POWERPC] iSeries: move detection of virtual cdroms Stephen Rothwell
  2007-10-11  5:25     ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Olof Johansson
  1 sibling, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:55 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev


Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/vio.c              |   78 ++++++++++---------------------
 arch/powerpc/platforms/iseries/iommu.c |   24 +++++++++-
 include/asm-powerpc/iseries/iommu.h    |    4 ++
 3 files changed, 52 insertions(+), 54 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index eaf7f69..b7c9e44 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -48,61 +48,33 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
 	.dev.bus = &vio_bus_type,
 };
 
-#ifdef CONFIG_PPC_ISERIES
-static struct iommu_table veth_iommu_table;
-struct iommu_table vio_iommu_table;
-
-static void __init iommu_vio_init(void)
-{
-	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
-	veth_iommu_table.it_size /= 2;
-	vio_iommu_table = veth_iommu_table;
-	vio_iommu_table.it_offset += veth_iommu_table.it_size;
-
-	if (!iommu_init_table(&veth_iommu_table, -1))
-		printk("Virtual Bus VETH TCE table failed.\n");
-	if (!iommu_init_table(&vio_iommu_table, -1))
-		printk("Virtual Bus VIO TCE table failed.\n");
-}
-#else
-static void __init iommu_vio_init(void)
-{
-}
-#endif
-
 static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
 {
-#ifdef CONFIG_PPC_ISERIES
-	if (firmware_has_feature(FW_FEATURE_ISERIES)) {
-		if (strcmp(dev->type, "network") == 0)
-			return &veth_iommu_table;
-		return &vio_iommu_table;
-	} else
-#endif
-	{
-		const unsigned char *dma_window;
-		struct iommu_table *tbl;
-		unsigned long offset, size;
-
-		dma_window = of_get_property(dev->dev.archdata.of_node,
-					  "ibm,my-dma-window", NULL);
-		if (!dma_window)
-			return NULL;
-
-		tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
-
-		of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
-				    &tbl->it_index, &offset, &size);
-
-		/* TCE table size - measured in tce entries */
-		tbl->it_size = size >> IOMMU_PAGE_SHIFT;
-		/* offset for VIO should always be 0 */
-		tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
-		tbl->it_busno = 0;
-		tbl->it_type = TCE_VB;
-
-		return iommu_init_table(tbl, -1);
-	}
+	const unsigned char *dma_window;
+	struct iommu_table *tbl;
+	unsigned long offset, size;
+
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return vio_build_iommu_table_iseries(dev);
+
+	dma_window = of_get_property(dev->dev.archdata.of_node,
+				  "ibm,my-dma-window", NULL);
+	if (!dma_window)
+		return NULL;
+
+	tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
+
+	of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
+			    &tbl->it_index, &offset, &size);
+
+	/* TCE table size - measured in tce entries */
+	tbl->it_size = size >> IOMMU_PAGE_SHIFT;
+	/* offset for VIO should always be 0 */
+	tbl->it_offset = offset >> IOMMU_PAGE_SHIFT;
+	tbl->it_busno = 0;
+	tbl->it_type = TCE_VB;
+
+	return iommu_init_table(tbl, -1);
 }
 
 /**
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 3281f10..49e9c66 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -31,6 +31,7 @@
 #include <linux/module.h>
 
 #include <asm/iommu.h>
+#include <asm/vio.h>
 #include <asm/tce.h>
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
@@ -191,7 +192,8 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
 }
 #endif
 
-extern struct iommu_table vio_iommu_table;
+static struct iommu_table veth_iommu_table;
+static struct iommu_table vio_iommu_table;
 
 void *iseries_hv_alloc(size_t size, dma_addr_t *dma_handle, gfp_t flag)
 {
@@ -219,6 +221,26 @@ void iseries_hv_unmap(dma_addr_t dma_handle, size_t size,
 	iommu_unmap_single(&vio_iommu_table, dma_handle, size, direction);
 }
 
+void __init iommu_vio_init(void)
+{
+	iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table);
+	veth_iommu_table.it_size /= 2;
+	vio_iommu_table = veth_iommu_table;
+	vio_iommu_table.it_offset += veth_iommu_table.it_size;
+
+	if (!iommu_init_table(&veth_iommu_table, -1))
+		printk("Virtual Bus VETH TCE table failed.\n");
+	if (!iommu_init_table(&vio_iommu_table, -1))
+		printk("Virtual Bus VIO TCE table failed.\n");
+}
+
+struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev)
+{
+	if (strcmp(dev->type, "network") == 0)
+		return &veth_iommu_table;
+	return &vio_iommu_table;
+}
+
 void iommu_init_early_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
index 6e323a1..c59ee7e 100644
--- a/include/asm-powerpc/iseries/iommu.h
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -22,6 +22,7 @@
  */
 
 struct pci_dev;
+struct vio_dev;
 struct device_node;
 struct iommu_table;
 
@@ -34,4 +35,7 @@ extern void iommu_table_getparms_iSeries(unsigned long busno,
 		unsigned char slotno, unsigned char virtbus,
 		struct iommu_table *tbl);
 
+extern struct iommu_table *vio_build_iommu_table_iseries(struct vio_dev *dev);
+extern void iommu_vio_init(void);
+
 #endif /* _ASM_POWERPC_ISERIES_IOMMU_H */
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/7] [POWERPC] iSeries: move detection of virtual cdroms
  2007-10-11  4:55     ` [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c Stephen Rothwell
@ 2007-10-11  4:57       ` Stephen Rothwell
  2007-10-11  4:58         ` [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:57 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viocd.c gets all
the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
Acked-by: Jens Axboe <jens.axboe@oracle.com>
---
 arch/powerpc/kernel/vio.c               |    3 -
 arch/powerpc/platforms/iseries/Makefile |    2 +-
 arch/powerpc/platforms/iseries/dt.c     |    4 -
 arch/powerpc/platforms/iseries/vio.c    |  317 +++++++++++++++++++++++++++++++
 drivers/cdrom/viocd.c                   |  116 ++----------
 include/asm-powerpc/iseries/vio.h       |   24 +++
 6 files changed, 361 insertions(+), 105 deletions(-)
 create mode 100644 arch/powerpc/platforms/iseries/vio.c

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index b7c9e44..cb22a35 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -247,9 +247,6 @@ static int __init vio_bus_init(void)
 	int err;
 	struct device_node *node_vroot;
 
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		iommu_vio_init();
-
 	err = bus_register(&vio_bus_type);
 	if (err) {
 		printk(KERN_ERR "failed to register VIO bus\n");
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index 60db509..a65f1b4 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -7,7 +7,7 @@ obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
 	hvcall.o proc.o htab.o iommu.o misc.o irq.o
 obj-$(CONFIG_PCI) += pci.o vpdinfo.o
 obj-$(CONFIG_SMP) += smp.o
-obj-$(CONFIG_VIOPATH) += viopath.o
+obj-$(CONFIG_VIOPATH) += viopath.o vio.o
 obj-$(CONFIG_MODULES) += ksyms.o
 
 quiet_cmd_dt_strings = DT_STR  $@
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 9e8a334..84fcee1 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -381,10 +381,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++)
-		dt_do_vdevice(dt, "viocd", reg, i, device_type_block,
-				"IBM,iSeries-viocd", 1);
 	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
 
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
new file mode 100644
index 0000000..08f6884
--- /dev/null
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -0,0 +1,317 @@
+/*
+ * Legacy iSeries specific vio initialisation
+ * that needs to be built in (not a module).
+ *
+ * © Copyright 2007 IBM Corporation
+ *	Author: Stephen Rothwell
+ *	Some parts collected from various other files
+ *
+ * This program is free software;  you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, 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
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/completion.h>
+#include <linux/proc_fs.h>
+
+#include <asm/firmware.h>
+#include <asm/iseries/vio.h>
+#include <asm/iseries/iommu.h>
+#include <asm/iseries/hv_types.h>
+#include <asm/iseries/hv_lp_event.h>
+
+#define FIRST_VTY	0
+#define NUM_VTYS	1
+#define FIRST_VSCSI	(FIRST_VTY + NUM_VTYS)
+#define NUM_VSCSIS	1
+#define FIRST_VLAN	(FIRST_VSCSI + NUM_VSCSIS)
+#define NUM_VLANS	HVMAXARCHITECTEDVIRTUALLANS
+#define FIRST_VIODASD	(FIRST_VLAN + NUM_VLANS)
+#define NUM_VIODASDS	HVMAXARCHITECTEDVIRTUALDISKS
+#define FIRST_VIOCD	(FIRST_VIODASD + NUM_VIODASDS)
+#define NUM_VIOCDS	HVMAXARCHITECTEDVIRTUALCDROMS
+#define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
+#define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
+
+static struct property * __init new_property(const char *name, int length,
+		const void *value)
+{
+	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
+			GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->name = (char *)(np + 1);
+	np->value = np->name + strlen(name) + 1;
+	strcpy(np->name, name);
+	memcpy(np->value, value, length);
+	np->length = length;
+	return np;
+}
+
+static void __init free_property(struct property *np)
+{
+	kfree(np);
+}
+
+static struct device_node * __init new_node(const char *path,
+		struct device_node *parent)
+{
+	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
+
+	if (!np)
+		return NULL;
+	np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+	if (!np->full_name) {
+		kfree(np);
+		return NULL;
+	}
+	strcpy(np->full_name, path);
+	of_node_set_flag(np, OF_DYNAMIC);
+	kref_init(&np->kref);
+	np->parent = of_node_get(parent);
+	return np;
+}
+
+static void __init free_node(struct device_node *np)
+{
+	struct property *next;
+	struct property *prop;
+
+	next = np->properties;
+	while (next) {
+		prop = next;
+		next = prop->next;
+		free_property(prop);
+	}
+	of_node_put(np->parent);
+	kfree(np->full_name);
+	kfree(np);
+}
+
+static int __init add_string_property(struct device_node *np, const char *name,
+		const char *value)
+{
+	struct property *nprop = new_property(name, strlen(value) + 1, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+static int __init add_raw_property(struct device_node *np, const char *name,
+		int length, const void *value)
+{
+	struct property *nprop = new_property(name, length, value);
+
+	if (!nprop)
+		return 0;
+	prom_add_property(np, nprop);
+	return 1;
+}
+
+struct viocd_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct cdrom_info {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
+static void __init handle_cd_event(struct HvLpEvent *event)
+{
+	struct viocdlpevent *bevent;
+	struct viocd_waitevent *pwe;
+
+	if (!event)
+		/* Notification that a partition went away! */
+		return;
+
+	/* First, we should NEVER get an int here...only acks */
+	if (hvlpevent_is_int(event)) {
+		printk(KERN_WARNING "handle_cd_event: got an unexpected int\n");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	bevent = (struct viocdlpevent *)event;
+
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viocdgetinfo:
+		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe->rc = event->xRc;
+		pwe->sub_result = bevent->sub_result;
+		complete(&pwe->com);
+		break;
+
+	default:
+		printk(KERN_WARNING "handle_cd_event: "
+			"message with unexpected subtype %0x04X!\n",
+			event->xSubtype & VIOMINOR_SUBTYPE_MASK);
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+	}
+}
+
+static void __init get_viocd_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct viocd_waitevent we;
+	struct cdrom_info *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2);
+	if (ret) {
+		printk(KERN_WARNING
+			"get_viocd_info: error opening path to host partition %d\n",
+			viopath_hostLp);
+		return;
+	}
+
+	/* Initialize our request handler */
+	vio_setHandler(viomajorsubtype_cdio, handle_cd_event);
+
+	unitinfo = iseries_hv_alloc(
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			&unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo) {
+		printk(KERN_WARNING
+			"get_viocd_info: error allocating unitinfo\n");
+		goto clear_handler;
+	}
+
+	memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS);
+
+	init_completion(&we.com);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_cdio | viocdgetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
+			sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING
+			"get_viocd_info: cdrom error sending event. rc %d\n",
+			(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	if (we.rc) {
+		printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n",
+			we.rc, we.sub_result);
+		goto hv_free;
+	}
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOCD + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viocd") ||
+			!add_string_property(np, "device_type", "block") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viocd") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS,
+			unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_cdio);
+	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
+}
+
+static int __init iseries_vio_init(void)
+{
+	struct device_node *vio_root;
+
+	if (!firmware_has_feature(FW_FEATURE_ISERIES))
+		return -ENODEV;
+
+	iommu_vio_init();
+
+	vio_root = of_find_node_by_path("/vdevice");
+	if (!vio_root)
+		return -ENODEV;
+
+	if (viopath_hostLp == HvLpIndexInvalid) {
+		vio_set_hostlp();
+		/* If we don't have a host, bail out */
+		if (viopath_hostLp == HvLpIndexInvalid)
+			goto put_node;
+	}
+
+	get_viocd_info(vio_root);
+
+	return 0;
+
+ put_node:
+	of_node_put(vio_root);
+	return -ENODEV;
+}
+arch_initcall(iseries_vio_init);
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c
index c081e54..880b5dc 100644
--- a/drivers/cdrom/viocd.c
+++ b/drivers/cdrom/viocd.c
@@ -56,30 +56,6 @@
 #define VIOCD_KERN_WARNING		KERN_WARNING "viocd: "
 #define VIOCD_KERN_INFO			KERN_INFO "viocd: "
 
-struct viocdlpevent {
-	struct HvLpEvent	event;
-	u32			reserved;
-	u16			version;
-	u16			sub_result;
-	u16			disk;
-	u16			flags;
-	u32			token;
-	u64			offset;		/* On open, max number of disks */
-	u64			len;		/* On open, size of the disk */
-	u32			block_size;	/* Only set on open */
-	u32			media_size;	/* Only set on open */
-};
-
-enum viocdsubtype {
-	viocdopen = 0x0001,
-	viocdclose = 0x0002,
-	viocdread = 0x0003,
-	viocdwrite = 0x0004,
-	viocdlockdoor = 0x0005,
-	viocdgetinfo = 0x0006,
-	viocdcheck = 0x0007
-};
-
 /*
  * Should probably make this a module parameter....sigh
  */
@@ -131,17 +107,13 @@ static struct capability_entry capability_table[] __initdata = {
 /* These are our internal structures for keeping track of devices */
 static int viocd_numdev;
 
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 struct disk_info {
 	struct gendisk			*viocd_disk;
 	struct cdrom_device_info	viocd_info;
 	struct device			*dev;
-	struct cdrom_info		unitinfo;
+	const char			*rsrcname;
+	const char			*type;
+	const char			*model;
 };
 static struct disk_info viocd_diskinfo[VIOCD_MAX_CD];
 
@@ -159,9 +131,9 @@ static int proc_viocd_show(struct seq_file *m, void *v)
 	for (i = 0; i < viocd_numdev; i++) {
 		seq_printf(m, "viocd device %d is iSeries resource %10.10s"
 				"type %4.4s, model %3.3s\n",
-				i, viocd_diskinfo[i].unitinfo.rsrcname,
-				viocd_diskinfo[i].unitinfo.type,
-				viocd_diskinfo[i].unitinfo.model);
+				i, viocd_diskinfo[i].rsrcname,
+				viocd_diskinfo[i].type,
+				viocd_diskinfo[i].model);
 	}
 	return 0;
 }
@@ -211,61 +183,6 @@ struct block_device_operations viocd_fops = {
 	.media_changed =	viocd_blk_media_changed,
 };
 
-/* Get info on CD devices from OS/400 */
-static void __init get_viocd_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	struct viocd_waitevent we;
-	struct cdrom_info *viocd_unitinfo;
-	dma_addr_t unitinfo_dmaaddr;
-
-	viocd_unitinfo = iseries_hv_alloc(
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			&unitinfo_dmaaddr, GFP_ATOMIC);
-	if (viocd_unitinfo == NULL) {
-		printk(VIOCD_KERN_WARNING "error allocating unitinfo\n");
-		return;
-	}
-
-	memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD);
-
-	init_completion(&we.com);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_cdio | viocdgetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0,
-			sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n",
-				(int)hvrc);
-		goto error_ret;
-	}
-
-	wait_for_completion(&we.com);
-
-	if (we.rc) {
-		const struct vio_error_entry *err =
-			vio_lookup_rc(viocd_err_table, we.sub_result);
-		printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n",
-				we.rc, we.sub_result, err->msg);
-		goto error_ret;
-	}
-
-	for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) {
-		viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i];
-		viocd_numdev++;
-	}
-
-error_ret:
-	iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD,
-			viocd_unitinfo, unitinfo_dmaaddr);
-}
-
 static int viocd_open(struct cdrom_device_info *cdi, int purpose)
 {
         struct disk_info *diskinfo = cdi->handle;
@@ -576,7 +493,6 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
 					bevent->block_size / 512);
 		}
 		/* FALLTHROUGH !! */
-	case viocdgetinfo:
 	case viocdlockdoor:
 		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
 return_complete:
@@ -660,22 +576,30 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	int deviceno;
 	struct disk_info *d;
 	struct cdrom_device_info *c;
-	struct cdrom_info *ci;
 	struct request_queue *q;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
 	deviceno = vdev->unit_address;
-	if (deviceno >= viocd_numdev)
+	if (deviceno > VIOCD_MAX_CD)
 		return -ENODEV;
+	if (!node)
+		return -ENODEV;
+
+	if (deviceno >= viocd_numdev)
+		viocd_numdev = deviceno + 1;
 
 	d = &viocd_diskinfo[deviceno];
+	d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL);
+	d->type = of_get_property(node, "linux,vio_type", NULL);
+	d->model = of_get_property(node, "linux,vio_model", NULL);
+
 	c = &d->viocd_info;
-	ci = &d->unitinfo;
 
 	c->ops = &viocd_dops;
 	c->speed = 4;
 	c->capacity = 1;
 	c->handle = d;
-	c->mask = ~find_capability(ci->type);
+	c->mask = ~find_capability(d->type);
 	sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno);
 
 	if (register_cdrom(c) != 0) {
@@ -685,7 +609,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 	}
 	printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s "
 			"type %4.4s, model %3.3s\n",
-			c->name, ci->rsrcname, ci->type, ci->model);
+			c->name, d->rsrcname, d->type, d->model);
 	q = blk_init_queue(do_viocd_request, &viocd_reqlock);
 	if (q == NULL) {
 		printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n",
@@ -794,8 +718,6 @@ static int __init viocd_init(void)
 	/* Initialize our request handler */
 	vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event);
 
-	get_viocd_info();
-
 	spin_lock_init(&viocd_reqlock);
 
 	ret = vio_register_driver(&viocd_driver);
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 5a5cd0f..e5a405b 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,30 @@
  */
 #define VIO_MAX_SUBTYPES 8
 
+struct viocdlpevent {
+	struct HvLpEvent	event;
+	u32			reserved;
+	u16			version;
+	u16			sub_result;
+	u16			disk;
+	u16			flags;
+	u32			token;
+	u64			offset;		/* On open, max number of disks */
+	u64			len;		/* On open, size of the disk */
+	u32			block_size;	/* Only set on open */
+	u32			media_size;	/* Only set on open */
+};
+
+enum viocdsubtype {
+	viocdopen = 0x0001,
+	viocdclose = 0x0002,
+	viocdread = 0x0003,
+	viocdwrite = 0x0004,
+	viocdlockdoor = 0x0005,
+	viocdgetinfo = 0x0006,
+	viocdcheck = 0x0007
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes
  2007-10-11  4:57       ` [PATCH 5/7] [POWERPC] iSeries: move detection of virtual cdroms Stephen Rothwell
@ 2007-10-11  4:58         ` Stephen Rothwell
  2007-10-11  4:59           ` [PATCH 7/7] [POWERPC] iSeries: move viodasd probing Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:58 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

Now we will only have entries in the device tree for the actual existing
devices (including their OS/400 properties).  This way viotape.c gets
all the information about the devices from the device tree.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/platforms/iseries/dt.c  |    7 --
 arch/powerpc/platforms/iseries/vio.c |  149 ++++++++++++++++++++++++++++++----
 drivers/char/viotape.c               |  124 ++++------------------------
 include/asm-powerpc/iseries/vio.h    |   41 +++++++++
 4 files changed, 192 insertions(+), 129 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 84fcee1..2e4ad6b 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -73,7 +73,6 @@ static char __initdata device_type_memory[] = "memory";
 static char __initdata device_type_serial[] = "serial";
 static char __initdata device_type_network[] = "network";
 static char __initdata device_type_block[] = "block";
-static char __initdata device_type_byte[] = "byte";
 static char __initdata device_type_pci[] = "pci";
 static char __initdata device_type_vdevice[] = "vdevice";
 static char __initdata device_type_vscsi[] = "vscsi";
@@ -380,12 +379,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
 		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
 				"IBM,iSeries-viodasd", 1);
-	reg += HVMAXARCHITECTEDVIRTUALDISKS;
-	reg += HVMAXARCHITECTEDVIRTUALCDROMS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++)
-		dt_do_vdevice(dt, "viotape", reg, i, device_type_byte,
-				"IBM,iSeries-viotape", 1);
 
 	dt_end_node(dt);
 }
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 08f6884..b4f7433 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -45,6 +45,18 @@
 #define FIRST_VIOTAPE	(FIRST_VIOCD + NUM_VIOCDS)
 #define NUM_VIOTAPES	HVMAXARCHITECTEDVIRTUALTAPES
 
+struct vio_waitevent {
+	struct completion	com;
+	int			rc;
+	u16			sub_result;
+};
+
+struct vio_resource {
+	char	rsrcname[10];
+	char	type[4];
+	char	model[3];
+};
+
 static struct property * __init new_property(const char *name, int length,
 		const void *value)
 {
@@ -123,22 +135,10 @@ static int __init add_raw_property(struct device_node *np, const char *name,
 	return 1;
 }
 
-struct viocd_waitevent {
-	struct completion	com;
-	int			rc;
-	u16			sub_result;
-};
-
-struct cdrom_info {
-	char	rsrcname[10];
-	char	type[4];
-	char	model[3];
-};
-
 static void __init handle_cd_event(struct HvLpEvent *event)
 {
 	struct viocdlpevent *bevent;
-	struct viocd_waitevent *pwe;
+	struct vio_waitevent *pwe;
 
 	if (!event)
 		/* Notification that a partition went away! */
@@ -158,7 +158,7 @@ static void __init handle_cd_event(struct HvLpEvent *event)
 
 	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
 	case viocdgetinfo:
-		pwe = (struct viocd_waitevent *)event->xCorrelationToken;
+		pwe = (struct vio_waitevent *)event->xCorrelationToken;
 		pwe->rc = event->xRc;
 		pwe->sub_result = bevent->sub_result;
 		complete(&pwe->com);
@@ -179,8 +179,8 @@ static void __init get_viocd_info(struct device_node *vio_root)
 {
 	HvLpEvent_Rc hvrc;
 	u32 unit;
-	struct viocd_waitevent we;
-	struct cdrom_info *unitinfo;
+	struct vio_waitevent we;
+	struct vio_resource *unitinfo;
 	dma_addr_t unitinfo_dmaaddr;
 	int ret;
 
@@ -286,6 +286,122 @@ static void __init get_viocd_info(struct device_node *vio_root)
 	viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2);
 }
 
+/* Handle interrupt events for tape */
+static void __init handle_tape_event(struct HvLpEvent *event)
+{
+	struct vio_waitevent *we;
+	struct viotapelpevent *tevent = (struct viotapelpevent *)event;
+
+	if (event == NULL)
+		/* Notification that a partition went away! */
+		return;
+
+	we = (struct vio_waitevent *)event->xCorrelationToken;
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case viotapegetinfo:
+		we->rc = tevent->sub_type_result;
+		complete(&we->com);
+		break;
+	default:
+		printk(KERN_WARNING "handle_tape_event: weird ack\n");
+	}
+}
+
+static void __init get_viotape_info(struct device_node *vio_root)
+{
+	HvLpEvent_Rc hvrc;
+	u32 unit;
+	struct vio_resource *unitinfo;
+	dma_addr_t unitinfo_dmaaddr;
+	size_t len = sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALTAPES;
+	struct vio_waitevent we;
+	int ret;
+
+	ret = viopath_open(viopath_hostLp, viomajorsubtype_tape, 2);
+	if (ret) {
+		printk(KERN_WARNING "get_viotape_info: "
+			"error on viopath_open to hostlp %d\n", ret);
+		return;
+	}
+
+	vio_setHandler(viomajorsubtype_tape, handle_tape_event);
+
+	unitinfo = iseries_hv_alloc(len, &unitinfo_dmaaddr, GFP_ATOMIC);
+	if (!unitinfo)
+		goto clear_handler;
+
+	memset(unitinfo, 0, len);
+
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_tape | viotapegetinfo,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)(unsigned long)&we, VIOVERSION << 16,
+			unitinfo_dmaaddr, len, 0, 0);
+	if (hvrc != HvLpEvent_Rc_Good) {
+		printk(KERN_WARNING "get_viotape_info: hv error on op %d\n",
+				(int)hvrc);
+		goto hv_free;
+	}
+
+	wait_for_completion(&we.com);
+
+	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
+			unitinfo[unit].rsrcname[0]; unit++) {
+		struct device_node *np;
+		char name[64];
+		u32 reg = FIRST_VIOTAPE + unit;
+
+		snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
+		np = new_node(name, vio_root);
+		if (!np)
+			goto hv_free;
+		if (!add_string_property(np, "name", "viotape") ||
+			!add_string_property(np, "device_type", "byte") ||
+			!add_string_property(np, "compatible",
+				"IBM,iSeries-viotape") ||
+			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+			!add_raw_property(np, "linux,unit_address",
+				sizeof(unit), &unit) ||
+			!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(unitinfo[unit].rsrcname),
+				unitinfo[unit].rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(unitinfo[unit].type),
+				unitinfo[unit].type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(unitinfo[unit].model),
+				unitinfo[unit].model))
+			goto node_free;
+		np->name = of_get_property(np, "name", NULL);
+		np->type = of_get_property(np, "device_type", NULL);
+		of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+		if (vio_root->pde) {
+			struct proc_dir_entry *ent;
+
+			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
+					vio_root->pde);
+			if (ent)
+				proc_device_tree_add_node(np, ent);
+		}
+#endif
+		continue;
+
+ node_free:
+		free_node(np);
+		break;
+	}
+
+ hv_free:
+	iseries_hv_free(len, unitinfo, unitinfo_dmaaddr);
+ clear_handler:
+	vio_clearHandler(viomajorsubtype_tape);
+	viopath_close(viopath_hostLp, viomajorsubtype_tape, 2);
+}
+
 static int __init iseries_vio_init(void)
 {
 	struct device_node *vio_root;
@@ -307,6 +423,7 @@ static int __init iseries_vio_init(void)
 	}
 
 	get_viocd_info(vio_root);
+	get_viotape_info(vio_root);
 
 	return 0;
 
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 064c091..f1d60f0 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -92,47 +92,6 @@ struct viot_devinfo_struct {
 #define VIOTAPOP_SETPART       14
 #define VIOTAPOP_UNLOAD        15
 
-struct viotapelpevent {
-	struct HvLpEvent event;
-	u32 reserved;
-	u16 version;
-	u16 sub_type_result;
-	u16 tape;
-	u16 flags;
-	u32 token;
-	u64 len;
-	union {
-		struct {
-			u32 tape_op;
-			u32 count;
-		} op;
-		struct {
-			u32 type;
-			u32 resid;
-			u32 dsreg;
-			u32 gstat;
-			u32 erreg;
-			u32 file_no;
-			u32 block_no;
-		} get_status;
-		struct {
-			u32 block_no;
-		} get_pos;
-	} u;
-};
-
-enum viotapesubtype {
-	viotapeopen = 0x0001,
-	viotapeclose = 0x0002,
-	viotaperead = 0x0003,
-	viotapewrite = 0x0004,
-	viotapegetinfo = 0x0005,
-	viotapeop = 0x0006,
-	viotapegetpos = 0x0007,
-	viotapesetpos = 0x0008,
-	viotapegetstatus = 0x0009
-};
-
 enum viotaperc {
 	viotape_InvalidRange = 0x0601,
 	viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
 #define VIOT_WRITING		2
 
 /* Our info on the tapes */
-struct tape_descr {
-	char rsrcname[10];
-	char type[4];
-	char model[3];
-};
-
-static struct tape_descr *viotape_unitinfo;
-static dma_addr_t viotape_unitinfo_token;
+static struct {
+	const char *rsrcname;
+	const char *type;
+	const char *model;
+} viotape_unitinfo[VIOTAPE_MAX_TAPE];
 
 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
 
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
 	return -err->errno;
 }
 
-/* Get info on all tapes from OS/400 */
-static int get_viotape_info(void)
-{
-	HvLpEvent_Rc hvrc;
-	int i;
-	size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
-	struct op_struct *op = get_op_struct();
-
-	if (op == NULL)
-		return -ENOMEM;
-
-	viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
-		GFP_ATOMIC);
-	if (viotape_unitinfo == NULL) {
-		free_op_struct(op);
-		return -ENOMEM;
-	}
-
-	memset(viotape_unitinfo, 0, len);
-
-	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
-			HvLpEvent_Type_VirtualIo,
-			viomajorsubtype_tape | viotapegetinfo,
-			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
-			viopath_sourceinst(viopath_hostLp),
-			viopath_targetinst(viopath_hostLp),
-			(u64) (unsigned long) op, VIOVERSION << 16,
-			viotape_unitinfo_token, len, 0, 0);
-	if (hvrc != HvLpEvent_Rc_Good) {
-		printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
-				(int)hvrc);
-		free_op_struct(op);
-		return -EIO;
-	}
-
-	wait_for_completion(&op->com);
-
-	free_op_struct(op);
-
-	for (i = 0;
-	     ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
-	     i++)
-		viotape_numdev++;
-	return 0;
-}
-
-
 /* Write */
 static ssize_t viotap_write(struct file *file, const char *buf,
 		size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
 	tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
 	op = (struct op_struct *)event->xCorrelationToken;
 	switch (tapeminor) {
-	case viotapegetinfo:
 	case viotapeopen:
 	case viotapeclose:
 		op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
 {
 	int i = vdev->unit_address;
 	int j;
+	struct device_node *node = vdev->dev.archdata.of_node;
 
-	if (i >= viotape_numdev)
+	if (i > VIOTAPE_MAX_TAPE)
+		return -ENODEV;
+	if (!node)
 		return -ENODEV;
 
+	if (i >= viotape_numdev)
+		viotape_numdev = i + 1;
+
 	tape_device[i] = &vdev->dev;
+	viotape_unitinfo[i].rsrcname = of_get_property(node,
+					"linux,vio_rsrcname", NULL);
+	viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
+					NULL);
+	viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
+					NULL);
 
 	state[i].cur_part = 0;
 	for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
 		goto unreg_chrdev;
 	}
 
-	if ((ret = get_viotape_info()) < 0) {
-		printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
-		goto unreg_class;
-	}
-
 	ret = vio_register_driver(&viotape_driver);
 	if (ret)
 		goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
 	vio_unregister_driver(&viotape_driver);
 	class_destroy(tape_class);
 	unregister_chrdev(VIOTAPE_MAJOR, "viotape");
-	if (viotape_unitinfo)
-		iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
-				viotape_unitinfo, viotape_unitinfo_token);
 	viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
 	vio_clearHandler(viomajorsubtype_tape);
 	clear_op_struct_pool();
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index e5a405b..2555dfd 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -75,6 +75,47 @@ enum viocdsubtype {
 	viocdcheck = 0x0007
 };
 
+struct viotapelpevent {
+	struct HvLpEvent event;
+	u32 reserved;
+	u16 version;
+	u16 sub_type_result;
+	u16 tape;
+	u16 flags;
+	u32 token;
+	u64 len;
+	union {
+		struct {
+			u32 tape_op;
+			u32 count;
+		} op;
+		struct {
+			u32 type;
+			u32 resid;
+			u32 dsreg;
+			u32 gstat;
+			u32 erreg;
+			u32 file_no;
+			u32 block_no;
+		} get_status;
+		struct {
+			u32 block_no;
+		} get_pos;
+	} u;
+};
+
+enum viotapesubtype {
+	viotapeopen = 0x0001,
+	viotapeclose = 0x0002,
+	viotaperead = 0x0003,
+	viotapewrite = 0x0004,
+	viotapegetinfo = 0x0005,
+	viotapeop = 0x0006,
+	viotapegetpos = 0x0007,
+	viotapesetpos = 0x0008,
+	viotapegetstatus = 0x0009
+};
+
 /*
  * Each subtype can register a handler to process their events.
  * The handler must have this interface.
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/7] [POWERPC] iSeries: move viodasd probing
  2007-10-11  4:58         ` [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes Stephen Rothwell
@ 2007-10-11  4:59           ` Stephen Rothwell
  0 siblings, 0 replies; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  4:59 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, Jens Axboe

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>
---
 arch/powerpc/platforms/iseries/dt.c  |    6 -
 arch/powerpc/platforms/iseries/vio.c |  301 +++++++++++++++++++++++----------
 drivers/block/viodasd.c              |   77 +++------
 include/asm-powerpc/iseries/vio.h    |   47 ++++++
 4 files changed, 282 insertions(+), 149 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index 2e4ad6b..4543c4b 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";
 static char __initdata device_type_memory[] = "memory";
 static char __initdata device_type_serial[] = "serial";
 static char __initdata device_type_network[] = "network";
-static char __initdata device_type_block[] = "block";
 static char __initdata device_type_pci[] = "pci";
 static char __initdata device_type_vdevice[] = "vdevice";
 static char __initdata device_type_vscsi[] = "vscsi";
@@ -374,11 +373,6 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
 
 		dt_end_node(dt);
 	}
-	reg += HVMAXARCHITECTEDVIRTUALLANS;
-
-	for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++)
-		dt_do_vdevice(dt, "viodasd", reg, i, device_type_block,
-				"IBM,iSeries-viodasd", 1);
 
 	dt_end_node(dt);
 }
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index b4f7433..d6435b0 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -25,8 +25,10 @@
 #include <linux/gfp.h>
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
+#include <linux/module.h>
 
 #include <asm/firmware.h>
+#include <asm/vio.h>
 #include <asm/iseries/vio.h>
 #include <asm/iseries/iommu.h>
 #include <asm/iseries/hv_types.h>
@@ -57,7 +59,7 @@ struct vio_resource {
 	char	model[3];
 };
 
-static struct property * __init new_property(const char *name, int length,
+static struct property *new_property(const char *name, int length,
 		const void *value)
 {
 	struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length,
@@ -78,7 +80,7 @@ static void __init free_property(struct property *np)
 	kfree(np);
 }
 
-static struct device_node * __init new_node(const char *path,
+static struct device_node *new_node(const char *path,
 		struct device_node *parent)
 {
 	struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL);
@@ -97,7 +99,7 @@ static struct device_node * __init new_node(const char *path,
 	return np;
 }
 
-static void __init free_node(struct device_node *np)
+static void free_node(struct device_node *np)
 {
 	struct property *next;
 	struct property *prop;
@@ -113,7 +115,7 @@ static void __init free_node(struct device_node *np)
 	kfree(np);
 }
 
-static int __init add_string_property(struct device_node *np, const char *name,
+static int add_string_property(struct device_node *np, const char *name,
 		const char *value)
 {
 	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,
 	return 1;
 }
 
-static int __init add_raw_property(struct device_node *np, const char *name,
+static int add_raw_property(struct device_node *np, const char *name,
 		int length, const void *value)
 {
 	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,
 	return 1;
 }
 
+static struct device_node *do_device_node(struct device_node *parent,
+		const char *name, u32 reg, u32 unit, const char *type,
+		const char *compat, struct vio_resource *res)
+{
+	struct device_node *np;
+	char path[32];
+
+	snprintf(path, sizeof(path), "/vdevice/%s@%08x", name, reg);
+	np = new_node(path, parent);
+	if (!np)
+		return NULL;
+	if (!add_string_property(np, "name", name) ||
+		!add_string_property(np, "device_type", type) ||
+		!add_string_property(np, "compatible", compat) ||
+		!add_raw_property(np, "reg", sizeof(reg), &reg) ||
+		!add_raw_property(np, "linux,unit_address",
+			sizeof(unit), &unit)) {
+		goto node_free;
+	}
+	if (res) {
+		if (!add_raw_property(np, "linux,vio_rsrcname",
+				sizeof(res->rsrcname), res->rsrcname) ||
+			!add_raw_property(np, "linux,vio_type",
+				sizeof(res->type), res->type) ||
+			!add_raw_property(np, "linux,vio_model",
+				sizeof(res->model), res->model))
+			goto node_free;
+	}
+	np->name = of_get_property(np, "name", NULL);
+	np->type = of_get_property(np, "device_type", NULL);
+	of_attach_node(np);
+#ifdef CONFIG_PROC_DEVICETREE
+	if (parent->pde) {
+		struct proc_dir_entry *ent;
+
+		ent = proc_mkdir(strrchr(np->full_name, '/') + 1, parent->pde);
+		if (ent)
+			proc_device_tree_add_node(np, ent);
+	}
+#endif
+	return np;
+
+ node_free:
+	free_node(np);
+	return NULL;
+}
+
+/*
+ * This is here so that we can dynamically add viodasd
+ * devices without exposing all the above infrastructure.
+ */
+struct vio_dev *vio_create_viodasd(u32 unit)
+{
+	struct device_node *vio_root;
+	struct device_node *np;
+	struct vio_dev *vdev = NULL;
+
+	vio_root = of_find_node_by_path("/vdevice");
+	if (!vio_root)
+		return NULL;
+	np = do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+			"block", "IBM,iSeries-viodasd", NULL);
+	of_node_put(vio_root);
+	if (np) {
+		vdev = vio_register_device_node(np);
+		if (!vdev)
+			free_node(np);
+	}
+	return vdev;
+}
+EXPORT_SYMBOL_GPL(vio_create_viodasd);
+
+static void __init handle_block_event(struct HvLpEvent *event)
+{
+	struct vioblocklpevent *bevent = (struct vioblocklpevent *)event;
+	struct vio_waitevent *pwe;
+
+	if (event == NULL)
+		/* Notification that a partition went away! */
+		return;
+	/* First, we should NEVER get an int here...only acks */
+	if (hvlpevent_is_int(event)) {
+		printk(KERN_WARNING "handle_viod_request: "
+		       "Yikes! got an int in viodasd event handler!\n");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+		return;
+	}
+
+	switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) {
+	case vioblockopen:
+		/*
+		 * Handle a response to an open request.  We get all the
+		 * disk information in the response, so update it.  The
+		 * correlation token contains a pointer to a waitevent
+		 * structure that has a completion in it.  update the
+		 * return code in the waitevent structure and post the
+		 * completion to wake up the guy who sent the request
+		 */
+		pwe = (struct vio_waitevent *)event->xCorrelationToken;
+		pwe->rc = event->xRc;
+		pwe->sub_result = bevent->sub_result;
+		complete(&pwe->com);
+		break;
+	case vioblockclose:
+		break;
+	default:
+		printk(KERN_WARNING "handle_viod_request: unexpected subtype!");
+		if (hvlpevent_need_ack(event)) {
+			event->xRc = HvLpEvent_Rc_InvalidSubtype;
+			HvCallEvent_ackLpEvent(event);
+		}
+	}
+}
+
+static void __init probe_disk(struct device_node *vio_root, u32 unit)
+{
+	HvLpEvent_Rc hvrc;
+	struct vio_waitevent we;
+	u16 flags = 0;
+
+retry:
+	init_completion(&we.com);
+
+	/* Send the open event to OS/400 */
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_blockio | vioblockopen,
+			HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			(u64)(unsigned long)&we, VIOVERSION << 16,
+			((u64)unit << 48) | ((u64)flags<< 32),
+			0, 0, 0);
+	if (hvrc != 0) {
+		printk(KERN_WARNING "probe_disk: bad rc on HV open %d\n",
+			(int)hvrc);
+		return;
+	}
+
+	wait_for_completion(&we.com);
+
+	if (we.rc != 0) {
+		if (flags != 0)
+			return;
+		/* try again with read only flag set */
+		flags = vioblockflags_ro;
+		goto retry;
+	}
+
+	/* Send the close event to OS/400.  We DON'T expect a response */
+	hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
+			HvLpEvent_Type_VirtualIo,
+			viomajorsubtype_blockio | vioblockclose,
+			HvLpEvent_AckInd_NoAck, HvLpEvent_AckType_ImmediateAck,
+			viopath_sourceinst(viopath_hostLp),
+			viopath_targetinst(viopath_hostLp),
+			0, VIOVERSION << 16,
+			((u64)unit << 48) | ((u64)flags << 32),
+			0, 0, 0);
+	if (hvrc != 0) {
+		printk(KERN_WARNING "probe_disk: "
+		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
+		return;
+	}
+
+	do_device_node(vio_root, "viodasd", FIRST_VIODASD + unit, unit,
+			"block", "IBM,iSeries-viodasd", NULL);
+}
+
+static void __init get_viodasd_info(struct device_node *vio_root)
+{
+	int rc;
+	u32 unit;
+
+	rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, 2);
+	if (rc) {
+		printk(KERN_WARNING "get_viodasd_info: "
+		       "error opening path to host partition %d\n",
+		       viopath_hostLp);
+		return;
+	}
+
+	/* Initialize our request handler */
+	vio_setHandler(viomajorsubtype_blockio, handle_block_event);
+
+	for (unit = 0; unit < HVMAXARCHITECTEDVIRTUALDISKS; unit++)
+		probe_disk(vio_root, unit);
+
+	vio_clearHandler(viomajorsubtype_blockio);
+	viopath_close(viopath_hostLp, viomajorsubtype_blockio, 2);
+}
+
 static void __init handle_cd_event(struct HvLpEvent *event)
 {
 	struct viocdlpevent *bevent;
@@ -233,49 +430,9 @@ static void __init get_viocd_info(struct device_node *vio_root)
 
 	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) &&
 			unitinfo[unit].rsrcname[0]; unit++) {
-		struct device_node *np;
-		char name[64];
-		u32 reg = FIRST_VIOCD + unit;
-
-		snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg);
-		np = new_node(name, vio_root);
-		if (!np)
-			goto hv_free;
-		if (!add_string_property(np, "name", "viocd") ||
-			!add_string_property(np, "device_type", "block") ||
-			!add_string_property(np, "compatible",
-				"IBM,iSeries-viocd") ||
-			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
-			!add_raw_property(np, "linux,unit_address",
-				sizeof(unit), &unit) ||
-			!add_raw_property(np, "linux,vio_rsrcname",
-				sizeof(unitinfo[unit].rsrcname),
-				unitinfo[unit].rsrcname) ||
-			!add_raw_property(np, "linux,vio_type",
-				sizeof(unitinfo[unit].type),
-				unitinfo[unit].type) ||
-			!add_raw_property(np, "linux,vio_model",
-				sizeof(unitinfo[unit].model),
-				unitinfo[unit].model))
-			goto node_free;
-		np->name = of_get_property(np, "name", NULL);
-		np->type = of_get_property(np, "device_type", NULL);
-		of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
-		if (vio_root->pde) {
-			struct proc_dir_entry *ent;
-
-			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
-					vio_root->pde);
-			if (ent)
-				proc_device_tree_add_node(np, ent);
-		}
-#endif
-		continue;
-
- node_free:
-		free_node(np);
-		break;
+		if (!do_device_node(vio_root, "viocd", FIRST_VIOCD + unit, unit,
+				"block", "IBM,iSeries-viocd", &unitinfo[unit]))
+			break;
 	}
 
  hv_free:
@@ -350,49 +507,10 @@ static void __init get_viotape_info(struct device_node *vio_root)
 
 	for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALTAPES) &&
 			unitinfo[unit].rsrcname[0]; unit++) {
-		struct device_node *np;
-		char name[64];
-		u32 reg = FIRST_VIOTAPE + unit;
-
-		snprintf(name, sizeof(name), "/vdevice/viotape@%08x", reg);
-		np = new_node(name, vio_root);
-		if (!np)
-			goto hv_free;
-		if (!add_string_property(np, "name", "viotape") ||
-			!add_string_property(np, "device_type", "byte") ||
-			!add_string_property(np, "compatible",
-				"IBM,iSeries-viotape") ||
-			!add_raw_property(np, "reg", sizeof(reg), &reg) ||
-			!add_raw_property(np, "linux,unit_address",
-				sizeof(unit), &unit) ||
-			!add_raw_property(np, "linux,vio_rsrcname",
-				sizeof(unitinfo[unit].rsrcname),
-				unitinfo[unit].rsrcname) ||
-			!add_raw_property(np, "linux,vio_type",
-				sizeof(unitinfo[unit].type),
-				unitinfo[unit].type) ||
-			!add_raw_property(np, "linux,vio_model",
-				sizeof(unitinfo[unit].model),
-				unitinfo[unit].model))
-			goto node_free;
-		np->name = of_get_property(np, "name", NULL);
-		np->type = of_get_property(np, "device_type", NULL);
-		of_attach_node(np);
-#ifdef CONFIG_PROC_DEVICETREE
-		if (vio_root->pde) {
-			struct proc_dir_entry *ent;
-
-			ent = proc_mkdir(strrchr(np->full_name, '/') + 1,
-					vio_root->pde);
-			if (ent)
-				proc_device_tree_add_node(np, ent);
-		}
-#endif
-		continue;
-
- node_free:
-		free_node(np);
-		break;
+		if (!do_device_node(vio_root, "viotape", FIRST_VIOTAPE + unit,
+				unit, "byte", "IBM,iSeries-viotape",
+				&unitinfo[unit]))
+			break;
 	}
 
  hv_free:
@@ -422,6 +540,7 @@ static int __init iseries_vio_init(void)
 			goto put_node;
 	}
 
+	get_viodasd_info(vio_root);
 	get_viocd_info(vio_root);
 	get_viotape_info(vio_root);
 
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index af3969a..e824b67 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -74,53 +74,9 @@ enum {
 static DEFINE_SPINLOCK(viodasd_spinlock);
 
 #define VIOMAXREQ		16
-#define VIOMAXBLOCKDMA		12
 
 #define DEVICE_NO(cell)	((struct viodasd_device *)(cell) - &viodasd_devices[0])
 
-struct open_data {
-	u64	disk_size;
-	u16	max_disk;
-	u16	cylinders;
-	u16	tracks;
-	u16	sectors;
-	u16	bytes_per_sector;
-};
-
-struct rw_data {
-	u64	offset;
-	struct {
-		u32	token;
-		u32	reserved;
-		u64	len;
-	} dma_info[VIOMAXBLOCKDMA];
-};
-
-struct vioblocklpevent {
-	struct HvLpEvent	event;
-	u32			reserved;
-	u16			version;
-	u16			sub_result;
-	u16			disk;
-	u16			flags;
-	union {
-		struct open_data	open_data;
-		struct rw_data		rw_data;
-		u64			changed;
-	} u;
-};
-
-#define vioblockflags_ro   0x0001
-
-enum vioblocksubtype {
-	vioblockopen = 0x0001,
-	vioblockclose = 0x0002,
-	vioblockread = 0x0003,
-	vioblockwrite = 0x0004,
-	vioblockflush = 0x0005,
-	vioblockcheck = 0x0007
-};
-
 struct viodasd_waitevent {
 	struct completion	com;
 	int			rc;
@@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q)
  * Probe a single disk and fill in the viodasd_device structure
  * for it.
  */
-static void probe_disk(struct viodasd_device *d)
+static int probe_disk(struct viodasd_device *d)
 {
 	HvLpEvent_Rc hvrc;
 	struct viodasd_waitevent we;
@@ -453,14 +409,14 @@ retry:
 			0, 0, 0);
 	if (hvrc != 0) {
 		printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc);
-		return;
+		return 0;
 	}
 
 	wait_for_completion(&we.com);
 
 	if (we.rc != 0) {
 		if (flags != 0)
-			return;
+			return 0;
 		/* try again with read only flag set */
 		flags = vioblockflags_ro;
 		goto retry;
@@ -490,15 +446,32 @@ retry:
 	if (hvrc != 0) {
 		printk(VIOD_KERN_WARNING
 		       "bad rc sending event to OS/400 %d\n", (int)hvrc);
-		return;
+		return 0;
 	}
+
+	if (d->dev == NULL) {
+		/* this is when we reprobe for new disks */
+		if (vio_create_viodasd(dev_no) == NULL) {
+			printk(VIOD_KERN_WARNING
+				"cannot allocate virtual device for disk %d\n",
+				dev_no);
+			return 0;
+		}
+		/*
+		 * The vio_create_viodasd will have recursed into this
+		 * routine with d->dev set to the new vio device and
+		 * will finish the setup of the disk below.
+		 */
+		return 1;
+	}
+
 	/* create the request queue for the disk */
 	spin_lock_init(&d->q_lock);
 	q = blk_init_queue(do_viodasd_request, &d->q_lock);
 	if (q == NULL) {
 		printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n",
 				dev_no);
-		return;
+		return 0;
 	}
 	g = alloc_disk(1 << PARTITION_SHIFT);
 	if (g == NULL) {
@@ -506,7 +479,7 @@ retry:
 				"cannot allocate disk structure for disk %d\n",
 				dev_no);
 		blk_cleanup_queue(q);
-		return;
+		return 0;
 	}
 
 	d->disk = g;
@@ -538,6 +511,7 @@ retry:
 
 	/* register us in the global list */
 	add_disk(g);
+	return 1;
 }
 
 /* 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)
 	struct viodasd_device *d = &viodasd_devices[vdev->unit_address];
 
 	d->dev = &vdev->dev;
-	probe_disk(d);
-	if (d->disk == NULL)
+	if (!probe_disk(d))
 		return -ENODEV;
 	return 0;
 }
diff --git a/include/asm-powerpc/iseries/vio.h b/include/asm-powerpc/iseries/vio.h
index 2555dfd..f9ac0d0 100644
--- a/include/asm-powerpc/iseries/vio.h
+++ b/include/asm-powerpc/iseries/vio.h
@@ -51,6 +51,51 @@
  */
 #define VIO_MAX_SUBTYPES 8
 
+#define VIOMAXBLOCKDMA	12
+
+struct open_data {
+	u64	disk_size;
+	u16	max_disk;
+	u16	cylinders;
+	u16	tracks;
+	u16	sectors;
+	u16	bytes_per_sector;
+};
+
+struct rw_data {
+	u64	offset;
+	struct {
+		u32	token;
+		u32	reserved;
+		u64	len;
+	} dma_info[VIOMAXBLOCKDMA];
+};
+
+struct vioblocklpevent {
+	struct HvLpEvent	event;
+	u32			reserved;
+	u16			version;
+	u16			sub_result;
+	u16			disk;
+	u16			flags;
+	union {
+		struct open_data	open_data;
+		struct rw_data		rw_data;
+		u64			changed;
+	} u;
+};
+
+#define vioblockflags_ro   0x0001
+
+enum vioblocksubtype {
+	vioblockopen = 0x0001,
+	vioblockclose = 0x0002,
+	vioblockread = 0x0003,
+	vioblockwrite = 0x0004,
+	vioblockflush = 0x0005,
+	vioblockcheck = 0x0007
+};
+
 struct viocdlpevent {
 	struct HvLpEvent	event;
 	u32			reserved;
@@ -133,6 +178,8 @@ extern void vio_set_hostlp(void);
 extern void *vio_get_event_buffer(int subtype);
 extern void vio_free_event_buffer(int subtype, void *buffer);
 
+extern struct vio_dev *vio_create_viodasd(u32 unit);
+
 extern HvLpIndex viopath_hostLp;
 extern HvLpIndex viopath_ourLp;
 
-- 
1.5.3.4

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
  2007-10-11  4:53   ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Stephen Rothwell
  2007-10-11  4:55     ` [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c Stephen Rothwell
@ 2007-10-11  5:25     ` Olof Johansson
  2007-10-11  5:27       ` Olof Johansson
  1 sibling, 1 reply; 11+ messages in thread
From: Olof Johansson @ 2007-10-11  5:25 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe

Hi Stephen,

On Thu, Oct 11, 2007 at 02:53:32PM +1000, Stephen Rothwell wrote:
> It was only being used to carry around dma_iommu_ops and vio_iommu_table
> which we can use directly instead.  This also means that vio_bus_device
> doesn't need to refer to them either.
> 
> diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
> index fd631d4..eaf7f69 100644
> --- a/arch/powerpc/kernel/vio.c
> +++ b/arch/powerpc/kernel/vio.c
> @@ -49,11 +49,8 @@ static struct vio_dev vio_bus_device  = { /* fake "parent" device */
>  };
>  
>  #ifdef CONFIG_PPC_ISERIES
> -struct device *iSeries_vio_dev = &vio_bus_device.dev;
> -EXPORT_SYMBOL(iSeries_vio_dev);
> -
>  static struct iommu_table veth_iommu_table;
> -static struct iommu_table vio_iommu_table;
> +struct iommu_table vio_iommu_table;
>  
>  static void __init iommu_vio_init(void)
>  {
> @@ -66,8 +63,6 @@ static void __init iommu_vio_init(void)
>  		printk("Virtual Bus VETH TCE table failed.\n");
>  	if (!iommu_init_table(&vio_iommu_table, -1))
>  		printk("Virtual Bus VIO TCE table failed.\n");
> -	vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
> -	vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
>  }
>  #else
>  static void __init iommu_vio_init(void)
> diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
> index 3b6a966..3281f10 100644
> --- a/arch/powerpc/platforms/iseries/iommu.c
> +++ b/arch/powerpc/platforms/iseries/iommu.c
> @@ -28,6 +28,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/list.h>
>  #include <linux/pci.h>
> +#include <linux/module.h>
>  
>  #include <asm/iommu.h>
>  #include <asm/tce.h>
> @@ -36,6 +37,7 @@
>  #include <asm/prom.h>
>  #include <asm/pci-bridge.h>
>  #include <asm/iseries/hv_call_xm.h>
> +#include <asm/iseries/hv_call_event.h>
>  #include <asm/iseries/iommu.h>
>  
>  static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages,
> @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
>  }
>  #endif
>  
> +extern struct iommu_table vio_iommu_table;

This looks like it really should go in a header file
instead. include/asm-powerpc/vio.h perhaps?



-Olof

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
  2007-10-11  5:25     ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Olof Johansson
@ 2007-10-11  5:27       ` Olof Johansson
  2007-10-11  5:29         ` Stephen Rothwell
  0 siblings, 1 reply; 11+ messages in thread
From: Olof Johansson @ 2007-10-11  5:27 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe

On Thu, Oct 11, 2007 at 12:25:35AM -0500, Olof Johansson wrote:
> Hi Stephen,
> 
> > @@ -189,6 +191,34 @@ void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
> >  }
> >  #endif
> >  
> > +extern struct iommu_table vio_iommu_table;
> 
> This looks like it really should go in a header file
> instead. include/asm-powerpc/vio.h perhaps?

Oh nevermind, I just noticed the variable got moved in the next
patch. Twice the review work!


-Olof

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
  2007-10-11  5:27       ` Olof Johansson
@ 2007-10-11  5:29         ` Stephen Rothwell
  2007-10-11  5:55           ` Olof Johansson
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Rothwell @ 2007-10-11  5:29 UTC (permalink / raw)
  To: Olof Johansson; +Cc: ppc-dev, paulus, Jens Axboe

[-- Attachment #1: Type: text/plain, Size: 337 bytes --]

Hi Olof,

On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
>
> Oh nevermind, I just noticed the variable got moved in the next
> patch. Twice the review work!

Thanks for the review in any case.

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

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/7] [POWERPC] remove iSeries_vio_dev
  2007-10-11  5:29         ` Stephen Rothwell
@ 2007-10-11  5:55           ` Olof Johansson
  0 siblings, 0 replies; 11+ messages in thread
From: Olof Johansson @ 2007-10-11  5:55 UTC (permalink / raw)
  To: Stephen Rothwell; +Cc: ppc-dev, paulus, Jens Axboe

On Thu, Oct 11, 2007 at 03:29:49PM +1000, Stephen Rothwell wrote:
> Hi Olof,
> 
> On Thu, 11 Oct 2007 00:27:31 -0500 Olof Johansson <olof@lixom.net> wrote:
> >
> > Oh nevermind, I just noticed the variable got moved in the next
> > patch. Twice the review work!
> 
> Thanks for the review in any case.

No problem. It's hard to split up changes like that anyway, I don't
blame you.

Rest of the patches look good to me. I had another couple of comments
but they were fixed by the end of the series too. :-)


-Olof

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2007-10-11  5:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-11  4:48 [PATCH 1/7] [POWERPC] Clean up vio.h Stephen Rothwell
2007-10-11  4:50 ` [PATCH 2/7] [POWERPC] iSeries: simplify viocd initialisation Stephen Rothwell
2007-10-11  4:53   ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Stephen Rothwell
2007-10-11  4:55     ` [PATCH 4/7] [POWERPC] Remove more iSeries specific stuff from vio.c Stephen Rothwell
2007-10-11  4:57       ` [PATCH 5/7] [POWERPC] iSeries: move detection of virtual cdroms Stephen Rothwell
2007-10-11  4:58         ` [PATCH 6/7] [POWERPC] iSeries: move detection of virtual tapes Stephen Rothwell
2007-10-11  4:59           ` [PATCH 7/7] [POWERPC] iSeries: move viodasd probing Stephen Rothwell
2007-10-11  5:25     ` [PATCH 3/7] [POWERPC] remove iSeries_vio_dev Olof Johansson
2007-10-11  5:27       ` Olof Johansson
2007-10-11  5:29         ` Stephen Rothwell
2007-10-11  5:55           ` Olof Johansson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).