diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2007-10-11 14:58:31 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-10-11 20:40:47 +1000 |
commit | 7465ce0db310d2fa29f721da7e3aacd1dad7090f (patch) | |
tree | ce8cd473877948310b2e86f685ab09686b79ea23 /drivers/char | |
parent | b833b481c10cf591b15cc674948cc514e55d3b94 (diff) | |
download | linux-7465ce0db310d2fa29f721da7e3aacd1dad7090f.tar.bz2 |
[POWERPC] iSeries: Move detection of virtual tapes
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>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/viotape.c | 124 |
1 files changed, 18 insertions, 106 deletions
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 064c09195215..f1d60f0cef8f 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(); |