aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/viotape.c
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2007-10-11 00:58:31 -0400
committerPaul Mackerras <paulus@samba.org>2007-10-11 06:40:47 -0400
commit7465ce0db310d2fa29f721da7e3aacd1dad7090f (patch)
treece8cd473877948310b2e86f685ab09686b79ea23 /drivers/char/viotape.c
parentb833b481c10cf591b15cc674948cc514e55d3b94 (diff)
[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/viotape.c')
-rw-r--r--drivers/char/viotape.c124
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 {
92#define VIOTAPOP_SETPART 14 92#define VIOTAPOP_SETPART 14
93#define VIOTAPOP_UNLOAD 15 93#define VIOTAPOP_UNLOAD 15
94 94
95struct viotapelpevent {
96 struct HvLpEvent event;
97 u32 reserved;
98 u16 version;
99 u16 sub_type_result;
100 u16 tape;
101 u16 flags;
102 u32 token;
103 u64 len;
104 union {
105 struct {
106 u32 tape_op;
107 u32 count;
108 } op;
109 struct {
110 u32 type;
111 u32 resid;
112 u32 dsreg;
113 u32 gstat;
114 u32 erreg;
115 u32 file_no;
116 u32 block_no;
117 } get_status;
118 struct {
119 u32 block_no;
120 } get_pos;
121 } u;
122};
123
124enum viotapesubtype {
125 viotapeopen = 0x0001,
126 viotapeclose = 0x0002,
127 viotaperead = 0x0003,
128 viotapewrite = 0x0004,
129 viotapegetinfo = 0x0005,
130 viotapeop = 0x0006,
131 viotapegetpos = 0x0007,
132 viotapesetpos = 0x0008,
133 viotapegetstatus = 0x0009
134};
135
136enum viotaperc { 95enum viotaperc {
137 viotape_InvalidRange = 0x0601, 96 viotape_InvalidRange = 0x0601,
138 viotape_InvalidToken = 0x0602, 97 viotape_InvalidToken = 0x0602,
@@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = {
223#define VIOT_WRITING 2 182#define VIOT_WRITING 2
224 183
225/* Our info on the tapes */ 184/* Our info on the tapes */
226struct tape_descr { 185static struct {
227 char rsrcname[10]; 186 const char *rsrcname;
228 char type[4]; 187 const char *type;
229 char model[3]; 188 const char *model;
230}; 189} viotape_unitinfo[VIOTAPE_MAX_TAPE];
231
232static struct tape_descr *viotape_unitinfo;
233static dma_addr_t viotape_unitinfo_token;
234 190
235static struct mtget viomtget[VIOTAPE_MAX_TAPE]; 191static struct mtget viomtget[VIOTAPE_MAX_TAPE];
236 192
@@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno)
381 return -err->errno; 337 return -err->errno;
382} 338}
383 339
384/* Get info on all tapes from OS/400 */
385static int get_viotape_info(void)
386{
387 HvLpEvent_Rc hvrc;
388 int i;
389 size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE;
390 struct op_struct *op = get_op_struct();
391
392 if (op == NULL)
393 return -ENOMEM;
394
395 viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token,
396 GFP_ATOMIC);
397 if (viotape_unitinfo == NULL) {
398 free_op_struct(op);
399 return -ENOMEM;
400 }
401
402 memset(viotape_unitinfo, 0, len);
403
404 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
405 HvLpEvent_Type_VirtualIo,
406 viomajorsubtype_tape | viotapegetinfo,
407 HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
408 viopath_sourceinst(viopath_hostLp),
409 viopath_targetinst(viopath_hostLp),
410 (u64) (unsigned long) op, VIOVERSION << 16,
411 viotape_unitinfo_token, len, 0, 0);
412 if (hvrc != HvLpEvent_Rc_Good) {
413 printk(VIOTAPE_KERN_WARN "hv error on op %d\n",
414 (int)hvrc);
415 free_op_struct(op);
416 return -EIO;
417 }
418
419 wait_for_completion(&op->com);
420
421 free_op_struct(op);
422
423 for (i = 0;
424 ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
425 i++)
426 viotape_numdev++;
427 return 0;
428}
429
430
431/* Write */ 340/* Write */
432static ssize_t viotap_write(struct file *file, const char *buf, 341static ssize_t viotap_write(struct file *file, const char *buf,
433 size_t count, loff_t * ppos) 342 size_t count, loff_t * ppos)
@@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event)
899 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; 808 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
900 op = (struct op_struct *)event->xCorrelationToken; 809 op = (struct op_struct *)event->xCorrelationToken;
901 switch (tapeminor) { 810 switch (tapeminor) {
902 case viotapegetinfo:
903 case viotapeopen: 811 case viotapeopen:
904 case viotapeclose: 812 case viotapeclose:
905 op->rc = tevent->sub_type_result; 813 op->rc = tevent->sub_type_result;
@@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
942{ 850{
943 int i = vdev->unit_address; 851 int i = vdev->unit_address;
944 int j; 852 int j;
853 struct device_node *node = vdev->dev.archdata.of_node;
945 854
946 if (i >= viotape_numdev) 855 if (i > VIOTAPE_MAX_TAPE)
856 return -ENODEV;
857 if (!node)
947 return -ENODEV; 858 return -ENODEV;
948 859
860 if (i >= viotape_numdev)
861 viotape_numdev = i + 1;
862
949 tape_device[i] = &vdev->dev; 863 tape_device[i] = &vdev->dev;
864 viotape_unitinfo[i].rsrcname = of_get_property(node,
865 "linux,vio_rsrcname", NULL);
866 viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type",
867 NULL);
868 viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model",
869 NULL);
950 870
951 state[i].cur_part = 0; 871 state[i].cur_part = 0;
952 for (j = 0; j < MAX_PARTITIONS; ++j) 872 for (j = 0; j < MAX_PARTITIONS; ++j)
@@ -1044,11 +964,6 @@ int __init viotap_init(void)
1044 goto unreg_chrdev; 964 goto unreg_chrdev;
1045 } 965 }
1046 966
1047 if ((ret = get_viotape_info()) < 0) {
1048 printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information");
1049 goto unreg_class;
1050 }
1051
1052 ret = vio_register_driver(&viotape_driver); 967 ret = vio_register_driver(&viotape_driver);
1053 if (ret) 968 if (ret)
1054 goto unreg_class; 969 goto unreg_class;
@@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void)
1102 vio_unregister_driver(&viotape_driver); 1017 vio_unregister_driver(&viotape_driver);
1103 class_destroy(tape_class); 1018 class_destroy(tape_class);
1104 unregister_chrdev(VIOTAPE_MAJOR, "viotape"); 1019 unregister_chrdev(VIOTAPE_MAJOR, "viotape");
1105 if (viotape_unitinfo)
1106 iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE,
1107 viotape_unitinfo, viotape_unitinfo_token);
1108 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); 1020 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1109 vio_clearHandler(viomajorsubtype_tape); 1021 vio_clearHandler(viomajorsubtype_tape);
1110 clear_op_struct_pool(); 1022 clear_op_struct_pool();