#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>
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).
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)
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);
}
}
\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];
(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;
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;
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, ',');
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 *));
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);
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);
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,