aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2006-06-29 09:08:18 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-06-29 09:08:18 -0400
commit405455734e1cdec09c37233216f9240cb1a058e5 (patch)
tree36e88909f646b635117041b19a851031fc8ffb41 /drivers/s390/block/dasd_devmap.c
parent8f27766a883149926e7c1f69d9f1d8f68efcd65f (diff)
[S390] add PAV support to the dasd driver.
Add support for parallel-access-volumes to the dasd driver. This allows concurrent access to dasd devices with multiple channel programs. Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r--drivers/s390/block/dasd_devmap.c80
1 files changed, 71 insertions, 9 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 672e50314b12..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
@@ -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++);
@@ -836,6 +859,38 @@ static struct attribute_group dasd_attr_group = {
836 .attrs = dasd_attrs, 859 .attrs = dasd_attrs,
837}; 860};
838 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
839 894
840/* 895/*
841 * Return copy of the device unique identifier. 896 * Return copy of the device unique identifier.
@@ -856,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
856 911
857/* 912/*
858 * 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.
859 */ 917 */
860int 918int
861dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 919dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
862{ 920{
863 struct dasd_devmap *devmap; 921 struct dasd_devmap *devmap;
922 int rc;
864 923
865 devmap = dasd_find_busid(cdev->dev.bus_id); 924 devmap = dasd_find_busid(cdev->dev.bus_id);
866 if (IS_ERR(devmap)) 925 if (IS_ERR(devmap))
867 return PTR_ERR(devmap); 926 return PTR_ERR(devmap);
868 spin_lock(&dasd_devmap_lock); 927 spin_lock(&dasd_devmap_lock);
869 devmap->uid = *uid; 928 devmap->uid = *uid;
929 rc = dasd_add_server(uid);
870 spin_unlock(&dasd_devmap_lock); 930 spin_unlock(&dasd_devmap_lock);
871 return 0; 931 return rc;
872} 932}
873EXPORT_SYMBOL(dasd_set_uid); 933EXPORT_SYMBOL_GPL(dasd_set_uid);
874 934
875/* 935/*
876 * Return value of the specified feature. 936 * Return value of the specified feature.
@@ -882,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
882 942
883 devmap = dasd_find_busid(cdev->dev.bus_id); 943 devmap = dasd_find_busid(cdev->dev.bus_id);
884 if (IS_ERR(devmap)) 944 if (IS_ERR(devmap))
885 return (int) PTR_ERR(devmap); 945 return PTR_ERR(devmap);
886 946
887 return ((devmap->features & feature) != 0); 947 return ((devmap->features & feature) != 0);
888} 948}
@@ -898,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
898 958
899 devmap = dasd_find_busid(cdev->dev.bus_id); 959 devmap = dasd_find_busid(cdev->dev.bus_id);
900 if (IS_ERR(devmap)) 960 if (IS_ERR(devmap))
901 return (int) PTR_ERR(devmap); 961 return PTR_ERR(devmap);
902 962
903 spin_lock(&dasd_devmap_lock); 963 spin_lock(&dasd_devmap_lock);
904 if (flag) 964 if (flag)
@@ -934,8 +994,10 @@ dasd_devmap_init(void)
934 dasd_max_devindex = 0; 994 dasd_max_devindex = 0;
935 for (i = 0; i < 256; i++) 995 for (i = 0; i < 256; i++)
936 INIT_LIST_HEAD(&dasd_hashlists[i]); 996 INIT_LIST_HEAD(&dasd_hashlists[i]);
937 return 0;
938 997
998 /* Initialize servermap structure. */
999 INIT_LIST_HEAD(&dasd_serverlist);
1000 return 0;
939} 1001}
940 1002
941void 1003void