X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fide%2Fide-tape.c;h=f04791a58df0b0784e3e754cad9a0275034f0712;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=5a3dc46008e64895fd5ccbe5e48dd3d32bd7a079;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 5a3dc4600..f04791a58 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -433,6 +433,7 @@ #include #include #include +#include #include #include #include @@ -443,6 +444,7 @@ #include #include #include +#include #include #include @@ -1011,7 +1013,9 @@ typedef struct ide_tape_obj { int debug_level; } idetape_tape_t; -static DECLARE_MUTEX(idetape_ref_sem); +static DEFINE_MUTEX(idetape_ref_mutex); + +static struct class *idetape_sysfs_class; #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) @@ -1022,11 +1026,11 @@ static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) { struct ide_tape_obj *tape = NULL; - down(&idetape_ref_sem); + mutex_lock(&idetape_ref_mutex); tape = ide_tape_g(disk); if (tape) kref_get(&tape->kref); - up(&idetape_ref_sem); + mutex_unlock(&idetape_ref_mutex); return tape; } @@ -1034,9 +1038,9 @@ static void ide_tape_release(struct kref *); static void ide_tape_put(struct ide_tape_obj *tape) { - down(&idetape_ref_sem); + mutex_lock(&idetape_ref_mutex); kref_put(&tape->kref, ide_tape_release); - up(&idetape_ref_sem); + mutex_unlock(&idetape_ref_mutex); } /* @@ -1288,11 +1292,11 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) { struct ide_tape_obj *tape = NULL; - down(&idetape_ref_sem); + mutex_lock(&idetape_ref_mutex); tape = idetape_devs[i]; if (tape) kref_get(&tape->kref); - up(&idetape_ref_sem); + mutex_unlock(&idetape_ref_mutex); return tape; } @@ -2333,7 +2337,7 @@ static ide_startstop_t idetape_rw_callback (ide_drive_t *drive) } if (time_after(jiffies, tape->insert_time)) tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); - if (jiffies - tape->avg_time >= HZ) { + if (time_after_eq(jiffies, tape->avg_time + HZ)) { tape->avg_speed = tape->avg_size * HZ / (jiffies - tape->avg_time) / 1024; tape->avg_size = 0; tape->avg_time = jiffies; @@ -2494,7 +2498,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, } else { return ide_do_reset(drive); } - } else if (jiffies - tape->dsc_polling_start > IDETAPE_DSC_MA_THRESHOLD) + } else if (time_after(jiffies, tape->dsc_polling_start + IDETAPE_DSC_MA_THRESHOLD)) tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW; idetape_postpone_request(drive); return ide_stopped; @@ -2903,8 +2907,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) } else if (!(tape->sense_key == 2 && tape->asc == 4 && (tape->ascq == 1 || tape->ascq == 8))) return -EIO; - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(HZ / 10); + msleep(100); } return -EIO; } @@ -4681,9 +4684,8 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) idetape_add_settings(drive); } -static int ide_tape_remove(struct device *dev) +static void ide_tape_remove(ide_drive_t *drive) { - ide_drive_t *drive = to_ide_device(dev); idetape_tape_t *tape = drive->driver_data; ide_unregister_subdriver(drive, tape->driver); @@ -4691,8 +4693,6 @@ static int ide_tape_remove(struct device *dev) ide_unregister_region(tape->disk); ide_tape_put(tape); - - return 0; } static void ide_tape_release(struct kref *kref) @@ -4705,6 +4705,10 @@ static void ide_tape_release(struct kref *kref) drive->dsc_overlap = 0; drive->driver_data = NULL; + class_device_destroy(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, tape->minor)); + class_device_destroy(idetape_sysfs_class, + MKDEV(IDETAPE_MAJOR, tape->minor + 128)); devfs_remove("%s/mt", drive->devfs_name); devfs_remove("%s/mtn", drive->devfs_name); devfs_unregister_tape(g->number); @@ -4740,16 +4744,16 @@ static ide_proc_entry_t idetape_proc[] = { #endif -static int ide_tape_probe(struct device *); +static int ide_tape_probe(ide_drive_t *); static ide_driver_t idetape_driver = { - .owner = THIS_MODULE, .gen_driver = { + .owner = THIS_MODULE, .name = "ide-tape", .bus = &ide_bus_type, - .probe = ide_tape_probe, - .remove = ide_tape_remove, }, + .probe = ide_tape_probe, + .remove = ide_tape_remove, .version = IDETAPE_VERSION, .media = ide_tape, .supports_dsc_overlap = 1, @@ -4820,9 +4824,8 @@ static struct block_device_operations idetape_block_ops = { .ioctl = idetape_ioctl, }; -static int ide_tape_probe(struct device *dev) +static int ide_tape_probe(ide_drive_t *drive) { - ide_drive_t *drive = to_ide_device(dev); idetape_tape_t *tape; struct gendisk *g; int minor; @@ -4845,7 +4848,7 @@ static int ide_tape_probe(struct device *dev) printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name); printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n"); } - tape = (idetape_tape_t *) kmalloc (sizeof (idetape_tape_t), GFP_KERNEL); + tape = (idetape_tape_t *) kzalloc (sizeof (idetape_tape_t), GFP_KERNEL); if (tape == NULL) { printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); goto failed; @@ -4859,8 +4862,6 @@ static int ide_tape_probe(struct device *dev) ide_register_subdriver(drive, &idetape_driver); - memset(tape, 0, sizeof(*tape)); - kref_init(&tape->kref); tape->drive = drive; @@ -4871,14 +4872,19 @@ static int ide_tape_probe(struct device *dev) drive->driver_data = tape; - down(&idetape_ref_sem); + mutex_lock(&idetape_ref_mutex); for (minor = 0; idetape_devs[minor]; minor++) ; idetape_devs[minor] = tape; - up(&idetape_ref_sem); + mutex_unlock(&idetape_ref_mutex); idetape_setup(drive, tape, minor); + class_device_create(idetape_sysfs_class, NULL, + MKDEV(IDETAPE_MAJOR, minor), &drive->gendev, "%s", tape->name); + class_device_create(idetape_sysfs_class, NULL, + MKDEV(IDETAPE_MAJOR, minor + 128), &drive->gendev, "n%s", tape->name); + devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor), S_IFCHR | S_IRUGO | S_IWUGO, "%s/mt", drive->devfs_name); @@ -4904,21 +4910,42 @@ MODULE_LICENSE("GPL"); static void __exit idetape_exit (void) { driver_unregister(&idetape_driver.gen_driver); + class_destroy(idetape_sysfs_class); unregister_chrdev(IDETAPE_MAJOR, "ht"); } -/* - * idetape_init will register the driver for each tape. - */ -static int idetape_init (void) +static int __init idetape_init(void) { + int error = 1; + idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape"); + if (IS_ERR(idetape_sysfs_class)) { + idetape_sysfs_class = NULL; + printk(KERN_ERR "Unable to create sysfs class for ide tapes\n"); + error = -EBUSY; + goto out; + } + if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); - return -EBUSY; + error = -EBUSY; + goto out_free_class; } - return driver_register(&idetape_driver.gen_driver); + + error = driver_register(&idetape_driver.gen_driver); + if (error) + goto out_free_driver; + + return 0; + +out_free_driver: + driver_unregister(&idetape_driver.gen_driver); +out_free_class: + class_destroy(idetape_sysfs_class); +out: + return error; } +MODULE_ALIAS("ide:*m-tape*"); module_init(idetape_init); module_exit(idetape_exit); MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);