cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dasd_diag.c (19159B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
      4 * Based on.......: linux/drivers/s390/block/mdisk.c
      5 * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
      6 * Bugreports.to..: <Linux390@de.ibm.com>
      7 * Copyright IBM Corp. 1999, 2000
      8 *
      9 */
     10
     11#define KMSG_COMPONENT "dasd"
     12
     13#include <linux/kernel_stat.h>
     14#include <linux/stddef.h>
     15#include <linux/kernel.h>
     16#include <linux/slab.h>
     17#include <linux/hdreg.h>
     18#include <linux/bio.h>
     19#include <linux/module.h>
     20#include <linux/init.h>
     21#include <linux/jiffies.h>
     22#include <asm/asm-extable.h>
     23#include <asm/dasd.h>
     24#include <asm/debug.h>
     25#include <asm/diag.h>
     26#include <asm/ebcdic.h>
     27#include <asm/io.h>
     28#include <asm/irq.h>
     29#include <asm/vtoc.h>
     30
     31#include "dasd_int.h"
     32#include "dasd_diag.h"
     33
     34#define PRINTK_HEADER "dasd(diag):"
     35
     36MODULE_LICENSE("GPL");
     37
     38/* The maximum number of blocks per request (max_blocks) is dependent on the
     39 * amount of storage that is available in the static I/O buffer for each
     40 * device. Currently each device gets 2 pages. We want to fit two requests
     41 * into the available memory so that we can immediately start the next if one
     42 * finishes. */
     43#define DIAG_MAX_BLOCKS	(((2 * PAGE_SIZE - sizeof(struct dasd_ccw_req) - \
     44			   sizeof(struct dasd_diag_req)) / \
     45		           sizeof(struct dasd_diag_bio)) / 2)
     46#define DIAG_MAX_RETRIES	32
     47#define DIAG_TIMEOUT		50
     48
     49static struct dasd_discipline dasd_diag_discipline;
     50
     51struct dasd_diag_private {
     52	struct dasd_diag_characteristics rdc_data;
     53	struct dasd_diag_rw_io iob;
     54	struct dasd_diag_init_io iib;
     55	blocknum_t pt_block;
     56	struct ccw_dev_id dev_id;
     57};
     58
     59struct dasd_diag_req {
     60	unsigned int block_count;
     61	struct dasd_diag_bio bio[];
     62};
     63
     64static const u8 DASD_DIAG_CMS1[] = { 0xc3, 0xd4, 0xe2, 0xf1 };/* EBCDIC CMS1 */
     65
     66/* Perform DIAG250 call with block I/O parameter list iob (input and output)
     67 * and function code cmd.
     68 * In case of an exception return 3. Otherwise return result of bitwise OR of
     69 * resulting condition code and DIAG return code. */
     70static inline int __dia250(void *iob, int cmd)
     71{
     72	union register_pair rx = { .even = (unsigned long)iob, };
     73	typedef union {
     74		struct dasd_diag_init_io init_io;
     75		struct dasd_diag_rw_io rw_io;
     76	} addr_type;
     77	int cc;
     78
     79	cc = 3;
     80	asm volatile(
     81		"	diag	%[rx],%[cmd],0x250\n"
     82		"0:	ipm	%[cc]\n"
     83		"	srl	%[cc],28\n"
     84		"1:\n"
     85		EX_TABLE(0b,1b)
     86		: [cc] "+&d" (cc), [rx] "+&d" (rx.pair), "+m" (*(addr_type *)iob)
     87		: [cmd] "d" (cmd)
     88		: "cc");
     89	return cc | rx.odd;
     90}
     91
     92static inline int dia250(void *iob, int cmd)
     93{
     94	diag_stat_inc(DIAG_STAT_X250);
     95	return __dia250(iob, cmd);
     96}
     97
     98/* Initialize block I/O to DIAG device using the specified blocksize and
     99 * block offset. On success, return zero and set end_block to contain the
    100 * number of blocks on the device minus the specified offset. Return non-zero
    101 * otherwise. */
    102static inline int
    103mdsk_init_io(struct dasd_device *device, unsigned int blocksize,
    104	     blocknum_t offset, blocknum_t *end_block)
    105{
    106	struct dasd_diag_private *private = device->private;
    107	struct dasd_diag_init_io *iib = &private->iib;
    108	int rc;
    109
    110	memset(iib, 0, sizeof (struct dasd_diag_init_io));
    111
    112	iib->dev_nr = private->dev_id.devno;
    113	iib->block_size = blocksize;
    114	iib->offset = offset;
    115	iib->flaga = DASD_DIAG_FLAGA_DEFAULT;
    116
    117	rc = dia250(iib, INIT_BIO);
    118
    119	if ((rc & 3) == 0 && end_block)
    120		*end_block = iib->end_block;
    121
    122	return rc;
    123}
    124
    125/* Remove block I/O environment for device. Return zero on success, non-zero
    126 * otherwise. */
    127static inline int
    128mdsk_term_io(struct dasd_device * device)
    129{
    130	struct dasd_diag_private *private = device->private;
    131	struct dasd_diag_init_io *iib = &private->iib;
    132	int rc;
    133
    134	memset(iib, 0, sizeof (struct dasd_diag_init_io));
    135	iib->dev_nr = private->dev_id.devno;
    136	rc = dia250(iib, TERM_BIO);
    137	return rc;
    138}
    139
    140/* Error recovery for failed DIAG requests - try to reestablish the DIAG
    141 * environment. */
    142static void
    143dasd_diag_erp(struct dasd_device *device)
    144{
    145	int rc;
    146
    147	mdsk_term_io(device);
    148	rc = mdsk_init_io(device, device->block->bp_block, 0, NULL);
    149	if (rc == 4) {
    150		if (!(test_and_set_bit(DASD_FLAG_DEVICE_RO, &device->flags)))
    151			pr_warn("%s: The access mode of a DIAG device changed to read-only\n",
    152				dev_name(&device->cdev->dev));
    153		rc = 0;
    154	}
    155	if (rc)
    156		pr_warn("%s: DIAG ERP failed with rc=%d\n",
    157			dev_name(&device->cdev->dev), rc);
    158}
    159
    160/* Start a given request at the device. Return zero on success, non-zero
    161 * otherwise. */
    162static int
    163dasd_start_diag(struct dasd_ccw_req * cqr)
    164{
    165	struct dasd_device *device;
    166	struct dasd_diag_private *private;
    167	struct dasd_diag_req *dreq;
    168	int rc;
    169
    170	device = cqr->startdev;
    171	if (cqr->retries < 0) {
    172		DBF_DEV_EVENT(DBF_ERR, device, "DIAG start_IO: request %p "
    173			    "- no retry left)", cqr);
    174		cqr->status = DASD_CQR_ERROR;
    175		return -EIO;
    176	}
    177	private = device->private;
    178	dreq = cqr->data;
    179
    180	private->iob.dev_nr = private->dev_id.devno;
    181	private->iob.key = 0;
    182	private->iob.flags = DASD_DIAG_RWFLAG_ASYNC;
    183	private->iob.block_count = dreq->block_count;
    184	private->iob.interrupt_params = (addr_t) cqr;
    185	private->iob.bio_list = dreq->bio;
    186	private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
    187
    188	cqr->startclk = get_tod_clock();
    189	cqr->starttime = jiffies;
    190	cqr->retries--;
    191
    192	rc = dia250(&private->iob, RW_BIO);
    193	switch (rc) {
    194	case 0: /* Synchronous I/O finished successfully */
    195		cqr->stopclk = get_tod_clock();
    196		cqr->status = DASD_CQR_SUCCESS;
    197		/* Indicate to calling function that only a dasd_schedule_bh()
    198		   and no timer is needed */
    199                rc = -EACCES;
    200		break;
    201	case 8: /* Asynchronous I/O was started */
    202		cqr->status = DASD_CQR_IN_IO;
    203		rc = 0;
    204		break;
    205	default: /* Error condition */
    206		cqr->status = DASD_CQR_QUEUED;
    207		DBF_DEV_EVENT(DBF_WARNING, device, "dia250 returned rc=%d", rc);
    208		dasd_diag_erp(device);
    209		rc = -EIO;
    210		break;
    211	}
    212	cqr->intrc = rc;
    213	return rc;
    214}
    215
    216/* Terminate given request at the device. */
    217static int
    218dasd_diag_term_IO(struct dasd_ccw_req * cqr)
    219{
    220	struct dasd_device *device;
    221
    222	device = cqr->startdev;
    223	mdsk_term_io(device);
    224	mdsk_init_io(device, device->block->bp_block, 0, NULL);
    225	cqr->status = DASD_CQR_CLEAR_PENDING;
    226	cqr->stopclk = get_tod_clock();
    227	dasd_schedule_device_bh(device);
    228	return 0;
    229}
    230
    231/* Handle external interruption. */
    232static void dasd_ext_handler(struct ext_code ext_code,
    233			     unsigned int param32, unsigned long param64)
    234{
    235	struct dasd_ccw_req *cqr, *next;
    236	struct dasd_device *device;
    237	unsigned long expires;
    238	unsigned long flags;
    239	addr_t ip;
    240	int rc;
    241
    242	switch (ext_code.subcode >> 8) {
    243	case DASD_DIAG_CODE_31BIT:
    244		ip = (addr_t) param32;
    245		break;
    246	case DASD_DIAG_CODE_64BIT:
    247		ip = (addr_t) param64;
    248		break;
    249	default:
    250		return;
    251	}
    252	inc_irq_stat(IRQEXT_DSD);
    253	if (!ip) {		/* no intparm: unsolicited interrupt */
    254		DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited "
    255			      "interrupt");
    256		return;
    257	}
    258	cqr = (struct dasd_ccw_req *) ip;
    259	device = (struct dasd_device *) cqr->startdev;
    260	if (strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) {
    261		DBF_DEV_EVENT(DBF_WARNING, device,
    262			    " magic number of dasd_ccw_req 0x%08X doesn't"
    263			    " match discipline 0x%08X",
    264			    cqr->magic, *(int *) (&device->discipline->name));
    265		return;
    266	}
    267
    268	/* get irq lock to modify request queue */
    269	spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
    270
    271	/* Check for a pending clear operation */
    272	if (cqr->status == DASD_CQR_CLEAR_PENDING) {
    273		cqr->status = DASD_CQR_CLEARED;
    274		dasd_device_clear_timer(device);
    275		dasd_schedule_device_bh(device);
    276		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
    277		return;
    278	}
    279
    280	cqr->stopclk = get_tod_clock();
    281
    282	expires = 0;
    283	if ((ext_code.subcode & 0xff) == 0) {
    284		cqr->status = DASD_CQR_SUCCESS;
    285		/* Start first request on queue if possible -> fast_io. */
    286		if (!list_empty(&device->ccw_queue)) {
    287			next = list_entry(device->ccw_queue.next,
    288					  struct dasd_ccw_req, devlist);
    289			if (next->status == DASD_CQR_QUEUED) {
    290				rc = dasd_start_diag(next);
    291				if (rc == 0)
    292					expires = next->expires;
    293			}
    294		}
    295	} else {
    296		cqr->status = DASD_CQR_QUEUED;
    297		DBF_DEV_EVENT(DBF_DEBUG, device, "interrupt status for "
    298			      "request %p was %d (%d retries left)", cqr,
    299			      ext_code.subcode & 0xff, cqr->retries);
    300		dasd_diag_erp(device);
    301	}
    302
    303	if (expires != 0)
    304		dasd_device_set_timer(device, expires);
    305	else
    306		dasd_device_clear_timer(device);
    307	dasd_schedule_device_bh(device);
    308
    309	spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
    310}
    311
    312/* Check whether device can be controlled by DIAG discipline. Return zero on
    313 * success, non-zero otherwise. */
    314static int
    315dasd_diag_check_device(struct dasd_device *device)
    316{
    317	struct dasd_diag_private *private = device->private;
    318	struct dasd_diag_characteristics *rdc_data;
    319	struct vtoc_cms_label *label;
    320	struct dasd_block *block;
    321	struct dasd_diag_bio *bio;
    322	unsigned int sb, bsize;
    323	blocknum_t end_block;
    324	int rc;
    325
    326	if (private == NULL) {
    327		private = kzalloc(sizeof(*private), GFP_KERNEL);
    328		if (private == NULL) {
    329			DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    330				"Allocating memory for private DASD data "
    331				      "failed\n");
    332			return -ENOMEM;
    333		}
    334		ccw_device_get_id(device->cdev, &private->dev_id);
    335		device->private = private;
    336	}
    337	block = dasd_alloc_block();
    338	if (IS_ERR(block)) {
    339		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    340			    "could not allocate dasd block structure");
    341		device->private = NULL;
    342		kfree(private);
    343		return PTR_ERR(block);
    344	}
    345	device->block = block;
    346	block->base = device;
    347
    348	/* Read Device Characteristics */
    349	rdc_data = &private->rdc_data;
    350	rdc_data->dev_nr = private->dev_id.devno;
    351	rdc_data->rdc_len = sizeof (struct dasd_diag_characteristics);
    352
    353	rc = diag210((struct diag210 *) rdc_data);
    354	if (rc) {
    355		DBF_DEV_EVENT(DBF_WARNING, device, "failed to retrieve device "
    356			    "information (rc=%d)", rc);
    357		rc = -EOPNOTSUPP;
    358		goto out;
    359	}
    360
    361	device->default_expires = DIAG_TIMEOUT;
    362	device->default_retries = DIAG_MAX_RETRIES;
    363
    364	/* Figure out position of label block */
    365	switch (private->rdc_data.vdev_class) {
    366	case DEV_CLASS_FBA:
    367		private->pt_block = 1;
    368		break;
    369	case DEV_CLASS_ECKD:
    370		private->pt_block = 2;
    371		break;
    372	default:
    373		pr_warn("%s: Device type %d is not supported in DIAG mode\n",
    374			dev_name(&device->cdev->dev),
    375			private->rdc_data.vdev_class);
    376		rc = -EOPNOTSUPP;
    377		goto out;
    378	}
    379
    380	DBF_DEV_EVENT(DBF_INFO, device,
    381		      "%04X: %04X on real %04X/%02X",
    382		      rdc_data->dev_nr,
    383		      rdc_data->vdev_type,
    384		      rdc_data->rdev_type, rdc_data->rdev_model);
    385
    386	/* terminate all outstanding operations */
    387	mdsk_term_io(device);
    388
    389	/* figure out blocksize of device */
    390	label = (struct vtoc_cms_label *) get_zeroed_page(GFP_KERNEL);
    391	if (label == NULL)  {
    392		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    393			    "No memory to allocate initialization request");
    394		rc = -ENOMEM;
    395		goto out;
    396	}
    397	bio = kzalloc(sizeof(*bio), GFP_KERNEL);
    398	if (bio == NULL)  {
    399		DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    400			      "No memory to allocate initialization bio");
    401		rc = -ENOMEM;
    402		goto out_label;
    403	}
    404	rc = 0;
    405	end_block = 0;
    406	/* try all sizes - needed for ECKD devices */
    407	for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
    408		mdsk_init_io(device, bsize, 0, &end_block);
    409		memset(bio, 0, sizeof(*bio));
    410		bio->type = MDSK_READ_REQ;
    411		bio->block_number = private->pt_block + 1;
    412		bio->buffer = label;
    413		memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io));
    414		private->iob.dev_nr = rdc_data->dev_nr;
    415		private->iob.key = 0;
    416		private->iob.flags = 0;	/* do synchronous io */
    417		private->iob.block_count = 1;
    418		private->iob.interrupt_params = 0;
    419		private->iob.bio_list = bio;
    420		private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT;
    421		rc = dia250(&private->iob, RW_BIO);
    422		if (rc == 3) {
    423			pr_warn("%s: A 64-bit DIAG call failed\n",
    424				dev_name(&device->cdev->dev));
    425			rc = -EOPNOTSUPP;
    426			goto out_bio;
    427		}
    428		mdsk_term_io(device);
    429		if (rc == 0)
    430			break;
    431	}
    432	if (bsize > PAGE_SIZE) {
    433		pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n",
    434			dev_name(&device->cdev->dev), rc);
    435		rc = -EIO;
    436		goto out_bio;
    437	}
    438	/* check for label block */
    439	if (memcmp(label->label_id, DASD_DIAG_CMS1,
    440		  sizeof(DASD_DIAG_CMS1)) == 0) {
    441		/* get formatted blocksize from label block */
    442		bsize = (unsigned int) label->block_size;
    443		block->blocks = (unsigned long) label->block_count;
    444	} else
    445		block->blocks = end_block;
    446	block->bp_block = bsize;
    447	block->s2b_shift = 0;	/* bits to shift 512 to get a block */
    448	for (sb = 512; sb < bsize; sb = sb << 1)
    449		block->s2b_shift++;
    450	rc = mdsk_init_io(device, block->bp_block, 0, NULL);
    451	if (rc && (rc != 4)) {
    452		pr_warn("%s: DIAG initialization failed with rc=%d\n",
    453			dev_name(&device->cdev->dev), rc);
    454		rc = -EIO;
    455	} else {
    456		if (rc == 4)
    457			set_bit(DASD_FLAG_DEVICE_RO, &device->flags);
    458		pr_info("%s: New DASD with %ld byte/block, total size %ld "
    459			"KB%s\n", dev_name(&device->cdev->dev),
    460			(unsigned long) block->bp_block,
    461			(unsigned long) (block->blocks <<
    462					 block->s2b_shift) >> 1,
    463			(rc == 4) ? ", read-only device" : "");
    464		rc = 0;
    465	}
    466out_bio:
    467	kfree(bio);
    468out_label:
    469	free_page((long) label);
    470out:
    471	if (rc) {
    472		device->block = NULL;
    473		dasd_free_block(block);
    474		device->private = NULL;
    475		kfree(private);
    476	}
    477	return rc;
    478}
    479
    480/* Fill in virtual disk geometry for device. Return zero on success, non-zero
    481 * otherwise. */
    482static int
    483dasd_diag_fill_geometry(struct dasd_block *block, struct hd_geometry *geo)
    484{
    485	if (dasd_check_blocksize(block->bp_block) != 0)
    486		return -EINVAL;
    487	geo->cylinders = (block->blocks << block->s2b_shift) >> 10;
    488	geo->heads = 16;
    489	geo->sectors = 128 >> block->s2b_shift;
    490	return 0;
    491}
    492
    493static dasd_erp_fn_t
    494dasd_diag_erp_action(struct dasd_ccw_req * cqr)
    495{
    496	return dasd_default_erp_action;
    497}
    498
    499static dasd_erp_fn_t
    500dasd_diag_erp_postaction(struct dasd_ccw_req * cqr)
    501{
    502	return dasd_default_erp_postaction;
    503}
    504
    505/* Create DASD request from block device request. Return pointer to new
    506 * request on success, ERR_PTR otherwise. */
    507static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
    508					       struct dasd_block *block,
    509					       struct request *req)
    510{
    511	struct dasd_ccw_req *cqr;
    512	struct dasd_diag_req *dreq;
    513	struct dasd_diag_bio *dbio;
    514	struct req_iterator iter;
    515	struct bio_vec bv;
    516	char *dst;
    517	unsigned int count;
    518	sector_t recid, first_rec, last_rec;
    519	unsigned int blksize, off;
    520	unsigned char rw_cmd;
    521
    522	if (rq_data_dir(req) == READ)
    523		rw_cmd = MDSK_READ_REQ;
    524	else if (rq_data_dir(req) == WRITE)
    525		rw_cmd = MDSK_WRITE_REQ;
    526	else
    527		return ERR_PTR(-EINVAL);
    528	blksize = block->bp_block;
    529	/* Calculate record id of first and last block. */
    530	first_rec = blk_rq_pos(req) >> block->s2b_shift;
    531	last_rec =
    532		(blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;
    533	/* Check struct bio and count the number of blocks for the request. */
    534	count = 0;
    535	rq_for_each_segment(bv, req, iter) {
    536		if (bv.bv_len & (blksize - 1))
    537			/* Fba can only do full blocks. */
    538			return ERR_PTR(-EINVAL);
    539		count += bv.bv_len >> (block->s2b_shift + 9);
    540	}
    541	/* Paranoia. */
    542	if (count != last_rec - first_rec + 1)
    543		return ERR_PTR(-EINVAL);
    544	/* Build the request */
    545	cqr = dasd_smalloc_request(DASD_DIAG_MAGIC, 0, struct_size(dreq, bio, count),
    546				   memdev, blk_mq_rq_to_pdu(req));
    547	if (IS_ERR(cqr))
    548		return cqr;
    549
    550	dreq = (struct dasd_diag_req *) cqr->data;
    551	dreq->block_count = count;
    552	dbio = dreq->bio;
    553	recid = first_rec;
    554	rq_for_each_segment(bv, req, iter) {
    555		dst = bvec_virt(&bv);
    556		for (off = 0; off < bv.bv_len; off += blksize) {
    557			memset(dbio, 0, sizeof (struct dasd_diag_bio));
    558			dbio->type = rw_cmd;
    559			dbio->block_number = recid + 1;
    560			dbio->buffer = dst;
    561			dbio++;
    562			dst += blksize;
    563			recid++;
    564		}
    565	}
    566	cqr->retries = memdev->default_retries;
    567	cqr->buildclk = get_tod_clock();
    568	if (blk_noretry_request(req) ||
    569	    block->base->features & DASD_FEATURE_FAILFAST)
    570		set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
    571	cqr->startdev = memdev;
    572	cqr->memdev = memdev;
    573	cqr->block = block;
    574	cqr->expires = memdev->default_expires * HZ;
    575	cqr->status = DASD_CQR_FILLED;
    576	return cqr;
    577}
    578
    579/* Release DASD request. Return non-zero if request was successful, zero
    580 * otherwise. */
    581static int
    582dasd_diag_free_cp(struct dasd_ccw_req *cqr, struct request *req)
    583{
    584	int status;
    585
    586	status = cqr->status == DASD_CQR_DONE;
    587	dasd_sfree_request(cqr, cqr->memdev);
    588	return status;
    589}
    590
    591static void dasd_diag_handle_terminated_request(struct dasd_ccw_req *cqr)
    592{
    593	if (cqr->retries < 0)
    594		cqr->status = DASD_CQR_FAILED;
    595	else
    596		cqr->status = DASD_CQR_FILLED;
    597};
    598
    599/* Fill in IOCTL data for device. */
    600static int
    601dasd_diag_fill_info(struct dasd_device * device,
    602		    struct dasd_information2_t * info)
    603{
    604	struct dasd_diag_private *private = device->private;
    605
    606	info->label_block = (unsigned int) private->pt_block;
    607	info->FBA_layout = 1;
    608	info->format = DASD_FORMAT_LDL;
    609	info->characteristics_size = sizeof(private->rdc_data);
    610	memcpy(info->characteristics, &private->rdc_data,
    611	       sizeof(private->rdc_data));
    612	info->confdata_size = 0;
    613	return 0;
    614}
    615
    616static void
    617dasd_diag_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
    618		     struct irb *stat)
    619{
    620	DBF_DEV_EVENT(DBF_WARNING, device, "%s",
    621		    "dump sense not available for DIAG data");
    622}
    623
    624/*
    625 * Initialize block layer request queue.
    626 */
    627static void dasd_diag_setup_blk_queue(struct dasd_block *block)
    628{
    629	unsigned int logical_block_size = block->bp_block;
    630	struct request_queue *q = block->request_queue;
    631	int max;
    632
    633	max = DIAG_MAX_BLOCKS << block->s2b_shift;
    634	blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
    635	q->limits.max_dev_sectors = max;
    636	blk_queue_logical_block_size(q, logical_block_size);
    637	blk_queue_max_hw_sectors(q, max);
    638	blk_queue_max_segments(q, USHRT_MAX);
    639	/* With page sized segments each segment can be translated into one idaw/tidaw */
    640	blk_queue_max_segment_size(q, PAGE_SIZE);
    641	blk_queue_segment_boundary(q, PAGE_SIZE - 1);
    642}
    643
    644static int dasd_diag_pe_handler(struct dasd_device *device,
    645				__u8 tbvpm, __u8 fcsecpm)
    646{
    647	return dasd_generic_verify_path(device, tbvpm);
    648}
    649
    650static struct dasd_discipline dasd_diag_discipline = {
    651	.owner = THIS_MODULE,
    652	.name = "DIAG",
    653	.ebcname = "DIAG",
    654	.check_device = dasd_diag_check_device,
    655	.pe_handler = dasd_diag_pe_handler,
    656	.fill_geometry = dasd_diag_fill_geometry,
    657	.setup_blk_queue = dasd_diag_setup_blk_queue,
    658	.start_IO = dasd_start_diag,
    659	.term_IO = dasd_diag_term_IO,
    660	.handle_terminated_request = dasd_diag_handle_terminated_request,
    661	.erp_action = dasd_diag_erp_action,
    662	.erp_postaction = dasd_diag_erp_postaction,
    663	.build_cp = dasd_diag_build_cp,
    664	.free_cp = dasd_diag_free_cp,
    665	.dump_sense = dasd_diag_dump_sense,
    666	.fill_info = dasd_diag_fill_info,
    667};
    668
    669static int __init
    670dasd_diag_init(void)
    671{
    672	if (!MACHINE_IS_VM) {
    673		pr_info("Discipline %s cannot be used without z/VM\n",
    674			dasd_diag_discipline.name);
    675		return -ENODEV;
    676	}
    677	ASCEBC(dasd_diag_discipline.ebcname, 4);
    678
    679	irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL);
    680	register_external_irq(EXT_IRQ_CP_SERVICE, dasd_ext_handler);
    681	dasd_diag_discipline_pointer = &dasd_diag_discipline;
    682	return 0;
    683}
    684
    685static void __exit
    686dasd_diag_cleanup(void)
    687{
    688	unregister_external_irq(EXT_IRQ_CP_SERVICE, dasd_ext_handler);
    689	irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL);
    690	dasd_diag_discipline_pointer = NULL;
    691}
    692
    693module_init(dasd_diag_init);
    694module_exit(dasd_diag_cleanup);