X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fide%2Fide-gd.c;h=214119026b3f4e55eec0c0eb1f60898ecc62e047;hb=22a0d6f1383c85a7a9759cb805fd06c848c9c4d3;hp=cae82b3c432a80a2d1d5861afd774ba620916171;hpb=7f3c868ba78e486bd9d7569f884dd46d8f59bb18;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index cae82b3..2141190 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -7,6 +7,7 @@ #include #include #include +#include #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) #define IDE_DISK_MINORS (1 << PARTN_BITS) @@ -25,7 +26,7 @@ module_param(debug_mask, ulong, 0644); static DEFINE_MUTEX(ide_disk_ref_mutex); -static void ide_disk_release(struct kref *); +static void ide_disk_release(struct device *); static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { @@ -37,7 +38,7 @@ static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) if (ide_device_get(idkp->drive)) idkp = NULL; else - kref_get(&idkp->kref); + get_device(&idkp->dev); } mutex_unlock(&ide_disk_ref_mutex); return idkp; @@ -48,7 +49,7 @@ static void ide_disk_put(struct ide_disk_obj *idkp) ide_drive_t *drive = idkp->drive; mutex_lock(&ide_disk_ref_mutex); - kref_put(&idkp->kref, ide_disk_release); + put_device(&idkp->dev); ide_device_put(drive); mutex_unlock(&ide_disk_ref_mutex); } @@ -66,17 +67,18 @@ static void ide_gd_remove(ide_drive_t *drive) struct gendisk *g = idkp->disk; ide_proc_unregister_driver(drive, idkp->driver); - + device_del(&idkp->dev); del_gendisk(g); - drive->disk_ops->flush(drive); - ide_disk_put(idkp); + mutex_lock(&ide_disk_ref_mutex); + put_device(&idkp->dev); + mutex_unlock(&ide_disk_ref_mutex); } -static void ide_disk_release(struct kref *kref) +static void ide_disk_release(struct device *dev) { - struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj); + struct ide_disk_obj *idkp = to_ide_drv(dev, ide_disk_obj); ide_drive_t *drive = idkp->drive; struct gendisk *g = idkp->disk; @@ -98,6 +100,19 @@ static void ide_gd_resume(ide_drive_t *drive) (void)drive->disk_ops->get_capacity(drive); } +static const struct dmi_system_id ide_coldreboot_table[] = { + { + /* Acer TravelMate 66x cuts power during reboot */ + .ident = "Acer TravelMate 660", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 660"), + }, + }, + + { } /* terminate list */ +}; + static void ide_gd_shutdown(ide_drive_t *drive) { #ifdef CONFIG_ALPHA @@ -114,7 +129,8 @@ static void ide_gd_shutdown(ide_drive_t *drive) the disk to expire its write cache. */ if (system_state != SYSTEM_POWER_OFF) { #else - if (system_state == SYSTEM_RESTART) { + if (system_state == SYSTEM_RESTART && + !dmi_check_system(ide_coldreboot_table)) { #endif drive->disk_ops->flush(drive); return; @@ -144,11 +160,6 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive, return drive->disk_ops->do_request(drive, rq, sector); } -static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs) -{ - return drive->disk_ops->end_request(drive, uptodate, nrsecs); -} - static struct ide_driver ide_gd_driver = { .gen_driver = { .owner = THIS_MODULE, @@ -161,8 +172,6 @@ static struct ide_driver ide_gd_driver = { .shutdown = ide_gd_shutdown, .version = IDE_GD_VERSION, .do_request = ide_gd_do_request, - .end_request = ide_gd_end_request, - .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_disk_proc_entries, .proc_devsets = ide_disk_proc_devsets, @@ -182,7 +191,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode) drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); idkp->openers++; @@ -232,7 +241,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); ide_drive_t *drive = idkp->drive; - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if (idkp->openers == 1) drive->disk_ops->flush(drive); @@ -278,6 +287,19 @@ static int ide_gd_media_changed(struct gendisk *disk) return ret; } +static unsigned long long ide_gd_set_capacity(struct gendisk *disk, + unsigned long long capacity) +{ + struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); + ide_drive_t *drive = idkp->drive; + const struct ide_disk_ops *disk_ops = drive->disk_ops; + + if (disk_ops->set_capacity) + return disk_ops->set_capacity(drive, capacity); + + return drive->capacity64; +} + static int ide_gd_revalidate_disk(struct gendisk *disk) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); @@ -306,6 +328,7 @@ static struct block_device_operations ide_gd_ops = { .locked_ioctl = ide_gd_ioctl, .getgeo = ide_gd_getgeo, .media_changed = ide_gd_media_changed, + .set_capacity = ide_gd_set_capacity, .revalidate_disk = ide_gd_revalidate_disk }; @@ -349,7 +372,12 @@ static int ide_gd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - kref_init(&idkp->kref); + idkp->dev.parent = &drive->gendev; + idkp->dev.release = ide_disk_release; + dev_set_name(&idkp->dev, dev_name(&drive->gendev)); + + if (device_register(&idkp->dev)) + goto out_free_disk; idkp->drive = drive; idkp->driver = &ide_gd_driver; @@ -374,6 +402,8 @@ static int ide_gd_probe(ide_drive_t *drive) add_disk(g); return 0; +out_free_disk: + put_disk(g); out_free_idkp: kfree(idkp); failed: