Annotation of /trunk/kernel26-alx/patches-2.6.29-r1/0310-2.6.29-fix-scsi-issues.patch
Parent Directory | Revision Log
Revision 876 -
(hide annotations)
(download)
Wed Aug 5 13:52:01 2009 UTC (14 years, 10 months ago) by niro
File size: 5533 byte(s)
Wed Aug 5 13:52:01 2009 UTC (14 years, 10 months ago) by niro
File size: 5533 byte(s)
*** empty log message ***
1 | niro | 876 | On Sun, 2008-05-04 at 09:34 -0500, James Bottomley wrote: |
2 | > On Sat, 2008-05-03 at 17:22 -0700, bugme-daemon@bugzilla.kernel.org | ||
3 | > wrote: | ||
4 | > > http://bugzilla.kernel.org/show_bug.cgi?id=9872 | ||
5 | > | ||
6 | > This isn't a bug. There have been numerous discussions about fixing it. | ||
7 | |||
8 | It is a kind of a "bug". The core does not call driver functions, if | ||
9 | bus_type is provided. So the warning is fine according to the current | ||
10 | logic of the core, telling you it will ignore things a driver asked for. | ||
11 | |||
12 | > The warning comes out of here in drivers/base/driver.c: | ||
13 | > | ||
14 | > if ((drv->bus->probe && drv->probe) || | ||
15 | > (drv->bus->remove && drv->remove) || | ||
16 | > (drv->bus->shutdown && drv->shutdown)) | ||
17 | > printk(KERN_WARNING "Driver '%s' needs updating - please use " | ||
18 | > "bus_type methods\n", drv->name); | ||
19 | > | ||
20 | > The problem is that SCSI drivers have both: SCSI uses the bus methods to | ||
21 | > trigger the probe and remove (as it must having a bus method) but it | ||
22 | > also uses the individual struct driver probe and remove methods to | ||
23 | > rethrow the events to the ULDs. | ||
24 | |||
25 | Looks like it does not use probe() on the bus. Now lets get rid of | ||
26 | remove(). :) | ||
27 | |||
28 | > According to Kay and Greg, this is a legitimate way of operating, and | ||
29 | > they're not going to remove the driver methods (otherwise we'd just take | ||
30 | > them into struct scsi_driver), so we're stuck trying to find a way to | ||
31 | > prevent the base warning about this. | ||
32 | |||
33 | Right, I guess, they are not going away, but you still should only use | ||
34 | one of them, and not both at the same time. | ||
35 | |||
36 | How about the following patch? Which does not use driver core pointers, | ||
37 | which are ignored by the core, to do private SCSI stuff. | ||
38 | |||
39 | Thanks, | ||
40 | Kay | ||
41 | |||
42 | |||
43 | |||
44 | From: Hannes Reinecke <hare@suse.de> | ||
45 | Subject: SCSI: do not use bus_type->remove() and driver->remove() at the same | ||
46 | time | ||
47 | |||
48 | If a driver sets blk_queue_prep_rq(), it should clean it up itself, and | ||
49 | not from the bus callbacks. This removes the need to hook into bus->remove(), | ||
50 | which should not be used at the same time as driver->remove(). | ||
51 | |||
52 | Signed-off-by: Hannes Reinecke <hare@suse.de> | ||
53 | Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> | ||
54 | --- | ||
55 | |||
56 | drivers/scsi/scsi_lib.c | 1 + | ||
57 | drivers/scsi/scsi_priv.h | 1 - | ||
58 | drivers/scsi/scsi_sysfs.c | 17 ----------------- | ||
59 | drivers/scsi/sd.c | 2 ++ | ||
60 | drivers/scsi/sr.c | 1 + | ||
61 | include/scsi/scsi_driver.h | 1 + | ||
62 | 6 files changed, 5 insertions(+), 18 deletions(-) | ||
63 | |||
64 | diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c | ||
65 | index a82d2fe..16d21d2 100644 | ||
66 | --- a/drivers/scsi/scsi_lib.c | ||
67 | +++ b/drivers/scsi/scsi_lib.c | ||
68 | @@ -1267,6 +1267,7 @@ int scsi_prep_fn(struct request_queue *q, struct request | ||
69 | *req) | ||
70 | ret = scsi_setup_blk_pc_cmnd(sdev, req); | ||
71 | return scsi_prep_return(q, req, ret); | ||
72 | } | ||
73 | +EXPORT_SYMBOL(scsi_prep_fn); | ||
74 | |||
75 | /* | ||
76 | * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else | ||
77 | diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h | ||
78 | index b33e725..8dd1e3b 100644 | ||
79 | --- a/drivers/scsi/scsi_priv.h | ||
80 | +++ b/drivers/scsi/scsi_priv.h | ||
81 | @@ -76,7 +76,6 @@ extern int scsi_init_queue(void); | ||
82 | extern void scsi_exit_queue(void); | ||
83 | struct request_queue; | ||
84 | struct request; | ||
85 | -extern int scsi_prep_fn(struct request_queue *, struct request *); | ||
86 | |||
87 | /* scsi_proc.c */ | ||
88 | #ifdef CONFIG_SCSI_PROC_FS | ||
89 | diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c | ||
90 | index 049103f..ad0b88b 100644 | ||
91 | --- a/drivers/scsi/scsi_sysfs.c | ||
92 | +++ b/drivers/scsi/scsi_sysfs.c | ||
93 | @@ -410,29 +410,12 @@ static int scsi_bus_resume(struct device * dev) | ||
94 | return err; | ||
95 | } | ||
96 | |||
97 | -static int scsi_bus_remove(struct device *dev) | ||
98 | -{ | ||
99 | - struct device_driver *drv = dev->driver; | ||
100 | - struct scsi_device *sdev = to_scsi_device(dev); | ||
101 | - int err = 0; | ||
102 | - | ||
103 | - /* reset the prep_fn back to the default since the | ||
104 | - * driver may have altered it and it's being removed */ | ||
105 | - blk_queue_prep_rq(sdev->request_queue, scsi_prep_fn); | ||
106 | - | ||
107 | - if (drv && drv->remove) | ||
108 | - err = drv->remove(dev); | ||
109 | - | ||
110 | - return 0; | ||
111 | -} | ||
112 | - | ||
113 | struct bus_type scsi_bus_type = { | ||
114 | .name = "scsi", | ||
115 | .match = scsi_bus_match, | ||
116 | .uevent = scsi_bus_uevent, | ||
117 | .suspend = scsi_bus_suspend, | ||
118 | .resume = scsi_bus_resume, | ||
119 | - .remove = scsi_bus_remove, | ||
120 | }; | ||
121 | |||
122 | int scsi_sysfs_register(void) | ||
123 | diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c | ||
124 | index 01cefbb..672a17a 100644 | ||
125 | --- a/drivers/scsi/sd.c | ||
126 | +++ b/drivers/scsi/sd.c | ||
127 | @@ -1743,6 +1743,8 @@ static int sd_remove(struct device *dev) | ||
128 | { | ||
129 | struct scsi_disk *sdkp = dev_get_drvdata(dev); | ||
130 | |||
131 | + blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); | ||
132 | + | ||
133 | device_del(&sdkp->dev); | ||
134 | del_gendisk(sdkp->disk); | ||
135 | sd_shutdown(dev); | ||
136 | diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c | ||
137 | index 7ee86d4..5860dc7 100644 | ||
138 | --- a/drivers/scsi/sr.c | ||
139 | +++ b/drivers/scsi/sr.c | ||
140 | @@ -901,6 +901,7 @@ static int sr_remove(struct device *dev) | ||
141 | { | ||
142 | struct scsi_cd *cd = dev_get_drvdata(dev); | ||
143 | |||
144 | + blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); | ||
145 | del_gendisk(cd->disk); | ||
146 | |||
147 | mutex_lock(&sr_ref_mutex); | ||
148 | diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h | ||
149 | index 1f5ca7f..9fd6702 100644 | ||
150 | --- a/include/scsi/scsi_driver.h | ||
151 | +++ b/include/scsi/scsi_driver.h | ||
152 | @@ -32,5 +32,6 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct | ||
153 | request *req); | ||
154 | int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); | ||
155 | int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); | ||
156 | int scsi_prep_return(struct request_queue *q, struct request *req, int ret); | ||
157 | +int scsi_prep_fn(struct request_queue *, struct request *); | ||
158 | |||
159 | #endif /* _SCSI_SCSI_DRIVER_H */ |