#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
+#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/spinlock.h>
#include <linux/file.h>
rq->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
- if (sizeof(rq->cmd) > CDROM_PACKET_SIZE)
- memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE);
rq->timeout = 60*HZ;
rq->cmd_type = REQ_TYPE_BLOCK_PC;
/*
* speed is given as the normal factor, e.g. 4 for 4x
*/
-static int pkt_set_speed(struct pktcdvd_device *pd, unsigned write_speed, unsigned read_speed)
+static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd,
+ unsigned write_speed, unsigned read_speed)
{
struct packet_command cgc;
struct request_sense sense;
return pkt_generic_packet(pd, &cgc);
}
-static int pkt_get_last_written(struct pktcdvd_device *pd, long *last_written)
+static noinline_for_stack int pkt_get_last_written(struct pktcdvd_device *pd,
+ long *last_written)
{
disc_information di;
track_information ti;
/*
* write mode select package based on pd->settings
*/
-static int pkt_set_write_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_set_write_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
return 1;
}
-static int pkt_probe_settings(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_probe_settings(struct pktcdvd_device *pd)
{
struct packet_command cgc;
unsigned char buf[12];
/*
* enable/disable write caching on drive
*/
-static int pkt_write_caching(struct pktcdvd_device *pd, int set)
+static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd,
+ int set)
{
struct packet_command cgc;
struct request_sense sense;
/*
* Returns drive maximum write speed
*/
-static int pkt_get_max_speed(struct pktcdvd_device *pd, unsigned *write_speed)
+static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd,
+ unsigned *write_speed)
{
struct packet_command cgc;
struct request_sense sense;
/*
* reads the maximum media speed from ATIP
*/
-static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed)
+static noinline_for_stack int pkt_media_speed(struct pktcdvd_device *pd,
+ unsigned *speed)
{
struct packet_command cgc;
struct request_sense sense;
}
}
-static int pkt_perform_opc(struct pktcdvd_device *pd)
+static noinline_for_stack int pkt_perform_opc(struct pktcdvd_device *pd)
{
struct packet_command cgc;
struct request_sense sense;
-static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec)
+static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd,
+ struct bio_vec *bvec)
{
struct pktcdvd_device *pd = q->queuedata;
- sector_t zone = ZONE(bio->bi_sector, pd);
- int used = ((bio->bi_sector - zone) << 9) + bio->bi_size;
+ sector_t zone = ZONE(bmd->bi_sector, pd);
+ int used = ((bmd->bi_sector - zone) << 9) + bmd->bi_size;
int remaining = (pd->settings.size << 9) - used;
int remaining2;
* A bio <= PAGE_SIZE must be allowed. If it crosses a packet
* boundary, pkt_make_request() will split the bio.
*/
- remaining2 = PAGE_SIZE - bio->bi_size;
+ remaining2 = PAGE_SIZE - bmd->bi_size;
remaining = max(remaining, remaining2);
BUG_ON(remaining < 0);
int i;
int ret = 0;
char b[BDEVNAME_SIZE];
- struct proc_dir_entry *proc;
struct block_device *bdev;
if (pd->pkt_dev == dev) {
goto out_mem;
}
- proc = create_proc_entry(pd->name, 0, pkt_proc);
- if (proc) {
- proc->data = pd;
- proc->proc_fops = &pkt_proc_fops;
- }
+ proc_create_data(pd->name, 0, pkt_proc, &pkt_proc_fops, pd);
DPRINTK(DRIVER_NAME": writer %s mapped to %s\n", pd->name, bdevname(bdev, b));
return 0;
return ret;
}
-static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- struct pktcdvd_device *pd = inode->i_bdev->bd_disk->private_data;
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct pktcdvd_device *pd;
+ long ret;
+
+ lock_kernel();
+ pd = inode->i_bdev->bd_disk->private_data;
VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, imajor(inode), iminor(inode));
case CDROM_LAST_WRITTEN:
case CDROM_SEND_PACKET:
case SCSI_IOCTL_SEND_COMMAND:
- return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
+ ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
+ break;
case CDROMEJECT:
/*
*/
if (pd->refcnt == 1)
pkt_lock_door(pd, 0);
- return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
+ ret = blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg);
+ break;
default:
VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd);
- return -ENOTTY;
+ ret = -ENOTTY;
}
-
- return 0;
+ unlock_kernel();
+ return ret;
}
static int pkt_media_changed(struct gendisk *disk)
.owner = THIS_MODULE,
.open = pkt_open,
.release = pkt_close,
- .ioctl = pkt_ioctl,
+ .unlocked_ioctl = pkt_ioctl,
.media_changed = pkt_media_changed,
};
mutex_unlock(&ctl_mutex);
}
-static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long pkt_ctl_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct pkt_ctrl_command ctrl_cmd;
case PKT_CTRL_CMD_SETUP:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ lock_kernel();
ret = pkt_setup_dev(new_decode_dev(ctrl_cmd.dev), &pkt_dev);
ctrl_cmd.pkt_dev = new_encode_dev(pkt_dev);
+ unlock_kernel();
break;
case PKT_CTRL_CMD_TEARDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ lock_kernel();
ret = pkt_remove_dev(new_decode_dev(ctrl_cmd.pkt_dev));
+ unlock_kernel();
break;
case PKT_CTRL_CMD_STATUS:
+ lock_kernel();
pkt_get_status(&ctrl_cmd);
+ unlock_kernel();
break;
default:
return -ENOTTY;
static const struct file_operations pkt_ctl_fops = {
- .ioctl = pkt_ctl_ioctl,
+ .unlocked_ioctl = pkt_ctl_ioctl,
.owner = THIS_MODULE,
};
goto out_misc;
}
- pkt_proc = proc_mkdir(DRIVER_NAME, proc_root_driver);
+ pkt_proc = proc_mkdir("driver/"DRIVER_NAME, NULL);
return 0;
static void __exit pkt_exit(void)
{
- remove_proc_entry(DRIVER_NAME, proc_root_driver);
+ remove_proc_entry("driver/"DRIVER_NAME, NULL);
misc_deregister(&pkt_misc);
pkt_debugfs_cleanup();