1 // SPDX-License-Identifier: GPL-2.0
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, 2001
10 * gendisk related functions for the dasd driver.
14 #include <linux/interrupt.h>
15 #include <linux/major.h>
17 #include <linux/blkpg.h>
19 #include <linux/uaccess.h>
23 static unsigned int queue_depth
= 32;
24 static unsigned int nr_hw_queues
= 4;
26 module_param(queue_depth
, uint
, 0444);
27 MODULE_PARM_DESC(queue_depth
, "Default queue depth for new DASD devices");
29 module_param(nr_hw_queues
, uint
, 0444);
30 MODULE_PARM_DESC(nr_hw_queues
, "Default number of hardware queues for new DASD devices");
33 * Allocate and register gendisk structure for device.
35 int dasd_gendisk_alloc(struct dasd_block
*block
)
37 struct queue_limits lim
= {
39 * With page sized segments, each segment can be translated into
42 .max_segment_size
= PAGE_SIZE
,
43 .seg_boundary_mask
= PAGE_SIZE
- 1,
44 .max_segments
= USHRT_MAX
,
47 struct dasd_device
*base
;
50 /* Make sure the minor for this device exists. */
52 if (base
->devindex
>= DASD_PER_MAJOR
)
55 block
->tag_set
.ops
= &dasd_mq_ops
;
56 block
->tag_set
.cmd_size
= sizeof(struct dasd_ccw_req
);
57 block
->tag_set
.nr_hw_queues
= nr_hw_queues
;
58 block
->tag_set
.queue_depth
= queue_depth
;
59 block
->tag_set
.flags
= BLK_MQ_F_SHOULD_MERGE
;
60 block
->tag_set
.numa_node
= NUMA_NO_NODE
;
61 rc
= blk_mq_alloc_tag_set(&block
->tag_set
);
65 gdp
= blk_mq_alloc_disk(&block
->tag_set
, &lim
, block
);
67 blk_mq_free_tag_set(&block
->tag_set
);
71 /* Initialize gendisk structure. */
72 gdp
->major
= DASD_MAJOR
;
73 gdp
->first_minor
= base
->devindex
<< DASD_PARTN_BITS
;
74 gdp
->minors
= 1 << DASD_PARTN_BITS
;
75 gdp
->fops
= &dasd_device_operations
;
79 * dasda - dasdz : 26 devices
80 * dasdaa - dasdzz : 676 devices, added up = 702
81 * dasdaaa - dasdzzz : 17576 devices, added up = 18278
82 * dasdaaaa - dasdzzzz : 456976 devices, added up = 475252
84 len
= sprintf(gdp
->disk_name
, "dasd");
85 if (base
->devindex
> 25) {
86 if (base
->devindex
> 701) {
87 if (base
->devindex
> 18277)
88 len
+= sprintf(gdp
->disk_name
+ len
, "%c",
89 'a'+(((base
->devindex
-18278)
91 len
+= sprintf(gdp
->disk_name
+ len
, "%c",
92 'a'+(((base
->devindex
-702)/676)%26));
94 len
+= sprintf(gdp
->disk_name
+ len
, "%c",
95 'a'+(((base
->devindex
-26)/26)%26));
97 len
+= sprintf(gdp
->disk_name
+ len
, "%c", 'a'+(base
->devindex
%26));
99 if (base
->features
& DASD_FEATURE_READONLY
||
100 test_bit(DASD_FLAG_DEVICE_RO
, &base
->flags
))
102 dasd_add_link_to_gendisk(gdp
, base
);
104 set_capacity(block
->gdp
, 0);
106 rc
= device_add_disk(&base
->cdev
->dev
, block
->gdp
, NULL
);
108 dasd_gendisk_free(block
);
116 * Unregister and free gendisk structure for device.
118 void dasd_gendisk_free(struct dasd_block
*block
)
121 del_gendisk(block
->gdp
);
122 block
->gdp
->private_data
= NULL
;
123 put_disk(block
->gdp
);
125 blk_mq_free_tag_set(&block
->tag_set
);
130 * Trigger a partition detection.
132 int dasd_scan_partitions(struct dasd_block
*block
)
134 struct file
*bdev_file
;
137 bdev_file
= bdev_file_open_by_dev(disk_devt(block
->gdp
), BLK_OPEN_READ
,
139 if (IS_ERR(bdev_file
)) {
140 DBF_DEV_EVENT(DBF_ERR
, block
->base
,
141 "scan partitions error, blkdev_get returned %ld",
146 mutex_lock(&block
->gdp
->open_mutex
);
147 rc
= bdev_disk_changed(block
->gdp
, false);
148 mutex_unlock(&block
->gdp
->open_mutex
);
150 DBF_DEV_EVENT(DBF_ERR
, block
->base
,
151 "scan partitions error, rc %d", rc
);
154 * Since the matching fput() call to the
155 * bdev_file_open_by_path() in this function is not called before
156 * dasd_destroy_partitions the offline open_count limit needs to be
157 * increased from 0 to 1. This is done by setting device->bdev_file
158 * (see dasd_generic_set_offline). As long as the partition detection
159 * is running no offline should be allowed. That is why the assignment
160 * to block->bdev_file is done AFTER the BLKRRPART ioctl.
162 block
->bdev_file
= bdev_file
;
167 * Remove all inodes in the system for a device, delete the
168 * partitions and make device unusable by setting its size to zero.
170 void dasd_destroy_partitions(struct dasd_block
*block
)
172 struct file
*bdev_file
;
175 * Get the bdev_file pointer from the device structure and clear
176 * device->bdev_file to lower the offline open_count limit again.
178 bdev_file
= block
->bdev_file
;
179 block
->bdev_file
= NULL
;
181 mutex_lock(&file_bdev(bdev_file
)->bd_disk
->open_mutex
);
182 bdev_disk_changed(file_bdev(bdev_file
)->bd_disk
, true);
183 mutex_unlock(&file_bdev(bdev_file
)->bd_disk
->open_mutex
);
185 /* Matching blkdev_put to the blkdev_get in dasd_scan_partitions. */
189 int dasd_gendisk_init(void)
193 /* Register to static dasd major 94 */
194 rc
= register_blkdev(DASD_MAJOR
, "dasd");
196 pr_warn("Registering the device driver with major number %d failed\n",
203 void dasd_gendisk_exit(void)
205 unregister_blkdev(DASD_MAJOR
, "dasd");