USB: usbnet: Use usb_endpoint_* functions
[safe/jmp/linux-2.6] / drivers / scsi / st.c
index 13b1d3a..e1a52c5 100644 (file)
@@ -35,7 +35,6 @@ static const char *verstr = "20050830";
 #include <linux/spinlock.h>
 #include <linux/blkdev.h>
 #include <linux/moduleparam.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/cdev.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
@@ -87,8 +86,9 @@ static int st_nr_dev;
 static struct class *st_sysfs_class;
 
 MODULE_AUTHOR("Kai Makisara");
-MODULE_DESCRIPTION("SCSI Tape Driver");
+MODULE_DESCRIPTION("SCSI tape (st) driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR);
 
 /* Set 'perm' (4th argument) to 0 to disable module_param's definition
  * of sysfs parameters (which module_param doesn't yet support).
@@ -195,9 +195,9 @@ static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
 static int st_probe(struct device *);
 static int st_remove(struct device *);
 
-static void do_create_driverfs_files(void);
+static int do_create_driverfs_files(void);
 static void do_remove_driverfs_files(void);
-static void do_create_class_files(struct scsi_tape *, int, int);
+static int do_create_class_files(struct scsi_tape *, int, int);
 
 static struct scsi_driver st_template = {
        .owner                  = THIS_MODULE,
@@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                       SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2],
                       SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]);
                if (cmdstatp->have_sense)
-                        __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
+                        __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
        } ) /* end DEB */
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
@@ -384,9 +384,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt)
                         scode != VOLUME_OVERFLOW &&
                         SRpnt->cmd[0] != MODE_SENSE &&
                         SRpnt->cmd[0] != TEST_UNIT_READY) {
-                               printk(KERN_WARNING "%s: Error with sense data: ", name);
-                               __scsi_print_sense("st", SRpnt->sense,
-                                                  SCSI_SENSE_BUFFERSIZE);
+
+                       __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
                }
        }
 
@@ -508,7 +507,7 @@ st_do_scsi(struct st_request * SRpnt, struct scsi_tape * STp, unsigned char *cmd
        STp->buffer->cmdstat.have_sense = 0;
        STp->buffer->syscall_result = 0;
 
-       if (scsi_execute_async(STp->device, cmd, direction,
+       if (scsi_execute_async(STp->device, cmd, COMMAND_SIZE(cmd[0]), direction,
                        &((STp->buffer)->sg[0]), bytes, (STp->buffer)->sg_segs,
                               timeout, retries, SRpnt, st_sleep_done, GFP_KERNEL)) {
                /* could not allocate the buffer or request was too large */
@@ -1178,7 +1177,10 @@ static int st_open(struct inode *inode, struct file *filp)
                goto err_out;
        if ((filp->f_flags & O_NONBLOCK) == 0 &&
            retval != CHKRES_READY) {
-               retval = (-EIO);
+               if (STp->ready == NO_TAPE)
+                       retval = (-ENOMEDIUM);
+               else
+                       retval = (-EIO);
                goto err_out;
        }
        return 0;
@@ -1193,7 +1195,7 @@ static int st_open(struct inode *inode, struct file *filp)
 \f
 
 /* Flush the tape buffer before close */
-static int st_flush(struct file *filp)
+static int st_flush(struct file *filp, fl_owner_t id)
 {
        int result = 0, result2;
        unsigned char cmd[MAX_COMMAND_SIZE];
@@ -2818,7 +2820,7 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon
                    (cmdstatp->sense_hdr.sense_key == NO_SENSE ||
                     cmdstatp->sense_hdr.sense_key == RECOVERED_ERROR) &&
                    undone == 0) {
-                       ioctl_result = 0;       /* EOF written succesfully at EOM */
+                       ioctl_result = 0;       /* EOF written successfully at EOM */
                        if (fileno >= 0)
                                fileno++;
                        STps->drv_file = fileno;
@@ -3590,17 +3592,15 @@ static struct st_buffer *
 
        i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
                max_sg * sizeof(struct st_buf_fragment);
-       tb = kmalloc(i, priority);
+       tb = kzalloc(i, priority);
        if (!tb) {
                printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n");
                return NULL;
        }
-       memset(tb, 0, i);
        tb->frp_segs = tb->orig_frp_segs = 0;
        tb->use_sg = max_sg;
        tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg);
 
-       tb->in_use = 1;
        tb->dma = need_dma;
        tb->buffer_size = got;
 
@@ -3840,7 +3840,7 @@ static int __init st_setup(char *str)
                                        break;
                                }
                        }
-                       if (i >= sizeof(parms) / sizeof(struct st_dev_parm))
+                       if (i >= ARRAY_SIZE(parms))
                                 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
                                        stp);
                        stp = strchr(stp, ',');
@@ -3924,14 +3924,13 @@ static int st_probe(struct device *dev)
                        goto out_put_disk;
                }
 
