* [PATCH] 0/5 PPC64 - make iSeries virtual devices/drivers appear in sysfs @ 2004-06-28 16:28 Stephen Rothwell 2004-06-28 16:33 ` [PATCH] 1/5 PPC64 - vio infrastructure modifications Stephen Rothwell 0 siblings, 1 reply; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:28 UTC (permalink / raw) To: Andrew Morton; +Cc: Linus, LKML, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 2005 bytes --] Hi Andrew, Linus, This is the patch I submitted for comment last week broken up a bit. The purpose of the patch set is to integrate the iSeries virtual device drivers in the driver infrastructure to allow for fairly reasonable user mode probing for devices. For each possible virtual device, there is an entry in /sys/devices/vio and /sys/bus/vio/devices with the exception of the virtual ethernets where there is an entry for each virtual lan that is actually configured. When the appropriate device driver is loaded (if it is a module), then entries for actually configured devices appear in /sys/bus/vio/drivers/<drivername>. To only create entries for configured devices in /sys/devices/vio (etc) would require some rework and moving of the device probing code for each driver. This may be done in the future. This patch set is meant to be fairly minimal in order to get user mode device enumeration. The patches following are: 1) update the vio infrastructure so that iSeries can use it. This patch has only very small changes to the way pSeries works - and then only internally to vio.c (apart from the renaminf of one routine). 2) integrate iseries_veth 3) viodasd 4) viocd 5) viotape arch/ppc64/kernel/vio.c | 189 +++++++++++++++++++++++++----------- drivers/block/viodasd.c | 87 ++++++++++------ drivers/cdrom/viocd.c | 185 +++++++++++++++++++++-------------- drivers/char/viotape.c | 119 ++++++++++++++-------- drivers/net/iseries_veth.c | 104 ++++++++++++------- drivers/net/iseries_veth.h | 2 drivers/pci/hotplug/rpaphp_vio.c | 4 include/asm-ppc64/iSeries/HvTypes.h | 4 include/asm-ppc64/vio.h | 8 + 9 files changed, 456 insertions(+), 246 deletions(-) As I said, I posted this patch set as a single patch last week. Unless we have objections, please apply. -- 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] 6+ messages in thread
* [PATCH] 1/5 PPC64 - vio infrastructure modifications 2004-06-28 16:28 [PATCH] 0/5 PPC64 - make iSeries virtual devices/drivers appear in sysfs Stephen Rothwell @ 2004-06-28 16:33 ` Stephen Rothwell 2004-06-28 16:35 ` [PATCH] 2/5 PPC64 - iseries_veth integration Stephen Rothwell 0 siblings, 1 reply; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:33 UTC (permalink / raw) To: Andrew Morton Cc: torvalds, linux-kernel, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 10463 bytes --] The intention here is to have no effect on pSeries except: 1) vio_register_device is renamed to vio_register_device_node to better reflect is purpose and to allow me to introduce vio_register_device_iseries. 2) I have introduced the name and type fields in struct vio_dev to make these two fields independent of subarchitecture. -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.6.7-bk9.base/arch/ppc64/kernel/vio.c 2.6.7-bk9.base.sysvio.1/arch/ppc64/kernel/vio.c --- 2.6.7-bk9.base/arch/ppc64/kernel/vio.c 2004-06-16 22:15:20.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.1/arch/ppc64/kernel/vio.c 2004-06-27 21:05:41.000000000 +1000 @@ -32,16 +32,19 @@ extern struct subsystem devices_subsys; /* needed for vio_find_name() */ -static struct iommu_table *vio_build_iommu_table(struct vio_dev *); static const struct vio_device_id *vio_match_device( const struct vio_device_id *, const struct vio_dev *); #ifdef CONFIG_PPC_PSERIES +static struct iommu_table *vio_build_iommu_table(struct vio_dev *); static int vio_num_address_cells; #endif static struct vio_dev *vio_bus_device; /* fake "parent" device */ #ifdef CONFIG_PPC_ISERIES +static struct vio_dev *__init vio_register_device_iseries(char *type, + uint32_t unit_num); + static struct iommu_table veth_iommu_table; static struct iommu_table vio_iommu_table; @@ -59,6 +62,9 @@ EXPORT_SYMBOL(iSeries_veth_dev); EXPORT_SYMBOL(iSeries_vio_dev); + +#define device_is_compatible(a, b) 1 + #endif /* convert from struct device to struct vio_dev and pass to driver. @@ -143,14 +149,12 @@ { DBGENTER(); -#ifdef CONFIG_PPC_PSERIES while (ids->type) { - if ((strncmp(((struct device_node *)dev->dev.platform_data)->type, ids->type, strlen(ids->type)) == 0) && + if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && device_is_compatible(dev->dev.platform_data, ids->compat)) return ids; ids++; } -#endif return NULL; } @@ -196,14 +200,41 @@ } #endif +#ifdef CONFIG_PPC_PSERIES +static void probe_bus_pseries(void) +{ + struct device_node *node_vroot, *of_node; + + node_vroot = find_devices("vdevice"); + if ((node_vroot == NULL) || (node_vroot->child == NULL)) + /* this machine doesn't do virtual IO, and that's ok */ + return; + + vio_num_address_cells = prom_n_addr_cells(node_vroot->child); + + /* + * Create struct vio_devices for each virtual device in the device tree. + * Drivers will associate with them later. + */ + for (of_node = node_vroot->child; of_node != NULL; + of_node = of_node->sibling) { + printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); + vio_register_device_node(of_node); + } +} +#endif + +#ifdef CONFIG_PPC_ISERIES +static void probe_bus_iseries(void) +{ +} +#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); @@ -229,25 +260,10 @@ } #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 */ - return 0; - } - - vio_num_address_cells = prom_n_addr_cells(node_vroot->child); - - /* - * Create struct vio_devices for each virtual device in the device tree. - * Drivers will associate with them later. - */ - for (of_node = node_vroot->child; - of_node != NULL; - of_node = of_node->sibling) { - printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); - - vio_register_device(of_node); - } + probe_bus_pseries(); +#endif +#ifdef CONFIG_PPC_ISERIES + probe_bus_iseries(); #endif return 0; @@ -255,20 +271,19 @@ __initcall(vio_bus_init); - -#ifdef CONFIG_PPC_PSERIES /* vio_dev refcount hit 0 */ static void __devinit vio_dev_release(struct device *dev) { - struct vio_dev *viodev = to_vio_dev(dev); - DBGENTER(); +#ifdef CONFIG_PPC_PSERIES /* XXX free TCE table */ - of_node_put(viodev->dev.platform_data); - kfree(viodev); + of_node_put(dev->platform_data); +#endif + kfree(to_vio_dev(dev)); } +#ifdef CONFIG_PPC_PSERIES static ssize_t viodev_show_devspec(struct device *dev, char *buf) { struct device_node *of_node = dev->platform_data; @@ -276,17 +291,43 @@ return sprintf(buf, "%s\n", of_node->full_name); } DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); +#endif static ssize_t viodev_show_name(struct device *dev, char *buf) { - struct device_node *of_node = dev->platform_data; - - return sprintf(buf, "%s\n", of_node->name); + return sprintf(buf, "%s\n", to_vio_dev(dev)->name); } DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_name, NULL); +static struct vio_dev * __devinit vio_register_device_common( + struct vio_dev *viodev, char *name, char *type, + uint32_t unit_address, struct iommu_table *iommu_table) +{ + DBGENTER(); + + viodev->name = name; + viodev->type = type; + viodev->unit_address = unit_address; + viodev->iommu_table = iommu_table; + /* init generic 'struct device' fields: */ + viodev->dev.parent = &vio_bus_device->dev; + viodev->dev.bus = &vio_bus_type; + viodev->dev.release = vio_dev_release; + + /* register with generic device framework */ + if (device_register(&viodev->dev)) { + printk(KERN_ERR "%s: failed to register device %s\n", + __FUNCTION__, viodev->dev.bus_id); + return NULL; + } + device_create_file(&viodev->dev, &dev_attr_name); + + return viodev; +} + +#ifdef CONFIG_PPC_PSERIES /** - * vio_register_device: - Register a new vio device. + * vio_register_device_node: - Register a new vio device. * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in @@ -294,7 +335,7 @@ * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ -struct vio_dev * __devinit vio_register_device(struct device_node *of_node) +struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) { struct vio_dev *viodev; unsigned int *unit_address; @@ -325,8 +366,6 @@ memset(viodev, 0, sizeof(struct vio_dev)); viodev->dev.platform_data = of_node_get(of_node); - viodev->unit_address = *unit_address; - viodev->iommu_table = vio_build_iommu_table(viodev); viodev->irq = NO_IRQ; irq_p = (unsigned int *)get_property(of_node, "interrupts", 0); @@ -339,36 +378,60 @@ viodev->irq = irq_offset_up(virq); } - /* init generic 'struct device' fields: */ - viodev->dev.parent = &vio_bus_device->dev; - viodev->dev.bus = &vio_bus_type; - snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", viodev->unit_address); - viodev->dev.release = vio_dev_release; + snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); /* register with generic device framework */ - if (device_register(&viodev->dev)) { - printk(KERN_ERR "%s: failed to register device %s\n", __FUNCTION__, - viodev->dev.bus_id); + if (vio_register_device_common(viodev, of_node->name, of_node->type, + *unit_address, vio_build_iommu_table(viodev)) + == NULL) { /* XXX free TCE table */ kfree(viodev); return NULL; } - device_create_file(&viodev->dev, &dev_attr_name); device_create_file(&viodev->dev, &dev_attr_devspec); return viodev; } -EXPORT_SYMBOL(vio_register_device); +EXPORT_SYMBOL(vio_register_device_node); +#endif + +#ifdef CONFIG_PPC_ISERIES +/** + * vio_register_device: - Register a new vio device. + * @voidev: The device to register. + */ +static struct vio_dev *__init vio_register_device_iseries(char *type, + uint32_t unit_num) +{ + struct vio_dev *viodev; + + DBGENTER(); + + /* allocate a vio_dev for this node */ + viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); + if (!viodev) + return NULL; + memset(viodev, 0, sizeof(struct vio_dev)); + + snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num); + + return vio_register_device_common(viodev, viodev->dev.bus_id, type, + unit_num, &vio_iommu_table); +} +#endif void __devinit vio_unregister_device(struct vio_dev *viodev) { DBGENTER(); +#ifdef CONFIG_PPC_PSERIES device_remove_file(&viodev->dev, &dev_attr_devspec); +#endif device_remove_file(&viodev->dev, &dev_attr_name); device_unregister(&viodev->dev); } EXPORT_SYMBOL(vio_unregister_device); +#ifdef CONFIG_PPC_PSERIES /** * vio_get_attribute: - get attribute for virtual device * @vdev: The vio device to get property. diff -ruN 2.6.7-bk9.base/drivers/pci/hotplug/rpaphp_vio.c 2.6.7-bk9.base.sysvio.1/drivers/pci/hotplug/rpaphp_vio.c --- 2.6.7-bk9.base/drivers/pci/hotplug/rpaphp_vio.c 2004-06-27 13:31:04.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.1/drivers/pci/hotplug/rpaphp_vio.c 2004-06-27 20:35:41.000000000 +1000 @@ -87,7 +87,7 @@ slot->dev_type = VIO_DEV; slot->dev.vio_dev = vio_find_node(dn); if (!slot->dev.vio_dev) - slot->dev.vio_dev = vio_register_device(dn); + slot->dev.vio_dev = vio_register_device_node(dn); if (slot->dev.vio_dev) slot->state = CONFIGURED; else @@ -108,7 +108,7 @@ { int retval = 0; - if ((slot->dev.vio_dev = vio_register_device(slot->dn))) { + if ((slot->dev.vio_dev = vio_register_device_node(slot->dn))) { info("%s: VIO adapter %s in slot[%s] has been configured\n", __FUNCTION__, slot->dn->name, slot->name); slot->state = CONFIGURED; diff -ruN 2.6.7-bk9.base/include/asm-ppc64/vio.h 2.6.7-bk9.base.sysvio.1/include/asm-ppc64/vio.h --- 2.6.7-bk9.base/include/asm-ppc64/vio.h 2004-06-16 22:15:30.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.1/include/asm-ppc64/vio.h 2004-06-27 20:45:48.000000000 +1000 @@ -14,6 +14,7 @@ #ifndef _ASM_VIO_H #define _ASM_VIO_H +#include <linux/config.h> #include <linux/init.h> #include <linux/errno.h> #include <linux/device.h> @@ -44,7 +45,10 @@ int vio_register_driver(struct vio_driver *drv); void vio_unregister_driver(struct vio_driver *drv); -struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev); +#ifdef CONFIG_PPC_PSERIES +struct vio_dev * __devinit vio_register_device_node( + struct device_node *node_vdev); +#endif void __devinit vio_unregister_device(struct vio_dev *dev); struct vio_dev *vio_find_node(struct device_node *vnode); @@ -108,6 +112,8 @@ */ struct vio_dev { struct iommu_table *iommu_table; /* vio_map_* uses this */ + char *name; + char *type; uint32_t unit_address; unsigned int irq; [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] 2/5 PPC64 - iseries_veth integration 2004-06-28 16:33 ` [PATCH] 1/5 PPC64 - vio infrastructure modifications Stephen Rothwell @ 2004-06-28 16:35 ` Stephen Rothwell 2004-06-28 16:38 ` [PATCH] 3/5 PPC64 - viodasd integration Stephen Rothwell 0 siblings, 1 reply; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:35 UTC (permalink / raw) To: Andrew Morton Cc: torvalds, linux-kernel, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 7281 bytes --] -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.6.7-bk9.base.sysvio.1/arch/ppc64/kernel/vio.c 2.6.7-bk9.base.sysvio.2/arch/ppc64/kernel/vio.c --- 2.6.7-bk9.base.sysvio.1/arch/ppc64/kernel/vio.c 2004-06-27 21:05:41.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.2/arch/ppc64/kernel/vio.c 2004-06-29 01:20:18.000000000 +1000 @@ -26,7 +26,9 @@ #include <asm/vio.h> #include <asm/hvcall.h> #include <asm/iSeries/vio.h> +#include <asm/iSeries/HvTypes.h> #include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/HvLpConfig.h> #define DBGENTER() pr_debug("%s entered\n", __FUNCTION__) @@ -48,19 +50,11 @@ 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); #define device_is_compatible(a, b) 1 @@ -227,6 +221,18 @@ #ifdef CONFIG_PPC_ISERIES static void probe_bus_iseries(void) { + HvLpIndexMap vlan_map = HvLpConfig_getVirtualLanIndexMap(); + struct vio_dev *viodev; + int i; + + vlan_map = HvLpConfig_getVirtualLanIndexMap(); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { + if ((vlan_map & (0x8000 >> i)) == 0) + continue; + viodev = vio_register_device_iseries("vlan", i); + /* veth is special and has it own iommu_table */ + viodev->iommu_table = &veth_iommu_table; + } } #endif diff -ruN 2.6.7-bk9.base.sysvio.1/drivers/net/iseries_veth.c 2.6.7-bk9.base.sysvio.2/drivers/net/iseries_veth.c --- 2.6.7-bk9.base.sysvio.1/drivers/net/iseries_veth.c 2004-06-16 22:15:24.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.2/drivers/net/iseries_veth.c 2004-06-20 01:34:46.000000000 +1000 @@ -81,8 +81,6 @@ #include "iseries_veth.h" -extern struct vio_dev *iSeries_veth_dev; - MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>"); MODULE_DESCRIPTION("iSeries Virtual ethernet driver"); MODULE_LICENSE("GPL"); @@ -119,6 +117,7 @@ int token; unsigned long in_use; struct sk_buff *skb; + struct device *dev; }; struct veth_lpar_connection { @@ -147,6 +146,7 @@ }; struct veth_port { + struct device *dev; struct net_device_stats stats; u64 mac_addr; HvLpIndexMap lpar_map; @@ -843,7 +843,7 @@ spin_unlock_irqrestore(&port->pending_gate, flags); } -struct net_device * __init veth_probe_one(int vlan) +static struct net_device * __init veth_probe_one(int vlan, struct device *vdev) { struct net_device *dev; struct veth_port *port; @@ -869,6 +869,7 @@ if (map & (0x8000 >> vlan)) port->lpar_map |= (1 << i); } + port->dev = vdev; dev->dev_addr[0] = 0x02; dev->dev_addr[1] = 0x01; @@ -893,6 +894,8 @@ dev->watchdog_timeo = 2 * (VETH_ACKTIMEOUT * HZ / 1000000); dev->tx_timeout = veth_tx_timeout; + SET_NETDEV_DEV(dev, vdev); + rc = register_netdev(dev); if (rc != 0) { veth_printk(KERN_ERR, @@ -945,7 +948,7 @@ } dma_length = skb->len; - dma_address = vio_map_single(iSeries_veth_dev, skb->data, + dma_address = dma_map_single(port->dev, skb->data, dma_length, DMA_TO_DEVICE); if (dma_mapping_error(dma_address)) @@ -954,6 +957,7 @@ /* Is it really necessary to check the length and address * fields of the first entry here? */ msg->skb = skb; + msg->dev = port->dev; msg->data.addr[0] = dma_address; msg->data.len[0] = dma_length; msg->data.eofmask = 1 << VETH_EOF_SHIFT; @@ -1059,7 +1063,7 @@ dma_address = msg->data.addr[0]; dma_length = msg->data.len[0]; - vio_unmap_single(iSeries_veth_dev, dma_address, dma_length, + dma_unmap_single(msg->dev, dma_address, dma_length, DMA_TO_DEVICE); if (msg->skb) { @@ -1327,6 +1331,58 @@ spin_unlock_irqrestore(&cnx->lock, flags); } +static int veth_remove(struct vio_dev *vdev) +{ + int i = vdev->unit_address; + struct net_device *dev; + + dev = veth_dev[i]; + if (dev != NULL) { + veth_dev[i] = NULL; + unregister_netdev(dev); + free_netdev(dev); + } + return 0; +} + +static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + int i = vdev->unit_address; + struct net_device *dev; + + dev = veth_probe_one(i, &vdev->dev); + if (dev == NULL) { + veth_remove(vdev); + return 1; + } + veth_dev[i] = dev; + + /* Start the state machine on each connection, to commence + * link negotiation */ + for (i = 0; i < HVMAXARCHITECTEDLPS; i++) + if (veth_cnx[i]) + veth_kick_statemachine(veth_cnx[i]); + + return 0; +} + +/** + * veth_device_table: Used by vio.c to match devices that we + * support. + */ +static struct vio_device_id veth_device_table[] __devinitdata = { + { "vlan", "" }, + { NULL, NULL } +}; +MODULE_DEVICE_TABLE(vio, veth_device_table); + +static struct vio_driver veth_driver = { + .name = "iseries_veth", + .id_table = veth_device_table, + .probe = veth_probe, + .remove = veth_remove +}; + /* * Module initialization/cleanup */ @@ -1335,27 +1391,17 @@ { int i; + vio_unregister_driver(&veth_driver); + for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) veth_destroy_connection(i); HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); - - for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; ++i) { - struct net_device *dev = veth_dev[i]; - - if (! dev) - continue; - - veth_dev[i] = NULL; - unregister_netdev(dev); - free_netdev(dev); - } } module_exit(veth_module_cleanup); int __init veth_module_init(void) { - HvLpIndexMap vlan_map = HvLpConfig_getVirtualLanIndexMap(); int i; int rc; @@ -1369,31 +1415,9 @@ } } - for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; ++i) { - struct net_device *dev; - - if (! (vlan_map & (0x8000 >> i))) - continue; - - dev = veth_probe_one(i); - - if (! dev) { - veth_module_cleanup(); - return rc; - } - - veth_dev[i] = dev; - } - HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan, &veth_handle_event); - /* Start the state machine on each connection, to commence - * link negotiation */ - for (i = 0; i < HVMAXARCHITECTEDLPS; i++) - if (veth_cnx[i]) - veth_kick_statemachine(veth_cnx[i]); - - return 0; + return vio_register_driver(&veth_driver); } module_init(veth_module_init); diff -ruN 2.6.7-bk9.base.sysvio.1/drivers/net/iseries_veth.h 2.6.7-bk9.base.sysvio.2/drivers/net/iseries_veth.h --- 2.6.7-bk9.base.sysvio.1/drivers/net/iseries_veth.h 2004-05-10 15:31:17.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.2/drivers/net/iseries_veth.h 2004-06-10 17:23:33.000000000 +1000 @@ -43,6 +43,4 @@ }; -#define HVMAXARCHITECTEDVIRTUALLANS (16) - #endif /* _ISERIES_VETH_H */ diff -ruN 2.6.7-bk9.base.sysvio.1/include/asm-ppc64/iSeries/HvTypes.h 2.6.7-bk9.base.sysvio.2/include/asm-ppc64/iSeries/HvTypes.h --- 2.6.7-bk9.base.sysvio.1/include/asm-ppc64/iSeries/HvTypes.h 2004-02-04 17:25:21.000000000 +1100 +++ 2.6.7-bk9.base.sysvio.2/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:23:21.000000000 +1000 @@ -65,6 +65,7 @@ #define HVMAXARCHITECTEDLPS 32 +#define HVMAXARCHITECTEDVIRTUALLANS 16 #define HVCHUNKSIZE 256 * 1024 #define HVPAGESIZE 4 * 1024 #define HVLPMINMEGSPRIMARY 256 [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] 3/5 PPC64 - viodasd integration 2004-06-28 16:35 ` [PATCH] 2/5 PPC64 - iseries_veth integration Stephen Rothwell @ 2004-06-28 16:38 ` Stephen Rothwell 2004-06-28 16:39 ` [PATCH] 4/5 PPC64 - viocd integration Stephen Rothwell 0 siblings, 1 reply; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:38 UTC (permalink / raw) To: Andrew Morton Cc: torvalds, linux-kernel, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 6054 bytes --] [Just realised I forgot the signed-off-by stuff] Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.6.7-bk9.base.sysvio.2/arch/ppc64/kernel/vio.c 2.6.7-bk9.base.sysvio.3/arch/ppc64/kernel/vio.c --- 2.6.7-bk9.base.sysvio.2/arch/ppc64/kernel/vio.c 2004-06-29 01:20:18.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.3/arch/ppc64/kernel/vio.c 2004-06-29 01:31:21.000000000 +1000 @@ -233,6 +233,8 @@ /* veth is special and has it own iommu_table */ viodev->iommu_table = &veth_iommu_table; } + for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) + vio_register_device_iseries("viodasd", i); } #endif diff -ruN 2.6.7-bk9.base.sysvio.2/drivers/block/viodasd.c 2.6.7-bk9.base.sysvio.3/drivers/block/viodasd.c --- 2.6.7-bk9.base.sysvio.2/drivers/block/viodasd.c 2004-06-27 20:30:00.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.3/drivers/block/viodasd.c 2004-06-27 20:33:23.000000000 +1000 @@ -68,7 +68,7 @@ enum { PARTITION_SHIFT = 3, - MAX_DISKNO = 32, + MAX_DISKNO = HVMAXARCHITECTEDVIRTUALDISKS, MAX_DISK_NAME = sizeof(((struct gendisk *)0)->disk_name) }; @@ -168,6 +168,7 @@ int read_only; spinlock_t q_lock; struct gendisk *disk; + struct device *dev; } viodasd_devices[MAX_DISKNO]; /* @@ -342,7 +343,7 @@ /* Now build the scatter-gather list */ nsg = blk_rq_map_sg(req->q, req, sg); - nsg = dma_map_sg(iSeries_vio_dev, sg, nsg, direction); + nsg = dma_map_sg(d->dev, sg, nsg, direction); spin_lock_irqsave(&viodasd_spinlock, flags); num_req_outstanding++; @@ -422,7 +423,7 @@ error_ret: num_req_outstanding--; spin_unlock_irqrestore(&viodasd_spinlock, flags); - dma_unmap_sg(iSeries_vio_dev, sg, nsg, direction); + dma_unmap_sg(d->dev, sg, nsg, direction); return -1; } @@ -557,6 +558,7 @@ g->fops = &viodasd_fops; g->queue = q; g->private_data = d; + g->driverfs_dev = d->dev; set_capacity(g, d->size >> 9); printk(VIOD_KERN_INFO "disk %d: %lu sectors (%lu MB) " @@ -623,7 +625,7 @@ struct scatterlist sg[VIOMAXBLOCKDMA]; struct HvLpEvent *event = &bevent->event; unsigned long irq_flags; - int device_no; + struct viodasd_device *d; int error; spinlock_t *qlock; @@ -633,7 +635,10 @@ pci_direction = DMA_FROM_DEVICE; else pci_direction = DMA_TO_DEVICE; - dma_unmap_sg(iSeries_vio_dev, sg, num_sg, pci_direction); + req = (struct request *)bevent->event.xCorrelationToken; + d = req->rq_disk->private_data; + + dma_unmap_sg(d->dev, sg, num_sg, pci_direction); /* * Since this is running in interrupt mode, we need to make sure @@ -643,9 +648,6 @@ num_req_outstanding--; spin_unlock_irqrestore(&viodasd_spinlock, irq_flags); - req = (struct request *)bevent->event.xCorrelationToken; - device_no = DEVICE_NO(req->rq_disk->private_data); - error = event->xRc != HvLpEvent_Rc_Good; if (error) { const struct vio_error_entry *err; @@ -660,7 +662,7 @@ spin_unlock_irqrestore(qlock, irq_flags); /* Finally, try to get more requests off of this device's queue */ - viodasd_restart_all_queues_starting_from(device_no); + viodasd_restart_all_queues_starting_from(DEVICE_NO(d)); return 0; } @@ -744,8 +746,47 @@ } static DRIVER_ATTR(probe, S_IWUSR, NULL, probe_disks); +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) + return -ENODEV; + return 0; +} + +static int viodasd_remove(struct vio_dev *vdev) +{ + struct viodasd_device *d; + + d = &viodasd_devices[vdev->unit_address]; + if (d->disk) { + del_gendisk(d->disk); + put_disk(d->disk); + blk_cleanup_queue(d->disk->queue); + d->disk = NULL; + } + d->dev = NULL; + return 0; +} + +/** + * viodasd_device_table: Used by vio.c to match devices that we + * support. + */ +static struct vio_device_id viodasd_device_table[] __devinitdata = { + { "viodasd", "" }, + { 0, } +}; + +MODULE_DEVICE_TABLE(vio, viodasd_device_table); static struct vio_driver viodasd_driver = { - .name = "viodasd" + .name = "viodasd", + .id_table = viodasd_device_table, + .probe = viodasd_probe, + .remove = viodasd_remove }; /* @@ -754,7 +795,7 @@ */ static int __init viodasd_init(void) { - int i; + int rc; /* Try to open to our host lp */ if (viopath_hostLp == HvLpIndexInvalid) @@ -788,33 +829,17 @@ /* Initialize our request handler */ vio_setHandler(viomajorsubtype_blockio, handle_block_event); - for (i = 0; i < MAX_DISKNO; i++) - probe_disk(&viodasd_devices[i]); - - vio_register_driver(&viodasd_driver); /* FIX ME - error checking */ - driver_create_file(&viodasd_driver.driver, &driver_attr_probe); - - return 0; + rc = vio_register_driver(&viodasd_driver); + if (rc == 0) + driver_create_file(&viodasd_driver.driver, &driver_attr_probe); + return rc; } module_init(viodasd_init); void viodasd_exit(void) { - int i; - struct viodasd_device *d; - driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); vio_unregister_driver(&viodasd_driver); - - for (i = 0; i < MAX_DISKNO; i++) { - d = &viodasd_devices[i]; - if (d->disk) { - del_gendisk(d->disk); - put_disk(d->disk); - blk_cleanup_queue(d->disk->queue); - d->disk = NULL; - } - } vio_clearHandler(viomajorsubtype_blockio); unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); diff -ruN 2.6.7-bk9.base.sysvio.2/include/asm-ppc64/iSeries/HvTypes.h 2.6.7-bk9.base.sysvio.3/include/asm-ppc64/iSeries/HvTypes.h --- 2.6.7-bk9.base.sysvio.2/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:23:21.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.3/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:39:53.000000000 +1000 @@ -66,6 +66,7 @@ #define HVMAXARCHITECTEDLPS 32 #define HVMAXARCHITECTEDVIRTUALLANS 16 +#define HVMAXARCHITECTEDVIRTUALDISKS 32 #define HVCHUNKSIZE 256 * 1024 #define HVPAGESIZE 4 * 1024 #define HVLPMINMEGSPRIMARY 256 [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] 4/5 PPC64 - viocd integration 2004-06-28 16:38 ` [PATCH] 3/5 PPC64 - viodasd integration Stephen Rothwell @ 2004-06-28 16:39 ` Stephen Rothwell 2004-06-28 16:41 ` [PATCH] 5/5 PPC64 - viotape integration Stephen Rothwell 0 siblings, 1 reply; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:39 UTC (permalink / raw) To: Andrew Morton Cc: torvalds, linux-kernel, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 9133 bytes --] Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.6.7-bk9.base.sysvio.3/arch/ppc64/kernel/vio.c 2.6.7-bk9.base.sysvio.4/arch/ppc64/kernel/vio.c --- 2.6.7-bk9.base.sysvio.3/arch/ppc64/kernel/vio.c 2004-06-29 01:31:21.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.4/arch/ppc64/kernel/vio.c 2004-06-29 01:48:10.000000000 +1000 @@ -235,6 +235,8 @@ } for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) vio_register_device_iseries("viodasd", i); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) + vio_register_device_iseries("viocd", i); } #endif diff -ruN 2.6.7-bk9.base.sysvio.3/drivers/cdrom/viocd.c 2.6.7-bk9.base.sysvio.4/drivers/cdrom/viocd.c --- 2.6.7-bk9.base.sysvio.3/drivers/cdrom/viocd.c 2004-05-10 15:31:08.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.4/drivers/cdrom/viocd.c 2004-06-20 00:11:22.000000000 +1000 @@ -44,6 +44,7 @@ #include <asm/bug.h> +#include <asm/vio.h> #include <asm/scatterlist.h> #include <asm/iSeries/HvTypes.h> #include <asm/iSeries/HvLpEvent.h> @@ -84,7 +85,7 @@ /* * Should probably make this a module parameter....sigh */ -#define VIOCD_MAX_CD 8 +#define VIOCD_MAX_CD HVMAXARCHITECTEDVIRTUALCDROMS static const struct vio_error_entry viocd_err_table[] = { {0x0201, EINVAL, "Invalid Range"}, @@ -144,6 +145,7 @@ struct disk_info { struct gendisk *viocd_disk; struct cdrom_device_info viocd_info; + struct device *dev; }; static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; @@ -260,13 +262,13 @@ for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) viocd_numdev++; - return; - error_ret: - dma_free_coherent(iSeries_vio_dev, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - viocd_unitinfo, unitinfo_dmaaddr); - viocd_unitinfo = NULL; + if (viocd_numdev == 0) { + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); + viocd_unitinfo = NULL; + } } static int viocd_open(struct cdrom_device_info *cdi, int purpose) @@ -341,7 +343,7 @@ return -1; } - if (dma_map_sg(iSeries_vio_dev, &sg, 1, DMA_FROM_DEVICE) == 0) { + if (dma_map_sg(diskinfo->dev, &sg, 1, DMA_FROM_DEVICE) == 0) { printk(VIOCD_KERN_WARNING "error allocating sg tce\n"); return -1; } @@ -513,8 +515,9 @@ * Since this is running in interrupt mode, we need to * make sure we're not stepping on any global I/O operations */ + di = &viocd_diskinfo[bevent->disk]; spin_lock_irqsave(&viocd_reqlock, flags); - dma_unmap_single(iSeries_vio_dev, bevent->token, bevent->len, + dma_unmap_single(di->dev, bevent->token, bevent->len, DMA_FROM_DEVICE); req = (struct request *)bevent->event.xCorrelationToken; rwreq--; @@ -565,12 +568,97 @@ return entry->capability; } -static int __init viocd_init(void) +static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) { struct gendisk *gendisk; int deviceno; - int ret = 0; + struct disk_info *d; + struct cdrom_device_info *c; + struct cdrom_info *ci; + + deviceno = vdev->unit_address; + if (deviceno >= viocd_numdev) + return -ENODEV; + + d = &viocd_diskinfo[deviceno]; + c = &d->viocd_info; + ci = &viocd_unitinfo[deviceno]; + + c->ops = &viocd_dops; + c->speed = 4; + c->capacity = 1; + c->handle = d; + c->mask = ~find_capability(ci->type); + sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); + + if (register_cdrom(c) != 0) { + printk(VIOCD_KERN_WARNING "Cannot register viocd CD-ROM %s!\n", + c->name); + return 0; + } + 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); + gendisk = alloc_disk(1); + if (gendisk == NULL) { + printk(VIOCD_KERN_WARNING "Cannot create gendisk for %s!\n", + c->name); + unregister_cdrom(c); + return 0; + } + gendisk->major = VIOCD_MAJOR; + gendisk->first_minor = deviceno; + strncpy(gendisk->disk_name, c->name, + sizeof(gendisk->disk_name)); + snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name), + VIOCD_DEVICE_DEVFS "%d", deviceno); + gendisk->queue = viocd_queue; + gendisk->fops = &viocd_fops; + gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; + set_capacity(gendisk, 0); + gendisk->private_data = d; + d->viocd_disk = gendisk; + d->dev = &vdev->dev; + gendisk->driverfs_dev = d->dev; + add_disk(gendisk); + + return 0; +} + +static int viocd_remove(struct vio_dev *vdev) +{ + struct disk_info *d = &viocd_diskinfo[vdev->unit_address]; + + if (unregister_cdrom(&d->viocd_info) != 0) + printk(VIOCD_KERN_WARNING + "Cannot unregister viocd CD-ROM %s!\n", + d->viocd_info.name); + del_gendisk(d->viocd_disk); + put_disk(d->viocd_disk); + return 0; +} + +/** + * viocd_device_table: Used by vio.c to match devices that we + * support. + */ +static struct vio_device_id viocd_device_table[] __devinitdata = { + { "viocd", "" }, + { 0, } +}; + +MODULE_DEVICE_TABLE(vio, viocd_device_table); +static struct vio_driver viocd_driver = { + .name = "viocd", + .id_table = viocd_device_table, + .probe = viocd_probe, + .remove = viocd_remove +}; + +static int __init viocd_init(void) +{ struct proc_dir_entry *e; + int ret = 0; if (viopath_hostLp == HvLpIndexInvalid) { vio_set_hostlp(); @@ -583,8 +671,7 @@ viopath_hostLp); if (register_blkdev(VIOCD_MAJOR, VIOCD_DEVICE) != 0) { - printk(VIOCD_KERN_WARNING - "Unable to get major %d for %s\n", + printk(VIOCD_KERN_WARNING "Unable to get major %d for %s\n", VIOCD_MAJOR, VIOCD_DEVICE); return -EIO; } @@ -605,59 +692,19 @@ if (viocd_numdev == 0) goto out_undo_vio; - ret = -ENOMEM; spin_lock_init(&viocd_reqlock); viocd_queue = blk_init_queue(do_viocd_request, &viocd_reqlock); - if (viocd_queue == NULL) - goto out_unregister; + if (viocd_queue == NULL) { + ret = -ENOMEM; + goto out_free_info; + } blk_queue_max_hw_segments(viocd_queue, 1); blk_queue_max_phys_segments(viocd_queue, 1); blk_queue_max_sectors(viocd_queue, 4096 / 512); - /* initialize units */ - for (deviceno = 0; deviceno < viocd_numdev; deviceno++) { - struct disk_info *d = &viocd_diskinfo[deviceno]; - struct cdrom_device_info *c = &d->viocd_info; - struct cdrom_info *ci = &viocd_unitinfo[deviceno]; - - c->ops = &viocd_dops; - c->speed = 4; - c->capacity = 1; - c->handle = d; - c->mask = ~find_capability(ci->type); - sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); - - if (register_cdrom(c) != 0) { - printk(VIOCD_KERN_WARNING - "Cannot register viocd CD-ROM %s!\n", - c->name); - continue; - } - 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); - gendisk = alloc_disk(1); - if (gendisk == NULL) { - printk(VIOCD_KERN_WARNING - "Cannot create gendisk for %s!\n", - c->name); - unregister_cdrom(c); - continue; - } - gendisk->major = VIOCD_MAJOR; - gendisk->first_minor = deviceno; - strncpy(gendisk->disk_name, c->name, - sizeof(gendisk->disk_name)); - snprintf(gendisk->devfs_name, sizeof(gendisk->devfs_name), - VIOCD_DEVICE_DEVFS "%d", deviceno); - gendisk->queue = viocd_queue; - gendisk->fops = &viocd_fops; - gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE; - set_capacity(gendisk, 0); - gendisk->private_data = d; - d->viocd_disk = gendisk; - add_disk(gendisk); - } + ret = vio_register_driver(&viocd_driver); + if (ret) + goto out_cleanup_queue; e = create_proc_entry("iSeries/viocd", S_IFREG|S_IRUGO, NULL); if (e) { @@ -667,6 +714,12 @@ return 0; +out_cleanup_queue: + blk_cleanup_queue(viocd_queue); +out_free_info: + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); out_undo_vio: vio_clearHandler(viomajorsubtype_cdio); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); @@ -677,18 +730,8 @@ static void __exit viocd_exit(void) { - int deviceno; - remove_proc_entry("iSeries/viocd", NULL); - for (deviceno = 0; deviceno < viocd_numdev; deviceno++) { - struct disk_info *d = &viocd_diskinfo[deviceno]; - if (unregister_cdrom(&d->viocd_info) != 0) - printk(VIOCD_KERN_WARNING - "Cannot unregister viocd CD-ROM %s!\n", - d->viocd_info.name); - del_gendisk(d->viocd_disk); - put_disk(d->viocd_disk); - } + vio_unregister_driver(&viocd_driver); blk_cleanup_queue(viocd_queue); if (viocd_unitinfo != NULL) dma_free_coherent(iSeries_vio_dev, diff -ruN 2.6.7-bk9.base.sysvio.3/include/asm-ppc64/iSeries/HvTypes.h 2.6.7-bk9.base.sysvio.4/include/asm-ppc64/iSeries/HvTypes.h --- 2.6.7-bk9.base.sysvio.3/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:39:53.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.4/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:49:33.000000000 +1000 @@ -67,6 +67,7 @@ #define HVMAXARCHITECTEDLPS 32 #define HVMAXARCHITECTEDVIRTUALLANS 16 #define HVMAXARCHITECTEDVIRTUALDISKS 32 +#define HVMAXARCHITECTEDVIRTUALCDROMS 8 #define HVCHUNKSIZE 256 * 1024 #define HVPAGESIZE 4 * 1024 #define HVLPMINMEGSPRIMARY 256 [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH] 5/5 PPC64 - viotape integration 2004-06-28 16:39 ` [PATCH] 4/5 PPC64 - viocd integration Stephen Rothwell @ 2004-06-28 16:41 ` Stephen Rothwell 0 siblings, 0 replies; 6+ messages in thread From: Stephen Rothwell @ 2004-06-28 16:41 UTC (permalink / raw) To: Andrew Morton Cc: torvalds, linux-kernel, boutcher, katzj, ipseries-list, linuxppc64-dev [-- Attachment #1: Type: text/plain, Size: 7266 bytes --] Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ diff -ruN 2.6.7-bk9.base.sysvio.4/arch/ppc64/kernel/vio.c 2.6.7-bk9.base.sysvio.5/arch/ppc64/kernel/vio.c --- 2.6.7-bk9.base.sysvio.4/arch/ppc64/kernel/vio.c 2004-06-29 01:48:10.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.5/arch/ppc64/kernel/vio.c 2004-06-29 01:56:56.000000000 +1000 @@ -237,6 +237,8 @@ vio_register_device_iseries("viodasd", i); for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) vio_register_device_iseries("viocd", i); + for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) + vio_register_device_iseries("viotape", i); } #endif diff -ruN 2.6.7-bk9.base.sysvio.4/drivers/char/viotape.c 2.6.7-bk9.base.sysvio.5/drivers/char/viotape.c --- 2.6.7-bk9.base.sysvio.4/drivers/char/viotape.c 2004-05-10 15:31:09.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.5/drivers/char/viotape.c 2004-06-20 01:17:34.000000000 +1000 @@ -53,6 +53,7 @@ #include <asm/uaccess.h> #include <asm/ioctls.h> +#include <asm/vio.h> #include <asm/iSeries/vio.h> #include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvCallEvent.h> @@ -216,7 +217,7 @@ }; /* Maximum number of tapes we support */ -#define VIOTAPE_MAX_TAPE 8 +#define VIOTAPE_MAX_TAPE HVMAXARCHITECTEDVIRTUALTAPES #define MAX_PARTITIONS 4 /* defines for current tape state */ @@ -238,6 +239,8 @@ static struct class_simple *tape_class; +static struct device *tape_device[VIOTAPE_MAX_TAPE]; + /* * maintain the current state of each tape (and partition) * so that we know when to write EOF marks. @@ -262,6 +265,7 @@ int rc; int non_blocking; struct completion com; + struct device *dev; struct op_struct *next; }; @@ -459,7 +463,8 @@ down(&reqSem); /* Allocate a DMA buffer */ - op->buffer = dma_alloc_coherent(iSeries_vio_dev, count, &op->dmaaddr, + op->dev = tape_device[devi.devno]; + op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr, GFP_ATOMIC); if (op->buffer == NULL) { @@ -509,7 +514,7 @@ } free_dma: - dma_free_coherent(iSeries_vio_dev, count, op->buffer, op->dmaaddr); + dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr); up_sem: up(&reqSem); free_op: @@ -550,7 +555,8 @@ chg_state(devi.devno, VIOT_READING, file); /* Allocate a DMA buffer */ - op->buffer = dma_alloc_coherent(iSeries_vio_dev, count, &op->dmaaddr, + op->dev = tape_device[devi.devno]; + op->buffer = dma_alloc_coherent(op->dev, count, &op->dmaaddr, GFP_ATOMIC); if (op->buffer == NULL) { ret = -EFAULT; @@ -588,7 +594,7 @@ } free_dma: - dma_free_coherent(iSeries_vio_dev, count, op->buffer, op->dmaaddr); + dma_free_coherent(op->dev, count, op->buffer, op->dmaaddr); up_sem: up(&reqSem); free_op: @@ -910,7 +916,7 @@ break; case viotapewrite: if (op->non_blocking) { - dma_free_coherent(iSeries_vio_dev, op->count, + dma_free_coherent(op->dev, op->count, op->buffer, op->dmaaddr); free_op_struct(op); up(&reqSem); @@ -936,12 +942,70 @@ } } +static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) +{ + char tapename[32]; + int i = vdev->unit_address; + int j; + + if (i >= viotape_numdev) + return -ENODEV; + + tape_device[i] = &vdev->dev; + + state[i].cur_part = 0; + for (j = 0; j < MAX_PARTITIONS; ++j) + state[i].part_stat_rwi[j] = VIOT_IDLE; + class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL, + "iseries!vt%d", i); + class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80), + NULL, "iseries!nvt%d", i); + devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, + "iseries/vt%d", i); + devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80), + S_IFCHR | S_IRUSR | S_IWUSR, "iseries/nvt%d", i); + sprintf(tapename, "iseries/vt%d", i); + state[i].dev_handle = devfs_register_tape(tapename); + printk(VIOTAPE_KERN_INFO "tape %s is iSeries " + "resource %10.10s type %4.4s, model %3.3s\n", + tapename, viotape_unitinfo[i].rsrcname, + viotape_unitinfo[i].type, viotape_unitinfo[i].model); + return 0; +} + +static int viotape_remove(struct vio_dev *vdev) +{ + int i = vdev->unit_address; + + devfs_remove("iseries/nvt%d", i); + devfs_remove("iseries/vt%d", i); + devfs_unregister_tape(state[i].dev_handle); + class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80)); + class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i)); + return 0; +} + +/** + * viotape_device_table: Used by vio.c to match devices that we + * support. + */ +static struct vio_device_id viotape_device_table[] __devinitdata = { + { "viotape", "" }, + { 0, } +}; + +MODULE_DEVICE_TABLE(vio, viotape_device_table); +static struct vio_driver viotape_driver = { + .name = "viotape", + .id_table = viotape_device_table, + .probe = viotape_probe, + .remove = viotape_remove +}; + int __init viotap_init(void) { int ret; - char tapename[32]; - int i; struct proc_dir_entry *e; op_struct_list = NULL; @@ -993,31 +1057,9 @@ goto unreg_class; } - for (i = 0; i < viotape_numdev; i++) { - int j; - - state[i].cur_part = 0; - for (j = 0; j < MAX_PARTITIONS; ++j) - state[i].part_stat_rwi[j] = VIOT_IDLE; - class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), - NULL, "iseries!vt%d", i); - class_simple_device_add(tape_class, - MKDEV(VIOTAPE_MAJOR, i | 0x80), - NULL, "iseries!nvt%d", i); - devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), - S_IFCHR | S_IRUSR | S_IWUSR, - "iseries/vt%d", i); - devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i | 0x80), - S_IFCHR | S_IRUSR | S_IWUSR, - "iseries/nvt%d", i); - sprintf(tapename, "iseries/vt%d", i); - state[i].dev_handle = devfs_register_tape(tapename); - printk(VIOTAPE_KERN_INFO "tape %s is iSeries " - "resource %10.10s type %4.4s, model %3.3s\n", - tapename, viotape_unitinfo[i].rsrcname, - viotape_unitinfo[i].type, - viotape_unitinfo[i].model); - } + ret = vio_register_driver(&viotape_driver); + if (ret) + goto unreg_class; e = create_proc_entry("iSeries/viotape", S_IFREG|S_IRUGO, NULL); if (e) { @@ -1064,17 +1106,10 @@ /* Cleanup */ static void __exit viotap_exit(void) { - int i, ret; + int ret; remove_proc_entry("iSeries/viotape", NULL); - - for (i = 0; i < viotape_numdev; ++i) { - devfs_remove("iseries/nvt%d", i); - devfs_remove("iseries/vt%d", i); - devfs_unregister_tape(state[i].dev_handle); - class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80)); - class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i)); - } + vio_unregister_driver(&viotape_driver); class_simple_destroy(tape_class); ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape"); if (ret < 0) diff -ruN 2.6.7-bk9.base.sysvio.4/include/asm-ppc64/iSeries/HvTypes.h 2.6.7-bk9.base.sysvio.5/include/asm-ppc64/iSeries/HvTypes.h --- 2.6.7-bk9.base.sysvio.4/include/asm-ppc64/iSeries/HvTypes.h 2004-06-29 01:49:33.000000000 +1000 +++ 2.6.7-bk9.base.sysvio.5/include/asm-ppc64/iSeries/HvTypes.h 2004-06-19 17:59:21.000000000 +1000 @@ -68,6 +68,7 @@ #define HVMAXARCHITECTEDVIRTUALLANS 16 #define HVMAXARCHITECTEDVIRTUALDISKS 32 #define HVMAXARCHITECTEDVIRTUALCDROMS 8 +#define HVMAXARCHITECTEDVIRTUALTAPES 8 #define HVCHUNKSIZE 256 * 1024 #define HVPAGESIZE 4 * 1024 #define HVLPMINMEGSPRIMARY 256 [-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-06-28 16:42 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-06-28 16:28 [PATCH] 0/5 PPC64 - make iSeries virtual devices/drivers appear in sysfs Stephen Rothwell 2004-06-28 16:33 ` [PATCH] 1/5 PPC64 - vio infrastructure modifications Stephen Rothwell 2004-06-28 16:35 ` [PATCH] 2/5 PPC64 - iseries_veth integration Stephen Rothwell 2004-06-28 16:38 ` [PATCH] 3/5 PPC64 - viodasd integration Stephen Rothwell 2004-06-28 16:39 ` [PATCH] 4/5 PPC64 - viocd integration Stephen Rothwell 2004-06-28 16:41 ` [PATCH] 5/5 PPC64 - viotape integration Stephen Rothwell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®