git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
rwsem generic spinlock: use IRQ save/restore spinlocks
[safe/jmp/linux-2.6]
/
drivers
/
scsi
/
hosts.c
diff --git
a/drivers/scsi/hosts.c
b/drivers/scsi/hosts.c
index
35cd892
..
6660fa9
100644
(file)
--- a/
drivers/scsi/hosts.c
+++ b/
drivers/scsi/hosts.c
@@
-24,6
+24,7
@@
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/blkdev.h>
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/kthread.h>
#include <linux/string.h>
#include <linux/mm.h>
@@
-40,7
+41,7
@@
#include "scsi_logging.h"
#include "scsi_logging.h"
-static
int scsi_host_next_hn;
/* host_no for next new host */
+static
atomic_t scsi_host_next_hn;
/* host_no for next new host */
static void scsi_host_cls_release(struct device *dev)
static void scsi_host_cls_release(struct device *dev)
@@
-164,8
+165,8
@@
void scsi_remove_host(struct Scsi_Host *shost)
return;
}
spin_unlock_irqrestore(shost->host_lock, flags);
return;
}
spin_unlock_irqrestore(shost->host_lock, flags);
- mutex_unlock(&shost->scan_mutex);
scsi_forget_host(shost);
scsi_forget_host(shost);
+ mutex_unlock(&shost->scan_mutex);
scsi_proc_host_rm(shost);
spin_lock_irqsave(shost->host_lock, flags);
scsi_proc_host_rm(shost);
spin_lock_irqsave(shost->host_lock, flags);
@@
-176,19
+177,24
@@
void scsi_remove_host(struct Scsi_Host *shost)
transport_unregister_device(&shost->shost_gendev);
device_unregister(&shost->shost_dev);
device_del(&shost->shost_gendev);
transport_unregister_device(&shost->shost_gendev);
device_unregister(&shost->shost_dev);
device_del(&shost->shost_gendev);
- scsi_proc_hostdir_rm(shost->hostt);
}
EXPORT_SYMBOL(scsi_remove_host);
/**
}
EXPORT_SYMBOL(scsi_remove_host);
/**
- * scsi_add_host
- add a scsi host
+ * scsi_add_host
_with_dma - add a scsi host with dma device
* @shost: scsi host pointer to add
* @dev: a struct device of type scsi class
* @shost: scsi host pointer to add
* @dev: a struct device of type scsi class
+ * @dma_dev: dma device for the host
+ *
+ * Note: You rarely need to worry about this unless you're in a
+ * virtualised host environments, so use the simpler scsi_add_host()
+ * function instead.
*
* Return value:
* 0 on success / != 0 for error
**/
*
* Return value:
* 0 on success / != 0 for error
**/
-int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
+int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+ struct device *dma_dev)
{
struct scsi_host_template *sht = shost->hostt;
int error = -EINVAL;
{
struct scsi_host_template *sht = shost->hostt;
int error = -EINVAL;
@@
-208,6
+214,9
@@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
if (!shost->shost_gendev.parent)
shost->shost_gendev.parent = dev ? dev : &platform_bus;
if (!shost->shost_gendev.parent)
shost->shost_gendev.parent = dev ? dev : &platform_bus;
+ shost->dma_dev = dma_dev;
+
+ device_enable_async_suspend(&shost->shost_gendev);
error = device_add(&shost->shost_gendev);
if (error)
error = device_add(&shost->shost_gendev);
if (error)
@@
-216,6
+225,8
@@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
scsi_host_set_state(shost, SHOST_RUNNING);
get_device(shost->shost_gendev.parent);
scsi_host_set_state(shost, SHOST_RUNNING);
get_device(shost->shost_gendev.parent);
+ device_enable_async_suspend(&shost->shost_dev);
+
error = device_add(&shost->shost_dev);
if (error)
goto out_del_gendev;
error = device_add(&shost->shost_dev);
if (error)
goto out_del_gendev;
@@
-232,8
+243,8
@@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
}
if (shost->transportt->create_work_queue) {
}
if (shost->transportt->create_work_queue) {
- snprintf(shost->work_q_name,
KOBJ_NAME_LEN, "scsi_wq_%d"
,
- shost->host_no);
+ snprintf(shost->work_q_name,
sizeof(shost->work_q_name)
,
+
"scsi_wq_%d",
shost->host_no);
shost->work_q = create_singlethread_workqueue(
shost->work_q_name);
if (!shost->work_q) {
shost->work_q = create_singlethread_workqueue(
shost->work_q_name);
if (!shost->work_q) {
@@
-263,13
+274,15
@@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
fail:
return error;
}
fail:
return error;
}
-EXPORT_SYMBOL(scsi_add_host);
+EXPORT_SYMBOL(scsi_add_host
_with_dma
);
static void scsi_host_dev_release(struct device *dev)
{
struct Scsi_Host *shost = dev_to_shost(dev);
struct device *parent = dev->parent;
static void scsi_host_dev_release(struct device *dev)
{
struct Scsi_Host *shost = dev_to_shost(dev);
struct device *parent = dev->parent;
+ scsi_proc_hostdir_rm(shost->hostt);
+
if (shost->ehandler)
kthread_stop(shost->ehandler);
if (shost->work_q)
if (shost->ehandler)
kthread_stop(shost->ehandler);
if (shost->work_q)
@@
-332,7
+345,11
@@
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
mutex_init(&shost->scan_mutex);
mutex_init(&shost->scan_mutex);
- shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */
+ /*
+ * subtract one because we increment first then return, but we need to
+ * know what the next host number was before increment
+ */
+ shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
shost->dma_channel = 0xff;
/* These three are default values which can be overridden */
shost->dma_channel = 0xff;
/* These three are default values which can be overridden */
@@
-388,8
+405,7
@@
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->dma_boundary = 0xffffffff;
device_initialize(&shost->shost_gendev);
shost->dma_boundary = 0xffffffff;
device_initialize(&shost->shost_gendev);
- snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
- shost->host_no);
+ dev_set_name(&shost->shost_gendev, "host%d", shost->host_no);
#ifndef CONFIG_SYSFS_DEPRECATED
shost->shost_gendev.bus = &scsi_bus_type;
#endif
#ifndef CONFIG_SYSFS_DEPRECATED
shost->shost_gendev.bus = &scsi_bus_type;
#endif
@@
-398,8
+414,7
@@
struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
device_initialize(&shost->shost_dev);
shost->shost_dev.parent = &shost->shost_gendev;
shost->shost_dev.class = &shost_class;
device_initialize(&shost->shost_dev);
shost->shost_dev.parent = &shost->shost_gendev;
shost->shost_dev.class = &shost_class;
- snprintf(shost->shost_dev.bus_id, BUS_ID_SIZE, "host%d",
- shost->host_no);
+ dev_set_name(&shost->shost_dev, "host%d", shost->host_no);
shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
shost->ehandler = kthread_run(scsi_error_handler, shost,
shost->shost_dev.groups = scsi_sysfs_shost_attr_groups;
shost->ehandler = kthread_run(scsi_error_handler, shost,
@@
-464,9
+479,10
@@
static int __scsi_host_match(struct device *dev, void *data)
struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{
struct device *cdev;
struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
{
struct device *cdev;
- struct Scsi_Host *shost =
ERR_PTR(-ENXIO)
;
+ struct Scsi_Host *shost =
NULL
;
- cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
+ cdev = class_find_device(&shost_class, NULL, &hostnum,
+ __scsi_host_match);
if (cdev) {
shost = scsi_host_get(class_to_shost(cdev));
put_device(cdev);
if (cdev) {
shost = scsi_host_get(class_to_shost(cdev));
put_device(cdev);