linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / scsi / st.c
index 7f669b6..7f96f33 100644 (file)
@@ -35,6 +35,7 @@ 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>
@@ -86,9 +87,8 @@ static int st_nr_dev;
 static struct class *st_sysfs_class;
 
 MODULE_AUTHOR("Kai Makisara");
-MODULE_DESCRIPTION("SCSI tape (st) driver");
+MODULE_DESCRIPTION("SCSI Tape 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).
@@ -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(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
+                        __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
        } ) /* end DEB */
        if (!debugging) { /* Abnormal conditions for tape */
                if (!cmdstatp->have_sense)
@@ -384,8 +384,9 @@ 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) {
-
-                       __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE);
+                               printk(KERN_WARNING "%s: Error with sense data: ", name);
+                               __scsi_print_sense("st", SRpnt->sense,
+                                                  SCSI_SENSE_BUFFERSIZE);
                }
        }
 
@@ -1192,7 +1193,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, fl_owner_t id)
+static int st_flush(struct file *filp)
 {
        int result = 0, result2;
        unsigned char cmd[MAX_COMMAND_SIZE];
@@ -2817,7 +2818,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 successfully at EOM */
+                       ioctl_result = 0;       /* EOF written succesfully at EOM */
                        if (fileno >= 0)
                                fileno++;
                        STps->drv_file = fileno;
@@ -3589,15 +3590,17 @@ static struct st_buffer *
 
        i = sizeof(struct st_buffer) + (max_sg - 1) * sizeof(struct scatterlist) +
                max_sg * sizeof(struct st_buf_fragment);
-       tb = kzalloc(i, priority);
+       tb = kmalloc(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;
 
@@ -3837,7 +3840,7 @@ static int __init st_setup(char *str)
                                        break;
                                }
                        }
-                       if (i >= ARRAY_SIZE(parms))
+                       if (i >= sizeof(parms) / sizeof(struct st_dev_parm))
                                 printk(KERN_WARNING "st: invalid parameter in '%s'\n",
                                        stp);
                        stp = strchr(stp, ',');
@@ -3921,13 +3924,14 @@ static int st_probe(struct device *dev)
                        goto out_put_disk;
                }
 
-               tmp_da = kzalloc(tmp_dev_max * sizeof(struct scsi_tape *), GFP_ATOMIC);
+               tmp_da = kmalloc(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 *));
@@ -3944,12 +3948,13 @@ static int st_probe(struct device *dev)
        if (i >= st_dev_max)
                panic("scsi_devices corrupt (st)");
 
-       tpnt = kzalloc(sizeof(struct scsi_tape), GFP_ATOMIC);
+       tpnt = kmalloc(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);
@@ -4051,8 +4056,23 @@ static int st_probe(struct device *dev)
                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]);
+       }
+       disk->number = devfs_register_tape(SDp->devfs_name);
+
        sdev_printk(KERN_WARNING, SDp,
-                   "Attached scsi tape %s\n", tape_name(tpnt));
+                   "Attached scsi tape %s", 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);
@@ -4104,9 +4124,13 @@ 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,