X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fs390%2Fblock%2Fdcssblk.c;h=35765f6a86e09c79cd7dd5d6cc49dfa52f3ea0d2;hb=88fb61e4ba263685a0d5b82c7e9cd6f22a9e6a9d;hp=be9b05347b4f9b839bcc75e8a7b57f98e2ad3113;hpb=95d465fd750897ab32462a6702fbfe1b122cbbc0;p=linux-2.6-omap-h63xx.git diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index be9b05347b4..15a5789b773 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -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; @@ -467,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: @@ -621,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; @@ -674,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; } @@ -747,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"); }