-               tmp_da = kmalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
+               tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
                if (tmp_da == NULL) {
                        write_unlock(&st_dev_arr_lock);
                        printk(KERN_ERR "st: Can't extend device array.\n");
                        goto out_put_disk;
                }
 
-               memset(tmp_da, 0, tmp_dev_max * sizeof(struct scsi_tape *));
                if (scsi_tapes != NULL) {
                        memcpy(tmp_da, scsi_tapes,
                               st_dev_max * sizeof(struct scsi_tape *));
@@ -3948,13 +3947,12 @@ static int st_probe(struct device *dev)
        if (i >= st_dev_max)
                panic("scsi_devices corrupt (st)");
 
-       tpnt = kmalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
+       tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
        if (tpnt == NULL) {
                write_unlock(&st_dev_arr_lock);
                printk(KERN_ERR "st: Can't allocate device descriptor.\n");
                goto out_put_disk;
        }
-       memset(tpnt, 0, sizeof(struct scsi_tape));
        kref_init(&tpnt->kref);
        tpnt->disk = disk;
        sprintf(disk->disk_name, "st%d", i);
@@ -4053,26 +4051,13 @@ static int st_probe(struct device *dev)
                        STm->cdevs[j] = cdev;
 
                }
-               do_create_class_files(tpnt, dev_num, mode);
-       }
-
-       for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-               /* Make sure that the minor numbers corresponding to the four
-                  first modes always get the same names */
-               i = mode << (4 - ST_NBR_MODE_BITS);
-               /*  Rewind entry  */
-               devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 0)),
-                             S_IFCHR | S_IRUGO | S_IWUGO,
-                             "%s/mt%s", SDp->devfs_name, st_formats[i]);
-               /*  No-rewind entry  */
-               devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, TAPE_MINOR(dev_num, mode, 1)),
-                             S_IFCHR | S_IRUGO | S_IWUGO,
-                             "%s/mt%sn", SDp->devfs_name, st_formats[i]);
+               error = do_create_class_files(tpnt, dev_num, mode);
+               if (error)
+                       goto out_free_tape;
        }
-       disk->number = devfs_register_tape(SDp->devfs_name);
 
        sdev_printk(KERN_WARNING, SDp,
-                   "Attached scsi tape %s", tape_name(tpnt));
+                   "Attached scsi tape %s\n", tape_name(tpnt));
        printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n",
               tape_name(tpnt), tpnt->try_dio ? "yes" : "no",
               queue_dma_alignment(SDp->request_queue) + 1);
@@ -4124,13 +4109,9 @@ static int st_remove(struct device *dev)
                        scsi_tapes[i] = NULL;
                        st_nr_dev--;
                        write_unlock(&st_dev_arr_lock);
