brintos

brintos / linux-shallow public Read only

0
0
Text · 23.9 KiB · fe94dec Raw
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