]> err.no Git - linux-2.6/blobdiff - drivers/s390/block/dasd_devmap.c
[S390] inaccessible PAV alias devices on LPAR.
[linux-2.6] / drivers / s390 / block / dasd_devmap.c
index 9e9ae71796028162b94d45316776ec2b2f7f0d6b..9d0c6e1a0e664a87beb7764eb32653ff8c1614fc 100644 (file)
@@ -13,7 +13,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -49,18 +48,20 @@ struct dasd_devmap {
 };
 
 /*
- * dasd_servermap is used to store the server_id of all storage servers
- * accessed by DASD device driver.
+ * dasd_server_ssid_map contains a globally unique storage server subsystem ID.
+ * dasd_server_ssid_list contains the list of all subsystem IDs accessed by
+ * the DASD device driver.
  */
-struct dasd_servermap {
+struct dasd_server_ssid_map {
        struct list_head list;
        struct server_id {
                char vendor[4];
                char serial[15];
        } sid;
+       __u16 ssid;
 };
 
-static struct list_head dasd_serverlist;
+static struct list_head dasd_server_ssid_list;
 
 /*
  * Parameter parsing functions for dasd= parameter. The syntax is:
@@ -90,7 +91,7 @@ static char *dasd[256];
 module_param_array(dasd, charp, NULL, 0);
 
 /*
- * Single spinlock to protect devmap structures and lists.
+ * Single spinlock to protect devmap and servermap structures and lists.
  */
 static DEFINE_SPINLOCK(dasd_devmap_lock);
 
@@ -265,8 +266,9 @@ dasd_parse_keyword( char *parsestring ) {
                if (dasd_page_cache)
                        return residual_str;
                dasd_page_cache =
-                       kmem_cache_create("dasd_page_cache", PAGE_SIZE, 0,
-                                         SLAB_CACHE_DMA, NULL, NULL );
+                       kmem_cache_create("dasd_page_cache", PAGE_SIZE,
+                                         PAGE_SIZE, SLAB_CACHE_DMA,
+                                         NULL, NULL );
                if (!dasd_page_cache)
                        MESSAGE(KERN_WARNING, "%s", "Failed to create slab, "
                                "fixed buffer mode disabled.");
@@ -395,7 +397,7 @@ dasd_add_busid(char *bus_id, int features)
        if (!new)
                return ERR_PTR(-ENOMEM);
        spin_lock(&dasd_devmap_lock);
-       devmap = 0;
+       devmap = NULL;
        hash = dasd_hash_busid(bus_id);
        list_for_each_entry(tmp, &dasd_hashlists[hash], list)
                if (strncmp(tmp->bus_id, bus_id, BUS_ID_SIZE) == 0) {
@@ -407,10 +409,10 @@ dasd_add_busid(char *bus_id, int features)
                new->devindex = dasd_max_devindex++;
                strncpy(new->bus_id, bus_id, BUS_ID_SIZE);
                new->features = features;
-               new->device = 0;
+               new->device = NULL;
                list_add(&new->list, &dasd_hashlists[hash]);
                devmap = new;
-               new = 0;
+               new = NULL;
        }
        spin_unlock(&dasd_devmap_lock);
        kfree(new);
@@ -480,7 +482,7 @@ dasd_device_from_devindex(int devindex)
        int i;
 
        spin_lock(&dasd_devmap_lock);
-       devmap = 0;
+       devmap = NULL;
        for (i = 0; (i < 256) && !devmap; i++)
                list_for_each_entry(tmp, &dasd_hashlists[i], list)
                        if (tmp->devindex == devindex) {
@@ -859,39 +861,6 @@ static struct attribute_group dasd_attr_group = {
        .attrs = dasd_attrs,
 };
 
-/*
- * Check if the related storage server is already contained in the
- * dasd_serverlist. If server is not contained, create new entry.
- * Return 0 if server was already in serverlist,
- *       1 if the server was added successfully
- *      <0 in case of error.
- */
-static int
-dasd_add_server(struct dasd_uid *uid)
-{
-       struct dasd_servermap *new, *tmp;
-
-       /* check if server is already contained */
-       list_for_each_entry(tmp, &dasd_serverlist, list)
-         // normale cmp?
-               if (strncmp(tmp->sid.vendor, uid->vendor,
-                           sizeof(tmp->sid.vendor)) == 0
-                   && strncmp(tmp->sid.serial, uid->serial,
-                              sizeof(tmp->sid.serial)) == 0)
-                       return 0;
-
-       new = (struct dasd_servermap *)
-               kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
-       if (!new)
-               return -ENOMEM;
-
-       strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
-       strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
-       list_add(&new->list, &dasd_serverlist);
-       return 1;
-}
-
-
 /*
  * Return copy of the device unique identifier.
  */
@@ -911,6 +880,9 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
 
 /*
  * Register the given device unique identifier into devmap struct.
+ * In addition check if the related storage server subsystem ID is already
+ * contained in the dasd_server_ssid_list. If subsystem ID is not contained,
+ * create new entry.
  * Return 0 if server was already in serverlist,
  *       1 if the server was added successful
  *      <0 in case of error.
@@ -919,16 +891,39 @@ int
 dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
 {
        struct dasd_devmap *devmap;
-       int rc;
+       struct dasd_server_ssid_map *srv, *tmp;
 
        devmap = dasd_find_busid(cdev->dev.bus_id);
        if (IS_ERR(devmap))
                return PTR_ERR(devmap);
+
+       /* generate entry for server_ssid_map */
+       srv = (struct dasd_server_ssid_map *)
+               kzalloc(sizeof(struct dasd_server_ssid_map), GFP_KERNEL);
+       if (!srv)
+               return -ENOMEM;
+       strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1);
+       strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1);
+       srv->ssid = uid->ssid;
+
+       /* server is already contained ? */
        spin_lock(&dasd_devmap_lock);
        devmap->uid = *uid;
-       rc = dasd_add_server(uid);
+       list_for_each_entry(tmp, &dasd_server_ssid_list, list) {
+               if (!memcmp(&srv->sid, &tmp->sid,
+                           sizeof(struct dasd_server_ssid_map))) {
+                       kfree(srv);
+                       srv = NULL;
+                       break;
+               }
+       }
+
+       /* add servermap to serverlist */
+       if (srv)
+               list_add(&srv->list, &dasd_server_ssid_list);
        spin_unlock(&dasd_devmap_lock);
-       return rc;
+
+       return (srv ? 1 : 0);
 }
 EXPORT_SYMBOL_GPL(dasd_set_uid);
 
@@ -996,7 +991,7 @@ dasd_devmap_init(void)
                INIT_LIST_HEAD(&dasd_hashlists[i]);
 
        /* Initialize servermap structure. */
-       INIT_LIST_HEAD(&dasd_serverlist);
+       INIT_LIST_HEAD(&dasd_server_ssid_list);
        return 0;
 }