X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fscsi%2Fst.c;h=71952703125a634a05869e1c6d44fe929a02f1ba;hb=51883b5e60796cce556370dbc368fd22c60c0e3e;hp=488ec7948a570766856436970a40aa2fd3813528;hpb=91614c054c9ffc26b47a5cb3135113aa0f6e6ff0;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 488ec79..7195270 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -9,7 +9,7 @@ Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, Michael Schaefer, J"org Weule, and Eric Youngdale. - Copyright 1992 - 2006 Kai Makisara + Copyright 1992 - 2008 Kai Makisara email Kai.Makisara@kolumbus.fi Some small formal changes - aeb, 950809 @@ -17,7 +17,7 @@ Last modified: 18-JAN-1998 Richard Gooch Devfs support */ -static const char *verstr = "20061107"; +static const char *verstr = "20080117"; #include @@ -89,6 +89,7 @@ MODULE_AUTHOR("Kai Makisara"); MODULE_DESCRIPTION("SCSI tape (st) driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_CHARDEV_MAJOR(SCSI_TAPE_MAJOR); +MODULE_ALIAS_SCSI_DEVICE(TYPE_TAPE); /* Set 'perm' (4th argument) to 0 to disable module_param's definition * of sysfs parameters (which module_param doesn't yet support). @@ -195,8 +196,8 @@ 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 int do_create_driverfs_files(void); -static void do_remove_driverfs_files(void); +static int do_create_sysfs_files(void); +static void do_remove_sysfs_files(void); static int do_create_class_files(struct scsi_tape *, int, int); static struct scsi_driver st_template = { @@ -1168,6 +1169,7 @@ static int st_open(struct inode *inode, struct file *filp) STps = &(STp->ps[i]); STps->rw = ST_IDLE; } + STp->try_dio_now = STp->try_dio; STp->recover_count = 0; DEB( STp->nbr_waits = STp->nbr_finished = 0; STp->nbr_requests = STp->nbr_dio = STp->nbr_pages = STp->nbr_combinable = 0; ) @@ -1400,9 +1402,9 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, struct st_buffer *STbp = STp->buffer; if (is_read) - i = STp->try_dio && try_rdio; + i = STp->try_dio_now && try_rdio; else - i = STp->try_dio && try_wdio; + i = STp->try_dio_now && try_wdio; if (i && ((unsigned long)buf & queue_dma_alignment( STp->device->request_queue)) == 0) { @@ -1483,7 +1485,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) struct st_buffer *STbp; char *name = tape_name(STp); - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; retval = rw_checks(STp, filp, count); @@ -1599,7 +1601,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) STm->do_async_writes && STps->eof < ST_EOM_OK; if (STp->block_size != 0 && STm->do_buffer_writes && - !(STp->try_dio && try_wdio) && STps->eof < ST_EOM_OK && + !(STp->try_dio_now && try_wdio) && STps->eof < ST_EOM_OK && STbp->buffer_bytes < STbp->buffer_size) { STp->dirty = 1; /* Don't write a buffer that is not full enough. */ @@ -1734,7 +1736,7 @@ st_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) if (SRpnt != NULL) st_release_request(SRpnt); release_buffering(STp, 0); - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -1769,7 +1771,7 @@ static long read_tape(struct scsi_tape *STp, long count, if (STp->block_size == 0) blks = bytes = count; else { - if (!(STp->try_dio && try_rdio) && STm->do_read_ahead) { + if (!(STp->try_dio_now && try_rdio) && STm->do_read_ahead) { blks = (STp->buffer)->buffer_blocks; bytes = blks * STp->block_size; } else { @@ -1940,7 +1942,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) struct st_buffer *STbp = STp->buffer; DEB( char *name = tape_name(STp); ) - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; retval = rw_checks(STp, filp, count); @@ -1948,10 +1950,12 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) goto out; STm = &(STp->modes[STp->current_mode]); - if (!(STm->do_read_ahead) && STp->block_size != 0 && - (count % STp->block_size) != 0) { - retval = (-EINVAL); /* Read must be integral number of blocks */ - goto out; + if (STp->block_size != 0 && (count % STp->block_size) != 0) { + if (!STm->do_read_ahead) { + retval = (-EINVAL); /* Read must be integral number of blocks */ + goto out; + } + STp->try_dio_now = 0; /* Direct i/o can't handle split blocks */ } STps = &(STp->ps[STp->partition]); @@ -2065,7 +2069,7 @@ st_read(struct file *filp, char __user *buf, size_t count, loff_t * ppos) release_buffering(STp, 1); STbp->buffer_bytes = 0; } - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -3210,8 +3214,7 @@ static int partition_tape(struct scsi_tape *STp, int size) /* The ioctl command */ -static int st_ioctl(struct inode *inode, struct file *file, - unsigned int cmd_in, unsigned long arg) +static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) { int i, cmd_nr, cmd_type, bt; int retval = 0; @@ -3222,7 +3225,7 @@ static int st_ioctl(struct inode *inode, struct file *file, char *name = tape_name(STp); void __user *p = (void __user *)arg; - if (down_interruptible(&STp->lock)) + if (mutex_lock_interruptible(&STp->lock)) return -ERESTARTSYS; DEB( @@ -3533,7 +3536,7 @@ static int st_ioctl(struct inode *inode, struct file *file, retval = (-EFAULT); goto out; } - up(&STp->lock); + mutex_unlock(&STp->lock); switch (cmd_in) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: @@ -3545,7 +3548,8 @@ static int st_ioctl(struct inode *inode, struct file *file, !capable(CAP_SYS_RAWIO)) i = -EPERM; else - i = scsi_cmd_ioctl(file, STp->disk, cmd_in, p); + i = scsi_cmd_ioctl(file, STp->disk->queue, + STp->disk, cmd_in, p); if (i != -ENOTTY) return i; break; @@ -3558,7 +3562,7 @@ static int st_ioctl(struct inode *inode, struct file *file, return retval; out: - up(&STp->lock); + mutex_unlock(&STp->lock); return retval; } @@ -3606,6 +3610,7 @@ static struct st_buffer * tb->dma = need_dma; tb->buffer_size = got; + sg_init_table(tb->sg, max_sg); return tb; } @@ -3792,13 +3797,11 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length) sg = &(STbp->sg[0]); frp = STbp->frp; for (i=count=0; count < length; i++) { - sg[i].page = frp[i].page; if (length - count > frp[i].length) - sg[i].length = frp[i].length; + sg_set_page(&sg[i], frp[i].page, frp[i].length, 0); else - sg[i].length = length - count; + sg_set_page(&sg[i], frp[i].page, length - count, 0); count += sg[i].length; - sg[i].offset = 0; } STbp->sg_segs = i; STbp->frp_sg_current = length; @@ -3861,12 +3864,12 @@ __setup("st=", st_setup); #endif -static struct file_operations st_fops = +static const struct file_operations st_fops = { .owner = THIS_MODULE, .read = st_read, .write = st_write, - .ioctl = st_ioctl, + .unlocked_ioctl = st_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = st_compat_ioctl, #endif @@ -4024,7 +4027,7 @@ static int st_probe(struct device *dev) tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; - init_MUTEX(&tpnt->lock); + mutex_init(&tpnt->lock); st_nr_dev++; write_unlock(&st_dev_arr_lock); @@ -4190,7 +4193,7 @@ static int __init init_st(void) if (err) goto err_chrdev; - err = do_create_driverfs_files(); + err = do_create_sysfs_files(); if (err) goto err_scsidrv; @@ -4208,7 +4211,7 @@ err_class: static void __exit exit_st(void) { - do_remove_driverfs_files(); + do_remove_sysfs_files(); scsi_unregister_driver(&st_template.gendrv); unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0), ST_MAX_TAPE_ENTRIES); @@ -4246,43 +4249,43 @@ static ssize_t st_version_show(struct device_driver *ddd, char *buf) } static DRIVER_ATTR(version, S_IRUGO, st_version_show, NULL); -static int do_create_driverfs_files(void) +static int do_create_sysfs_files(void) { - struct device_driver *driverfs = &st_template.gendrv; + struct device_driver *sysfs = &st_template.gendrv; int err; - err = driver_create_file(driverfs, &driver_attr_try_direct_io); + err = driver_create_file(sysfs, &driver_attr_try_direct_io); if (err) return err; - err = driver_create_file(driverfs, &driver_attr_fixed_buffer_size); + err = driver_create_file(sysfs, &driver_attr_fixed_buffer_size); if (err) goto err_try_direct_io; - err = driver_create_file(driverfs, &driver_attr_max_sg_segs); + err = driver_create_file(sysfs, &driver_attr_max_sg_segs); if (err) goto err_attr_fixed_buf; - err = driver_create_file(driverfs, &driver_attr_version); + err = driver_create_file(sysfs, &driver_attr_version); if (err) goto err_attr_max_sg; return 0; err_attr_max_sg: - driver_remove_file(driverfs, &driver_attr_max_sg_segs); + driver_remove_file(sysfs, &driver_attr_max_sg_segs); err_attr_fixed_buf: - driver_remove_file(driverfs, &driver_attr_fixed_buffer_size); + driver_remove_file(sysfs, &driver_attr_fixed_buffer_size); err_try_direct_io: - driver_remove_file(driverfs, &driver_attr_try_direct_io); + driver_remove_file(sysfs, &driver_attr_try_direct_io); return err; } -static void do_remove_driverfs_files(void) +static void do_remove_sysfs_files(void) { - struct device_driver *driverfs = &st_template.gendrv; + struct device_driver *sysfs = &st_template.gendrv; - driver_remove_file(driverfs, &driver_attr_version); - driver_remove_file(driverfs, &driver_attr_max_sg_segs); - driver_remove_file(driverfs, &driver_attr_fixed_buffer_size); - driver_remove_file(driverfs, &driver_attr_try_direct_io); + driver_remove_file(sysfs, &driver_attr_version); + driver_remove_file(sysfs, &driver_attr_max_sg_segs); + driver_remove_file(sysfs, &driver_attr_fixed_buffer_size); + driver_remove_file(sysfs, &driver_attr_try_direct_io); } @@ -4441,15 +4444,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa } /* Populate the scatter/gather list */ - sgl[0].page = pages[0]; - sgl[0].offset = uaddr & ~PAGE_MASK; + sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK); if (nr_pages > 1) { sgl[0].length = PAGE_SIZE - sgl[0].offset; count -= sgl[0].length; for (i=1; i < nr_pages ; i++) { - sgl[i].offset = 0; - sgl[i].page = pages[i]; - sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE; + sg_set_page(&sgl[i], pages[i], + count < PAGE_SIZE ? count : PAGE_SIZE, 0);; count -= PAGE_SIZE; } } @@ -4478,7 +4479,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p int i; for (i=0; i < nr_pages; i++) { - struct page *page = sgl[i].page; + struct page *page = sg_page(&sgl[i]); if (dirtied) SetPageDirty(page);