Commit 0859138b authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] LDM-based scsi host lookup

Replace scsi_host_hn_get with scsi_host_lookup that walks
through the shost class and gets a proper reference to the
host.  This should fix the OOPS that Douglas saw last week.
parent b4152e7c
...@@ -523,16 +523,33 @@ struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *shost) ...@@ -523,16 +523,33 @@ struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *shost)
} }
/** /**
* scsi_host_hn_get - get a Scsi_Host by host no and inc ref count * scsi_host_lookup - get a reference to a Scsi_Host by host no
* @host_no: host number to locate *
* @hostnum: host number to locate
* *
* Return value: * Return value:
* A pointer to located Scsi_Host or NULL. * A pointer to located Scsi_Host or NULL.
**/ **/
struct Scsi_Host *scsi_host_hn_get(unsigned short host_no) struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{ {
/* XXX Inc ref count */ struct class *class = class_get(&shost_class);
return scsi_find_host_by_num(host_no); struct class_device *cdev;
struct Scsi_Host *shost = NULL, *p;
if (class) {
down_read(&class->subsys.rwsem);
list_for_each_entry(cdev, &class->children, node) {
p = class_to_shost(cdev);
if (p->host_no == hostnum) {
scsi_host_get(p);
shost = p;
break;
}
}
up_read(&class->subsys.rwsem);
}
return shost;
} }
/** /**
...@@ -541,10 +558,8 @@ struct Scsi_Host *scsi_host_hn_get(unsigned short host_no) ...@@ -541,10 +558,8 @@ struct Scsi_Host *scsi_host_hn_get(unsigned short host_no)
**/ **/
void scsi_host_get(struct Scsi_Host *shost) void scsi_host_get(struct Scsi_Host *shost)
{ {
get_device(&shost->host_gendev); get_device(&shost->host_gendev);
class_device_get(&shost->class_dev); class_device_get(&shost->class_dev);
return;
} }
/** /**
...@@ -556,7 +571,6 @@ void scsi_host_put(struct Scsi_Host *shost) ...@@ -556,7 +571,6 @@ void scsi_host_put(struct Scsi_Host *shost)
class_device_put(&shost->class_dev); class_device_put(&shost->class_dev);
put_device(&shost->host_gendev); put_device(&shost->host_gendev);
return;
} }
/** /**
......
...@@ -56,7 +56,7 @@ struct scsi_target { ...@@ -56,7 +56,7 @@ struct scsi_target {
extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *); extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *); extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
extern struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *);
extern struct Scsi_Host *scsi_host_hn_get(unsigned short); extern struct Scsi_Host *scsi_host_lookup(unsigned short);
extern void scsi_host_put(struct Scsi_Host *); extern void scsi_host_put(struct Scsi_Host *);
extern void scsi_host_init(void); extern void scsi_host_init(void);
...@@ -129,4 +129,6 @@ extern void scsi_sysfs_unregister(void); ...@@ -129,4 +129,6 @@ extern void scsi_sysfs_unregister(void);
extern struct class_device_attribute *scsi_sysfs_shost_attrs[]; extern struct class_device_attribute *scsi_sysfs_shost_attrs[];
extern struct device_attribute *scsi_sysfs_sdev_attrs[]; extern struct device_attribute *scsi_sysfs_sdev_attrs[];
extern struct class shost_class;
#endif /* _SCSI_PRIV_H */ #endif /* _SCSI_PRIV_H */
...@@ -250,7 +250,7 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun) ...@@ -250,7 +250,7 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
struct scsi_device *sdev; struct scsi_device *sdev;
int error = -ENODEV; int error = -ENODEV;
shost = scsi_host_hn_get(host); shost = scsi_host_lookup(host);
if (!shost) if (!shost)
return -ENODEV; return -ENODEV;
...@@ -272,7 +272,7 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -272,7 +272,7 @@ static int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
struct Scsi_Host *shost; struct Scsi_Host *shost;
int error = -ENODEV; int error = -ENODEV;
shost = scsi_host_hn_get(host); shost = scsi_host_lookup(host);
if (!shost) if (!shost)
return -ENODEV; return -ENODEV;
sdev = scsi_find_device(shost, channel, id, lun); sdev = scsi_find_device(shost, channel, id, lun);
......
...@@ -54,7 +54,7 @@ struct class_device_attribute *scsi_sysfs_shost_attrs[] = { ...@@ -54,7 +54,7 @@ struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
NULL NULL
}; };
static struct class shost_class = { struct class shost_class = {
.name = "scsi_host", .name = "scsi_host",
}; };
......
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