6964 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>4 * Horst Hummel <Horst.Hummel@de.ibm.com>5 * Carsten Otte <Cotte@de.ibm.com>6 * Martin Schwidefsky <schwidefsky@de.ibm.com>7 * Bugreports.to..: <Linux390@de.ibm.com>8 * Copyright IBM Corp. 1999, 20099 * EMC Symmetrix ioctl Copyright EMC Corporation, 200810 * Author.........: Nigel Hislop <hislop_nigel@emc.com>11 */12 13#include <linux/stddef.h>14#include <linux/kernel.h>15#include <linux/slab.h>16#include <linux/hdreg.h> /* HDIO_GETGEO */17#include <linux/bio.h>18#include <linux/module.h>19#include <linux/compat.h>20#include <linux/init.h>21#include <linux/seq_file.h>22#include <linux/uaccess.h>23#include <linux/io.h>24 25#include <asm/css_chars.h>26#include <asm/debug.h>27#include <asm/idals.h>28#include <asm/ebcdic.h>29#include <asm/cio.h>30#include <asm/ccwdev.h>31#include <asm/itcw.h>32#include <asm/schid.h>33#include <asm/chpid.h>34 35#include "dasd_int.h"36#include "dasd_eckd.h"37 38/*39 * raw track access always map to 64k in memory40 * so it maps to 16 blocks of 4k per track41 */42#define DASD_RAW_BLOCK_PER_TRACK 1643#define DASD_RAW_BLOCKSIZE 409644/* 64k are 128 x 512 byte sectors */45#define DASD_RAW_SECTORS_PER_TRACK 12846 47MODULE_DESCRIPTION("S/390 DASD ECKD Disks device driver");48MODULE_LICENSE("GPL");49 50static struct dasd_discipline dasd_eckd_discipline;51 52/* The ccw bus type uses this table to find devices that it sends to53 * dasd_eckd_probe */54static struct ccw_device_id dasd_eckd_ids[] = {55 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3390, 0), .driver_info = 0x1},56 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3390, 0), .driver_info = 0x2},57 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3380, 0), .driver_info = 0x3},58 { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), .driver_info = 0x4},59 { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), .driver_info = 0x5},60 { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), .driver_info = 0x6},61 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), .driver_info = 0x7},62 { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), .driver_info = 0x8},63 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), .driver_info = 0x9},64 { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), .driver_info = 0xa},65 { /* end of list */ },66};67 68MODULE_DEVICE_TABLE(ccw, dasd_eckd_ids);69 70static struct ccw_driver dasd_eckd_driver; /* see below */71 72static void *rawpadpage;73 74#define INIT_CQR_OK 075#define INIT_CQR_UNFORMATTED 176#define INIT_CQR_ERROR 277 78/* emergency request for reserve/release */79static struct {80 struct dasd_ccw_req cqr;81 struct ccw1 ccw;82 char data[32];83} *dasd_reserve_req;84static DEFINE_MUTEX(dasd_reserve_mutex);85 86static struct {87 struct dasd_ccw_req cqr;88 struct ccw1 ccw[2];89 char data[40];90} *dasd_vol_info_req;91static DEFINE_MUTEX(dasd_vol_info_mutex);92 93struct ext_pool_exhaust_work_data {94 struct work_struct worker;95 struct dasd_device *device;96 struct dasd_device *base;97};98 99/* definitions for the path verification worker */100struct pe_handler_work_data {101 struct work_struct worker;102 struct dasd_device *device;103 struct dasd_ccw_req cqr;104 struct ccw1 ccw;105 __u8 rcd_buffer[DASD_ECKD_RCD_DATA_SIZE];106 int isglobal;107 __u8 tbvpm;108 __u8 fcsecpm;109};110static struct pe_handler_work_data *pe_handler_worker;111static DEFINE_MUTEX(dasd_pe_handler_mutex);112 113struct check_attention_work_data {114 struct work_struct worker;115 struct dasd_device *device;116 __u8 lpum;117};118 119static int dasd_eckd_ext_pool_id(struct dasd_device *);120static int prepare_itcw(struct itcw *, unsigned int, unsigned int, int,121 struct dasd_device *, struct dasd_device *,122 unsigned int, int, unsigned int, unsigned int,123 unsigned int, unsigned int);124static int dasd_eckd_query_pprc_status(struct dasd_device *,125 struct dasd_pprc_data_sc4 *);126 127/* initial attempt at a probe function. this can be simplified once128 * the other detection code is gone */129static int130dasd_eckd_probe (struct ccw_device *cdev)131{132 int ret;133 134 /* set ECKD specific ccw-device options */135 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE |136 CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH);137 if (ret) {138 DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s",139 "dasd_eckd_probe: could not set "140 "ccw-device options");141 return ret;142 }143 ret = dasd_generic_probe(cdev);144 return ret;145}146 147static int148dasd_eckd_set_online(struct ccw_device *cdev)149{150 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);151}152 153static const int sizes_trk0[] = { 28, 148, 84 };154#define LABEL_SIZE 140155 156/* head and record addresses of count_area read in analysis ccw */157static const int count_area_head[] = { 0, 0, 0, 0, 1 };158static const int count_area_rec[] = { 1, 2, 3, 4, 1 };159 160static inline unsigned int161ceil_quot(unsigned int d1, unsigned int d2)162{163 return (d1 + (d2 - 1)) / d2;164}165 166static unsigned int167recs_per_track(struct dasd_eckd_characteristics * rdc,168 unsigned int kl, unsigned int dl)169{170 int dn, kn;171 172 switch (rdc->dev_type) {173 case 0x3380:174 if (kl)175 return 1499 / (15 + 7 + ceil_quot(kl + 12, 32) +176 ceil_quot(dl + 12, 32));177 else178 return 1499 / (15 + ceil_quot(dl + 12, 32));179 case 0x3390:180 dn = ceil_quot(dl + 6, 232) + 1;181 if (kl) {182 kn = ceil_quot(kl + 6, 232) + 1;183 return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +184 9 + ceil_quot(dl + 6 * dn, 34));185 } else186 return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));187 case 0x9345:188 dn = ceil_quot(dl + 6, 232) + 1;189 if (kl) {190 kn = ceil_quot(kl + 6, 232) + 1;191 return 1420 / (18 + 7 + ceil_quot(kl + 6 * kn, 34) +192 ceil_quot(dl + 6 * dn, 34));193 } else194 return 1420 / (18 + 7 + ceil_quot(dl + 6 * dn, 34));195 }196 return 0;197}198 199static void set_ch_t(struct ch_t *geo, __u32 cyl, __u8 head)200{201 geo->cyl = (__u16) cyl;202 geo->head = cyl >> 16;203 geo->head <<= 4;204 geo->head |= head;205}206 207/*208 * calculate failing track from sense data depending if209 * it is an EAV device or not210 */211static int dasd_eckd_track_from_irb(struct irb *irb, struct dasd_device *device,212 sector_t *track)213{214 struct dasd_eckd_private *private = device->private;215 u8 *sense = NULL;216 u32 cyl;217 u8 head;218 219 sense = dasd_get_sense(irb);220 if (!sense) {221 DBF_DEV_EVENT(DBF_WARNING, device, "%s",222 "ESE error no sense data\n");223 return -EINVAL;224 }225 if (!(sense[27] & DASD_SENSE_BIT_2)) {226 DBF_DEV_EVENT(DBF_WARNING, device, "%s",227 "ESE error no valid track data\n");228 return -EINVAL;229 }230 231 if (sense[27] & DASD_SENSE_BIT_3) {232 /* enhanced addressing */233 cyl = sense[30] << 20;234 cyl |= (sense[31] & 0xF0) << 12;235 cyl |= sense[28] << 8;236 cyl |= sense[29];237 } else {238 cyl = sense[29] << 8;239 cyl |= sense[30];240 }241 head = sense[31] & 0x0F;242 *track = cyl * private->rdc_data.trk_per_cyl + head;243 return 0;244}245 246static int set_timestamp(struct ccw1 *ccw, struct DE_eckd_data *data,247 struct dasd_device *device)248{249 struct dasd_eckd_private *private = device->private;250 int rc;251 252 rc = get_phys_clock(&data->ep_sys_time);253 /*254 * Ignore return code if XRC is not supported or255 * sync clock is switched off256 */257 if ((rc && !private->rdc_data.facilities.XRC_supported) ||258 rc == -EOPNOTSUPP || rc == -EACCES)259 return 0;260 261 /* switch on System Time Stamp - needed for XRC Support */262 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */263 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */264 265 if (ccw) {266 ccw->count = sizeof(struct DE_eckd_data);267 ccw->flags |= CCW_FLAG_SLI;268 }269 270 return rc;271}272 273static int274define_extent(struct ccw1 *ccw, struct DE_eckd_data *data, unsigned int trk,275 unsigned int totrk, int cmd, struct dasd_device *device,276 int blksize)277{278 struct dasd_eckd_private *private = device->private;279 u16 heads, beghead, endhead;280 u32 begcyl, endcyl;281 int rc = 0;282 283 if (ccw) {284 ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;285 ccw->flags = 0;286 ccw->count = 16;287 ccw->cda = virt_to_dma32(data);288 }289 290 memset(data, 0, sizeof(struct DE_eckd_data));291 switch (cmd) {292 case DASD_ECKD_CCW_READ_HOME_ADDRESS:293 case DASD_ECKD_CCW_READ_RECORD_ZERO:294 case DASD_ECKD_CCW_READ:295 case DASD_ECKD_CCW_READ_MT:296 case DASD_ECKD_CCW_READ_CKD:297 case DASD_ECKD_CCW_READ_CKD_MT:298 case DASD_ECKD_CCW_READ_KD:299 case DASD_ECKD_CCW_READ_KD_MT:300 data->mask.perm = 0x1;301 data->attributes.operation = private->attrib.operation;302 break;303 case DASD_ECKD_CCW_READ_COUNT:304 data->mask.perm = 0x1;305 data->attributes.operation = DASD_BYPASS_CACHE;306 break;307 case DASD_ECKD_CCW_READ_TRACK:308 case DASD_ECKD_CCW_READ_TRACK_DATA:309 data->mask.perm = 0x1;310 data->attributes.operation = private->attrib.operation;311 data->blk_size = 0;312 break;313 case DASD_ECKD_CCW_WRITE:314 case DASD_ECKD_CCW_WRITE_MT:315 case DASD_ECKD_CCW_WRITE_KD:316 case DASD_ECKD_CCW_WRITE_KD_MT:317 data->mask.perm = 0x02;318 data->attributes.operation = private->attrib.operation;319 rc = set_timestamp(ccw, data, device);320 break;321 case DASD_ECKD_CCW_WRITE_CKD:322 case DASD_ECKD_CCW_WRITE_CKD_MT:323 data->attributes.operation = DASD_BYPASS_CACHE;324 rc = set_timestamp(ccw, data, device);325 break;326 case DASD_ECKD_CCW_ERASE:327 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:328 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:329 data->mask.perm = 0x3;330 data->mask.auth = 0x1;331 data->attributes.operation = DASD_BYPASS_CACHE;332 rc = set_timestamp(ccw, data, device);333 break;334 case DASD_ECKD_CCW_WRITE_FULL_TRACK:335 data->mask.perm = 0x03;336 data->attributes.operation = private->attrib.operation;337 data->blk_size = 0;338 break;339 case DASD_ECKD_CCW_WRITE_TRACK_DATA:340 data->mask.perm = 0x02;341 data->attributes.operation = private->attrib.operation;342 data->blk_size = blksize;343 rc = set_timestamp(ccw, data, device);344 break;345 default:346 dev_err(&device->cdev->dev,347 "0x%x is not a known command\n", cmd);348 break;349 }350 351 data->attributes.mode = 0x3; /* ECKD */352 353 if ((private->rdc_data.cu_type == 0x2105 ||354 private->rdc_data.cu_type == 0x2107 ||355 private->rdc_data.cu_type == 0x1750)356 && !(private->uses_cdl && trk < 2))357 data->ga_extended |= 0x40; /* Regular Data Format Mode */358 359 heads = private->rdc_data.trk_per_cyl;360 begcyl = trk / heads;361 beghead = trk % heads;362 endcyl = totrk / heads;363 endhead = totrk % heads;364 365 /* check for sequential prestage - enhance cylinder range */366 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||367 data->attributes.operation == DASD_SEQ_ACCESS) {368 369 if (endcyl + private->attrib.nr_cyl < private->real_cyl)370 endcyl += private->attrib.nr_cyl;371 else372 endcyl = (private->real_cyl - 1);373 }374 375 set_ch_t(&data->beg_ext, begcyl, beghead);376 set_ch_t(&data->end_ext, endcyl, endhead);377 return rc;378}379 380 381static void locate_record_ext(struct ccw1 *ccw, struct LRE_eckd_data *data,382 unsigned int trk, unsigned int rec_on_trk,383 int count, int cmd, struct dasd_device *device,384 unsigned int reclen, unsigned int tlf)385{386 struct dasd_eckd_private *private = device->private;387 int sector;388 int dn, d;389 390 if (ccw) {391 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD_EXT;392 ccw->flags = 0;393 if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK)394 ccw->count = 22;395 else396 ccw->count = 20;397 ccw->cda = virt_to_dma32(data);398 }399 400 memset(data, 0, sizeof(*data));401 sector = 0;402 if (rec_on_trk) {403 switch (private->rdc_data.dev_type) {404 case 0x3390:405 dn = ceil_quot(reclen + 6, 232);406 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);407 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;408 break;409 case 0x3380:410 d = 7 + ceil_quot(reclen + 12, 32);411 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;412 break;413 }414 }415 data->sector = sector;416 /* note: meaning of count depends on the operation417 * for record based I/O it's the number of records, but for418 * track based I/O it's the number of tracks419 */420 data->count = count;421 switch (cmd) {422 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:423 data->operation.orientation = 0x3;424 data->operation.operation = 0x03;425 break;426 case DASD_ECKD_CCW_READ_HOME_ADDRESS:427 data->operation.orientation = 0x3;428 data->operation.operation = 0x16;429 break;430 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:431 data->operation.orientation = 0x1;432 data->operation.operation = 0x03;433 data->count++;434 break;435 case DASD_ECKD_CCW_READ_RECORD_ZERO:436 data->operation.orientation = 0x3;437 data->operation.operation = 0x16;438 data->count++;439 break;440 case DASD_ECKD_CCW_WRITE:441 case DASD_ECKD_CCW_WRITE_MT:442 case DASD_ECKD_CCW_WRITE_KD:443 case DASD_ECKD_CCW_WRITE_KD_MT:444 data->auxiliary.length_valid = 0x1;445 data->length = reclen;446 data->operation.operation = 0x01;447 break;448 case DASD_ECKD_CCW_WRITE_CKD:449 case DASD_ECKD_CCW_WRITE_CKD_MT:450 data->auxiliary.length_valid = 0x1;451 data->length = reclen;452 data->operation.operation = 0x03;453 break;454 case DASD_ECKD_CCW_WRITE_FULL_TRACK:455 data->operation.orientation = 0x0;456 data->operation.operation = 0x3F;457 data->extended_operation = 0x11;458 data->length = 0;459 data->extended_parameter_length = 0x02;460 if (data->count > 8) {461 data->extended_parameter[0] = 0xFF;462 data->extended_parameter[1] = 0xFF;463 data->extended_parameter[1] <<= (16 - count);464 } else {465 data->extended_parameter[0] = 0xFF;466 data->extended_parameter[0] <<= (8 - count);467 data->extended_parameter[1] = 0x00;468 }469 data->sector = 0xFF;470 break;471 case DASD_ECKD_CCW_WRITE_TRACK_DATA:472 data->auxiliary.length_valid = 0x1;473 data->length = reclen; /* not tlf, as one might think */474 data->operation.operation = 0x3F;475 data->extended_operation = 0x23;476 break;477 case DASD_ECKD_CCW_READ:478 case DASD_ECKD_CCW_READ_MT:479 case DASD_ECKD_CCW_READ_KD:480 case DASD_ECKD_CCW_READ_KD_MT:481 data->auxiliary.length_valid = 0x1;482 data->length = reclen;483 data->operation.operation = 0x06;484 break;485 case DASD_ECKD_CCW_READ_CKD:486 case DASD_ECKD_CCW_READ_CKD_MT:487 data->auxiliary.length_valid = 0x1;488 data->length = reclen;489 data->operation.operation = 0x16;490 break;491 case DASD_ECKD_CCW_READ_COUNT:492 data->operation.operation = 0x06;493 break;494 case DASD_ECKD_CCW_READ_TRACK:495 data->operation.orientation = 0x1;496 data->operation.operation = 0x0C;497 data->extended_parameter_length = 0;498 data->sector = 0xFF;499 break;500 case DASD_ECKD_CCW_READ_TRACK_DATA:501 data->auxiliary.length_valid = 0x1;502 data->length = tlf;503 data->operation.operation = 0x0C;504 break;505 case DASD_ECKD_CCW_ERASE:506 data->length = reclen;507 data->auxiliary.length_valid = 0x1;508 data->operation.operation = 0x0b;509 break;510 default:511 DBF_DEV_EVENT(DBF_ERR, device,512 "fill LRE unknown opcode 0x%x", cmd);513 BUG();514 }515 set_ch_t(&data->seek_addr,516 trk / private->rdc_data.trk_per_cyl,517 trk % private->rdc_data.trk_per_cyl);518 data->search_arg.cyl = data->seek_addr.cyl;519 data->search_arg.head = data->seek_addr.head;520 data->search_arg.record = rec_on_trk;521}522 523static int prefix_LRE(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,524 unsigned int trk, unsigned int totrk, int cmd,525 struct dasd_device *basedev, struct dasd_device *startdev,526 unsigned int format, unsigned int rec_on_trk, int count,527 unsigned int blksize, unsigned int tlf)528{529 struct dasd_eckd_private *basepriv, *startpriv;530 struct LRE_eckd_data *lredata;531 struct DE_eckd_data *dedata;532 int rc = 0;533 534 basepriv = basedev->private;535 startpriv = startdev->private;536 dedata = &pfxdata->define_extent;537 lredata = &pfxdata->locate_record;538 539 ccw->cmd_code = DASD_ECKD_CCW_PFX;540 ccw->flags = 0;541 if (cmd == DASD_ECKD_CCW_WRITE_FULL_TRACK) {542 ccw->count = sizeof(*pfxdata) + 2;543 ccw->cda = virt_to_dma32(pfxdata);544 memset(pfxdata, 0, sizeof(*pfxdata) + 2);545 } else {546 ccw->count = sizeof(*pfxdata);547 ccw->cda = virt_to_dma32(pfxdata);548 memset(pfxdata, 0, sizeof(*pfxdata));549 }550 551 /* prefix data */552 if (format > 1) {553 DBF_DEV_EVENT(DBF_ERR, basedev,554 "PFX LRE unknown format 0x%x", format);555 BUG();556 return -EINVAL;557 }558 pfxdata->format = format;559 pfxdata->base_address = basepriv->conf.ned->unit_addr;560 pfxdata->base_lss = basepriv->conf.ned->ID;561 pfxdata->validity.define_extent = 1;562 563 /* private uid is kept up to date, conf_data may be outdated */564 if (startpriv->uid.type == UA_BASE_PAV_ALIAS)565 pfxdata->validity.verify_base = 1;566 567 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS) {568 pfxdata->validity.verify_base = 1;569 pfxdata->validity.hyper_pav = 1;570 }571 572 rc = define_extent(NULL, dedata, trk, totrk, cmd, basedev, blksize);573 574 /*575 * For some commands the System Time Stamp is set in the define extent576 * data when XRC is supported. The validity of the time stamp must be577 * reflected in the prefix data as well.578 */579 if (dedata->ga_extended & 0x08 && dedata->ga_extended & 0x02)580 pfxdata->validity.time_stamp = 1; /* 'Time Stamp Valid' */581 582 if (format == 1) {583 locate_record_ext(NULL, lredata, trk, rec_on_trk, count, cmd,584 basedev, blksize, tlf);585 }586 587 return rc;588}589 590static int prefix(struct ccw1 *ccw, struct PFX_eckd_data *pfxdata,591 unsigned int trk, unsigned int totrk, int cmd,592 struct dasd_device *basedev, struct dasd_device *startdev)593{594 return prefix_LRE(ccw, pfxdata, trk, totrk, cmd, basedev, startdev,595 0, 0, 0, 0, 0);596}597 598static void599locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, unsigned int trk,600 unsigned int rec_on_trk, int no_rec, int cmd,601 struct dasd_device * device, int reclen)602{603 struct dasd_eckd_private *private = device->private;604 int sector;605 int dn, d;606 607 DBF_DEV_EVENT(DBF_INFO, device,608 "Locate: trk %d, rec %d, no_rec %d, cmd %d, reclen %d",609 trk, rec_on_trk, no_rec, cmd, reclen);610 611 ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;612 ccw->flags = 0;613 ccw->count = 16;614 ccw->cda = virt_to_dma32(data);615 616 memset(data, 0, sizeof(struct LO_eckd_data));617 sector = 0;618 if (rec_on_trk) {619 switch (private->rdc_data.dev_type) {620 case 0x3390:621 dn = ceil_quot(reclen + 6, 232);622 d = 9 + ceil_quot(reclen + 6 * (dn + 1), 34);623 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;624 break;625 case 0x3380:626 d = 7 + ceil_quot(reclen + 12, 32);627 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;628 break;629 }630 }631 data->sector = sector;632 data->count = no_rec;633 switch (cmd) {634 case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:635 data->operation.orientation = 0x3;636 data->operation.operation = 0x03;637 break;638 case DASD_ECKD_CCW_READ_HOME_ADDRESS:639 data->operation.orientation = 0x3;640 data->operation.operation = 0x16;641 break;642 case DASD_ECKD_CCW_WRITE_RECORD_ZERO:643 data->operation.orientation = 0x1;644 data->operation.operation = 0x03;645 data->count++;646 break;647 case DASD_ECKD_CCW_READ_RECORD_ZERO:648 data->operation.orientation = 0x3;649 data->operation.operation = 0x16;650 data->count++;651 break;652 case DASD_ECKD_CCW_WRITE:653 case DASD_ECKD_CCW_WRITE_MT:654 case DASD_ECKD_CCW_WRITE_KD:655 case DASD_ECKD_CCW_WRITE_KD_MT:656 data->auxiliary.last_bytes_used = 0x1;657 data->length = reclen;658 data->operation.operation = 0x01;659 break;660 case DASD_ECKD_CCW_WRITE_CKD:661 case DASD_ECKD_CCW_WRITE_CKD_MT:662 data->auxiliary.last_bytes_used = 0x1;663 data->length = reclen;664 data->operation.operation = 0x03;665 break;666 case DASD_ECKD_CCW_READ:667 case DASD_ECKD_CCW_READ_MT:668 case DASD_ECKD_CCW_READ_KD:669 case DASD_ECKD_CCW_READ_KD_MT:670 data->auxiliary.last_bytes_used = 0x1;671 data->length = reclen;672 data->operation.operation = 0x06;673 break;674 case DASD_ECKD_CCW_READ_CKD:675 case DASD_ECKD_CCW_READ_CKD_MT:676 data->auxiliary.last_bytes_used = 0x1;677 data->length = reclen;678 data->operation.operation = 0x16;679 break;680 case DASD_ECKD_CCW_READ_COUNT:681 data->operation.operation = 0x06;682 break;683 case DASD_ECKD_CCW_ERASE:684 data->length = reclen;685 data->auxiliary.last_bytes_used = 0x1;686 data->operation.operation = 0x0b;687 break;688 default:689 DBF_DEV_EVENT(DBF_ERR, device, "unknown locate record "690 "opcode 0x%x", cmd);691 }692 set_ch_t(&data->seek_addr,693 trk / private->rdc_data.trk_per_cyl,694 trk % private->rdc_data.trk_per_cyl);695 data->search_arg.cyl = data->seek_addr.cyl;696 data->search_arg.head = data->seek_addr.head;697 data->search_arg.record = rec_on_trk;698}699 700/*701 * Returns 1 if the block is one of the special blocks that needs702 * to get read/written with the KD variant of the command.703 * That is DASD_ECKD_READ_KD_MT instead of DASD_ECKD_READ_MT and704 * DASD_ECKD_WRITE_KD_MT instead of DASD_ECKD_WRITE_MT.705 * Luckily the KD variants differ only by one bit (0x08) from the706 * normal variant. So don't wonder about code like:707 * if (dasd_eckd_cdl_special(blk_per_trk, recid))708 * ccw->cmd_code |= 0x8;709 */710static inline int711dasd_eckd_cdl_special(int blk_per_trk, int recid)712{713 if (recid < 3)714 return 1;715 if (recid < blk_per_trk)716 return 0;717 if (recid < 2 * blk_per_trk)718 return 1;719 return 0;720}721 722/*723 * Returns the record size for the special blocks of the cdl format.724 * Only returns something useful if dasd_eckd_cdl_special is true725 * for the recid.726 */727static inline int728dasd_eckd_cdl_reclen(int recid)729{730 if (recid < 3)731 return sizes_trk0[recid];732 return LABEL_SIZE;733}734/* create unique id from private structure. */735static void create_uid(struct dasd_conf *conf, struct dasd_uid *uid)736{737 int count;738 739 memset(uid, 0, sizeof(struct dasd_uid));740 memcpy(uid->vendor, conf->ned->HDA_manufacturer,741 sizeof(uid->vendor) - 1);742 EBCASC(uid->vendor, sizeof(uid->vendor) - 1);743 memcpy(uid->serial, &conf->ned->serial,744 sizeof(uid->serial) - 1);745 EBCASC(uid->serial, sizeof(uid->serial) - 1);746 uid->ssid = conf->gneq->subsystemID;747 uid->real_unit_addr = conf->ned->unit_addr;748 if (conf->sneq) {749 uid->type = conf->sneq->sua_flags;750 if (uid->type == UA_BASE_PAV_ALIAS)751 uid->base_unit_addr = conf->sneq->base_unit_addr;752 } else {753 uid->type = UA_BASE_DEVICE;754 }755 if (conf->vdsneq) {756 for (count = 0; count < 16; count++) {757 sprintf(uid->vduit+2*count, "%02x",758 conf->vdsneq->uit[count]);759 }760 }761}762 763/*764 * Generate device unique id that specifies the physical device.765 */766static int dasd_eckd_generate_uid(struct dasd_device *device)767{768 struct dasd_eckd_private *private = device->private;769 unsigned long flags;770 771 if (!private)772 return -ENODEV;773 if (!private->conf.ned || !private->conf.gneq)774 return -ENODEV;775 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);776 create_uid(&private->conf, &private->uid);777 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);778 return 0;779}780 781static int dasd_eckd_get_uid(struct dasd_device *device, struct dasd_uid *uid)782{783 struct dasd_eckd_private *private = device->private;784 unsigned long flags;785 786 if (private) {787 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);788 *uid = private->uid;789 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);790 return 0;791 }792 return -EINVAL;793}794 795/*796 * compare device UID with data of a given dasd_eckd_private structure797 * return 0 for match798 */799static int dasd_eckd_compare_path_uid(struct dasd_device *device,800 struct dasd_conf *path_conf)801{802 struct dasd_uid device_uid;803 struct dasd_uid path_uid;804 805 create_uid(path_conf, &path_uid);806 dasd_eckd_get_uid(device, &device_uid);807 808 return memcmp(&device_uid, &path_uid, sizeof(struct dasd_uid));809}810 811static void dasd_eckd_fill_rcd_cqr(struct dasd_device *device,812 struct dasd_ccw_req *cqr,813 __u8 *rcd_buffer,814 __u8 lpm)815{816 struct ccw1 *ccw;817 /*818 * buffer has to start with EBCDIC "V1.0" to show819 * support for virtual device SNEQ820 */821 rcd_buffer[0] = 0xE5;822 rcd_buffer[1] = 0xF1;823 rcd_buffer[2] = 0x4B;824 rcd_buffer[3] = 0xF0;825 826 ccw = cqr->cpaddr;827 ccw->cmd_code = DASD_ECKD_CCW_RCD;828 ccw->flags = 0;829 ccw->cda = virt_to_dma32(rcd_buffer);830 ccw->count = DASD_ECKD_RCD_DATA_SIZE;831 cqr->magic = DASD_ECKD_MAGIC;832 833 cqr->startdev = device;834 cqr->memdev = device;835 cqr->block = NULL;836 cqr->expires = 10*HZ;837 cqr->lpm = lpm;838 cqr->retries = 256;839 cqr->buildclk = get_tod_clock();840 cqr->status = DASD_CQR_FILLED;841 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);842}843 844/*845 * Wakeup helper for read_conf846 * if the cqr is not done and needs some error recovery847 * the buffer has to be re-initialized with the EBCDIC "V1.0"848 * to show support for virtual device SNEQ849 */850static void read_conf_cb(struct dasd_ccw_req *cqr, void *data)851{852 struct ccw1 *ccw;853 __u8 *rcd_buffer;854 855 if (cqr->status != DASD_CQR_DONE) {856 ccw = cqr->cpaddr;857 rcd_buffer = dma32_to_virt(ccw->cda);858 memset(rcd_buffer, 0, sizeof(*rcd_buffer));859 860 rcd_buffer[0] = 0xE5;861 rcd_buffer[1] = 0xF1;862 rcd_buffer[2] = 0x4B;863 rcd_buffer[3] = 0xF0;864 }865 dasd_wakeup_cb(cqr, data);866}867 868static int dasd_eckd_read_conf_immediately(struct dasd_device *device,869 struct dasd_ccw_req *cqr,870 __u8 *rcd_buffer,871 __u8 lpm)872{873 struct ciw *ciw;874 int rc;875 /*876 * sanity check: scan for RCD command in extended SenseID data877 * some devices do not support RCD878 */879 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);880 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD)881 return -EOPNOTSUPP;882 883 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buffer, lpm);884 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);885 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);886 cqr->retries = 5;887 cqr->callback = read_conf_cb;888 rc = dasd_sleep_on_immediatly(cqr);889 return rc;890}891 892static int dasd_eckd_read_conf_lpm(struct dasd_device *device,893 void **rcd_buffer,894 int *rcd_buffer_size, __u8 lpm)895{896 struct ciw *ciw;897 char *rcd_buf = NULL;898 int ret;899 struct dasd_ccw_req *cqr;900 901 /*902 * sanity check: scan for RCD command in extended SenseID data903 * some devices do not support RCD904 */905 ciw = ccw_device_get_ciw(device->cdev, CIW_TYPE_RCD);906 if (!ciw || ciw->cmd != DASD_ECKD_CCW_RCD) {907 ret = -EOPNOTSUPP;908 goto out_error;909 }910 rcd_buf = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL | GFP_DMA);911 if (!rcd_buf) {912 ret = -ENOMEM;913 goto out_error;914 }915 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* RCD */,916 0, /* use rcd_buf as data ara */917 device, NULL);918 if (IS_ERR(cqr)) {919 DBF_DEV_EVENT(DBF_WARNING, device, "%s",920 "Could not allocate RCD request");921 ret = -ENOMEM;922 goto out_error;923 }924 dasd_eckd_fill_rcd_cqr(device, cqr, rcd_buf, lpm);925 cqr->callback = read_conf_cb;926 ret = dasd_sleep_on(cqr);927 /*928 * on success we update the user input parms929 */930 dasd_sfree_request(cqr, cqr->memdev);931 if (ret)932 goto out_error;933 934 *rcd_buffer_size = DASD_ECKD_RCD_DATA_SIZE;935 *rcd_buffer = rcd_buf;936 return 0;937out_error:938 kfree(rcd_buf);939 *rcd_buffer = NULL;940 *rcd_buffer_size = 0;941 return ret;942}943 944static int dasd_eckd_identify_conf_parts(struct dasd_conf *conf)945{946 947 struct dasd_sneq *sneq;948 int i, count;949 950 conf->ned = NULL;951 conf->sneq = NULL;952 conf->vdsneq = NULL;953 conf->gneq = NULL;954 count = conf->len / sizeof(struct dasd_sneq);955 sneq = (struct dasd_sneq *)conf->data;956 for (i = 0; i < count; ++i) {957 if (sneq->flags.identifier == 1 && sneq->format == 1)958 conf->sneq = sneq;959 else if (sneq->flags.identifier == 1 && sneq->format == 4)960 conf->vdsneq = (struct vd_sneq *)sneq;961 else if (sneq->flags.identifier == 2)962 conf->gneq = (struct dasd_gneq *)sneq;963 else if (sneq->flags.identifier == 3 && sneq->res1 == 1)964 conf->ned = (struct dasd_ned *)sneq;965 sneq++;966 }967 if (!conf->ned || !conf->gneq) {968 conf->ned = NULL;969 conf->sneq = NULL;970 conf->vdsneq = NULL;971 conf->gneq = NULL;972 return -EINVAL;973 }974 return 0;975 976};977 978static unsigned char dasd_eckd_path_access(void *conf_data, int conf_len)979{980 struct dasd_gneq *gneq;981 int i, count, found;982 983 count = conf_len / sizeof(*gneq);984 gneq = (struct dasd_gneq *)conf_data;985 found = 0;986 for (i = 0; i < count; ++i) {987 if (gneq->flags.identifier == 2) {988 found = 1;989 break;990 }991 gneq++;992 }993 if (found)994 return ((char *)gneq)[18] & 0x07;995 else996 return 0;997}998 999static void dasd_eckd_store_conf_data(struct dasd_device *device,1000 struct dasd_conf_data *conf_data, int chp)1001{1002 struct dasd_eckd_private *private = device->private;1003 struct channel_path_desc_fmt0 *chp_desc;1004 struct subchannel_id sch_id;1005 void *cdp;1006 1007 /*1008 * path handling and read_conf allocate data1009 * free it before replacing the pointer1010 * also replace the old private->conf_data pointer1011 * with the new one if this points to the same data1012 */1013 cdp = device->path[chp].conf_data;1014 if (private->conf.data == cdp) {1015 private->conf.data = (void *)conf_data;1016 dasd_eckd_identify_conf_parts(&private->conf);1017 }1018 ccw_device_get_schid(device->cdev, &sch_id);1019 device->path[chp].conf_data = conf_data;1020 device->path[chp].cssid = sch_id.cssid;1021 device->path[chp].ssid = sch_id.ssid;1022 chp_desc = ccw_device_get_chp_desc(device->cdev, chp);1023 if (chp_desc)1024 device->path[chp].chpid = chp_desc->chpid;1025 kfree(chp_desc);1026 kfree(cdp);1027}1028 1029static void dasd_eckd_clear_conf_data(struct dasd_device *device)1030{1031 struct dasd_eckd_private *private = device->private;1032 int i;1033 1034 private->conf.data = NULL;1035 private->conf.len = 0;1036 for (i = 0; i < 8; i++) {1037 kfree(device->path[i].conf_data);1038 device->path[i].conf_data = NULL;1039 device->path[i].cssid = 0;1040 device->path[i].ssid = 0;1041 device->path[i].chpid = 0;1042 dasd_path_notoper(device, i);1043 }1044}1045 1046static void dasd_eckd_read_fc_security(struct dasd_device *device)1047{1048 struct dasd_eckd_private *private = device->private;1049 u8 esm_valid;1050 u8 esm[8];1051 int chp;1052 int rc;1053 1054 rc = chsc_scud(private->uid.ssid, (u64 *)esm, &esm_valid);1055 if (rc) {1056 for (chp = 0; chp < 8; chp++)1057 device->path[chp].fc_security = 0;1058 return;1059 }1060 1061 for (chp = 0; chp < 8; chp++) {1062 if (esm_valid & (0x80 >> chp))1063 device->path[chp].fc_security = esm[chp];1064 else1065 device->path[chp].fc_security = 0;1066 }1067}1068 1069static void dasd_eckd_get_uid_string(struct dasd_conf *conf, char *print_uid)1070{1071 struct dasd_uid uid;1072 1073 create_uid(conf, &uid);1074 snprintf(print_uid, DASD_UID_STRLEN, "%s.%s.%04x.%02x%s%s",1075 uid.vendor, uid.serial, uid.ssid, uid.real_unit_addr,1076 uid.vduit[0] ? "." : "", uid.vduit);1077}1078 1079static int dasd_eckd_check_cabling(struct dasd_device *device,1080 void *conf_data, __u8 lpm)1081{1082 char print_path_uid[DASD_UID_STRLEN], print_device_uid[DASD_UID_STRLEN];1083 struct dasd_eckd_private *private = device->private;1084 struct dasd_conf path_conf;1085 1086 path_conf.data = conf_data;1087 path_conf.len = DASD_ECKD_RCD_DATA_SIZE;1088 if (dasd_eckd_identify_conf_parts(&path_conf))1089 return 1;1090 1091 if (dasd_eckd_compare_path_uid(device, &path_conf)) {1092 dasd_eckd_get_uid_string(&path_conf, print_path_uid);1093 dasd_eckd_get_uid_string(&private->conf, print_device_uid);1094 dev_err(&device->cdev->dev,1095 "Not all channel paths lead to the same device, path %02X leads to device %s instead of %s\n",1096 lpm, print_path_uid, print_device_uid);1097 return 1;1098 }1099 1100 return 0;1101}1102 1103static int dasd_eckd_read_conf(struct dasd_device *device)1104{1105 void *conf_data;1106 int conf_len, conf_data_saved;1107 int rc, path_err, pos;1108 __u8 lpm, opm;1109 struct dasd_eckd_private *private;1110 1111 private = device->private;1112 opm = ccw_device_get_path_mask(device->cdev);1113 conf_data_saved = 0;1114 path_err = 0;1115 /* get configuration data per operational path */1116 for (lpm = 0x80; lpm; lpm>>= 1) {1117 if (!(lpm & opm))1118 continue;1119 rc = dasd_eckd_read_conf_lpm(device, &conf_data,1120 &conf_len, lpm);1121 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */1122 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,1123 "Read configuration data returned "1124 "error %d", rc);1125 return rc;1126 }1127 if (conf_data == NULL) {1128 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",1129 "No configuration data "1130 "retrieved");1131 /* no further analysis possible */1132 dasd_path_add_opm(device, opm);1133 continue; /* no error */1134 }1135 /* save first valid configuration data */1136 if (!conf_data_saved) {1137 /* initially clear previously stored conf_data */1138 dasd_eckd_clear_conf_data(device);1139 private->conf.data = conf_data;1140 private->conf.len = conf_len;1141 if (dasd_eckd_identify_conf_parts(&private->conf)) {1142 private->conf.data = NULL;1143 private->conf.len = 0;1144 kfree(conf_data);1145 continue;1146 }1147 /*1148 * build device UID that other path data1149 * can be compared to it1150 */1151 dasd_eckd_generate_uid(device);1152 conf_data_saved++;1153 } else if (dasd_eckd_check_cabling(device, conf_data, lpm)) {1154 dasd_path_add_cablepm(device, lpm);1155 path_err = -EINVAL;1156 kfree(conf_data);1157 continue;1158 }1159 1160 pos = pathmask_to_pos(lpm);1161 dasd_eckd_store_conf_data(device, conf_data, pos);1162 1163 switch (dasd_eckd_path_access(conf_data, conf_len)) {1164 case 0x02:1165 dasd_path_add_nppm(device, lpm);1166 break;1167 case 0x03:1168 dasd_path_add_ppm(device, lpm);1169 break;1170 }1171 if (!dasd_path_get_opm(device)) {1172 dasd_path_set_opm(device, lpm);1173 dasd_generic_path_operational(device);1174 } else {1175 dasd_path_add_opm(device, lpm);1176 }1177 }1178 1179 return path_err;1180}1181 1182static u32 get_fcx_max_data(struct dasd_device *device)1183{1184 struct dasd_eckd_private *private = device->private;1185 int fcx_in_css, fcx_in_gneq, fcx_in_features;1186 unsigned int mdc;1187 int tpm;1188 1189 if (dasd_nofcx)1190 return 0;1191 /* is transport mode supported? */1192 fcx_in_css = css_general_characteristics.fcx;1193 fcx_in_gneq = private->conf.gneq->reserved2[7] & 0x04;1194 fcx_in_features = private->features.feature[40] & 0x80;1195 tpm = fcx_in_css && fcx_in_gneq && fcx_in_features;1196 1197 if (!tpm)1198 return 0;1199 1200 mdc = ccw_device_get_mdc(device->cdev, 0);1201 if (mdc == 0) {1202 dev_warn(&device->cdev->dev, "Detecting the maximum supported data size for zHPF requests failed\n");1203 return 0;1204 } else {1205 return (u32)mdc * FCX_MAX_DATA_FACTOR;1206 }1207}1208 1209static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)1210{1211 struct dasd_eckd_private *private = device->private;1212 unsigned int mdc;1213 u32 fcx_max_data;1214 1215 if (private->fcx_max_data) {1216 mdc = ccw_device_get_mdc(device->cdev, lpm);1217 if (mdc == 0) {1218 dev_warn(&device->cdev->dev,1219 "Detecting the maximum data size for zHPF "1220 "requests failed (rc=%d) for a new path %x\n",1221 mdc, lpm);1222 return mdc;1223 }1224 fcx_max_data = (u32)mdc * FCX_MAX_DATA_FACTOR;1225 if (fcx_max_data < private->fcx_max_data) {1226 dev_warn(&device->cdev->dev,1227 "The maximum data size for zHPF requests %u "1228 "on a new path %x is below the active maximum "1229 "%u\n", fcx_max_data, lpm,1230 private->fcx_max_data);1231 return -EACCES;1232 }1233 }1234 return 0;1235}1236 1237static int rebuild_device_uid(struct dasd_device *device,1238 struct pe_handler_work_data *data)1239{1240 struct dasd_eckd_private *private = device->private;1241 __u8 lpm, opm = dasd_path_get_opm(device);1242 int rc = -ENODEV;1243 1244 for (lpm = 0x80; lpm; lpm >>= 1) {1245 if (!(lpm & opm))1246 continue;1247 memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));1248 memset(&data->cqr, 0, sizeof(data->cqr));1249 data->cqr.cpaddr = &data->ccw;1250 rc = dasd_eckd_read_conf_immediately(device, &data->cqr,1251 data->rcd_buffer,1252 lpm);1253 1254 if (rc) {1255 if (rc == -EOPNOTSUPP) /* -EOPNOTSUPP is ok */1256 continue;1257 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,1258 "Read configuration data "1259 "returned error %d", rc);1260 break;1261 }1262 memcpy(private->conf.data, data->rcd_buffer,1263 DASD_ECKD_RCD_DATA_SIZE);1264 if (dasd_eckd_identify_conf_parts(&private->conf)) {1265 rc = -ENODEV;1266 } else /* first valid path is enough */1267 break;1268 }1269 1270 if (!rc)1271 rc = dasd_eckd_generate_uid(device);1272 1273 return rc;1274}1275 1276static void dasd_eckd_path_available_action(struct dasd_device *device,1277 struct pe_handler_work_data *data)1278{1279 __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE];1280 __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm;1281 struct dasd_conf_data *conf_data;1282 char print_uid[DASD_UID_STRLEN];1283 struct dasd_conf path_conf;1284 unsigned long flags;1285 int rc, pos;1286 1287 opm = 0;1288 npm = 0;1289 ppm = 0;1290 epm = 0;1291 hpfpm = 0;1292 cablepm = 0;1293 1294 for (lpm = 0x80; lpm; lpm >>= 1) {1295 if (!(lpm & data->tbvpm))1296 continue;1297 memset(&data->rcd_buffer, 0, sizeof(data->rcd_buffer));1298 memset(&data->cqr, 0, sizeof(data->cqr));1299 data->cqr.cpaddr = &data->ccw;1300 rc = dasd_eckd_read_conf_immediately(device, &data->cqr,1301 data->rcd_buffer,1302 lpm);1303 if (!rc) {1304 switch (dasd_eckd_path_access(data->rcd_buffer,1305 DASD_ECKD_RCD_DATA_SIZE)1306 ) {1307 case 0x02:1308 npm |= lpm;1309 break;1310 case 0x03:1311 ppm |= lpm;1312 break;1313 }1314 opm |= lpm;1315 } else if (rc == -EOPNOTSUPP) {1316 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",1317 "path verification: No configuration "1318 "data retrieved");1319 opm |= lpm;1320 } else if (rc == -EAGAIN) {1321 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",1322 "path verification: device is stopped,"1323 " try again later");1324 epm |= lpm;1325 } else {1326 dev_warn(&device->cdev->dev,1327 "Reading device feature codes failed "1328 "(rc=%d) for new path %x\n", rc, lpm);1329 continue;1330 }1331 if (verify_fcx_max_data(device, lpm)) {1332 opm &= ~lpm;1333 npm &= ~lpm;1334 ppm &= ~lpm;1335 hpfpm |= lpm;1336 continue;1337 }1338 1339 /*1340 * save conf_data for comparison after1341 * rebuild_device_uid may have changed1342 * the original data1343 */1344 memcpy(&path_rcd_buf, data->rcd_buffer,1345 DASD_ECKD_RCD_DATA_SIZE);1346 path_conf.data = (void *)&path_rcd_buf;1347 path_conf.len = DASD_ECKD_RCD_DATA_SIZE;1348 if (dasd_eckd_identify_conf_parts(&path_conf)) {1349 path_conf.data = NULL;1350 path_conf.len = 0;1351 continue;1352 }1353 1354 /*1355 * compare path UID with device UID only if at least1356 * one valid path is left1357 * in other case the device UID may have changed and1358 * the first working path UID will be used as device UID1359 */1360 if (dasd_path_get_opm(device) &&1361 dasd_eckd_compare_path_uid(device, &path_conf)) {1362 /*1363 * the comparison was not successful1364 * rebuild the device UID with at least one1365 * known path in case a z/VM hyperswap command1366 * has changed the device1367 *1368 * after this compare again1369 *1370 * if either the rebuild or the recompare fails1371 * the path can not be used1372 */1373 if (rebuild_device_uid(device, data) ||1374 dasd_eckd_compare_path_uid(1375 device, &path_conf)) {1376 dasd_eckd_get_uid_string(&path_conf, print_uid);1377 dev_err(&device->cdev->dev,1378 "The newly added channel path %02X "1379 "will not be used because it leads "1380 "to a different device %s\n",1381 lpm, print_uid);1382 opm &= ~lpm;1383 npm &= ~lpm;1384 ppm &= ~lpm;1385 cablepm |= lpm;1386 continue;1387 }1388 }1389 1390 conf_data = kzalloc(DASD_ECKD_RCD_DATA_SIZE, GFP_KERNEL);1391 if (conf_data) {1392 memcpy(conf_data, data->rcd_buffer,1393 DASD_ECKD_RCD_DATA_SIZE);1394 } else {1395 /*1396 * path is operational but path config data could not1397 * be stored due to low mem condition1398 * add it to the error path mask and schedule a path1399 * verification later that this could be added again1400 */1401 epm |= lpm;1402 }1403 pos = pathmask_to_pos(lpm);1404 dasd_eckd_store_conf_data(device, conf_data, pos);1405 1406 /*1407 * There is a small chance that a path is lost again between1408 * above path verification and the following modification of1409 * the device opm mask. We could avoid that race here by using1410 * yet another path mask, but we rather deal with this unlikely1411 * situation in dasd_start_IO.1412 */1413 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);1414 if (!dasd_path_get_opm(device) && opm) {1415 dasd_path_set_opm(device, opm);1416 dasd_generic_path_operational(device);1417 } else {1418 dasd_path_add_opm(device, opm);1419 }1420 dasd_path_add_nppm(device, npm);1421 dasd_path_add_ppm(device, ppm);1422 if (epm) {1423 dasd_path_add_tbvpm(device, epm);1424 dasd_device_set_timer(device, 50);1425 }1426 dasd_path_add_cablepm(device, cablepm);1427 dasd_path_add_nohpfpm(device, hpfpm);1428 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);1429 1430 dasd_path_create_kobj(device, pos);1431 }1432}1433 1434static void do_pe_handler_work(struct work_struct *work)1435{1436 struct pe_handler_work_data *data;1437 struct dasd_device *device;1438 1439 data = container_of(work, struct pe_handler_work_data, worker);1440 device = data->device;1441 1442 /* delay path verification until device was resumed */1443 if (test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {1444 schedule_work(work);1445 return;1446 }1447 /* check if path verification already running and delay if so */1448 if (test_and_set_bit(DASD_FLAG_PATH_VERIFY, &device->flags)) {1449 schedule_work(work);1450 return;1451 }1452 1453 if (data->tbvpm)1454 dasd_eckd_path_available_action(device, data);1455 if (data->fcsecpm)1456 dasd_eckd_read_fc_security(device);1457 1458 clear_bit(DASD_FLAG_PATH_VERIFY, &device->flags);1459 dasd_put_device(device);1460 if (data->isglobal)1461 mutex_unlock(&dasd_pe_handler_mutex);1462 else1463 kfree(data);1464}1465 1466static int dasd_eckd_pe_handler(struct dasd_device *device,1467 __u8 tbvpm, __u8 fcsecpm)1468{1469 struct pe_handler_work_data *data;1470 1471 data = kzalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA);1472 if (!data) {1473 if (mutex_trylock(&dasd_pe_handler_mutex)) {1474 data = pe_handler_worker;1475 data->isglobal = 1;1476 } else {1477 return -ENOMEM;1478 }1479 }1480 INIT_WORK(&data->worker, do_pe_handler_work);1481 dasd_get_device(device);1482 data->device = device;1483 data->tbvpm = tbvpm;1484 data->fcsecpm = fcsecpm;1485 schedule_work(&data->worker);1486 return 0;1487}1488 1489static void dasd_eckd_reset_path(struct dasd_device *device, __u8 pm)1490{1491 struct dasd_eckd_private *private = device->private;1492 unsigned long flags;1493 1494 if (!private->fcx_max_data)1495 private->fcx_max_data = get_fcx_max_data(device);1496 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);1497 dasd_path_set_tbvpm(device, pm ? : dasd_path_get_notoperpm(device));1498 dasd_schedule_device_bh(device);1499 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);1500}1501 1502static int dasd_eckd_read_features(struct dasd_device *device)1503{1504 struct dasd_eckd_private *private = device->private;1505 struct dasd_psf_prssd_data *prssdp;1506 struct dasd_rssd_features *features;1507 struct dasd_ccw_req *cqr;1508 struct ccw1 *ccw;1509 int rc;1510 1511 memset(&private->features, 0, sizeof(struct dasd_rssd_features));1512 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,1513 (sizeof(struct dasd_psf_prssd_data) +1514 sizeof(struct dasd_rssd_features)),1515 device, NULL);1516 if (IS_ERR(cqr)) {1517 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not "1518 "allocate initialization request");1519 return PTR_ERR(cqr);1520 }1521 cqr->startdev = device;1522 cqr->memdev = device;1523 cqr->block = NULL;1524 cqr->retries = 256;1525 cqr->expires = 10 * HZ;1526 1527 /* Prepare for Read Subsystem Data */1528 prssdp = (struct dasd_psf_prssd_data *) cqr->data;1529 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));1530 prssdp->order = PSF_ORDER_PRSSD;1531 prssdp->suborder = 0x41; /* Read Feature Codes */1532 /* all other bytes of prssdp must be zero */1533 1534 ccw = cqr->cpaddr;1535 ccw->cmd_code = DASD_ECKD_CCW_PSF;1536 ccw->count = sizeof(struct dasd_psf_prssd_data);1537 ccw->flags |= CCW_FLAG_CC;1538 ccw->cda = virt_to_dma32(prssdp);1539 1540 /* Read Subsystem Data - feature codes */1541 features = (struct dasd_rssd_features *) (prssdp + 1);1542 memset(features, 0, sizeof(struct dasd_rssd_features));1543 1544 ccw++;1545 ccw->cmd_code = DASD_ECKD_CCW_RSSD;1546 ccw->count = sizeof(struct dasd_rssd_features);1547 ccw->cda = virt_to_dma32(features);1548 1549 cqr->buildclk = get_tod_clock();1550 cqr->status = DASD_CQR_FILLED;1551 rc = dasd_sleep_on(cqr);1552 if (rc == 0) {1553 prssdp = (struct dasd_psf_prssd_data *) cqr->data;1554 features = (struct dasd_rssd_features *) (prssdp + 1);1555 memcpy(&private->features, features,1556 sizeof(struct dasd_rssd_features));1557 } else1558 dev_warn(&device->cdev->dev, "Reading device feature codes"1559 " failed with rc=%d\n", rc);1560 dasd_sfree_request(cqr, cqr->memdev);1561 return rc;1562}1563 1564/* Read Volume Information - Volume Storage Query */1565static int dasd_eckd_read_vol_info(struct dasd_device *device)1566{1567 struct dasd_eckd_private *private = device->private;1568 struct dasd_psf_prssd_data *prssdp;1569 struct dasd_rssd_vsq *vsq;1570 struct dasd_ccw_req *cqr;1571 struct ccw1 *ccw;1572 int useglobal;1573 int rc;1574 1575 /* This command cannot be executed on an alias device */1576 if (private->uid.type == UA_BASE_PAV_ALIAS ||1577 private->uid.type == UA_HYPER_PAV_ALIAS)1578 return 0;1579 1580 useglobal = 0;1581 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 /* PSF + RSSD */,1582 sizeof(*prssdp) + sizeof(*vsq), device, NULL);1583 if (IS_ERR(cqr)) {1584 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",1585 "Could not allocate initialization request");1586 mutex_lock(&dasd_vol_info_mutex);1587 useglobal = 1;1588 cqr = &dasd_vol_info_req->cqr;1589 memset(cqr, 0, sizeof(*cqr));1590 memset(dasd_vol_info_req, 0, sizeof(*dasd_vol_info_req));1591 cqr->cpaddr = &dasd_vol_info_req->ccw;1592 cqr->data = &dasd_vol_info_req->data;1593 cqr->magic = DASD_ECKD_MAGIC;1594 }1595 1596 /* Prepare for Read Subsystem Data */1597 prssdp = cqr->data;1598 prssdp->order = PSF_ORDER_PRSSD;1599 prssdp->suborder = PSF_SUBORDER_VSQ; /* Volume Storage Query */1600 prssdp->lss = private->conf.ned->ID;1601 prssdp->volume = private->conf.ned->unit_addr;1602 1603 ccw = cqr->cpaddr;1604 ccw->cmd_code = DASD_ECKD_CCW_PSF;1605 ccw->count = sizeof(*prssdp);1606 ccw->flags |= CCW_FLAG_CC;1607 ccw->cda = virt_to_dma32(prssdp);1608 1609 /* Read Subsystem Data - Volume Storage Query */1610 vsq = (struct dasd_rssd_vsq *)(prssdp + 1);1611 memset(vsq, 0, sizeof(*vsq));1612 1613 ccw++;1614 ccw->cmd_code = DASD_ECKD_CCW_RSSD;1615 ccw->count = sizeof(*vsq);1616 ccw->flags |= CCW_FLAG_SLI;1617 ccw->cda = virt_to_dma32(vsq);1618 1619 cqr->buildclk = get_tod_clock();1620 cqr->status = DASD_CQR_FILLED;1621 cqr->startdev = device;1622 cqr->memdev = device;1623 cqr->block = NULL;1624 cqr->retries = 256;1625 cqr->expires = device->default_expires * HZ;1626 /* The command might not be supported. Suppress the error output */1627 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);1628 1629 rc = dasd_sleep_on_interruptible(cqr);1630 if (rc == 0) {1631 memcpy(&private->vsq, vsq, sizeof(*vsq));1632 } else {1633 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,1634 "Reading the volume storage information failed with rc=%d", rc);1635 }1636 1637 if (useglobal)1638 mutex_unlock(&dasd_vol_info_mutex);1639 else1640 dasd_sfree_request(cqr, cqr->memdev);1641 1642 return rc;1643}1644 1645static int dasd_eckd_is_ese(struct dasd_device *device)1646{1647 struct dasd_eckd_private *private = device->private;1648 1649 return private->vsq.vol_info.ese;1650}1651 1652static int dasd_eckd_ext_pool_id(struct dasd_device *device)1653{1654 struct dasd_eckd_private *private = device->private;1655 1656 return private->vsq.extent_pool_id;1657}1658 1659/*1660 * This value represents the total amount of available space. As more space is1661 * allocated by ESE volumes, this value will decrease.1662 * The data for this value is therefore updated on any call.1663 */1664static int dasd_eckd_space_configured(struct dasd_device *device)1665{1666 struct dasd_eckd_private *private = device->private;1667 int rc;1668 1669 rc = dasd_eckd_read_vol_info(device);1670 1671 return rc ? : private->vsq.space_configured;1672}1673 1674/*1675 * The value of space allocated by an ESE volume may have changed and is1676 * therefore updated on any call.1677 */1678static int dasd_eckd_space_allocated(struct dasd_device *device)1679{1680 struct dasd_eckd_private *private = device->private;1681 int rc;1682 1683 rc = dasd_eckd_read_vol_info(device);1684 1685 return rc ? : private->vsq.space_allocated;1686}1687 1688static int dasd_eckd_logical_capacity(struct dasd_device *device)1689{1690 struct dasd_eckd_private *private = device->private;1691 1692 return private->vsq.logical_capacity;1693}1694 1695static void dasd_eckd_ext_pool_exhaust_work(struct work_struct *work)1696{1697 struct ext_pool_exhaust_work_data *data;1698 struct dasd_device *device;1699 struct dasd_device *base;1700 1701 data = container_of(work, struct ext_pool_exhaust_work_data, worker);1702 device = data->device;1703 base = data->base;1704 1705 if (!base)1706 base = device;1707 if (dasd_eckd_space_configured(base) != 0) {1708 dasd_generic_space_avail(device);1709 } else {1710 dev_warn(&device->cdev->dev, "No space left in the extent pool\n");1711 DBF_DEV_EVENT(DBF_WARNING, device, "%s", "out of space");1712 }1713 1714 dasd_put_device(device);1715 kfree(data);1716}1717 1718static int dasd_eckd_ext_pool_exhaust(struct dasd_device *device,1719 struct dasd_ccw_req *cqr)1720{1721 struct ext_pool_exhaust_work_data *data;1722 1723 data = kzalloc(sizeof(*data), GFP_ATOMIC);1724 if (!data)1725 return -ENOMEM;1726 INIT_WORK(&data->worker, dasd_eckd_ext_pool_exhaust_work);1727 dasd_get_device(device);1728 data->device = device;1729 1730 if (cqr->block)1731 data->base = cqr->block->base;1732 else if (cqr->basedev)1733 data->base = cqr->basedev;1734 else1735 data->base = NULL;1736 1737 schedule_work(&data->worker);1738 1739 return 0;1740}1741 1742static void dasd_eckd_cpy_ext_pool_data(struct dasd_device *device,1743 struct dasd_rssd_lcq *lcq)1744{1745 struct dasd_eckd_private *private = device->private;1746 int pool_id = dasd_eckd_ext_pool_id(device);1747 struct dasd_ext_pool_sum eps;1748 int i;1749 1750 for (i = 0; i < lcq->pool_count; i++) {1751 eps = lcq->ext_pool_sum[i];1752 if (eps.pool_id == pool_id) {1753 memcpy(&private->eps, &eps,1754 sizeof(struct dasd_ext_pool_sum));1755 }1756 }1757}1758 1759/* Read Extent Pool Information - Logical Configuration Query */1760static int dasd_eckd_read_ext_pool_info(struct dasd_device *device)1761{1762 struct dasd_eckd_private *private = device->private;1763 struct dasd_psf_prssd_data *prssdp;1764 struct dasd_rssd_lcq *lcq;1765 struct dasd_ccw_req *cqr;1766 struct ccw1 *ccw;1767 int rc;1768 1769 /* This command cannot be executed on an alias device */1770 if (private->uid.type == UA_BASE_PAV_ALIAS ||1771 private->uid.type == UA_HYPER_PAV_ALIAS)1772 return 0;1773 1774 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2 /* PSF + RSSD */,1775 sizeof(*prssdp) + sizeof(*lcq), device, NULL);1776 if (IS_ERR(cqr)) {1777 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",1778 "Could not allocate initialization request");1779 return PTR_ERR(cqr);1780 }1781 1782 /* Prepare for Read Subsystem Data */1783 prssdp = cqr->data;1784 memset(prssdp, 0, sizeof(*prssdp));1785 prssdp->order = PSF_ORDER_PRSSD;1786 prssdp->suborder = PSF_SUBORDER_LCQ; /* Logical Configuration Query */1787 1788 ccw = cqr->cpaddr;1789 ccw->cmd_code = DASD_ECKD_CCW_PSF;1790 ccw->count = sizeof(*prssdp);1791 ccw->flags |= CCW_FLAG_CC;1792 ccw->cda = virt_to_dma32(prssdp);1793 1794 lcq = (struct dasd_rssd_lcq *)(prssdp + 1);1795 memset(lcq, 0, sizeof(*lcq));1796 1797 ccw++;1798 ccw->cmd_code = DASD_ECKD_CCW_RSSD;1799 ccw->count = sizeof(*lcq);1800 ccw->flags |= CCW_FLAG_SLI;1801 ccw->cda = virt_to_dma32(lcq);1802 1803 cqr->buildclk = get_tod_clock();1804 cqr->status = DASD_CQR_FILLED;1805 cqr->startdev = device;1806 cqr->memdev = device;1807 cqr->block = NULL;1808 cqr->retries = 256;1809 cqr->expires = device->default_expires * HZ;1810 /* The command might not be supported. Suppress the error output */1811 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);1812 1813 rc = dasd_sleep_on_interruptible(cqr);1814 if (rc == 0) {1815 dasd_eckd_cpy_ext_pool_data(device, lcq);1816 } else {1817 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,1818 "Reading the logical configuration failed with rc=%d", rc);1819 }1820 1821 dasd_sfree_request(cqr, cqr->memdev);1822 1823 return rc;1824}1825 1826/*1827 * Depending on the device type, the extent size is specified either as1828 * cylinders per extent (CKD) or size per extent (FBA)1829 * A 1GB size corresponds to 1113cyl, and 16MB to 21cyl.1830 */1831static int dasd_eckd_ext_size(struct dasd_device *device)1832{1833 struct dasd_eckd_private *private = device->private;1834 struct dasd_ext_pool_sum eps = private->eps;1835 1836 if (!eps.flags.extent_size_valid)1837 return 0;1838 if (eps.extent_size.size_1G)1839 return 1113;1840 if (eps.extent_size.size_16M)1841 return 21;1842 1843 return 0;1844}1845 1846static int dasd_eckd_ext_pool_warn_thrshld(struct dasd_device *device)1847{1848 struct dasd_eckd_private *private = device->private;1849 1850 return private->eps.warn_thrshld;1851}1852 1853static int dasd_eckd_ext_pool_cap_at_warnlevel(struct dasd_device *device)1854{1855 struct dasd_eckd_private *private = device->private;1856 1857 return private->eps.flags.capacity_at_warnlevel;1858}1859 1860/*1861 * Extent Pool out of space1862 */1863static int dasd_eckd_ext_pool_oos(struct dasd_device *device)1864{1865 struct dasd_eckd_private *private = device->private;1866 1867 return private->eps.flags.pool_oos;1868}1869 1870/*1871 * Build CP for Perform Subsystem Function - SSC.1872 */1873static struct dasd_ccw_req *dasd_eckd_build_psf_ssc(struct dasd_device *device,1874 int enable_pav)1875{1876 struct dasd_ccw_req *cqr;1877 struct dasd_psf_ssc_data *psf_ssc_data;1878 struct ccw1 *ccw;1879 1880 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ ,1881 sizeof(struct dasd_psf_ssc_data),1882 device, NULL);1883 1884 if (IS_ERR(cqr)) {1885 DBF_DEV_EVENT(DBF_WARNING, device, "%s",1886 "Could not allocate PSF-SSC request");1887 return cqr;1888 }1889 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;1890 psf_ssc_data->order = PSF_ORDER_SSC;1891 psf_ssc_data->suborder = 0xc0;1892 if (enable_pav) {1893 psf_ssc_data->suborder |= 0x08;1894 psf_ssc_data->reserved[0] = 0x88;1895 }1896 ccw = cqr->cpaddr;1897 ccw->cmd_code = DASD_ECKD_CCW_PSF;1898 ccw->cda = virt_to_dma32(psf_ssc_data);1899 ccw->count = 66;1900 1901 cqr->startdev = device;1902 cqr->memdev = device;1903 cqr->block = NULL;1904 cqr->retries = 256;1905 cqr->expires = 10*HZ;1906 cqr->buildclk = get_tod_clock();1907 cqr->status = DASD_CQR_FILLED;1908 return cqr;1909}1910 1911/*1912 * Perform Subsystem Function.1913 * It is necessary to trigger CIO for channel revalidation since this1914 * call might change behaviour of DASD devices.1915 */1916static int1917dasd_eckd_psf_ssc(struct dasd_device *device, int enable_pav,1918 unsigned long flags)1919{1920 struct dasd_ccw_req *cqr;1921 int rc;1922 1923 cqr = dasd_eckd_build_psf_ssc(device, enable_pav);1924 if (IS_ERR(cqr))1925 return PTR_ERR(cqr);1926 1927 /*1928 * set flags e.g. turn on failfast, to prevent blocking1929 * the calling function should handle failed requests1930 */1931 cqr->flags |= flags;1932 1933 rc = dasd_sleep_on(cqr);1934 if (!rc)1935 /* trigger CIO to reprobe devices */1936 css_schedule_reprobe();1937 else if (cqr->intrc == -EAGAIN)1938 rc = -EAGAIN;1939 1940 dasd_sfree_request(cqr, cqr->memdev);1941 return rc;1942}1943 1944/*1945 * Valide storage server of current device.1946 */1947static int dasd_eckd_validate_server(struct dasd_device *device,1948 unsigned long flags)1949{1950 struct dasd_eckd_private *private = device->private;1951 int enable_pav, rc;1952 1953 if (private->uid.type == UA_BASE_PAV_ALIAS ||1954 private->uid.type == UA_HYPER_PAV_ALIAS)1955 return 0;1956 if (dasd_nopav || MACHINE_IS_VM)1957 enable_pav = 0;1958 else1959 enable_pav = 1;1960 rc = dasd_eckd_psf_ssc(device, enable_pav, flags);1961 1962 /* may be requested feature is not available on server,1963 * therefore just report error and go ahead */1964 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x "1965 "returned rc=%d", private->uid.ssid, rc);1966 return rc;1967}1968 1969/*1970 * worker to do a validate server in case of a lost pathgroup1971 */1972static void dasd_eckd_do_validate_server(struct work_struct *work)1973{1974 struct dasd_device *device = container_of(work, struct dasd_device,1975 kick_validate);1976 unsigned long flags = 0;1977 1978 set_bit(DASD_CQR_FLAGS_FAILFAST, &flags);1979 if (dasd_eckd_validate_server(device, flags)1980 == -EAGAIN) {1981 /* schedule worker again if failed */1982 schedule_work(&device->kick_validate);1983 return;1984 }1985 1986 dasd_put_device(device);1987}1988 1989static void dasd_eckd_kick_validate_server(struct dasd_device *device)1990{1991 dasd_get_device(device);1992 /* exit if device not online or in offline processing */1993 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||1994 device->state < DASD_STATE_ONLINE) {1995 dasd_put_device(device);1996 return;1997 }1998 /* queue call to do_validate_server to the kernel event daemon. */1999 if (!schedule_work(&device->kick_validate))2000 dasd_put_device(device);2001}2002 2003/*2004 * return if the device is the copy relation primary if a copy relation is active2005 */2006static int dasd_device_is_primary(struct dasd_device *device)2007{2008 if (!device->copy)2009 return 1;2010 2011 if (device->copy->active->device == device)2012 return 1;2013 2014 return 0;2015}2016 2017static int dasd_eckd_alloc_block(struct dasd_device *device)2018{2019 struct dasd_block *block;2020 struct dasd_uid temp_uid;2021 2022 if (!dasd_device_is_primary(device))2023 return 0;2024 2025 dasd_eckd_get_uid(device, &temp_uid);2026 if (temp_uid.type == UA_BASE_DEVICE) {2027 block = dasd_alloc_block();2028 if (IS_ERR(block)) {2029 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",2030 "could not allocate dasd block structure");2031 return PTR_ERR(block);2032 }2033 device->block = block;2034 block->base = device;2035 }2036 return 0;2037}2038 2039static bool dasd_eckd_pprc_enabled(struct dasd_device *device)2040{2041 struct dasd_eckd_private *private = device->private;2042 2043 return private->rdc_data.facilities.PPRC_enabled;2044}2045 2046/*2047 * Check device characteristics.2048 * If the device is accessible using ECKD discipline, the device is enabled.2049 */2050static int2051dasd_eckd_check_characteristics(struct dasd_device *device)2052{2053 struct dasd_eckd_private *private = device->private;2054 int rc, i;2055 int readonly;2056 unsigned long value;2057 2058 /* setup work queue for validate server*/2059 INIT_WORK(&device->kick_validate, dasd_eckd_do_validate_server);2060 /* setup work queue for summary unit check */2061 INIT_WORK(&device->suc_work, dasd_alias_handle_summary_unit_check);2062 2063 if (!ccw_device_is_pathgroup(device->cdev)) {2064 dev_warn(&device->cdev->dev,2065 "A channel path group could not be established\n");2066 return -EIO;2067 }2068 if (!ccw_device_is_multipath(device->cdev)) {2069 dev_info(&device->cdev->dev,2070 "The DASD is not operating in multipath mode\n");2071 }2072 if (!private) {2073 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);2074 if (!private) {2075 dev_warn(&device->cdev->dev,2076 "Allocating memory for private DASD data "2077 "failed\n");2078 return -ENOMEM;2079 }2080 device->private = private;2081 } else {2082 memset(private, 0, sizeof(*private));2083 }2084 /* Invalidate status of initial analysis. */2085 private->init_cqr_status = -1;2086 /* Set default cache operations. */2087 private->attrib.operation = DASD_NORMAL_CACHE;2088 private->attrib.nr_cyl = 0;2089 2090 /* Read Configuration Data */2091 rc = dasd_eckd_read_conf(device);2092 if (rc)2093 goto out_err1;2094 2095 /* set some default values */2096 device->default_expires = DASD_EXPIRES;2097 device->default_retries = DASD_RETRIES;2098 device->path_thrhld = DASD_ECKD_PATH_THRHLD;2099 device->path_interval = DASD_ECKD_PATH_INTERVAL;2100 device->aq_timeouts = DASD_RETRIES_MAX;2101 2102 if (private->conf.gneq) {2103 value = 1;2104 for (i = 0; i < private->conf.gneq->timeout.value; i++)2105 value = 10 * value;2106 value = value * private->conf.gneq->timeout.number;2107 /* do not accept useless values */2108 if (value != 0 && value <= DASD_EXPIRES_MAX)2109 device->default_expires = value;2110 }2111 2112 /* Read Device Characteristics */2113 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,2114 &private->rdc_data, 64);2115 if (rc) {2116 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,2117 "Read device characteristic failed, rc=%d", rc);2118 goto out_err1;2119 }2120 2121 /* setup PPRC for device from devmap */2122 rc = dasd_devmap_set_device_copy_relation(device->cdev,2123 dasd_eckd_pprc_enabled(device));2124 if (rc) {2125 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,2126 "copy relation setup failed, rc=%d", rc);2127 goto out_err1;2128 }2129 2130 /* check if block device is needed and allocate in case */2131 rc = dasd_eckd_alloc_block(device);2132 if (rc)2133 goto out_err1;2134 2135 /* register lcu with alias handling, enable PAV */2136 rc = dasd_alias_make_device_known_to_lcu(device);2137 if (rc)2138 goto out_err2;2139 2140 dasd_eckd_validate_server(device, 0);2141 2142 /* device may report different configuration data after LCU setup */2143 rc = dasd_eckd_read_conf(device);2144 if (rc)2145 goto out_err3;2146 2147 dasd_eckd_read_fc_security(device);2148 dasd_path_create_kobjects(device);2149 2150 /* Read Feature Codes */2151 dasd_eckd_read_features(device);2152 2153 /* Read Volume Information */2154 dasd_eckd_read_vol_info(device);2155 2156 /* Read Extent Pool Information */2157 dasd_eckd_read_ext_pool_info(device);2158 2159 if ((device->features & DASD_FEATURE_USERAW) &&2160 !(private->rdc_data.facilities.RT_in_LR)) {2161 dev_err(&device->cdev->dev, "The storage server does not "2162 "support raw-track access\n");2163 rc = -EINVAL;2164 goto out_err3;2165 }2166 2167 /* find the valid cylinder size */2168 if (private->rdc_data.no_cyl == LV_COMPAT_CYL &&2169 private->rdc_data.long_no_cyl)2170 private->real_cyl = private->rdc_data.long_no_cyl;2171 else2172 private->real_cyl = private->rdc_data.no_cyl;2173 2174 private->fcx_max_data = get_fcx_max_data(device);2175 2176 readonly = dasd_device_is_ro(device);2177 if (readonly)2178 set_bit(DASD_FLAG_DEVICE_RO, &device->flags);2179 2180 dev_info(&device->cdev->dev, "New DASD %04X/%02X (CU %04X/%02X) "2181 "with %d cylinders, %d heads, %d sectors%s\n",2182 private->rdc_data.dev_type,2183 private->rdc_data.dev_model,2184 private->rdc_data.cu_type,2185 private->rdc_data.cu_model.model,2186 private->real_cyl,2187 private->rdc_data.trk_per_cyl,2188 private->rdc_data.sec_per_trk,2189 readonly ? ", read-only device" : "");2190 return 0;2191 2192out_err3:2193 dasd_alias_disconnect_device_from_lcu(device);2194out_err2:2195 dasd_free_block(device->block);2196 device->block = NULL;2197out_err1:2198 dasd_eckd_clear_conf_data(device);2199 dasd_path_remove_kobjects(device);2200 kfree(device->private);2201 device->private = NULL;2202 return rc;2203}2204 2205static void dasd_eckd_uncheck_device(struct dasd_device *device)2206{2207 struct dasd_eckd_private *private = device->private;2208 2209 if (!private)2210 return;2211 2212 dasd_alias_disconnect_device_from_lcu(device);2213 private->conf.ned = NULL;2214 private->conf.sneq = NULL;2215 private->conf.vdsneq = NULL;2216 private->conf.gneq = NULL;2217 dasd_eckd_clear_conf_data(device);2218 dasd_path_remove_kobjects(device);2219}2220 2221static struct dasd_ccw_req *2222dasd_eckd_analysis_ccw(struct dasd_device *device)2223{2224 struct dasd_eckd_private *private = device->private;2225 struct eckd_count *count_data;2226 struct LO_eckd_data *LO_data;2227 struct dasd_ccw_req *cqr;2228 struct ccw1 *ccw;2229 int cplength, datasize;2230 int i;2231 2232 cplength = 8;2233 datasize = sizeof(struct DE_eckd_data) + 2*sizeof(struct LO_eckd_data);2234 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize, device,2235 NULL);2236 if (IS_ERR(cqr))2237 return cqr;2238 ccw = cqr->cpaddr;2239 /* Define extent for the first 2 tracks. */2240 define_extent(ccw++, cqr->data, 0, 1,2241 DASD_ECKD_CCW_READ_COUNT, device, 0);2242 LO_data = cqr->data + sizeof(struct DE_eckd_data);2243 /* Locate record for the first 4 records on track 0. */2244 ccw[-1].flags |= CCW_FLAG_CC;2245 locate_record(ccw++, LO_data++, 0, 0, 4,2246 DASD_ECKD_CCW_READ_COUNT, device, 0);2247 2248 count_data = private->count_area;2249 for (i = 0; i < 4; i++) {2250 ccw[-1].flags |= CCW_FLAG_CC;2251 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;2252 ccw->flags = 0;2253 ccw->count = 8;2254 ccw->cda = virt_to_dma32(count_data);2255 ccw++;2256 count_data++;2257 }2258 2259 /* Locate record for the first record on track 1. */2260 ccw[-1].flags |= CCW_FLAG_CC;2261 locate_record(ccw++, LO_data++, 1, 0, 1,2262 DASD_ECKD_CCW_READ_COUNT, device, 0);2263 /* Read count ccw. */2264 ccw[-1].flags |= CCW_FLAG_CC;2265 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;2266 ccw->flags = 0;2267 ccw->count = 8;2268 ccw->cda = virt_to_dma32(count_data);2269 2270 cqr->block = NULL;2271 cqr->startdev = device;2272 cqr->memdev = device;2273 cqr->retries = 255;2274 cqr->buildclk = get_tod_clock();2275 cqr->status = DASD_CQR_FILLED;2276 /* Set flags to suppress output for expected errors */2277 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);2278 set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);2279 2280 return cqr;2281}2282 2283/* differentiate between 'no record found' and any other error */2284static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr)2285{2286 char *sense;2287 if (init_cqr->status == DASD_CQR_DONE)2288 return INIT_CQR_OK;2289 else if (init_cqr->status == DASD_CQR_NEED_ERP ||2290 init_cqr->status == DASD_CQR_FAILED) {2291 sense = dasd_get_sense(&init_cqr->irb);2292 if (sense && (sense[1] & SNS1_NO_REC_FOUND))2293 return INIT_CQR_UNFORMATTED;2294 else2295 return INIT_CQR_ERROR;2296 } else2297 return INIT_CQR_ERROR;2298}2299 2300/*2301 * This is the callback function for the init_analysis cqr. It saves2302 * the status of the initial analysis ccw before it frees it and kicks2303 * the device to continue the startup sequence. This will call2304 * dasd_eckd_do_analysis again (if the devices has not been marked2305 * for deletion in the meantime).2306 */2307static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr,2308 void *data)2309{2310 struct dasd_device *device = init_cqr->startdev;2311 struct dasd_eckd_private *private = device->private;2312 2313 private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr);2314 dasd_sfree_request(init_cqr, device);2315 dasd_kick_device(device);2316}2317 2318static int dasd_eckd_start_analysis(struct dasd_block *block)2319{2320 struct dasd_ccw_req *init_cqr;2321 2322 init_cqr = dasd_eckd_analysis_ccw(block->base);2323 if (IS_ERR(init_cqr))2324 return PTR_ERR(init_cqr);2325 init_cqr->callback = dasd_eckd_analysis_callback;2326 init_cqr->callback_data = NULL;2327 init_cqr->expires = 5*HZ;2328 /* first try without ERP, so we can later handle unformatted2329 * devices as special case2330 */2331 clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags);2332 init_cqr->retries = 0;2333 dasd_add_request_head(init_cqr);2334 return -EAGAIN;2335}2336 2337static int dasd_eckd_end_analysis(struct dasd_block *block)2338{2339 struct dasd_device *device = block->base;2340 struct dasd_eckd_private *private = device->private;2341 struct eckd_count *count_area;2342 unsigned int sb, blk_per_trk;2343 int status, i;2344 struct dasd_ccw_req *init_cqr;2345 2346 status = private->init_cqr_status;2347 private->init_cqr_status = -1;2348 if (status == INIT_CQR_ERROR) {2349 /* try again, this time with full ERP */2350 init_cqr = dasd_eckd_analysis_ccw(device);2351 dasd_sleep_on(init_cqr);2352 status = dasd_eckd_analysis_evaluation(init_cqr);2353 dasd_sfree_request(init_cqr, device);2354 }2355 2356 if (device->features & DASD_FEATURE_USERAW) {2357 block->bp_block = DASD_RAW_BLOCKSIZE;2358 blk_per_trk = DASD_RAW_BLOCK_PER_TRACK;2359 block->s2b_shift = 3;2360 goto raw;2361 }2362 2363 if (status == INIT_CQR_UNFORMATTED) {2364 dev_warn(&device->cdev->dev, "The DASD is not formatted\n");2365 return -EMEDIUMTYPE;2366 } else if (status == INIT_CQR_ERROR) {2367 dev_err(&device->cdev->dev,2368 "Detecting the DASD disk layout failed because "2369 "of an I/O error\n");2370 return -EIO;2371 }2372 2373 private->uses_cdl = 1;2374 /* Check Track 0 for Compatible Disk Layout */2375 count_area = NULL;2376 for (i = 0; i < 3; i++) {2377 if (private->count_area[i].kl != 4 ||2378 private->count_area[i].dl != dasd_eckd_cdl_reclen(i) - 4 ||2379 private->count_area[i].cyl != 0 ||2380 private->count_area[i].head != count_area_head[i] ||2381 private->count_area[i].record != count_area_rec[i]) {2382 private->uses_cdl = 0;2383 break;2384 }2385 }2386 if (i == 3)2387 count_area = &private->count_area[3];2388 2389 if (private->uses_cdl == 0) {2390 for (i = 0; i < 5; i++) {2391 if ((private->count_area[i].kl != 0) ||2392 (private->count_area[i].dl !=2393 private->count_area[0].dl) ||2394 private->count_area[i].cyl != 0 ||2395 private->count_area[i].head != count_area_head[i] ||2396 private->count_area[i].record != count_area_rec[i])2397 break;2398 }2399 if (i == 5)2400 count_area = &private->count_area[0];2401 } else {2402 if (private->count_area[3].record == 1)2403 dev_warn(&device->cdev->dev,2404 "Track 0 has no records following the VTOC\n");2405 }2406 2407 if (count_area != NULL && count_area->kl == 0) {2408 /* we found notthing violating our disk layout */2409 if (dasd_check_blocksize(count_area->dl) == 0)2410 block->bp_block = count_area->dl;2411 }2412 if (block->bp_block == 0) {2413 dev_warn(&device->cdev->dev,2414 "The disk layout of the DASD is not supported\n");2415 return -EMEDIUMTYPE;2416 }2417 block->s2b_shift = 0; /* bits to shift 512 to get a block */2418 for (sb = 512; sb < block->bp_block; sb = sb << 1)2419 block->s2b_shift++;2420 2421 blk_per_trk = recs_per_track(&private->rdc_data, 0, block->bp_block);2422 2423raw:2424 block->blocks = ((unsigned long) private->real_cyl *2425 private->rdc_data.trk_per_cyl *2426 blk_per_trk);2427 2428 dev_info(&device->cdev->dev,2429 "DASD with %u KB/block, %lu KB total size, %u KB/track, "2430 "%s\n", (block->bp_block >> 10),2431 (((unsigned long) private->real_cyl *2432 private->rdc_data.trk_per_cyl *2433 blk_per_trk * (block->bp_block >> 9)) >> 1),2434 ((blk_per_trk * block->bp_block) >> 10),2435 private->uses_cdl ?2436 "compatible disk layout" : "linux disk layout");2437 2438 return 0;2439}2440 2441static int dasd_eckd_do_analysis(struct dasd_block *block)2442{2443 struct dasd_eckd_private *private = block->base->private;2444 2445 if (private->init_cqr_status < 0)2446 return dasd_eckd_start_analysis(block);2447 else2448 return dasd_eckd_end_analysis(block);2449}2450 2451static int dasd_eckd_basic_to_ready(struct dasd_device *device)2452{2453 return dasd_alias_add_device(device);2454};2455 2456static int dasd_eckd_online_to_ready(struct dasd_device *device)2457{2458 if (cancel_work_sync(&device->reload_device))2459 dasd_put_device(device);2460 if (cancel_work_sync(&device->kick_validate))2461 dasd_put_device(device);2462 2463 return 0;2464};2465 2466static int dasd_eckd_basic_to_known(struct dasd_device *device)2467{2468 return dasd_alias_remove_device(device);2469};2470 2471static int2472dasd_eckd_fill_geometry(struct dasd_block *block, struct hd_geometry *geo)2473{2474 struct dasd_eckd_private *private = block->base->private;2475 2476 if (dasd_check_blocksize(block->bp_block) == 0) {2477 geo->sectors = recs_per_track(&private->rdc_data,2478 0, block->bp_block);2479 }2480 geo->cylinders = private->rdc_data.no_cyl;2481 geo->heads = private->rdc_data.trk_per_cyl;2482 return 0;2483}2484 2485/*2486 * Build the TCW request for the format check2487 */2488static struct dasd_ccw_req *2489dasd_eckd_build_check_tcw(struct dasd_device *base, struct format_data_t *fdata,2490 int enable_pav, struct eckd_count *fmt_buffer,2491 int rpt)2492{2493 struct dasd_eckd_private *start_priv;2494 struct dasd_device *startdev = NULL;2495 struct tidaw *last_tidaw = NULL;2496 struct dasd_ccw_req *cqr;2497 struct itcw *itcw;2498 int itcw_size;2499 int count;2500 int rc;2501 int i;2502 2503 if (enable_pav)2504 startdev = dasd_alias_get_start_dev(base);2505 2506 if (!startdev)2507 startdev = base;2508 2509 start_priv = startdev->private;2510 2511 count = rpt * (fdata->stop_unit - fdata->start_unit + 1);2512 2513 /*2514 * we're adding 'count' amount of tidaw to the itcw.2515 * calculate the corresponding itcw_size2516 */2517 itcw_size = itcw_calc_size(0, count, 0);2518 2519 cqr = dasd_fmalloc_request(DASD_ECKD_MAGIC, 0, itcw_size, startdev);2520 if (IS_ERR(cqr))2521 return cqr;2522 2523 start_priv->count++;2524 2525 itcw = itcw_init(cqr->data, itcw_size, ITCW_OP_READ, 0, count, 0);2526 if (IS_ERR(itcw)) {2527 rc = -EINVAL;2528 goto out_err;2529 }2530 2531 cqr->cpaddr = itcw_get_tcw(itcw);2532 rc = prepare_itcw(itcw, fdata->start_unit, fdata->stop_unit,2533 DASD_ECKD_CCW_READ_COUNT_MT, base, startdev, 0, count,2534 sizeof(struct eckd_count),2535 count * sizeof(struct eckd_count), 0, rpt);2536 if (rc)2537 goto out_err;2538 2539 for (i = 0; i < count; i++) {2540 last_tidaw = itcw_add_tidaw(itcw, 0, fmt_buffer++,2541 sizeof(struct eckd_count));2542 if (IS_ERR(last_tidaw)) {2543 rc = -EINVAL;2544 goto out_err;2545 }2546 }2547 2548 last_tidaw->flags |= TIDAW_FLAGS_LAST;2549 itcw_finalize(itcw);2550 2551 cqr->cpmode = 1;2552 cqr->startdev = startdev;2553 cqr->memdev = startdev;2554 cqr->basedev = base;2555 cqr->retries = startdev->default_retries;2556 cqr->expires = startdev->default_expires * HZ;2557 cqr->buildclk = get_tod_clock();2558 cqr->status = DASD_CQR_FILLED;2559 /* Set flags to suppress output for expected errors */2560 set_bit(DASD_CQR_SUPPRESS_IL, &cqr->flags);2561 2562 return cqr;2563 2564out_err:2565 dasd_sfree_request(cqr, startdev);2566 2567 return ERR_PTR(rc);2568}2569 2570/*2571 * Build the CCW request for the format check2572 */2573static struct dasd_ccw_req *2574dasd_eckd_build_check(struct dasd_device *base, struct format_data_t *fdata,2575 int enable_pav, struct eckd_count *fmt_buffer, int rpt)2576{2577 struct dasd_eckd_private *start_priv;2578 struct dasd_eckd_private *base_priv;2579 struct dasd_device *startdev = NULL;2580 struct dasd_ccw_req *cqr;2581 struct ccw1 *ccw;2582 void *data;2583 int cplength, datasize;2584 int use_prefix;2585 int count;2586 int i;2587 2588 if (enable_pav)2589 startdev = dasd_alias_get_start_dev(base);2590 2591 if (!startdev)2592 startdev = base;2593 2594 start_priv = startdev->private;2595 base_priv = base->private;2596 2597 count = rpt * (fdata->stop_unit - fdata->start_unit + 1);2598 2599 use_prefix = base_priv->features.feature[8] & 0x01;2600 2601 if (use_prefix) {2602 cplength = 1;2603 datasize = sizeof(struct PFX_eckd_data);2604 } else {2605 cplength = 2;2606 datasize = sizeof(struct DE_eckd_data) +2607 sizeof(struct LO_eckd_data);2608 }2609 cplength += count;2610 2611 cqr = dasd_fmalloc_request(DASD_ECKD_MAGIC, cplength, datasize, startdev);2612 if (IS_ERR(cqr))2613 return cqr;2614 2615 start_priv->count++;2616 data = cqr->data;2617 ccw = cqr->cpaddr;2618 2619 if (use_prefix) {2620 prefix_LRE(ccw++, data, fdata->start_unit, fdata->stop_unit,2621 DASD_ECKD_CCW_READ_COUNT, base, startdev, 1, 0,2622 count, 0, 0);2623 } else {2624 define_extent(ccw++, data, fdata->start_unit, fdata->stop_unit,2625 DASD_ECKD_CCW_READ_COUNT, startdev, 0);2626 2627 data += sizeof(struct DE_eckd_data);2628 ccw[-1].flags |= CCW_FLAG_CC;2629 2630 locate_record(ccw++, data, fdata->start_unit, 0, count,2631 DASD_ECKD_CCW_READ_COUNT, base, 0);2632 }2633 2634 for (i = 0; i < count; i++) {2635 ccw[-1].flags |= CCW_FLAG_CC;2636 ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;2637 ccw->flags = CCW_FLAG_SLI;2638 ccw->count = 8;2639 ccw->cda = virt_to_dma32(fmt_buffer);2640 ccw++;2641 fmt_buffer++;2642 }2643 2644 cqr->startdev = startdev;2645 cqr->memdev = startdev;2646 cqr->basedev = base;2647 cqr->retries = DASD_RETRIES;2648 cqr->expires = startdev->default_expires * HZ;2649 cqr->buildclk = get_tod_clock();2650 cqr->status = DASD_CQR_FILLED;2651 /* Set flags to suppress output for expected errors */2652 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);2653 2654 return cqr;2655}2656 2657static struct dasd_ccw_req *2658dasd_eckd_build_format(struct dasd_device *base, struct dasd_device *startdev,2659 struct format_data_t *fdata, int enable_pav)2660{2661 struct dasd_eckd_private *base_priv;2662 struct dasd_eckd_private *start_priv;2663 struct dasd_ccw_req *fcp;2664 struct eckd_count *ect;2665 struct ch_t address;2666 struct ccw1 *ccw;2667 void *data;2668 int rpt;2669 int cplength, datasize;2670 int i, j;2671 int intensity = 0;2672 int r0_perm;2673 int nr_tracks;2674 int use_prefix;2675 2676 if (enable_pav)2677 startdev = dasd_alias_get_start_dev(base);2678 2679 if (!startdev)2680 startdev = base;2681 2682 start_priv = startdev->private;2683 base_priv = base->private;2684 2685 rpt = recs_per_track(&base_priv->rdc_data, 0, fdata->blksize);2686 2687 nr_tracks = fdata->stop_unit - fdata->start_unit + 1;2688 2689 /*2690 * fdata->intensity is a bit string that tells us what to do:2691 * Bit 0: write record zero2692 * Bit 1: write home address, currently not supported2693 * Bit 2: invalidate tracks2694 * Bit 3: use OS/390 compatible disk layout (cdl)2695 * Bit 4: do not allow storage subsystem to modify record zero2696 * Only some bit combinations do make sense.2697 */2698 if (fdata->intensity & 0x10) {2699 r0_perm = 0;2700 intensity = fdata->intensity & ~0x10;2701 } else {2702 r0_perm = 1;2703 intensity = fdata->intensity;2704 }2705 2706 use_prefix = base_priv->features.feature[8] & 0x01;2707 2708 switch (intensity) {2709 case 0x00: /* Normal format */2710 case 0x08: /* Normal format, use cdl. */2711 cplength = 2 + (rpt*nr_tracks);2712 if (use_prefix)2713 datasize = sizeof(struct PFX_eckd_data) +2714 sizeof(struct LO_eckd_data) +2715 rpt * nr_tracks * sizeof(struct eckd_count);2716 else2717 datasize = sizeof(struct DE_eckd_data) +2718 sizeof(struct LO_eckd_data) +2719 rpt * nr_tracks * sizeof(struct eckd_count);2720 break;2721 case 0x01: /* Write record zero and format track. */2722 case 0x09: /* Write record zero and format track, use cdl. */2723 cplength = 2 + rpt * nr_tracks;2724 if (use_prefix)2725 datasize = sizeof(struct PFX_eckd_data) +2726 sizeof(struct LO_eckd_data) +2727 sizeof(struct eckd_count) +2728 rpt * nr_tracks * sizeof(struct eckd_count);2729 else2730 datasize = sizeof(struct DE_eckd_data) +2731 sizeof(struct LO_eckd_data) +2732 sizeof(struct eckd_count) +2733 rpt * nr_tracks * sizeof(struct eckd_count);2734 break;2735 case 0x04: /* Invalidate track. */2736 case 0x0c: /* Invalidate track, use cdl. */2737 cplength = 3;2738 if (use_prefix)2739 datasize = sizeof(struct PFX_eckd_data) +2740 sizeof(struct LO_eckd_data) +2741 sizeof(struct eckd_count);2742 else2743 datasize = sizeof(struct DE_eckd_data) +2744 sizeof(struct LO_eckd_data) +2745 sizeof(struct eckd_count);2746 break;2747 default:2748 dev_warn(&startdev->cdev->dev,2749 "An I/O control call used incorrect flags 0x%x\n",2750 fdata->intensity);2751 return ERR_PTR(-EINVAL);2752 }2753 2754 fcp = dasd_fmalloc_request(DASD_ECKD_MAGIC, cplength, datasize, startdev);2755 if (IS_ERR(fcp))2756 return fcp;2757 2758 start_priv->count++;2759 data = fcp->data;2760 ccw = fcp->cpaddr;2761 2762 switch (intensity & ~0x08) {2763 case 0x00: /* Normal format. */2764 if (use_prefix) {2765 prefix(ccw++, (struct PFX_eckd_data *) data,2766 fdata->start_unit, fdata->stop_unit,2767 DASD_ECKD_CCW_WRITE_CKD, base, startdev);2768 /* grant subsystem permission to format R0 */2769 if (r0_perm)2770 ((struct PFX_eckd_data *)data)2771 ->define_extent.ga_extended |= 0x04;2772 data += sizeof(struct PFX_eckd_data);2773 } else {2774 define_extent(ccw++, (struct DE_eckd_data *) data,2775 fdata->start_unit, fdata->stop_unit,2776 DASD_ECKD_CCW_WRITE_CKD, startdev, 0);2777 /* grant subsystem permission to format R0 */2778 if (r0_perm)2779 ((struct DE_eckd_data *) data)2780 ->ga_extended |= 0x04;2781 data += sizeof(struct DE_eckd_data);2782 }2783 ccw[-1].flags |= CCW_FLAG_CC;2784 locate_record(ccw++, (struct LO_eckd_data *) data,2785 fdata->start_unit, 0, rpt*nr_tracks,2786 DASD_ECKD_CCW_WRITE_CKD, base,2787 fdata->blksize);2788 data += sizeof(struct LO_eckd_data);2789 break;2790 case 0x01: /* Write record zero + format track. */2791 if (use_prefix) {2792 prefix(ccw++, (struct PFX_eckd_data *) data,2793 fdata->start_unit, fdata->stop_unit,2794 DASD_ECKD_CCW_WRITE_RECORD_ZERO,2795 base, startdev);2796 data += sizeof(struct PFX_eckd_data);2797 } else {2798 define_extent(ccw++, (struct DE_eckd_data *) data,2799 fdata->start_unit, fdata->stop_unit,2800 DASD_ECKD_CCW_WRITE_RECORD_ZERO, startdev, 0);2801 data += sizeof(struct DE_eckd_data);2802 }2803 ccw[-1].flags |= CCW_FLAG_CC;2804 locate_record(ccw++, (struct LO_eckd_data *) data,2805 fdata->start_unit, 0, rpt * nr_tracks + 1,2806 DASD_ECKD_CCW_WRITE_RECORD_ZERO, base,2807 base->block->bp_block);2808 data += sizeof(struct LO_eckd_data);2809 break;2810 case 0x04: /* Invalidate track. */2811 if (use_prefix) {2812 prefix(ccw++, (struct PFX_eckd_data *) data,2813 fdata->start_unit, fdata->stop_unit,2814 DASD_ECKD_CCW_WRITE_CKD, base, startdev);2815 data += sizeof(struct PFX_eckd_data);2816 } else {2817 define_extent(ccw++, (struct DE_eckd_data *) data,2818 fdata->start_unit, fdata->stop_unit,2819 DASD_ECKD_CCW_WRITE_CKD, startdev, 0);2820 data += sizeof(struct DE_eckd_data);2821 }2822 ccw[-1].flags |= CCW_FLAG_CC;2823 locate_record(ccw++, (struct LO_eckd_data *) data,2824 fdata->start_unit, 0, 1,2825 DASD_ECKD_CCW_WRITE_CKD, base, 8);2826 data += sizeof(struct LO_eckd_data);2827 break;2828 }2829 2830 for (j = 0; j < nr_tracks; j++) {2831 /* calculate cylinder and head for the current track */2832 set_ch_t(&address,2833 (fdata->start_unit + j) /2834 base_priv->rdc_data.trk_per_cyl,2835 (fdata->start_unit + j) %2836 base_priv->rdc_data.trk_per_cyl);2837 if (intensity & 0x01) { /* write record zero */2838 ect = (struct eckd_count *) data;2839 data += sizeof(struct eckd_count);2840 ect->cyl = address.cyl;2841 ect->head = address.head;2842 ect->record = 0;2843 ect->kl = 0;2844 ect->dl = 8;2845 ccw[-1].flags |= CCW_FLAG_CC;2846 ccw->cmd_code = DASD_ECKD_CCW_WRITE_RECORD_ZERO;2847 ccw->flags = CCW_FLAG_SLI;2848 ccw->count = 8;2849 ccw->cda = virt_to_dma32(ect);2850 ccw++;2851 }2852 if ((intensity & ~0x08) & 0x04) { /* erase track */2853 ect = (struct eckd_count *) data;2854 data += sizeof(struct eckd_count);2855 ect->cyl = address.cyl;2856 ect->head = address.head;2857 ect->record = 1;2858 ect->kl = 0;2859 ect->dl = 0;2860 ccw[-1].flags |= CCW_FLAG_CC;2861 ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;2862 ccw->flags = CCW_FLAG_SLI;2863 ccw->count = 8;2864 ccw->cda = virt_to_dma32(ect);2865 } else { /* write remaining records */2866 for (i = 0; i < rpt; i++) {2867 ect = (struct eckd_count *) data;2868 data += sizeof(struct eckd_count);2869 ect->cyl = address.cyl;2870 ect->head = address.head;2871 ect->record = i + 1;2872 ect->kl = 0;2873 ect->dl = fdata->blksize;2874 /*2875 * Check for special tracks 0-12876 * when formatting CDL2877 */2878 if ((intensity & 0x08) &&2879 address.cyl == 0 && address.head == 0) {2880 if (i < 3) {2881 ect->kl = 4;2882 ect->dl = sizes_trk0[i] - 4;2883 }2884 }2885 if ((intensity & 0x08) &&2886 address.cyl == 0 && address.head == 1) {2887 ect->kl = 44;2888 ect->dl = LABEL_SIZE - 44;2889 }2890 ccw[-1].flags |= CCW_FLAG_CC;2891 if (i != 0 || j == 0)2892 ccw->cmd_code =2893 DASD_ECKD_CCW_WRITE_CKD;2894 else2895 ccw->cmd_code =2896 DASD_ECKD_CCW_WRITE_CKD_MT;2897 ccw->flags = CCW_FLAG_SLI;2898 ccw->count = 8;2899 ccw->cda = virt_to_dma32(ect);2900 ccw++;2901 }2902 }2903 }2904 2905 fcp->startdev = startdev;2906 fcp->memdev = startdev;2907 fcp->basedev = base;2908 fcp->retries = 256;2909 fcp->expires = startdev->default_expires * HZ;2910 fcp->buildclk = get_tod_clock();2911 fcp->status = DASD_CQR_FILLED;2912 2913 return fcp;2914}2915 2916/*2917 * Wrapper function to build a CCW request depending on input data2918 */2919static struct dasd_ccw_req *2920dasd_eckd_format_build_ccw_req(struct dasd_device *base,2921 struct format_data_t *fdata, int enable_pav,2922 int tpm, struct eckd_count *fmt_buffer, int rpt)2923{2924 struct dasd_ccw_req *ccw_req;2925 2926 if (!fmt_buffer) {2927 ccw_req = dasd_eckd_build_format(base, NULL, fdata, enable_pav);2928 } else {2929 if (tpm)2930 ccw_req = dasd_eckd_build_check_tcw(base, fdata,2931 enable_pav,2932 fmt_buffer, rpt);2933 else2934 ccw_req = dasd_eckd_build_check(base, fdata, enable_pav,2935 fmt_buffer, rpt);2936 }2937 2938 return ccw_req;2939}2940 2941/*2942 * Sanity checks on format_data2943 */2944static int dasd_eckd_format_sanity_checks(struct dasd_device *base,2945 struct format_data_t *fdata)2946{2947 struct dasd_eckd_private *private = base->private;2948 2949 if (fdata->start_unit >=2950 (private->real_cyl * private->rdc_data.trk_per_cyl)) {2951 dev_warn(&base->cdev->dev,2952 "Start track number %u used in formatting is too big\n",2953 fdata->start_unit);2954 return -EINVAL;2955 }2956 if (fdata->stop_unit >=2957 (private->real_cyl * private->rdc_data.trk_per_cyl)) {2958 dev_warn(&base->cdev->dev,2959 "Stop track number %u used in formatting is too big\n",2960 fdata->stop_unit);2961 return -EINVAL;2962 }2963 if (fdata->start_unit > fdata->stop_unit) {2964 dev_warn(&base->cdev->dev,2965 "Start track %u used in formatting exceeds end track\n",2966 fdata->start_unit);2967 return -EINVAL;2968 }2969 if (dasd_check_blocksize(fdata->blksize) != 0) {2970 dev_warn(&base->cdev->dev,2971 "The DASD cannot be formatted with block size %u\n",2972 fdata->blksize);2973 return -EINVAL;2974 }2975 return 0;2976}2977 2978/*2979 * This function will process format_data originally coming from an IOCTL2980 */2981static int dasd_eckd_format_process_data(struct dasd_device *base,2982 struct format_data_t *fdata,2983 int enable_pav, int tpm,2984 struct eckd_count *fmt_buffer, int rpt,2985 struct irb *irb)2986{2987 struct dasd_eckd_private *private = base->private;2988 struct dasd_ccw_req *cqr, *n;2989 struct list_head format_queue;2990 struct dasd_device *device;2991 char *sense = NULL;2992 int old_start, old_stop, format_step;2993 int step, retry;2994 int rc;2995 2996 rc = dasd_eckd_format_sanity_checks(base, fdata);2997 if (rc)2998 return rc;2999 3000 INIT_LIST_HEAD(&format_queue);3001 3002 old_start = fdata->start_unit;3003 old_stop = fdata->stop_unit;3004 3005 if (!tpm && fmt_buffer != NULL) {3006 /* Command Mode / Format Check */3007 format_step = 1;3008 } else if (tpm && fmt_buffer != NULL) {3009 /* Transport Mode / Format Check */3010 format_step = DASD_CQR_MAX_CCW / rpt;3011 } else {3012 /* Normal Formatting */3013 format_step = DASD_CQR_MAX_CCW /3014 recs_per_track(&private->rdc_data, 0, fdata->blksize);3015 }3016 3017 do {3018 retry = 0;3019 while (fdata->start_unit <= old_stop) {3020 step = fdata->stop_unit - fdata->start_unit + 1;3021 if (step > format_step) {3022 fdata->stop_unit =3023 fdata->start_unit + format_step - 1;3024 }3025 3026 cqr = dasd_eckd_format_build_ccw_req(base, fdata,3027 enable_pav, tpm,3028 fmt_buffer, rpt);3029 if (IS_ERR(cqr)) {3030 rc = PTR_ERR(cqr);3031 if (rc == -ENOMEM) {3032 if (list_empty(&format_queue))3033 goto out;3034 /*3035 * not enough memory available, start3036 * requests retry after first requests3037 * were finished3038 */3039 retry = 1;3040 break;3041 }3042 goto out_err;3043 }3044 list_add_tail(&cqr->blocklist, &format_queue);3045 3046 if (fmt_buffer) {3047 step = fdata->stop_unit - fdata->start_unit + 1;3048 fmt_buffer += rpt * step;3049 }3050 fdata->start_unit = fdata->stop_unit + 1;3051 fdata->stop_unit = old_stop;3052 }3053 3054 rc = dasd_sleep_on_queue(&format_queue);3055 3056out_err:3057 list_for_each_entry_safe(cqr, n, &format_queue, blocklist) {3058 device = cqr->startdev;3059 private = device->private;3060 3061 if (cqr->status == DASD_CQR_FAILED) {3062 /*3063 * Only get sense data if called by format3064 * check3065 */3066 if (fmt_buffer && irb) {3067 sense = dasd_get_sense(&cqr->irb);3068 memcpy(irb, &cqr->irb, sizeof(*irb));3069 }3070 rc = -EIO;3071 }3072 list_del_init(&cqr->blocklist);3073 dasd_ffree_request(cqr, device);3074 private->count--;3075 }3076 3077 if (rc && rc != -EIO)3078 goto out;3079 if (rc == -EIO) {3080 /*3081 * In case fewer than the expected records are on the3082 * track, we will most likely get a 'No Record Found'3083 * error (in command mode) or a 'File Protected' error3084 * (in transport mode). Those particular cases shouldn't3085 * pass the -EIO to the IOCTL, therefore reset the rc3086 * and continue.3087 */3088 if (sense &&3089 (sense[1] & SNS1_NO_REC_FOUND ||3090 sense[1] & SNS1_FILE_PROTECTED))3091 retry = 1;3092 else3093 goto out;3094 }3095 3096 } while (retry);3097 3098out:3099 fdata->start_unit = old_start;3100 fdata->stop_unit = old_stop;3101 3102 return rc;3103}3104 3105static int dasd_eckd_format_device(struct dasd_device *base,3106 struct format_data_t *fdata, int enable_pav)3107{3108 return dasd_eckd_format_process_data(base, fdata, enable_pav, 0, NULL,3109 0, NULL);3110}3111 3112static bool test_and_set_format_track(struct dasd_format_entry *to_format,3113 struct dasd_ccw_req *cqr)3114{3115 struct dasd_block *block = cqr->block;3116 struct dasd_format_entry *format;3117 unsigned long flags;3118 bool rc = false;3119 3120 spin_lock_irqsave(&block->format_lock, flags);3121 if (cqr->trkcount != atomic_read(&block->trkcount)) {3122 /*3123 * The number of formatted tracks has changed after request3124 * start and we can not tell if the current track was involved.3125 * To avoid data corruption treat it as if the current track is3126 * involved3127 */3128 rc = true;3129 goto out;3130 }3131 list_for_each_entry(format, &block->format_list, list) {3132 if (format->track == to_format->track) {3133 rc = true;3134 goto out;3135 }3136 }3137 list_add_tail(&to_format->list, &block->format_list);3138 3139out:3140 spin_unlock_irqrestore(&block->format_lock, flags);3141 return rc;3142}3143 3144static void clear_format_track(struct dasd_format_entry *format,3145 struct dasd_block *block)3146{3147 unsigned long flags;3148 3149 spin_lock_irqsave(&block->format_lock, flags);3150 atomic_inc(&block->trkcount);3151 list_del_init(&format->list);3152 spin_unlock_irqrestore(&block->format_lock, flags);3153}3154 3155/*3156 * Callback function to free ESE format requests.3157 */3158static void dasd_eckd_ese_format_cb(struct dasd_ccw_req *cqr, void *data)3159{3160 struct dasd_device *device = cqr->startdev;3161 struct dasd_eckd_private *private = device->private;3162 struct dasd_format_entry *format = data;3163 3164 clear_format_track(format, cqr->basedev->block);3165 private->count--;3166 dasd_ffree_request(cqr, device);3167}3168 3169static struct dasd_ccw_req *3170dasd_eckd_ese_format(struct dasd_device *startdev, struct dasd_ccw_req *cqr,3171 struct irb *irb)3172{3173 struct dasd_eckd_private *private;3174 struct dasd_format_entry *format;3175 struct format_data_t fdata;3176 unsigned int recs_per_trk;3177 struct dasd_ccw_req *fcqr;3178 struct dasd_device *base;3179 struct dasd_block *block;3180 unsigned int blksize;3181 struct request *req;3182 sector_t first_trk;3183 sector_t last_trk;3184 sector_t curr_trk;3185 int rc;3186 3187 req = dasd_get_callback_data(cqr);3188 block = cqr->block;3189 base = block->base;3190 private = base->private;3191 blksize = block->bp_block;3192 recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize);3193 format = &startdev->format_entry;3194 3195 first_trk = blk_rq_pos(req) >> block->s2b_shift;3196 sector_div(first_trk, recs_per_trk);3197 last_trk =3198 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;3199 sector_div(last_trk, recs_per_trk);3200 rc = dasd_eckd_track_from_irb(irb, base, &curr_trk);3201 if (rc)3202 return ERR_PTR(rc);3203 3204 if (curr_trk < first_trk || curr_trk > last_trk) {3205 DBF_DEV_EVENT(DBF_WARNING, startdev,3206 "ESE error track %llu not within range %llu - %llu\n",3207 curr_trk, first_trk, last_trk);3208 return ERR_PTR(-EINVAL);3209 }3210 format->track = curr_trk;3211 /* test if track is already in formatting by another thread */3212 if (test_and_set_format_track(format, cqr)) {3213 /* this is no real error so do not count down retries */3214 cqr->retries++;3215 return ERR_PTR(-EEXIST);3216 }3217 3218 fdata.start_unit = curr_trk;3219 fdata.stop_unit = curr_trk;3220 fdata.blksize = blksize;3221 fdata.intensity = private->uses_cdl ? DASD_FMT_INT_COMPAT : 0;3222 3223 rc = dasd_eckd_format_sanity_checks(base, &fdata);3224 if (rc)3225 return ERR_PTR(-EINVAL);3226 3227 /*3228 * We're building the request with PAV disabled as we're reusing3229 * the former startdev.3230 */3231 fcqr = dasd_eckd_build_format(base, startdev, &fdata, 0);3232 if (IS_ERR(fcqr))3233 return fcqr;3234 3235 fcqr->callback = dasd_eckd_ese_format_cb;3236 fcqr->callback_data = (void *) format;3237 3238 return fcqr;3239}3240 3241/*3242 * When data is read from an unformatted area of an ESE volume, this function3243 * returns zeroed data and thereby mimics a read of zero data.3244 *3245 * The first unformatted track is the one that got the NRF error, the address is3246 * encoded in the sense data.3247 *3248 * All tracks before have returned valid data and should not be touched.3249 * All tracks after the unformatted track might be formatted or not. This is3250 * currently not known, remember the processed data and return the remainder of3251 * the request to the blocklayer in __dasd_cleanup_cqr().3252 */3253static int dasd_eckd_ese_read(struct dasd_ccw_req *cqr, struct irb *irb)3254{3255 struct dasd_eckd_private *private;3256 sector_t first_trk, last_trk;3257 sector_t first_blk, last_blk;3258 unsigned int blksize, off;3259 unsigned int recs_per_trk;3260 struct dasd_device *base;3261 struct req_iterator iter;3262 struct dasd_block *block;3263 unsigned int skip_block;3264 unsigned int blk_count;3265 struct request *req;3266 struct bio_vec bv;3267 sector_t curr_trk;3268 sector_t end_blk;3269 char *dst;3270 int rc;3271 3272 req = (struct request *) cqr->callback_data;3273 base = cqr->block->base;3274 blksize = base->block->bp_block;3275 block = cqr->block;3276 private = base->private;3277 skip_block = 0;3278 blk_count = 0;3279 3280 recs_per_trk = recs_per_track(&private->rdc_data, 0, blksize);3281 first_trk = first_blk = blk_rq_pos(req) >> block->s2b_shift;3282 sector_div(first_trk, recs_per_trk);3283 last_trk = last_blk =3284 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;3285 sector_div(last_trk, recs_per_trk);3286 rc = dasd_eckd_track_from_irb(irb, base, &curr_trk);3287 if (rc)3288 return rc;3289 3290 /* sanity check if the current track from sense data is valid */3291 if (curr_trk < first_trk || curr_trk > last_trk) {3292 DBF_DEV_EVENT(DBF_WARNING, base,3293 "ESE error track %llu not within range %llu - %llu\n",3294 curr_trk, first_trk, last_trk);3295 return -EINVAL;3296 }3297 3298 /*3299 * if not the first track got the NRF error we have to skip over valid3300 * blocks3301 */3302 if (curr_trk != first_trk)3303 skip_block = curr_trk * recs_per_trk - first_blk;3304 3305 /* we have no information beyond the current track */3306 end_blk = (curr_trk + 1) * recs_per_trk;3307 3308 rq_for_each_segment(bv, req, iter) {3309 dst = bvec_virt(&bv);3310 for (off = 0; off < bv.bv_len; off += blksize) {3311 if (first_blk + blk_count >= end_blk) {3312 cqr->proc_bytes = blk_count * blksize;3313 return 0;3314 }3315 if (dst && !skip_block)3316 memset(dst, 0, blksize);3317 else3318 skip_block--;3319 dst += blksize;3320 blk_count++;3321 }3322 }3323 return 0;3324}3325 3326/*3327 * Helper function to count consecutive records of a single track.3328 */3329static int dasd_eckd_count_records(struct eckd_count *fmt_buffer, int start,3330 int max)3331{3332 int head;3333 int i;3334 3335 head = fmt_buffer[start].head;3336 3337 /*3338 * There are 3 conditions where we stop counting:3339 * - if data reoccurs (same head and record may reoccur), which may3340 * happen due to the way DASD_ECKD_CCW_READ_COUNT works3341 * - when the head changes, because we're iterating over several tracks3342 * then (DASD_ECKD_CCW_READ_COUNT_MT)3343 * - when we've reached the end of sensible data in the buffer (the3344 * record will be 0 then)3345 */3346 for (i = start; i < max; i++) {3347 if (i > start) {3348 if ((fmt_buffer[i].head == head &&3349 fmt_buffer[i].record == 1) ||3350 fmt_buffer[i].head != head ||3351 fmt_buffer[i].record == 0)3352 break;3353 }3354 }3355 3356 return i - start;3357}3358 3359/*3360 * Evaluate a given range of tracks. Data like number of records, blocksize,3361 * record ids, and key length are compared with expected data.3362 *3363 * If a mismatch occurs, the corresponding error bit is set, as well as3364 * additional information, depending on the error.3365 */3366static void dasd_eckd_format_evaluate_tracks(struct eckd_count *fmt_buffer,3367 struct format_check_t *cdata,3368 int rpt_max, int rpt_exp,3369 int trk_per_cyl, int tpm)3370{3371 struct ch_t geo;3372 int max_entries;3373 int count = 0;3374 int trkcount;3375 int blksize;3376 int pos = 0;3377 int i, j;3378 int kl;3379 3380 trkcount = cdata->expect.stop_unit - cdata->expect.start_unit + 1;3381 max_entries = trkcount * rpt_max;3382 3383 for (i = cdata->expect.start_unit; i <= cdata->expect.stop_unit; i++) {3384 /* Calculate the correct next starting position in the buffer */3385 if (tpm) {3386 while (fmt_buffer[pos].record == 0 &&3387 fmt_buffer[pos].dl == 0) {3388 if (pos++ > max_entries)3389 break;3390 }3391 } else {3392 if (i != cdata->expect.start_unit)3393 pos += rpt_max - count;3394 }3395 3396 /* Calculate the expected geo values for the current track */3397 set_ch_t(&geo, i / trk_per_cyl, i % trk_per_cyl);3398 3399 /* Count and check number of records */3400 count = dasd_eckd_count_records(fmt_buffer, pos, pos + rpt_max);3401 3402 if (count < rpt_exp) {3403 cdata->result = DASD_FMT_ERR_TOO_FEW_RECORDS;3404 break;3405 }3406 if (count > rpt_exp) {3407 cdata->result = DASD_FMT_ERR_TOO_MANY_RECORDS;3408 break;3409 }3410 3411 for (j = 0; j < count; j++, pos++) {3412 blksize = cdata->expect.blksize;3413 kl = 0;3414 3415 /*3416 * Set special values when checking CDL formatted3417 * devices.3418 */3419 if ((cdata->expect.intensity & 0x08) &&3420 geo.cyl == 0 && geo.head == 0) {3421 if (j < 3) {3422 blksize = sizes_trk0[j] - 4;3423 kl = 4;3424 }3425 }3426 if ((cdata->expect.intensity & 0x08) &&3427 geo.cyl == 0 && geo.head == 1) {3428 blksize = LABEL_SIZE - 44;3429 kl = 44;3430 }3431 3432 /* Check blocksize */3433 if (fmt_buffer[pos].dl != blksize) {3434 cdata->result = DASD_FMT_ERR_BLKSIZE;3435 goto out;3436 }3437 /* Check if key length is 0 */3438 if (fmt_buffer[pos].kl != kl) {3439 cdata->result = DASD_FMT_ERR_KEY_LENGTH;3440 goto out;3441 }3442 /* Check if record_id is correct */3443 if (fmt_buffer[pos].cyl != geo.cyl ||3444 fmt_buffer[pos].head != geo.head ||3445 fmt_buffer[pos].record != (j + 1)) {3446 cdata->result = DASD_FMT_ERR_RECORD_ID;3447 goto out;3448 }3449 }3450 }3451 3452out:3453 /*3454 * In case of no errors, we need to decrease by one3455 * to get the correct positions.3456 */3457 if (!cdata->result) {3458 i--;3459 pos--;3460 }3461 3462 cdata->unit = i;3463 cdata->num_records = count;3464 cdata->rec = fmt_buffer[pos].record;3465 cdata->blksize = fmt_buffer[pos].dl;3466 cdata->key_length = fmt_buffer[pos].kl;3467}3468 3469/*3470 * Check the format of a range of tracks of a DASD.3471 */3472static int dasd_eckd_check_device_format(struct dasd_device *base,3473 struct format_check_t *cdata,3474 int enable_pav)3475{3476 struct dasd_eckd_private *private = base->private;3477 struct eckd_count *fmt_buffer;3478 struct irb irb;3479 int rpt_max, rpt_exp;3480 int fmt_buffer_size;3481 int trk_per_cyl;3482 int trkcount;3483 int tpm = 0;3484 int rc;3485 3486 trk_per_cyl = private->rdc_data.trk_per_cyl;3487 3488 /* Get maximum and expected amount of records per track */3489 rpt_max = recs_per_track(&private->rdc_data, 0, 512) + 1;3490 rpt_exp = recs_per_track(&private->rdc_data, 0, cdata->expect.blksize);3491 3492 trkcount = cdata->expect.stop_unit - cdata->expect.start_unit + 1;3493 fmt_buffer_size = trkcount * rpt_max * sizeof(struct eckd_count);3494 3495 fmt_buffer = kzalloc(fmt_buffer_size, GFP_KERNEL | GFP_DMA);3496 if (!fmt_buffer)3497 return -ENOMEM;3498 3499 /*3500 * A certain FICON feature subset is needed to operate in transport3501 * mode. Additionally, the support for transport mode is implicitly3502 * checked by comparing the buffer size with fcx_max_data. As long as3503 * the buffer size is smaller we can operate in transport mode and3504 * process multiple tracks. If not, only one track at once is being3505 * processed using command mode.3506 */3507 if ((private->features.feature[40] & 0x04) &&3508 fmt_buffer_size <= private->fcx_max_data)3509 tpm = 1;3510 3511 rc = dasd_eckd_format_process_data(base, &cdata->expect, enable_pav,3512 tpm, fmt_buffer, rpt_max, &irb);3513 if (rc && rc != -EIO)3514 goto out;3515 if (rc == -EIO) {3516 /*3517 * If our first attempt with transport mode enabled comes back3518 * with an incorrect length error, we're going to retry the3519 * check with command mode.3520 */3521 if (tpm && scsw_cstat(&irb.scsw) == 0x40) {3522 tpm = 0;3523 rc = dasd_eckd_format_process_data(base, &cdata->expect,3524 enable_pav, tpm,3525 fmt_buffer, rpt_max,3526 &irb);3527 if (rc)3528 goto out;3529 } else {3530 goto out;3531 }3532 }3533 3534 dasd_eckd_format_evaluate_tracks(fmt_buffer, cdata, rpt_max, rpt_exp,3535 trk_per_cyl, tpm);3536 3537out:3538 kfree(fmt_buffer);3539 3540 return rc;3541}3542 3543static void dasd_eckd_handle_terminated_request(struct dasd_ccw_req *cqr)3544{3545 if (cqr->retries < 0) {3546 cqr->status = DASD_CQR_FAILED;3547 return;3548 }3549 cqr->status = DASD_CQR_FILLED;3550 if (cqr->block && (cqr->startdev != cqr->block->base)) {3551 dasd_eckd_reset_ccw_to_base_io(cqr);3552 cqr->startdev = cqr->block->base;3553 cqr->lpm = dasd_path_get_opm(cqr->block->base);3554 }3555};3556 3557static dasd_erp_fn_t3558dasd_eckd_erp_action(struct dasd_ccw_req * cqr)3559{3560 struct dasd_device *device = (struct dasd_device *) cqr->startdev;3561 struct ccw_device *cdev = device->cdev;3562 3563 switch (cdev->id.cu_type) {3564 case 0x3990:3565 case 0x2105:3566 case 0x2107:3567 case 0x1750:3568 return dasd_3990_erp_action;3569 case 0x9343:3570 case 0x3880:3571 default:3572 return dasd_default_erp_action;3573 }3574}3575 3576static dasd_erp_fn_t3577dasd_eckd_erp_postaction(struct dasd_ccw_req * cqr)3578{3579 return dasd_default_erp_postaction;3580}3581 3582static void dasd_eckd_check_for_device_change(struct dasd_device *device,3583 struct dasd_ccw_req *cqr,3584 struct irb *irb)3585{3586 char mask;3587 char *sense = NULL;3588 struct dasd_eckd_private *private = device->private;3589 3590 /* first of all check for state change pending interrupt */3591 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP;3592 if ((scsw_dstat(&irb->scsw) & mask) == mask) {3593 /*3594 * for alias only, not in offline processing3595 * and only if not suspended3596 */3597 if (!device->block && private->lcu &&3598 device->state == DASD_STATE_ONLINE &&3599 !test_bit(DASD_FLAG_OFFLINE, &device->flags) &&3600 !test_bit(DASD_FLAG_SUSPENDED, &device->flags)) {3601 /* schedule worker to reload device */3602 dasd_reload_device(device);3603 }3604 dasd_generic_handle_state_change(device);3605 return;3606 }3607 3608 sense = dasd_get_sense(irb);3609 if (!sense)3610 return;3611 3612 /* summary unit check */3613 if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) &&3614 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) {3615 if (test_and_set_bit(DASD_FLAG_SUC, &device->flags)) {3616 DBF_DEV_EVENT(DBF_WARNING, device, "%s",3617 "eckd suc: device already notified");3618 return;3619 }3620 sense = dasd_get_sense(irb);3621 if (!sense) {3622 DBF_DEV_EVENT(DBF_WARNING, device, "%s",3623 "eckd suc: no reason code available");3624 clear_bit(DASD_FLAG_SUC, &device->flags);3625 return;3626 3627 }3628 private->suc_reason = sense[8];3629 DBF_DEV_EVENT(DBF_NOTICE, device, "%s %x",3630 "eckd handle summary unit check: reason",3631 private->suc_reason);3632 dasd_get_device(device);3633 if (!schedule_work(&device->suc_work))3634 dasd_put_device(device);3635 3636 return;3637 }3638 3639 /* service information message SIM */3640 if (!cqr && !(sense[27] & DASD_SENSE_BIT_0) &&3641 ((sense[6] & DASD_SIM_SENSE) == DASD_SIM_SENSE)) {3642 dasd_3990_erp_handle_sim(device, sense);3643 return;3644 }3645 3646 /* loss of device reservation is handled via base devices only3647 * as alias devices may be used with several bases3648 */3649 if (device->block && (sense[27] & DASD_SENSE_BIT_0) &&3650 (sense[7] == 0x3F) &&3651 (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) &&3652 test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) {3653 if (device->features & DASD_FEATURE_FAILONSLCK)3654 set_bit(DASD_FLAG_LOCK_STOLEN, &device->flags);3655 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);3656 dev_err(&device->cdev->dev,3657 "The device reservation was lost\n");3658 }3659}3660 3661static int dasd_eckd_ras_sanity_checks(struct dasd_device *device,3662 unsigned int first_trk,3663 unsigned int last_trk)3664{3665 struct dasd_eckd_private *private = device->private;3666 unsigned int trks_per_vol;3667 int rc = 0;3668 3669 trks_per_vol = private->real_cyl * private->rdc_data.trk_per_cyl;3670 3671 if (first_trk >= trks_per_vol) {3672 dev_warn(&device->cdev->dev,3673 "Start track number %u used in the space release command is too big\n",3674 first_trk);3675 rc = -EINVAL;3676 } else if (last_trk >= trks_per_vol) {3677 dev_warn(&device->cdev->dev,3678 "Stop track number %u used in the space release command is too big\n",3679 last_trk);3680 rc = -EINVAL;3681 } else if (first_trk > last_trk) {3682 dev_warn(&device->cdev->dev,3683 "Start track %u used in the space release command exceeds the end track\n",3684 first_trk);3685 rc = -EINVAL;3686 }3687 return rc;3688}3689 3690/*3691 * Helper function to count the amount of involved extents within a given range3692 * with extent alignment in mind.3693 */3694static int count_exts(unsigned int from, unsigned int to, int trks_per_ext)3695{3696 int cur_pos = 0;3697 int count = 0;3698 int tmp;3699 3700 if (from == to)3701 return 1;3702 3703 /* Count first partial extent */3704 if (from % trks_per_ext != 0) {3705 tmp = from + trks_per_ext - (from % trks_per_ext) - 1;3706 if (tmp > to)3707 tmp = to;3708 cur_pos = tmp - from + 1;3709 count++;3710 }3711 /* Count full extents */3712 if (to - (from + cur_pos) + 1 >= trks_per_ext) {3713 tmp = to - ((to - trks_per_ext + 1) % trks_per_ext);3714 count += (tmp - (from + cur_pos) + 1) / trks_per_ext;3715 cur_pos = tmp;3716 }3717 /* Count last partial extent */3718 if (cur_pos < to)3719 count++;3720 3721 return count;3722}3723 3724static int dasd_in_copy_relation(struct dasd_device *device)3725{3726 struct dasd_pprc_data_sc4 *temp;3727 int rc;3728 3729 if (!dasd_eckd_pprc_enabled(device))3730 return 0;3731 3732 temp = kzalloc(sizeof(*temp), GFP_KERNEL);3733 if (!temp)3734 return -ENOMEM;3735 3736 rc = dasd_eckd_query_pprc_status(device, temp);3737 if (!rc)3738 rc = temp->dev_info[0].state;3739 3740 kfree(temp);3741 return rc;3742}3743 3744/*3745 * Release allocated space for a given range or an entire volume.3746 */3747static struct dasd_ccw_req *3748dasd_eckd_dso_ras(struct dasd_device *device, struct dasd_block *block,3749 struct request *req, unsigned int first_trk,3750 unsigned int last_trk, int by_extent)3751{3752 struct dasd_eckd_private *private = device->private;3753 struct dasd_dso_ras_ext_range *ras_range;3754 struct dasd_rssd_features *features;3755 struct dasd_dso_ras_data *ras_data;3756 u16 heads, beg_head, end_head;3757 int cur_to_trk, cur_from_trk;3758 struct dasd_ccw_req *cqr;3759 u32 beg_cyl, end_cyl;3760 int copy_relation;3761 struct ccw1 *ccw;3762 int trks_per_ext;3763 size_t ras_size;3764 size_t size;3765 int nr_exts;3766 void *rq;3767 int i;3768 3769 if (dasd_eckd_ras_sanity_checks(device, first_trk, last_trk))3770 return ERR_PTR(-EINVAL);3771 3772 copy_relation = dasd_in_copy_relation(device);3773 if (copy_relation < 0)3774 return ERR_PTR(copy_relation);3775 3776 rq = req ? blk_mq_rq_to_pdu(req) : NULL;3777 3778 features = &private->features;3779 3780 trks_per_ext = dasd_eckd_ext_size(device) * private->rdc_data.trk_per_cyl;3781 nr_exts = 0;3782 if (by_extent)3783 nr_exts = count_exts(first_trk, last_trk, trks_per_ext);3784 ras_size = sizeof(*ras_data);3785 size = ras_size + (nr_exts * sizeof(*ras_range));3786 3787 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, size, device, rq);3788 if (IS_ERR(cqr)) {3789 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",3790 "Could not allocate RAS request");3791 return cqr;3792 }3793 3794 ras_data = cqr->data;3795 memset(ras_data, 0, size);3796 3797 ras_data->order = DSO_ORDER_RAS;3798 ras_data->flags.vol_type = 0; /* CKD volume */3799 /* Release specified extents or entire volume */3800 ras_data->op_flags.by_extent = by_extent;3801 /*3802 * This bit guarantees initialisation of tracks within an extent that is3803 * not fully specified, but is only supported with a certain feature3804 * subset and for devices not in a copy relation.3805 */3806 if (features->feature[56] & 0x01 && !copy_relation)3807 ras_data->op_flags.guarantee_init = 1;3808 3809 ras_data->lss = private->conf.ned->ID;3810 ras_data->dev_addr = private->conf.ned->unit_addr;3811 ras_data->nr_exts = nr_exts;3812 3813 if (by_extent) {3814 heads = private->rdc_data.trk_per_cyl;3815 cur_from_trk = first_trk;3816 cur_to_trk = first_trk + trks_per_ext -3817 (first_trk % trks_per_ext) - 1;3818 if (cur_to_trk > last_trk)3819 cur_to_trk = last_trk;3820 ras_range = (struct dasd_dso_ras_ext_range *)(cqr->data + ras_size);3821 3822 for (i = 0; i < nr_exts; i++) {3823 beg_cyl = cur_from_trk / heads;3824 beg_head = cur_from_trk % heads;3825 end_cyl = cur_to_trk / heads;3826 end_head = cur_to_trk % heads;3827 3828 set_ch_t(&ras_range->beg_ext, beg_cyl, beg_head);3829 set_ch_t(&ras_range->end_ext, end_cyl, end_head);3830 3831 cur_from_trk = cur_to_trk + 1;3832 cur_to_trk = cur_from_trk + trks_per_ext - 1;3833 if (cur_to_trk > last_trk)3834 cur_to_trk = last_trk;3835 ras_range++;3836 }3837 }3838 3839 ccw = cqr->cpaddr;3840 ccw->cda = virt_to_dma32(cqr->data);3841 ccw->cmd_code = DASD_ECKD_CCW_DSO;3842 ccw->count = size;3843 3844 cqr->startdev = device;3845 cqr->memdev = device;3846 cqr->block = block;3847 cqr->retries = 256;3848 cqr->expires = device->default_expires * HZ;3849 cqr->buildclk = get_tod_clock();3850 cqr->status = DASD_CQR_FILLED;3851 3852 return cqr;3853}3854 3855static int dasd_eckd_release_space_full(struct dasd_device *device)3856{3857 struct dasd_ccw_req *cqr;3858 int rc;3859 3860 cqr = dasd_eckd_dso_ras(device, NULL, NULL, 0, 0, 0);3861 if (IS_ERR(cqr))3862 return PTR_ERR(cqr);3863 3864 rc = dasd_sleep_on_interruptible(cqr);3865 3866 dasd_sfree_request(cqr, cqr->memdev);3867 3868 return rc;3869}3870 3871static int dasd_eckd_release_space_trks(struct dasd_device *device,3872 unsigned int from, unsigned int to)3873{3874 struct dasd_eckd_private *private = device->private;3875 struct dasd_block *block = device->block;3876 struct dasd_ccw_req *cqr, *n;3877 struct list_head ras_queue;3878 unsigned int device_exts;3879 int trks_per_ext;3880 int stop, step;3881 int cur_pos;3882 int rc = 0;3883 int retry;3884 3885 INIT_LIST_HEAD(&ras_queue);3886 3887 device_exts = private->real_cyl / dasd_eckd_ext_size(device);3888 trks_per_ext = dasd_eckd_ext_size(device) * private->rdc_data.trk_per_cyl;3889 3890 /* Make sure device limits are not exceeded */3891 step = trks_per_ext * min(device_exts, DASD_ECKD_RAS_EXTS_MAX);3892 cur_pos = from;3893 3894 do {3895 retry = 0;3896 while (cur_pos < to) {3897 stop = cur_pos + step -3898 ((cur_pos + step) % trks_per_ext) - 1;3899 if (stop > to)3900 stop = to;3901 3902 cqr = dasd_eckd_dso_ras(device, NULL, NULL, cur_pos, stop, 1);3903 if (IS_ERR(cqr)) {3904 rc = PTR_ERR(cqr);3905 if (rc == -ENOMEM) {3906 if (list_empty(&ras_queue))3907 goto out;3908 retry = 1;3909 break;3910 }3911 goto err_out;3912 }3913 3914 spin_lock_irq(&block->queue_lock);3915 list_add_tail(&cqr->blocklist, &ras_queue);3916 spin_unlock_irq(&block->queue_lock);3917 cur_pos = stop + 1;3918 }3919 3920 rc = dasd_sleep_on_queue_interruptible(&ras_queue);3921 3922err_out:3923 list_for_each_entry_safe(cqr, n, &ras_queue, blocklist) {3924 device = cqr->startdev;3925 private = device->private;3926 3927 spin_lock_irq(&block->queue_lock);3928 list_del_init(&cqr->blocklist);3929 spin_unlock_irq(&block->queue_lock);3930 dasd_sfree_request(cqr, device);3931 private->count--;3932 }3933 } while (retry);3934 3935out:3936 return rc;3937}3938 3939static int dasd_eckd_release_space(struct dasd_device *device,3940 struct format_data_t *rdata)3941{3942 if (rdata->intensity & DASD_FMT_INT_ESE_FULL)3943 return dasd_eckd_release_space_full(device);3944 else if (rdata->intensity == 0)3945 return dasd_eckd_release_space_trks(device, rdata->start_unit,3946 rdata->stop_unit);3947 else3948 return -EINVAL;3949}3950 3951static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_single(3952 struct dasd_device *startdev,3953 struct dasd_block *block,3954 struct request *req,3955 sector_t first_rec,3956 sector_t last_rec,3957 sector_t first_trk,3958 sector_t last_trk,3959 unsigned int first_offs,3960 unsigned int last_offs,3961 unsigned int blk_per_trk,3962 unsigned int blksize)3963{3964 struct dasd_eckd_private *private;3965 dma64_t *idaws;3966 struct LO_eckd_data *LO_data;3967 struct dasd_ccw_req *cqr;3968 struct ccw1 *ccw;3969 struct req_iterator iter;3970 struct bio_vec bv;3971 char *dst;3972 unsigned int off;3973 int count, cidaw, cplength, datasize;3974 sector_t recid;3975 unsigned char cmd, rcmd;3976 int use_prefix;3977 struct dasd_device *basedev;3978 3979 basedev = block->base;3980 private = basedev->private;3981 if (rq_data_dir(req) == READ)3982 cmd = DASD_ECKD_CCW_READ_MT;3983 else if (rq_data_dir(req) == WRITE)3984 cmd = DASD_ECKD_CCW_WRITE_MT;3985 else3986 return ERR_PTR(-EINVAL);3987 3988 /* Check struct bio and count the number of blocks for the request. */3989 count = 0;3990 cidaw = 0;3991 rq_for_each_segment(bv, req, iter) {3992 if (bv.bv_len & (blksize - 1))3993 /* Eckd can only do full blocks. */3994 return ERR_PTR(-EINVAL);3995 count += bv.bv_len >> (block->s2b_shift + 9);3996 if (idal_is_needed (page_address(bv.bv_page), bv.bv_len))3997 cidaw += bv.bv_len >> (block->s2b_shift + 9);3998 }3999 /* Paranoia. */4000 if (count != last_rec - first_rec + 1)4001 return ERR_PTR(-EINVAL);4002 4003 /* use the prefix command if available */4004 use_prefix = private->features.feature[8] & 0x01;4005 if (use_prefix) {4006 /* 1x prefix + number of blocks */4007 cplength = 2 + count;4008 /* 1x prefix + cidaws*sizeof(long) */4009 datasize = sizeof(struct PFX_eckd_data) +4010 sizeof(struct LO_eckd_data) +4011 cidaw * sizeof(unsigned long);4012 } else {4013 /* 1x define extent + 1x locate record + number of blocks */4014 cplength = 2 + count;4015 /* 1x define extent + 1x locate record + cidaws*sizeof(long) */4016 datasize = sizeof(struct DE_eckd_data) +4017 sizeof(struct LO_eckd_data) +4018 cidaw * sizeof(unsigned long);4019 }4020 /* Find out the number of additional locate record ccws for cdl. */4021 if (private->uses_cdl && first_rec < 2*blk_per_trk) {4022 if (last_rec >= 2*blk_per_trk)4023 count = 2*blk_per_trk - first_rec;4024 cplength += count;4025 datasize += count*sizeof(struct LO_eckd_data);4026 }4027 /* Allocate the ccw request. */4028 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize,4029 startdev, blk_mq_rq_to_pdu(req));4030 if (IS_ERR(cqr))4031 return cqr;4032 ccw = cqr->cpaddr;4033 /* First ccw is define extent or prefix. */4034 if (use_prefix) {4035 if (prefix(ccw++, cqr->data, first_trk,4036 last_trk, cmd, basedev, startdev) == -EAGAIN) {4037 /* Clock not in sync and XRC is enabled.4038 * Try again later.4039 */4040 dasd_sfree_request(cqr, startdev);4041 return ERR_PTR(-EAGAIN);4042 }4043 idaws = (dma64_t *)(cqr->data + sizeof(struct PFX_eckd_data));4044 } else {4045 if (define_extent(ccw++, cqr->data, first_trk,4046 last_trk, cmd, basedev, 0) == -EAGAIN) {4047 /* Clock not in sync and XRC is enabled.4048 * Try again later.4049 */4050 dasd_sfree_request(cqr, startdev);4051 return ERR_PTR(-EAGAIN);4052 }4053 idaws = (dma64_t *)(cqr->data + sizeof(struct DE_eckd_data));4054 }4055 /* Build locate_record+read/write/ccws. */4056 LO_data = (struct LO_eckd_data *) (idaws + cidaw);4057 recid = first_rec;4058 if (private->uses_cdl == 0 || recid > 2*blk_per_trk) {4059 /* Only standard blocks so there is just one locate record. */4060 ccw[-1].flags |= CCW_FLAG_CC;4061 locate_record(ccw++, LO_data++, first_trk, first_offs + 1,4062 last_rec - recid + 1, cmd, basedev, blksize);4063 }4064 rq_for_each_segment(bv, req, iter) {4065 dst = bvec_virt(&bv);4066 if (dasd_page_cache) {4067 char *copy = kmem_cache_alloc(dasd_page_cache,4068 GFP_DMA | __GFP_NOWARN);4069 if (copy && rq_data_dir(req) == WRITE)4070 memcpy(copy + bv.bv_offset, dst, bv.bv_len);4071 if (copy)4072 dst = copy + bv.bv_offset;4073 }4074 for (off = 0; off < bv.bv_len; off += blksize) {4075 sector_t trkid = recid;4076 unsigned int recoffs = sector_div(trkid, blk_per_trk);4077 rcmd = cmd;4078 count = blksize;4079 /* Locate record for cdl special block ? */4080 if (private->uses_cdl && recid < 2*blk_per_trk) {4081 if (dasd_eckd_cdl_special(blk_per_trk, recid)){4082 rcmd |= 0x8;4083 count = dasd_eckd_cdl_reclen(recid);4084 if (count < blksize &&4085 rq_data_dir(req) == READ)4086 memset(dst + count, 0xe5,4087 blksize - count);4088 }4089 ccw[-1].flags |= CCW_FLAG_CC;4090 locate_record(ccw++, LO_data++,4091 trkid, recoffs + 1,4092 1, rcmd, basedev, count);4093 }4094 /* Locate record for standard blocks ? */4095 if (private->uses_cdl && recid == 2*blk_per_trk) {4096 ccw[-1].flags |= CCW_FLAG_CC;4097 locate_record(ccw++, LO_data++,4098 trkid, recoffs + 1,4099 last_rec - recid + 1,4100 cmd, basedev, count);4101 }4102 /* Read/write ccw. */4103 ccw[-1].flags |= CCW_FLAG_CC;4104 ccw->cmd_code = rcmd;4105 ccw->count = count;4106 if (idal_is_needed(dst, blksize)) {4107 ccw->cda = virt_to_dma32(idaws);4108 ccw->flags = CCW_FLAG_IDA;4109 idaws = idal_create_words(idaws, dst, blksize);4110 } else {4111 ccw->cda = virt_to_dma32(dst);4112 ccw->flags = 0;4113 }4114 ccw++;4115 dst += blksize;4116 recid++;4117 }4118 }4119 if (blk_noretry_request(req) ||4120 block->base->features & DASD_FEATURE_FAILFAST)4121 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);4122 cqr->startdev = startdev;4123 cqr->memdev = startdev;4124 cqr->block = block;4125 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */4126 cqr->lpm = dasd_path_get_ppm(startdev);4127 cqr->retries = startdev->default_retries;4128 cqr->buildclk = get_tod_clock();4129 cqr->status = DASD_CQR_FILLED;4130 4131 /* Set flags to suppress output for expected errors */4132 if (dasd_eckd_is_ese(basedev)) {4133 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);4134 }4135 4136 return cqr;4137}4138 4139static struct dasd_ccw_req *dasd_eckd_build_cp_cmd_track(4140 struct dasd_device *startdev,4141 struct dasd_block *block,4142 struct request *req,4143 sector_t first_rec,4144 sector_t last_rec,4145 sector_t first_trk,4146 sector_t last_trk,4147 unsigned int first_offs,4148 unsigned int last_offs,4149 unsigned int blk_per_trk,4150 unsigned int blksize)4151{4152 dma64_t *idaws;4153 struct dasd_ccw_req *cqr;4154 struct ccw1 *ccw;4155 struct req_iterator iter;4156 struct bio_vec bv;4157 char *dst, *idaw_dst;4158 unsigned int cidaw, cplength, datasize;4159 unsigned int tlf;4160 sector_t recid;4161 unsigned char cmd;4162 struct dasd_device *basedev;4163 unsigned int trkcount, count, count_to_trk_end;4164 unsigned int idaw_len, seg_len, part_len, len_to_track_end;4165 unsigned char new_track, end_idaw;4166 sector_t trkid;4167 unsigned int recoffs;4168 4169 basedev = block->base;4170 if (rq_data_dir(req) == READ)4171 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;4172 else if (rq_data_dir(req) == WRITE)4173 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;4174 else4175 return ERR_PTR(-EINVAL);4176 4177 /* Track based I/O needs IDAWs for each page, and not just for4178 * 64 bit addresses. We need additional idals for pages4179 * that get filled from two tracks, so we use the number4180 * of records as upper limit.4181 */4182 cidaw = last_rec - first_rec + 1;4183 trkcount = last_trk - first_trk + 1;4184 4185 /* 1x prefix + one read/write ccw per track */4186 cplength = 1 + trkcount;4187 4188 datasize = sizeof(struct PFX_eckd_data) + cidaw * sizeof(unsigned long);4189 4190 /* Allocate the ccw request. */4191 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength, datasize,4192 startdev, blk_mq_rq_to_pdu(req));4193 if (IS_ERR(cqr))4194 return cqr;4195 ccw = cqr->cpaddr;4196 /* transfer length factor: how many bytes to read from the last track */4197 if (first_trk == last_trk)4198 tlf = last_offs - first_offs + 1;4199 else4200 tlf = last_offs + 1;4201 tlf *= blksize;4202 4203 if (prefix_LRE(ccw++, cqr->data, first_trk,4204 last_trk, cmd, basedev, startdev,4205 1 /* format */, first_offs + 1,4206 trkcount, blksize,4207 tlf) == -EAGAIN) {4208 /* Clock not in sync and XRC is enabled.4209 * Try again later.4210 */4211 dasd_sfree_request(cqr, startdev);4212 return ERR_PTR(-EAGAIN);4213 }4214 4215 /*4216 * The translation of request into ccw programs must meet the4217 * following conditions:4218 * - all idaws but the first and the last must address full pages4219 * (or 2K blocks on 31-bit)4220 * - the scope of a ccw and it's idal ends with the track boundaries4221 */4222 idaws = (dma64_t *)(cqr->data + sizeof(struct PFX_eckd_data));4223 recid = first_rec;4224 new_track = 1;4225 end_idaw = 0;4226 len_to_track_end = 0;4227 idaw_dst = NULL;4228 idaw_len = 0;4229 rq_for_each_segment(bv, req, iter) {4230 dst = bvec_virt(&bv);4231 seg_len = bv.bv_len;4232 while (seg_len) {4233 if (new_track) {4234 trkid = recid;4235 recoffs = sector_div(trkid, blk_per_trk);4236 count_to_trk_end = blk_per_trk - recoffs;4237 count = min((last_rec - recid + 1),4238 (sector_t)count_to_trk_end);4239 len_to_track_end = count * blksize;4240 ccw[-1].flags |= CCW_FLAG_CC;4241 ccw->cmd_code = cmd;4242 ccw->count = len_to_track_end;4243 ccw->cda = virt_to_dma32(idaws);4244 ccw->flags = CCW_FLAG_IDA;4245 ccw++;4246 recid += count;4247 new_track = 0;4248 /* first idaw for a ccw may start anywhere */4249 if (!idaw_dst)4250 idaw_dst = dst;4251 }4252 /* If we start a new idaw, we must make sure that it4253 * starts on an IDA_BLOCK_SIZE boundary.4254 * If we continue an idaw, we must make sure that the4255 * current segment begins where the so far accumulated4256 * idaw ends4257 */4258 if (!idaw_dst) {4259 if ((unsigned long)(dst) & (IDA_BLOCK_SIZE - 1)) {4260 dasd_sfree_request(cqr, startdev);4261 return ERR_PTR(-ERANGE);4262 } else4263 idaw_dst = dst;4264 }4265 if ((idaw_dst + idaw_len) != dst) {4266 dasd_sfree_request(cqr, startdev);4267 return ERR_PTR(-ERANGE);4268 }4269 part_len = min(seg_len, len_to_track_end);4270 seg_len -= part_len;4271 dst += part_len;4272 idaw_len += part_len;4273 len_to_track_end -= part_len;4274 /* collected memory area ends on an IDA_BLOCK border,4275 * -> create an idaw4276 * idal_create_words will handle cases where idaw_len4277 * is larger then IDA_BLOCK_SIZE4278 */4279 if (!((unsigned long)(idaw_dst + idaw_len) & (IDA_BLOCK_SIZE - 1)))4280 end_idaw = 1;4281 /* We also need to end the idaw at track end */4282 if (!len_to_track_end) {4283 new_track = 1;4284 end_idaw = 1;4285 }4286 if (end_idaw) {4287 idaws = idal_create_words(idaws, idaw_dst,4288 idaw_len);4289 idaw_dst = NULL;4290 idaw_len = 0;4291 end_idaw = 0;4292 }4293 }4294 }4295 4296 if (blk_noretry_request(req) ||4297 block->base->features & DASD_FEATURE_FAILFAST)4298 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);4299 cqr->startdev = startdev;4300 cqr->memdev = startdev;4301 cqr->block = block;4302 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */4303 cqr->lpm = dasd_path_get_ppm(startdev);4304 cqr->retries = startdev->default_retries;4305 cqr->buildclk = get_tod_clock();4306 cqr->status = DASD_CQR_FILLED;4307 4308 /* Set flags to suppress output for expected errors */4309 if (dasd_eckd_is_ese(basedev))4310 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);4311 4312 return cqr;4313}4314 4315static int prepare_itcw(struct itcw *itcw,4316 unsigned int trk, unsigned int totrk, int cmd,4317 struct dasd_device *basedev,4318 struct dasd_device *startdev,4319 unsigned int rec_on_trk, int count,4320 unsigned int blksize,4321 unsigned int total_data_size,4322 unsigned int tlf,4323 unsigned int blk_per_trk)4324{4325 struct PFX_eckd_data pfxdata;4326 struct dasd_eckd_private *basepriv, *startpriv;4327 struct DE_eckd_data *dedata;4328 struct LRE_eckd_data *lredata;4329 struct dcw *dcw;4330 4331 u32 begcyl, endcyl;4332 u16 heads, beghead, endhead;4333 u8 pfx_cmd;4334 4335 int rc = 0;4336 int sector = 0;4337 int dn, d;4338 4339 4340 /* setup prefix data */4341 basepriv = basedev->private;4342 startpriv = startdev->private;4343 dedata = &pfxdata.define_extent;4344 lredata = &pfxdata.locate_record;4345 4346 memset(&pfxdata, 0, sizeof(pfxdata));4347 pfxdata.format = 1; /* PFX with LRE */4348 pfxdata.base_address = basepriv->conf.ned->unit_addr;4349 pfxdata.base_lss = basepriv->conf.ned->ID;4350 pfxdata.validity.define_extent = 1;4351 4352 /* private uid is kept up to date, conf_data may be outdated */4353 if (startpriv->uid.type == UA_BASE_PAV_ALIAS)4354 pfxdata.validity.verify_base = 1;4355 4356 if (startpriv->uid.type == UA_HYPER_PAV_ALIAS) {4357 pfxdata.validity.verify_base = 1;4358 pfxdata.validity.hyper_pav = 1;4359 }4360 4361 switch (cmd) {4362 case DASD_ECKD_CCW_READ_TRACK_DATA:4363 dedata->mask.perm = 0x1;4364 dedata->attributes.operation = basepriv->attrib.operation;4365 dedata->blk_size = blksize;4366 dedata->ga_extended |= 0x42;4367 lredata->operation.orientation = 0x0;4368 lredata->operation.operation = 0x0C;4369 lredata->auxiliary.check_bytes = 0x01;4370 pfx_cmd = DASD_ECKD_CCW_PFX_READ;4371 break;4372 case DASD_ECKD_CCW_WRITE_TRACK_DATA:4373 dedata->mask.perm = 0x02;4374 dedata->attributes.operation = basepriv->attrib.operation;4375 dedata->blk_size = blksize;4376 rc = set_timestamp(NULL, dedata, basedev);4377 dedata->ga_extended |= 0x42;4378 lredata->operation.orientation = 0x0;4379 lredata->operation.operation = 0x3F;4380 lredata->extended_operation = 0x23;4381 lredata->auxiliary.check_bytes = 0x2;4382 /*4383 * If XRC is supported the System Time Stamp is set. The4384 * validity of the time stamp must be reflected in the prefix4385 * data as well.4386 */4387 if (dedata->ga_extended & 0x08 && dedata->ga_extended & 0x02)4388 pfxdata.validity.time_stamp = 1; /* 'Time Stamp Valid' */4389 pfx_cmd = DASD_ECKD_CCW_PFX;4390 break;4391 case DASD_ECKD_CCW_READ_COUNT_MT:4392 dedata->mask.perm = 0x1;4393 dedata->attributes.operation = DASD_BYPASS_CACHE;4394 dedata->ga_extended |= 0x42;4395 dedata->blk_size = blksize;4396 lredata->operation.orientation = 0x2;4397 lredata->operation.operation = 0x16;4398 lredata->auxiliary.check_bytes = 0x01;4399 pfx_cmd = DASD_ECKD_CCW_PFX_READ;4400 break;4401 default:4402 DBF_DEV_EVENT(DBF_ERR, basedev,4403 "prepare itcw, unknown opcode 0x%x", cmd);4404 BUG();4405 break;4406 }4407 if (rc)4408 return rc;4409 4410 dedata->attributes.mode = 0x3; /* ECKD */4411 4412 heads = basepriv->rdc_data.trk_per_cyl;4413 begcyl = trk / heads;4414 beghead = trk % heads;4415 endcyl = totrk / heads;4416 endhead = totrk % heads;4417 4418 /* check for sequential prestage - enhance cylinder range */4419 if (dedata->attributes.operation == DASD_SEQ_PRESTAGE ||4420 dedata->attributes.operation == DASD_SEQ_ACCESS) {4421 4422 if (endcyl + basepriv->attrib.nr_cyl < basepriv->real_cyl)4423 endcyl += basepriv->attrib.nr_cyl;4424 else4425 endcyl = (basepriv->real_cyl - 1);4426 }4427 4428 set_ch_t(&dedata->beg_ext, begcyl, beghead);4429 set_ch_t(&dedata->end_ext, endcyl, endhead);4430 4431 dedata->ep_format = 0x20; /* records per track is valid */4432 dedata->ep_rec_per_track = blk_per_trk;4433 4434 if (rec_on_trk) {4435 switch (basepriv->rdc_data.dev_type) {4436 case 0x3390:4437 dn = ceil_quot(blksize + 6, 232);4438 d = 9 + ceil_quot(blksize + 6 * (dn + 1), 34);4439 sector = (49 + (rec_on_trk - 1) * (10 + d)) / 8;4440 break;4441 case 0x3380:4442 d = 7 + ceil_quot(blksize + 12, 32);4443 sector = (39 + (rec_on_trk - 1) * (8 + d)) / 7;4444 break;4445 }4446 }4447 4448 if (cmd == DASD_ECKD_CCW_READ_COUNT_MT) {4449 lredata->auxiliary.length_valid = 0;4450 lredata->auxiliary.length_scope = 0;4451 lredata->sector = 0xff;4452 } else {4453 lredata->auxiliary.length_valid = 1;4454 lredata->auxiliary.length_scope = 1;4455 lredata->sector = sector;4456 }4457 lredata->auxiliary.imbedded_ccw_valid = 1;4458 lredata->length = tlf;4459 lredata->imbedded_ccw = cmd;4460 lredata->count = count;4461 set_ch_t(&lredata->seek_addr, begcyl, beghead);4462 lredata->search_arg.cyl = lredata->seek_addr.cyl;4463 lredata->search_arg.head = lredata->seek_addr.head;4464 lredata->search_arg.record = rec_on_trk;4465 4466 dcw = itcw_add_dcw(itcw, pfx_cmd, 0,4467 &pfxdata, sizeof(pfxdata), total_data_size);4468 return PTR_ERR_OR_ZERO(dcw);4469}4470 4471static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(4472 struct dasd_device *startdev,4473 struct dasd_block *block,4474 struct request *req,4475 sector_t first_rec,4476 sector_t last_rec,4477 sector_t first_trk,4478 sector_t last_trk,4479 unsigned int first_offs,4480 unsigned int last_offs,4481 unsigned int blk_per_trk,4482 unsigned int blksize)4483{4484 struct dasd_ccw_req *cqr;4485 struct req_iterator iter;4486 struct bio_vec bv;4487 char *dst;4488 unsigned int trkcount, ctidaw;4489 unsigned char cmd;4490 struct dasd_device *basedev;4491 unsigned int tlf;4492 struct itcw *itcw;4493 struct tidaw *last_tidaw = NULL;4494 int itcw_op;4495 size_t itcw_size;4496 u8 tidaw_flags;4497 unsigned int seg_len, part_len, len_to_track_end;4498 unsigned char new_track;4499 sector_t recid, trkid;4500 unsigned int offs;4501 unsigned int count, count_to_trk_end;4502 int ret;4503 4504 basedev = block->base;4505 if (rq_data_dir(req) == READ) {4506 cmd = DASD_ECKD_CCW_READ_TRACK_DATA;4507 itcw_op = ITCW_OP_READ;4508 } else if (rq_data_dir(req) == WRITE) {4509 cmd = DASD_ECKD_CCW_WRITE_TRACK_DATA;4510 itcw_op = ITCW_OP_WRITE;4511 } else4512 return ERR_PTR(-EINVAL);4513 4514 /* trackbased I/O needs address all memory via TIDAWs,4515 * not just for 64 bit addresses. This allows us to map4516 * each segment directly to one tidaw.4517 * In the case of write requests, additional tidaws may4518 * be needed when a segment crosses a track boundary.4519 */4520 trkcount = last_trk - first_trk + 1;4521 ctidaw = 0;4522 rq_for_each_segment(bv, req, iter) {4523 ++ctidaw;4524 }4525 if (rq_data_dir(req) == WRITE)4526 ctidaw += (last_trk - first_trk);4527 4528 /* Allocate the ccw request. */4529 itcw_size = itcw_calc_size(0, ctidaw, 0);4530 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 0, itcw_size, startdev,4531 blk_mq_rq_to_pdu(req));4532 if (IS_ERR(cqr))4533 return cqr;4534 4535 /* transfer length factor: how many bytes to read from the last track */4536 if (first_trk == last_trk)4537 tlf = last_offs - first_offs + 1;4538 else4539 tlf = last_offs + 1;4540 tlf *= blksize;4541 4542 itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0);4543 if (IS_ERR(itcw)) {4544 ret = -EINVAL;4545 goto out_error;4546 }4547 cqr->cpaddr = itcw_get_tcw(itcw);4548 if (prepare_itcw(itcw, first_trk, last_trk,4549 cmd, basedev, startdev,4550 first_offs + 1,4551 trkcount, blksize,4552 (last_rec - first_rec + 1) * blksize,4553 tlf, blk_per_trk) == -EAGAIN) {4554 /* Clock not in sync and XRC is enabled.4555 * Try again later.4556 */4557 ret = -EAGAIN;4558 goto out_error;4559 }4560 len_to_track_end = 0;4561 /*4562 * A tidaw can address 4k of memory, but must not cross page boundaries4563 * We can let the block layer handle this by setting seg_boundary_mask4564 * to page boundaries and max_segment_size to page size when setting up4565 * the request queue.4566 * For write requests, a TIDAW must not cross track boundaries, because4567 * we have to set the CBC flag on the last tidaw for each track.4568 */4569 if (rq_data_dir(req) == WRITE) {4570 new_track = 1;4571 recid = first_rec;4572 rq_for_each_segment(bv, req, iter) {4573 dst = bvec_virt(&bv);4574 seg_len = bv.bv_len;4575 while (seg_len) {4576 if (new_track) {4577 trkid = recid;4578 offs = sector_div(trkid, blk_per_trk);4579 count_to_trk_end = blk_per_trk - offs;4580 count = min((last_rec - recid + 1),4581 (sector_t)count_to_trk_end);4582 len_to_track_end = count * blksize;4583 recid += count;4584 new_track = 0;4585 }4586 part_len = min(seg_len, len_to_track_end);4587 seg_len -= part_len;4588 len_to_track_end -= part_len;4589 /* We need to end the tidaw at track end */4590 if (!len_to_track_end) {4591 new_track = 1;4592 tidaw_flags = TIDAW_FLAGS_INSERT_CBC;4593 } else4594 tidaw_flags = 0;4595 last_tidaw = itcw_add_tidaw(itcw, tidaw_flags,4596 dst, part_len);4597 if (IS_ERR(last_tidaw)) {4598 ret = -EINVAL;4599 goto out_error;4600 }4601 dst += part_len;4602 }4603 }4604 } else {4605 rq_for_each_segment(bv, req, iter) {4606 dst = bvec_virt(&bv);4607 last_tidaw = itcw_add_tidaw(itcw, 0x00,4608 dst, bv.bv_len);4609 if (IS_ERR(last_tidaw)) {4610 ret = -EINVAL;4611 goto out_error;4612 }4613 }4614 }4615 last_tidaw->flags |= TIDAW_FLAGS_LAST;4616 last_tidaw->flags &= ~TIDAW_FLAGS_INSERT_CBC;4617 itcw_finalize(itcw);4618 4619 if (blk_noretry_request(req) ||4620 block->base->features & DASD_FEATURE_FAILFAST)4621 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);4622 cqr->cpmode = 1;4623 cqr->startdev = startdev;4624 cqr->memdev = startdev;4625 cqr->block = block;4626 cqr->expires = startdev->default_expires * HZ; /* default 5 minutes */4627 cqr->lpm = dasd_path_get_ppm(startdev);4628 cqr->retries = startdev->default_retries;4629 cqr->buildclk = get_tod_clock();4630 cqr->status = DASD_CQR_FILLED;4631 4632 /* Set flags to suppress output for expected errors */4633 if (dasd_eckd_is_ese(basedev)) {4634 set_bit(DASD_CQR_SUPPRESS_NRF, &cqr->flags);4635 set_bit(DASD_CQR_SUPPRESS_IT, &cqr->flags);4636 }4637 4638 return cqr;4639out_error:4640 dasd_sfree_request(cqr, startdev);4641 return ERR_PTR(ret);4642}4643 4644static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,4645 struct dasd_block *block,4646 struct request *req)4647{4648 int cmdrtd, cmdwtd;4649 int use_prefix;4650 int fcx_multitrack;4651 struct dasd_eckd_private *private;4652 struct dasd_device *basedev;4653 sector_t first_rec, last_rec;4654 sector_t first_trk, last_trk;4655 unsigned int first_offs, last_offs;4656 unsigned int blk_per_trk, blksize;4657 int cdlspecial;4658 unsigned int data_size;4659 struct dasd_ccw_req *cqr;4660 4661 basedev = block->base;4662 private = basedev->private;4663 4664 /* Calculate number of blocks/records per track. */4665 blksize = block->bp_block;4666 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);4667 if (blk_per_trk == 0)4668 return ERR_PTR(-EINVAL);4669 /* Calculate record id of first and last block. */4670 first_rec = first_trk = blk_rq_pos(req) >> block->s2b_shift;4671 first_offs = sector_div(first_trk, blk_per_trk);4672 last_rec = last_trk =4673 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift;4674 last_offs = sector_div(last_trk, blk_per_trk);4675 cdlspecial = (private->uses_cdl && first_rec < 2*blk_per_trk);4676 4677 fcx_multitrack = private->features.feature[40] & 0x20;4678 data_size = blk_rq_bytes(req);4679 if (data_size % blksize)4680 return ERR_PTR(-EINVAL);4681 /* tpm write request add CBC data on each track boundary */4682 if (rq_data_dir(req) == WRITE)4683 data_size += (last_trk - first_trk) * 4;4684 4685 /* is read track data and write track data in command mode supported? */4686 cmdrtd = private->features.feature[9] & 0x20;4687 cmdwtd = private->features.feature[12] & 0x40;4688 use_prefix = private->features.feature[8] & 0x01;4689 4690 cqr = NULL;4691 if (cdlspecial || dasd_page_cache) {4692 /* do nothing, just fall through to the cmd mode single case */4693 } else if ((data_size <= private->fcx_max_data)4694 && (fcx_multitrack || (first_trk == last_trk))) {4695 cqr = dasd_eckd_build_cp_tpm_track(startdev, block, req,4696 first_rec, last_rec,4697 first_trk, last_trk,4698 first_offs, last_offs,4699 blk_per_trk, blksize);4700 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&4701 (PTR_ERR(cqr) != -ENOMEM))4702 cqr = NULL;4703 } else if (use_prefix &&4704 (((rq_data_dir(req) == READ) && cmdrtd) ||4705 ((rq_data_dir(req) == WRITE) && cmdwtd))) {4706 cqr = dasd_eckd_build_cp_cmd_track(startdev, block, req,4707 first_rec, last_rec,4708 first_trk, last_trk,4709 first_offs, last_offs,4710 blk_per_trk, blksize);4711 if (IS_ERR(cqr) && (PTR_ERR(cqr) != -EAGAIN) &&4712 (PTR_ERR(cqr) != -ENOMEM))4713 cqr = NULL;4714 }4715 if (!cqr)4716 cqr = dasd_eckd_build_cp_cmd_single(startdev, block, req,4717 first_rec, last_rec,4718 first_trk, last_trk,4719 first_offs, last_offs,4720 blk_per_trk, blksize);4721 return cqr;4722}4723 4724static struct dasd_ccw_req *dasd_eckd_build_cp_raw(struct dasd_device *startdev,4725 struct dasd_block *block,4726 struct request *req)4727{4728 sector_t start_padding_sectors, end_sector_offset, end_padding_sectors;4729 unsigned int seg_len, len_to_track_end;4730 unsigned int cidaw, cplength, datasize;4731 sector_t first_trk, last_trk, sectors;4732 struct dasd_eckd_private *base_priv;4733 struct dasd_device *basedev;4734 struct req_iterator iter;4735 struct dasd_ccw_req *cqr;4736 unsigned int trkcount;4737 unsigned int size;4738 unsigned char cmd;4739 struct bio_vec bv;4740 struct ccw1 *ccw;4741 dma64_t *idaws;4742 int use_prefix;4743 void *data;4744 char *dst;4745 4746 /*4747 * raw track access needs to be mutiple of 64k and on 64k boundary4748 * For read requests we can fix an incorrect alignment by padding4749 * the request with dummy pages.4750 */4751 start_padding_sectors = blk_rq_pos(req) % DASD_RAW_SECTORS_PER_TRACK;4752 end_sector_offset = (blk_rq_pos(req) + blk_rq_sectors(req)) %4753 DASD_RAW_SECTORS_PER_TRACK;4754 end_padding_sectors = (DASD_RAW_SECTORS_PER_TRACK - end_sector_offset) %4755 DASD_RAW_SECTORS_PER_TRACK;4756 basedev = block->base;4757 if ((start_padding_sectors || end_padding_sectors) &&4758 (rq_data_dir(req) == WRITE)) {4759 DBF_DEV_EVENT(DBF_ERR, basedev,4760 "raw write not track aligned (%llu,%llu) req %p",4761 start_padding_sectors, end_padding_sectors, req);4762 return ERR_PTR(-EINVAL);4763 }4764 4765 first_trk = blk_rq_pos(req) / DASD_RAW_SECTORS_PER_TRACK;4766 last_trk = (blk_rq_pos(req) + blk_rq_sectors(req) - 1) /4767 DASD_RAW_SECTORS_PER_TRACK;4768 trkcount = last_trk - first_trk + 1;4769 4770 if (rq_data_dir(req) == READ)4771 cmd = DASD_ECKD_CCW_READ_TRACK;4772 else if (rq_data_dir(req) == WRITE)4773 cmd = DASD_ECKD_CCW_WRITE_FULL_TRACK;4774 else4775 return ERR_PTR(-EINVAL);4776 4777 /*4778 * Raw track based I/O needs IDAWs for each page,4779 * and not just for 64 bit addresses.4780 */4781 cidaw = trkcount * DASD_RAW_BLOCK_PER_TRACK;4782 4783 /*4784 * struct PFX_eckd_data and struct LRE_eckd_data can have up to 2 bytes4785 * of extended parameter. This is needed for write full track.4786 */4787 base_priv = basedev->private;4788 use_prefix = base_priv->features.feature[8] & 0x01;4789 if (use_prefix) {4790 cplength = 1 + trkcount;4791 size = sizeof(struct PFX_eckd_data) + 2;4792 } else {4793 cplength = 2 + trkcount;4794 size = sizeof(struct DE_eckd_data) +4795 sizeof(struct LRE_eckd_data) + 2;4796 }4797 size = ALIGN(size, 8);4798 4799 datasize = size + cidaw * sizeof(unsigned long);4800 4801 /* Allocate the ccw request. */4802 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, cplength,4803 datasize, startdev, blk_mq_rq_to_pdu(req));4804 if (IS_ERR(cqr))4805 return cqr;4806 4807 ccw = cqr->cpaddr;4808 data = cqr->data;4809 4810 if (use_prefix) {4811 prefix_LRE(ccw++, data, first_trk, last_trk, cmd, basedev,4812 startdev, 1, 0, trkcount, 0, 0);4813 } else {4814 define_extent(ccw++, data, first_trk, last_trk, cmd, basedev, 0);4815 ccw[-1].flags |= CCW_FLAG_CC;4816 4817 data += sizeof(struct DE_eckd_data);4818 locate_record_ext(ccw++, data, first_trk, 0,4819 trkcount, cmd, basedev, 0, 0);4820 }4821 4822 idaws = (dma64_t *)(cqr->data + size);4823 len_to_track_end = 0;4824 if (start_padding_sectors) {4825 ccw[-1].flags |= CCW_FLAG_CC;4826 ccw->cmd_code = cmd;4827 /* maximum 3390 track size */4828 ccw->count = 57326;4829 /* 64k map to one track */4830 len_to_track_end = 65536 - start_padding_sectors * 512;4831 ccw->cda = virt_to_dma32(idaws);4832 ccw->flags |= CCW_FLAG_IDA;4833 ccw->flags |= CCW_FLAG_SLI;4834 ccw++;4835 for (sectors = 0; sectors < start_padding_sectors; sectors += 8)4836 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);4837 }4838 rq_for_each_segment(bv, req, iter) {4839 dst = bvec_virt(&bv);4840 seg_len = bv.bv_len;4841 if (cmd == DASD_ECKD_CCW_READ_TRACK)4842 memset(dst, 0, seg_len);4843 if (!len_to_track_end) {4844 ccw[-1].flags |= CCW_FLAG_CC;4845 ccw->cmd_code = cmd;4846 /* maximum 3390 track size */4847 ccw->count = 57326;4848 /* 64k map to one track */4849 len_to_track_end = 65536;4850 ccw->cda = virt_to_dma32(idaws);4851 ccw->flags |= CCW_FLAG_IDA;4852 ccw->flags |= CCW_FLAG_SLI;4853 ccw++;4854 }4855 len_to_track_end -= seg_len;4856 idaws = idal_create_words(idaws, dst, seg_len);4857 }4858 for (sectors = 0; sectors < end_padding_sectors; sectors += 8)4859 idaws = idal_create_words(idaws, rawpadpage, PAGE_SIZE);4860 if (blk_noretry_request(req) ||4861 block->base->features & DASD_FEATURE_FAILFAST)4862 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);4863 cqr->startdev = startdev;4864 cqr->memdev = startdev;4865 cqr->block = block;4866 cqr->expires = startdev->default_expires * HZ;4867 cqr->lpm = dasd_path_get_ppm(startdev);4868 cqr->retries = startdev->default_retries;4869 cqr->buildclk = get_tod_clock();4870 cqr->status = DASD_CQR_FILLED;4871 4872 return cqr;4873}4874 4875 4876static int4877dasd_eckd_free_cp(struct dasd_ccw_req *cqr, struct request *req)4878{4879 struct dasd_eckd_private *private;4880 struct ccw1 *ccw;4881 struct req_iterator iter;4882 struct bio_vec bv;4883 char *dst, *cda;4884 unsigned int blksize, blk_per_trk, off;4885 sector_t recid;4886 int status;4887 4888 if (!dasd_page_cache)4889 goto out;4890 private = cqr->block->base->private;4891 blksize = cqr->block->bp_block;4892 blk_per_trk = recs_per_track(&private->rdc_data, 0, blksize);4893 recid = blk_rq_pos(req) >> cqr->block->s2b_shift;4894 ccw = cqr->cpaddr;4895 /* Skip over define extent & locate record. */4896 ccw++;4897 if (private->uses_cdl == 0 || recid > 2*blk_per_trk)4898 ccw++;4899 rq_for_each_segment(bv, req, iter) {4900 dst = bvec_virt(&bv);4901 for (off = 0; off < bv.bv_len; off += blksize) {4902 /* Skip locate record. */4903 if (private->uses_cdl && recid <= 2*blk_per_trk)4904 ccw++;4905 if (dst) {4906 if (ccw->flags & CCW_FLAG_IDA)4907 cda = dma64_to_virt(*((dma64_t *)dma32_to_virt(ccw->cda)));4908 else4909 cda = dma32_to_virt(ccw->cda);4910 if (dst != cda) {4911 if (rq_data_dir(req) == READ)4912 memcpy(dst, cda, bv.bv_len);4913 kmem_cache_free(dasd_page_cache,4914 (void *)((addr_t)cda & PAGE_MASK));4915 }4916 dst = NULL;4917 }4918 ccw++;4919 recid++;4920 }4921 }4922out:4923 status = cqr->status == DASD_CQR_DONE;4924 dasd_sfree_request(cqr, cqr->memdev);4925 return status;4926}4927 4928/*4929 * Modify ccw/tcw in cqr so it can be started on a base device.4930 *4931 * Note that this is not enough to restart the cqr!4932 * Either reset cqr->startdev as well (summary unit check handling)4933 * or restart via separate cqr (as in ERP handling).4934 */4935void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *cqr)4936{4937 struct ccw1 *ccw;4938 struct PFX_eckd_data *pfxdata;4939 struct tcw *tcw;4940 struct tccb *tccb;4941 struct dcw *dcw;4942 4943 if (cqr->cpmode == 1) {4944 tcw = cqr->cpaddr;4945 tccb = tcw_get_tccb(tcw);4946 dcw = (struct dcw *)&tccb->tca[0];4947 pfxdata = (struct PFX_eckd_data *)&dcw->cd[0];4948 pfxdata->validity.verify_base = 0;4949 pfxdata->validity.hyper_pav = 0;4950 } else {4951 ccw = cqr->cpaddr;4952 pfxdata = cqr->data;4953 if (ccw->cmd_code == DASD_ECKD_CCW_PFX) {4954 pfxdata->validity.verify_base = 0;4955 pfxdata->validity.hyper_pav = 0;4956 }4957 }4958}4959 4960#define DASD_ECKD_CHANQ_MAX_SIZE 44961 4962static struct dasd_ccw_req *dasd_eckd_build_alias_cp(struct dasd_device *base,4963 struct dasd_block *block,4964 struct request *req)4965{4966 struct dasd_eckd_private *private;4967 struct dasd_device *startdev;4968 unsigned long flags;4969 struct dasd_ccw_req *cqr;4970 4971 startdev = dasd_alias_get_start_dev(base);4972 if (!startdev)4973 startdev = base;4974 private = startdev->private;4975 if (private->count >= DASD_ECKD_CHANQ_MAX_SIZE)4976 return ERR_PTR(-EBUSY);4977 4978 spin_lock_irqsave(get_ccwdev_lock(startdev->cdev), flags);4979 private->count++;4980 if ((base->features & DASD_FEATURE_USERAW))4981 cqr = dasd_eckd_build_cp_raw(startdev, block, req);4982 else4983 cqr = dasd_eckd_build_cp(startdev, block, req);4984 if (IS_ERR(cqr))4985 private->count--;4986 spin_unlock_irqrestore(get_ccwdev_lock(startdev->cdev), flags);4987 return cqr;4988}4989 4990static int dasd_eckd_free_alias_cp(struct dasd_ccw_req *cqr,4991 struct request *req)4992{4993 struct dasd_eckd_private *private;4994 unsigned long flags;4995 4996 spin_lock_irqsave(get_ccwdev_lock(cqr->memdev->cdev), flags);4997 private = cqr->memdev->private;4998 private->count--;4999 spin_unlock_irqrestore(get_ccwdev_lock(cqr->memdev->cdev), flags);5000 return dasd_eckd_free_cp(cqr, req);5001}5002 5003static int5004dasd_eckd_fill_info(struct dasd_device * device,5005 struct dasd_information2_t * info)5006{5007 struct dasd_eckd_private *private = device->private;5008 5009 info->label_block = 2;5010 info->FBA_layout = private->uses_cdl ? 0 : 1;5011 info->format = private->uses_cdl ? DASD_FORMAT_CDL : DASD_FORMAT_LDL;5012 info->characteristics_size = sizeof(private->rdc_data);5013 memcpy(info->characteristics, &private->rdc_data,5014 sizeof(private->rdc_data));5015 info->confdata_size = min_t(unsigned long, private->conf.len,5016 sizeof(info->configuration_data));5017 memcpy(info->configuration_data, private->conf.data,5018 info->confdata_size);5019 return 0;5020}5021 5022/*5023 * SECTION: ioctl functions for eckd devices.5024 */5025 5026/*5027 * Release device ioctl.5028 * Buils a channel programm to releases a prior reserved5029 * (see dasd_eckd_reserve) device.5030 */5031static int5032dasd_eckd_release(struct dasd_device *device)5033{5034 struct dasd_ccw_req *cqr;5035 int rc;5036 struct ccw1 *ccw;5037 int useglobal;5038 5039 if (!capable(CAP_SYS_ADMIN))5040 return -EACCES;5041 5042 useglobal = 0;5043 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);5044 if (IS_ERR(cqr)) {5045 mutex_lock(&dasd_reserve_mutex);5046 useglobal = 1;5047 cqr = &dasd_reserve_req->cqr;5048 memset(cqr, 0, sizeof(*cqr));5049 memset(&dasd_reserve_req->ccw, 0,5050 sizeof(dasd_reserve_req->ccw));5051 cqr->cpaddr = &dasd_reserve_req->ccw;5052 cqr->data = &dasd_reserve_req->data;5053 cqr->magic = DASD_ECKD_MAGIC;5054 }5055 ccw = cqr->cpaddr;5056 ccw->cmd_code = DASD_ECKD_CCW_RELEASE;5057 ccw->flags |= CCW_FLAG_SLI;5058 ccw->count = 32;5059 ccw->cda = virt_to_dma32(cqr->data);5060 cqr->startdev = device;5061 cqr->memdev = device;5062 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5063 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);5064 cqr->retries = 2; /* set retry counter to enable basic ERP */5065 cqr->expires = 2 * HZ;5066 cqr->buildclk = get_tod_clock();5067 cqr->status = DASD_CQR_FILLED;5068 5069 rc = dasd_sleep_on_immediatly(cqr);5070 if (!rc)5071 clear_bit(DASD_FLAG_IS_RESERVED, &device->flags);5072 5073 if (useglobal)5074 mutex_unlock(&dasd_reserve_mutex);5075 else5076 dasd_sfree_request(cqr, cqr->memdev);5077 return rc;5078}5079 5080/*5081 * Reserve device ioctl.5082 * Options are set to 'synchronous wait for interrupt' and5083 * 'timeout the request'. This leads to a terminate IO if5084 * the interrupt is outstanding for a certain time.5085 */5086static int5087dasd_eckd_reserve(struct dasd_device *device)5088{5089 struct dasd_ccw_req *cqr;5090 int rc;5091 struct ccw1 *ccw;5092 int useglobal;5093 5094 if (!capable(CAP_SYS_ADMIN))5095 return -EACCES;5096 5097 useglobal = 0;5098 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);5099 if (IS_ERR(cqr)) {5100 mutex_lock(&dasd_reserve_mutex);5101 useglobal = 1;5102 cqr = &dasd_reserve_req->cqr;5103 memset(cqr, 0, sizeof(*cqr));5104 memset(&dasd_reserve_req->ccw, 0,5105 sizeof(dasd_reserve_req->ccw));5106 cqr->cpaddr = &dasd_reserve_req->ccw;5107 cqr->data = &dasd_reserve_req->data;5108 cqr->magic = DASD_ECKD_MAGIC;5109 }5110 ccw = cqr->cpaddr;5111 ccw->cmd_code = DASD_ECKD_CCW_RESERVE;5112 ccw->flags |= CCW_FLAG_SLI;5113 ccw->count = 32;5114 ccw->cda = virt_to_dma32(cqr->data);5115 cqr->startdev = device;5116 cqr->memdev = device;5117 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5118 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);5119 cqr->retries = 2; /* set retry counter to enable basic ERP */5120 cqr->expires = 2 * HZ;5121 cqr->buildclk = get_tod_clock();5122 cqr->status = DASD_CQR_FILLED;5123 5124 rc = dasd_sleep_on_immediatly(cqr);5125 if (!rc)5126 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);5127 5128 if (useglobal)5129 mutex_unlock(&dasd_reserve_mutex);5130 else5131 dasd_sfree_request(cqr, cqr->memdev);5132 return rc;5133}5134 5135/*5136 * Steal lock ioctl - unconditional reserve device.5137 * Buils a channel programm to break a device's reservation.5138 * (unconditional reserve)5139 */5140static int5141dasd_eckd_steal_lock(struct dasd_device *device)5142{5143 struct dasd_ccw_req *cqr;5144 int rc;5145 struct ccw1 *ccw;5146 int useglobal;5147 5148 if (!capable(CAP_SYS_ADMIN))5149 return -EACCES;5150 5151 useglobal = 0;5152 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 32, device, NULL);5153 if (IS_ERR(cqr)) {5154 mutex_lock(&dasd_reserve_mutex);5155 useglobal = 1;5156 cqr = &dasd_reserve_req->cqr;5157 memset(cqr, 0, sizeof(*cqr));5158 memset(&dasd_reserve_req->ccw, 0,5159 sizeof(dasd_reserve_req->ccw));5160 cqr->cpaddr = &dasd_reserve_req->ccw;5161 cqr->data = &dasd_reserve_req->data;5162 cqr->magic = DASD_ECKD_MAGIC;5163 }5164 ccw = cqr->cpaddr;5165 ccw->cmd_code = DASD_ECKD_CCW_SLCK;5166 ccw->flags |= CCW_FLAG_SLI;5167 ccw->count = 32;5168 ccw->cda = virt_to_dma32(cqr->data);5169 cqr->startdev = device;5170 cqr->memdev = device;5171 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5172 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);5173 cqr->retries = 2; /* set retry counter to enable basic ERP */5174 cqr->expires = 2 * HZ;5175 cqr->buildclk = get_tod_clock();5176 cqr->status = DASD_CQR_FILLED;5177 5178 rc = dasd_sleep_on_immediatly(cqr);5179 if (!rc)5180 set_bit(DASD_FLAG_IS_RESERVED, &device->flags);5181 5182 if (useglobal)5183 mutex_unlock(&dasd_reserve_mutex);5184 else5185 dasd_sfree_request(cqr, cqr->memdev);5186 return rc;5187}5188 5189/*5190 * SNID - Sense Path Group ID5191 * This ioctl may be used in situations where I/O is stalled due to5192 * a reserve, so if the normal dasd_smalloc_request fails, we use the5193 * preallocated dasd_reserve_req.5194 */5195static int dasd_eckd_snid(struct dasd_device *device,5196 void __user *argp)5197{5198 struct dasd_ccw_req *cqr;5199 int rc;5200 struct ccw1 *ccw;5201 int useglobal;5202 struct dasd_snid_ioctl_data usrparm;5203 5204 if (!capable(CAP_SYS_ADMIN))5205 return -EACCES;5206 5207 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))5208 return -EFAULT;5209 5210 useglobal = 0;5211 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1,5212 sizeof(struct dasd_snid_data), device,5213 NULL);5214 if (IS_ERR(cqr)) {5215 mutex_lock(&dasd_reserve_mutex);5216 useglobal = 1;5217 cqr = &dasd_reserve_req->cqr;5218 memset(cqr, 0, sizeof(*cqr));5219 memset(&dasd_reserve_req->ccw, 0,5220 sizeof(dasd_reserve_req->ccw));5221 cqr->cpaddr = &dasd_reserve_req->ccw;5222 cqr->data = &dasd_reserve_req->data;5223 cqr->magic = DASD_ECKD_MAGIC;5224 }5225 ccw = cqr->cpaddr;5226 ccw->cmd_code = DASD_ECKD_CCW_SNID;5227 ccw->flags |= CCW_FLAG_SLI;5228 ccw->count = 12;5229 ccw->cda = virt_to_dma32(cqr->data);5230 cqr->startdev = device;5231 cqr->memdev = device;5232 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5233 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);5234 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);5235 cqr->retries = 5;5236 cqr->expires = 10 * HZ;5237 cqr->buildclk = get_tod_clock();5238 cqr->status = DASD_CQR_FILLED;5239 cqr->lpm = usrparm.path_mask;5240 5241 rc = dasd_sleep_on_immediatly(cqr);5242 /* verify that I/O processing didn't modify the path mask */5243 if (!rc && usrparm.path_mask && (cqr->lpm != usrparm.path_mask))5244 rc = -EIO;5245 if (!rc) {5246 usrparm.data = *((struct dasd_snid_data *)cqr->data);5247 if (copy_to_user(argp, &usrparm, sizeof(usrparm)))5248 rc = -EFAULT;5249 }5250 5251 if (useglobal)5252 mutex_unlock(&dasd_reserve_mutex);5253 else5254 dasd_sfree_request(cqr, cqr->memdev);5255 return rc;5256}5257 5258/*5259 * Read performance statistics5260 */5261static int5262dasd_eckd_performance(struct dasd_device *device, void __user *argp)5263{5264 struct dasd_psf_prssd_data *prssdp;5265 struct dasd_rssd_perf_stats_t *stats;5266 struct dasd_ccw_req *cqr;5267 struct ccw1 *ccw;5268 int rc;5269 5270 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,5271 (sizeof(struct dasd_psf_prssd_data) +5272 sizeof(struct dasd_rssd_perf_stats_t)),5273 device, NULL);5274 if (IS_ERR(cqr)) {5275 DBF_DEV_EVENT(DBF_WARNING, device, "%s",5276 "Could not allocate initialization request");5277 return PTR_ERR(cqr);5278 }5279 cqr->startdev = device;5280 cqr->memdev = device;5281 cqr->retries = 0;5282 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5283 cqr->expires = 10 * HZ;5284 5285 /* Prepare for Read Subsystem Data */5286 prssdp = (struct dasd_psf_prssd_data *) cqr->data;5287 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));5288 prssdp->order = PSF_ORDER_PRSSD;5289 prssdp->suborder = 0x01; /* Performance Statistics */5290 prssdp->varies[1] = 0x01; /* Perf Statistics for the Subsystem */5291 5292 ccw = cqr->cpaddr;5293 ccw->cmd_code = DASD_ECKD_CCW_PSF;5294 ccw->count = sizeof(struct dasd_psf_prssd_data);5295 ccw->flags |= CCW_FLAG_CC;5296 ccw->cda = virt_to_dma32(prssdp);5297 5298 /* Read Subsystem Data - Performance Statistics */5299 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);5300 memset(stats, 0, sizeof(struct dasd_rssd_perf_stats_t));5301 5302 ccw++;5303 ccw->cmd_code = DASD_ECKD_CCW_RSSD;5304 ccw->count = sizeof(struct dasd_rssd_perf_stats_t);5305 ccw->cda = virt_to_dma32(stats);5306 5307 cqr->buildclk = get_tod_clock();5308 cqr->status = DASD_CQR_FILLED;5309 rc = dasd_sleep_on(cqr);5310 if (rc == 0) {5311 prssdp = (struct dasd_psf_prssd_data *) cqr->data;5312 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);5313 if (copy_to_user(argp, stats,5314 sizeof(struct dasd_rssd_perf_stats_t)))5315 rc = -EFAULT;5316 }5317 dasd_sfree_request(cqr, cqr->memdev);5318 return rc;5319}5320 5321/*5322 * Get attributes (cache operations)5323 * Returnes the cache attributes used in Define Extend (DE).5324 */5325static int5326dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)5327{5328 struct dasd_eckd_private *private = device->private;5329 struct attrib_data_t attrib = private->attrib;5330 int rc;5331 5332 if (!capable(CAP_SYS_ADMIN))5333 return -EACCES;5334 if (!argp)5335 return -EINVAL;5336 5337 rc = 0;5338 if (copy_to_user(argp, (long *) &attrib,5339 sizeof(struct attrib_data_t)))5340 rc = -EFAULT;5341 5342 return rc;5343}5344 5345/*5346 * Set attributes (cache operations)5347 * Stores the attributes for cache operation to be used in Define Extend (DE).5348 */5349static int5350dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)5351{5352 struct dasd_eckd_private *private = device->private;5353 struct attrib_data_t attrib;5354 5355 if (!capable(CAP_SYS_ADMIN))5356 return -EACCES;5357 if (!argp)5358 return -EINVAL;5359 5360 if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))5361 return -EFAULT;5362 private->attrib = attrib;5363 5364 dev_info(&device->cdev->dev,5365 "The DASD cache mode was set to %x (%i cylinder prestage)\n",5366 private->attrib.operation, private->attrib.nr_cyl);5367 return 0;5368}5369 5370/*5371 * Issue syscall I/O to EMC Symmetrix array.5372 * CCWs are PSF and RSSD5373 */5374static int dasd_symm_io(struct dasd_device *device, void __user *argp)5375{5376 struct dasd_symmio_parms usrparm;5377 char *psf_data, *rssd_result;5378 struct dasd_ccw_req *cqr;5379 struct ccw1 *ccw;5380 char psf0, psf1;5381 int rc;5382 5383 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))5384 return -EACCES;5385 psf0 = psf1 = 0;5386 5387 /* Copy parms from caller */5388 rc = -EFAULT;5389 if (copy_from_user(&usrparm, argp, sizeof(usrparm)))5390 goto out;5391 if (is_compat_task()) {5392 /* Make sure pointers are sane even on 31 bit. */5393 rc = -EINVAL;5394 if ((usrparm.psf_data >> 32) != 0)5395 goto out;5396 if ((usrparm.rssd_result >> 32) != 0)5397 goto out;5398 usrparm.psf_data &= 0x7fffffffULL;5399 usrparm.rssd_result &= 0x7fffffffULL;5400 }5401 /* at least 2 bytes are accessed and should be allocated */5402 if (usrparm.psf_data_len < 2) {5403 DBF_DEV_EVENT(DBF_WARNING, device,5404 "Symmetrix ioctl invalid data length %d",5405 usrparm.psf_data_len);5406 rc = -EINVAL;5407 goto out;5408 }5409 /* alloc I/O data area */5410 psf_data = kzalloc(usrparm.psf_data_len, GFP_KERNEL | GFP_DMA);5411 rssd_result = kzalloc(usrparm.rssd_result_len, GFP_KERNEL | GFP_DMA);5412 if (!psf_data || !rssd_result) {5413 rc = -ENOMEM;5414 goto out_free;5415 }5416 5417 /* get syscall header from user space */5418 rc = -EFAULT;5419 if (copy_from_user(psf_data,5420 (void __user *)(unsigned long) usrparm.psf_data,5421 usrparm.psf_data_len))5422 goto out_free;5423 psf0 = psf_data[0];5424 psf1 = psf_data[1];5425 5426 /* setup CCWs for PSF + RSSD */5427 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 2, 0, device, NULL);5428 if (IS_ERR(cqr)) {5429 DBF_DEV_EVENT(DBF_WARNING, device, "%s",5430 "Could not allocate initialization request");5431 rc = PTR_ERR(cqr);5432 goto out_free;5433 }5434 5435 cqr->startdev = device;5436 cqr->memdev = device;5437 cqr->retries = 3;5438 cqr->expires = 10 * HZ;5439 cqr->buildclk = get_tod_clock();5440 cqr->status = DASD_CQR_FILLED;5441 5442 /* Build the ccws */5443 ccw = cqr->cpaddr;5444 5445 /* PSF ccw */5446 ccw->cmd_code = DASD_ECKD_CCW_PSF;5447 ccw->count = usrparm.psf_data_len;5448 ccw->flags |= CCW_FLAG_CC;5449 ccw->cda = virt_to_dma32(psf_data);5450 5451 ccw++;5452 5453 /* RSSD ccw */5454 ccw->cmd_code = DASD_ECKD_CCW_RSSD;5455 ccw->count = usrparm.rssd_result_len;5456 ccw->flags = CCW_FLAG_SLI ;5457 ccw->cda = virt_to_dma32(rssd_result);5458 5459 rc = dasd_sleep_on(cqr);5460 if (rc)5461 goto out_sfree;5462 5463 rc = -EFAULT;5464 if (copy_to_user((void __user *)(unsigned long) usrparm.rssd_result,5465 rssd_result, usrparm.rssd_result_len))5466 goto out_sfree;5467 rc = 0;5468 5469out_sfree:5470 dasd_sfree_request(cqr, cqr->memdev);5471out_free:5472 kfree(rssd_result);5473 kfree(psf_data);5474out:5475 DBF_DEV_EVENT(DBF_WARNING, device,5476 "Symmetrix ioctl (0x%02x 0x%02x): rc=%d",5477 (int) psf0, (int) psf1, rc);5478 return rc;5479}5480 5481static int5482dasd_eckd_ioctl(struct dasd_block *block, unsigned int cmd, void __user *argp)5483{5484 struct dasd_device *device = block->base;5485 5486 switch (cmd) {5487 case BIODASDGATTR:5488 return dasd_eckd_get_attrib(device, argp);5489 case BIODASDSATTR:5490 return dasd_eckd_set_attrib(device, argp);5491 case BIODASDPSRD:5492 return dasd_eckd_performance(device, argp);5493 case BIODASDRLSE:5494 return dasd_eckd_release(device);5495 case BIODASDRSRV:5496 return dasd_eckd_reserve(device);5497 case BIODASDSLCK:5498 return dasd_eckd_steal_lock(device);5499 case BIODASDSNID:5500 return dasd_eckd_snid(device, argp);5501 case BIODASDSYMMIO:5502 return dasd_symm_io(device, argp);5503 default:5504 return -ENOTTY;5505 }5506}5507 5508/*5509 * Dump the range of CCWs into 'page' buffer5510 * and return number of printed chars.5511 */5512static void5513dasd_eckd_dump_ccw_range(struct dasd_device *device, struct ccw1 *from,5514 struct ccw1 *to, char *page)5515{5516 int len, count;5517 char *datap;5518 5519 len = 0;5520 while (from <= to) {5521 len += sprintf(page + len, "CCW %px: %08X %08X DAT:",5522 from, ((int *) from)[0], ((int *) from)[1]);5523 5524 /* get pointer to data (consider IDALs) */5525 if (from->flags & CCW_FLAG_IDA)5526 datap = dma64_to_virt(*((dma64_t *)dma32_to_virt(from->cda)));5527 else5528 datap = dma32_to_virt(from->cda);5529 5530 /* dump data (max 128 bytes) */5531 for (count = 0; count < from->count && count < 128; count++) {5532 if (count % 32 == 0)5533 len += sprintf(page + len, "\n");5534 if (count % 8 == 0)5535 len += sprintf(page + len, " ");5536 if (count % 4 == 0)5537 len += sprintf(page + len, " ");5538 len += sprintf(page + len, "%02x", datap[count]);5539 }5540 len += sprintf(page + len, "\n");5541 from++;5542 }5543 if (len > 0)5544 dev_err(&device->cdev->dev, "%s", page);5545}5546 5547static void5548dasd_eckd_dump_sense_dbf(struct dasd_device *device, struct irb *irb,5549 char *reason)5550{5551 u64 *sense;5552 u64 *stat;5553 5554 sense = (u64 *) dasd_get_sense(irb);5555 stat = (u64 *) &irb->scsw;5556 if (sense) {5557 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : "5558 "%016llx %016llx %016llx %016llx",5559 reason, *stat, *((u32 *) (stat + 1)),5560 sense[0], sense[1], sense[2], sense[3]);5561 } else {5562 DBF_DEV_EVENT(DBF_EMERG, device, "%s: %016llx %08x : %s",5563 reason, *stat, *((u32 *) (stat + 1)),5564 "NO VALID SENSE");5565 }5566}5567 5568/*5569 * Print sense data and related channel program.5570 * Parts are printed because printk buffer is only 1024 bytes.5571 */5572static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,5573 struct dasd_ccw_req *req, struct irb *irb)5574{5575 struct ccw1 *first, *last, *fail, *from, *to;5576 struct device *dev;5577 int len, sl, sct;5578 char *page;5579 5580 dev = &device->cdev->dev;5581 5582 page = (char *) get_zeroed_page(GFP_ATOMIC);5583 if (page == NULL) {5584 DBF_DEV_EVENT(DBF_WARNING, device, "%s",5585 "No memory to dump sense data\n");5586 return;5587 }5588 /* dump the sense data */5589 len = sprintf(page, "I/O status report:\n");5590 len += sprintf(page + len,5591 "in req: %px CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X CS:%02X RC:%d\n",5592 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),5593 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),5594 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),5595 req ? req->intrc : 0);5596 len += sprintf(page + len, "Failing CCW: %px\n",5597 dma32_to_virt(irb->scsw.cmd.cpa));5598 if (irb->esw.esw0.erw.cons) {5599 for (sl = 0; sl < 4; sl++) {5600 len += sprintf(page + len, "Sense(hex) %2d-%2d:",5601 (8 * sl), ((8 * sl) + 7));5602 5603 for (sct = 0; sct < 8; sct++) {5604 len += sprintf(page + len, " %02x",5605 irb->ecw[8 * sl + sct]);5606 }5607 len += sprintf(page + len, "\n");5608 }5609 5610 if (irb->ecw[27] & DASD_SENSE_BIT_0) {5611 /* 24 Byte Sense Data */5612 sprintf(page + len,5613 "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",5614 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,5615 irb->ecw[1] & 0x10 ? "" : "no");5616 } else {5617 /* 32 Byte Sense Data */5618 sprintf(page + len,5619 "32 Byte: Format: %x Exception class %x\n",5620 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);5621 }5622 } else {5623 sprintf(page + len, "SORRY - NO VALID SENSE AVAILABLE\n");5624 }5625 dev_err(dev, "%s", page);5626 5627 if (req) {5628 /* req == NULL for unsolicited interrupts */5629 /* dump the Channel Program (max 140 Bytes per line) */5630 /* Count CCW and print first CCWs (maximum 7) */5631 first = req->cpaddr;5632 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);5633 to = min(first + 6, last);5634 dev_err(dev, "Related CP in req: %px\n", req);5635 dasd_eckd_dump_ccw_range(device, first, to, page);5636 5637 /* print failing CCW area (maximum 4) */5638 /* scsw->cda is either valid or zero */5639 from = ++to;5640 fail = dma32_to_virt(irb->scsw.cmd.cpa); /* failing CCW */5641 if (from < fail - 2) {5642 from = fail - 2; /* there is a gap - print header */5643 dev_err(dev, "......\n");5644 }5645 to = min(fail + 1, last);5646 dasd_eckd_dump_ccw_range(device, from, to, page + len);5647 5648 /* print last CCWs (maximum 2) */5649 len = 0;5650 from = max(from, ++to);5651 if (from < last - 1) {5652 from = last - 1; /* there is a gap - print header */5653 dev_err(dev, "......\n");5654 }5655 dasd_eckd_dump_ccw_range(device, from, last, page + len);5656 }5657 free_page((unsigned long) page);5658}5659 5660 5661/*5662 * Print sense data from a tcw.5663 */5664static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,5665 struct dasd_ccw_req *req, struct irb *irb)5666{5667 char *page;5668 int len, sl, sct, residual;5669 struct tsb *tsb;5670 u8 *sense, *rcq;5671 5672 page = (char *) get_zeroed_page(GFP_ATOMIC);5673 if (page == NULL) {5674 DBF_DEV_EVENT(DBF_WARNING, device, " %s",5675 "No memory to dump sense data");5676 return;5677 }5678 /* dump the sense data */5679 len = sprintf(page, "I/O status report:\n");5680 len += sprintf(page + len,5681 "in req: %px CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "5682 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n",5683 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),5684 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),5685 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),5686 irb->scsw.tm.fcxs,5687 (irb->scsw.tm.ifob << 7) | irb->scsw.tm.sesq,5688 req ? req->intrc : 0);5689 len += sprintf(page + len, "Failing TCW: %px\n",5690 dma32_to_virt(irb->scsw.tm.tcw));5691 5692 tsb = NULL;5693 sense = NULL;5694 if (irb->scsw.tm.tcw && (irb->scsw.tm.fcxs & 0x01))5695 tsb = tcw_get_tsb(dma32_to_virt(irb->scsw.tm.tcw));5696 5697 if (tsb) {5698 len += sprintf(page + len, "tsb->length %d\n", tsb->length);5699 len += sprintf(page + len, "tsb->flags %x\n", tsb->flags);5700 len += sprintf(page + len, "tsb->dcw_offset %d\n", tsb->dcw_offset);5701 len += sprintf(page + len, "tsb->count %d\n", tsb->count);5702 residual = tsb->count - 28;5703 len += sprintf(page + len, "residual %d\n", residual);5704 5705 switch (tsb->flags & 0x07) {5706 case 1: /* tsa_iostat */5707 len += sprintf(page + len, "tsb->tsa.iostat.dev_time %d\n",5708 tsb->tsa.iostat.dev_time);5709 len += sprintf(page + len, "tsb->tsa.iostat.def_time %d\n",5710 tsb->tsa.iostat.def_time);5711 len += sprintf(page + len, "tsb->tsa.iostat.queue_time %d\n",5712 tsb->tsa.iostat.queue_time);5713 len += sprintf(page + len, "tsb->tsa.iostat.dev_busy_time %d\n",5714 tsb->tsa.iostat.dev_busy_time);5715 len += sprintf(page + len, "tsb->tsa.iostat.dev_act_time %d\n",5716 tsb->tsa.iostat.dev_act_time);5717 sense = tsb->tsa.iostat.sense;5718 break;5719 case 2: /* ts_ddpc */5720 len += sprintf(page + len, "tsb->tsa.ddpc.rc %d\n",5721 tsb->tsa.ddpc.rc);5722 for (sl = 0; sl < 2; sl++) {5723 len += sprintf(page + len,5724 "tsb->tsa.ddpc.rcq %2d-%2d: ",5725 (8 * sl), ((8 * sl) + 7));5726 rcq = tsb->tsa.ddpc.rcq;5727 for (sct = 0; sct < 8; sct++) {5728 len += sprintf(page + len, "%02x",5729 rcq[8 * sl + sct]);5730 }5731 len += sprintf(page + len, "\n");5732 }5733 sense = tsb->tsa.ddpc.sense;5734 break;5735 case 3: /* tsa_intrg */5736 len += sprintf(page + len,5737 "tsb->tsa.intrg.: not supported yet\n");5738 break;5739 }5740 5741 if (sense) {5742 for (sl = 0; sl < 4; sl++) {5743 len += sprintf(page + len,5744 "Sense(hex) %2d-%2d:",5745 (8 * sl), ((8 * sl) + 7));5746 for (sct = 0; sct < 8; sct++) {5747 len += sprintf(page + len, " %02x",5748 sense[8 * sl + sct]);5749 }5750 len += sprintf(page + len, "\n");5751 }5752 5753 if (sense[27] & DASD_SENSE_BIT_0) {5754 /* 24 Byte Sense Data */5755 sprintf(page + len,5756 "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",5757 sense[7] >> 4, sense[7] & 0x0f,5758 sense[1] & 0x10 ? "" : "no");5759 } else {5760 /* 32 Byte Sense Data */5761 sprintf(page + len,5762 "32 Byte: Format: %x Exception class %x\n",5763 sense[6] & 0x0f, sense[22] >> 4);5764 }5765 } else {5766 sprintf(page + len, "SORRY - NO VALID SENSE AVAILABLE\n");5767 }5768 } else {5769 sprintf(page + len, "SORRY - NO TSB DATA AVAILABLE\n");5770 }5771 dev_err(&device->cdev->dev, "%s", page);5772 free_page((unsigned long) page);5773}5774 5775static void dasd_eckd_dump_sense(struct dasd_device *device,5776 struct dasd_ccw_req *req, struct irb *irb)5777{5778 u8 *sense = dasd_get_sense(irb);5779 5780 /*5781 * In some cases certain errors might be expected and5782 * log messages shouldn't be written then.5783 * Check if the according suppress bit is set.5784 */5785 if (sense && (sense[1] & SNS1_INV_TRACK_FORMAT) &&5786 !(sense[2] & SNS2_ENV_DATA_PRESENT) &&5787 test_bit(DASD_CQR_SUPPRESS_IT, &req->flags))5788 return;5789 5790 if (sense && sense[0] & SNS0_CMD_REJECT &&5791 test_bit(DASD_CQR_SUPPRESS_CR, &req->flags))5792 return;5793 5794 if (sense && sense[1] & SNS1_NO_REC_FOUND &&5795 test_bit(DASD_CQR_SUPPRESS_NRF, &req->flags))5796 return;5797 5798 if (scsw_cstat(&irb->scsw) == 0x40 &&5799 test_bit(DASD_CQR_SUPPRESS_IL, &req->flags))5800 return;5801 5802 if (scsw_is_tm(&irb->scsw))5803 dasd_eckd_dump_sense_tcw(device, req, irb);5804 else5805 dasd_eckd_dump_sense_ccw(device, req, irb);5806}5807 5808static int dasd_eckd_reload_device(struct dasd_device *device)5809{5810 struct dasd_eckd_private *private = device->private;5811 char print_uid[DASD_UID_STRLEN];5812 int rc, old_base;5813 struct dasd_uid uid;5814 unsigned long flags;5815 5816 /*5817 * remove device from alias handling to prevent new requests5818 * from being scheduled on the wrong alias device5819 */5820 dasd_alias_remove_device(device);5821 5822 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);5823 old_base = private->uid.base_unit_addr;5824 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);5825 5826 /* Read Configuration Data */5827 rc = dasd_eckd_read_conf(device);5828 if (rc)5829 goto out_err;5830 5831 dasd_eckd_read_fc_security(device);5832 5833 rc = dasd_eckd_generate_uid(device);5834 if (rc)5835 goto out_err;5836 /*5837 * update unit address configuration and5838 * add device to alias management5839 */5840 dasd_alias_update_add_device(device);5841 5842 dasd_eckd_get_uid(device, &uid);5843 5844 if (old_base != uid.base_unit_addr) {5845 dasd_eckd_get_uid_string(&private->conf, print_uid);5846 dev_info(&device->cdev->dev,5847 "An Alias device was reassigned to a new base device "5848 "with UID: %s\n", print_uid);5849 }5850 return 0;5851 5852out_err:5853 return -1;5854}5855 5856static int dasd_eckd_read_message_buffer(struct dasd_device *device,5857 struct dasd_rssd_messages *messages,5858 __u8 lpum)5859{5860 struct dasd_rssd_messages *message_buf;5861 struct dasd_psf_prssd_data *prssdp;5862 struct dasd_ccw_req *cqr;5863 struct ccw1 *ccw;5864 int rc;5865 5866 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,5867 (sizeof(struct dasd_psf_prssd_data) +5868 sizeof(struct dasd_rssd_messages)),5869 device, NULL);5870 if (IS_ERR(cqr)) {5871 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",5872 "Could not allocate read message buffer request");5873 return PTR_ERR(cqr);5874 }5875 5876 cqr->lpm = lpum;5877retry:5878 cqr->startdev = device;5879 cqr->memdev = device;5880 cqr->block = NULL;5881 cqr->expires = 10 * HZ;5882 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);5883 /* dasd_sleep_on_immediatly does not do complex error5884 * recovery so clear erp flag and set retry counter to5885 * do basic erp */5886 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);5887 cqr->retries = 256;5888 5889 /* Prepare for Read Subsystem Data */5890 prssdp = (struct dasd_psf_prssd_data *) cqr->data;5891 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));5892 prssdp->order = PSF_ORDER_PRSSD;5893 prssdp->suborder = 0x03; /* Message Buffer */5894 /* all other bytes of prssdp must be zero */5895 5896 ccw = cqr->cpaddr;5897 ccw->cmd_code = DASD_ECKD_CCW_PSF;5898 ccw->count = sizeof(struct dasd_psf_prssd_data);5899 ccw->flags |= CCW_FLAG_CC;5900 ccw->flags |= CCW_FLAG_SLI;5901 ccw->cda = virt_to_dma32(prssdp);5902 5903 /* Read Subsystem Data - message buffer */5904 message_buf = (struct dasd_rssd_messages *) (prssdp + 1);5905 memset(message_buf, 0, sizeof(struct dasd_rssd_messages));5906 5907 ccw++;5908 ccw->cmd_code = DASD_ECKD_CCW_RSSD;5909 ccw->count = sizeof(struct dasd_rssd_messages);5910 ccw->flags |= CCW_FLAG_SLI;5911 ccw->cda = virt_to_dma32(message_buf);5912 5913 cqr->buildclk = get_tod_clock();5914 cqr->status = DASD_CQR_FILLED;5915 rc = dasd_sleep_on_immediatly(cqr);5916 if (rc == 0) {5917 prssdp = (struct dasd_psf_prssd_data *) cqr->data;5918 message_buf = (struct dasd_rssd_messages *)5919 (prssdp + 1);5920 memcpy(messages, message_buf,5921 sizeof(struct dasd_rssd_messages));5922 } else if (cqr->lpm) {5923 /*5924 * on z/VM we might not be able to do I/O on the requested path5925 * but instead we get the required information on any path5926 * so retry with open path mask5927 */5928 cqr->lpm = 0;5929 goto retry;5930 } else5931 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,5932 "Reading messages failed with rc=%d\n"5933 , rc);5934 dasd_sfree_request(cqr, cqr->memdev);5935 return rc;5936}5937 5938static int dasd_eckd_query_host_access(struct dasd_device *device,5939 struct dasd_psf_query_host_access *data)5940{5941 struct dasd_eckd_private *private = device->private;5942 struct dasd_psf_query_host_access *host_access;5943 struct dasd_psf_prssd_data *prssdp;5944 struct dasd_ccw_req *cqr;5945 struct ccw1 *ccw;5946 int rc;5947 5948 /* not available for HYPER PAV alias devices */5949 if (!device->block && private->lcu->pav == HYPER_PAV)5950 return -EOPNOTSUPP;5951 5952 /* may not be supported by the storage server */5953 if (!(private->features.feature[14] & 0x80))5954 return -EOPNOTSUPP;5955 5956 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,5957 sizeof(struct dasd_psf_prssd_data) + 1,5958 device, NULL);5959 if (IS_ERR(cqr)) {5960 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",5961 "Could not allocate read message buffer request");5962 return PTR_ERR(cqr);5963 }5964 host_access = kzalloc(sizeof(*host_access), GFP_KERNEL | GFP_DMA);5965 if (!host_access) {5966 dasd_sfree_request(cqr, device);5967 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",5968 "Could not allocate host_access buffer");5969 return -ENOMEM;5970 }5971 cqr->startdev = device;5972 cqr->memdev = device;5973 cqr->block = NULL;5974 cqr->retries = 256;5975 cqr->expires = 10 * HZ;5976 5977 /* Prepare for Read Subsystem Data */5978 prssdp = (struct dasd_psf_prssd_data *) cqr->data;5979 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));5980 prssdp->order = PSF_ORDER_PRSSD;5981 prssdp->suborder = PSF_SUBORDER_QHA; /* query host access */5982 /* LSS and Volume that will be queried */5983 prssdp->lss = private->conf.ned->ID;5984 prssdp->volume = private->conf.ned->unit_addr;5985 /* all other bytes of prssdp must be zero */5986 5987 ccw = cqr->cpaddr;5988 ccw->cmd_code = DASD_ECKD_CCW_PSF;5989 ccw->count = sizeof(struct dasd_psf_prssd_data);5990 ccw->flags |= CCW_FLAG_CC;5991 ccw->flags |= CCW_FLAG_SLI;5992 ccw->cda = virt_to_dma32(prssdp);5993 5994 /* Read Subsystem Data - query host access */5995 ccw++;5996 ccw->cmd_code = DASD_ECKD_CCW_RSSD;5997 ccw->count = sizeof(struct dasd_psf_query_host_access);5998 ccw->flags |= CCW_FLAG_SLI;5999 ccw->cda = virt_to_dma32(host_access);6000 6001 cqr->buildclk = get_tod_clock();6002 cqr->status = DASD_CQR_FILLED;6003 /* the command might not be supported, suppress error message */6004 __set_bit(DASD_CQR_SUPPRESS_CR, &cqr->flags);6005 rc = dasd_sleep_on_interruptible(cqr);6006 if (rc == 0) {6007 *data = *host_access;6008 } else {6009 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,6010 "Reading host access data failed with rc=%d\n",6011 rc);6012 rc = -EOPNOTSUPP;6013 }6014 6015 dasd_sfree_request(cqr, cqr->memdev);6016 kfree(host_access);6017 return rc;6018}6019/*6020 * return number of grouped devices6021 */6022static int dasd_eckd_host_access_count(struct dasd_device *device)6023{6024 struct dasd_psf_query_host_access *access;6025 struct dasd_ckd_path_group_entry *entry;6026 struct dasd_ckd_host_information *info;6027 int count = 0;6028 int rc, i;6029 6030 access = kzalloc(sizeof(*access), GFP_NOIO);6031 if (!access) {6032 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",6033 "Could not allocate access buffer");6034 return -ENOMEM;6035 }6036 rc = dasd_eckd_query_host_access(device, access);6037 if (rc) {6038 kfree(access);6039 return rc;6040 }6041 6042 info = (struct dasd_ckd_host_information *)6043 access->host_access_information;6044 for (i = 0; i < info->entry_count; i++) {6045 entry = (struct dasd_ckd_path_group_entry *)6046 (info->entry + i * info->entry_size);6047 if (entry->status_flags & DASD_ECKD_PG_GROUPED)6048 count++;6049 }6050 6051 kfree(access);6052 return count;6053}6054 6055/*6056 * write host access information to a sequential file6057 */6058static int dasd_hosts_print(struct dasd_device *device, struct seq_file *m)6059{6060 struct dasd_psf_query_host_access *access;6061 struct dasd_ckd_path_group_entry *entry;6062 struct dasd_ckd_host_information *info;6063 char sysplex[9] = "";6064 int rc, i;6065 6066 access = kzalloc(sizeof(*access), GFP_NOIO);6067 if (!access) {6068 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",6069 "Could not allocate access buffer");6070 return -ENOMEM;6071 }6072 rc = dasd_eckd_query_host_access(device, access);6073 if (rc) {6074 kfree(access);6075 return rc;6076 }6077 6078 info = (struct dasd_ckd_host_information *)6079 access->host_access_information;6080 for (i = 0; i < info->entry_count; i++) {6081 entry = (struct dasd_ckd_path_group_entry *)6082 (info->entry + i * info->entry_size);6083 /* PGID */6084 seq_printf(m, "pgid %*phN\n", 11, entry->pgid);6085 /* FLAGS */6086 seq_printf(m, "status_flags %02x\n", entry->status_flags);6087 /* SYSPLEX NAME */6088 memcpy(&sysplex, &entry->sysplex_name, sizeof(sysplex) - 1);6089 EBCASC(sysplex, sizeof(sysplex));6090 seq_printf(m, "sysplex_name %8s\n", sysplex);6091 /* SUPPORTED CYLINDER */6092 seq_printf(m, "supported_cylinder %d\n", entry->cylinder);6093 /* TIMESTAMP */6094 seq_printf(m, "timestamp %lu\n", (unsigned long)6095 entry->timestamp);6096 }6097 kfree(access);6098 6099 return 0;6100}6101 6102static struct dasd_device6103*copy_relation_find_device(struct dasd_copy_relation *copy,6104 char *busid)6105{6106 int i;6107 6108 for (i = 0; i < DASD_CP_ENTRIES; i++) {6109 if (copy->entry[i].configured &&6110 strncmp(copy->entry[i].busid, busid, DASD_BUS_ID_SIZE) == 0)6111 return copy->entry[i].device;6112 }6113 return NULL;6114}6115 6116/*6117 * set the new active/primary device6118 */6119static void copy_pair_set_active(struct dasd_copy_relation *copy, char *new_busid,6120 char *old_busid)6121{6122 int i;6123 6124 for (i = 0; i < DASD_CP_ENTRIES; i++) {6125 if (copy->entry[i].configured &&6126 strncmp(copy->entry[i].busid, new_busid,6127 DASD_BUS_ID_SIZE) == 0) {6128 copy->active = ©->entry[i];6129 copy->entry[i].primary = true;6130 } else if (copy->entry[i].configured &&6131 strncmp(copy->entry[i].busid, old_busid,6132 DASD_BUS_ID_SIZE) == 0) {6133 copy->entry[i].primary = false;6134 }6135 }6136}6137 6138/*6139 * The function will swap the role of a given copy pair.6140 * During the swap operation the relation of the blockdevice is disconnected6141 * from the old primary and connected to the new.6142 *6143 * IO is paused on the block queue before swap and may be resumed afterwards.6144 */6145static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid,6146 char *sec_busid)6147{6148 struct dasd_device *primary, *secondary;6149 struct dasd_copy_relation *copy;6150 struct dasd_block *block;6151 struct gendisk *gdp;6152 6153 copy = device->copy;6154 if (!copy)6155 return DASD_COPYPAIRSWAP_INVALID;6156 primary = copy->active->device;6157 if (!primary)6158 return DASD_COPYPAIRSWAP_INVALID;6159 /* double check if swap has correct primary */6160 if (strncmp(dev_name(&primary->cdev->dev), prim_busid, DASD_BUS_ID_SIZE) != 0)6161 return DASD_COPYPAIRSWAP_PRIMARY;6162 6163 secondary = copy_relation_find_device(copy, sec_busid);6164 if (!secondary)6165 return DASD_COPYPAIRSWAP_SECONDARY;6166 6167 /*6168 * usually the device should be quiesced for swap6169 * for paranoia stop device and requeue requests again6170 */6171 dasd_device_set_stop_bits(primary, DASD_STOPPED_PPRC);6172 dasd_device_set_stop_bits(secondary, DASD_STOPPED_PPRC);6173 dasd_generic_requeue_all_requests(primary);6174 6175 /* swap DASD internal device <> block assignment */6176 block = primary->block;6177 primary->block = NULL;6178 secondary->block = block;6179 block->base = secondary;6180 /* set new primary device in COPY relation */6181 copy_pair_set_active(copy, sec_busid, prim_busid);6182 6183 /* swap blocklayer device link */6184 gdp = block->gdp;6185 dasd_add_link_to_gendisk(gdp, secondary);6186 6187 /* re-enable device */6188 dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC);6189 dasd_device_remove_stop_bits(secondary, DASD_STOPPED_PPRC);6190 dasd_schedule_device_bh(secondary);6191 6192 return DASD_COPYPAIRSWAP_SUCCESS;6193}6194 6195/*6196 * Perform Subsystem Function - Peer-to-Peer Remote Copy Extended Query6197 */6198static int dasd_eckd_query_pprc_status(struct dasd_device *device,6199 struct dasd_pprc_data_sc4 *data)6200{6201 struct dasd_pprc_data_sc4 *pprc_data;6202 struct dasd_psf_prssd_data *prssdp;6203 struct dasd_ccw_req *cqr;6204 struct ccw1 *ccw;6205 int rc;6206 6207 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,6208 sizeof(*prssdp) + sizeof(*pprc_data) + 1,6209 device, NULL);6210 if (IS_ERR(cqr)) {6211 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",6212 "Could not allocate query PPRC status request");6213 return PTR_ERR(cqr);6214 }6215 cqr->startdev = device;6216 cqr->memdev = device;6217 cqr->block = NULL;6218 cqr->retries = 256;6219 cqr->expires = 10 * HZ;6220 6221 /* Prepare for Read Subsystem Data */6222 prssdp = (struct dasd_psf_prssd_data *)cqr->data;6223 memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));6224 prssdp->order = PSF_ORDER_PRSSD;6225 prssdp->suborder = PSF_SUBORDER_PPRCEQ;6226 prssdp->varies[0] = PPRCEQ_SCOPE_4;6227 pprc_data = (struct dasd_pprc_data_sc4 *)(prssdp + 1);6228 6229 ccw = cqr->cpaddr;6230 ccw->cmd_code = DASD_ECKD_CCW_PSF;6231 ccw->count = sizeof(struct dasd_psf_prssd_data);6232 ccw->flags |= CCW_FLAG_CC;6233 ccw->flags |= CCW_FLAG_SLI;6234 ccw->cda = virt_to_dma32(prssdp);6235 6236 /* Read Subsystem Data - query host access */6237 ccw++;6238 ccw->cmd_code = DASD_ECKD_CCW_RSSD;6239 ccw->count = sizeof(*pprc_data);6240 ccw->flags |= CCW_FLAG_SLI;6241 ccw->cda = virt_to_dma32(pprc_data);6242 6243 cqr->buildclk = get_tod_clock();6244 cqr->status = DASD_CQR_FILLED;6245 6246 rc = dasd_sleep_on_interruptible(cqr);6247 if (rc == 0) {6248 *data = *pprc_data;6249 } else {6250 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,6251 "PPRC Extended Query failed with rc=%d\n",6252 rc);6253 rc = -EOPNOTSUPP;6254 }6255 6256 dasd_sfree_request(cqr, cqr->memdev);6257 return rc;6258}6259 6260/*6261 * ECKD NOP - no operation6262 */6263static int dasd_eckd_nop(struct dasd_device *device)6264{6265 struct dasd_ccw_req *cqr;6266 struct ccw1 *ccw;6267 int rc;6268 6269 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1, 1, device, NULL);6270 if (IS_ERR(cqr)) {6271 DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s",6272 "Could not allocate NOP request");6273 return PTR_ERR(cqr);6274 }6275 cqr->startdev = device;6276 cqr->memdev = device;6277 cqr->block = NULL;6278 cqr->retries = 1;6279 cqr->expires = 10 * HZ;6280 6281 ccw = cqr->cpaddr;6282 ccw->cmd_code = DASD_ECKD_CCW_NOP;6283 ccw->flags |= CCW_FLAG_SLI;6284 6285 cqr->buildclk = get_tod_clock();6286 cqr->status = DASD_CQR_FILLED;6287 6288 rc = dasd_sleep_on_interruptible(cqr);6289 if (rc != 0) {6290 DBF_EVENT_DEVID(DBF_WARNING, device->cdev,6291 "NOP failed with rc=%d\n", rc);6292 rc = -EOPNOTSUPP;6293 }6294 dasd_sfree_request(cqr, cqr->memdev);6295 return rc;6296}6297 6298static int dasd_eckd_device_ping(struct dasd_device *device)6299{6300 return dasd_eckd_nop(device);6301}6302 6303/*6304 * Perform Subsystem Function - CUIR response6305 */6306static int6307dasd_eckd_psf_cuir_response(struct dasd_device *device, int response,6308 __u32 message_id, __u8 lpum)6309{6310 struct dasd_psf_cuir_response *psf_cuir;6311 int pos = pathmask_to_pos(lpum);6312 struct dasd_ccw_req *cqr;6313 struct ccw1 *ccw;6314 int rc;6315 6316 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ ,6317 sizeof(struct dasd_psf_cuir_response),6318 device, NULL);6319 6320 if (IS_ERR(cqr)) {6321 DBF_DEV_EVENT(DBF_WARNING, device, "%s",6322 "Could not allocate PSF-CUIR request");6323 return PTR_ERR(cqr);6324 }6325 6326 psf_cuir = (struct dasd_psf_cuir_response *)cqr->data;6327 psf_cuir->order = PSF_ORDER_CUIR_RESPONSE;6328 psf_cuir->cc = response;6329 psf_cuir->chpid = device->path[pos].chpid;6330 psf_cuir->message_id = message_id;6331 psf_cuir->cssid = device->path[pos].cssid;6332 psf_cuir->ssid = device->path[pos].ssid;6333 ccw = cqr->cpaddr;6334 ccw->cmd_code = DASD_ECKD_CCW_PSF;6335 ccw->cda = virt_to_dma32(psf_cuir);6336 ccw->flags = CCW_FLAG_SLI;6337 ccw->count = sizeof(struct dasd_psf_cuir_response);6338 6339 cqr->startdev = device;6340 cqr->memdev = device;6341 cqr->block = NULL;6342 cqr->retries = 256;6343 cqr->expires = 10*HZ;6344 cqr->buildclk = get_tod_clock();6345 cqr->status = DASD_CQR_FILLED;6346 set_bit(DASD_CQR_VERIFY_PATH, &cqr->flags);6347 6348 rc = dasd_sleep_on(cqr);6349 6350 dasd_sfree_request(cqr, cqr->memdev);6351 return rc;6352}6353 6354/*6355 * return configuration data that is referenced by record selector6356 * if a record selector is specified or per default return the6357 * conf_data pointer for the path specified by lpum6358 */6359static struct dasd_conf_data *dasd_eckd_get_ref_conf(struct dasd_device *device,6360 __u8 lpum,6361 struct dasd_cuir_message *cuir)6362{6363 struct dasd_conf_data *conf_data;6364 int path, pos;6365 6366 if (cuir->record_selector == 0)6367 goto out;6368 for (path = 0x80, pos = 0; path; path >>= 1, pos++) {6369 conf_data = device->path[pos].conf_data;6370 if (conf_data->gneq.record_selector ==6371 cuir->record_selector)6372 return conf_data;6373 }6374out:6375 return device->path[pathmask_to_pos(lpum)].conf_data;6376}6377 6378/*6379 * This function determines the scope of a reconfiguration request by6380 * analysing the path and device selection data provided in the CUIR request.6381 * Returns a path mask containing CUIR affected paths for the give device.6382 *6383 * If the CUIR request does not contain the required information return the6384 * path mask of the path the attention message for the CUIR request was reveived6385 * on.6386 */6387static int dasd_eckd_cuir_scope(struct dasd_device *device, __u8 lpum,6388 struct dasd_cuir_message *cuir)6389{6390 struct dasd_conf_data *ref_conf_data;6391 unsigned long bitmask = 0, mask = 0;6392 struct dasd_conf_data *conf_data;6393 unsigned int pos, path;6394 char *ref_gneq, *gneq;6395 char *ref_ned, *ned;6396 int tbcpm = 0;6397 6398 /* if CUIR request does not specify the scope use the path6399 the attention message was presented on */6400 if (!cuir->ned_map ||6401 !(cuir->neq_map[0] | cuir->neq_map[1] | cuir->neq_map[2]))6402 return lpum;6403 6404 /* get reference conf data */6405 ref_conf_data = dasd_eckd_get_ref_conf(device, lpum, cuir);6406 /* reference ned is determined by ned_map field */6407 pos = 8 - ffs(cuir->ned_map);6408 ref_ned = (char *)&ref_conf_data->neds[pos];6409 ref_gneq = (char *)&ref_conf_data->gneq;6410 /* transfer 24 bit neq_map to mask */6411 mask = cuir->neq_map[2];6412 mask |= cuir->neq_map[1] << 8;6413 mask |= cuir->neq_map[0] << 16;6414 6415 for (path = 0; path < 8; path++) {6416 /* initialise data per path */6417 bitmask = mask;6418 conf_data = device->path[path].conf_data;6419 pos = 8 - ffs(cuir->ned_map);6420 ned = (char *) &conf_data->neds[pos];6421 /* compare reference ned and per path ned */6422 if (memcmp(ref_ned, ned, sizeof(*ned)) != 0)6423 continue;6424 gneq = (char *)&conf_data->gneq;6425 /* compare reference gneq and per_path gneq under6426 24 bit mask where mask bit 0 equals byte 7 of6427 the gneq and mask bit 24 equals byte 31 */6428 while (bitmask) {6429 pos = ffs(bitmask) - 1;6430 if (memcmp(&ref_gneq[31 - pos], &gneq[31 - pos], 1)6431 != 0)6432 break;6433 clear_bit(pos, &bitmask);6434 }6435 if (bitmask)6436 continue;6437 /* device and path match the reference values6438 add path to CUIR scope */6439 tbcpm |= 0x80 >> path;6440 }6441 return tbcpm;6442}6443 6444static void dasd_eckd_cuir_notify_user(struct dasd_device *device,6445 unsigned long paths, int action)6446{6447 int pos;6448 6449 while (paths) {6450 /* get position of bit in mask */6451 pos = 8 - ffs(paths);6452 /* get channel path descriptor from this position */6453 if (action == CUIR_QUIESCE)6454 pr_warn("Service on the storage server caused path %x.%02x to go offline",6455 device->path[pos].cssid,6456 device->path[pos].chpid);6457 else if (action == CUIR_RESUME)6458 pr_info("Path %x.%02x is back online after service on the storage server",6459 device->path[pos].cssid,6460 device->path[pos].chpid);6461 clear_bit(7 - pos, &paths);6462 }6463}6464 6465static int dasd_eckd_cuir_remove_path(struct dasd_device *device, __u8 lpum,6466 struct dasd_cuir_message *cuir)6467{6468 unsigned long tbcpm;6469 6470 tbcpm = dasd_eckd_cuir_scope(device, lpum, cuir);6471 /* nothing to do if path is not in use */6472 if (!(dasd_path_get_opm(device) & tbcpm))6473 return 0;6474 if (!(dasd_path_get_opm(device) & ~tbcpm)) {6475 /* no path would be left if the CUIR action is taken6476 return error */6477 return -EINVAL;6478 }6479 /* remove device from operational path mask */6480 dasd_path_remove_opm(device, tbcpm);6481 dasd_path_add_cuirpm(device, tbcpm);6482 return tbcpm;6483}6484 6485/*6486 * walk through all devices and build a path mask to quiesce them6487 * return an error if the last path to a device would be removed6488 *6489 * if only part of the devices are quiesced and an error6490 * occurs no onlining necessary, the storage server will6491 * notify the already set offline devices again6492 */6493static int dasd_eckd_cuir_quiesce(struct dasd_device *device, __u8 lpum,6494 struct dasd_cuir_message *cuir)6495{6496 struct dasd_eckd_private *private = device->private;6497 struct alias_pav_group *pavgroup, *tempgroup;6498 struct dasd_device *dev, *n;6499 unsigned long paths = 0;6500 unsigned long flags;6501 int tbcpm;6502 6503 /* active devices */6504 list_for_each_entry_safe(dev, n, &private->lcu->active_devices,6505 alias_list) {6506 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);6507 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);6508 spin_unlock_irqrestore(get_ccwdev_lock(dev->cdev), flags);6509 if (tbcpm < 0)6510 goto out_err;6511 paths |= tbcpm;6512 }6513 /* inactive devices */6514 list_for_each_entry_safe(dev, n, &private->lcu->inactive_devices,6515 alias_list) {6516 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);6517 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);6518 spin_unlock_irqrestore(get_ccwdev_lock(dev->cdev), flags);6519 if (tbcpm < 0)6520 goto out_err;6521 paths |= tbcpm;6522 }6523 /* devices in PAV groups */6524 list_for_each_entry_safe(pavgroup, tempgroup,6525 &private->lcu->grouplist, group) {6526 list_for_each_entry_safe(dev, n, &pavgroup->baselist,6527 alias_list) {6528 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);6529 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);6530 spin_unlock_irqrestore(6531 get_ccwdev_lock(dev->cdev), flags);6532 if (tbcpm < 0)6533 goto out_err;6534 paths |= tbcpm;6535 }6536 list_for_each_entry_safe(dev, n, &pavgroup->aliaslist,6537 alias_list) {6538 spin_lock_irqsave(get_ccwdev_lock(dev->cdev), flags);6539 tbcpm = dasd_eckd_cuir_remove_path(dev, lpum, cuir);6540 spin_unlock_irqrestore(6541 get_ccwdev_lock(dev->cdev), flags);6542 if (tbcpm < 0)6543 goto out_err;6544 paths |= tbcpm;6545 }6546 }6547 /* notify user about all paths affected by CUIR action */6548 dasd_eckd_cuir_notify_user(device, paths, CUIR_QUIESCE);6549 return 0;6550out_err:6551 return tbcpm;6552}6553 6554static int dasd_eckd_cuir_resume(struct dasd_device *device, __u8 lpum,6555 struct dasd_cuir_message *cuir)6556{6557 struct dasd_eckd_private *private = device->private;6558 struct alias_pav_group *pavgroup, *tempgroup;6559 struct dasd_device *dev, *n;6560 unsigned long paths = 0;6561 int tbcpm;6562 6563 /*6564 * the path may have been added through a generic path event before6565 * only trigger path verification if the path is not already in use6566 */6567 list_for_each_entry_safe(dev, n,6568 &private->lcu->active_devices,6569 alias_list) {6570 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);6571 paths |= tbcpm;6572 if (!(dasd_path_get_opm(dev) & tbcpm)) {6573 dasd_path_add_tbvpm(dev, tbcpm);6574 dasd_schedule_device_bh(dev);6575 }6576 }6577 list_for_each_entry_safe(dev, n,6578 &private->lcu->inactive_devices,6579 alias_list) {6580 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);6581 paths |= tbcpm;6582 if (!(dasd_path_get_opm(dev) & tbcpm)) {6583 dasd_path_add_tbvpm(dev, tbcpm);6584 dasd_schedule_device_bh(dev);6585 }6586 }6587 /* devices in PAV groups */6588 list_for_each_entry_safe(pavgroup, tempgroup,6589 &private->lcu->grouplist,6590 group) {6591 list_for_each_entry_safe(dev, n,6592 &pavgroup->baselist,6593 alias_list) {6594 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);6595 paths |= tbcpm;6596 if (!(dasd_path_get_opm(dev) & tbcpm)) {6597 dasd_path_add_tbvpm(dev, tbcpm);6598 dasd_schedule_device_bh(dev);6599 }6600 }6601 list_for_each_entry_safe(dev, n,6602 &pavgroup->aliaslist,6603 alias_list) {6604 tbcpm = dasd_eckd_cuir_scope(dev, lpum, cuir);6605 paths |= tbcpm;6606 if (!(dasd_path_get_opm(dev) & tbcpm)) {6607 dasd_path_add_tbvpm(dev, tbcpm);6608 dasd_schedule_device_bh(dev);6609 }6610 }6611 }6612 /* notify user about all paths affected by CUIR action */6613 dasd_eckd_cuir_notify_user(device, paths, CUIR_RESUME);6614 return 0;6615}6616 6617static void dasd_eckd_handle_cuir(struct dasd_device *device, void *messages,6618 __u8 lpum)6619{6620 struct dasd_cuir_message *cuir = messages;6621 int response;6622 6623 DBF_DEV_EVENT(DBF_WARNING, device,6624 "CUIR request: %016llx %016llx %016llx %08x",6625 ((u64 *)cuir)[0], ((u64 *)cuir)[1], ((u64 *)cuir)[2],6626 ((u32 *)cuir)[3]);6627 6628 if (cuir->code == CUIR_QUIESCE) {6629 /* quiesce */6630 if (dasd_eckd_cuir_quiesce(device, lpum, cuir))6631 response = PSF_CUIR_LAST_PATH;6632 else6633 response = PSF_CUIR_COMPLETED;6634 } else if (cuir->code == CUIR_RESUME) {6635 /* resume */6636 dasd_eckd_cuir_resume(device, lpum, cuir);6637 response = PSF_CUIR_COMPLETED;6638 } else6639 response = PSF_CUIR_NOT_SUPPORTED;6640 6641 dasd_eckd_psf_cuir_response(device, response,6642 cuir->message_id, lpum);6643 DBF_DEV_EVENT(DBF_WARNING, device,6644 "CUIR response: %d on message ID %08x", response,6645 cuir->message_id);6646 /* to make sure there is no attention left schedule work again */6647 device->discipline->check_attention(device, lpum);6648}6649 6650static void dasd_eckd_oos_resume(struct dasd_device *device)6651{6652 struct dasd_eckd_private *private = device->private;6653 struct alias_pav_group *pavgroup, *tempgroup;6654 struct dasd_device *dev, *n;6655 unsigned long flags;6656 6657 spin_lock_irqsave(&private->lcu->lock, flags);6658 list_for_each_entry_safe(dev, n, &private->lcu->active_devices,6659 alias_list) {6660 if (dev->stopped & DASD_STOPPED_NOSPC)6661 dasd_generic_space_avail(dev);6662 }6663 list_for_each_entry_safe(dev, n, &private->lcu->inactive_devices,6664 alias_list) {6665 if (dev->stopped & DASD_STOPPED_NOSPC)6666 dasd_generic_space_avail(dev);6667 }6668 /* devices in PAV groups */6669 list_for_each_entry_safe(pavgroup, tempgroup,6670 &private->lcu->grouplist,6671 group) {6672 list_for_each_entry_safe(dev, n, &pavgroup->baselist,6673 alias_list) {6674 if (dev->stopped & DASD_STOPPED_NOSPC)6675 dasd_generic_space_avail(dev);6676 }6677 list_for_each_entry_safe(dev, n, &pavgroup->aliaslist,6678 alias_list) {6679 if (dev->stopped & DASD_STOPPED_NOSPC)6680 dasd_generic_space_avail(dev);6681 }6682 }6683 spin_unlock_irqrestore(&private->lcu->lock, flags);6684}6685 6686static void dasd_eckd_handle_oos(struct dasd_device *device, void *messages,6687 __u8 lpum)6688{6689 struct dasd_oos_message *oos = messages;6690 6691 switch (oos->code) {6692 case REPO_WARN:6693 case POOL_WARN:6694 dev_warn(&device->cdev->dev,6695 "Extent pool usage has reached a critical value\n");6696 dasd_eckd_oos_resume(device);6697 break;6698 case REPO_EXHAUST:6699 case POOL_EXHAUST:6700 dev_warn(&device->cdev->dev,6701 "Extent pool is exhausted\n");6702 break;6703 case REPO_RELIEVE:6704 case POOL_RELIEVE:6705 dev_info(&device->cdev->dev,6706 "Extent pool physical space constraint has been relieved\n");6707 break;6708 }6709 6710 /* In any case, update related data */6711 dasd_eckd_read_ext_pool_info(device);6712 6713 /* to make sure there is no attention left schedule work again */6714 device->discipline->check_attention(device, lpum);6715}6716 6717static void dasd_eckd_check_attention_work(struct work_struct *work)6718{6719 struct check_attention_work_data *data;6720 struct dasd_rssd_messages *messages;6721 struct dasd_device *device;6722 int rc;6723 6724 data = container_of(work, struct check_attention_work_data, worker);6725 device = data->device;6726 messages = kzalloc(sizeof(*messages), GFP_KERNEL);6727 if (!messages) {6728 DBF_DEV_EVENT(DBF_WARNING, device, "%s",6729 "Could not allocate attention message buffer");6730 goto out;6731 }6732 rc = dasd_eckd_read_message_buffer(device, messages, data->lpum);6733 if (rc)6734 goto out;6735 6736 if (messages->length == ATTENTION_LENGTH_CUIR &&6737 messages->format == ATTENTION_FORMAT_CUIR)6738 dasd_eckd_handle_cuir(device, messages, data->lpum);6739 if (messages->length == ATTENTION_LENGTH_OOS &&6740 messages->format == ATTENTION_FORMAT_OOS)6741 dasd_eckd_handle_oos(device, messages, data->lpum);6742 6743out:6744 dasd_put_device(device);6745 kfree(messages);6746 kfree(data);6747}6748 6749static int dasd_eckd_check_attention(struct dasd_device *device, __u8 lpum)6750{6751 struct check_attention_work_data *data;6752 6753 data = kzalloc(sizeof(*data), GFP_ATOMIC);6754 if (!data)6755 return -ENOMEM;6756 INIT_WORK(&data->worker, dasd_eckd_check_attention_work);6757 dasd_get_device(device);6758 data->device = device;6759 data->lpum = lpum;6760 schedule_work(&data->worker);6761 return 0;6762}6763 6764static int dasd_eckd_disable_hpf_path(struct dasd_device *device, __u8 lpum)6765{6766 if (~lpum & dasd_path_get_opm(device)) {6767 dasd_path_add_nohpfpm(device, lpum);6768 dasd_path_remove_opm(device, lpum);6769 dev_err(&device->cdev->dev,6770 "Channel path %02X lost HPF functionality and is disabled\n",6771 lpum);6772 return 1;6773 }6774 return 0;6775}6776 6777static void dasd_eckd_disable_hpf_device(struct dasd_device *device)6778{6779 struct dasd_eckd_private *private = device->private;6780 6781 dev_err(&device->cdev->dev,6782 "High Performance FICON disabled\n");6783 private->fcx_max_data = 0;6784}6785 6786static int dasd_eckd_hpf_enabled(struct dasd_device *device)6787{6788 struct dasd_eckd_private *private = device->private;6789 6790 return private->fcx_max_data ? 1 : 0;6791}6792 6793static void dasd_eckd_handle_hpf_error(struct dasd_device *device,6794 struct irb *irb)6795{6796 struct dasd_eckd_private *private = device->private;6797 6798 if (!private->fcx_max_data) {6799 /* sanity check for no HPF, the error makes no sense */6800 DBF_DEV_EVENT(DBF_WARNING, device, "%s",6801 "Trying to disable HPF for a non HPF device");6802 return;6803 }6804 if (irb->scsw.tm.sesq == SCSW_SESQ_DEV_NOFCX) {6805 dasd_eckd_disable_hpf_device(device);6806 } else if (irb->scsw.tm.sesq == SCSW_SESQ_PATH_NOFCX) {6807 if (dasd_eckd_disable_hpf_path(device, irb->esw.esw1.lpum))6808 return;6809 dasd_eckd_disable_hpf_device(device);6810 dasd_path_set_tbvpm(device,6811 dasd_path_get_hpfpm(device));6812 }6813 /*6814 * prevent that any new I/O ist started on the device and schedule a6815 * requeue of existing requests6816 */6817 dasd_device_set_stop_bits(device, DASD_STOPPED_NOT_ACC);6818 dasd_schedule_requeue(device);6819}6820 6821static unsigned int dasd_eckd_max_sectors(struct dasd_block *block)6822{6823 if (block->base->features & DASD_FEATURE_USERAW) {6824 /*6825 * the max_blocks value for raw_track access is 2566826 * it is higher than the native ECKD value because we6827 * only need one ccw per track6828 * so the max_hw_sectors are6829 * 2048 x 512B = 1024kB = 16 tracks6830 */6831 return DASD_ECKD_MAX_BLOCKS_RAW << block->s2b_shift;6832 }6833 6834 return DASD_ECKD_MAX_BLOCKS << block->s2b_shift;6835}6836 6837static struct ccw_driver dasd_eckd_driver = {6838 .driver = {6839 .name = "dasd-eckd",6840 .owner = THIS_MODULE,6841 .dev_groups = dasd_dev_groups,6842 },6843 .ids = dasd_eckd_ids,6844 .probe = dasd_eckd_probe,6845 .remove = dasd_generic_remove,6846 .set_offline = dasd_generic_set_offline,6847 .set_online = dasd_eckd_set_online,6848 .notify = dasd_generic_notify,6849 .path_event = dasd_generic_path_event,6850 .shutdown = dasd_generic_shutdown,6851 .uc_handler = dasd_generic_uc_handler,6852 .int_class = IRQIO_DAS,6853};6854 6855static struct dasd_discipline dasd_eckd_discipline = {6856 .owner = THIS_MODULE,6857 .name = "ECKD",6858 .ebcname = "ECKD",6859 .check_device = dasd_eckd_check_characteristics,6860 .uncheck_device = dasd_eckd_uncheck_device,6861 .do_analysis = dasd_eckd_do_analysis,6862 .pe_handler = dasd_eckd_pe_handler,6863 .basic_to_ready = dasd_eckd_basic_to_ready,6864 .online_to_ready = dasd_eckd_online_to_ready,6865 .basic_to_known = dasd_eckd_basic_to_known,6866 .max_sectors = dasd_eckd_max_sectors,6867 .fill_geometry = dasd_eckd_fill_geometry,6868 .start_IO = dasd_start_IO,6869 .term_IO = dasd_term_IO,6870 .handle_terminated_request = dasd_eckd_handle_terminated_request,6871 .format_device = dasd_eckd_format_device,6872 .check_device_format = dasd_eckd_check_device_format,6873 .erp_action = dasd_eckd_erp_action,6874 .erp_postaction = dasd_eckd_erp_postaction,6875 .check_for_device_change = dasd_eckd_check_for_device_change,6876 .build_cp = dasd_eckd_build_alias_cp,6877 .free_cp = dasd_eckd_free_alias_cp,6878 .dump_sense = dasd_eckd_dump_sense,6879 .dump_sense_dbf = dasd_eckd_dump_sense_dbf,6880 .fill_info = dasd_eckd_fill_info,6881 .ioctl = dasd_eckd_ioctl,6882 .reload = dasd_eckd_reload_device,6883 .get_uid = dasd_eckd_get_uid,6884 .kick_validate = dasd_eckd_kick_validate_server,6885 .check_attention = dasd_eckd_check_attention,6886 .host_access_count = dasd_eckd_host_access_count,6887 .hosts_print = dasd_hosts_print,6888 .handle_hpf_error = dasd_eckd_handle_hpf_error,6889 .disable_hpf = dasd_eckd_disable_hpf_device,6890 .hpf_enabled = dasd_eckd_hpf_enabled,6891 .reset_path = dasd_eckd_reset_path,6892 .is_ese = dasd_eckd_is_ese,6893 .space_allocated = dasd_eckd_space_allocated,6894 .space_configured = dasd_eckd_space_configured,6895 .logical_capacity = dasd_eckd_logical_capacity,6896 .release_space = dasd_eckd_release_space,6897 .ext_pool_id = dasd_eckd_ext_pool_id,6898 .ext_size = dasd_eckd_ext_size,6899 .ext_pool_cap_at_warnlevel = dasd_eckd_ext_pool_cap_at_warnlevel,6900 .ext_pool_warn_thrshld = dasd_eckd_ext_pool_warn_thrshld,6901 .ext_pool_oos = dasd_eckd_ext_pool_oos,6902 .ext_pool_exhaust = dasd_eckd_ext_pool_exhaust,6903 .ese_format = dasd_eckd_ese_format,6904 .ese_read = dasd_eckd_ese_read,6905 .pprc_status = dasd_eckd_query_pprc_status,6906 .pprc_enabled = dasd_eckd_pprc_enabled,6907 .copy_pair_swap = dasd_eckd_copy_pair_swap,6908 .device_ping = dasd_eckd_device_ping,6909};6910 6911static int __init6912dasd_eckd_init(void)6913{6914 int ret;6915 6916 ASCEBC(dasd_eckd_discipline.ebcname, 4);6917 dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req),6918 GFP_KERNEL | GFP_DMA);6919 if (!dasd_reserve_req)6920 return -ENOMEM;6921 dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req),6922 GFP_KERNEL | GFP_DMA);6923 if (!dasd_vol_info_req) {6924 kfree(dasd_reserve_req);6925 return -ENOMEM;6926 }6927 pe_handler_worker = kmalloc(sizeof(*pe_handler_worker),6928 GFP_KERNEL | GFP_DMA);6929 if (!pe_handler_worker) {6930 kfree(dasd_reserve_req);6931 kfree(dasd_vol_info_req);6932 return -ENOMEM;6933 }6934 rawpadpage = (void *)__get_free_page(GFP_KERNEL);6935 if (!rawpadpage) {6936 kfree(pe_handler_worker);6937 kfree(dasd_reserve_req);6938 kfree(dasd_vol_info_req);6939 return -ENOMEM;6940 }6941 ret = ccw_driver_register(&dasd_eckd_driver);6942 if (!ret)6943 wait_for_device_probe();6944 else {6945 kfree(pe_handler_worker);6946 kfree(dasd_reserve_req);6947 kfree(dasd_vol_info_req);6948 free_page((unsigned long)rawpadpage);6949 }6950 return ret;6951}6952 6953static void __exit6954dasd_eckd_cleanup(void)6955{6956 ccw_driver_unregister(&dasd_eckd_driver);6957 kfree(pe_handler_worker);6958 kfree(dasd_reserve_req);6959 free_page((unsigned long)rawpadpage);6960}6961 6962module_init(dasd_eckd_init);6963module_exit(dasd_eckd_cleanup);6964