diff options
-rw-r--r-- | drivers/s390/block/dasd.c | 21 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 |
2 files changed, 21 insertions, 1 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 08c88fcd8963..06bb992a4c6c 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -156,7 +156,12 @@ dasd_state_known_to_new(struct dasd_device * device) | |||
156 | /* disable extended error reporting for this device */ | 156 | /* disable extended error reporting for this device */ |
157 | dasd_disable_eer(device); | 157 | dasd_disable_eer(device); |
158 | /* Forget the discipline information. */ | 158 | /* Forget the discipline information. */ |
159 | if (device->discipline) | ||
160 | module_put(device->discipline->owner); | ||
159 | device->discipline = NULL; | 161 | device->discipline = NULL; |
162 | if (device->base_discipline) | ||
163 | module_put(device->base_discipline->owner); | ||
164 | device->base_discipline = NULL; | ||
160 | device->state = DASD_STATE_NEW; | 165 | device->state = DASD_STATE_NEW; |
161 | 166 | ||
162 | dasd_free_queue(device); | 167 | dasd_free_queue(device); |
@@ -1880,9 +1885,10 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
1880 | */ | 1885 | */ |
1881 | int | 1886 | int |
1882 | dasd_generic_set_online (struct ccw_device *cdev, | 1887 | dasd_generic_set_online (struct ccw_device *cdev, |
1883 | struct dasd_discipline *discipline) | 1888 | struct dasd_discipline *base_discipline) |
1884 | 1889 | ||
1885 | { | 1890 | { |
1891 | struct dasd_discipline *discipline; | ||
1886 | struct dasd_device *device; | 1892 | struct dasd_device *device; |
1887 | int rc; | 1893 | int rc; |
1888 | 1894 | ||
@@ -1890,6 +1896,7 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1890 | if (IS_ERR(device)) | 1896 | if (IS_ERR(device)) |
1891 | return PTR_ERR(device); | 1897 | return PTR_ERR(device); |
1892 | 1898 | ||
1899 | discipline = base_discipline; | ||
1893 | if (device->features & DASD_FEATURE_USEDIAG) { | 1900 | if (device->features & DASD_FEATURE_USEDIAG) { |
1894 | if (!dasd_diag_discipline_pointer) { | 1901 | if (!dasd_diag_discipline_pointer) { |
1895 | printk (KERN_WARNING | 1902 | printk (KERN_WARNING |
@@ -1901,6 +1908,16 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1901 | } | 1908 | } |
1902 | discipline = dasd_diag_discipline_pointer; | 1909 | discipline = dasd_diag_discipline_pointer; |
1903 | } | 1910 | } |
1911 | if (!try_module_get(base_discipline->owner)) { | ||
1912 | dasd_delete_device(device); | ||
1913 | return -EINVAL; | ||
1914 | } | ||
1915 | if (!try_module_get(discipline->owner)) { | ||
1916 | module_put(base_discipline->owner); | ||
1917 | dasd_delete_device(device); | ||
1918 | return -EINVAL; | ||
1919 | } | ||
1920 | device->base_discipline = base_discipline; | ||
1904 | device->discipline = discipline; | 1921 | device->discipline = discipline; |
1905 | 1922 | ||
1906 | rc = discipline->check_device(device); | 1923 | rc = discipline->check_device(device); |
@@ -1909,6 +1926,8 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1909 | "dasd_generic couldn't online device %s " | 1926 | "dasd_generic couldn't online device %s " |
1910 | "with discipline %s rc=%i\n", | 1927 | "with discipline %s rc=%i\n", |
1911 | cdev->dev.bus_id, discipline->name, rc); | 1928 | cdev->dev.bus_id, discipline->name, rc); |
1929 | module_put(discipline->owner); | ||
1930 | module_put(base_discipline->owner); | ||
1912 | dasd_delete_device(device); | 1931 | dasd_delete_device(device); |
1913 | return rc; | 1932 | return rc; |
1914 | } | 1933 | } |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index d1b08fa13fd2..5efac1b97ece 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -321,6 +321,7 @@ struct dasd_device { | |||
321 | 321 | ||
322 | /* Device discipline stuff. */ | 322 | /* Device discipline stuff. */ |
323 | struct dasd_discipline *discipline; | 323 | struct dasd_discipline *discipline; |
324 | struct dasd_discipline *base_discipline; | ||
324 | char *private; | 325 | char *private; |
325 | 326 | ||
326 | /* Device state and target state. */ | 327 | /* Device state and target state. */ |