if (count < blksize)
if (count < blksize && rq_data_dir(req) == READ)
dasd_eckd_build_cp(struct dasd_device * device, struct request *req){	struct dasd_eckd_private *private;	unsigned long *idaws;	struct LO_eckd_data *LO_data;	struct dasd_ccw_req *cqr;	struct ccw1 *ccw;	struct bio *bio;	struct bio_vec *bv;	char *dst;	unsigned int blksize, blk_per_trk, off;	int count, cidaw, cplength, datasize;	sector_t recid, first_rec, last_rec;	sector_t first_trk, last_trk;	unsigned int first_offs, last_offs;	unsigned char cmd, rcmd;	int i;	private = (struct dasd_eckd_private *) device->private;	if (rq_data_dir(req) == READ)		cmd = DASD_ECKD_CCW_READ_MT;	else if (rq_data_dir(req) == WRITE)		cmd = DASD_ECKD_CCW_WRITE_MT;	else		return ERR_PTR(-EINVAL);	/* Calculate number of blocks/records per track. */	blksize = device->bp_block;	blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);	/* Calculate record id of first and last block. */	first_rec = first_trk = req->sector >> device->s2b_shift;	first_offs = sector_div(first_trk, blk_per_trk);	last_rec = last_trk =		(req->sector + req->nr_sectors - 1) >> device->s2b_shift;	last_offs = sector_div(last_trk, blk_per_trk);	/* Check struct bio and count the number of blocks for the request. */	count = 0;	cidaw = 0;	rq_for_each_bio(bio, req) {		bio_for_each_segment(bv, bio, i) {			if (bv->bv_len & (blksize - 1))				/* Eckd can only do full blocks. */				return ERR_PTR(-EINVAL);			count += bv->bv_len >> (device->s2b_shift + 9);#if defined(CONFIG_ARCH_S390X)			if (idal_is_needed (page_address(bv->bv_page),					    bv->bv_len))				cidaw += bv->bv_len >> (device->s2b_shift + 9);#endif		}	}	/* Paranoia. */	if (count != last_rec - first_rec + 1)		return ERR_PTR(-EINVAL);	/* 1x define extent + 1x locate record + number of blocks */	cplength = 2 + count;	/* 1x define extent + 1x locate record + cidaws*sizeof(long) */	datasize = sizeof(struct DE_eckd_data) + sizeof(struct LO_eckd_data) +		cidaw * sizeof(unsigned long);	/* Find out the number of additional locate record ccws for cdl. */	if (private->uses_cdl && first_rec < 2*blk_per_trk) {		if (last_rec >= 2*blk_per_trk)			count = 2*blk_per_trk - first_rec;		cplength += count;		datasize += count*sizeof(struct LO_eckd_data);	}	/* Allocate the ccw request. */	cqr = dasd_smalloc_request(dasd_eckd_discipline.name,				   cplength, datasize, device);	if (IS_ERR(cqr))		return cqr;	ccw = cqr->cpaddr;	/* First ccw is define extent. */	define_extent(ccw++, cqr->data, first_trk, last_trk, cmd, device);	/* Build locate_record+read/write/ccws. */	idaws = (unsigned long *) (cqr->data + sizeof(struct DE_eckd_data));	LO_data = (struct LO_eckd_data *) (idaws + cidaw);	recid = first_rec;	if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {		/* Only standard blocks so there is just one locate record. */		ccw[-1].flags |= CCW_FLAG_CC;		locate_record(ccw++, LO_data++, first_trk, first_offs + 1,			      last_rec - recid + 1, cmd, device, blksize);	}	rq_for_each_bio(bio, req) bio_for_each_segment(bv, bio, i) {		dst = page_address(bv->bv_page) + bv->bv_offset;		if (dasd_page_cache) {			char *copy = kmem_cache_alloc(dasd_page_cache,						      SLAB_DMA | __GFP_NOWARN);			if (copy && rq_data_dir(req) == WRITE)				memcpy(copy + bv->bv_offset, dst, bv->bv_len);			if (copy)				dst = copy + bv->bv_offset;		}		for (off = 0; off < bv->bv_len; off += blksize) {			sector_t trkid = recid;			unsigned int recoffs = sector_div(trkid, blk_per_trk);			rcmd = cmd;			count = blksize;			/* Locate record for cdl special block ? */			if (private->uses_cdl && recid < 2*blk_per_trk) {				if (dasd_eckd_cdl_special(blk_per_trk, recid)){					rcmd |= 0x8;					count = dasd_eckd_cdl_reclen(recid);					if (count < blksize)						memset(dst + count, 0xe5,						       blksize - count);				}				ccw[-1].flags |= CCW_FLAG_CC;				locate_record(ccw++, LO_data++,					      trkid, recoffs + 1,					      1, rcmd, device, count);			}			/* Locate record for standard blocks ? */			if (private->uses_cdl && recid == 2*blk_per_trk) {				ccw[-1].flags |= CCW_FLAG_CC;				locate_record(ccw++, LO_data++,					      trkid, recoffs + 1,					      last_rec - recid + 1,					      cmd, device, count);			}			/* Read/write ccw. */			ccw[-1].flags |= CCW_FLAG_CC;			ccw->cmd_code = rcmd;			ccw->count = count;			if (idal_is_needed(dst, blksize)) {				ccw->cda = (__u32)(addr_t) idaws;				ccw->flags = CCW_FLAG_IDA;				idaws = idal_create_words(idaws, dst, blksize);			} else {				ccw->cda = (__u32)(addr_t) dst;				ccw->flags = 0;			}			ccw++;			dst += blksize;			recid++;		}	}	cqr->device = device;	cqr->expires = 5 * 60 * HZ;	/* 5 minutes */	cqr->lpm = private->path_data.ppm;	cqr->retries = 256;	cqr->buildclk = get_clock();	cqr->status = DASD_CQR_FILLED;	return cqr;}