aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r--drivers/s390/block/dasd_devmap.c102
1 files changed, 83 insertions, 19 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 216bc4fba199..9e9ae7179602 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -27,7 +27,7 @@
27#include "dasd_int.h" 27#include "dasd_int.h"
28 28
29kmem_cache_t *dasd_page_cache; 29kmem_cache_t *dasd_page_cache;
30EXPORT_SYMBOL(dasd_page_cache); 30EXPORT_SYMBOL_GPL(dasd_page_cache);
31 31
32/* 32/*
33 * dasd_devmap_t is used to store the features and the relation 33 * dasd_devmap_t is used to store the features and the relation
@@ -49,6 +49,20 @@ struct dasd_devmap {
49}; 49};
50 50
51/* 51/*
52 * dasd_servermap is used to store the server_id of all storage servers
53 * accessed by DASD device driver.
54 */
55struct dasd_servermap {
56 struct list_head list;
57 struct server_id {
58 char vendor[4];
59 char serial[15];
60 } sid;
61};
62
63static struct list_head dasd_serverlist;
64
65/*
52 * Parameter parsing functions for dasd= parameter. The syntax is: 66 * Parameter parsing functions for dasd= parameter. The syntax is:
53 * <devno> : (0x)?[0-9a-fA-F]+ 67 * <devno> : (0x)?[0-9a-fA-F]+
54 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ 68 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
@@ -64,6 +78,8 @@ struct dasd_devmap {
64 78
65int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 79int dasd_probeonly = 0; /* is true, when probeonly mode is active */
66int dasd_autodetect = 0; /* is true, when autodetection is active */ 80int dasd_autodetect = 0; /* is true, when autodetection is active */
81int dasd_nopav = 0; /* is true, when PAV is disabled */
82EXPORT_SYMBOL_GPL(dasd_nopav);
67 83
68/* 84/*
69 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 85 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -123,7 +139,7 @@ static inline int
123dasd_busid(char **str, int *id0, int *id1, int *devno) 139dasd_busid(char **str, int *id0, int *id1, int *devno)
124{ 140{
125 int val, old_style; 141 int val, old_style;
126 142
127 /* check for leading '0x' */ 143 /* check for leading '0x' */
128 old_style = 0; 144 old_style = 0;
129 if ((*str)[0] == '0' && (*str)[1] == 'x') { 145 if ((*str)[0] == '0' && (*str)[1] == 'x') {
@@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp)
179 features = 0; 195 features = 0;
180 196
181 while (1) { 197 while (1) {
182 for (len = 0; 198 for (len = 0;
183 str[len] && str[len] != ':' && str[len] != ')'; len++); 199 str[len] && str[len] != ':' && str[len] != ')'; len++);
184 if (len == 2 && !strncmp(str, "ro", 2)) 200 if (len == 2 && !strncmp(str, "ro", 2))
185 features |= DASD_FEATURE_READONLY; 201 features |= DASD_FEATURE_READONLY;
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) {
228 length = strlen(parsestring); 244 length = strlen(parsestring);
229 residual_str = parsestring + length; 245 residual_str = parsestring + length;
230 } 246 }
231 if (strncmp ("autodetect", parsestring, length) == 0) { 247 if (strncmp("autodetect", parsestring, length) == 0) {
232 dasd_autodetect = 1; 248 dasd_autodetect = 1;
233 MESSAGE (KERN_INFO, "%s", 249 MESSAGE (KERN_INFO, "%s",
234 "turning to autodetection mode"); 250 "turning to autodetection mode");
235 return residual_str; 251 return residual_str;
236 } 252 }
237 if (strncmp ("probeonly", parsestring, length) == 0) { 253 if (strncmp("probeonly", parsestring, length) == 0) {
238 dasd_probeonly = 1; 254 dasd_probeonly = 1;
239 MESSAGE(KERN_INFO, "%s", 255 MESSAGE(KERN_INFO, "%s",
240 "turning to probeonly mode"); 256 "turning to probeonly mode");
241 return residual_str; 257 return residual_str;
242 } 258 }
243 if (strncmp ("fixedbuffers", parsestring, length) == 0) { 259 if (strncmp("nopav", parsestring, length) == 0) {
260 dasd_nopav = 1;
261 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
262 return residual_str;
263 }
264 if (strncmp("fixedbuffers", parsestring, length) == 0) {
244 if (dasd_page_cache) 265 if (dasd_page_cache)
245 return residual_str; 266 return residual_str;
246 dasd_page_cache = 267 dasd_page_cache =
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) {
294 features = dasd_feature_list(str, &str); 315 features = dasd_feature_list(str, &str);
295 if (features < 0) 316 if (features < 0)
296 return ERR_PTR(-EINVAL); 317 return ERR_PTR(-EINVAL);
318 /* each device in dasd= parameter should be set initially online */
319 features |= DASD_FEATURE_INITIAL_ONLINE;
297 while (from <= to) { 320 while (from <= to) {
298 sprintf(bus_id, "%01x.%01x.%04x", 321 sprintf(bus_id, "%01x.%01x.%04x",
299 from_id0, from_id1, from++); 322 from_id0, from_id1, from++);
@@ -359,7 +382,7 @@ dasd_parse(void)
359 * Add a devmap for the device specified by busid. It is possible that 382 * Add a devmap for the device specified by busid. It is possible that
360 * the devmap already exists (dasd= parameter). The order of the devices 383 * the devmap already exists (dasd= parameter). The order of the devices
361 * added through this function will define the kdevs for the individual 384 * added through this function will define the kdevs for the individual
362 * devices. 385 * devices.
363 */ 386 */
364static struct dasd_devmap * 387static struct dasd_devmap *
365dasd_add_busid(char *bus_id, int features) 388dasd_add_busid(char *bus_id, int features)
@@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features)
368 int hash; 391 int hash;
369 392
370 new = (struct dasd_devmap *) 393 new = (struct dasd_devmap *)
371 kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); 394 kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL);
372 if (!new) 395 if (!new)
373 return ERR_PTR(-ENOMEM); 396 return ERR_PTR(-ENOMEM);
374 spin_lock(&dasd_devmap_lock); 397 spin_lock(&dasd_devmap_lock);
@@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf)
630} 653}
631 654
632static ssize_t 655static ssize_t
633dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 656dasd_ro_store(struct device *dev, struct device_attribute *attr,
657 const char *buf, size_t count)
634{ 658{
635 struct dasd_devmap *devmap; 659 struct dasd_devmap *devmap;
636 int ro_flag; 660 int ro_flag;
@@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store);
658 * use_diag controls whether the driver should use diag rather than ssch 682 * use_diag controls whether the driver should use diag rather than ssch
659 * to talk to the device 683 * to talk to the device
660 */ 684 */
661static ssize_t 685static ssize_t
662dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) 686dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
663{ 687{
664 struct dasd_devmap *devmap; 688 struct dasd_devmap *devmap;
@@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
673} 697}
674 698
675static ssize_t 699static ssize_t
676dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 700dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
701 const char *buf, size_t count)
677{ 702{
678 struct dasd_devmap *devmap; 703 struct dasd_devmap *devmap;
679 ssize_t rc; 704 ssize_t rc;
@@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha
697 return rc; 722 return rc;
698} 723}
699 724
700static 725static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
701DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store);
702 726
703static ssize_t 727static ssize_t
704dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) 728dasd_discipline_show(struct device *dev, struct device_attribute *attr,
729 char *buf)
705{ 730{
706 struct dasd_devmap *devmap; 731 struct dasd_devmap *devmap;
707 char *dname; 732 char *dname;
@@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = {
834 .attrs = dasd_attrs, 859 .attrs = dasd_attrs,
835}; 860};
836 861
862/*
863 * Check if the related storage server is already contained in the
864 * dasd_serverlist. If server is not contained, create new entry.
865 * Return 0 if server was already in serverlist,
866 * 1 if the server was added successfully
867 * <0 in case of error.
868 */
869static int
870dasd_add_server(struct dasd_uid *uid)
871{
872 struct dasd_servermap *new, *tmp;
873
874 /* check if server is already contained */
875 list_for_each_entry(tmp, &dasd_serverlist, list)
876 // normale cmp?
877 if (strncmp(tmp->sid.vendor, uid->vendor,
878 sizeof(tmp->sid.vendor)) == 0
879 && strncmp(tmp->sid.serial, uid->serial,
880 sizeof(tmp->sid.serial)) == 0)
881 return 0;
882
883 new = (struct dasd_servermap *)
884 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
885 if (!new)
886 return -ENOMEM;
887
888 strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
889 strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
890 list_add(&new->list, &dasd_serverlist);
891 return 1;
892}
893
837 894
838/* 895/*
839 * Return copy of the device unique identifier. 896 * Return copy of the device unique identifier.
@@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
854 911
855/* 912/*
856 * Register the given device unique identifier into devmap struct. 913 * Register the given device unique identifier into devmap struct.
914 * Return 0 if server was already in serverlist,
915 * 1 if the server was added successful
916 * <0 in case of error.
857 */ 917 */
858int 918int
859dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 919dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
860{ 920{
861 struct dasd_devmap *devmap; 921 struct dasd_devmap *devmap;
922 int rc;
862 923
863 devmap = dasd_find_busid(cdev->dev.bus_id); 924 devmap = dasd_find_busid(cdev->dev.bus_id);
864 if (IS_ERR(devmap)) 925 if (IS_ERR(devmap))
865 return PTR_ERR(devmap); 926 return PTR_ERR(devmap);
866 spin_lock(&dasd_devmap_lock); 927 spin_lock(&dasd_devmap_lock);
867 devmap->uid = *uid; 928 devmap->uid = *uid;
929 rc = dasd_add_server(uid);
868 spin_unlock(&dasd_devmap_lock); 930 spin_unlock(&dasd_devmap_lock);
869 return 0; 931 return rc;
870} 932}
871EXPORT_SYMBOL(dasd_set_uid); 933EXPORT_SYMBOL_GPL(dasd_set_uid);
872 934
873/* 935/*
874 * Return value of the specified feature. 936 * Return value of the specified feature.
@@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
880 942
881 devmap = dasd_find_busid(cdev->dev.bus_id); 943 devmap = dasd_find_busid(cdev->dev.bus_id);
882 if (IS_ERR(devmap)) 944 if (IS_ERR(devmap))
883 return (int) PTR_ERR(devmap); 945 return PTR_ERR(devmap);
884 946
885 return ((devmap->features & feature) != 0); 947 return ((devmap->features & feature) != 0);
886} 948}
@@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
896 958
897 devmap = dasd_find_busid(cdev->dev.bus_id); 959 devmap = dasd_find_busid(cdev->dev.bus_id);
898 if (IS_ERR(devmap)) 960 if (IS_ERR(devmap))
899 return (int) PTR_ERR(devmap); 961 return PTR_ERR(devmap);
900 962
901 spin_lock(&dasd_devmap_lock); 963 spin_lock(&dasd_devmap_lock);
902 if (flag) 964 if (flag)
@@ -932,8 +994,10 @@ dasd_devmap_init(void)
932 dasd_max_devindex = 0; 994 dasd_max_devindex = 0;
933 for (i = 0; i < 256; i++) 995 for (i = 0; i < 256; i++)
934 INIT_LIST_HEAD(&dasd_hashlists[i]); 996 INIT_LIST_HEAD(&dasd_hashlists[i]);
935 return 0;
936 997
998 /* Initialize servermap structure. */
999 INIT_LIST_HEAD(&dasd_serverlist);
1000 return 0;
937} 1001}
938 1002
939void 1003void