-                       devfs_unregister_tape(tpnt->disk->number);
                        sysfs_remove_link(&tpnt->device->sdev_gendev.kobj,
                                          "tape");
                        for (mode = 0; mode < ST_NBR_MODES; ++mode) {
-                               j = mode << (4 - ST_NBR_MODE_BITS);
-                               devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[j]);
-                               devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[j]);
                                for (j=0; j < 2; j++) {
                                        class_device_destroy(st_sysfs_class,
                                                             MKDEV(SCSI_TAPE_MAJOR,
@@ -4181,32 +4162,45 @@ static void scsi_tape_release(struct kref *kref)
 
 static int __init init_st(void)
 {
+       int err;
+
        validate_options();
 
-       printk(KERN_INFO
-               "st: Version %s, fixed bufsize %d, s/g segs %d\n",
+       printk(KERN_INFO "st: Version %s, fixed bufsize %d, s/g segs %d\n",
                verstr, st_fixed_buffer_size, st_max_sg_segs);
 
        st_sysfs_class = class_create(THIS_MODULE, "scsi_tape");
        if (IS_ERR(st_sysfs_class)) {
-               st_sysfs_class = NULL;
                printk(KERN_ERR "Unable create sysfs class for SCSI tapes\n");
-               return 1;
+               return PTR_ERR(st_sysfs_class);
        }
 
-       if (!register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-                                   ST_MAX_TAPE_ENTRIES, "st")) {
-               if (scsi_register_driver(&st_template.gendrv) == 0) {
-                       do_create_driverfs_files();
-                       return 0;
-               }
-               unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
-                                        ST_MAX_TAPE_ENTRIES);
+       err = register_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
+                                    ST_MAX_TAPE_ENTRIES, "st");
+       if (err) {
+               printk(KERN_ERR "Unable to get major %d for SCSI tapes\n",
+                      SCSI_TAPE_MAJOR);
+               goto err_class;
        }
-       class_destroy(st_sysfs_class);
 
-       printk(KERN_ERR "Unable to get major %d for SCSI tapes\n", SCSI_TAPE_MAJOR);
-       return 1;
+       err = scsi_register_driver(&st_template.gendrv);
+       if (err)
+               goto err_chrdev;
+
+       err = do_create_driverfs_files();
+       if (err)
+               goto err_scsidrv;
+
+       return 0;
+
+err_scsidrv:
+       scsi_unregister_driver(&st_template.gendrv);
+err_chrdev:
+       unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
+                                ST_MAX_TAPE_ENTRIES);
+err_class:
+       class_destroy(st_sysfs_class);
+       return err;
 }
 
 static void __exit exit_st(void)
@@ -4249,14 +4243,33 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf)
 }
 static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL);
 
-static void do_create_driverfs_files(void)
+static int do_create_driverfs_files(void)
 {
        struct device_driver *driverfs = &st_template.gendrv;
+       int err;
+
+       err = driver_create_file(driverfs, &driver_attr_try_direct_io);
+       if (err)
+               return err;
+       err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
+       if (err)
+               goto err_try_direct_io;
+       err = driver_create_file(driverfs, &driver_attr_max_sg_segs);
+       if (err)
+               goto err_attr_fixed_buf;
+       err = driver_create_file(driverfs, &driver_attr_version);
+       if (err)
+               goto err_attr_max_sg;
 
-       driver_create_file(driverfs, &driver_attr_try_direct_io);
-       driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
-       driver_create_file(driverfs, &driver_attr_max_sg_segs);
-       driver_create_file(driverfs, &driver_attr_version);
+       return 0;
+
+err_attr_max_sg:
+       driver_remove_file(driverfs, &driver_attr_max_sg_segs);
+err_attr_fixed_buf:
+       driver_remove_file(driverfs, &driver_attr_fixed_buffer_size);
+err_try_direct_io:
+       driver_remove_file(driverfs, &driver_attr_try_direct_io);
+       return err;
 }
 
 static void do_remove_driverfs_files(void)
@@ -4317,15 +4330,12 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf)
 
 CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL);
 
-static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
+static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
 {
        int i, rew, error;
        char name[10];
        struct class_device *st_class_member;
 
-       if (!st_sysfs_class)
-               return;
-
        for (rew=0; rew < 2; rew++) {
                /* Make sure that the minor numbers corresponding to the four
                   first modes always get the same names */
@@ -4340,18 +4350,24 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                if (IS_ERR(st_class_member)) {
                        printk(KERN_WARNING "st%d: class_device_create failed\n",
                               dev_num);
+                       error = PTR_ERR(st_class_member);
                        goto out;
                }
                class_set_devdata(st_class_member, &STp->modes[mode]);
 
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_defined);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_blksize);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_density);
-               class_device_create_file(st_class_member,
-                                        &class_device_attr_default_compression);
+               error = class_device_create_file(st_class_member,
+                                              &class_device_attr_defined);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                           &class_device_attr_default_blksize);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                           &class_device_attr_default_density);
+               if (error) goto out;
+               error = class_device_create_file(st_class_member,
+                                       &class_device_attr_default_compression);
+               if (error) goto out;
+
                if (mode == 0 && rew == 0) {
                        error = sysfs_create_link(&STp->device->sdev_gendev.kobj,
                                                  &st_class_member->kobj,
@@ -4360,11 +4376,15 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                                printk(KERN_ERR
                                       "st%d: Can't create sysfs link from SCSI device.\n",
                                       dev_num);
+                               goto out;
                        }
                }
        }
- out:
-       return;
+
+       return 0;
+
+out:
+       return error;
 }
 
 /* The following functions may be useful for a larger audience. */