Lines Matching +full:static +full:- +full:trace +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0
38 * is used to read spool data page-wise.
44 static char ur_banner[] = "z/VM virtual unit record device driver";
50 static dev_t ur_first_dev_maj_min;
51 static const struct class vmur_class = {
54 static struct debug_info *vmur_dbf;
57 static struct ccw_device_id ur_ids[] = {
65 static int ur_probe(struct ccw_device *cdev);
66 static void ur_remove(struct ccw_device *cdev);
67 static int ur_set_online(struct ccw_device *cdev);
68 static int ur_set_offline(struct ccw_device *cdev);
70 static struct ccw_driver ur_driver = {
83 static DEFINE_MUTEX(vmur_mutex);
85 static void ur_uevent(struct work_struct *ws);
91 * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the
92 * ur device using dev_get_drvdata(&cdev->dev) pointer.
95 * - ur_probe gets a urd reference, ur_remove drops the reference
96 * dev_get_drvdata(&cdev->dev)
97 * - ur_open gets a urd reference, ur_release drops the reference
98 * (urf->urd)
101 * - urdev_alloc get a cdev reference (urd->cdev)
102 * - urdev_free drops the cdev reference (urd->cdev)
104 * Setting and clearing of dev_get_drvdata(&cdev->dev) is protected by the ccwdev lock
106 static struct urdev *urdev_alloc(struct ccw_device *cdev) in urdev_alloc()
113 urd->reclen = cdev->id.driver_info; in urdev_alloc()
114 ccw_device_get_id(cdev, &urd->dev_id); in urdev_alloc()
115 mutex_init(&urd->io_mutex); in urdev_alloc()
116 init_waitqueue_head(&urd->wait); in urdev_alloc()
117 INIT_WORK(&urd->uevent_work, ur_uevent); in urdev_alloc()
118 spin_lock_init(&urd->open_lock); in urdev_alloc()
119 refcount_set(&urd->ref_count, 1); in urdev_alloc()
120 urd->cdev = cdev; in urdev_alloc()
121 get_device(&cdev->dev); in urdev_alloc()
125 static void urdev_free(struct urdev *urd) in urdev_free()
127 TRACE("urdev_free: %p\n", urd); in urdev_free()
128 if (urd->cdev) in urdev_free()
129 put_device(&urd->cdev->dev); in urdev_free()
133 static void urdev_get(struct urdev *urd) in urdev_get()
135 refcount_inc(&urd->ref_count); in urdev_get()
138 static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) in urdev_get_from_cdev()
144 urd = dev_get_drvdata(&cdev->dev); in urdev_get_from_cdev()
151 static struct urdev *urdev_get_from_devno(u16 devno) in urdev_get_from_devno()
162 put_device(&cdev->dev); in urdev_get_from_devno()
166 static void urdev_put(struct urdev *urd) in urdev_put()
168 if (refcount_dec_and_test(&urd->ref_count)) in urdev_put()
173 * Low-level functions to do I/O to a ur device.
183 * on a completion event it publishes at urd->io_done. The function
195 static void free_chan_prog(struct ccw1 *cpa) in free_chan_prog()
199 while (ptr->cda) { in free_chan_prog()
200 kfree(dma32_to_virt(ptr->cda)); in free_chan_prog()
209 * with a final NOP CCW command-chained on (which ensures that CE and DE
214 static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count, in alloc_chan_prog()
221 TRACE("alloc_chan_prog(%p, %i, %i)\n", ubuf, rec_count, reclen); in alloc_chan_prog()
231 return ERR_PTR(-ENOMEM); in alloc_chan_prog()
240 return ERR_PTR(-ENOMEM); in alloc_chan_prog()
245 return ERR_PTR(-EFAULT); in alloc_chan_prog()
254 static int do_ur_io(struct urdev *urd, struct ccw1 *cpa) in do_ur_io()
257 struct ccw_device *cdev = urd->cdev; in do_ur_io()
260 TRACE("do_ur_io: cpa=%p\n", cpa); in do_ur_io()
262 rc = mutex_lock_interruptible(&urd->io_mutex); in do_ur_io()
266 urd->io_done = &event; in do_ur_io()
272 TRACE("do_ur_io: ccw_device_start returned %d\n", rc); in do_ur_io()
277 TRACE("do_ur_io: I/O complete\n"); in do_ur_io()
281 mutex_unlock(&urd->io_mutex); in do_ur_io()
285 static void ur_uevent(struct work_struct *ws) in ur_uevent()
289 "EVENT=unsol_de", /* Unsolicited device-end interrupt */ in ur_uevent()
293 kobject_uevent_env(&urd->cdev->dev.kobj, KOBJ_CHANGE, envp); in ur_uevent()
300 static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, in ur_int_handler()
306 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n", in ur_int_handler()
307 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, in ur_int_handler()
308 irb->scsw.cmd.count); in ur_int_handler()
310 urd = dev_get_drvdata(&cdev->dev); in ur_int_handler()
312 TRACE("ur_int_handler: unsolicited interrupt\n"); in ur_int_handler()
314 if (scsw_dstat(&irb->scsw) & DEV_STAT_DEV_END) { in ur_int_handler()
317 * device-ready state. in ur_int_handler()
320 schedule_work(&urd->uevent_work); in ur_int_handler()
327 urd->io_request_rc = PTR_ERR(irb); in ur_int_handler()
328 else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) in ur_int_handler()
329 urd->io_request_rc = 0; in ur_int_handler()
331 urd->io_request_rc = -EIO; in ur_int_handler()
333 complete(urd->io_done); in ur_int_handler()
337 * reclen sysfs attribute - The record length to be used for write CCWs
339 static ssize_t ur_attr_reclen_show(struct device *dev, in ur_attr_reclen_show()
347 return -ENODEV; in ur_attr_reclen_show()
348 rc = sysfs_emit(buf, "%zu\n", urd->reclen); in ur_attr_reclen_show()
353 static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL);
355 static int ur_create_attributes(struct device *dev) in ur_create_attributes()
360 static void ur_remove_attributes(struct device *dev) in ur_remove_attributes()
366 * diagnose code 0x210 - retrieve device information
372 static int get_urd_class(struct urdev *urd) in get_urd_class()
374 static struct diag210 ur_diag210; in get_urd_class()
377 ur_diag210.vrdcdvno = urd->dev_id.devno; in get_urd_class()
383 return -EOPNOTSUPP; in get_urd_class()
387 return -ENODEV; in get_urd_class()
389 return -EIO; in get_urd_class()
396 static struct urfile *urfile_alloc(struct urdev *urd) in urfile_alloc()
403 urf->urd = urd; in urfile_alloc()
405 TRACE("urfile_alloc: urd=%p urf=%p rl=%zu\n", urd, urf, in urfile_alloc()
406 urf->dev_reclen); in urfile_alloc()
411 static void urfile_free(struct urfile *urf) in urfile_free()
413 TRACE("urfile_free: urf=%p urd=%p\n", urf, urf->urd); in urfile_free()
420 static ssize_t do_write(struct urdev *urd, const char __user *udata, in do_write()
434 if (urd->io_request_rc) { in do_write()
435 rc = urd->io_request_rc; in do_write()
446 static ssize_t ur_write(struct file *file, const char __user *udata, in ur_write()
449 struct urfile *urf = file->private_data; in ur_write()
451 TRACE("ur_write: count=%zu\n", count); in ur_write()
456 if (count % urf->dev_reclen) in ur_write()
457 return -EINVAL; /* count must be a multiple of reclen */ in ur_write()
459 if (count > urf->dev_reclen * MAX_RECS_PER_IO) in ur_write()
460 count = urf->dev_reclen * MAX_RECS_PER_IO; in ur_write()
462 return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); in ur_write()
466 * diagnose code 0x14 subcode 0x0028 - position spool file to designated
472 static int diag_position_to_record(int devno, int record) in diag_position_to_record()
481 return -ENOMEDIUM; in diag_position_to_record()
483 return -ENODATA; /* position beyond end of file */ in diag_position_to_record()
485 return -EIO; in diag_position_to_record()
490 * diagnose code 0x14 subcode 0x0000 - read next spool file buffer
497 static int diag_read_file(int devno, char *buf) in diag_read_file()
506 return -ENODATA; in diag_read_file()
508 return -ENOMEDIUM; in diag_read_file()
510 return -EIO; in diag_read_file()
514 static ssize_t diag14_read(struct file *file, char __user *ubuf, size_t count, in diag14_read()
523 urd = ((struct urfile *) file->private_data)->urd; in diag14_read()
524 reclen = ((struct urfile *) file->private_data)->file_reclen; in diag14_read()
526 rc = diag_position_to_record(urd->dev_id.devno, *offs / PAGE_SIZE + 1); in diag14_read()
527 if (rc == -ENODATA) in diag14_read()
535 return -ENOMEM; in diag14_read()
540 rc = diag_read_file(urd->dev_id.devno, buf); in diag14_read()
541 if (rc == -ENODATA) { in diag14_read()
548 len = min(count - copied, PAGE_SIZE - res); in diag14_read()
550 rc = -EFAULT; in diag14_read()
564 static ssize_t ur_read(struct file *file, char __user *ubuf, size_t count, in ur_read()
570 TRACE("ur_read: count=%zu ppos=%li\n", count, (unsigned long) *offs); in ur_read()
575 urd = ((struct urfile *) file->private_data)->urd; in ur_read()
576 rc = mutex_lock_interruptible(&urd->io_mutex); in ur_read()
580 mutex_unlock(&urd->io_mutex); in ur_read()
585 * diagnose code 0x14 subcode 0x0fff - retrieve next file descriptor
590 static int diag_read_next_file_info(struct file_control_block *buf, int spid) in diag_read_next_file_info()
599 return -ENODATA; in diag_read_next_file_info()
603 static int verify_uri_device(struct urdev *urd) in verify_uri_device()
611 return -ENOMEM; in verify_uri_device()
619 if (fcb->file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) { in verify_uri_device()
620 rc = -EPERM; in verify_uri_device()
627 rc = -ENOMEM; in verify_uri_device()
630 rc = diag_read_file(urd->dev_id.devno, buf); in verify_uri_device()
631 if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */ in verify_uri_device()
638 if (!(fcb->file_stat & FLG_IN_USE)) { in verify_uri_device()
639 rc = -EMFILE; in verify_uri_device()
651 static int verify_device(struct urdev *urd) in verify_device()
653 switch (urd->class) { in verify_device()
659 return -EOPNOTSUPP; in verify_device()
663 static int get_uri_file_reclen(struct urdev *urd) in get_uri_file_reclen()
670 return -ENOMEM; in get_uri_file_reclen()
674 if (fcb->file_stat & FLG_CP_DUMP) in get_uri_file_reclen()
677 rc = fcb->rec_len; in get_uri_file_reclen()
684 static int get_file_reclen(struct urdev *urd) in get_file_reclen()
686 switch (urd->class) { in get_file_reclen()
692 return -EOPNOTSUPP; in get_file_reclen()
696 static int ur_open(struct inode *inode, struct file *file) in ur_open()
704 accmode = file->f_flags & O_ACCMODE; in ur_open()
707 return -EACCES; in ur_open()
716 rc = -ENXIO; in ur_open()
720 spin_lock(&urd->open_lock); in ur_open()
721 while (urd->open_flag) { in ur_open()
722 spin_unlock(&urd->open_lock); in ur_open()
723 if (file->f_flags & O_NONBLOCK) { in ur_open()
724 rc = -EBUSY; in ur_open()
727 if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) { in ur_open()
728 rc = -ERESTARTSYS; in ur_open()
731 spin_lock(&urd->open_lock); in ur_open()
733 urd->open_flag++; in ur_open()
734 spin_unlock(&urd->open_lock); in ur_open()
736 TRACE("ur_open\n"); in ur_open()
738 if (((accmode == O_RDONLY) && (urd->class != DEV_CLASS_UR_I)) || in ur_open()
739 ((accmode == O_WRONLY) && (urd->class != DEV_CLASS_UR_O))) { in ur_open()
740 TRACE("ur_open: unsupported dev class (%d)\n", urd->class); in ur_open()
741 rc = -EACCES; in ur_open()
751 rc = -ENOMEM; in ur_open()
755 urf->dev_reclen = urd->reclen; in ur_open()
759 urf->file_reclen = rc; in ur_open()
760 file->private_data = urf; in ur_open()
766 spin_lock(&urd->open_lock); in ur_open()
767 urd->open_flag--; in ur_open()
768 spin_unlock(&urd->open_lock); in ur_open()
775 static int ur_release(struct inode *inode, struct file *file) in ur_release()
777 struct urfile *urf = file->private_data; in ur_release()
779 TRACE("ur_release\n"); in ur_release()
780 spin_lock(&urf->urd->open_lock); in ur_release()
781 urf->urd->open_flag--; in ur_release()
782 spin_unlock(&urf->urd->open_lock); in ur_release()
783 wake_up_interruptible(&urf->urd->wait); in ur_release()
784 urdev_put(urf->urd); in ur_release()
789 static loff_t ur_llseek(struct file *file, loff_t offset, int whence) in ur_llseek()
791 if ((file->f_flags & O_ACCMODE) != O_RDONLY) in ur_llseek()
792 return -ESPIPE; /* seek allowed only for reader */ in ur_llseek()
794 return -ESPIPE; /* only multiples of 4K allowed */ in ur_llseek()
798 static const struct file_operations ur_fops = {
818 * urd->char_device is used as indication that the online function has
821 static int ur_probe(struct ccw_device *cdev) in ur_probe()
826 TRACE("ur_probe: cdev=%p\n", cdev); in ur_probe()
831 rc = -ENOMEM; in ur_probe()
835 rc = ur_create_attributes(&cdev->dev); in ur_probe()
837 rc = -ENOMEM; in ur_probe()
842 urd->class = get_urd_class(urd); in ur_probe()
843 if (urd->class < 0) { in ur_probe()
844 rc = urd->class; in ur_probe()
847 if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { in ur_probe()
848 rc = -EOPNOTSUPP; in ur_probe()
852 dev_set_drvdata(&cdev->dev, urd); in ur_probe()
853 cdev->handler = ur_int_handler; in ur_probe()
860 ur_remove_attributes(&cdev->dev); in ur_probe()
868 static int ur_set_online(struct ccw_device *cdev) in ur_set_online()
874 TRACE("ur_set_online: cdev=%p\n", cdev); in ur_set_online()
880 rc = -ENODEV; in ur_set_online()
884 if (urd->char_device) { in ur_set_online()
886 rc = -EBUSY; in ur_set_online()
890 minor = urd->dev_id.devno; in ur_set_online()
893 urd->char_device = cdev_alloc(); in ur_set_online()
894 if (!urd->char_device) { in ur_set_online()
895 rc = -ENOMEM; in ur_set_online()
899 urd->char_device->ops = &ur_fops; in ur_set_online()
900 urd->char_device->owner = ur_fops.owner; in ur_set_online()
902 rc = cdev_add(urd->char_device, MKDEV(major, minor), 1); in ur_set_online()
905 if (urd->cdev->id.cu_type == READER_PUNCH_DEVTYPE) { in ur_set_online()
906 if (urd->class == DEV_CLASS_UR_I) in ur_set_online()
907 scnprintf(node_id, sizeof(node_id), "vmrdr-%s", dev_name(&cdev->dev)); in ur_set_online()
908 if (urd->class == DEV_CLASS_UR_O) in ur_set_online()
909 scnprintf(node_id, sizeof(node_id), "vmpun-%s", dev_name(&cdev->dev)); in ur_set_online()
910 } else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) { in ur_set_online()
911 scnprintf(node_id, sizeof(node_id), "vmprt-%s", dev_name(&cdev->dev)); in ur_set_online()
913 rc = -EOPNOTSUPP; in ur_set_online()
917 urd->device = device_create(&vmur_class, &cdev->dev, in ur_set_online()
918 urd->char_device->dev, NULL, "%s", node_id); in ur_set_online()
919 if (IS_ERR(urd->device)) { in ur_set_online()
920 rc = PTR_ERR(urd->device); in ur_set_online()
921 TRACE("ur_set_online: device_create rc=%d\n", rc); in ur_set_online()
929 cdev_del(urd->char_device); in ur_set_online()
930 urd->char_device = NULL; in ur_set_online()
938 static int ur_set_offline_force(struct ccw_device *cdev, int force) in ur_set_offline_force()
943 TRACE("ur_set_offline: cdev=%p\n", cdev); in ur_set_offline_force()
947 return -ENODEV; in ur_set_offline_force()
948 if (!urd->char_device) { in ur_set_offline_force()
950 rc = -EBUSY; in ur_set_offline_force()
953 if (!force && (refcount_read(&urd->ref_count) > 2)) { in ur_set_offline_force()
955 TRACE("ur_set_offline: BUSY\n"); in ur_set_offline_force()
956 rc = -EBUSY; in ur_set_offline_force()
959 if (cancel_work_sync(&urd->uevent_work)) { in ur_set_offline_force()
960 /* Work not run yet - need to release reference here */ in ur_set_offline_force()
963 device_destroy(&vmur_class, urd->char_device->dev); in ur_set_offline_force()
964 cdev_del(urd->char_device); in ur_set_offline_force()
965 urd->char_device = NULL; in ur_set_offline_force()
973 static int ur_set_offline(struct ccw_device *cdev) in ur_set_offline()
983 static void ur_remove(struct ccw_device *cdev) in ur_remove()
987 TRACE("ur_remove\n"); in ur_remove()
991 if (cdev->online) in ur_remove()
993 ur_remove_attributes(&cdev->dev); in ur_remove()
996 urdev_put(dev_get_drvdata(&cdev->dev)); in ur_remove()
997 dev_set_drvdata(&cdev->dev, NULL); in ur_remove()
998 cdev->handler = NULL; in ur_remove()
1007 static int __init ur_init(void) in ur_init()
1015 return -ENODEV; in ur_init()
1020 return -ENOMEM; in ur_init()
1055 static void __exit ur_exit(void) in ur_exit()