]> err.no Git - linux-2.6/blobdiff - drivers/ide/ide-tape.c
Merge with http://kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6] / drivers / ide / ide-tape.c
index 4825448549850d48cb212d5f4bc006be12904988..0ac7eb8f40d537ae04c2db1b23a2d819df835e69 100644 (file)
@@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj {
 
 static DECLARE_MUTEX(idetape_ref_sem);
 
+static struct class *idetape_sysfs_class;
+
 #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
 
 #define ide_tape_g(disk) \
@@ -2903,8 +2905,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,21 +4682,12 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor)
        idetape_add_settings(drive);
 }
 
-static int idetape_cleanup (ide_drive_t *drive)
+static int ide_tape_remove(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape = drive->driver_data;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ide_lock, flags);
-       if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage ||
-           tape->first_stage != NULL || tape->merge_stage_size) {
-               spin_unlock_irqrestore(&ide_lock, flags);
-               return 1;
-       }
 
-       spin_unlock_irqrestore(&ide_lock, flags);
-       DRIVER(drive)->busy = 0;
-       (void) ide_unregister_subdriver(drive);
+       ide_unregister_subdriver(drive, tape->driver);
 
        ide_unregister_region(tape->disk);
 
@@ -4710,8 +4702,14 @@ static void ide_tape_release(struct kref *kref)
        ide_drive_t *drive = tape->drive;
        struct gendisk *g = tape->disk;
 
+       BUG_ON(tape->first_stage != NULL || tape->merge_stage_size);
+
        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);
@@ -4747,26 +4745,24 @@ static ide_proc_entry_t idetape_proc[] = {
 
 #endif
 
-static int idetape_attach(ide_drive_t *drive);
+static int ide_tape_probe(struct device *);
 
-/*
- *     IDE subdriver functions, registered with ide.c
- */
 static ide_driver_t idetape_driver = {
        .owner                  = THIS_MODULE,
-       .name                   = "ide-tape",
+       .gen_driver = {
+               .name           = "ide-tape",
+               .bus            = &ide_bus_type,
+               .probe          = ide_tape_probe,
+               .remove         = ide_tape_remove,
+       },
        .version                = IDETAPE_VERSION,
        .media                  = ide_tape,
-       .busy                   = 1,
        .supports_dsc_overlap   = 1,
-       .cleanup                = idetape_cleanup,
        .do_request             = idetape_do_request,
        .end_request            = idetape_end_request,
        .error                  = __ide_error,
        .abort                  = __ide_abort,
        .proc                   = idetape_proc,
-       .attach                 = idetape_attach,
-       .drives                 = LIST_HEAD_INIT(idetape_driver.drives),
 };
 
 /*
@@ -4829,8 +4825,9 @@ static struct block_device_operations idetape_block_ops = {
        .ioctl          = idetape_ioctl,
 };
 
-static int idetape_attach (ide_drive_t *drive)
+static int ide_tape_probe(struct device *dev)
 {
+       ide_drive_t *drive = to_ide_device(dev);
        idetape_tape_t *tape;
        struct gendisk *g;
        int minor;
@@ -4853,7 +4850,7 @@ static int idetape_attach (ide_drive_t *drive)
                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;
@@ -4865,12 +4862,7 @@ static int idetape_attach (ide_drive_t *drive)
 
        ide_init_disk(g, drive);
 
-       if (ide_register_subdriver(drive, &idetape_driver)) {
-               printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name);
-               goto out_put_disk;
-       }
-
-       memset(tape, 0, sizeof(*tape));
+       ide_register_subdriver(drive, &idetape_driver);
 
        kref_init(&tape->kref);
 
@@ -4890,6 +4882,11 @@ static int idetape_attach (ide_drive_t *drive)
 
        idetape_setup(drive, tape, minor);
 
+       class_device_create(idetape_sysfs_class, NULL,
+                       MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
+       class_device_create(idetape_sysfs_class, NULL,
+                       MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
+
        devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
                        S_IFCHR | S_IRUGO | S_IWUGO,
                        "%s/mt", drive->devfs_name);
@@ -4902,12 +4899,11 @@ static int idetape_attach (ide_drive_t *drive)
        ide_register_region(g);
 
        return 0;
-out_put_disk:
-       put_disk(g);
+
 out_free_tape:
        kfree(tape);
 failed:
-       return 1;
+       return -ENODEV;
 }
 
 MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
@@ -4915,7 +4911,8 @@ MODULE_LICENSE("GPL");
 
 static void __exit idetape_exit (void)
 {
-       ide_unregister_driver(&idetape_driver);
+       driver_unregister(&idetape_driver.gen_driver);
+       class_destroy(idetape_sysfs_class);
        unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 
@@ -4924,12 +4921,33 @@ static void __exit idetape_exit (void)
  */
 static int 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;
        }
-       ide_register_driver(&idetape_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_init(idetape_init);