Commit 865e9146 authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] cleanup code for /proc add/remove single device

two new helpers in scsi_scan.c: scsi_add_single_device and
scsi_remove_single_device that do all hard work.  Thanks to
beeing in scsi_scan.c and using proper helpers they're a lot
smaller and cleaner.
parent 64ac28dd
...@@ -521,6 +521,8 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *); ...@@ -521,6 +521,8 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *);
extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *, extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *,
uint, uint, uint); uint, uint, uint);
extern void scsi_free_sdev(struct scsi_device *); extern void scsi_free_sdev(struct scsi_device *);
extern int scsi_add_single_device(uint, uint, uint, uint);
extern int scsi_remove_single_device(uint, uint, uint, uint);
/* /*
* Prototypes for functions in constants.c * Prototypes for functions in constants.c
......
...@@ -399,11 +399,8 @@ static void scsi_dump_status(int level) ...@@ -399,11 +399,8 @@ static void scsi_dump_status(int level)
static int proc_scsi_gen_write(struct file * file, const char * buf, static int proc_scsi_gen_write(struct file * file, const char * buf,
unsigned long length, void *data) unsigned long length, void *data)
{ {
Scsi_Device *sdev;
struct Scsi_Host *shost;
char *p;
int host, channel, id, lun; int host, channel, id, lun;
char * buffer; char *buffer, *p;
int err; int err;
if (!buf || length>PAGE_SIZE) if (!buf || length>PAGE_SIZE)
...@@ -529,35 +526,9 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -529,35 +526,9 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
id = simple_strtoul(p + 1, &p, 0); id = simple_strtoul(p + 1, &p, 0);
lun = simple_strtoul(p + 1, &p, 0); lun = simple_strtoul(p + 1, &p, 0);
printk(KERN_INFO "scsi singledevice %d %d %d %d\n", host, channel, err = scsi_add_single_device(host, channel, id, lun);
id, lun); if (err >= 0)
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
if (shost->host_no == host) {
break;
}
}
err = -ENXIO;
if (!shost)
goto out;
for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
if ((sdev->channel == channel
&& sdev->id == id
&& sdev->lun == lun)) {
break;
}
}
err = -ENOSYS;
if (sdev)
goto out; /* We do not yet support unplugging */
scan_scsis(shost, 1, channel, id, lun);
err = length; err = length;
goto out;
}
/* /*
* Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi * Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi
* with "0 1 2 3" replaced by your "Host Channel Id Lun". * with "0 1 2 3" replaced by your "Host Channel Id Lun".
...@@ -569,7 +540,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -569,7 +540,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
* hardware and thoroughly confuse the SCSI subsystem. * hardware and thoroughly confuse the SCSI subsystem.
* *
*/ */
else if (!strncmp("remove-single-device", buffer + 5, 20)) { } else if (!strncmp("remove-single-device", buffer + 5, 20)) {
p = buffer + 26; p = buffer + 26;
host = simple_strtoul(p, &p, 0); host = simple_strtoul(p, &p, 0);
...@@ -577,39 +548,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, ...@@ -577,39 +548,7 @@ static int proc_scsi_gen_write(struct file * file, const char * buf,
id = simple_strtoul(p + 1, &p, 0); id = simple_strtoul(p + 1, &p, 0);
lun = simple_strtoul(p + 1, &p, 0); lun = simple_strtoul(p + 1, &p, 0);
err = scsi_remove_single_device(host, channel, id, lun);
for (shost = scsi_host_get_next(NULL); shost;
shost = scsi_host_get_next(shost)) {
if (shost->host_no == host) {
break;
}
}
err = -ENODEV;
if (!shost)
goto out;
for (sdev = shost->host_queue; sdev; sdev = sdev->next) {
if ((sdev->channel == channel
&& sdev->id == id
&& sdev->lun == lun)) {
break;
}
}
if (sdev == NULL)
goto out; /* there is no such device attached */
err = -EBUSY;
if (sdev->access_count)
goto out;
scsi_detach_device(sdev);
if (sdev->attached == 0) {
devfs_unregister (sdev->de);
scsi_free_sdev(sdev);
err = 0;
}
} }
out: out:
......
...@@ -1862,6 +1862,69 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan) ...@@ -1862,6 +1862,69 @@ static int scsi_report_lun_scan(Scsi_Device *sdevscan)
} }
int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
{
struct scsi_device *sdevscan, *sdev;
struct Scsi_Host *shost;
int error = -ENODEV;
shost = scsi_host_hn_get(host);
if (!shost)
return -ENODEV;
sdev = scsi_find_device(shost, channel, id, lun);
if (!sdev)
goto out;
error = -ENOMEM;
sdevscan = scsi_alloc_sdev(shost, channel, id, lun);
if (!sdevscan)
goto out;
sdevscan->scsi_level = scsi_find_scsi_level(channel, id, shost);
error = scsi_probe_and_add_lun(sdevscan, &sdev, NULL);
scsi_free_sdev(sdevscan);
error = -ENODEV;
if (error != SCSI_SCAN_LUN_PRESENT)
goto out;
scsi_attach_device(sdev);
error = 0;
out:
scsi_host_put(shost);
return error;
}
int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
{
struct scsi_device *sdev;
struct Scsi_Host *shost;
int error = -ENODEV;
shost = scsi_host_hn_get(host);
if (!shost)
return -ENODEV;
sdev = scsi_find_device(shost, channel, id, lun);
if (!sdev)
goto out;
error = -EBUSY;
if (sdev->access_count)
goto out;
scsi_detach_device(sdev);
if (sdev->attached)
goto out;
devfs_unregister(sdev->de);
scsi_free_sdev(sdev);
error = 0;
out:
scsi_host_put(shost);
return error;
}
/** /**
* scsi_scan_target - scan a target id, possibly including all LUNs on the * scsi_scan_target - scan a target id, possibly including all LUNs on the
* target. * target.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment