1066 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Linux driver for System z and s390 unit record devices4 * (z/VM virtual punch, reader, printer)5 *6 * Copyright IBM Corp. 2001, 20097 * Authors: Malcolm Beattie <beattiem@uk.ibm.com>8 * Michael Holzheu <holzheu@de.ibm.com>9 * Frank Munzert <munzert@de.ibm.com>10 */11 12#define KMSG_COMPONENT "vmur"13#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt14 15#include <linux/cdev.h>16#include <linux/slab.h>17#include <linux/module.h>18#include <linux/kobject.h>19 20#include <linux/uaccess.h>21#include <asm/cio.h>22#include <asm/ccwdev.h>23#include <asm/debug.h>24#include <asm/diag.h>25#include <asm/scsw.h>26 27#include "vmur.h"28 29/*30 * Driver overview31 *32 * Unit record device support is implemented as a character device driver.33 * We can fit at least 16 bits into a device minor number and use the34 * simple method of mapping a character device number with minor abcd35 * to the unit record device with devno abcd.36 * I/O to virtual unit record devices is handled as follows:37 * Reads: Diagnose code 0x14 (input spool file manipulation)38 * is used to read spool data page-wise.39 * Writes: The CCW used is WRITE_CCW_CMD (0x01). The device's record length40 * is available by reading sysfs attr reclen. Each write() to the device41 * must specify an integral multiple (maximal 511) of reclen.42 */43 44static char ur_banner[] = "z/VM virtual unit record device driver";45 46MODULE_AUTHOR("IBM Corporation");47MODULE_DESCRIPTION("s390 z/VM virtual unit record device driver");48MODULE_LICENSE("GPL");49 50static dev_t ur_first_dev_maj_min;51static const struct class vmur_class = {52 .name = "vmur",53};54static struct debug_info *vmur_dbf;55 56/* We put the device's record length (for writes) in the driver_info field */57static struct ccw_device_id ur_ids[] = {58 { CCWDEV_CU_DI(READER_PUNCH_DEVTYPE, 80) },59 { CCWDEV_CU_DI(PRINTER_DEVTYPE, 132) },60 { /* end of list */ }61};62 63MODULE_DEVICE_TABLE(ccw, ur_ids);64 65static int ur_probe(struct ccw_device *cdev);66static void ur_remove(struct ccw_device *cdev);67static int ur_set_online(struct ccw_device *cdev);68static int ur_set_offline(struct ccw_device *cdev);69 70static struct ccw_driver ur_driver = {71 .driver = {72 .name = "vmur",73 .owner = THIS_MODULE,74 },75 .ids = ur_ids,76 .probe = ur_probe,77 .remove = ur_remove,78 .set_online = ur_set_online,79 .set_offline = ur_set_offline,80 .int_class = IRQIO_VMR,81};82 83static DEFINE_MUTEX(vmur_mutex);84 85static void ur_uevent(struct work_struct *ws);86 87/*88 * Allocation, freeing, getting and putting of urdev structures89 *90 * Each ur device (urd) contains a reference to its corresponding ccw device91 * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the92 * ur device using dev_get_drvdata(&cdev->dev) pointer.93 *94 * urd references:95 * - ur_probe gets a urd reference, ur_remove drops the reference96 * dev_get_drvdata(&cdev->dev)97 * - ur_open gets a urd reference, ur_release drops the reference98 * (urf->urd)99 *100 * cdev references:101 * - urdev_alloc get a cdev reference (urd->cdev)102 * - urdev_free drops the cdev reference (urd->cdev)103 *104 * Setting and clearing of dev_get_drvdata(&cdev->dev) is protected by the ccwdev lock105 */106static struct urdev *urdev_alloc(struct ccw_device *cdev)107{108 struct urdev *urd;109 110 urd = kzalloc(sizeof(struct urdev), GFP_KERNEL);111 if (!urd)112 return NULL;113 urd->reclen = cdev->id.driver_info;114 ccw_device_get_id(cdev, &urd->dev_id);115 mutex_init(&urd->io_mutex);116 init_waitqueue_head(&urd->wait);117 INIT_WORK(&urd->uevent_work, ur_uevent);118 spin_lock_init(&urd->open_lock);119 refcount_set(&urd->ref_count, 1);120 urd->cdev = cdev;121 get_device(&cdev->dev);122 return urd;123}124 125static void urdev_free(struct urdev *urd)126{127 TRACE("urdev_free: %p\n", urd);128 if (urd->cdev)129 put_device(&urd->cdev->dev);130 kfree(urd);131}132 133static void urdev_get(struct urdev *urd)134{135 refcount_inc(&urd->ref_count);136}137 138static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev)139{140 struct urdev *urd;141 unsigned long flags;142 143 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);144 urd = dev_get_drvdata(&cdev->dev);145 if (urd)146 urdev_get(urd);147 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);148 return urd;149}150 151static struct urdev *urdev_get_from_devno(u16 devno)152{153 char bus_id[16];154 struct ccw_device *cdev;155 struct urdev *urd;156 157 sprintf(bus_id, "0.0.%04x", devno);158 cdev = get_ccwdev_by_busid(&ur_driver, bus_id);159 if (!cdev)160 return NULL;161 urd = urdev_get_from_cdev(cdev);162 put_device(&cdev->dev);163 return urd;164}165 166static void urdev_put(struct urdev *urd)167{168 if (refcount_dec_and_test(&urd->ref_count))169 urdev_free(urd);170}171 172/*173 * Low-level functions to do I/O to a ur device.174 * alloc_chan_prog175 * free_chan_prog176 * do_ur_io177 * ur_int_handler178 *179 * alloc_chan_prog allocates and builds the channel program180 * free_chan_prog frees memory of the channel program181 *182 * do_ur_io issues the channel program to the device and blocks waiting183 * on a completion event it publishes at urd->io_done. The function184 * serialises itself on the device's mutex so that only one I/O185 * is issued at a time (and that I/O is synchronous).186 *187 * ur_int_handler catches the "I/O done" interrupt, writes the188 * subchannel status word into the scsw member of the urdev structure189 * and complete()s the io_done to wake the waiting do_ur_io.190 *191 * The caller of do_ur_io is responsible for kfree()ing the channel program192 * address pointer that alloc_chan_prog returned.193 */194 195static void free_chan_prog(struct ccw1 *cpa)196{197 struct ccw1 *ptr = cpa;198 199 while (ptr->cda) {200 kfree(dma32_to_virt(ptr->cda));201 ptr++;202 }203 kfree(cpa);204}205 206/*207 * alloc_chan_prog208 * The channel program we use is write commands chained together209 * with a final NOP CCW command-chained on (which ensures that CE and DE210 * are presented together in a single interrupt instead of as separate211 * interrupts unless an incorrect length indication kicks in first). The212 * data length in each CCW is reclen.213 */214static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count,215 int reclen)216{217 struct ccw1 *cpa;218 void *kbuf;219 int i;220 221 TRACE("alloc_chan_prog(%p, %i, %i)\n", ubuf, rec_count, reclen);222 223 /*224 * We chain a NOP onto the writes to force CE+DE together.225 * That means we allocate room for CCWs to cover count/reclen226 * records plus a NOP.227 */228 cpa = kcalloc(rec_count + 1, sizeof(struct ccw1),229 GFP_KERNEL | GFP_DMA);230 if (!cpa)231 return ERR_PTR(-ENOMEM);232 233 for (i = 0; i < rec_count; i++) {234 cpa[i].cmd_code = WRITE_CCW_CMD;235 cpa[i].flags = CCW_FLAG_CC | CCW_FLAG_SLI;236 cpa[i].count = reclen;237 kbuf = kmalloc(reclen, GFP_KERNEL | GFP_DMA);238 if (!kbuf) {239 free_chan_prog(cpa);240 return ERR_PTR(-ENOMEM);241 }242 cpa[i].cda = virt_to_dma32(kbuf);243 if (copy_from_user(kbuf, ubuf, reclen)) {244 free_chan_prog(cpa);245 return ERR_PTR(-EFAULT);246 }247 ubuf += reclen;248 }249 /* The following NOP CCW forces CE+DE to be presented together */250 cpa[i].cmd_code = CCW_CMD_NOOP;251 return cpa;252}253 254static int do_ur_io(struct urdev *urd, struct ccw1 *cpa)255{256 int rc;257 struct ccw_device *cdev = urd->cdev;258 DECLARE_COMPLETION_ONSTACK(event);259 260 TRACE("do_ur_io: cpa=%p\n", cpa);261 262 rc = mutex_lock_interruptible(&urd->io_mutex);263 if (rc)264 return rc;265 266 urd->io_done = &event;267 268 spin_lock_irq(get_ccwdev_lock(cdev));269 rc = ccw_device_start(cdev, cpa, 1, 0, 0);270 spin_unlock_irq(get_ccwdev_lock(cdev));271 272 TRACE("do_ur_io: ccw_device_start returned %d\n", rc);273 if (rc)274 goto out;275 276 wait_for_completion(&event);277 TRACE("do_ur_io: I/O complete\n");278 rc = 0;279 280out:281 mutex_unlock(&urd->io_mutex);282 return rc;283}284 285static void ur_uevent(struct work_struct *ws)286{287 struct urdev *urd = container_of(ws, struct urdev, uevent_work);288 char *envp[] = {289 "EVENT=unsol_de", /* Unsolicited device-end interrupt */290 NULL291 };292 293 kobject_uevent_env(&urd->cdev->dev.kobj, KOBJ_CHANGE, envp);294 urdev_put(urd);295}296 297/*298 * ur interrupt handler, called from the ccw_device layer299 */300static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm,301 struct irb *irb)302{303 struct urdev *urd;304 305 if (!IS_ERR(irb)) {306 TRACE("ur_int_handler: intparm=0x%lx cstat=%02x dstat=%02x res=%u\n",307 intparm, irb->scsw.cmd.cstat, irb->scsw.cmd.dstat,308 irb->scsw.cmd.count);309 }310 urd = dev_get_drvdata(&cdev->dev);311 if (!intparm) {312 TRACE("ur_int_handler: unsolicited interrupt\n");313 314 if (scsw_dstat(&irb->scsw) & DEV_STAT_DEV_END) {315 /*316 * Userspace might be interested in a transition to317 * device-ready state.318 */319 urdev_get(urd);320 schedule_work(&urd->uevent_work);321 }322 323 return;324 }325 /* On special conditions irb is an error pointer */326 if (IS_ERR(irb))327 urd->io_request_rc = PTR_ERR(irb);328 else if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))329 urd->io_request_rc = 0;330 else331 urd->io_request_rc = -EIO;332 333 complete(urd->io_done);334}335 336/*337 * reclen sysfs attribute - The record length to be used for write CCWs338 */339static ssize_t ur_attr_reclen_show(struct device *dev,340 struct device_attribute *attr, char *buf)341{342 struct urdev *urd;343 int rc;344 345 urd = urdev_get_from_cdev(to_ccwdev(dev));346 if (!urd)347 return -ENODEV;348 rc = sprintf(buf, "%zu\n", urd->reclen);349 urdev_put(urd);350 return rc;351}352 353static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL);354 355static int ur_create_attributes(struct device *dev)356{357 return device_create_file(dev, &dev_attr_reclen);358}359 360static void ur_remove_attributes(struct device *dev)361{362 device_remove_file(dev, &dev_attr_reclen);363}364 365/*366 * diagnose code 0x210 - retrieve device information367 * cc=0 normal completion, we have a real device368 * cc=1 CP paging error369 * cc=2 The virtual device exists, but is not associated with a real device370 * cc=3 Invalid device address, or the virtual device does not exist371 */372static int get_urd_class(struct urdev *urd)373{374 static struct diag210 ur_diag210;375 int cc;376 377 ur_diag210.vrdcdvno = urd->dev_id.devno;378 ur_diag210.vrdclen = sizeof(struct diag210);379 380 cc = diag210(&ur_diag210);381 switch (cc) {382 case 0:383 return -EOPNOTSUPP;384 case 2:385 return ur_diag210.vrdcvcla; /* virtual device class */386 case 3:387 return -ENODEV;388 default:389 return -EIO;390 }391}392 393/*394 * Allocation and freeing of urfile structures395 */396static struct urfile *urfile_alloc(struct urdev *urd)397{398 struct urfile *urf;399 400 urf = kzalloc(sizeof(struct urfile), GFP_KERNEL);401 if (!urf)402 return NULL;403 urf->urd = urd;404 405 TRACE("urfile_alloc: urd=%p urf=%p rl=%zu\n", urd, urf,406 urf->dev_reclen);407 408 return urf;409}410 411static void urfile_free(struct urfile *urf)412{413 TRACE("urfile_free: urf=%p urd=%p\n", urf, urf->urd);414 kfree(urf);415}416 417/*418 * The fops implementation of the character device driver419 */420static ssize_t do_write(struct urdev *urd, const char __user *udata,421 size_t count, size_t reclen, loff_t *ppos)422{423 struct ccw1 *cpa;424 int rc;425 426 cpa = alloc_chan_prog(udata, count / reclen, reclen);427 if (IS_ERR(cpa))428 return PTR_ERR(cpa);429 430 rc = do_ur_io(urd, cpa);431 if (rc)432 goto fail_kfree_cpa;433 434 if (urd->io_request_rc) {435 rc = urd->io_request_rc;436 goto fail_kfree_cpa;437 }438 *ppos += count;439 rc = count;440 441fail_kfree_cpa:442 free_chan_prog(cpa);443 return rc;444}445 446static ssize_t ur_write(struct file *file, const char __user *udata,447 size_t count, loff_t *ppos)448{449 struct urfile *urf = file->private_data;450 451 TRACE("ur_write: count=%zu\n", count);452 453 if (count == 0)454 return 0;455 456 if (count % urf->dev_reclen)457 return -EINVAL; /* count must be a multiple of reclen */458 459 if (count > urf->dev_reclen * MAX_RECS_PER_IO)460 count = urf->dev_reclen * MAX_RECS_PER_IO;461 462 return do_write(urf->urd, udata, count, urf->dev_reclen, ppos);463}464 465/*466 * diagnose code 0x14 subcode 0x0028 - position spool file to designated467 * record468 * cc=0 normal completion469 * cc=2 no file active on the virtual reader or device not ready470 * cc=3 record specified is beyond EOF471 */472static int diag_position_to_record(int devno, int record)473{474 int cc;475 476 cc = diag14(record, devno, 0x28);477 switch (cc) {478 case 0:479 return 0;480 case 2:481 return -ENOMEDIUM;482 case 3:483 return -ENODATA; /* position beyond end of file */484 default:485 return -EIO;486 }487}488 489/*490 * diagnose code 0x14 subcode 0x0000 - read next spool file buffer491 * cc=0 normal completion492 * cc=1 EOF reached493 * cc=2 no file active on the virtual reader, and no file eligible494 * cc=3 file already active on the virtual reader or specified virtual495 * reader does not exist or is not a reader496 */497static int diag_read_file(int devno, char *buf)498{499 int cc;500 501 cc = diag14((unsigned long) buf, devno, 0x00);502 switch (cc) {503 case 0:504 return 0;505 case 1:506 return -ENODATA;507 case 2:508 return -ENOMEDIUM;509 default:510 return -EIO;511 }512}513 514static ssize_t diag14_read(struct file *file, char __user *ubuf, size_t count,515 loff_t *offs)516{517 size_t len, copied, res;518 char *buf;519 int rc;520 u16 reclen;521 struct urdev *urd;522 523 urd = ((struct urfile *) file->private_data)->urd;524 reclen = ((struct urfile *) file->private_data)->file_reclen;525 526 rc = diag_position_to_record(urd->dev_id.devno, *offs / PAGE_SIZE + 1);527 if (rc == -ENODATA)528 return 0;529 if (rc)530 return rc;531 532 len = min((size_t) PAGE_SIZE, count);533 buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);534 if (!buf)535 return -ENOMEM;536 537 copied = 0;538 res = (size_t) (*offs % PAGE_SIZE);539 do {540 rc = diag_read_file(urd->dev_id.devno, buf);541 if (rc == -ENODATA) {542 break;543 }544 if (rc)545 goto fail;546 if (reclen && (copied == 0) && (*offs < PAGE_SIZE))547 *((u16 *) &buf[FILE_RECLEN_OFFSET]) = reclen;548 len = min(count - copied, PAGE_SIZE - res);549 if (copy_to_user(ubuf + copied, buf + res, len)) {550 rc = -EFAULT;551 goto fail;552 }553 res = 0;554 copied += len;555 } while (copied != count);556 557 *offs += copied;558 rc = copied;559fail:560 free_page((unsigned long) buf);561 return rc;562}563 564static ssize_t ur_read(struct file *file, char __user *ubuf, size_t count,565 loff_t *offs)566{567 struct urdev *urd;568 int rc;569 570 TRACE("ur_read: count=%zu ppos=%li\n", count, (unsigned long) *offs);571 572 if (count == 0)573 return 0;574 575 urd = ((struct urfile *) file->private_data)->urd;576 rc = mutex_lock_interruptible(&urd->io_mutex);577 if (rc)578 return rc;579 rc = diag14_read(file, ubuf, count, offs);580 mutex_unlock(&urd->io_mutex);581 return rc;582}583 584/*585 * diagnose code 0x14 subcode 0x0fff - retrieve next file descriptor586 * cc=0 normal completion587 * cc=1 no files on reader queue or no subsequent file588 * cc=2 spid specified is invalid589 */590static int diag_read_next_file_info(struct file_control_block *buf, int spid)591{592 int cc;593 594 cc = diag14((unsigned long) buf, spid, 0xfff);595 switch (cc) {596 case 0:597 return 0;598 default:599 return -ENODATA;600 }601}602 603static int verify_uri_device(struct urdev *urd)604{605 struct file_control_block *fcb;606 char *buf;607 int rc;608 609 fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA);610 if (!fcb)611 return -ENOMEM;612 613 /* check for empty reader device (beginning of chain) */614 rc = diag_read_next_file_info(fcb, 0);615 if (rc)616 goto fail_free_fcb;617 618 /* if file is in hold status, we do not read it */619 if (fcb->file_stat & (FLG_SYSTEM_HOLD | FLG_USER_HOLD)) {620 rc = -EPERM;621 goto fail_free_fcb;622 }623 624 /* open file on virtual reader */625 buf = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);626 if (!buf) {627 rc = -ENOMEM;628 goto fail_free_fcb;629 }630 rc = diag_read_file(urd->dev_id.devno, buf);631 if ((rc != 0) && (rc != -ENODATA)) /* EOF does not hurt */632 goto fail_free_buf;633 634 /* check if the file on top of the queue is open now */635 rc = diag_read_next_file_info(fcb, 0);636 if (rc)637 goto fail_free_buf;638 if (!(fcb->file_stat & FLG_IN_USE)) {639 rc = -EMFILE;640 goto fail_free_buf;641 }642 rc = 0;643 644fail_free_buf:645 free_page((unsigned long) buf);646fail_free_fcb:647 kfree(fcb);648 return rc;649}650 651static int verify_device(struct urdev *urd)652{653 switch (urd->class) {654 case DEV_CLASS_UR_O:655 return 0; /* no check needed here */656 case DEV_CLASS_UR_I:657 return verify_uri_device(urd);658 default:659 return -EOPNOTSUPP;660 }661}662 663static int get_uri_file_reclen(struct urdev *urd)664{665 struct file_control_block *fcb;666 int rc;667 668 fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA);669 if (!fcb)670 return -ENOMEM;671 rc = diag_read_next_file_info(fcb, 0);672 if (rc)673 goto fail_free;674 if (fcb->file_stat & FLG_CP_DUMP)675 rc = 0;676 else677 rc = fcb->rec_len;678 679fail_free:680 kfree(fcb);681 return rc;682}683 684static int get_file_reclen(struct urdev *urd)685{686 switch (urd->class) {687 case DEV_CLASS_UR_O:688 return 0;689 case DEV_CLASS_UR_I:690 return get_uri_file_reclen(urd);691 default:692 return -EOPNOTSUPP;693 }694}695 696static int ur_open(struct inode *inode, struct file *file)697{698 u16 devno;699 struct urdev *urd;700 struct urfile *urf;701 unsigned short accmode;702 int rc;703 704 accmode = file->f_flags & O_ACCMODE;705 706 if (accmode == O_RDWR)707 return -EACCES;708 /*709 * We treat the minor number as the devno of the ur device710 * to find in the driver tree.711 */712 devno = iminor(file_inode(file));713 714 urd = urdev_get_from_devno(devno);715 if (!urd) {716 rc = -ENXIO;717 goto out;718 }719 720 spin_lock(&urd->open_lock);721 while (urd->open_flag) {722 spin_unlock(&urd->open_lock);723 if (file->f_flags & O_NONBLOCK) {724 rc = -EBUSY;725 goto fail_put;726 }727 if (wait_event_interruptible(urd->wait, urd->open_flag == 0)) {728 rc = -ERESTARTSYS;729 goto fail_put;730 }731 spin_lock(&urd->open_lock);732 }733 urd->open_flag++;734 spin_unlock(&urd->open_lock);735 736 TRACE("ur_open\n");737 738 if (((accmode == O_RDONLY) && (urd->class != DEV_CLASS_UR_I)) ||739 ((accmode == O_WRONLY) && (urd->class != DEV_CLASS_UR_O))) {740 TRACE("ur_open: unsupported dev class (%d)\n", urd->class);741 rc = -EACCES;742 goto fail_unlock;743 }744 745 rc = verify_device(urd);746 if (rc)747 goto fail_unlock;748 749 urf = urfile_alloc(urd);750 if (!urf) {751 rc = -ENOMEM;752 goto fail_unlock;753 }754 755 urf->dev_reclen = urd->reclen;756 rc = get_file_reclen(urd);757 if (rc < 0)758 goto fail_urfile_free;759 urf->file_reclen = rc;760 file->private_data = urf;761 return 0;762 763fail_urfile_free:764 urfile_free(urf);765fail_unlock:766 spin_lock(&urd->open_lock);767 urd->open_flag--;768 spin_unlock(&urd->open_lock);769fail_put:770 urdev_put(urd);771out:772 return rc;773}774 775static int ur_release(struct inode *inode, struct file *file)776{777 struct urfile *urf = file->private_data;778 779 TRACE("ur_release\n");780 spin_lock(&urf->urd->open_lock);781 urf->urd->open_flag--;782 spin_unlock(&urf->urd->open_lock);783 wake_up_interruptible(&urf->urd->wait);784 urdev_put(urf->urd);785 urfile_free(urf);786 return 0;787}788 789static loff_t ur_llseek(struct file *file, loff_t offset, int whence)790{791 if ((file->f_flags & O_ACCMODE) != O_RDONLY)792 return -ESPIPE; /* seek allowed only for reader */793 if (offset % PAGE_SIZE)794 return -ESPIPE; /* only multiples of 4K allowed */795 return no_seek_end_llseek(file, offset, whence);796}797 798static const struct file_operations ur_fops = {799 .owner = THIS_MODULE,800 .open = ur_open,801 .release = ur_release,802 .read = ur_read,803 .write = ur_write,804 .llseek = ur_llseek,805};806 807/*808 * ccw_device infrastructure:809 * ur_probe creates the struct urdev (with refcount = 1), the device810 * attributes, sets up the interrupt handler and validates the virtual811 * unit record device.812 * ur_remove removes the device attributes and drops the reference to813 * struct urdev.814 *815 * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized816 * by the vmur_mutex lock.817 *818 * urd->char_device is used as indication that the online function has819 * been completed successfully.820 */821static int ur_probe(struct ccw_device *cdev)822{823 struct urdev *urd;824 int rc;825 826 TRACE("ur_probe: cdev=%p\n", cdev);827 828 mutex_lock(&vmur_mutex);829 urd = urdev_alloc(cdev);830 if (!urd) {831 rc = -ENOMEM;832 goto fail_unlock;833 }834 835 rc = ur_create_attributes(&cdev->dev);836 if (rc) {837 rc = -ENOMEM;838 goto fail_urdev_put;839 }840 841 /* validate virtual unit record device */842 urd->class = get_urd_class(urd);843 if (urd->class < 0) {844 rc = urd->class;845 goto fail_remove_attr;846 }847 if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) {848 rc = -EOPNOTSUPP;849 goto fail_remove_attr;850 }851 spin_lock_irq(get_ccwdev_lock(cdev));852 dev_set_drvdata(&cdev->dev, urd);853 cdev->handler = ur_int_handler;854 spin_unlock_irq(get_ccwdev_lock(cdev));855 856 mutex_unlock(&vmur_mutex);857 return 0;858 859fail_remove_attr:860 ur_remove_attributes(&cdev->dev);861fail_urdev_put:862 urdev_put(urd);863fail_unlock:864 mutex_unlock(&vmur_mutex);865 return rc;866}867 868static int ur_set_online(struct ccw_device *cdev)869{870 struct urdev *urd;871 int minor, major, rc;872 char node_id[16];873 874 TRACE("ur_set_online: cdev=%p\n", cdev);875 876 mutex_lock(&vmur_mutex);877 urd = urdev_get_from_cdev(cdev);878 if (!urd) {879 /* ur_remove already deleted our urd */880 rc = -ENODEV;881 goto fail_unlock;882 }883 884 if (urd->char_device) {885 /* Another ur_set_online was faster */886 rc = -EBUSY;887 goto fail_urdev_put;888 }889 890 minor = urd->dev_id.devno;891 major = MAJOR(ur_first_dev_maj_min);892 893 urd->char_device = cdev_alloc();894 if (!urd->char_device) {895 rc = -ENOMEM;896 goto fail_urdev_put;897 }898 899 urd->char_device->ops = &ur_fops;900 urd->char_device->owner = ur_fops.owner;901 902 rc = cdev_add(urd->char_device, MKDEV(major, minor), 1);903 if (rc)904 goto fail_free_cdev;905 if (urd->cdev->id.cu_type == READER_PUNCH_DEVTYPE) {906 if (urd->class == DEV_CLASS_UR_I)907 sprintf(node_id, "vmrdr-%s", dev_name(&cdev->dev));908 if (urd->class == DEV_CLASS_UR_O)909 sprintf(node_id, "vmpun-%s", dev_name(&cdev->dev));910 } else if (urd->cdev->id.cu_type == PRINTER_DEVTYPE) {911 sprintf(node_id, "vmprt-%s", dev_name(&cdev->dev));912 } else {913 rc = -EOPNOTSUPP;914 goto fail_free_cdev;915 }916 917 urd->device = device_create(&vmur_class, &cdev->dev,918 urd->char_device->dev, NULL, "%s", node_id);919 if (IS_ERR(urd->device)) {920 rc = PTR_ERR(urd->device);921 TRACE("ur_set_online: device_create rc=%d\n", rc);922 goto fail_free_cdev;923 }924 urdev_put(urd);925 mutex_unlock(&vmur_mutex);926 return 0;927 928fail_free_cdev:929 cdev_del(urd->char_device);930 urd->char_device = NULL;931fail_urdev_put:932 urdev_put(urd);933fail_unlock:934 mutex_unlock(&vmur_mutex);935 return rc;936}937 938static int ur_set_offline_force(struct ccw_device *cdev, int force)939{940 struct urdev *urd;941 int rc;942 943 TRACE("ur_set_offline: cdev=%p\n", cdev);944 urd = urdev_get_from_cdev(cdev);945 if (!urd)946 /* ur_remove already deleted our urd */947 return -ENODEV;948 if (!urd->char_device) {949 /* Another ur_set_offline was faster */950 rc = -EBUSY;951 goto fail_urdev_put;952 }953 if (!force && (refcount_read(&urd->ref_count) > 2)) {954 /* There is still a user of urd (e.g. ur_open) */955 TRACE("ur_set_offline: BUSY\n");956 rc = -EBUSY;957 goto fail_urdev_put;958 }959 if (cancel_work_sync(&urd->uevent_work)) {960 /* Work not run yet - need to release reference here */961 urdev_put(urd);962 }963 device_destroy(&vmur_class, urd->char_device->dev);964 cdev_del(urd->char_device);965 urd->char_device = NULL;966 rc = 0;967 968fail_urdev_put:969 urdev_put(urd);970 return rc;971}972 973static int ur_set_offline(struct ccw_device *cdev)974{975 int rc;976 977 mutex_lock(&vmur_mutex);978 rc = ur_set_offline_force(cdev, 0);979 mutex_unlock(&vmur_mutex);980 return rc;981}982 983static void ur_remove(struct ccw_device *cdev)984{985 unsigned long flags;986 987 TRACE("ur_remove\n");988 989 mutex_lock(&vmur_mutex);990 991 if (cdev->online)992 ur_set_offline_force(cdev, 1);993 ur_remove_attributes(&cdev->dev);994 995 spin_lock_irqsave(get_ccwdev_lock(cdev), flags);996 urdev_put(dev_get_drvdata(&cdev->dev));997 dev_set_drvdata(&cdev->dev, NULL);998 cdev->handler = NULL;999 spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);1000 1001 mutex_unlock(&vmur_mutex);1002}1003 1004/*1005 * Module initialisation and cleanup1006 */1007static int __init ur_init(void)1008{1009 int rc;1010 dev_t dev;1011 1012 if (!MACHINE_IS_VM) {1013 pr_err("The %s cannot be loaded without z/VM\n",1014 ur_banner);1015 return -ENODEV;1016 }1017 1018 vmur_dbf = debug_register("vmur", 4, 1, 4 * sizeof(long));1019 if (!vmur_dbf)1020 return -ENOMEM;1021 rc = debug_register_view(vmur_dbf, &debug_sprintf_view);1022 if (rc)1023 goto fail_free_dbf;1024 1025 debug_set_level(vmur_dbf, 6);1026 1027 rc = class_register(&vmur_class);1028 if (rc)1029 goto fail_free_dbf;1030 1031 rc = ccw_driver_register(&ur_driver);1032 if (rc)1033 goto fail_class_destroy;1034 1035 rc = alloc_chrdev_region(&dev, 0, NUM_MINORS, "vmur");1036 if (rc) {1037 pr_err("Kernel function alloc_chrdev_region failed with "1038 "error code %d\n", rc);1039 goto fail_unregister_driver;1040 }1041 ur_first_dev_maj_min = MKDEV(MAJOR(dev), 0);1042 1043 pr_info("%s loaded.\n", ur_banner);1044 return 0;1045 1046fail_unregister_driver:1047 ccw_driver_unregister(&ur_driver);1048fail_class_destroy:1049 class_unregister(&vmur_class);1050fail_free_dbf:1051 debug_unregister(vmur_dbf);1052 return rc;1053}1054 1055static void __exit ur_exit(void)1056{1057 unregister_chrdev_region(ur_first_dev_maj_min, NUM_MINORS);1058 ccw_driver_unregister(&ur_driver);1059 class_unregister(&vmur_class);1060 debug_unregister(vmur_dbf);1061 pr_info("%s unloaded.\n", ur_banner);1062}1063 1064module_init(ur_init);1065module_exit(ur_exit);1066