Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 77161
b: refs/heads/master
c: da707c5
h: refs/heads/master
i:
  77159: bcd842a
v: v3
  • Loading branch information
FUJITA Tomonori authored and James Bottomley committed Jan 25, 2008
1 parent e021027 commit 39333ff
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a3d2c2e8f5e01e185013d8f944c0a26fdc558ad8
refs/heads/master: da707c54c3424b4b50d4352c2103867284ba6724
71 changes: 40 additions & 31 deletions trunk/drivers/scsi/ch.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/compat.h>
#include <linux/chio.h> /* here are all the ioctls */
#include <linux/mutex.h>
#include <linux/idr.h>

#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
Expand All @@ -33,6 +34,7 @@

#define CH_DT_MAX 16
#define CH_TYPES 8
#define CH_MAX_DEVS 128

MODULE_DESCRIPTION("device driver for scsi media changer devices");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org>");
Expand Down Expand Up @@ -113,9 +115,8 @@ typedef struct {
struct mutex lock;
} scsi_changer;

static LIST_HEAD(ch_devlist);
static DEFINE_SPINLOCK(ch_devlist_lock);
static int ch_devcount;
static DEFINE_IDR(ch_index_idr);
static DEFINE_SPINLOCK(ch_index_lock);

static struct scsi_driver ch_template =
{
Expand Down Expand Up @@ -598,20 +599,17 @@ ch_release(struct inode *inode, struct file *file)
static int
ch_open(struct inode *inode, struct file *file)
{
scsi_changer *tmp, *ch;
scsi_changer *ch;
int minor = iminor(inode);

spin_lock(&ch_devlist_lock);
ch = NULL;
list_for_each_entry(tmp,&ch_devlist,list) {
if (tmp->minor == minor)
ch = tmp;
}
spin_lock(&ch_index_lock);
ch = idr_find(&ch_index_idr, minor);

if (NULL == ch || scsi_device_get(ch->device)) {
spin_unlock(&ch_devlist_lock);
spin_unlock(&ch_index_lock);
return -ENXIO;
}
spin_unlock(&ch_devlist_lock);
spin_unlock(&ch_index_lock);

file->private_data = ch;
return 0;
Expand Down Expand Up @@ -914,6 +912,7 @@ static int ch_probe(struct device *dev)
{
struct scsi_device *sd = to_scsi_device(dev);
struct class_device *class_dev;
int minor, ret = -ENOMEM;
scsi_changer *ch;

if (sd->type != TYPE_MEDIUM_CHANGER)
Expand All @@ -923,7 +922,22 @@ static int ch_probe(struct device *dev)
if (NULL == ch)
return -ENOMEM;

ch->minor = ch_devcount;
if (!idr_pre_get(&ch_index_idr, GFP_KERNEL))
goto free_ch;

spin_lock(&ch_index_lock);
ret = idr_get_new(&ch_index_idr, ch, &minor);
spin_unlock(&ch_index_lock);

if (ret)
goto free_ch;

if (minor > CH_MAX_DEVS) {
ret = -ENODEV;
goto remove_idr;
}

ch->minor = minor;
sprintf(ch->name,"ch%d",ch->minor);

class_dev = class_device_create(ch_sysfs_class, NULL,
Expand All @@ -932,8 +946,8 @@ static int ch_probe(struct device *dev)
if (IS_ERR(class_dev)) {
printk(KERN_WARNING "ch%d: class_device_create failed\n",
ch->minor);
kfree(ch);
return PTR_ERR(class_dev);
ret = PTR_ERR(class_dev);
goto remove_idr;
}

mutex_init(&ch->lock);
Expand All @@ -942,35 +956,29 @@ static int ch_probe(struct device *dev)
if (init)
ch_init_elem(ch);

dev_set_drvdata(dev, ch);
sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name);

spin_lock(&ch_devlist_lock);
list_add_tail(&ch->list,&ch_devlist);
ch_devcount++;
spin_unlock(&ch_devlist_lock);
return 0;
remove_idr:
idr_remove(&ch_index_idr, minor);
free_ch:
kfree(ch);
return ret;
}

static int ch_remove(struct device *dev)
{
struct scsi_device *sd = to_scsi_device(dev);
scsi_changer *tmp, *ch;
scsi_changer *ch = dev_get_drvdata(dev);

spin_lock(&ch_devlist_lock);
ch = NULL;
list_for_each_entry(tmp,&ch_devlist,list) {
if (tmp->device == sd)
ch = tmp;
}
BUG_ON(NULL == ch);
list_del(&ch->list);
spin_unlock(&ch_devlist_lock);
spin_lock(&ch_index_lock);
idr_remove(&ch_index_idr, ch->minor);
spin_unlock(&ch_index_lock);

class_device_destroy(ch_sysfs_class,
MKDEV(SCSI_CHANGER_MAJOR,ch->minor));
kfree(ch->dt);
kfree(ch);
ch_devcount--;
return 0;
}

Expand Down Expand Up @@ -1007,6 +1015,7 @@ static void __exit exit_ch_module(void)
scsi_unregister_driver(&ch_template.gendrv);
unregister_chrdev(SCSI_CHANGER_MAJOR, "ch");
class_destroy(ch_sysfs_class);
idr_destroy(&ch_index_idr);
}

module_init(init_ch_module);
Expand Down

0 comments on commit 39333ff

Please sign in to comment.