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