1 // SPDX-License-Identifier: GPL-2.0
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com>
5 * Copyright IBM Corp. 1999, 2009
8 #define KMSG_COMPONENT "dasd-fba"
10 #include <linux/stddef.h>
11 #include <linux/kernel.h>
12 #include <asm/debug.h>
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>
20 #include <asm/idals.h>
21 #include <asm/ebcdic.h>
23 #include <asm/ccwdev.h>
30 #endif /* PRINTK_HEADER */
31 #define PRINTK_HEADER "dasd(fba):"
33 #define FBA_DEFAULT_RETRIES 32
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
40 MODULE_LICENSE("GPL");
42 static struct dasd_discipline dasd_fba_discipline
;
43 static void *dasd_fba_zero_page
;
45 struct dasd_fba_private
{
46 struct dasd_fba_characteristics rdc_data
;
49 static 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 */ },
55 MODULE_DEVICE_TABLE(ccw
, dasd_fba_ids
);
57 static struct ccw_driver dasd_fba_driver
; /* see below */
59 dasd_fba_probe(struct ccw_device
*cdev
)
61 return dasd_generic_probe(cdev
);
65 dasd_fba_set_online(struct ccw_device
*cdev
)
67 return dasd_generic_set_online(cdev
, &dasd_fba_discipline
);
70 static struct ccw_driver dasd_fba_driver
= {
76 .probe
= dasd_fba_probe
,
77 .remove
= dasd_generic_remove
,
78 .set_offline
= dasd_generic_set_offline
,
79 .set_online
= dasd_fba_set_online
,
80 .notify
= dasd_generic_notify
,
81 .path_event
= dasd_generic_path_event
,
82 .int_class
= IRQIO_DAS
,
86 define_extent(struct ccw1
* ccw
, struct DE_fba_data
*data
, int rw
,
87 int blksize
, int beg
, int nr
)
89 ccw
->cmd_code
= DASD_FBA_CCW_DEFINE_EXTENT
;
92 ccw
->cda
= (__u32
) __pa(data
);
93 memset(data
, 0, sizeof (struct DE_fba_data
));
95 (data
->mask
).perm
= 0x0;
97 (data
->mask
).perm
= 0x1;
99 data
->mask
.perm
= 0x2;
100 data
->blk_size
= blksize
;
102 data
->ext_end
= nr
- 1;
106 locate_record(struct ccw1
* ccw
, struct LO_fba_data
*data
, int rw
,
107 int block_nr
, int block_ct
)
109 ccw
->cmd_code
= DASD_FBA_CCW_LOCATE
;
112 ccw
->cda
= (__u32
) __pa(data
);
113 memset(data
, 0, sizeof (struct LO_fba_data
));
115 data
->operation
.cmd
= 0x5;
117 data
->operation
.cmd
= 0x6;
119 data
->operation
.cmd
= 0x8;
120 data
->blk_nr
= block_nr
;
121 data
->blk_ct
= block_ct
;
125 dasd_fba_check_characteristics(struct dasd_device
*device
)
127 struct dasd_fba_private
*private = device
->private;
128 struct ccw_device
*cdev
= device
->cdev
;
129 struct dasd_block
*block
;
133 private = kzalloc(sizeof(*private), GFP_KERNEL
| GFP_DMA
);
135 dev_warn(&device
->cdev
->dev
,
136 "Allocating memory for private DASD "
140 device
->private = private;
142 memset(private, 0, sizeof(*private));
144 block
= dasd_alloc_block();
146 DBF_EVENT_DEVID(DBF_WARNING
, cdev
, "%s", "could not allocate "
147 "dasd block structure");
148 device
->private = NULL
;
150 return PTR_ERR(block
);
152 device
->block
= block
;
153 block
->base
= device
;
155 /* Read Device Characteristics */
156 rc
= dasd_generic_read_dev_chars(device
, DASD_FBA_MAGIC
,
157 &private->rdc_data
, 32);
159 DBF_EVENT_DEVID(DBF_WARNING
, cdev
, "Read device "
160 "characteristics returned error %d", rc
);
161 device
->block
= NULL
;
162 dasd_free_block(block
);
163 device
->private = NULL
;
168 device
->default_expires
= DASD_EXPIRES
;
169 device
->default_retries
= FBA_DEFAULT_RETRIES
;
170 dasd_path_set_opm(device
, LPM_ANYPATH
);
172 readonly
= dasd_device_is_ro(device
);
174 set_bit(DASD_FLAG_DEVICE_RO
, &device
->flags
);
176 /* FBA supports discard, set the according feature bit */
177 dasd_set_feature(cdev
, DASD_FEATURE_DISCARD
, 1);
179 dev_info(&device
->cdev
->dev
,
180 "New FBA DASD %04X/%02X (CU %04X/%02X) with %d MB "
186 ((private->rdc_data
.blk_bdsa
*
187 (private->rdc_data
.blk_size
>> 9)) >> 11),
188 private->rdc_data
.blk_size
,
189 readonly
? ", read-only device" : "");
193 static int dasd_fba_do_analysis(struct dasd_block
*block
)
195 struct dasd_fba_private
*private = block
->base
->private;
198 rc
= dasd_check_blocksize(private->rdc_data
.blk_size
);
200 DBF_DEV_EVENT(DBF_WARNING
, block
->base
, "unknown blocksize %d",
201 private->rdc_data
.blk_size
);
204 block
->blocks
= private->rdc_data
.blk_bdsa
;
205 block
->bp_block
= private->rdc_data
.blk_size
;
206 block
->s2b_shift
= 0; /* bits to shift 512 to get a block */
207 for (sb
= 512; sb
< private->rdc_data
.blk_size
; sb
= sb
<< 1)
212 static int dasd_fba_fill_geometry(struct dasd_block
*block
,
213 struct hd_geometry
*geo
)
215 if (dasd_check_blocksize(block
->bp_block
) != 0)
217 geo
->cylinders
= (block
->blocks
<< block
->s2b_shift
) >> 10;
219 geo
->sectors
= 128 >> block
->s2b_shift
;
224 dasd_fba_erp_action(struct dasd_ccw_req
* cqr
)
226 return dasd_default_erp_action
;
230 dasd_fba_erp_postaction(struct dasd_ccw_req
* cqr
)
232 if (cqr
->function
== dasd_default_erp_action
)
233 return dasd_default_erp_postaction
;
235 DBF_DEV_EVENT(DBF_WARNING
, cqr
->startdev
, "unknown ERP action %p",
240 static void dasd_fba_check_for_device_change(struct dasd_device
*device
,
241 struct dasd_ccw_req
*cqr
,
246 /* first of all check for state change pending interrupt */
247 mask
= DEV_STAT_ATTENTION
| DEV_STAT_DEV_END
| DEV_STAT_UNIT_EXCEP
;
248 if ((irb
->scsw
.cmd
.dstat
& mask
) == mask
)
249 dasd_generic_handle_state_change(device
);
254 * Builds a CCW with no data payload
256 static void ccw_write_no_data(struct ccw1
*ccw
)
258 ccw
->cmd_code
= DASD_FBA_CCW_WRITE
;
259 ccw
->flags
|= CCW_FLAG_SLI
;
264 * Builds a CCW that writes only zeroes.
266 static void ccw_write_zero(struct ccw1
*ccw
, int count
)
268 ccw
->cmd_code
= DASD_FBA_CCW_WRITE
;
269 ccw
->flags
|= CCW_FLAG_SLI
;
271 ccw
->cda
= (__u32
) (addr_t
) dasd_fba_zero_page
;
275 * Helper function to count the amount of necessary CCWs within a given range
276 * with 4k alignment and command chaining in mind.
278 static int count_ccws(sector_t first_rec
, sector_t last_rec
,
279 unsigned int blocks_per_page
)
281 sector_t wz_stop
= 0, d_stop
= 0;
285 if (first_rec
% blocks_per_page
!= 0) {
286 wz_stop
= first_rec
+ blocks_per_page
-
287 (first_rec
% blocks_per_page
) - 1;
288 if (wz_stop
> last_rec
)
290 cur_pos
= wz_stop
- first_rec
+ 1;
294 if (last_rec
- (first_rec
+ cur_pos
) + 1 >= blocks_per_page
) {
295 if ((last_rec
- blocks_per_page
+ 1) % blocks_per_page
!= 0)
296 d_stop
= last_rec
- ((last_rec
- blocks_per_page
+ 1) %
301 cur_pos
+= d_stop
- (first_rec
+ cur_pos
) + 1;
305 if (cur_pos
== 0 || first_rec
+ cur_pos
- 1 < last_rec
)
312 * This function builds a CCW request for block layer discard requests.
313 * Each page in the z/VM hypervisor that represents certain records of an FBA
314 * device will be padded with zeros. This is a special behaviour of the WRITE
315 * command which is triggered when no data payload is added to the CCW.
317 * Note: Due to issues in some z/VM versions, we can't fully utilise this
318 * special behaviour. We have to keep a 4k (or 8 block) alignment in mind to
319 * work around those issues and write actual zeroes to the unaligned parts in
320 * the request. This workaround might be removed in the future.
322 static struct dasd_ccw_req
*dasd_fba_build_cp_discard(
323 struct dasd_device
*memdev
,
324 struct dasd_block
*block
,
327 struct LO_fba_data
*LO_data
;
328 struct dasd_ccw_req
*cqr
;
331 sector_t wz_stop
= 0, d_stop
= 0;
332 sector_t first_rec
, last_rec
;
334 unsigned int blksize
= block
->bp_block
;
335 unsigned int blocks_per_page
;
338 int cur_pos
= 0; /* Current position within the extent */
344 first_rec
= blk_rq_pos(req
) >> block
->s2b_shift
;
346 (blk_rq_pos(req
) + blk_rq_sectors(req
) - 1) >> block
->s2b_shift
;
347 count
= last_rec
- first_rec
+ 1;
349 blocks_per_page
= BLOCKS_PER_PAGE(blksize
);
350 nr_ccws
= count_ccws(first_rec
, last_rec
, blocks_per_page
);
352 /* define extent + nr_ccws * locate record + nr_ccws * single CCW */
353 cplength
= 1 + 2 * nr_ccws
;
354 datasize
= sizeof(struct DE_fba_data
) +
355 nr_ccws
* (sizeof(struct LO_fba_data
) + sizeof(struct ccw1
));
357 cqr
= dasd_smalloc_request(DASD_FBA_MAGIC
, cplength
, datasize
, memdev
,
358 blk_mq_rq_to_pdu(req
));
364 define_extent(ccw
++, cqr
->data
, WRITE
, blksize
, first_rec
, count
);
365 LO_data
= cqr
->data
+ sizeof(struct DE_fba_data
);
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
)
373 wz_count
= wz_stop
- first_rec
+ 1;
375 ccw
[-1].flags
|= CCW_FLAG_CC
;
376 locate_record(ccw
++, LO_data
++, WRITE
, cur_pos
, wz_count
);
378 ccw
[-1].flags
|= CCW_FLAG_CC
;
379 ccw_write_zero(ccw
++, wz_count
* blksize
);
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) %
393 d_count
= d_stop
- (first_rec
+ cur_pos
) + 1;
395 ccw
[-1].flags
|= CCW_FLAG_CC
;
396 locate_record(ccw
++, LO_data
++, WRITE
, cur_pos
, d_count
);
398 ccw
[-1].flags
|= CCW_FLAG_CC
;
399 ccw_write_no_data(ccw
++);
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
) {
407 wz_count
= last_rec
- d_stop
;
408 else if (wz_stop
!= 0)
409 wz_count
= last_rec
- wz_stop
;
413 ccw
[-1].flags
|= CCW_FLAG_CC
;
414 locate_record(ccw
++, LO_data
++, WRITE
, cur_pos
, wz_count
);
416 ccw
[-1].flags
|= CCW_FLAG_CC
;
417 ccw_write_zero(ccw
++, wz_count
* blksize
);
420 if (blk_noretry_request(req
) ||
421 block
->base
->features
& DASD_FEATURE_FAILFAST
)
422 set_bit(DASD_CQR_FLAGS_FAILFAST
, &cqr
->flags
);
424 cqr
->startdev
= memdev
;
425 cqr
->memdev
= memdev
;
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
;
435 static struct dasd_ccw_req
*dasd_fba_build_cp_regular(
436 struct dasd_device
*memdev
,
437 struct dasd_block
*block
,
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
;
445 struct req_iterator iter
;
448 int count
, cidaw
, cplength
, datasize
;
449 sector_t recid
, first_rec
, last_rec
;
450 unsigned int blksize
, off
;
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
;
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
;
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. */
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
;
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);
484 * Find out number of additional locate record ccws if the device
485 * can't do data chaining.
487 if (private->rdc_data
.mode
.bits
.data_chain
== 0) {
488 cplength
+= count
- 1;
489 datasize
+= (count
- 1)*sizeof(struct LO_fba_data
);
491 /* Allocate the ccw request. */
492 cqr
= dasd_smalloc_request(DASD_FBA_MAGIC
, cplength
, datasize
, memdev
,
493 blk_mq_rq_to_pdu(req
));
497 /* First ccw is define extent. */
498 define_extent(ccw
++, cqr
->data
, rq_data_dir(req
),
499 block
->bp_block
, blk_rq_pos(req
), blk_rq_sectors(req
));
500 /* Build locate_record + read/write ccws. */
501 idaws
= (unsigned long *) (cqr
->data
+ sizeof(struct DE_fba_data
));
502 LO_data
= (struct LO_fba_data
*) (idaws
+ cidaw
);
503 /* Locate record for all blocks for smart devices. */
504 if (private->rdc_data
.mode
.bits
.data_chain
!= 0) {
505 ccw
[-1].flags
|= CCW_FLAG_CC
;
506 locate_record(ccw
++, LO_data
++, rq_data_dir(req
), 0, count
);
509 rq_for_each_segment(bv
, req
, iter
) {
510 dst
= page_address(bv
.bv_page
) + bv
.bv_offset
;
511 if (dasd_page_cache
) {
512 char *copy
= kmem_cache_alloc(dasd_page_cache
,
513 GFP_DMA
| __GFP_NOWARN
);
514 if (copy
&& rq_data_dir(req
) == WRITE
)
515 memcpy(copy
+ bv
.bv_offset
, dst
, bv
.bv_len
);
517 dst
= copy
+ bv
.bv_offset
;
519 for (off
= 0; off
< bv
.bv_len
; off
+= blksize
) {
520 /* Locate record for stupid devices. */
521 if (private->rdc_data
.mode
.bits
.data_chain
== 0) {
522 ccw
[-1].flags
|= CCW_FLAG_CC
;
523 locate_record(ccw
, LO_data
++,
525 recid
- first_rec
, 1);
526 ccw
->flags
= CCW_FLAG_CC
;
529 if (recid
> first_rec
)
530 ccw
[-1].flags
|= CCW_FLAG_DC
;
532 ccw
[-1].flags
|= CCW_FLAG_CC
;
535 ccw
->count
= block
->bp_block
;
536 if (idal_is_needed(dst
, blksize
)) {
537 ccw
->cda
= (__u32
)(addr_t
) idaws
;
538 ccw
->flags
= CCW_FLAG_IDA
;
539 idaws
= idal_create_words(idaws
, dst
, blksize
);
541 ccw
->cda
= (__u32
)(addr_t
) dst
;
549 if (blk_noretry_request(req
) ||
550 block
->base
->features
& DASD_FEATURE_FAILFAST
)
551 set_bit(DASD_CQR_FLAGS_FAILFAST
, &cqr
->flags
);
552 cqr
->startdev
= memdev
;
553 cqr
->memdev
= memdev
;
555 cqr
->expires
= memdev
->default_expires
* HZ
; /* default 5 minutes */
556 cqr
->retries
= memdev
->default_retries
;
557 cqr
->buildclk
= get_tod_clock();
558 cqr
->status
= DASD_CQR_FILLED
;
562 static struct dasd_ccw_req
*dasd_fba_build_cp(struct dasd_device
*memdev
,
563 struct dasd_block
*block
,
566 if (req_op(req
) == REQ_OP_DISCARD
|| req_op(req
) == REQ_OP_WRITE_ZEROES
)
567 return dasd_fba_build_cp_discard(memdev
, block
, req
);
569 return dasd_fba_build_cp_regular(memdev
, block
, req
);
573 dasd_fba_free_cp(struct dasd_ccw_req
*cqr
, struct request
*req
)
575 struct dasd_fba_private
*private = cqr
->block
->base
->private;
577 struct req_iterator iter
;
580 unsigned int blksize
, off
;
583 if (!dasd_page_cache
)
585 blksize
= cqr
->block
->bp_block
;
587 /* Skip over define extent & locate record. */
589 if (private->rdc_data
.mode
.bits
.data_chain
!= 0)
591 rq_for_each_segment(bv
, req
, iter
) {
592 dst
= page_address(bv
.bv_page
) + bv
.bv_offset
;
593 for (off
= 0; off
< bv
.bv_len
; off
+= blksize
) {
594 /* Skip locate record. */
595 if (private->rdc_data
.mode
.bits
.data_chain
== 0)
598 if (ccw
->flags
& CCW_FLAG_IDA
)
599 cda
= *((char **)((addr_t
) ccw
->cda
));
601 cda
= (char *)((addr_t
) ccw
->cda
);
603 if (rq_data_dir(req
) == READ
)
604 memcpy(dst
, cda
, bv
.bv_len
);
605 kmem_cache_free(dasd_page_cache
,
606 (void *)((addr_t
)cda
& PAGE_MASK
));
614 status
= cqr
->status
== DASD_CQR_DONE
;
615 dasd_sfree_request(cqr
, cqr
->memdev
);
619 static void dasd_fba_handle_terminated_request(struct dasd_ccw_req
*cqr
)
621 if (cqr
->retries
< 0)
622 cqr
->status
= DASD_CQR_FAILED
;
624 cqr
->status
= DASD_CQR_FILLED
;
628 dasd_fba_fill_info(struct dasd_device
* device
,
629 struct dasd_information2_t
* info
)
631 struct dasd_fba_private
*private = device
->private;
633 info
->label_block
= 1;
634 info
->FBA_layout
= 1;
635 info
->format
= DASD_FORMAT_LDL
;
636 info
->characteristics_size
= sizeof(private->rdc_data
);
637 memcpy(info
->characteristics
, &private->rdc_data
,
638 sizeof(private->rdc_data
));
639 info
->confdata_size
= 0;
644 dasd_fba_dump_sense_dbf(struct dasd_device
*device
, struct irb
*irb
,
649 sense
= (u64
*) dasd_get_sense(irb
);
651 DBF_DEV_EVENT(DBF_EMERG
, device
,
652 "%s: %s %02x%02x%02x %016llx %016llx %016llx "
654 scsw_is_tm(&irb
->scsw
) ? "t" : "c",
655 scsw_cc(&irb
->scsw
), scsw_cstat(&irb
->scsw
),
656 scsw_dstat(&irb
->scsw
), sense
[0], sense
[1],
659 DBF_DEV_EVENT(DBF_EMERG
, device
, "%s",
660 "SORRY - NO VALID SENSE AVAILABLE\n");
666 dasd_fba_dump_sense(struct dasd_device
*device
, struct dasd_ccw_req
* req
,
670 struct ccw1
*act
, *end
, *last
;
671 int len
, sl
, sct
, count
;
673 page
= (char *) get_zeroed_page(GFP_ATOMIC
);
675 DBF_DEV_EVENT(DBF_WARNING
, device
, "%s",
676 "No memory to dump sense data");
679 len
= sprintf(page
, PRINTK_HEADER
680 " I/O status report for device %s:\n",
681 dev_name(&device
->cdev
->dev
));
682 len
+= sprintf(page
+ len
, PRINTK_HEADER
683 " in req: %p CS: 0x%02X DS: 0x%02X\n", req
,
684 irb
->scsw
.cmd
.cstat
, irb
->scsw
.cmd
.dstat
);
685 len
+= sprintf(page
+ len
, PRINTK_HEADER
686 " device %s: Failing CCW: %p\n",
687 dev_name(&device
->cdev
->dev
),
688 (void *) (addr_t
) irb
->scsw
.cmd
.cpa
);
689 if (irb
->esw
.esw0
.erw
.cons
) {
690 for (sl
= 0; sl
< 4; sl
++) {
691 len
+= sprintf(page
+ len
, PRINTK_HEADER
692 " Sense(hex) %2d-%2d:",
693 (8 * sl
), ((8 * sl
) + 7));
695 for (sct
= 0; sct
< 8; sct
++) {
696 len
+= sprintf(page
+ len
, " %02x",
697 irb
->ecw
[8 * sl
+ sct
]);
699 len
+= sprintf(page
+ len
, "\n");
702 len
+= sprintf(page
+ len
, PRINTK_HEADER
703 " SORRY - NO VALID SENSE AVAILABLE\n");
705 printk(KERN_ERR
"%s", page
);
707 /* dump the Channel Program */
708 /* print first CCWs (maximum 8) */
710 for (last
= act
; last
->flags
& (CCW_FLAG_CC
| CCW_FLAG_DC
); last
++);
711 end
= min(act
+ 8, last
);
712 len
= sprintf(page
, PRINTK_HEADER
" Related CP in req: %p\n", req
);
714 len
+= sprintf(page
+ len
, PRINTK_HEADER
715 " CCW %p: %08X %08X DAT:",
716 act
, ((int *) act
)[0], ((int *) act
)[1]);
717 for (count
= 0; count
< 32 && count
< act
->count
;
718 count
+= sizeof(int))
719 len
+= sprintf(page
+ len
, " %08X",
720 ((int *) (addr_t
) act
->cda
)
722 len
+= sprintf(page
+ len
, "\n");
725 printk(KERN_ERR
"%s", page
);
728 /* print failing CCW area */
730 if (act
< ((struct ccw1
*)(addr_t
) irb
->scsw
.cmd
.cpa
) - 2) {
731 act
= ((struct ccw1
*)(addr_t
) irb
->scsw
.cmd
.cpa
) - 2;
732 len
+= sprintf(page
+ len
, PRINTK_HEADER
"......\n");
734 end
= min((struct ccw1
*)(addr_t
) irb
->scsw
.cmd
.cpa
+ 2, last
);
736 len
+= sprintf(page
+ len
, PRINTK_HEADER
737 " CCW %p: %08X %08X DAT:",
738 act
, ((int *) act
)[0], ((int *) act
)[1]);
739 for (count
= 0; count
< 32 && count
< act
->count
;
740 count
+= sizeof(int))
741 len
+= sprintf(page
+ len
, " %08X",
742 ((int *) (addr_t
) act
->cda
)
744 len
+= sprintf(page
+ len
, "\n");
748 /* print last CCWs */
749 if (act
< last
- 2) {
751 len
+= sprintf(page
+ len
, PRINTK_HEADER
"......\n");
753 while (act
<= last
) {
754 len
+= sprintf(page
+ len
, PRINTK_HEADER
755 " CCW %p: %08X %08X DAT:",
756 act
, ((int *) act
)[0], ((int *) act
)[1]);
757 for (count
= 0; count
< 32 && count
< act
->count
;
758 count
+= sizeof(int))
759 len
+= sprintf(page
+ len
, " %08X",
760 ((int *) (addr_t
) act
->cda
)
762 len
+= sprintf(page
+ len
, "\n");
766 printk(KERN_ERR
"%s", page
);
767 free_page((unsigned long) page
);
771 * Initialize block layer request queue.
773 static void dasd_fba_setup_blk_queue(struct dasd_block
*block
)
775 unsigned int logical_block_size
= block
->bp_block
;
776 struct request_queue
*q
= block
->request_queue
;
777 unsigned int max_bytes
, max_discard_sectors
;
780 max
= DASD_FBA_MAX_BLOCKS
<< block
->s2b_shift
;
781 blk_queue_flag_set(QUEUE_FLAG_NONROT
, q
);
782 q
->limits
.max_dev_sectors
= max
;
783 blk_queue_logical_block_size(q
, logical_block_size
);
784 blk_queue_max_hw_sectors(q
, max
);
785 blk_queue_max_segments(q
, USHRT_MAX
);
786 /* With page sized segments each segment can be translated into one idaw/tidaw */
787 blk_queue_max_segment_size(q
, PAGE_SIZE
);
788 blk_queue_segment_boundary(q
, PAGE_SIZE
- 1);
790 q
->limits
.discard_granularity
= logical_block_size
;
791 q
->limits
.discard_alignment
= PAGE_SIZE
;
793 /* Calculate max_discard_sectors and make it PAGE aligned */
794 max_bytes
= USHRT_MAX
* logical_block_size
;
795 max_bytes
= ALIGN_DOWN(max_bytes
, PAGE_SIZE
);
796 max_discard_sectors
= max_bytes
/ logical_block_size
;
798 blk_queue_max_discard_sectors(q
, max_discard_sectors
);
799 blk_queue_max_write_zeroes_sectors(q
, max_discard_sectors
);
800 blk_queue_flag_set(QUEUE_FLAG_DISCARD
, q
);
803 static struct dasd_discipline dasd_fba_discipline
= {
804 .owner
= THIS_MODULE
,
807 .check_device
= dasd_fba_check_characteristics
,
808 .do_analysis
= dasd_fba_do_analysis
,
809 .verify_path
= dasd_generic_verify_path
,
810 .setup_blk_queue
= dasd_fba_setup_blk_queue
,
811 .fill_geometry
= dasd_fba_fill_geometry
,
812 .start_IO
= dasd_start_IO
,
813 .term_IO
= dasd_term_IO
,
814 .handle_terminated_request
= dasd_fba_handle_terminated_request
,
815 .erp_action
= dasd_fba_erp_action
,
816 .erp_postaction
= dasd_fba_erp_postaction
,
817 .check_for_device_change
= dasd_fba_check_for_device_change
,
818 .build_cp
= dasd_fba_build_cp
,
819 .free_cp
= dasd_fba_free_cp
,
820 .dump_sense
= dasd_fba_dump_sense
,
821 .dump_sense_dbf
= dasd_fba_dump_sense_dbf
,
822 .fill_info
= dasd_fba_fill_info
,
830 ASCEBC(dasd_fba_discipline
.ebcname
, 4);
832 dasd_fba_zero_page
= (void *)get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
833 if (!dasd_fba_zero_page
)
836 ret
= ccw_driver_register(&dasd_fba_driver
);
838 wait_for_device_probe();
844 dasd_fba_cleanup(void)
846 ccw_driver_unregister(&dasd_fba_driver
);
847 free_page((unsigned long)dasd_fba_zero_page
);
850 module_init(dasd_fba_init
);
851 module_exit(dasd_fba_cleanup
);