Lines Matching +full:de +full:- +full:serialized
1 // SPDX-License-Identifier: GPL-2.0
8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Frank Munzert <munzert@de.ibm.com>
36 * is used to read spool data page-wise.
87 * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the
88 * ur device using dev_get_drvdata(&cdev->dev) pointer.
91 * - ur_probe gets a urd reference, ur_remove drops the reference
92 * dev_get_drvdata(&cdev->dev)
93 * - ur_open gets a urd reference, ur_release drops the reference
94 * (urf->urd)
97 * - urdev_alloc get a cdev reference (urd->cdev)
98 * - urdev_free drops the cdev reference (urd->cdev)
100 * Setting and clearing of dev_get_drvdata(&cdev->dev) is protected by the ccwdev lock
109 urd->reclen = cdev->id.driver_info; in urdev_alloc()
110 ccw_device_get_id(cdev, &urd->dev_id); in urdev_alloc()
111 mutex_init(&urd->io_mutex); in urdev_alloc()
112 init_waitqueue_head(&urd->wait); in urdev_alloc()
113 spin_lock_init(&urd->open_lock); in urdev_alloc()
114 refcount_set(&urd->ref_count, 1); in urdev_alloc()
115 urd->cdev = cdev; in urdev_alloc()
116 get_device(&cdev->dev); in urdev_alloc()
123 if (urd->cdev) in urdev_free()
124 put_device(&urd->cdev->dev); in urdev_free()
130 refcount_inc(&urd->ref_count); in urdev_get()
139 urd = dev_get_drvdata(&cdev->dev); in urdev_get_from_cdev()
157 put_device(&cdev->dev); in urdev_get_from_devno()
163 if (refcount_dec_and_test(&urd->ref_count)) in urdev_put()
178 struct urdev *urd = dev_get_drvdata(&cdev->dev); in ur_pm_suspend()
181 if (urd->open_flag) { in ur_pm_suspend()
183 "suspend.\n", dev_name(&cdev->dev), ur_banner); in ur_pm_suspend()
184 return -EBUSY; in ur_pm_suspend()
190 * Low-level functions to do I/O to a ur device.
200 * on a completion event it publishes at urd->io_done. The function
216 while (ptr->cda) { in free_chan_prog()
217 kfree((void *)(addr_t) ptr->cda); in free_chan_prog()
226 * with a final NOP CCW command-chained on (which ensures that CE and DE
241 * We chain a NOP onto the writes to force CE+DE together. in alloc_chan_prog()
248 return ERR_PTR(-ENOMEM); in alloc_chan_prog()
257 return ERR_PTR(-ENOMEM); in alloc_chan_prog()
262 return ERR_PTR(-EFAULT); in alloc_chan_prog()
266 /* The following NOP CCW forces CE+DE to be presented together */ in alloc_chan_prog()
274 struct ccw_device *cdev = urd->cdev; in do_ur_io()
279 rc = mutex_lock_interruptible(&urd->io_mutex); in do_ur_io()
283 urd->io_done = &event; in do_ur_io()
298 mutex_unlock(&urd->io_mutex); in do_ur_io()
312 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat, in ur_int_handler()
313 irb->scsw.cmd.count); in ur_int_handler()
319 urd = dev_get_drvdata(&cdev->dev); in ur_int_handler()
323 urd->io_request_rc = PTR_ERR(irb); in ur_int_handler()
324 else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) in ur_int_handler()
325 urd->io_request_rc = 0; in ur_int_handler()
327 urd->io_request_rc = -EIO; in ur_int_handler()
329 complete(urd->io_done); in ur_int_handler()
333 * reclen sysfs attribute - The record length to be used for write CCWs
343 return -ENODEV; in ur_attr_reclen_show()
344 rc = sprintf(buf, "%zu\n", urd->reclen); in ur_attr_reclen_show()
362 * diagnose code 0x210 - retrieve device information
373 ur_diag210.vrdcdvno = urd->dev_id.devno; in get_urd_class()
379 return -EOPNOTSUPP; in get_urd_class()
383 return -ENODEV; in get_urd_class()
385 return -EIO; in get_urd_class()
399 urf->urd = urd; in urfile_alloc()
402 urf->dev_reclen); in urfile_alloc()
409 TRACE("urfile_free: urf=%p urd=%p\n", urf, urf->urd); in urfile_free()
430 if (urd->io_request_rc) { in do_write()
431 rc = urd->io_request_rc; in do_write()
445 struct urfile *urf = file->private_data; in ur_write()
452 if (count % urf->dev_reclen) in ur_write()
453 return -EINVAL; /* count must be a multiple of reclen */ in ur_write()
455 if (count > urf->dev_reclen * MAX_RECS_PER_IO) in ur_write()
456 count = urf->dev_reclen * MAX_RECS_PER_IO; in ur_write()
458 return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); in ur_write()
462 * diagnose code 0x14 subcode 0x0028 - position spool file to designated
477 return -ENOMEDIUM; in diag_position_to_record()
479 return -ENODATA; /* position beyond end of file */ in diag_position_to_record()
481 return -EIO; in diag_position_to_record()
486 * diagnose code 0x14 subcode 0x0000 - read next spool file buffer
502 return -ENODATA; in diag_read_file()
504 return -ENOMEDIUM; in diag_read_file()
506 return -EIO; in diag_read_file()
519 urd = ((struct urfile *) file->private_data)->urd; in diag14_read()
520 reclen = ((struct urfile *) file->private_data)->file_reclen; in diag14_read()
522 rc = diag_position_to_record(urd->dev_id.devno, *offs / PAGE_SIZE + 1); in diag14_read()
523 if (rc == -ENODATA) in diag14_read()
531 return -ENOMEM; in diag14_read()
536 rc = diag_read_file(urd->dev_id.devno, buf); in diag14_read()
537 if (rc == -ENODATA) { in diag14_read()
544 len = min(count - copied, PAGE_SIZE - res); in diag14_read()
546 rc = -EFAULT; in diag14_read()
571 urd = ((struct urfile *) file->private_data)->urd; in ur_read()
572 rc = mutex_lock_interruptible(&urd->io_mutex); in ur_read()
576 mutex_unlock(&urd->io_mutex); in ur_read()
581 * diagnose code 0x14 subcode 0x0fff - retrieve next file descriptor
595 return -ENODATA; in diag_read_next_file_info()
607 return -ENOMEM; in verify_uri_device()
615 if (fcb->file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) { in verify_uri_device()
616 rc = -EPERM; in verify_uri_device()
623 rc = -ENOMEM; in verify_uri_device()
626 rc = diag_read_file(urd->dev_id.devno, buf); in verify_uri_device()
627 if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */ in verify_uri_device()
634 if (!(fcb->file_stat & FLG_IN_USE)) { in verify_uri_device()
635 rc = -EMFILE; in verify_uri_device()
649 switch (urd->class) { in verify_device()
655 return -EOPNOTSUPP; in verify_device()
666 return -ENOMEM; in get_uri_file_reclen()
670 if (fcb->file_stat & FLG_CP_DUMP) in get_uri_file_reclen()
673 rc = fcb->rec_len; in get_uri_file_reclen()
682 switch (urd->class) { in get_file_reclen()
688 return -EOPNOTSUPP; in get_file_reclen()
700 accmode = file->f_flags & O_ACCMODE; in ur_open()
703 return -EACCES; in ur_open()
708 devno = MINOR(file_inode(file)->i_rdev); in ur_open()
712 rc = -ENXIO; in ur_open()
716 spin_lock(&urd->open_lock); in ur_open()
717 while (urd->open_flag) { in ur_open()
718 spin_unlock(&urd->open_lock); in ur_open()
719 if (file->f_flags & O_NONBLOCK) { in ur_open()
720 rc = -EBUSY; in ur_open()
723 if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) { in ur_open()
724 rc = -ERESTARTSYS; in ur_open()
727 spin_lock(&urd->open_lock); in ur_open()
729 urd->open_flag++; in ur_open()
730 spin_unlock(&urd->open_lock); in ur_open()
734 if (((accmode == O_RDONLY) && (urd->class != DEV_CLASS_UR_I)) || in ur_open()
735 ((accmode == O_WRONLY) && (urd->class != DEV_CLASS_UR_O))) { in ur_open()
736 TRACE("ur_open: unsupported dev class (%d)\n", urd->class); in ur_open()
737 rc = -EACCES; in ur_open()
747 rc = -ENOMEM; in ur_open()
751 urf->dev_reclen = urd->reclen; in ur_open()
755 urf->file_reclen = rc; in ur_open()
756 file->private_data = urf; in ur_open()
762 spin_lock(&urd->open_lock); in ur_open()
763 urd->open_flag--; in ur_open()
764 spin_unlock(&urd->open_lock); in ur_open()
773 struct urfile *urf = file->private_data; in ur_release()
776 spin_lock(&urf->urd->open_lock); in ur_release()
777 urf->urd->open_flag--; in ur_release()
778 spin_unlock(&urf->urd->open_lock); in ur_release()
779 wake_up_interruptible(&urf->urd->wait); in ur_release()
780 urdev_put(urf->urd); in ur_release()
787 if ((file->f_flags & O_ACCMODE) != O_RDONLY) in ur_llseek()
788 return -ESPIPE; /* seek allowed only for reader */ in ur_llseek()
790 return -ESPIPE; /* only multiples of 4K allowed */ in ur_llseek()
811 * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized
814 * urd->char_device is used as indication that the online function has
827 rc = -ENOMEM; in ur_probe()
831 rc = ur_create_attributes(&cdev->dev); in ur_probe()
833 rc = -ENOMEM; in ur_probe()
836 cdev->handler = ur_int_handler; in ur_probe()
839 urd->class = get_urd_class(urd); in ur_probe()
840 if (urd->class < 0) { in ur_probe()
841 rc = urd->class; in ur_probe()
844 if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { in ur_probe()
845 rc = -EOPNOTSUPP; in ur_probe()
849 dev_set_drvdata(&cdev->dev, urd); in ur_probe()
856 ur_remove_attributes(&cdev->dev); in ur_probe()
876 rc = -ENODEV; in ur_set_online()
880 if (urd->char_device) { in ur_set_online()
882 rc = -EBUSY; in ur_set_online()
886 minor = urd->dev_id.devno; in ur_set_online()
889 urd->char_device = cdev_alloc(); in ur_set_online()
890 if (!urd->char_device) { in ur_set_online()
891 rc = -ENOMEM; in ur_set_online()
895 urd->char_device->ops = &ur_fops; in ur_set_online()
896 urd->char_device->owner = ur_fops.owner; in ur_set_online()
898 rc = cdev_add(urd->char_device, MKDEV(major, minor), 1); in ur_set_online()
901 if (urd->cdev->id.cu_type == READER_PUNCH_DEVTYPE) { in ur_set_online()
902 if (urd->class == DEV_CLASS_UR_I) in ur_set_online()
903 sprintf(node_id, "vmrdr-%s", dev_name(&cdev->dev)); in ur_set_online()
904 if (urd->class == DEV_CLASS_UR_O) in ur_set_online()
905 sprintf(node_id, "vmpun-%s", dev_name(&cdev->dev)); in ur_set_online()
906 } else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) { in ur_set_online()
907 sprintf(node_id, "vmprt-%s", dev_name(&cdev->dev)); in ur_set_online()
909 rc = -EOPNOTSUPP; in ur_set_online()
913 urd->device = device_create(vmur_class, &cdev->dev, in ur_set_online()
914 urd->char_device->dev, NULL, "%s", node_id); in ur_set_online()
915 if (IS_ERR(urd->device)) { in ur_set_online()
916 rc = PTR_ERR(urd->device); in ur_set_online()
925 cdev_del(urd->char_device); in ur_set_online()
926 urd->char_device = NULL; in ur_set_online()
943 return -ENODEV; in ur_set_offline_force()
944 if (!urd->char_device) { in ur_set_offline_force()
946 rc = -EBUSY; in ur_set_offline_force()
949 if (!force && (refcount_read(&urd->ref_count) > 2)) { in ur_set_offline_force()
952 rc = -EBUSY; in ur_set_offline_force()
955 device_destroy(vmur_class, urd->char_device->dev); in ur_set_offline_force()
956 cdev_del(urd->char_device); in ur_set_offline_force()
957 urd->char_device = NULL; in ur_set_offline_force()
983 if (cdev->online) in ur_remove()
985 ur_remove_attributes(&cdev->dev); in ur_remove()
988 urdev_put(dev_get_drvdata(&cdev->dev)); in ur_remove()
989 dev_set_drvdata(&cdev->dev, NULL); in ur_remove()
1006 return -ENODEV; in ur_init()
1011 return -ENOMEM; in ur_init()