]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/block/dcssblk.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[linux-2.6-omap-h63xx.git] / drivers / s390 / block / dcssblk.c
index 44133250da2eeddb5252d244224607d333c4a5a0..15a5789b773425ba35a0ee0e6f43b8bf18866872 100644 (file)
@@ -102,7 +102,7 @@ dcssblk_release_segment(struct device *dev)
  * device needs to be enqueued before the semaphore is
  * freed.
  */
-static inline int
+static int
 dcssblk_assign_free_minor(struct dcssblk_dev_info *dev_info)
 {
        int minor, found;
@@ -193,6 +193,12 @@ dcssblk_segment_warn(int rc, char* seg_name)
        }
 }
 
+static void dcssblk_unregister_callback(struct device *dev)
+{
+       device_unregister(dev);
+       put_device(dev);
+}
+
 /*
  * device attribute for switching shared/nonshared (exclusive)
  * operation (show + store)
@@ -230,7 +236,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
                                           SEGMENT_SHARED);
                if (rc < 0) {
                        BUG_ON(rc == -EINVAL);
-                       if (rc == -EIO || rc == -ENOENT)
+                       if (rc != -EAGAIN)
                                goto removeseg;
                } else {
                        dev_info->is_shared = 1;
@@ -253,7 +259,7 @@ dcssblk_shared_store(struct device *dev, struct device_attribute *attr, const ch
                                           SEGMENT_EXCLUSIVE);
                if (rc < 0) {
                        BUG_ON(rc == -EINVAL);
-                       if (rc == -EIO || rc == -ENOENT)
+                       if (rc != -EAGAIN)
                                goto removeseg;
                } else {
                        dev_info->is_shared = 0;
@@ -276,8 +282,7 @@ removeseg:
        blk_cleanup_queue(dev_info->dcssblk_queue);
        dev_info->gd->queue = NULL;
        put_disk(dev_info->gd);
-       device_unregister(dev);
-       put_device(dev);
+       rc = device_schedule_callback(dev, dcssblk_unregister_callback);
 out:
        up_write(&dcssblk_devices_sem);
        return rc;
@@ -388,12 +393,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
        /*
         * get a struct dcssblk_dev_info
         */
-       dev_info = kmalloc(sizeof(struct dcssblk_dev_info), GFP_KERNEL);
+       dev_info = kzalloc(sizeof(struct dcssblk_dev_info), GFP_KERNEL);
        if (dev_info == NULL) {
                rc = -ENOMEM;
                goto out;
        }
-       memset(dev_info, 0, sizeof(struct dcssblk_dev_info));
 
        strcpy(dev_info->segment_name, local_buf);
        strlcpy(dev_info->dev.bus_id, local_buf, BUS_ID_SIZE);
@@ -468,11 +472,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
        if (rc)
                goto unregister_dev;
 
-       add_disk(dev_info->gd);
-
        blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request);
        blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096);
 
+       add_disk(dev_info->gd);
+
        switch (dev_info->segment_type) {
                case SEG_TYPE_SR:
                case SEG_TYPE_ER:
@@ -622,7 +626,7 @@ out:
 }
 
 static int
-dcssblk_make_request(request_queue_t *q, struct bio *bio)
+dcssblk_make_request(struct request_queue *q, struct bio *bio)
 {
        struct dcssblk_dev_info *dev_info;
        struct bio_vec *bvec;
@@ -675,10 +679,10 @@ dcssblk_make_request(request_queue_t *q, struct bio *bio)
                }
                bytes_done += bvec->bv_len;
        }
-       bio_endio(bio, bytes_done, 0);
+       bio_endio(bio, 0);
        return 0;
 fail:
-       bio_io_error(bio, bio->bi_size);
+       bio_io_error(bio);
        return 0;
 }
 
@@ -748,14 +752,9 @@ dcssblk_check_params(void)
 static void __exit
 dcssblk_exit(void)
 {
-       int rc;
-
        PRINT_DEBUG("DCSSBLOCK EXIT...\n");
        s390_root_dev_unregister(dcssblk_root_dev);
-       rc = unregister_blkdev(dcssblk_major, DCSSBLK_NAME);
-       if (rc) {
-               PRINT_ERR("unregister_blkdev() failed!\n");
-       }
+       unregister_blkdev(dcssblk_major, DCSSBLK_NAME);
        PRINT_DEBUG("...finished!\n");
 }