dasd_fba.c (23720B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com> 5 * Copyright IBM Corp. 1999, 2009 6 */ 7 8#define KMSG_COMPONENT "dasd-fba" 9 10#include <linux/stddef.h> 11#include <linux/kernel.h> 12#include <asm/debug.h> 13 14#include <linux/slab.h> 15#include <linux/hdreg.h> /* HDIO_GETGEO */ 16#include <linux/bio.h> 17#include <linux/module.h> 18#include <linux/init.h> 19 20#include <asm/idals.h> 21#include <asm/ebcdic.h> 22#include <asm/io.h> 23#include <asm/ccwdev.h> 24 25#include "dasd_int.h" 26#include "dasd_fba.h" 27 28#ifdef PRINTK_HEADER 29#undef PRINTK_HEADER 30#endif /* PRINTK_HEADER */ 31#define PRINTK_HEADER "dasd(fba):" 32 33#define FBA_DEFAULT_RETRIES 32 34 35#define DASD_FBA_CCW_WRITE 0x41 36#define DASD_FBA_CCW_READ 0x42 37#define DASD_FBA_CCW_LOCATE 0x43 38#define DASD_FBA_CCW_DEFINE_EXTENT 0x63 39 40MODULE_LICENSE("GPL"); 41 42static struct dasd_discipline dasd_fba_discipline; 43static void *dasd_fba_zero_page; 44 45struct dasd_fba_private { 46 struct dasd_fba_characteristics rdc_data; 47}; 48 49static struct ccw_device_id dasd_fba_ids[] = { 50 { CCW_DEVICE_DEVTYPE (0x6310, 0, 0x9336, 0), .driver_info = 0x1}, 51 { CCW_DEVICE_DEVTYPE (0x3880, 0, 0x3370, 0), .driver_info = 0x2}, 52 { /* end of list */ }, 53}; 54 55MODULE_DEVICE_TABLE(ccw, dasd_fba_ids); 56 57static int 58dasd_fba_set_online(struct ccw_device *cdev) 59{ 60 return dasd_generic_set_online(cdev, &dasd_fba_discipline); 61} 62 63static struct ccw_driver dasd_fba_driver = { 64 .driver = { 65 .name = "dasd-fba", 66 .owner = THIS_MODULE, 67 .dev_groups = dasd_dev_groups, 68 }, 69 .ids = dasd_fba_ids, 70 .probe = dasd_generic_probe, 71 .remove = dasd_generic_remove, 72 .set_offline = dasd_generic_set_offline, 73 .set_online = dasd_fba_set_online, 74 .notify = dasd_generic_notify, 75 .path_event = dasd_generic_path_event, 76 .int_class = IRQIO_DAS, 77}; 78 79static void 80define_extent(struct ccw1 * ccw, struct DE_fba_data *data, int rw, 81 int blksize, int beg, int nr) 82{ 83 ccw->cmd_code = DASD_FBA_CCW_DEFINE_EXTENT; 84 ccw->flags = 0; 85 ccw->count = 16; 86 ccw->cda = (__u32) __pa(data); 87 memset(data, 0, sizeof (struct DE_fba_data)); 88 if (rw == WRITE) 89 (data->mask).perm = 0x0; 90 else if (rw == READ) 91 (data->mask).perm = 0x1; 92 else 93 data->mask.perm = 0x2; 94 data->blk_size = blksize; 95 data->ext_loc = beg; 96 data->ext_end = nr - 1; 97} 98 99static void 100locate_record(struct ccw1 * ccw, struct LO_fba_data *data, int rw, 101 int block_nr, int block_ct) 102{ 103 ccw->cmd_code = DASD_FBA_CCW_LOCATE; 104 ccw->flags = 0; 105 ccw->count = 8; 106 ccw->cda = (__u32) __pa(data); 107 memset(data, 0, sizeof (struct LO_fba_data)); 108 if (rw == WRITE) 109 data->operation.cmd = 0x5; 110 else if (rw == READ) 111 data->operation.cmd = 0x6; 112 else 113 data->operation.cmd = 0x8; 114 data->blk_nr = block_nr; 115 data->blk_ct = block_ct; 116} 117 118static int 119dasd_fba_check_characteristics(struct dasd_device *device) 120{ 121 struct dasd_fba_private *private = device->private; 122 struct ccw_device *cdev = device->cdev; 123 struct dasd_block *block; 124 int readonly, rc; 125 126 if (!private) { 127 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); 128 if (!private) { 129 dev_warn(&device->cdev->dev, 130 "Allocating memory for private DASD " 131 "data failed\n"); 132 return -ENOMEM; 133 } 134 device->private = private; 135 } else { 136 memset(private, 0, sizeof(*private)); 137 } 138 block = dasd_alloc_block(); 139 if (IS_ERR(block)) { 140 DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", "could not allocate " 141 "dasd block structure"); 142 device->private = NULL; 143 kfree(private); 144 return PTR_ERR(block); 145 } 146 device->block = block; 147 block->base = device; 148 149 /* Read Device Characteristics */ 150 rc = dasd_generic_read_dev_chars(device, DASD_FBA_MAGIC, 151 &private->rdc_data, 32); 152 if (rc) { 153 DBF_EVENT_DEVID(DBF_WARNING, cdev, "Read device " 154 "characteristics returned error %d", rc); 155 device->block = NULL; 156 dasd_free_block(block); 157 device->private = NULL; 158 kfree(private); 159 return rc; 160 } 161 162 device->default_expires = DASD_EXPIRES; 163 device->default_retries = FBA_DEFAULT_RETRIES; 164 dasd_path_set_opm(device, LPM_ANYPATH); 165 166 readonly = dasd_device_is_ro(device); 167 if (readonly) 168 set_bit(DASD_FLAG_DEVICE_RO, &device->flags); 169 170 /* FBA supports discard, set the according feature bit */ 171 dasd_set_feature(cdev, DASD_FEATURE_DISCARD, 1); 172 173 dev_info(&device->cdev->dev, 174 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB " 175 "and %d B/blk%s\n", 176 cdev->id.dev_type, 177 cdev->id.dev_model, 178 cdev->id.cu_type, 179 cdev->id.cu_model, 180 ((private->rdc_data.blk_bdsa * 181 (private->rdc_data.blk_size >> 9)) >> 11), 182 private->rdc_data.blk_size, 183 readonly ? ", read-only device" : ""); 184 return 0; 185} 186 187static int dasd_fba_do_analysis(struct dasd_block *block) 188{ 189 struct dasd_fba_private *private = block->base->private; 190 int sb, rc; 191 192 rc = dasd_check_blocksize(private->rdc_data.blk_size); 193 if (rc) { 194 DBF_DEV_EVENT(DBF_WARNING, block->base, "unknown blocksize %d", 195 private->rdc_data.blk_size); 196 return rc; 197 } 198 block->blocks = private->rdc_data.blk_bdsa; 199 block->bp_block = private->rdc_data.blk_size; 200 block->s2b_shift = 0; /* bits to shift 512 to get a block */ 201 for (sb = 512; sb < private->rdc_data.blk_size; sb = sb << 1) 202 block->s2b_shift++; 203 return 0; 204} 205 206static int dasd_fba_fill_geometry(struct dasd_block *block, 207 struct hd_geometry *geo) 208{ 209 if (dasd_check_blocksize(block->bp_block) != 0) 210 return -EINVAL; 211 geo->cylinders = (block->blocks << block->s2b_shift) >> 10; 212 geo->heads = 16; 213 geo->sectors = 128 >> block->s2b_shift; 214 return 0; 215} 216 217static dasd_erp_fn_t 218dasd_fba_erp_action(struct dasd_ccw_req * cqr) 219{ 220 return dasd_default_erp_action; 221} 222 223static dasd_erp_fn_t 224dasd_fba_erp_postaction(struct dasd_ccw_req * cqr) 225{ 226 if (cqr->function == dasd_default_erp_action) 227 return dasd_default_erp_postaction; 228 229 DBF_DEV_EVENT(DBF_WARNING, cqr->startdev, "unknown ERP action %p", 230 cqr->function); 231 return NULL; 232} 233 234static void dasd_fba_check_for_device_change(struct dasd_device *device, 235 struct dasd_ccw_req *cqr, 236 struct irb *irb) 237{ 238 char mask; 239 240 /* first of all check for state change pending interrupt */ 241 mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; 242 if ((irb->scsw.cmd.dstat & mask) == mask) 243 dasd_generic_handle_state_change(device); 244}; 245 246 247/* 248 * Builds a CCW with no data payload 249 */ 250static void ccw_write_no_data(struct ccw1 *ccw) 251{ 252 ccw->cmd_code = DASD_FBA_CCW_WRITE; 253 ccw->flags |= CCW_FLAG_SLI; 254 ccw->count = 0; 255} 256 257/* 258 * Builds a CCW that writes only zeroes. 259 */ 260static void ccw_write_zero(struct ccw1 *ccw, int count) 261{ 262 ccw->cmd_code = DASD_FBA_CCW_WRITE; 263 ccw->flags |= CCW_FLAG_SLI; 264 ccw->count = count; 265 ccw->cda = (__u32) (addr_t) dasd_fba_zero_page; 266} 267 268/* 269 * Helper function to count the amount of necessary CCWs within a given range 270 * with 4k alignment and command chaining in mind. 271 */ 272static int count_ccws(sector_t first_rec, sector_t last_rec, 273 unsigned int blocks_per_page) 274{ 275 sector_t wz_stop = 0, d_stop = 0; 276 int cur_pos = 0; 277 int count = 0; 278 279 if (first_rec % blocks_per_page != 0) { 280 wz_stop = first_rec + blocks_per_page - 281 (first_rec % blocks_per_page) - 1; 282 if (wz_stop > last_rec) 283 wz_stop = last_rec; 284 cur_pos = wz_stop - first_rec + 1; 285 count++; 286 } 287 288 if (last_rec - (first_rec + cur_pos) + 1 >= blocks_per_page) { 289 if ((last_rec - blocks_per_page + 1) % blocks_per_page != 0) 290 d_stop = last_rec - ((last_rec - blocks_per_page + 1) % 291 blocks_per_page); 292 else 293 d_stop = last_rec; 294 295 cur_pos += d_stop - (first_rec + cur_pos) + 1; 296 count++; 297 } 298 299 if (cur_pos == 0 || first_rec + cur_pos - 1 < last_rec) 300 count++; 301 302 return count; 303} 304 305/* 306 * This function builds a CCW request for block layer discard requests. 307 * Each page in the z/VM hypervisor that represents certain records of an FBA 308 * device will be padded with zeros. This is a special behaviour of the WRITE 309 * command which is triggered when no data payload is added to the CCW. 310 * 311 * Note: Due to issues in some z/VM versions, we can't fully utilise this 312 * special behaviour. We have to keep a 4k (or 8 block) alignment in mind to 313 * work around those issues and write actual zeroes to the unaligned parts in 314 * the request. This workaround might be removed in the future. 315 */ 316static struct dasd_ccw_req *dasd_fba_build_cp_discard( 317 struct dasd_device *memdev, 318 struct dasd_block *block, 319 struct request *req) 320{ 321 struct LO_fba_data *LO_data; 322 struct dasd_ccw_req *cqr; 323 struct ccw1 *ccw; 324 325 sector_t wz_stop = 0, d_stop = 0; 326 sector_t first_rec, last_rec; 327 328 unsigned int blksize = block->bp_block; 329 unsigned int blocks_per_page; 330 int wz_count = 0; 331 int d_count = 0; 332 int cur_pos = 0; /* Current position within the extent */ 333 int count = 0; 334 int cplength; 335 int datasize; 336 int nr_ccws; 337 338 first_rec = blk_rq_pos(req) >> block->s2b_shift; 339 last_rec = 340 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; 341 count = last_rec - first_rec + 1; 342 343 blocks_per_page = BLOCKS_PER_PAGE(blksize); 344 nr_ccws = count_ccws(first_rec, last_rec, blocks_per_page); 345 346 /* define extent + nr_ccws * locate record + nr_ccws * single CCW */ 347 cplength = 1 + 2 * nr_ccws; 348 datasize = sizeof(struct DE_fba_data) + 349 nr_ccws * (sizeof(struct LO_fba_data) + sizeof(struct ccw1)); 350 351 cqr = dasd_smalloc_request(DASD_FBA_MAGIC, cplength, datasize, memdev, 352 blk_mq_rq_to_pdu(req)); 353 if (IS_ERR(cqr)) 354 return cqr; 355 356 ccw = cqr->cpaddr; 357 358 define_extent(ccw++, cqr->data, WRITE, blksize, first_rec, count); 359 LO_data = cqr->data + sizeof(struct DE_fba_data); 360 361 /* First part is not aligned. Calculate range to write zeroes. */ 362 if (first_rec % blocks_per_page != 0) { 363 wz_stop = first_rec + blocks_per_page - 364 (first_rec % blocks_per_page) - 1; 365 if (wz_stop > last_rec) 366 wz_stop = last_rec; 367 wz_count = wz_stop - first_rec + 1; 368 369 ccw[-1].flags |= CCW_FLAG_CC; 370 locate_record(ccw++, LO_data++, WRITE, cur_pos, wz_count); 371 372 ccw[-1].flags |= CCW_FLAG_CC; 373 ccw_write_zero(ccw++, wz_count * blksize); 374 375 cur_pos = wz_count; 376 } 377 378 /* We can do proper discard when we've got at least blocks_per_page blocks. */ 379 if (last_rec - (first_rec + cur_pos) + 1 >= blocks_per_page) { 380 /* is last record at page boundary? */ 381 if ((last_rec - blocks_per_page + 1) % blocks_per_page != 0) 382 d_stop = last_rec - ((last_rec - blocks_per_page + 1) % 383 blocks_per_page); 384 else 385 d_stop = last_rec; 386 387 d_count = d_stop - (first_rec + cur_pos) + 1; 388 389 ccw[-1].flags |= CCW_FLAG_CC; 390 locate_record(ccw++, LO_data++, WRITE, cur_pos, d_count); 391 392 ccw[-1].flags |= CCW_FLAG_CC; 393 ccw_write_no_data(ccw++); 394 395 cur_pos += d_count; 396 } 397 398 /* We might still have some bits left which need to be zeroed. */ 399 if (cur_pos == 0 || first_rec + cur_pos - 1 < last_rec) { 400 if (d_stop != 0) 401 wz_count = last_rec - d_stop; 402 else if (wz_stop != 0) 403 wz_count = last_rec - wz_stop; 404 else 405 wz_count = count; 406 407 ccw[-1].flags |= CCW_FLAG_CC; 408 locate_record(ccw++, LO_data++, WRITE, cur_pos, wz_count); 409 410 ccw[-1].flags |= CCW_FLAG_CC; 411 ccw_write_zero(ccw++, wz_count * blksize); 412 } 413 414 if (blk_noretry_request(req) || 415 block->base->features & DASD_FEATURE_FAILFAST) 416 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 417 418 cqr->startdev = memdev; 419 cqr->memdev = memdev; 420 cqr->block = block; 421 cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */ 422 cqr->retries = memdev->default_retries; 423 cqr->buildclk = get_tod_clock(); 424 cqr->status = DASD_CQR_FILLED; 425 426 return cqr; 427} 428 429static struct dasd_ccw_req *dasd_fba_build_cp_regular( 430 struct dasd_device *memdev, 431 struct dasd_block *block, 432 struct request *req) 433{ 434 struct dasd_fba_private *private = block->base->private; 435 unsigned long *idaws; 436 struct LO_fba_data *LO_data; 437 struct dasd_ccw_req *cqr; 438 struct ccw1 *ccw; 439 struct req_iterator iter; 440 struct bio_vec bv; 441 char *dst; 442 int count, cidaw, cplength, datasize; 443 sector_t recid, first_rec, last_rec; 444 unsigned int blksize, off; 445 unsigned char cmd; 446 447 if (rq_data_dir(req) == READ) { 448 cmd = DASD_FBA_CCW_READ; 449 } else if (rq_data_dir(req) == WRITE) { 450 cmd = DASD_FBA_CCW_WRITE; 451 } else 452 return ERR_PTR(-EINVAL); 453 blksize = block->bp_block; 454 /* Calculate record id of first and last block. */ 455 first_rec = blk_rq_pos(req) >> block->s2b_shift; 456 last_rec = 457 (blk_rq_pos(req) + blk_rq_sectors(req) - 1) >> block->s2b_shift; 458 /* Check struct bio and count the number of blocks for the request. */ 459 count = 0; 460 cidaw = 0; 461 rq_for_each_segment(bv, req, iter) { 462 if (bv.bv_len & (blksize - 1)) 463 /* Fba can only do full blocks. */ 464 return ERR_PTR(-EINVAL); 465 count += bv.bv_len >> (block->s2b_shift + 9); 466 if (idal_is_needed (page_address(bv.bv_page), bv.bv_len)) 467 cidaw += bv.bv_len / blksize; 468 } 469 /* Paranoia. */ 470 if (count != last_rec - first_rec + 1) 471 return ERR_PTR(-EINVAL); 472 /* 1x define extent + 1x locate record + number of blocks */ 473 cplength = 2 + count; 474 /* 1x define extent + 1x locate record */ 475 datasize = sizeof(struct DE_fba_data) + sizeof(struct LO_fba_data) + 476 cidaw * sizeof(unsigned long); 477 /* 478 * Find out number of additional locate record ccws if the device 479 * can't do data chaining. 480 */ 481 if (private->rdc_data.mode.bits.data_chain == 0) { 482 cplength += count - 1; 483 datasize += (count - 1)*sizeof(struct LO_fba_data); 484 } 485 /* Allocate the ccw request. */ 486 cqr = dasd_smalloc_request(DASD_FBA_MAGIC, cplength, datasize, memdev, 487 blk_mq_rq_to_pdu(req)); 488 if (IS_ERR(cqr)) 489 return cqr; 490 ccw = cqr->cpaddr; 491 /* First ccw is define extent. */ 492 define_extent(ccw++, cqr->data, rq_data_dir(req), 493 block->bp_block, blk_rq_pos(req), blk_rq_sectors(req)); 494 /* Build locate_record + read/write ccws. */ 495 idaws = (unsigned long *) (cqr->data + sizeof(struct DE_fba_data)); 496 LO_data = (struct LO_fba_data *) (idaws + cidaw); 497 /* Locate record for all blocks for smart devices. */ 498 if (private->rdc_data.mode.bits.data_chain != 0) { 499 ccw[-1].flags |= CCW_FLAG_CC; 500 locate_record(ccw++, LO_data++, rq_data_dir(req), 0, count); 501 } 502 recid = first_rec; 503 rq_for_each_segment(bv, req, iter) { 504 dst = bvec_virt(&bv); 505 if (dasd_page_cache) { 506 char *copy = kmem_cache_alloc(dasd_page_cache, 507 GFP_DMA | __GFP_NOWARN); 508 if (copy && rq_data_dir(req) == WRITE) 509 memcpy(copy + bv.bv_offset, dst, bv.bv_len); 510 if (copy) 511 dst = copy + bv.bv_offset; 512 } 513 for (off = 0; off < bv.bv_len; off += blksize) { 514 /* Locate record for stupid devices. */ 515 if (private->rdc_data.mode.bits.data_chain == 0) { 516 ccw[-1].flags |= CCW_FLAG_CC; 517 locate_record(ccw, LO_data++, 518 rq_data_dir(req), 519 recid - first_rec, 1); 520 ccw->flags = CCW_FLAG_CC; 521 ccw++; 522 } else { 523 if (recid > first_rec) 524 ccw[-1].flags |= CCW_FLAG_DC; 525 else 526 ccw[-1].flags |= CCW_FLAG_CC; 527 } 528 ccw->cmd_code = cmd; 529 ccw->count = block->bp_block; 530 if (idal_is_needed(dst, blksize)) { 531 ccw->cda = (__u32)(addr_t) idaws; 532 ccw->flags = CCW_FLAG_IDA; 533 idaws = idal_create_words(idaws, dst, blksize); 534 } else { 535 ccw->cda = (__u32)(addr_t) dst; 536 ccw->flags = 0; 537 } 538 ccw++; 539 dst += blksize; 540 recid++; 541 } 542 } 543 if (blk_noretry_request(req) || 544 block->base->features & DASD_FEATURE_FAILFAST) 545 set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags); 546 cqr->startdev = memdev; 547 cqr->memdev = memdev; 548 cqr->block = block; 549 cqr->expires = memdev->default_expires * HZ; /* default 5 minutes */ 550 cqr->retries = memdev->default_retries; 551 cqr->buildclk = get_tod_clock(); 552 cqr->status = DASD_CQR_FILLED; 553 return cqr; 554} 555 556static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device *memdev, 557 struct dasd_block *block, 558 struct request *req) 559{ 560 if (req_op(req) == REQ_OP_DISCARD || req_op(req) == REQ_OP_WRITE_ZEROES) 561 return dasd_fba_build_cp_discard(memdev, block, req); 562 else 563 return dasd_fba_build_cp_regular(memdev, block, req); 564} 565 566static int 567dasd_fba_free_cp(struct dasd_ccw_req *cqr, struct request *req) 568{ 569 struct dasd_fba_private *private = cqr->block->base->private; 570 struct ccw1 *ccw; 571 struct req_iterator iter; 572 struct bio_vec bv; 573 char *dst, *cda; 574 unsigned int blksize, off; 575 int status; 576 577 if (!dasd_page_cache) 578 goto out; 579 blksize = cqr->block->bp_block; 580 ccw = cqr->cpaddr; 581 /* Skip over define extent & locate record. */ 582 ccw++; 583 if (private->rdc_data.mode.bits.data_chain != 0) 584 ccw++; 585 rq_for_each_segment(bv, req, iter) { 586 dst = bvec_virt(&bv); 587 for (off = 0; off < bv.bv_len; off += blksize) { 588 /* Skip locate record. */ 589 if (private->rdc_data.mode.bits.data_chain == 0) 590 ccw++; 591 if (dst) { 592 if (ccw->flags & CCW_FLAG_IDA) 593 cda = *((char **)((addr_t) ccw->cda)); 594 else 595 cda = (char *)((addr_t) ccw->cda); 596 if (dst != cda) { 597 if (rq_data_dir(req) == READ) 598 memcpy(dst, cda, bv.bv_len); 599 kmem_cache_free(dasd_page_cache, 600 (void *)((addr_t)cda & PAGE_MASK)); 601 } 602 dst = NULL; 603 } 604 ccw++; 605 } 606 } 607out: 608 status = cqr->status == DASD_CQR_DONE; 609 dasd_sfree_request(cqr, cqr->memdev); 610 return status; 611} 612 613static void dasd_fba_handle_terminated_request(struct dasd_ccw_req *cqr) 614{ 615 if (cqr->retries < 0) 616 cqr->status = DASD_CQR_FAILED; 617 else 618 cqr->status = DASD_CQR_FILLED; 619}; 620 621static int 622dasd_fba_fill_info(struct dasd_device * device, 623 struct dasd_information2_t * info) 624{ 625 struct dasd_fba_private *private = device->private; 626 627 info->label_block = 1; 628 info->FBA_layout = 1; 629 info->format = DASD_FORMAT_LDL; 630 info->characteristics_size = sizeof(private->rdc_data); 631 memcpy(info->characteristics, &private->rdc_data, 632 sizeof(private->rdc_data)); 633 info->confdata_size = 0; 634 return 0; 635} 636 637static void 638dasd_fba_dump_sense_dbf(struct dasd_device *device, struct irb *irb, 639 char *reason) 640{ 641 u64 *sense; 642 643 sense = (u64 *) dasd_get_sense(irb); 644 if (sense) { 645 DBF_DEV_EVENT(DBF_EMERG, device, 646 "%s: %s %02x%02x%02x %016llx %016llx %016llx " 647 "%016llx", reason, 648 scsw_is_tm(&irb->scsw) ? "t" : "c", 649 scsw_cc(&irb->scsw), scsw_cstat(&irb->scsw), 650 scsw_dstat(&irb->scsw), sense[0], sense[1], 651 sense[2], sense[3]); 652 } else { 653 DBF_DEV_EVENT(DBF_EMERG, device, "%s", 654 "SORRY - NO VALID SENSE AVAILABLE\n"); 655 } 656} 657 658 659static void 660dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, 661 struct irb *irb) 662{ 663 char *page; 664 struct ccw1 *act, *end, *last; 665 int len, sl, sct, count; 666 667 page = (char *) get_zeroed_page(GFP_ATOMIC); 668 if (page == NULL) { 669 DBF_DEV_EVENT(DBF_WARNING, device, "%s", 670 "No memory to dump sense data"); 671 return; 672 } 673 len = sprintf(page, PRINTK_HEADER 674 " I/O status report for device %s:\n", 675 dev_name(&device->cdev->dev)); 676 len += sprintf(page + len, PRINTK_HEADER 677 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 678 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); 679 len += sprintf(page + len, PRINTK_HEADER 680 " device %s: Failing CCW: %p\n", 681 dev_name(&device->cdev->dev), 682 (void *) (addr_t) irb->scsw.cmd.cpa); 683 if (irb->esw.esw0.erw.cons) { 684 for (sl = 0; sl < 4; sl++) { 685 len += sprintf(page + len, PRINTK_HEADER 686 " Sense(hex) %2d-%2d:", 687 (8 * sl), ((8 * sl) + 7)); 688 689 for (sct = 0; sct < 8; sct++) { 690 len += sprintf(page + len, " %02x", 691 irb->ecw[8 * sl + sct]); 692 } 693 len += sprintf(page + len, "\n"); 694 } 695 } else { 696 len += sprintf(page + len, PRINTK_HEADER 697 " SORRY - NO VALID SENSE AVAILABLE\n"); 698 } 699 printk(KERN_ERR "%s", page); 700 701 /* dump the Channel Program */ 702 /* print first CCWs (maximum 8) */ 703 act = req->cpaddr; 704 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 705 end = min(act + 8, last); 706 len = sprintf(page, PRINTK_HEADER " Related CP in req: %p\n", req); 707 while (act <= end) { 708 len += sprintf(page + len, PRINTK_HEADER 709 " CCW %p: %08X %08X DAT:", 710 act, ((int *) act)[0], ((int *) act)[1]); 711 for (count = 0; count < 32 && count < act->count; 712 count += sizeof(int)) 713 len += sprintf(page + len, " %08X", 714 ((int *) (addr_t) act->cda) 715 [(count>>2)]); 716 len += sprintf(page + len, "\n"); 717 act++; 718 } 719 printk(KERN_ERR "%s", page); 720 721 722 /* print failing CCW area */ 723 len = 0; 724 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) { 725 act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2; 726 len += sprintf(page + len, PRINTK_HEADER "......\n"); 727 } 728 end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last); 729 while (act <= end) { 730 len += sprintf(page + len, PRINTK_HEADER 731 " CCW %p: %08X %08X DAT:", 732 act, ((int *) act)[0], ((int *) act)[1]); 733 for (count = 0; count < 32 && count < act->count; 734 count += sizeof(int)) 735 len += sprintf(page + len, " %08X", 736 ((int *) (addr_t) act->cda) 737 [(count>>2)]); 738 len += sprintf(page + len, "\n"); 739 act++; 740 } 741 742 /* print last CCWs */ 743 if (act < last - 2) { 744 act = last - 2; 745 len += sprintf(page + len, PRINTK_HEADER "......\n"); 746 } 747 while (act <= last) { 748 len += sprintf(page + len, PRINTK_HEADER 749 " CCW %p: %08X %08X DAT:", 750 act, ((int *) act)[0], ((int *) act)[1]); 751 for (count = 0; count < 32 && count < act->count; 752 count += sizeof(int)) 753 len += sprintf(page + len, " %08X", 754 ((int *) (addr_t) act->cda) 755 [(count>>2)]); 756 len += sprintf(page + len, "\n"); 757 act++; 758 } 759 if (len > 0) 760 printk(KERN_ERR "%s", page); 761 free_page((unsigned long) page); 762} 763 764/* 765 * Initialize block layer request queue. 766 */ 767static void dasd_fba_setup_blk_queue(struct dasd_block *block) 768{ 769 unsigned int logical_block_size = block->bp_block; 770 struct request_queue *q = block->request_queue; 771 unsigned int max_bytes, max_discard_sectors; 772 int max; 773 774 max = DASD_FBA_MAX_BLOCKS << block->s2b_shift; 775 blk_queue_flag_set(QUEUE_FLAG_NONROT, q); 776 q->limits.max_dev_sectors = max; 777 blk_queue_logical_block_size(q, logical_block_size); 778 blk_queue_max_hw_sectors(q, max); 779 blk_queue_max_segments(q, USHRT_MAX); 780 /* With page sized segments each segment can be translated into one idaw/tidaw */ 781 blk_queue_max_segment_size(q, PAGE_SIZE); 782 blk_queue_segment_boundary(q, PAGE_SIZE - 1); 783 784 q->limits.discard_granularity = logical_block_size; 785 786 /* Calculate max_discard_sectors and make it PAGE aligned */ 787 max_bytes = USHRT_MAX * logical_block_size; 788 max_bytes = ALIGN_DOWN(max_bytes, PAGE_SIZE); 789 max_discard_sectors = max_bytes / logical_block_size; 790 791 blk_queue_max_discard_sectors(q, max_discard_sectors); 792 blk_queue_max_write_zeroes_sectors(q, max_discard_sectors); 793} 794 795static int dasd_fba_pe_handler(struct dasd_device *device, 796 __u8 tbvpm, __u8 fcsecpm) 797{ 798 return dasd_generic_verify_path(device, tbvpm); 799} 800 801static struct dasd_discipline dasd_fba_discipline = { 802 .owner = THIS_MODULE, 803 .name = "FBA ", 804 .ebcname = "FBA ", 805 .check_device = dasd_fba_check_characteristics, 806 .do_analysis = dasd_fba_do_analysis, 807 .pe_handler = dasd_fba_pe_handler, 808 .setup_blk_queue = dasd_fba_setup_blk_queue, 809 .fill_geometry = dasd_fba_fill_geometry, 810 .start_IO = dasd_start_IO, 811 .term_IO = dasd_term_IO, 812 .handle_terminated_request = dasd_fba_handle_terminated_request, 813 .erp_action = dasd_fba_erp_action, 814 .erp_postaction = dasd_fba_erp_postaction, 815 .check_for_device_change = dasd_fba_check_for_device_change, 816 .build_cp = dasd_fba_build_cp, 817 .free_cp = dasd_fba_free_cp, 818 .dump_sense = dasd_fba_dump_sense, 819 .dump_sense_dbf = dasd_fba_dump_sense_dbf, 820 .fill_info = dasd_fba_fill_info, 821}; 822 823static int __init 824dasd_fba_init(void) 825{ 826 int ret; 827 828 ASCEBC(dasd_fba_discipline.ebcname, 4); 829 830 dasd_fba_zero_page = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 831 if (!dasd_fba_zero_page) 832 return -ENOMEM; 833 834 ret = ccw_driver_register(&dasd_fba_driver); 835 if (!ret) 836 wait_for_device_probe(); 837 838 return ret; 839} 840 841static void __exit 842dasd_fba_cleanup(void) 843{ 844 ccw_driver_unregister(&dasd_fba_driver); 845 free_page((unsigned long)dasd_fba_zero_page); 846} 847 848module_init(dasd_fba_init); 849module_exit(dasd_fba_cleanup);