1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * character device frontend for tape device driver
4 *
5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001, 2006
7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
10 * Martin Schwidefsky <schwidefsky@de.ibm.com>
11 */
12
13 #define pr_fmt(fmt) "tape: " fmt
14
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/proc_fs.h>
18 #include <linux/mtio.h>
19
20 #include <linux/uaccess.h>
21
22 #define TAPE_DBF_AREA tape_core_dbf
23
24 #include "tape.h"
25 #include "tape_std.h"
26 #include "tape_class.h"
27
28 #define TAPECHAR_MAJOR 0 /* get dynamic major */
29
30 /*
31 * file operation structure for tape character frontend
32 */
33 static ssize_t tapechar_read(struct file *, char __user *, size_t, loff_t *);
34 static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *);
35 static int tapechar_open(struct inode *,struct file *);
36 static int tapechar_release(struct inode *,struct file *);
37 static long tapechar_ioctl(struct file *, unsigned int, unsigned long);
38
39 static const struct file_operations tape_fops =
40 {
41 .owner = THIS_MODULE,
42 .read = tapechar_read,
43 .write = tapechar_write,
44 .unlocked_ioctl = tapechar_ioctl,
45 .open = tapechar_open,
46 .release = tapechar_release,
47 };
48
49 static int tapechar_major = TAPECHAR_MAJOR;
50
51 /*
52 * This function is called for every new tapedevice
53 */
54 int
tapechar_setup_device(struct tape_device * device)55 tapechar_setup_device(struct tape_device * device)
56 {
57 char device_name[20];
58
59 scnprintf(device_name, sizeof(device_name), "ntibm%i", device->first_minor / 2);
60 device->nt = register_tape_dev(
61 &device->cdev->dev,
62 MKDEV(tapechar_major, device->first_minor),
63 &tape_fops,
64 device_name,
65 "non-rewinding"
66 );
67 device_name[0] = 'r';
68 device->rt = register_tape_dev(
69 &device->cdev->dev,
70 MKDEV(tapechar_major, device->first_minor + 1),
71 &tape_fops,
72 device_name,
73 "rewinding"
74 );
75
76 return 0;
77 }
78
79 void
tapechar_cleanup_device(struct tape_device * device)80 tapechar_cleanup_device(struct tape_device *device)
81 {
82 unregister_tape_dev(&device->cdev->dev, device->rt);
83 device->rt = NULL;
84 unregister_tape_dev(&device->cdev->dev, device->nt);
85 device->nt = NULL;
86 }
87
88
89 /*
90 * Tape device read function
91 */
92 static ssize_t
tapechar_read(struct file * filp,char __user * data,size_t count,loff_t * ppos)93 tapechar_read(struct file *filp, char __user *data, size_t count, loff_t *ppos)
94 {
95 struct tape_request *request;
96 struct ccw1 *ccw, *last_ccw;
97 struct tape_device *device;
98 struct idal_buffer **ibs;
99 size_t block_size;
100 size_t read = 0;
101 int rc;
102
103 DBF_EVENT(6, "TCHAR:read\n");
104 device = (struct tape_device *) filp->private_data;
105
106 /*
107 * If the tape isn't terminated yet, do it now. And since we then
108 * are at the end of the tape there wouldn't be anything to read
109 * anyways. So we return immediately.
110 */
111 if(device->required_tapemarks) {
112 return tape_std_terminate_write(device);
113 }
114
115 /* Find out block size to use */
116 if (device->char_data.block_size != 0) {
117 if (count < device->char_data.block_size) {
118 DBF_EVENT(3, "TCHAR:read smaller than block "
119 "size was requested\n");
120 return -EINVAL;
121 }
122 block_size = device->char_data.block_size;
123 } else {
124 block_size = count;
125 }
126
127 rc = tape_check_idalbuffer(device, block_size);
128 if (rc)
129 return rc;
130
131 DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size);
132 /* Let the discipline build the ccw chain. */
133 request = device->discipline->read_block(device);
134 if (IS_ERR(request))
135 return PTR_ERR(request);
136 /* Execute it. */
137 rc = tape_do_io(device, request);
138 if (rc == 0) {
139 DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc);
140 /* Channel Program Address (cpa) points to last CCW + 8 */
141 last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa);
142 ccw = request->cpaddr;
143 ibs = device->char_data.ibs;
144 while (++ccw < last_ccw) {
145 /* Copy data from idal buffer to user space. */
146 if (idal_buffer_to_user(*ibs++, data, ccw->count) != 0) {
147 rc = -EFAULT;
148 break;
149 }
150 read += ccw->count;
151 data += ccw->count;
152 }
153 if (&last_ccw[-1] == &request->cpaddr[1] &&
154 request->rescnt == last_ccw[-1].count)
155 rc = 0;
156 else
157 rc = read - request->rescnt;
158 }
159 tape_free_request(request);
160 return rc;
161 }
162
163 /*
164 * Tape device write function
165 */
166 static ssize_t
tapechar_write(struct file * filp,const char __user * data,size_t count,loff_t * ppos)167 tapechar_write(struct file *filp, const char __user *data, size_t count, loff_t *ppos)
168 {
169 struct tape_request *request;
170 struct ccw1 *ccw, *last_ccw;
171 struct tape_device *device;
172 struct idal_buffer **ibs;
173 size_t written = 0;
174 size_t block_size;
175 int nblocks;
176 int i, rc;
177
178 DBF_EVENT(6, "TCHAR:write\n");
179 device = (struct tape_device *) filp->private_data;
180 /* Find out block size and number of blocks */
181 if (device->char_data.block_size != 0) {
182 if (count < device->char_data.block_size) {
183 DBF_EVENT(3, "TCHAR:write smaller than block "
184 "size was requested\n");
185 return -EINVAL;
186 }
187 block_size = device->char_data.block_size;
188 nblocks = count / block_size;
189 } else {
190 block_size = count;
191 nblocks = 1;
192 }
193
194 rc = tape_check_idalbuffer(device, block_size);
195 if (rc)
196 return rc;
197
198 DBF_EVENT(6, "TCHAR:nbytes: %lx\n", block_size);
199 DBF_EVENT(6, "TCHAR:nblocks: %x\n", nblocks);
200 /* Let the discipline build the ccw chain. */
201 request = device->discipline->write_block(device);
202 if (IS_ERR(request))
203 return PTR_ERR(request);
204
205 for (i = 0; i < nblocks; i++) {
206 size_t wbytes = 0; /* Used to trace written data in dbf */
207
208 ibs = device->char_data.ibs;
209 while (ibs && *ibs) {
210 if (idal_buffer_from_user(*ibs, data, (*ibs)->size)) {
211 rc = -EFAULT;
212 goto out;
213 }
214 data += (*ibs)->size;
215 ibs++;
216 }
217 rc = tape_do_io(device, request);
218 if (rc)
219 goto out;
220
221 /* Channel Program Address (cpa) points to last CCW + 8 */
222 last_ccw = dma32_to_virt(request->irb.scsw.cmd.cpa);
223 ccw = request->cpaddr;
224 while (++ccw < last_ccw)
225 wbytes += ccw->count;
226 DBF_EVENT(6, "TCHAR:wbytes: %lx\n", wbytes - request->rescnt);
227 written += wbytes - request->rescnt;
228 if (request->rescnt != 0)
229 break;
230 }
231
232 out:
233 tape_free_request(request);
234 if (rc == -ENOSPC) {
235 /*
236 * Ok, the device has no more space. It has NOT written
237 * the block.
238 */
239 if (device->discipline->process_eov)
240 device->discipline->process_eov(device);
241 if (written > 0)
242 rc = 0;
243
244 }
245
246 /*
247 * After doing a write we always need two tapemarks to correctly
248 * terminate the tape (one to terminate the file, the second to
249 * flag the end of recorded data.
250 * Since process_eov positions the tape in front of the written
251 * tapemark it doesn't hurt to write two marks again.
252 */
253 if (!rc)
254 device->required_tapemarks = 2;
255
256 return rc ? rc : written;
257 }
258
259 /*
260 * Character frontend tape device open function.
261 */
262 static int
tapechar_open(struct inode * inode,struct file * filp)263 tapechar_open (struct inode *inode, struct file *filp)
264 {
265 struct tape_device *device;
266 int minor, rc;
267
268 DBF_EVENT(6, "TCHAR:open: %i:%i\n",
269 imajor(file_inode(filp)),
270 iminor(file_inode(filp)));
271
272 if (imajor(file_inode(filp)) != tapechar_major)
273 return -ENODEV;
274
275 minor = iminor(file_inode(filp));
276 device = tape_find_device(minor / TAPE_MINORS_PER_DEV);
277 if (IS_ERR(device)) {
278 DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n");
279 return PTR_ERR(device);
280 }
281
282 rc = tape_open(device);
283 if (rc == 0) {
284 filp->private_data = device;
285 stream_open(inode, filp);
286 } else
287 tape_put_device(device);
288
289 return rc;
290 }
291
292 /*
293 * Character frontend tape device release function.
294 */
295
296 static int
tapechar_release(struct inode * inode,struct file * filp)297 tapechar_release(struct inode *inode, struct file *filp)
298 {
299 struct tape_device *device;
300
301 DBF_EVENT(6, "TCHAR:release: %x\n", iminor(inode));
302 device = (struct tape_device *) filp->private_data;
303
304 /*
305 * If this is the rewinding tape minor then rewind. In that case we
306 * write all required tapemarks. Otherwise only one to terminate the
307 * file.
308 */
309 if ((iminor(inode) & 1) != 0) {
310 if (device->required_tapemarks)
311 tape_std_terminate_write(device);
312 tape_mtop(device, MTREW, 1);
313 } else {
314 if (device->required_tapemarks > 1) {
315 if (tape_mtop(device, MTWEOF, 1) == 0)
316 device->required_tapemarks--;
317 }
318 }
319
320 if (device->char_data.ibs)
321 idal_buffer_array_free(&device->char_data.ibs);
322 tape_release(device);
323 filp->private_data = NULL;
324 tape_put_device(device);
325
326 return 0;
327 }
328
329 /*
330 * Tape device io controls.
331 */
332 static int
__tapechar_ioctl(struct tape_device * device,unsigned int no,void __user * data)333 __tapechar_ioctl(struct tape_device *device,
334 unsigned int no, void __user *data)
335 {
336 int rc;
337
338 if (no == MTIOCTOP) {
339 struct mtop op;
340
341 if (copy_from_user(&op, data, sizeof(op)) != 0)
342 return -EFAULT;
343 if (op.mt_count < 0)
344 return -EINVAL;
345
346 /*
347 * Operations that change tape position should write final
348 * tapemarks.
349 */
350 switch (op.mt_op) {
351 case MTFSF:
352 case MTBSF:
353 case MTFSR:
354 case MTBSR:
355 case MTREW:
356 case MTOFFL:
357 case MTEOM:
358 case MTRETEN:
359 case MTBSFM:
360 case MTFSFM:
361 case MTSEEK:
362 if (device->required_tapemarks)
363 tape_std_terminate_write(device);
364 }
365 rc = tape_mtop(device, op.mt_op, op.mt_count);
366
367 if (op.mt_op == MTWEOF && rc == 0) {
368 if (op.mt_count > device->required_tapemarks)
369 device->required_tapemarks = 0;
370 else
371 device->required_tapemarks -= op.mt_count;
372 }
373 return rc;
374 }
375 if (no == MTIOCPOS) {
376 /* MTIOCPOS: query the tape position. */
377 struct mtpos pos;
378
379 rc = tape_mtop(device, MTTELL, 1);
380 if (rc < 0)
381 return rc;
382 pos.mt_blkno = rc;
383 return put_user_mtpos(data, &pos);
384 }
385 if (no == MTIOCGET) {
386 /* MTIOCGET: query the tape drive status. */
387 struct mtget get;
388
389 memset(&get, 0, sizeof(get));
390 get.mt_type = MT_ISUNKNOWN;
391 get.mt_resid = 0 /* device->devstat.rescnt */;
392 get.mt_dsreg =
393 ((device->char_data.block_size << MT_ST_BLKSIZE_SHIFT)
394 & MT_ST_BLKSIZE_MASK);
395 /* FIXME: mt_gstat, mt_erreg, mt_fileno */
396 get.mt_gstat = 0;
397 get.mt_erreg = 0;
398 get.mt_fileno = 0;
399 get.mt_gstat = device->tape_generic_status;
400
401 if (device->medium_state == MS_LOADED) {
402 rc = tape_mtop(device, MTTELL, 1);
403
404 if (rc < 0)
405 return rc;
406
407 if (rc == 0)
408 get.mt_gstat |= GMT_BOT(~0);
409
410 get.mt_blkno = rc;
411 }
412
413 return put_user_mtget(data, &get);
414 }
415 return -EINVAL;
416 }
417
418 static long
tapechar_ioctl(struct file * filp,unsigned int no,unsigned long data)419 tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data)
420 {
421 struct tape_device *device;
422 long rc;
423
424 DBF_EVENT(6, "TCHAR:ioct\n");
425
426 device = (struct tape_device *) filp->private_data;
427 mutex_lock(&device->mutex);
428 rc = __tapechar_ioctl(device, no, (void __user *)data);
429 mutex_unlock(&device->mutex);
430 return rc;
431 }
432
433 /*
434 * Initialize character device frontend.
435 */
436 int
tapechar_init(void)437 tapechar_init (void)
438 {
439 dev_t dev;
440
441 if (alloc_chrdev_region(&dev, 0, 256, "tape") != 0)
442 return -1;
443
444 tapechar_major = MAJOR(dev);
445
446 return 0;
447 }
448
449 /*
450 * cleanup
451 */
452 void
tapechar_exit(void)453 tapechar_exit(void)
454 {
455 unregister_chrdev_region(MKDEV(tapechar_major, 0), 256);
456 }
457