diff options
Diffstat (limited to 'drivers/ide/ide-gd.c')
-rw-r--r-- | drivers/ide/ide-gd.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 70aeeb18833e..70ea8763567d 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #include <linux/smp_lock.h> | ||
2 | #include <linux/module.h> | 1 | #include <linux/module.h> |
3 | #include <linux/types.h> | 2 | #include <linux/types.h> |
4 | #include <linux/string.h> | 3 | #include <linux/string.h> |
@@ -23,6 +22,7 @@ | |||
23 | #define IDE_GD_VERSION "1.18" | 22 | #define IDE_GD_VERSION "1.18" |
24 | 23 | ||
25 | /* module parameters */ | 24 | /* module parameters */ |
25 | static DEFINE_MUTEX(ide_gd_mutex); | ||
26 | static unsigned long debug_mask; | 26 | static unsigned long debug_mask; |
27 | module_param(debug_mask, ulong, 0644); | 27 | module_param(debug_mask, ulong, 0644); |
28 | 28 | ||
@@ -242,9 +242,9 @@ static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode) | |||
242 | { | 242 | { |
243 | int ret; | 243 | int ret; |
244 | 244 | ||
245 | lock_kernel(); | 245 | mutex_lock(&ide_gd_mutex); |
246 | ret = ide_gd_open(bdev, mode); | 246 | ret = ide_gd_open(bdev, mode); |
247 | unlock_kernel(); | 247 | mutex_unlock(&ide_gd_mutex); |
248 | 248 | ||
249 | return ret; | 249 | return ret; |
250 | } | 250 | } |
@@ -257,7 +257,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) | |||
257 | 257 | ||
258 | ide_debug_log(IDE_DBG_FUNC, "enter"); | 258 | ide_debug_log(IDE_DBG_FUNC, "enter"); |
259 | 259 | ||
260 | lock_kernel(); | 260 | mutex_lock(&ide_gd_mutex); |
261 | if (idkp->openers == 1) | 261 | if (idkp->openers == 1) |
262 | drive->disk_ops->flush(drive); | 262 | drive->disk_ops->flush(drive); |
263 | 263 | ||
@@ -269,7 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) | |||
269 | idkp->openers--; | 269 | idkp->openers--; |
270 | 270 | ||
271 | ide_disk_put(idkp); | 271 | ide_disk_put(idkp); |
272 | unlock_kernel(); | 272 | mutex_unlock(&ide_gd_mutex); |
273 | 273 | ||
274 | return 0; | 274 | return 0; |
275 | } | 275 | } |
@@ -285,11 +285,12 @@ static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | |||
285 | return 0; | 285 | return 0; |
286 | } | 286 | } |
287 | 287 | ||
288 | static int ide_gd_media_changed(struct gendisk *disk) | 288 | static unsigned int ide_gd_check_events(struct gendisk *disk, |
289 | unsigned int clearing) | ||
289 | { | 290 | { |
290 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | 291 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
291 | ide_drive_t *drive = idkp->drive; | 292 | ide_drive_t *drive = idkp->drive; |
292 | int ret; | 293 | bool ret; |
293 | 294 | ||
294 | /* do not scan partitions twice if this is a removable device */ | 295 | /* do not scan partitions twice if this is a removable device */ |
295 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { | 296 | if (drive->dev_flags & IDE_DFLAG_ATTACH) { |
@@ -297,10 +298,16 @@ static int ide_gd_media_changed(struct gendisk *disk) | |||
297 | return 0; | 298 | return 0; |
298 | } | 299 | } |
299 | 300 | ||
300 | ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED); | 301 | /* |
302 | * The following is used to force revalidation on the first open on | ||
303 | * removeable devices, and never gets reported to userland as | ||
304 | * genhd->events is 0. This is intended as removeable ide disk | ||
305 | * can't really detect MEDIA_CHANGE events. | ||
306 | */ | ||
307 | ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; | ||
301 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; | 308 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
302 | 309 | ||
303 | return ret; | 310 | return ret ? DISK_EVENT_MEDIA_CHANGE : 0; |
304 | } | 311 | } |
305 | 312 | ||
306 | static void ide_gd_unlock_native_capacity(struct gendisk *disk) | 313 | static void ide_gd_unlock_native_capacity(struct gendisk *disk) |
@@ -318,7 +325,7 @@ static int ide_gd_revalidate_disk(struct gendisk *disk) | |||
318 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); | 325 | struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); |
319 | ide_drive_t *drive = idkp->drive; | 326 | ide_drive_t *drive = idkp->drive; |
320 | 327 | ||
321 | if (ide_gd_media_changed(disk)) | 328 | if (ide_gd_check_events(disk, 0)) |
322 | drive->disk_ops->get_capacity(drive); | 329 | drive->disk_ops->get_capacity(drive); |
323 | 330 | ||
324 | set_capacity(disk, ide_gd_capacity(drive)); | 331 | set_capacity(disk, ide_gd_capacity(drive)); |
@@ -340,7 +347,7 @@ static const struct block_device_operations ide_gd_ops = { | |||
340 | .release = ide_gd_release, | 347 | .release = ide_gd_release, |
341 | .ioctl = ide_gd_ioctl, | 348 | .ioctl = ide_gd_ioctl, |
342 | .getgeo = ide_gd_getgeo, | 349 | .getgeo = ide_gd_getgeo, |
343 | .media_changed = ide_gd_media_changed, | 350 | .check_events = ide_gd_check_events, |
344 | .unlock_native_capacity = ide_gd_unlock_native_capacity, | 351 | .unlock_native_capacity = ide_gd_unlock_native_capacity, |
345 | .revalidate_disk = ide_gd_revalidate_disk | 352 | .revalidate_disk = ide_gd_revalidate_disk |
346 | }; | 353 | }; |