1 |
On Sun, 2008-05-04 at 09:34 -0500, James Bottomley wrote: |
diff -Naur linux-2.6.29/drivers/scsi/scsi_lib.c linux-2.6.29-alx/drivers/scsi/scsi_lib.c |
2 |
> On Sat, 2008-05-03 at 17:22 -0700, bugme-daemon@bugzilla.kernel.org |
--- linux-2.6.29/drivers/scsi/scsi_lib.c 2009-03-24 00:12:14.000000000 +0100 |
3 |
> wrote: |
+++ linux-2.6.29-alx/drivers/scsi/scsi_lib.c 2009-08-05 16:03:06.000000000 +0200 |
4 |
> > http://bugzilla.kernel.org/show_bug.cgi?id=9872 |
@@ -1411,6 +1411,7 @@ |
5 |
> |
ret = scsi_setup_blk_pc_cmnd(sdev, req); |
6 |
> This isn't a bug. There have been numerous discussions about fixing it. |
return scsi_prep_return(q, req, ret); |
|
|
|
|
It is a kind of a "bug". The core does not call driver functions, if |
|
|
bus_type is provided. So the warning is fine according to the current |
|
|
logic of the core, telling you it will ignore things a driver asked for. |
|
|
|
|
|
> The warning comes out of here in drivers/base/driver.c: |
|
|
> |
|
|
> if ((drv->bus->probe && drv->probe) || |
|
|
> (drv->bus->remove && drv->remove) || |
|
|
> (drv->bus->shutdown && drv->shutdown)) |
|
|
> printk(KERN_WARNING "Driver '%s' needs updating - please use " |
|
|
> "bus_type methods\n", drv->name); |
|
|
> |
|
|
> The problem is that SCSI drivers have both: SCSI uses the bus methods to |
|
|
> trigger the probe and remove (as it must having a bus method) but it |
|
|
> also uses the individual struct driver probe and remove methods to |
|
|
> rethrow the events to the ULDs. |
|
|
|
|
|
Looks like it does not use probe() on the bus. Now lets get rid of |
|
|
remove(). :) |
|
|
|
|
|
> According to Kay and Greg, this is a legitimate way of operating, and |
|
|
> they're not going to remove the driver methods (otherwise we'd just take |
|
|
> them into struct scsi_driver), so we're stuck trying to find a way to |
|
|
> prevent the base warning about this. |
|
|
|
|
|
Right, I guess, they are not going away, but you still should only use |
|
|
one of them, and not both at the same time. |
|
|
|
|
|
How about the following patch? Which does not use driver core pointers, |
|
|
which are ignored by the core, to do private SCSI stuff. |
|
|
|
|
|
Thanks, |
|
|
Kay |
|
|
|
|
|
|
|
|
|
|
|
From: Hannes Reinecke <hare@suse.de> |
|
|
Subject: SCSI: do not use bus_type->remove() and driver->remove() at the same |
|
|
time |
|
|
|
|
|
If a driver sets blk_queue_prep_rq(), it should clean it up itself, and |
|
|
not from the bus callbacks. This removes the need to hook into bus->remove(), |
|
|
which should not be used at the same time as driver->remove(). |
|
|
|
|
|
Signed-off-by: Hannes Reinecke <hare@suse.de> |
|
|
Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> |
|
|
--- |
|
|
|
|
|
drivers/scsi/scsi_lib.c | 1 + |
|
|
drivers/scsi/scsi_priv.h | 1 - |
|
|
drivers/scsi/scsi_sysfs.c | 17 ----------------- |
|
|
drivers/scsi/sd.c | 2 ++ |
|
|
drivers/scsi/sr.c | 1 + |
|
|
include/scsi/scsi_driver.h | 1 + |
|
|
6 files changed, 5 insertions(+), 18 deletions(-) |
|
|
|
|
|
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c |
|
|
index a82d2fe..16d21d2 100644 |
|
|
--- a/drivers/scsi/scsi_lib.c |
|
|
+++ b/drivers/scsi/scsi_lib.c |
|
|
@@ -1267,6 +1267,7 @@ int scsi_prep_fn(struct request_queue *q, struct request |
|
|
*req) |
|
|
ret = scsi_setup_blk_pc_cmnd(sdev, req); |
|
|
return scsi_prep_return(q, req, ret); |
|
7 |
} |
} |
8 |
+EXPORT_SYMBOL(scsi_prep_fn); |
+EXPORT_SYMBOL(scsi_prep_fn); |
9 |
|
|
10 |
/* |
/* |
11 |
* scsi_dev_queue_ready: if we can send requests to sdev, return 1 else |
* scsi_dev_queue_ready: if we can send requests to sdev, return 1 else |
12 |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h |
diff -Naur linux-2.6.29/drivers/scsi/scsi_priv.h linux-2.6.29-alx/drivers/scsi/scsi_priv.h |
13 |
index b33e725..8dd1e3b 100644 |
--- linux-2.6.29/drivers/scsi/scsi_priv.h 2009-03-24 00:12:14.000000000 +0100 |
14 |
--- a/drivers/scsi/scsi_priv.h |
+++ linux-2.6.29-alx/drivers/scsi/scsi_priv.h 2009-08-05 16:03:58.000000000 +0200 |
15 |
+++ b/drivers/scsi/scsi_priv.h |
@@ -74,7 +74,6 @@ |
|
@@ -76,7 +76,6 @@ extern int scsi_init_queue(void); |
|
16 |
extern void scsi_exit_queue(void); |
extern void scsi_exit_queue(void); |
17 |
struct request_queue; |
struct request_queue; |
18 |
struct request; |
struct request; |
19 |
-extern int scsi_prep_fn(struct request_queue *, struct request *); |
-extern int scsi_prep_fn(struct request_queue *, struct request *); |
20 |
|
extern struct kmem_cache *scsi_sdb_cache; |
21 |
|
|
22 |
/* scsi_proc.c */ |
/* scsi_proc.c */ |
23 |
#ifdef CONFIG_SCSI_PROC_FS |
diff -Naur linux-2.6.29/drivers/scsi/scsi_sysfs.c linux-2.6.29-alx/drivers/scsi/scsi_sysfs.c |
24 |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c |
--- linux-2.6.29/drivers/scsi/scsi_sysfs.c 2009-03-24 00:12:14.000000000 +0100 |
25 |
index 049103f..ad0b88b 100644 |
+++ linux-2.6.29-alx/drivers/scsi/scsi_sysfs.c 2009-08-05 16:04:41.000000000 +0200 |
26 |
--- a/drivers/scsi/scsi_sysfs.c |
@@ -420,29 +420,12 @@ |
27 |
+++ b/drivers/scsi/scsi_sysfs.c |
return err; |
|
@@ -410,29 +410,12 @@ static int scsi_bus_resume(struct device * dev) |
|
|
return err; |
|
28 |
} |
} |
29 |
|
|
30 |
-static int scsi_bus_remove(struct device *dev) |
-static int scsi_bus_remove(struct device *dev) |
31 |
-{ |
-{ |
32 |
- struct device_driver *drv = dev->driver; |
- struct device_driver *drv = dev->driver; |
33 |
- struct scsi_device *sdev = to_scsi_device(dev); |
- struct scsi_device *sdev = to_scsi_device(dev); |
34 |
- int err = 0; |
- int err = 0; |
35 |
- |
- |
36 |
- /* reset the prep_fn back to the default since the |
- /* reset the prep_fn back to the default since the |
37 |
- * driver may have altered it and it's being removed */ |
- * driver may have altered it and it's being removed */ |
38 |
- blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn); |
- blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn); |
39 |
- |
- |
40 |
- if (drv && drv->remove) |
- if (drv && drv->remove) |
41 |
- err = drv->remove(dev); |
- err = drv->remove(dev); |
42 |
- |
- |
43 |
- return 0; |
- return 0; |
44 |
-} |
-} |
45 |
- |
- |
46 |
struct bus_type scsi_bus_type = { |
struct bus_type scsi_bus_type = { |
47 |
.name = "scsi", |
.name = "scsi", |
48 |
.match = scsi_bus_match, |
.match = scsi_bus_match, |
49 |
.uevent = scsi_bus_uevent, |
.uevent = scsi_bus_uevent, |
50 |
.suspend = scsi_bus_suspend, |
.suspend = scsi_bus_suspend, |
51 |
.resume = scsi_bus_resume, |
.resume = scsi_bus_resume, |
52 |
- .remove = scsi_bus_remove, |
- .remove = scsi_bus_remove, |
53 |
}; |
}; |
54 |
|
EXPORT_SYMBOL_GPL(scsi_bus_type); |
55 |
int scsi_sysfs_register(void) |
|
56 |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c |
diff -Naur linux-2.6.29/drivers/scsi/sd.c linux-2.6.29-alx/drivers/scsi/sd.c |
57 |
index 01cefbb..672a17a 100644 |
--- linux-2.6.29/drivers/scsi/sd.c 2009-03-24 00:12:14.000000000 +0100 |
58 |
--- a/drivers/scsi/sd.c |
+++ linux-2.6.29-alx/drivers/scsi/sd.c 2009-08-05 16:05:26.000000000 +0200 |
59 |
+++ b/drivers/scsi/sd.c |
@@ -1961,6 +1961,8 @@ |
|
@@ -1743,6 +1743,8 @@ static int sd_remove(struct device *dev) |
|
60 |
{ |
{ |
61 |
struct scsi_disk *sdkp = dev_get_drvdata(dev); |
struct scsi_disk *sdkp = dev_get_drvdata(dev); |
62 |
|
|
63 |
+ blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); |
+ blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); |
64 |
+ |
+ |
65 |
device_del(&sdkp->dev); |
device_del(&sdkp->dev); |
66 |
del_gendisk(sdkp->disk); |
del_gendisk(sdkp->disk); |
67 |
sd_shutdown(dev); |
sd_shutdown(dev); |
68 |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c |
diff -Naur linux-2.6.29/drivers/scsi/sr.c linux-2.6.29-alx/drivers/scsi/sr.c |
69 |
index 7ee86d4..5860dc7 100644 |
--- linux-2.6.29/drivers/scsi/sr.c 2009-03-24 00:12:14.000000000 +0100 |
70 |
--- a/drivers/scsi/sr.c |
+++ linux-2.6.29-alx/drivers/scsi/sr.c 2009-08-05 16:06:09.000000000 +0200 |
71 |
+++ b/drivers/scsi/sr.c |
@@ -889,6 +889,7 @@ |
|
@@ -901,6 +901,7 @@ static int sr_remove(struct device *dev) |
|
72 |
{ |
{ |
73 |
struct scsi_cd *cd = dev_get_drvdata(dev); |
struct scsi_cd *cd = dev_get_drvdata(dev); |
74 |
|
|
75 |
+ blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); |
+ blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); |
76 |
del_gendisk(cd->disk); |
del_gendisk(cd->disk); |
77 |
|
|
78 |
mutex_lock(&sr_ref_mutex); |
mutex_lock(&sr_ref_mutex); |
79 |
diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h |
diff -Naur linux-2.6.29/include/scsi/scsi_driver.h linux-2.6.29-alx/include/scsi/scsi_driver.h |
80 |
index 1f5ca7f..9fd6702 100644 |
--- linux-2.6.29/include/scsi/scsi_driver.h 2009-03-24 00:12:14.000000000 +0100 |
81 |
--- a/include/scsi/scsi_driver.h |
+++ linux-2.6.29-alx/include/scsi/scsi_driver.h 2009-08-05 16:06:52.000000000 +0200 |
82 |
+++ b/include/scsi/scsi_driver.h |
@@ -32,5 +32,6 @@ |
|
@@ -32,5 +32,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct |
|
|
request *req); |
|
83 |
int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); |
int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); |
84 |
int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); |
int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); |
85 |
int scsi_prep_return(struct request_queue *q, struct request *req, int ret); |
int scsi_prep_return(struct request_queue *q, struct request *req, int ret); |
86 |
+int scsi_prep_fn(struct request_queue *, struct request *); |
+int scsi_prep_fn(struct request_queue *, struct request *); |
87 |
|
|
88 |
#endif /* _SCSI_SCSI_DRIVER_H */ |
#endif /* _SCSI_SCSI_DRIVER_H */ |