[PATCH] move the iSeries virtual devices to vio
Stephen Rothwell
sfr at canb.auug.org.au
Fri Apr 2 15:33:00 EST 2004
Hi Anton,
This patch changes the iSeries virtual device drivers to use the
vio infrastructure for DMA mapping instead of the PCI infrastructure.
This is a ste alogn the way to integrating them correctly into the
driver model.
Patch relative to my previous patches. Built and booted on iSeries,
built on pSeries and pmac.
Please apply to Ameslab.
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
-------------- next part --------------
diff -ruN ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/Makefile ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/Makefile
--- ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/Makefile 2004-03-20 23:04:34.000000000 +1100
+++ ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/Makefile 2004-04-01 16:58:24.000000000 +1000
@@ -11,7 +11,7 @@
udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
ptrace32.o signal32.o rtc.o init_task.o \
lmb.o cputable.o cpu_setup_power4.o idle_power4.o \
- iommu.o
+ iommu.o vio.o
obj-$(CONFIG_PPC_OF) += of_device.o
@@ -34,7 +34,7 @@
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
eeh.o nvram.o pSeries_nvram.o rtasd.o ras.o \
open_pic.o xics.o pSeries_htab.o rtas.o \
- chrp_setup.o i8259.o prom.o vio.o pSeries_iommu.o
+ chrp_setup.o i8259.o prom.o pSeries_iommu.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
diff -ruN ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/dma.c ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/dma.c
--- ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/dma.c 2004-04-02 13:52:26.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/dma.c 2004-04-02 13:53:18.000000000 +1000
@@ -5,14 +5,11 @@
* the pci and vio busses
*/
-#include <linux/config.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
/* Include the busses we support */
#include <linux/pci.h>
-#ifdef CONFIG_PPC_PSERIES
#include <asm/vio.h>
-#endif
#include <asm/scatterlist.h>
#include <asm/bug.h>
@@ -20,10 +17,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_dma_supported(to_pci_dev(dev), mask);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_dma_supported(to_vio_dev(dev), mask);
-#endif
BUG();
return 0;
}
@@ -33,10 +28,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_set_dma_mask(to_vio_dev(dev), dma_mask);
-#endif
BUG();
return 0;
}
@@ -47,10 +40,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_alloc_consistent(to_vio_dev(dev), size, dma_handle);
-#endif
BUG();
return 0;
}
@@ -61,10 +52,8 @@
{
if (dev->bus == &pci_bus_type)
pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_free_consistent(to_vio_dev(dev), size, cpu_addr, dma_handle);
-#endif
else
BUG();
}
@@ -75,10 +64,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_map_single(to_vio_dev(dev), cpu_addr, size, direction);
-#endif
BUG();
return (dma_addr_t)0;
}
@@ -89,10 +76,8 @@
{
if (dev->bus == &pci_bus_type)
pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_unmap_single(to_vio_dev(dev), dma_addr, size, direction);
-#endif
else
BUG();
}
@@ -104,10 +89,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_map_page(to_vio_dev(dev), page, offset, size, direction);
-#endif
BUG();
return (dma_addr_t)0;
}
@@ -118,10 +101,8 @@
{
if (dev->bus == &pci_bus_type)
pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_unmap_page(to_vio_dev(dev), dma_address, size, direction);
-#endif
else
BUG();
}
@@ -132,10 +113,8 @@
{
if (dev->bus == &pci_bus_type)
return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
if (dev->bus == &vio_bus_type)
return vio_map_sg(to_vio_dev(dev), sg, nents, direction);
-#endif
BUG();
return 0;
}
@@ -146,10 +125,8 @@
{
if (dev->bus == &pci_bus_type)
pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_unmap_sg(to_vio_dev(dev), sg, nhwentries, direction);
-#endif
else
BUG();
}
@@ -160,10 +137,8 @@
{
if (dev->bus == &pci_bus_type)
pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_dma_sync_single(to_vio_dev(dev), dma_handle, size, direction);
-#endif
else
BUG();
}
@@ -174,10 +149,8 @@
{
if (dev->bus == &pci_bus_type)
pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction);
-#ifdef CONFIG_PPC_PSERIES
else if (dev->bus == &vio_bus_type)
vio_dma_sync_sg(to_vio_dev(dev), sg, nelems, direction);
-#endif
else
BUG();
}
diff -ruN ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/iSeries_iommu.c ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/iSeries_iommu.c
--- ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/iSeries_iommu.c 2004-04-02 13:52:30.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/iSeries_iommu.c 2004-04-02 15:20:25.000000000 +1000
@@ -2,24 +2,24 @@
* arch/ppc64/kernel/iSeries_iommu.c
*
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
- *
- * Rewrite, cleanup:
+ *
+ * Rewrite, cleanup:
*
* Copyright (C) 2004 Olof Johansson <olof at austin.ibm.com>, IBM Corporation
*
* Dynamic DMA mapping support, iSeries-specific parts.
*
- *
+ *
* 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
@@ -44,28 +44,12 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/iSeries/iSeries_pci.h>
-#include <asm/iSeries/vio.h>
#include <asm/machdep.h>
#include "pci.h"
-static struct iommu_table veth_iommu_table; /* Tce table for virtual ethernet */
-static struct iommu_table vio_iommu_table; /* Tce table for virtual I/O */
-
-static struct iSeries_Device_Node veth_dev_node = { .LogicalSlot = 0xFF, .iommu_table = &veth_iommu_table };
-static struct iSeries_Device_Node vio_dev_node = { .LogicalSlot = 0xFF, .iommu_table = &vio_iommu_table };
-
-static struct pci_dev _veth_dev = { .sysdata = &veth_dev_node };
-static struct pci_dev _vio_dev = { .sysdata = &vio_dev_node, .dev.bus = &pci_bus_type };
-
-struct pci_dev *iSeries_veth_dev = &_veth_dev;
-struct device *iSeries_vio_dev = &_vio_dev.dev;
-
-EXPORT_SYMBOL(iSeries_veth_dev);
-EXPORT_SYMBOL(iSeries_vio_dev);
-
extern struct list_head iSeries_Global_Device_List;
@@ -74,7 +58,7 @@
{
u64 rc;
union tce_entry tce;
-
+
while (npages--) {
tce.te_word = 0;
tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> PAGE_SHIFT;
@@ -91,9 +75,9 @@
if (direction != DMA_TO_DEVICE)
tce.te_bits.tb_pciwr = 1;
}
-
- rc = HvCallXm_setTce((u64)tbl->it_index,
- (u64)index,
+
+ rc = HvCallXm_setTce((u64)tbl->it_index,
+ (u64)index,
tce.te_word);
if (rc)
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc);
@@ -114,7 +98,7 @@
(u64)index,
tce.te_word);
- if (rc)
+ if (rc)
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc);
index++;
@@ -122,50 +106,10 @@
}
-void __init iommu_vio_init(void)
-{
- struct iommu_table *t;
- struct iommu_table_cb cb;
- unsigned long cbp;
-
- cb.itc_busno = 255; /* Bus 255 is the virtual bus */
- cb.itc_virtbus = 0xff; /* Ask for virtual bus */
-
- cbp = virt_to_abs(&cb);
- HvCallXm_getTceTableParms(cbp);
-
- veth_iommu_table.it_size = cb.itc_size / 2;
- veth_iommu_table.it_busno = cb.itc_busno;
- veth_iommu_table.it_offset = cb.itc_offset;
- veth_iommu_table.it_index = cb.itc_index;
- veth_iommu_table.it_type = TCE_VB;
- veth_iommu_table.it_entrysize = sizeof(union tce_entry);
- veth_iommu_table.it_blocksize = 1;
-
- t = iommu_init_table(&veth_iommu_table);
-
- if (!t)
- printk("Virtual Bus VETH TCE table failed.\n");
-
- vio_iommu_table.it_size = cb.itc_size - veth_iommu_table.it_size;
- vio_iommu_table.it_busno = cb.itc_busno;
- vio_iommu_table.it_offset = cb.itc_offset +
- veth_iommu_table.it_size * (PAGE_SIZE/sizeof(union tce_entry));
- vio_iommu_table.it_index = cb.itc_index;
- vio_iommu_table.it_type = TCE_VB;
- vio_iommu_table.it_entrysize = sizeof(union tce_entry);
- vio_iommu_table.it_blocksize = 1;
-
- t = iommu_init_table(&vio_iommu_table);
-
- if (!t)
- printk("Virtual Bus VIO TCE table failed.\n");
-}
-
/*
* This function compares the known tables to find an iommu_table
- * that has already been built for hardware TCEs.
+ * that has already been built for hardware TCEs.
*/
static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
@@ -173,26 +117,26 @@
for (dp = (struct iSeries_Device_Node *)iSeries_Global_Device_List.next;
dp != (struct iSeries_Device_Node *)&iSeries_Global_Device_List;
- dp = (struct iSeries_Device_Node *)dp->Device_List.next)
+ dp = (struct iSeries_Device_Node *)dp->Device_List.next)
if (dp->iommu_table != NULL &&
dp->iommu_table->it_type == TCE_PCI &&
dp->iommu_table->it_offset == tbl->it_offset &&
dp->iommu_table->it_index == tbl->it_index &&
- dp->iommu_table->it_size == tbl->it_size)
+ dp->iommu_table->it_size == tbl->it_size)
return dp->iommu_table;
-
+
return NULL;
}
/*
* Call Hv with the architected data structure to get TCE table info.
- * info. Put the returned data into the Linux representation of the
- * TCE table data.
- * The Hardware Tce table comes in three flavors.
- * 1. TCE table shared between Buses.
- * 2. TCE table per Bus.
- * 3. TCE Table per IOA.
+ * info. Put the returned data into the Linux representation of the
+ * TCE table data.
+ * The Hardware Tce table comes in three flavors.
+ * 1. TCE table shared between Buses.
+ * 2. TCE table per Bus.
+ * 3. TCE Table per IOA.
*/
static void iommu_table_getparms(struct iSeries_Device_Node* dn,
struct iommu_table* tbl)
@@ -201,7 +145,7 @@
parms = (struct iommu_table_cb*)kmalloc(sizeof(*parms), GFP_KERNEL);
- if (parms == NULL)
+ if (parms == NULL)
panic("PCI_DMA: TCE Table Allocation failed.");
memset(parms, 0, sizeof(*parms));
diff -ruN ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/iSeries_pci.c ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/iSeries_pci.c
--- ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/iSeries_pci.c 2004-03-30 12:04:37.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/iSeries_pci.c 2004-04-02 14:28:49.000000000 +1000
@@ -46,7 +46,6 @@
#include <asm/iSeries/iSeries_irq.h>
#include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/mf.h>
-#include <asm/iSeries/vio.h>
#include "iSeries_IoMmTable.h"
#include "pci.h"
@@ -243,11 +242,6 @@
iSeries_IoMmTable_Status();
iSeries_activate_IRQs();
mf_displaySrc(0xC9000200);
-
- /* Now set up virtual bus device information */
- if (device_register(iSeries_vio_dev)) {
- printk("pcibios error registering iSeries_vio_dev\n");
- }
}
void pcibios_fixup_bus(struct pci_bus *PciBus)
diff -ruN ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/vio.c ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/vio.c
--- ppc64-2.5-iseries.dma.4/arch/ppc64/kernel/vio.c 2004-04-02 13:52:34.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/arch/ppc64/kernel/vio.c 2004-04-02 14:38:03.000000000 +1000
@@ -25,6 +25,8 @@
#include <asm/ppcdebug.h>
#include <asm/vio.h>
#include <asm/hvcall.h>
+#include <asm/iSeries/vio.h>
+#include <asm/iSeries/HvCallXm.h>
#define DBGENTER() pr_debug("%s entered\n", __FUNCTION__)
@@ -32,9 +34,31 @@
struct iommu_table *vio_build_iommu_table(struct vio_dev *dev);
+#ifdef CONFIG_PPC_PSERIES
static int vio_num_address_cells;
+#endif
static struct vio_dev *vio_bus_device; /* fake "parent" device */
+#ifdef CONFIG_PPC_ISERIES
+static struct iommu_table veth_iommu_table;
+static struct iommu_table vio_iommu_table;
+
+static struct vio_dev _veth_dev = {
+ .iommu_table = &veth_iommu_table,
+ .dev.bus = &vio_bus_type
+};
+static struct vio_dev _vio_dev = {
+ .iommu_table = &vio_iommu_table,
+ .dev.bus = &vio_bus_type
+};
+
+struct vio_dev *iSeries_veth_dev = &_veth_dev;
+struct device *iSeries_vio_dev = &_vio_dev.dev;
+
+EXPORT_SYMBOL(iSeries_veth_dev);
+EXPORT_SYMBOL(iSeries_vio_dev);
+#endif
+
/* convert from struct device to struct vio_dev and pass to driver.
* dev->driver has already been set by generic code because vio_bus_match
* succeeded. */
@@ -117,21 +141,67 @@
{
DBGENTER();
+#ifdef CONFIG_PPC_PSERIES
while (ids->type) {
if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) &&
device_is_compatible((struct device_node*)dev->archdata, ids->compat))
return ids;
ids++;
}
+#endif
return NULL;
}
+#ifdef CONFIG_PPC_ISERIES
+void __init iommu_vio_init(void)
+{
+ struct iommu_table *t;
+ struct iommu_table_cb cb;
+ unsigned long cbp;
+
+ cb.itc_busno = 255; /* Bus 255 is the virtual bus */
+ cb.itc_virtbus = 0xff; /* Ask for virtual bus */
+
+ cbp = virt_to_abs(&cb);
+ HvCallXm_getTceTableParms(cbp);
+
+ veth_iommu_table.it_size = cb.itc_size / 2;
+ veth_iommu_table.it_busno = cb.itc_busno;
+ veth_iommu_table.it_offset = cb.itc_offset;
+ veth_iommu_table.it_index = cb.itc_index;
+ veth_iommu_table.it_type = TCE_VB;
+ veth_iommu_table.it_entrysize = sizeof(union tce_entry);
+ veth_iommu_table.it_blocksize = 1;
+
+ t = iommu_init_table(&veth_iommu_table);
+
+ if (!t)
+ printk("Virtual Bus VETH TCE table failed.\n");
+
+ vio_iommu_table.it_size = cb.itc_size - veth_iommu_table.it_size;
+ vio_iommu_table.it_busno = cb.itc_busno;
+ vio_iommu_table.it_offset = cb.itc_offset +
+ veth_iommu_table.it_size * (PAGE_SIZE/sizeof(union tce_entry));
+ vio_iommu_table.it_index = cb.itc_index;
+ vio_iommu_table.it_type = TCE_VB;
+ vio_iommu_table.it_entrysize = sizeof(union tce_entry);
+ vio_iommu_table.it_blocksize = 1;
+
+ t = iommu_init_table(&vio_iommu_table);
+
+ if (!t)
+ printk("Virtual Bus VIO TCE table failed.\n");
+}
+#endif
+
/**
* vio_bus_init: - Initialize the virtual IO bus
*/
static int __init vio_bus_init(void)
{
+#ifdef CONFIG_PPC_PSERIES
struct device_node *node_vroot, *of_node;
+#endif
int err;
err = bus_register(&vio_bus_type);
@@ -156,6 +226,7 @@
return err;
}
+#ifdef CONFIG_PPC_PSERIES
node_vroot = find_devices("vdevice");
if ((node_vroot == NULL) || (node_vroot->child == NULL)) {
/* this machine doesn't do virtual IO, and that's ok */
@@ -175,6 +246,7 @@
vio_register_device(of_node);
}
+#endif
return 0;
}
@@ -182,6 +254,7 @@
__initcall(vio_bus_init);
+#ifdef CONFIG_PPC_PSERIES
/* vio_dev refcount hit 0 */
static void __devinit vio_dev_release(struct device *dev)
{
@@ -412,6 +485,7 @@
return rc;
}
EXPORT_SYMBOL(vio_disable_interrupts);
+#endif
dma_addr_t vio_map_single(struct vio_dev *dev, void *vaddr,
diff -ruN ppc64-2.5-iseries.dma.4/drivers/net/iseries_veth.c ppc64-2.5-iseries.vio.1/drivers/net/iseries_veth.c
--- ppc64-2.5-iseries.dma.4/drivers/net/iseries_veth.c 2004-03-31 16:04:29.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/drivers/net/iseries_veth.c 2004-04-02 14:32:02.000000000 +1000
@@ -78,10 +78,11 @@
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iommu.h>
+#include <asm/vio.h>
#include "iseries_veth.h"
-extern struct pci_dev *iSeries_veth_dev;
+extern struct vio_dev *iSeries_veth_dev;
MODULE_AUTHOR("Kyle Lucke <klucke at us.ibm.com>");
MODULE_DESCRIPTION("iSeries Virtual ethernet driver");
@@ -899,12 +900,12 @@
}
dma_length = skb->len;
- dma_address = pci_map_single(iSeries_veth_dev, skb->data,
- dma_length, PCI_DMA_TODEVICE);
+ dma_address = vio_map_single(iSeries_veth_dev, skb->data,
+ dma_length, DMA_TO_DEVICE);
/* Is it really necessary to check the length and address
* fields of the first entry here? */
- if (!pci_dma_mapping_error(dma_address)) {
+ if (!vio_dma_mapping_error(dma_address)) {
msg->skb = skb;
msg->data.addr[0] = dma_address;
msg->data.len[0] = dma_length;
@@ -1028,8 +1029,8 @@
dma_address = myMsg->data.addr[0];
dma_length = myMsg->data.len[0];
- pci_unmap_single(iSeries_veth_dev, dma_address, dma_length,
- PCI_DMA_TODEVICE);
+ vio_unmap_single(iSeries_veth_dev, dma_address, dma_length,
+ DMA_TO_DEVICE);
if (myMsg->skb) {
dev_kfree_skb_any(myMsg->skb);
diff -ruN ppc64-2.5-iseries.dma.4/drivers/scsi/ibmvscsi/iseries_vscsi.c ppc64-2.5-iseries.vio.1/drivers/scsi/ibmvscsi/iseries_vscsi.c
--- ppc64-2.5-iseries.dma.4/drivers/scsi/ibmvscsi/iseries_vscsi.c 2004-03-31 10:04:35.000000000 +1000
+++ ppc64-2.5-iseries.vio.1/drivers/scsi/ibmvscsi/iseries_vscsi.c 2004-04-02 14:38:57.000000000 +1000
@@ -32,17 +32,16 @@
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpConfig.h>
-#include <linux/pci.h>
+#include <asm/vio.h>
#include <linux/device.h>
#include "ibmvscsi.h"
static void noop_release(struct device *dev) {};
/* global variables */
-extern struct device *iSeries_vio_dev;
static struct ibmvscsi_host_data *single_host_data;
-static struct pci_dev iseries_vscsi_dev = {
- .dev.bus = &pci_bus_type,
+static struct vio_dev iseries_vscsi_dev = {
+ .dev.bus = &vio_bus_type,
.dev.bus_id = "vscsi",
.dev.release = noop_release
};
@@ -142,7 +141,7 @@
int __init ibmvscsi_module_init(void)
{
- iseries_vscsi_dev.sysdata = to_pci_dev(iSeries_vio_dev)->sysdata;
+ iseries_vscsi_dev.archdata = to_vio_dev(iSeries_vio_dev)->archdata;
if (device_register(&iseries_vscsi_dev.dev)) {
printk(KERN_ERR "ibmvscsi: failed to register device\n");
return 1;
More information about the Linuxppc64-dev
mailing list