15 #define KMSG_COMPONENT "dasd"
17 #include <linux/ctype.h>
19 #include <linux/module.h>
20 #include <linux/slab.h>
22 #include <asm/debug.h>
23 #include <asm/uaccess.h>
27 #define PRINTK_HEADER "dasd_devmap:"
28 #define DASD_BUS_ID_SIZE 20
79 static char *
dasd[256];
90 static struct list_head dasd_hashlists[256];
93 static struct dasd_devmap *dasd_add_busid(
const char *,
int);
96 dasd_hash_busid(
const char *
bus_id)
113 dasd_call_setup(
char *
str)
115 static int count = 0;
122 __setup (
"dasd=", dasd_call_setup);
125 #define DASD_IPLDEV "ipldev"
132 dasd_busid(
char **str,
int *
id0,
int *
id1,
int *
devno)
139 pr_err(
"The IPL device is not a CCW device\n");
151 if ((*str)[0] ==
'0' && (*str)[1] ==
'x') {
158 if (old_style || (*str)[0] !=
'.') {
160 if (val < 0 || val > 0xffff)
166 if (val < 0 || val > 0xff)
173 if (val < 0 || val > 0xff || (*str)++[0] !=
'.')
179 if (val < 0 || val > 0xffff)
191 dasd_feature_list(
char *str,
char **endp)
205 str[len] && str[len] !=
':' && str[len] !=
')'; len++);
206 if (len == 2 && !
strncmp(str,
"ro", 2))
208 else if (len == 4 && !
strncmp(str,
"diag", 4))
210 else if (len == 3 && !
strncmp(str,
"raw", 3))
212 else if (len == 6 && !
strncmp(str,
"erplog", 6))
214 else if (len == 8 && !
strncmp(str,
"failfast", 8))
217 pr_warning(
"%*s is not a supported device option\n",
227 pr_warning(
"A closing parenthesis ')' is missing in the "
228 "dasd= parameter\n");
245 dasd_parse_keyword(
char *parsestring ) {
247 char *nextcomma, *residual_str;
250 nextcomma =
strchr(parsestring,
',');
252 length = nextcomma - parsestring;
253 residual_str = nextcomma + 1;
255 length =
strlen(parsestring);
256 residual_str = parsestring +
length;
258 if (
strncmp(
"autodetect", parsestring, length) == 0) {
260 pr_info(
"The autodetection mode has been activated\n");
263 if (
strncmp(
"probeonly", parsestring, length) == 0) {
265 pr_info(
"The probeonly mode has been activated\n");
268 if (
strncmp(
"nopav", parsestring, length) == 0) {
270 pr_info(
"'nopav' is not supported on z/VM\n");
273 pr_info(
"PAV support has be deactivated\n");
277 if (
strncmp(
"nofcx", parsestring, length) == 0) {
279 pr_info(
"High Performance FICON support has been "
283 if (
strncmp(
"fixedbuffers", parsestring, length) == 0) {
290 if (!dasd_page_cache)
292 "fixed buffer mode disabled.");
295 "turning on fixed buffer mode");
309 dasd_parse_range(
char *parsestring ) {
312 int from, from_id0, from_id1;
313 int to, to_id0, to_id1;
318 rc = dasd_busid(&str, &from_id0, &from_id1, &from);
325 rc = dasd_busid(&str, &to_id0, &to_id1, &to);
329 (from_id0 != to_id0 || from_id1 != to_id1 || from > to))
332 pr_err(
"%s is not a valid device range\n", parsestring);
335 features = dasd_feature_list(str, &str);
341 sprintf(bus_id,
"%01x.%01x.%04x",
342 from_id0, from_id1, from++);
343 devmap = dasd_add_busid(bus_id, features);
345 return (
char *)devmap;
351 pr_warning(
"The dasd= parameter value %s has an invalid ending\n",
357 dasd_parse_next_element(
char *parsestring ) {
359 residual_str = dasd_parse_keyword(parsestring);
360 if (!IS_ERR(residual_str))
362 residual_str = dasd_parse_range(parsestring);
381 for (i = 0; i < 256; i++) {
384 parsestring =
dasd[
i];
386 while (*parsestring) {
387 parsestring = dasd_parse_next_element(parsestring);
388 if(IS_ERR(parsestring)) {
389 rc = PTR_ERR(parsestring);
408 dasd_add_busid(
const char *bus_id,
int features)
417 spin_lock(&dasd_devmap_lock);
419 hash = dasd_hash_busid(bus_id);
431 list_add(&new->list, &dasd_hashlists[hash]);
435 spin_unlock(&dasd_devmap_lock);
444 dasd_find_busid(
const char *bus_id)
449 spin_lock(&dasd_devmap_lock);
450 devmap = ERR_PTR(-
ENODEV);
451 hash = dasd_hash_busid(bus_id);
458 spin_unlock(&dasd_devmap_lock);
468 return IS_ERR(dasd_find_busid(bus_id)) ? -
ENOENT : 0;
476 dasd_forget_ranges(
void)
481 spin_lock(&dasd_devmap_lock);
482 for (i = 0; i < 256; i++) {
489 spin_unlock(&dasd_devmap_lock);
502 spin_lock(&dasd_devmap_lock);
504 for (i = 0; (i < 256) && !devmap; i++)
511 if (devmap && devmap->
device) {
513 dasd_get_device(device);
515 device = ERR_PTR(-
ENODEV);
516 spin_unlock(&dasd_devmap_lock);
529 devmap = dasd_find_busid(dev_name(&cdev->
dev));
531 devmap = dasd_add_busid(dev_name(&cdev->
dev),
547 devmap = dasd_devmap_from_cdev(cdev);
549 return (
void *) devmap;
556 spin_lock(&dasd_devmap_lock);
567 spin_unlock(&dasd_devmap_lock);
598 devmap = dasd_find_busid(dev_name(&device->
cdev->dev));
600 spin_lock(&dasd_devmap_lock);
601 if (devmap->
device != device) {
602 spin_unlock(&dasd_devmap_lock);
603 dasd_put_device(device);
607 spin_unlock(&dasd_devmap_lock);
657 dasd_get_device(device);
680 devmap = dasd_find_busid(dev_name(&device->
cdev->dev));
683 spin_lock(&dasd_devmap_lock);
684 gdp->private_data = devmap;
685 spin_unlock(&dasd_devmap_lock);
693 if (!gdp->private_data)
696 spin_lock(&dasd_devmap_lock);
697 devmap = gdp->private_data;
698 if (devmap && devmap->
device) {
700 dasd_get_device(device);
702 spin_unlock(&dasd_devmap_lock);
719 devmap = dasd_find_busid(dev_name(dev));
728 const char *buf,
size_t count)
734 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
736 return PTR_ERR(devmap);
739 if (((endp + 1) < (buf + count)) || (val > 1))
742 spin_lock(&dasd_devmap_lock);
749 spin_unlock(&dasd_devmap_lock);
753 static DEVICE_ATTR(failfast, 0644, dasd_ff_show, dasd_ff_store);
764 devmap = dasd_find_busid(dev_name(dev));
774 const char *buf,
size_t count)
781 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
783 return PTR_ERR(devmap);
786 if (((endp + 1) < (buf + count)) || (val > 1))
789 spin_lock(&dasd_devmap_lock);
799 spin_unlock(&dasd_devmap_lock);
800 if (device && device->
block && device->
block->gdp)
811 dasd_erplog_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
816 devmap = dasd_find_busid(dev_name(dev));
826 const char *buf,
size_t count)
832 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
834 return PTR_ERR(devmap);
837 if (((endp + 1) < (buf + count)) || (val > 1))
840 spin_lock(&dasd_devmap_lock);
847 spin_unlock(&dasd_devmap_lock);
851 static DEVICE_ATTR(erplog, 0644, dasd_erplog_show, dasd_erplog_store);
858 dasd_use_diag_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
863 devmap = dasd_find_busid(dev_name(dev));
868 return sprintf(buf, use_diag ?
"1\n" :
"0\n");
873 const char *buf,
size_t count)
880 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
882 return PTR_ERR(devmap);
885 if (((endp + 1) < (buf + count)) || (val > 1))
888 spin_lock(&dasd_devmap_lock);
898 spin_unlock(&dasd_devmap_lock);
902 static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
909 dasd_use_raw_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
914 devmap = dasd_find_busid(dev_name(dev));
919 return sprintf(buf, use_raw ?
"1\n" :
"0\n");
924 const char *buf,
size_t count)
930 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
932 return PTR_ERR(devmap);
937 spin_lock(&dasd_devmap_lock);
947 spin_unlock(&dasd_devmap_lock);
951 static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
965 dasd_put_device(device);
970 dasd_put_device(device);
988 if (!IS_ERR(device)) {
989 switch (device->
state) {
1012 dasd_put_device(device);
1020 static ssize_t dasd_alias_show(
struct device *dev,
1030 if (device->discipline && device->discipline->get_uid &&
1031 !device->discipline->get_uid(device, &
uid)) {
1034 dasd_put_device(device);
1038 dasd_put_device(device);
1045 static ssize_t dasd_vendor_show(
struct device *dev,
1059 vendor =
uid.vendor;
1061 dasd_put_device(device);
1068 #define UID_STRLEN ( 3 + 1 + 14 + 1 +\
1073 dasd_uid_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
1086 !device->
discipline->get_uid(device, &uid)) {
1089 snprintf(ua_string,
sizeof(ua_string),
"%02x",
1093 snprintf(ua_string,
sizeof(ua_string),
"%02x",
1097 snprintf(ua_string,
sizeof(ua_string),
"xx");
1101 snprintf(ua_string,
sizeof(ua_string),
"%02x",
1107 snprintf(uid_string,
sizeof(uid_string),
1112 snprintf(uid_string,
sizeof(uid_string),
1116 dasd_put_device(device);
1126 dasd_eer_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
1131 devmap = dasd_find_busid(dev_name(dev));
1132 if (!IS_ERR(devmap) && devmap->
device)
1141 const char *buf,
size_t count)
1147 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
1149 return PTR_ERR(devmap);
1154 if (((endp + 1) < (buf + count)) || (val > 1))
1166 static DEVICE_ATTR(eer_enabled, 0644, dasd_eer_show, dasd_eer_store);
1172 dasd_expires_show(
struct device *dev,
struct device_attribute *attr,
char *buf)
1181 dasd_put_device(device);
1187 const char *buf,
size_t count)
1198 dasd_put_device(device);
1205 dasd_put_device(device);
1209 static DEVICE_ATTR(expires, 0644, dasd_expires_show, dasd_expires_store);
1211 static ssize_t dasd_reservation_policy_show(
struct device *dev,
1218 devmap = dasd_find_busid(dev_name(dev));
1219 if (IS_ERR(devmap)) {
1222 spin_lock(&dasd_devmap_lock);
1227 spin_unlock(&dasd_devmap_lock);
1232 static ssize_t dasd_reservation_policy_store(
struct device *dev,
1234 const char *buf,
size_t count)
1239 devmap = dasd_devmap_from_cdev(
to_ccwdev(dev));
1241 return PTR_ERR(devmap);
1243 spin_lock(&dasd_devmap_lock);
1252 spin_unlock(&dasd_devmap_lock);
1260 dasd_reservation_policy_show, dasd_reservation_policy_store);
1262 static ssize_t dasd_reservation_state_show(
struct device *dev,
1279 dasd_put_device(device);
1283 static ssize_t dasd_reservation_state_store(
struct device *dev,
1285 const char *buf,
size_t count)
1297 dasd_put_device(device);
1305 static DEVICE_ATTR(last_known_reservation_state, 0644,
1306 dasd_reservation_state_show, dasd_reservation_state_store);
1308 static struct attribute * dasd_attrs[] = {
1309 &dev_attr_readonly.attr,
1310 &dev_attr_discipline.attr,
1311 &dev_attr_status.attr,
1312 &dev_attr_alias.attr,
1313 &dev_attr_vendor.attr,
1315 &dev_attr_use_diag.attr,
1316 &dev_attr_raw_track_access.attr,
1317 &dev_attr_eer_enabled.attr,
1318 &dev_attr_erplog.attr,
1319 &dev_attr_failfast.attr,
1320 &dev_attr_expires.attr,
1321 &dev_attr_reservation_policy.attr,
1322 &dev_attr_last_known_reservation_state.attr,
1327 .attrs = dasd_attrs,
1338 devmap = dasd_find_busid(dev_name(&cdev->
dev));
1340 return PTR_ERR(devmap);
1342 return ((devmap->
features & feature) != 0);
1354 devmap = dasd_find_busid(dev_name(&cdev->
dev));
1356 return PTR_ERR(devmap);
1358 spin_lock(&dasd_devmap_lock);
1365 spin_unlock(&dasd_devmap_lock);
1390 for (i = 0; i < 256; i++)
1391 INIT_LIST_HEAD(&dasd_hashlists[i]);
1398 dasd_forget_ranges();