diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-11 21:15:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-09-11 21:15:18 -0400 |
commit | 8e78b7dc93c580c050435b0f88991c26e02166bc (patch) | |
tree | 3356cfe6423b049f2f4852bffb5a6324b0556dc1 /drivers/scsi | |
parent | 06a660ada2064bbdcd09aeb8173f2ad128c71978 (diff) | |
parent | 294ab783ad98066b87296db1311c7ba2a60206a5 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull second round of SCSI updates from James Bottomley:
"There's one late arriving patch here (added today), fixing a build
issue which the scsi_dh patch set in here uncovered. Other than that,
everything has been incubated in -next and the checkers for a week.
The major pieces of this patch are a set patches facilitating better
integration between scsi and scsi_dh (the device handling layer used
by multi-path; all the dm parts are acked by Mike Snitzer).
This also includes driver updates for mp3sas, scsi_debug and an
assortment of bug fixes"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (50 commits)
scsi_dh: fix randconfig build error
scsi: fix scsi_error_handler vs. scsi_host_dev_release race
fcoe: Convert use of __constant_htons to htons
mpt2sas: setpci reset kernel oops fix
pm80xx: Don't override ts->stat on IO_OPEN_CNX_ERROR_HW_RESOURCE_BUSY
lpfc: Fix possible use-after-free and double free in lpfc_mbx_cmpl_rdp_page_a2()
bfa: Fix incorrect de-reference of pointer
bfa: Fix indentation
scsi_transport_sas: Remove check for SAS expander when querying bay/enclosure IDs.
scsi_debug: resp_request: remove unused variable
scsi_debug: fix REPORT LUNS Well Known LU
scsi_debug: schedule_resp fix input variable check
scsi_debug: make dump_sector static
scsi_debug: vfree is null safe so drop the check
scsi_debug: use SCSI_W_LUN_REPORT_LUNS instead of SAM2_WLUN_REPORT_LUNS;
scsi_debug: define pr_fmt() for consistent logging
mpt2sas: Refcount fw_events and fix unsafe list usage
mpt2sas: Refcount sas_device objects and fix unsafe list usage
scsi_dh: return SCSI_DH_NOTCONN in scsi_dh_activate()
scsi_dh: don't allow to detach device handlers at runtime
...
Diffstat (limited to 'drivers/scsi')
35 files changed, 1832 insertions, 1214 deletions
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 471d08791766..1a8c9b53fafa 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -172,6 +172,7 @@ scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o | |||
172 | scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o | 172 | scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o |
173 | scsi_mod-y += scsi_trace.o scsi_logging.o | 173 | scsi_mod-y += scsi_trace.o scsi_logging.o |
174 | scsi_mod-$(CONFIG_PM) += scsi_pm.o | 174 | scsi_mod-$(CONFIG_PM) += scsi_pm.o |
175 | scsi_mod-$(CONFIG_SCSI_DH) += scsi_dh.o | ||
175 | 176 | ||
176 | hv_storvsc-y := storvsc_drv.o | 177 | hv_storvsc-y := storvsc_drv.o |
177 | 178 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index edb43fda9f36..c831e30411fa 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c | |||
@@ -983,7 +983,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, | |||
983 | { | 983 | { |
984 | int err, i; | 984 | int err, i; |
985 | u32 offs, size; | 985 | u32 offs, size; |
986 | struct asd_ll_el *el; | 986 | struct asd_ll_el *el = NULL; |
987 | struct asd_ctrla_phy_settings *ps; | 987 | struct asd_ctrla_phy_settings *ps; |
988 | struct asd_ctrla_phy_settings dflt_ps; | 988 | struct asd_ctrla_phy_settings dflt_ps; |
989 | 989 | ||
@@ -1004,6 +1004,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, | |||
1004 | 1004 | ||
1005 | size = sizeof(struct asd_ctrla_phy_settings); | 1005 | size = sizeof(struct asd_ctrla_phy_settings); |
1006 | ps = &dflt_ps; | 1006 | ps = &dflt_ps; |
1007 | goto out_process; | ||
1007 | } | 1008 | } |
1008 | 1009 | ||
1009 | if (size == 0) | 1010 | if (size == 0) |
@@ -1028,7 +1029,7 @@ static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, | |||
1028 | ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); | 1029 | ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); |
1029 | goto out2; | 1030 | goto out2; |
1030 | } | 1031 | } |
1031 | 1032 | out_process: | |
1032 | err = asd_process_ctrla_phy_settings(asd_ha, ps); | 1033 | err = asd_process_ctrla_phy_settings(asd_ha, ps); |
1033 | if (err) { | 1034 | if (err) { |
1034 | ASD_DPRINTK("couldn't process ctrla phy settings\n"); | 1035 | ASD_DPRINTK("couldn't process ctrla phy settings\n"); |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 315d6d6dcfc8..98f7e8cca52d 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -3665,19 +3665,19 @@ bfa_cb_sfp_state_query(struct bfa_sfp_s *sfp) | |||
3665 | if (sfp->state_query_cbfn) | 3665 | if (sfp->state_query_cbfn) |
3666 | sfp->state_query_cbfn(sfp->state_query_cbarg, | 3666 | sfp->state_query_cbfn(sfp->state_query_cbarg, |
3667 | sfp->status); | 3667 | sfp->status); |
3668 | sfp->media = NULL; | 3668 | sfp->media = NULL; |
3669 | } | 3669 | } |
3670 | 3670 | ||
3671 | if (sfp->portspeed) { | 3671 | if (sfp->portspeed) { |
3672 | sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed); | 3672 | sfp->status = bfa_sfp_speed_valid(sfp, sfp->portspeed); |
3673 | if (sfp->state_query_cbfn) | 3673 | if (sfp->state_query_cbfn) |
3674 | sfp->state_query_cbfn(sfp->state_query_cbarg, | 3674 | sfp->state_query_cbfn(sfp->state_query_cbarg, |
3675 | sfp->status); | 3675 | sfp->status); |
3676 | sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; | 3676 | sfp->portspeed = BFA_PORT_SPEED_UNKNOWN; |
3677 | } | 3677 | } |
3678 | 3678 | ||
3679 | sfp->state_query_lock = 0; | 3679 | sfp->state_query_lock = 0; |
3680 | sfp->state_query_cbfn = NULL; | 3680 | sfp->state_query_cbfn = NULL; |
3681 | } | 3681 | } |
3682 | 3682 | ||
3683 | /* | 3683 | /* |
@@ -3878,7 +3878,7 @@ bfa_sfp_show_comp(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg) | |||
3878 | bfa_trc(sfp, sfp->data_valid); | 3878 | bfa_trc(sfp, sfp->data_valid); |
3879 | if (sfp->data_valid) { | 3879 | if (sfp->data_valid) { |
3880 | u32 size = sizeof(struct sfp_mem_s); | 3880 | u32 size = sizeof(struct sfp_mem_s); |
3881 | u8 *des = (u8 *) &(sfp->sfpmem); | 3881 | u8 *des = (u8 *)(sfp->sfpmem); |
3882 | memcpy(des, sfp->dbuf_kva, size); | 3882 | memcpy(des, sfp->dbuf_kva, size); |
3883 | } | 3883 | } |
3884 | /* | 3884 | /* |
diff --git a/drivers/scsi/device_handler/Kconfig b/drivers/scsi/device_handler/Kconfig index 69abd0ad48e2..e5647d59224f 100644 --- a/drivers/scsi/device_handler/Kconfig +++ b/drivers/scsi/device_handler/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | menuconfig SCSI_DH | 5 | menuconfig SCSI_DH |
6 | tristate "SCSI Device Handlers" | 6 | bool "SCSI Device Handlers" |
7 | depends on SCSI | 7 | depends on SCSI |
8 | default n | 8 | default n |
9 | help | 9 | help |
diff --git a/drivers/scsi/device_handler/Makefile b/drivers/scsi/device_handler/Makefile index e1d2ea083e15..09866c50fbb4 100644 --- a/drivers/scsi/device_handler/Makefile +++ b/drivers/scsi/device_handler/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # | 1 | # |
2 | # SCSI Device Handler | 2 | # SCSI Device Handler |
3 | # | 3 | # |
4 | obj-$(CONFIG_SCSI_DH) += scsi_dh.o | ||
5 | obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o | 4 | obj-$(CONFIG_SCSI_DH_RDAC) += scsi_dh_rdac.o |
6 | obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o | 5 | obj-$(CONFIG_SCSI_DH_HP_SW) += scsi_dh_hp_sw.o |
7 | obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o | 6 | obj-$(CONFIG_SCSI_DH_EMC) += scsi_dh_emc.o |
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c deleted file mode 100644 index 1efebc9eedfb..000000000000 --- a/drivers/scsi/device_handler/scsi_dh.c +++ /dev/null | |||
@@ -1,621 +0,0 @@ | |||
1 | /* | ||
2 | * SCSI device handler infrastruture. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | * | ||
18 | * Copyright IBM Corporation, 2007 | ||
19 | * Authors: | ||
20 | * Chandra Seetharaman <sekharan@us.ibm.com> | ||
21 | * Mike Anderson <andmike@linux.vnet.ibm.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/slab.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <scsi/scsi_dh.h> | ||
27 | #include "../scsi_priv.h" | ||
28 | |||
29 | static DEFINE_SPINLOCK(list_lock); | ||
30 | static LIST_HEAD(scsi_dh_list); | ||
31 | |||
32 | static struct scsi_device_handler *get_device_handler(const char *name) | ||
33 | { | ||
34 | struct scsi_device_handler *tmp, *found = NULL; | ||
35 | |||
36 | spin_lock(&list_lock); | ||
37 | list_for_each_entry(tmp, &scsi_dh_list, list) { | ||
38 | if (!strncmp(tmp->name, name, strlen(tmp->name))) { | ||
39 | found = tmp; | ||
40 | break; | ||
41 | } | ||
42 | } | ||
43 | spin_unlock(&list_lock); | ||
44 | return found; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * device_handler_match_function - Match a device handler to a device | ||
49 | * @sdev - SCSI device to be tested | ||
50 | * | ||
51 | * Tests @sdev against the match function of all registered device_handler. | ||
52 | * Returns the found device handler or NULL if not found. | ||
53 | */ | ||
54 | static struct scsi_device_handler * | ||
55 | device_handler_match_function(struct scsi_device *sdev) | ||
56 | { | ||
57 | struct scsi_device_handler *tmp_dh, *found_dh = NULL; | ||
58 | |||
59 | spin_lock(&list_lock); | ||
60 | list_for_each_entry(tmp_dh, &scsi_dh_list, list) { | ||
61 | if (tmp_dh->match && tmp_dh->match(sdev)) { | ||
62 | found_dh = tmp_dh; | ||
63 | break; | ||
64 | } | ||
65 | } | ||
66 | spin_unlock(&list_lock); | ||
67 | return found_dh; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * device_handler_match - Attach a device handler to a device | ||
72 | * @scsi_dh - The device handler to match against or NULL | ||
73 | * @sdev - SCSI device to be tested against @scsi_dh | ||
74 | * | ||
75 | * Tests @sdev against the device handler @scsi_dh or against | ||
76 | * all registered device_handler if @scsi_dh == NULL. | ||
77 | * Returns the found device handler or NULL if not found. | ||
78 | */ | ||
79 | static struct scsi_device_handler * | ||
80 | device_handler_match(struct scsi_device_handler *scsi_dh, | ||
81 | struct scsi_device *sdev) | ||
82 | { | ||
83 | struct scsi_device_handler *found_dh; | ||
84 | |||
85 | found_dh = device_handler_match_function(sdev); | ||
86 | |||
87 | if (scsi_dh && found_dh != scsi_dh) | ||
88 | found_dh = NULL; | ||
89 | |||
90 | return found_dh; | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * scsi_dh_handler_attach - Attach a device handler to a device | ||
95 | * @sdev - SCSI device the device handler should attach to | ||
96 | * @scsi_dh - The device handler to attach | ||
97 | */ | ||
98 | static int scsi_dh_handler_attach(struct scsi_device *sdev, | ||
99 | struct scsi_device_handler *scsi_dh) | ||
100 | { | ||
101 | struct scsi_dh_data *d; | ||
102 | |||
103 | if (sdev->scsi_dh_data) { | ||
104 | if (sdev->scsi_dh_data->scsi_dh != scsi_dh) | ||
105 | return -EBUSY; | ||
106 | |||
107 | kref_get(&sdev->scsi_dh_data->kref); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | if (!try_module_get(scsi_dh->module)) | ||
112 | return -EINVAL; | ||
113 | |||
114 | d = scsi_dh->attach(sdev); | ||
115 | if (IS_ERR(d)) { | ||
116 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%ld)\n", | ||
117 | scsi_dh->name, PTR_ERR(d)); | ||
118 | module_put(scsi_dh->module); | ||
119 | return PTR_ERR(d); | ||
120 | } | ||
121 | |||
122 | d->scsi_dh = scsi_dh; | ||
123 | kref_init(&d->kref); | ||
124 | d->sdev = sdev; | ||
125 | |||
126 | spin_lock_irq(sdev->request_queue->queue_lock); | ||
127 | sdev->scsi_dh_data = d; | ||
128 | spin_unlock_irq(sdev->request_queue->queue_lock); | ||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static void __detach_handler (struct kref *kref) | ||
133 | { | ||
134 | struct scsi_dh_data *scsi_dh_data = | ||
135 | container_of(kref, struct scsi_dh_data, kref); | ||
136 | struct scsi_device_handler *scsi_dh = scsi_dh_data->scsi_dh; | ||
137 | struct scsi_device *sdev = scsi_dh_data->sdev; | ||
138 | |||
139 | scsi_dh->detach(sdev); | ||
140 | |||
141 | spin_lock_irq(sdev->request_queue->queue_lock); | ||
142 | sdev->scsi_dh_data = NULL; | ||
143 | spin_unlock_irq(sdev->request_queue->queue_lock); | ||
144 | |||
145 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", scsi_dh->name); | ||
146 | module_put(scsi_dh->module); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * scsi_dh_handler_detach - Detach a device handler from a device | ||
151 | * @sdev - SCSI device the device handler should be detached from | ||
152 | * @scsi_dh - Device handler to be detached | ||
153 | * | ||
154 | * Detach from a device handler. If a device handler is specified, | ||
155 | * only detach if the currently attached handler matches @scsi_dh. | ||
156 | */ | ||
157 | static void scsi_dh_handler_detach(struct scsi_device *sdev, | ||
158 | struct scsi_device_handler *scsi_dh) | ||
159 | { | ||
160 | if (!sdev->scsi_dh_data) | ||
161 | return; | ||
162 | |||
163 | if (scsi_dh && scsi_dh != sdev->scsi_dh_data->scsi_dh) | ||
164 | return; | ||
165 | |||
166 | if (!scsi_dh) | ||
167 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
168 | |||
169 | if (scsi_dh) | ||
170 | kref_put(&sdev->scsi_dh_data->kref, __detach_handler); | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Functions for sysfs attribute 'dh_state' | ||
175 | */ | ||
176 | static ssize_t | ||
177 | store_dh_state(struct device *dev, struct device_attribute *attr, | ||
178 | const char *buf, size_t count) | ||
179 | { | ||
180 | struct scsi_device *sdev = to_scsi_device(dev); | ||
181 | struct scsi_device_handler *scsi_dh; | ||
182 | int err = -EINVAL; | ||
183 | |||
184 | if (sdev->sdev_state == SDEV_CANCEL || | ||
185 | sdev->sdev_state == SDEV_DEL) | ||
186 | return -ENODEV; | ||
187 | |||
188 | if (!sdev->scsi_dh_data) { | ||
189 | /* | ||
190 | * Attach to a device handler | ||
191 | */ | ||
192 | if (!(scsi_dh = get_device_handler(buf))) | ||
193 | return err; | ||
194 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
195 | } else { | ||
196 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
197 | if (!strncmp(buf, "detach", 6)) { | ||
198 | /* | ||
199 | * Detach from a device handler | ||
200 | */ | ||
201 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
202 | err = 0; | ||
203 | } else if (!strncmp(buf, "activate", 8)) { | ||
204 | /* | ||
205 | * Activate a device handler | ||
206 | */ | ||
207 | if (scsi_dh->activate) | ||
208 | err = scsi_dh->activate(sdev, NULL, NULL); | ||
209 | else | ||
210 | err = 0; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | return err<0?err:count; | ||
215 | } | ||
216 | |||
217 | static ssize_t | ||
218 | show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) | ||
219 | { | ||
220 | struct scsi_device *sdev = to_scsi_device(dev); | ||
221 | |||
222 | if (!sdev->scsi_dh_data) | ||
223 | return snprintf(buf, 20, "detached\n"); | ||
224 | |||
225 | return snprintf(buf, 20, "%s\n", sdev->scsi_dh_data->scsi_dh->name); | ||
226 | } | ||
227 | |||
228 | static struct device_attribute scsi_dh_state_attr = | ||
229 | __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, | ||
230 | store_dh_state); | ||
231 | |||
232 | /* | ||
233 | * scsi_dh_sysfs_attr_add - Callback for scsi_init_dh | ||
234 | */ | ||
235 | static int scsi_dh_sysfs_attr_add(struct device *dev, void *data) | ||
236 | { | ||
237 | struct scsi_device *sdev; | ||
238 | int err; | ||
239 | |||
240 | if (!scsi_is_sdev_device(dev)) | ||
241 | return 0; | ||
242 | |||
243 | sdev = to_scsi_device(dev); | ||
244 | |||
245 | err = device_create_file(&sdev->sdev_gendev, | ||
246 | &scsi_dh_state_attr); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * scsi_dh_sysfs_attr_remove - Callback for scsi_exit_dh | ||
253 | */ | ||
254 | static int scsi_dh_sysfs_attr_remove(struct device *dev, void *data) | ||
255 | { | ||
256 | struct scsi_device *sdev; | ||
257 | |||
258 | if (!scsi_is_sdev_device(dev)) | ||
259 | return 0; | ||
260 | |||
261 | sdev = to_scsi_device(dev); | ||
262 | |||
263 | device_remove_file(&sdev->sdev_gendev, | ||
264 | &scsi_dh_state_attr); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * scsi_dh_notifier - notifier chain callback | ||
271 | */ | ||
272 | static int scsi_dh_notifier(struct notifier_block *nb, | ||
273 | unsigned long action, void *data) | ||
274 | { | ||
275 | struct device *dev = data; | ||
276 | struct scsi_device *sdev; | ||
277 | int err = 0; | ||
278 | struct scsi_device_handler *devinfo = NULL; | ||
279 | |||
280 | if (!scsi_is_sdev_device(dev)) | ||
281 | return 0; | ||
282 | |||
283 | sdev = to_scsi_device(dev); | ||
284 | |||
285 | if (action == BUS_NOTIFY_ADD_DEVICE) { | ||
286 | err = device_create_file(dev, &scsi_dh_state_attr); | ||
287 | /* don't care about err */ | ||
288 | devinfo = device_handler_match(NULL, sdev); | ||
289 | if (devinfo) | ||
290 | err = scsi_dh_handler_attach(sdev, devinfo); | ||
291 | } else if (action == BUS_NOTIFY_DEL_DEVICE) { | ||
292 | device_remove_file(dev, &scsi_dh_state_attr); | ||
293 | scsi_dh_handler_detach(sdev, NULL); | ||
294 | } | ||
295 | return err; | ||
296 | } | ||
297 | |||
298 | /* | ||
299 | * scsi_dh_notifier_add - Callback for scsi_register_device_handler | ||
300 | */ | ||
301 | static int scsi_dh_notifier_add(struct device *dev, void *data) | ||
302 | { | ||
303 | struct scsi_device_handler *scsi_dh = data; | ||
304 | struct scsi_device *sdev; | ||
305 | |||
306 | if (!scsi_is_sdev_device(dev)) | ||
307 | return 0; | ||
308 | |||
309 | if (!get_device(dev)) | ||
310 | return 0; | ||
311 | |||
312 | sdev = to_scsi_device(dev); | ||
313 | |||
314 | if (device_handler_match(scsi_dh, sdev)) | ||
315 | scsi_dh_handler_attach(sdev, scsi_dh); | ||
316 | |||
317 | put_device(dev); | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | * scsi_dh_notifier_remove - Callback for scsi_unregister_device_handler | ||
324 | */ | ||
325 | static int scsi_dh_notifier_remove(struct device *dev, void *data) | ||
326 | { | ||
327 | struct scsi_device_handler *scsi_dh = data; | ||
328 | struct scsi_device *sdev; | ||
329 | |||
330 | if (!scsi_is_sdev_device(dev)) | ||
331 | return 0; | ||
332 | |||
333 | if (!get_device(dev)) | ||
334 | return 0; | ||
335 | |||
336 | sdev = to_scsi_device(dev); | ||
337 | |||
338 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
339 | |||
340 | put_device(dev); | ||
341 | |||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * scsi_register_device_handler - register a device handler personality | ||
347 | * module. | ||
348 | * @scsi_dh - device handler to be registered. | ||
349 | * | ||
350 | * Returns 0 on success, -EBUSY if handler already registered. | ||
351 | */ | ||
352 | int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) | ||
353 | { | ||
354 | |||
355 | if (get_device_handler(scsi_dh->name)) | ||
356 | return -EBUSY; | ||
357 | |||
358 | if (!scsi_dh->attach || !scsi_dh->detach) | ||
359 | return -EINVAL; | ||
360 | |||
361 | spin_lock(&list_lock); | ||
362 | list_add(&scsi_dh->list, &scsi_dh_list); | ||
363 | spin_unlock(&list_lock); | ||
364 | |||
365 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, scsi_dh_notifier_add); | ||
366 | printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); | ||
367 | |||
368 | return SCSI_DH_OK; | ||
369 | } | ||
370 | EXPORT_SYMBOL_GPL(scsi_register_device_handler); | ||
371 | |||
372 | /* | ||
373 | * scsi_unregister_device_handler - register a device handler personality | ||
374 | * module. | ||
375 | * @scsi_dh - device handler to be unregistered. | ||
376 | * | ||
377 | * Returns 0 on success, -ENODEV if handler not registered. | ||
378 | */ | ||
379 | int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) | ||
380 | { | ||
381 | |||
382 | if (!get_device_handler(scsi_dh->name)) | ||
383 | return -ENODEV; | ||
384 | |||
385 | bus_for_each_dev(&scsi_bus_type, NULL, scsi_dh, | ||
386 | scsi_dh_notifier_remove); | ||
387 | |||
388 | spin_lock(&list_lock); | ||
389 | list_del(&scsi_dh->list); | ||
390 | spin_unlock(&list_lock); | ||
391 | printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name); | ||
392 | |||
393 | return SCSI_DH_OK; | ||
394 | } | ||
395 | EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); | ||
396 | |||
397 | /* | ||
398 | * scsi_dh_activate - activate the path associated with the scsi_device | ||
399 | * corresponding to the given request queue. | ||
400 | * Returns immediately without waiting for activation to be completed. | ||
401 | * @q - Request queue that is associated with the scsi_device to be | ||
402 | * activated. | ||
403 | * @fn - Function to be called upon completion of the activation. | ||
404 | * Function fn is called with data (below) and the error code. | ||
405 | * Function fn may be called from the same calling context. So, | ||
406 | * do not hold the lock in the caller which may be needed in fn. | ||
407 | * @data - data passed to the function fn upon completion. | ||
408 | * | ||
409 | */ | ||
410 | int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) | ||
411 | { | ||
412 | int err = 0; | ||
413 | unsigned long flags; | ||
414 | struct scsi_device *sdev; | ||
415 | struct scsi_device_handler *scsi_dh = NULL; | ||
416 | struct device *dev = NULL; | ||
417 | |||
418 | spin_lock_irqsave(q->queue_lock, flags); | ||
419 | sdev = q->queuedata; | ||
420 | if (!sdev) { | ||
421 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
422 | err = SCSI_DH_NOSYS; | ||
423 | if (fn) | ||
424 | fn(data, err); | ||
425 | return err; | ||
426 | } | ||
427 | |||
428 | if (sdev->scsi_dh_data) | ||
429 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
430 | dev = get_device(&sdev->sdev_gendev); | ||
431 | if (!scsi_dh || !dev || | ||
432 | sdev->sdev_state == SDEV_CANCEL || | ||
433 | sdev->sdev_state == SDEV_DEL) | ||
434 | err = SCSI_DH_NOSYS; | ||
435 | if (sdev->sdev_state == SDEV_OFFLINE) | ||
436 | err = SCSI_DH_DEV_OFFLINED; | ||
437 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
438 | |||
439 | if (err) { | ||
440 | if (fn) | ||
441 | fn(data, err); | ||
442 | goto out; | ||
443 | } | ||
444 | |||
445 | if (scsi_dh->activate) | ||
446 | err = scsi_dh->activate(sdev, fn, data); | ||
447 | out: | ||
448 | put_device(dev); | ||
449 | return err; | ||
450 | } | ||
451 | EXPORT_SYMBOL_GPL(scsi_dh_activate); | ||
452 | |||
453 | /* | ||
454 | * scsi_dh_set_params - set the parameters for the device as per the | ||
455 | * string specified in params. | ||
456 | * @q - Request queue that is associated with the scsi_device for | ||
457 | * which the parameters to be set. | ||
458 | * @params - parameters in the following format | ||
459 | * "no_of_params\0param1\0param2\0param3\0...\0" | ||
460 | * for example, string for 2 parameters with value 10 and 21 | ||
461 | * is specified as "2\010\021\0". | ||
462 | */ | ||
463 | int scsi_dh_set_params(struct request_queue *q, const char *params) | ||
464 | { | ||
465 | int err = -SCSI_DH_NOSYS; | ||
466 | unsigned long flags; | ||
467 | struct scsi_device *sdev; | ||
468 | struct scsi_device_handler *scsi_dh = NULL; | ||
469 | |||
470 | spin_lock_irqsave(q->queue_lock, flags); | ||
471 | sdev = q->queuedata; | ||
472 | if (sdev && sdev->scsi_dh_data) | ||
473 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
474 | if (scsi_dh && scsi_dh->set_params && get_device(&sdev->sdev_gendev)) | ||
475 | err = 0; | ||
476 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
477 | |||
478 | if (err) | ||
479 | return err; | ||
480 | err = scsi_dh->set_params(sdev, params); | ||
481 | put_device(&sdev->sdev_gendev); | ||
482 | return err; | ||
483 | } | ||
484 | EXPORT_SYMBOL_GPL(scsi_dh_set_params); | ||
485 | |||
486 | /* | ||
487 | * scsi_dh_handler_exist - Return TRUE(1) if a device handler exists for | ||
488 | * the given name. FALSE(0) otherwise. | ||
489 | * @name - name of the device handler. | ||
490 | */ | ||
491 | int scsi_dh_handler_exist(const char *name) | ||
492 | { | ||
493 | return (get_device_handler(name) != NULL); | ||
494 | } | ||
495 | EXPORT_SYMBOL_GPL(scsi_dh_handler_exist); | ||
496 | |||
497 | /* | ||
498 | * scsi_dh_attach - Attach device handler | ||
499 | * @q - Request queue that is associated with the scsi_device | ||
500 | * the handler should be attached to | ||
501 | * @name - name of the handler to attach | ||
502 | */ | ||
503 | int scsi_dh_attach(struct request_queue *q, const char *name) | ||
504 | { | ||
505 | unsigned long flags; | ||
506 | struct scsi_device *sdev; | ||
507 | struct scsi_device_handler *scsi_dh; | ||
508 | int err = 0; | ||
509 | |||
510 | scsi_dh = get_device_handler(name); | ||
511 | if (!scsi_dh) | ||
512 | return -EINVAL; | ||
513 | |||
514 | spin_lock_irqsave(q->queue_lock, flags); | ||
515 | sdev = q->queuedata; | ||
516 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
517 | err = -ENODEV; | ||
518 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
519 | |||
520 | if (!err) { | ||
521 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
522 | put_device(&sdev->sdev_gendev); | ||
523 | } | ||
524 | return err; | ||
525 | } | ||
526 | EXPORT_SYMBOL_GPL(scsi_dh_attach); | ||
527 | |||
528 | /* | ||
529 | * scsi_dh_detach - Detach device handler | ||
530 | * @q - Request queue that is associated with the scsi_device | ||
531 | * the handler should be detached from | ||
532 | * | ||
533 | * This function will detach the device handler only | ||
534 | * if the sdev is not part of the internal list, ie | ||
535 | * if it has been attached manually. | ||
536 | */ | ||
537 | void scsi_dh_detach(struct request_queue *q) | ||
538 | { | ||
539 | unsigned long flags; | ||
540 | struct scsi_device *sdev; | ||
541 | struct scsi_device_handler *scsi_dh = NULL; | ||
542 | |||
543 | spin_lock_irqsave(q->queue_lock, flags); | ||
544 | sdev = q->queuedata; | ||
545 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
546 | sdev = NULL; | ||
547 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
548 | |||
549 | if (!sdev) | ||
550 | return; | ||
551 | |||
552 | if (sdev->scsi_dh_data) { | ||
553 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | ||
554 | scsi_dh_handler_detach(sdev, scsi_dh); | ||
555 | } | ||
556 | put_device(&sdev->sdev_gendev); | ||
557 | } | ||
558 | EXPORT_SYMBOL_GPL(scsi_dh_detach); | ||
559 | |||
560 | /* | ||
561 | * scsi_dh_attached_handler_name - Get attached device handler's name | ||
562 | * @q - Request queue that is associated with the scsi_device | ||
563 | * that may have a device handler attached | ||
564 | * @gfp - the GFP mask used in the kmalloc() call when allocating memory | ||
565 | * | ||
566 | * Returns name of attached handler, NULL if no handler is attached. | ||
567 | * Caller must take care to free the returned string. | ||
568 | */ | ||
569 | const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp) | ||
570 | { | ||
571 | unsigned long flags; | ||
572 | struct scsi_device *sdev; | ||
573 | const char *handler_name = NULL; | ||
574 | |||
575 | spin_lock_irqsave(q->queue_lock, flags); | ||
576 | sdev = q->queuedata; | ||
577 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
578 | sdev = NULL; | ||
579 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
580 | |||
581 | if (!sdev) | ||
582 | return NULL; | ||
583 | |||
584 | if (sdev->scsi_dh_data) | ||
585 | handler_name = kstrdup(sdev->scsi_dh_data->scsi_dh->name, gfp); | ||
586 | |||
587 | put_device(&sdev->sdev_gendev); | ||
588 | return handler_name; | ||
589 | } | ||
590 | EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name); | ||
591 | |||
592 | static struct notifier_block scsi_dh_nb = { | ||
593 | .notifier_call = scsi_dh_notifier | ||
594 | }; | ||
595 | |||
596 | static int __init scsi_dh_init(void) | ||
597 | { | ||
598 | int r; | ||
599 | |||
600 | r = bus_register_notifier(&scsi_bus_type, &scsi_dh_nb); | ||
601 | |||
602 | if (!r) | ||
603 | bus_for_each_dev(&scsi_bus_type, NULL, NULL, | ||
604 | scsi_dh_sysfs_attr_add); | ||
605 | |||
606 | return r; | ||
607 | } | ||
608 | |||
609 | static void __exit scsi_dh_exit(void) | ||
610 | { | ||
611 | bus_for_each_dev(&scsi_bus_type, NULL, NULL, | ||
612 | scsi_dh_sysfs_attr_remove); | ||
613 | bus_unregister_notifier(&scsi_bus_type, &scsi_dh_nb); | ||
614 | } | ||
615 | |||
616 | module_init(scsi_dh_init); | ||
617 | module_exit(scsi_dh_exit); | ||
618 | |||
619 | MODULE_DESCRIPTION("SCSI device handler"); | ||
620 | MODULE_AUTHOR("Chandra Seetharaman <sekharan@us.ibm.com>"); | ||
621 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 854b568b9931..cc2773b5de68 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #define ALUA_OPTIMIZE_STPG 1 | 62 | #define ALUA_OPTIMIZE_STPG 1 |
63 | 63 | ||
64 | struct alua_dh_data { | 64 | struct alua_dh_data { |
65 | struct scsi_dh_data dh_data; | ||
66 | int group_id; | 65 | int group_id; |
67 | int rel_port; | 66 | int rel_port; |
68 | int tpgs; | 67 | int tpgs; |
@@ -86,11 +85,6 @@ struct alua_dh_data { | |||
86 | static char print_alua_state(int); | 85 | static char print_alua_state(int); |
87 | static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *); | 86 | static int alua_check_sense(struct scsi_device *, struct scsi_sense_hdr *); |
88 | 87 | ||
89 | static inline struct alua_dh_data *get_alua_data(struct scsi_device *sdev) | ||
90 | { | ||
91 | return container_of(sdev->scsi_dh_data, struct alua_dh_data, dh_data); | ||
92 | } | ||
93 | |||
94 | static int realloc_buffer(struct alua_dh_data *h, unsigned len) | 88 | static int realloc_buffer(struct alua_dh_data *h, unsigned len) |
95 | { | 89 | { |
96 | if (h->buff && h->buff != h->inq) | 90 | if (h->buff && h->buff != h->inq) |
@@ -708,7 +702,7 @@ out: | |||
708 | */ | 702 | */ |
709 | static int alua_set_params(struct scsi_device *sdev, const char *params) | 703 | static int alua_set_params(struct scsi_device *sdev, const char *params) |
710 | { | 704 | { |
711 | struct alua_dh_data *h = get_alua_data(sdev); | 705 | struct alua_dh_data *h = sdev->handler_data; |
712 | unsigned int optimize = 0, argc; | 706 | unsigned int optimize = 0, argc; |
713 | const char *p = params; | 707 | const char *p = params; |
714 | int result = SCSI_DH_OK; | 708 | int result = SCSI_DH_OK; |
@@ -746,7 +740,7 @@ MODULE_PARM_DESC(optimize_stpg, "Allow use of a non-optimized path, rather than | |||
746 | static int alua_activate(struct scsi_device *sdev, | 740 | static int alua_activate(struct scsi_device *sdev, |
747 | activate_complete fn, void *data) | 741 | activate_complete fn, void *data) |
748 | { | 742 | { |
749 | struct alua_dh_data *h = get_alua_data(sdev); | 743 | struct alua_dh_data *h = sdev->handler_data; |
750 | int err = SCSI_DH_OK; | 744 | int err = SCSI_DH_OK; |
751 | int stpg = 0; | 745 | int stpg = 0; |
752 | 746 | ||
@@ -804,7 +798,7 @@ out: | |||
804 | */ | 798 | */ |
805 | static int alua_prep_fn(struct scsi_device *sdev, struct request *req) | 799 | static int alua_prep_fn(struct scsi_device *sdev, struct request *req) |
806 | { | 800 | { |
807 | struct alua_dh_data *h = get_alua_data(sdev); | 801 | struct alua_dh_data *h = sdev->handler_data; |
808 | int ret = BLKPREP_OK; | 802 | int ret = BLKPREP_OK; |
809 | 803 | ||
810 | if (h->state == TPGS_STATE_TRANSITIONING) | 804 | if (h->state == TPGS_STATE_TRANSITIONING) |
@@ -819,23 +813,18 @@ static int alua_prep_fn(struct scsi_device *sdev, struct request *req) | |||
819 | 813 | ||
820 | } | 814 | } |
821 | 815 | ||
822 | static bool alua_match(struct scsi_device *sdev) | ||
823 | { | ||
824 | return (scsi_device_tpgs(sdev) != 0); | ||
825 | } | ||
826 | |||
827 | /* | 816 | /* |
828 | * alua_bus_attach - Attach device handler | 817 | * alua_bus_attach - Attach device handler |
829 | * @sdev: device to be attached to | 818 | * @sdev: device to be attached to |
830 | */ | 819 | */ |
831 | static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev) | 820 | static int alua_bus_attach(struct scsi_device *sdev) |
832 | { | 821 | { |
833 | struct alua_dh_data *h; | 822 | struct alua_dh_data *h; |
834 | int err; | 823 | int err; |
835 | 824 | ||
836 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 825 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
837 | if (!h) | 826 | if (!h) |
838 | return ERR_PTR(-ENOMEM); | 827 | return -ENOMEM; |
839 | h->tpgs = TPGS_MODE_UNINITIALIZED; | 828 | h->tpgs = TPGS_MODE_UNINITIALIZED; |
840 | h->state = TPGS_STATE_OPTIMIZED; | 829 | h->state = TPGS_STATE_OPTIMIZED; |
841 | h->group_id = -1; | 830 | h->group_id = -1; |
@@ -848,11 +837,11 @@ static struct scsi_dh_data *alua_bus_attach(struct scsi_device *sdev) | |||
848 | if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED) | 837 | if (err != SCSI_DH_OK && err != SCSI_DH_DEV_OFFLINED) |
849 | goto failed; | 838 | goto failed; |
850 | 839 | ||
851 | sdev_printk(KERN_NOTICE, sdev, "%s: Attached\n", ALUA_DH_NAME); | 840 | sdev->handler_data = h; |
852 | return &h->dh_data; | 841 | return 0; |
853 | failed: | 842 | failed: |
854 | kfree(h); | 843 | kfree(h); |
855 | return ERR_PTR(-EINVAL); | 844 | return -EINVAL; |
856 | } | 845 | } |
857 | 846 | ||
858 | /* | 847 | /* |
@@ -861,10 +850,11 @@ failed: | |||
861 | */ | 850 | */ |
862 | static void alua_bus_detach(struct scsi_device *sdev) | 851 | static void alua_bus_detach(struct scsi_device *sdev) |
863 | { | 852 | { |
864 | struct alua_dh_data *h = get_alua_data(sdev); | 853 | struct alua_dh_data *h = sdev->handler_data; |
865 | 854 | ||
866 | if (h->buff && h->inq != h->buff) | 855 | if (h->buff && h->inq != h->buff) |
867 | kfree(h->buff); | 856 | kfree(h->buff); |
857 | sdev->handler_data = NULL; | ||
868 | kfree(h); | 858 | kfree(h); |
869 | } | 859 | } |
870 | 860 | ||
@@ -877,7 +867,6 @@ static struct scsi_device_handler alua_dh = { | |||
877 | .check_sense = alua_check_sense, | 867 | .check_sense = alua_check_sense, |
878 | .activate = alua_activate, | 868 | .activate = alua_activate, |
879 | .set_params = alua_set_params, | 869 | .set_params = alua_set_params, |
880 | .match = alua_match, | ||
881 | }; | 870 | }; |
882 | 871 | ||
883 | static int __init alua_init(void) | 872 | static int __init alua_init(void) |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 6ed1caadbc6a..e6fb97cb12f4 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
@@ -72,7 +72,6 @@ static const char * lun_state[] = | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | struct clariion_dh_data { | 74 | struct clariion_dh_data { |
75 | struct scsi_dh_data dh_data; | ||
76 | /* | 75 | /* |
77 | * Flags: | 76 | * Flags: |
78 | * CLARIION_SHORT_TRESPASS | 77 | * CLARIION_SHORT_TRESPASS |
@@ -114,13 +113,6 @@ struct clariion_dh_data { | |||
114 | int current_sp; | 113 | int current_sp; |
115 | }; | 114 | }; |
116 | 115 | ||
117 | static inline struct clariion_dh_data | ||
118 | *get_clariion_data(struct scsi_device *sdev) | ||
119 | { | ||
120 | return container_of(sdev->scsi_dh_data, struct clariion_dh_data, | ||
121 | dh_data); | ||
122 | } | ||
123 | |||
124 | /* | 116 | /* |
125 | * Parse MODE_SELECT cmd reply. | 117 | * Parse MODE_SELECT cmd reply. |
126 | */ | 118 | */ |
@@ -450,7 +442,7 @@ static int clariion_check_sense(struct scsi_device *sdev, | |||
450 | 442 | ||
451 | static int clariion_prep_fn(struct scsi_device *sdev, struct request *req) | 443 | static int clariion_prep_fn(struct scsi_device *sdev, struct request *req) |
452 | { | 444 | { |
453 | struct clariion_dh_data *h = get_clariion_data(sdev); | 445 | struct clariion_dh_data *h = sdev->handler_data; |
454 | int ret = BLKPREP_OK; | 446 | int ret = BLKPREP_OK; |
455 | 447 | ||
456 | if (h->lun_state != CLARIION_LUN_OWNED) { | 448 | if (h->lun_state != CLARIION_LUN_OWNED) { |
@@ -533,7 +525,7 @@ retry: | |||
533 | static int clariion_activate(struct scsi_device *sdev, | 525 | static int clariion_activate(struct scsi_device *sdev, |
534 | activate_complete fn, void *data) | 526 | activate_complete fn, void *data) |
535 | { | 527 | { |
536 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | 528 | struct clariion_dh_data *csdev = sdev->handler_data; |
537 | int result; | 529 | int result; |
538 | 530 | ||
539 | result = clariion_send_inquiry(sdev, csdev); | 531 | result = clariion_send_inquiry(sdev, csdev); |
@@ -574,7 +566,7 @@ done: | |||
574 | */ | 566 | */ |
575 | static int clariion_set_params(struct scsi_device *sdev, const char *params) | 567 | static int clariion_set_params(struct scsi_device *sdev, const char *params) |
576 | { | 568 | { |
577 | struct clariion_dh_data *csdev = get_clariion_data(sdev); | 569 | struct clariion_dh_data *csdev = sdev->handler_data; |
578 | unsigned int hr = 0, st = 0, argc; | 570 | unsigned int hr = 0, st = 0, argc; |
579 | const char *p = params; | 571 | const char *p = params; |
580 | int result = SCSI_DH_OK; | 572 | int result = SCSI_DH_OK; |
@@ -622,42 +614,14 @@ done: | |||
622 | return result; | 614 | return result; |
623 | } | 615 | } |
624 | 616 | ||
625 | static const struct { | 617 | static int clariion_bus_attach(struct scsi_device *sdev) |
626 | char *vendor; | ||
627 | char *model; | ||
628 | } clariion_dev_list[] = { | ||
629 | {"DGC", "RAID"}, | ||
630 | {"DGC", "DISK"}, | ||
631 | {"DGC", "VRAID"}, | ||
632 | {NULL, NULL}, | ||
633 | }; | ||
634 | |||
635 | static bool clariion_match(struct scsi_device *sdev) | ||
636 | { | ||
637 | int i; | ||
638 | |||
639 | if (scsi_device_tpgs(sdev)) | ||
640 | return false; | ||
641 | |||
642 | for (i = 0; clariion_dev_list[i].vendor; i++) { | ||
643 | if (!strncmp(sdev->vendor, clariion_dev_list[i].vendor, | ||
644 | strlen(clariion_dev_list[i].vendor)) && | ||
645 | !strncmp(sdev->model, clariion_dev_list[i].model, | ||
646 | strlen(clariion_dev_list[i].model))) { | ||
647 | return true; | ||
648 | } | ||
649 | } | ||
650 | return false; | ||
651 | } | ||
652 | |||
653 | static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev) | ||
654 | { | 618 | { |
655 | struct clariion_dh_data *h; | 619 | struct clariion_dh_data *h; |
656 | int err; | 620 | int err; |
657 | 621 | ||
658 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 622 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
659 | if (!h) | 623 | if (!h) |
660 | return ERR_PTR(-ENOMEM); | 624 | return -ENOMEM; |
661 | h->lun_state = CLARIION_LUN_UNINITIALIZED; | 625 | h->lun_state = CLARIION_LUN_UNINITIALIZED; |
662 | h->default_sp = CLARIION_UNBOUND_LU; | 626 | h->default_sp = CLARIION_UNBOUND_LU; |
663 | h->current_sp = CLARIION_UNBOUND_LU; | 627 | h->current_sp = CLARIION_UNBOUND_LU; |
@@ -675,18 +639,19 @@ static struct scsi_dh_data *clariion_bus_attach(struct scsi_device *sdev) | |||
675 | CLARIION_NAME, h->current_sp + 'A', | 639 | CLARIION_NAME, h->current_sp + 'A', |
676 | h->port, lun_state[h->lun_state], | 640 | h->port, lun_state[h->lun_state], |
677 | h->default_sp + 'A'); | 641 | h->default_sp + 'A'); |
678 | return &h->dh_data; | 642 | |
643 | sdev->handler_data = h; | ||
644 | return 0; | ||
679 | 645 | ||
680 | failed: | 646 | failed: |
681 | kfree(h); | 647 | kfree(h); |
682 | return ERR_PTR(-EINVAL); | 648 | return -EINVAL; |
683 | } | 649 | } |
684 | 650 | ||
685 | static void clariion_bus_detach(struct scsi_device *sdev) | 651 | static void clariion_bus_detach(struct scsi_device *sdev) |
686 | { | 652 | { |
687 | struct clariion_dh_data *h = get_clariion_data(sdev); | 653 | kfree(sdev->handler_data); |
688 | 654 | sdev->handler_data = NULL; | |
689 | kfree(h); | ||
690 | } | 655 | } |
691 | 656 | ||
692 | static struct scsi_device_handler clariion_dh = { | 657 | static struct scsi_device_handler clariion_dh = { |
@@ -698,7 +663,6 @@ static struct scsi_device_handler clariion_dh = { | |||
698 | .activate = clariion_activate, | 663 | .activate = clariion_activate, |
699 | .prep_fn = clariion_prep_fn, | 664 | .prep_fn = clariion_prep_fn, |
700 | .set_params = clariion_set_params, | 665 | .set_params = clariion_set_params, |
701 | .match = clariion_match, | ||
702 | }; | 666 | }; |
703 | 667 | ||
704 | static int __init clariion_init(void) | 668 | static int __init clariion_init(void) |
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 485d99544a15..9406d5f4a3d3 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #define HP_SW_PATH_PASSIVE 1 | 38 | #define HP_SW_PATH_PASSIVE 1 |
39 | 39 | ||
40 | struct hp_sw_dh_data { | 40 | struct hp_sw_dh_data { |
41 | struct scsi_dh_data dh_data; | ||
42 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; | 41 | unsigned char sense[SCSI_SENSE_BUFFERSIZE]; |
43 | int path_state; | 42 | int path_state; |
44 | int retries; | 43 | int retries; |
@@ -50,11 +49,6 @@ struct hp_sw_dh_data { | |||
50 | 49 | ||
51 | static int hp_sw_start_stop(struct hp_sw_dh_data *); | 50 | static int hp_sw_start_stop(struct hp_sw_dh_data *); |
52 | 51 | ||
53 | static inline struct hp_sw_dh_data *get_hp_sw_data(struct scsi_device *sdev) | ||
54 | { | ||
55 | return container_of(sdev->scsi_dh_data, struct hp_sw_dh_data, dh_data); | ||
56 | } | ||
57 | |||
58 | /* | 52 | /* |
59 | * tur_done - Handle TEST UNIT READY return status | 53 | * tur_done - Handle TEST UNIT READY return status |
60 | * @sdev: sdev the command has been sent to | 54 | * @sdev: sdev the command has been sent to |
@@ -267,7 +261,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) | |||
267 | 261 | ||
268 | static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) | 262 | static int hp_sw_prep_fn(struct scsi_device *sdev, struct request *req) |
269 | { | 263 | { |
270 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | 264 | struct hp_sw_dh_data *h = sdev->handler_data; |
271 | int ret = BLKPREP_OK; | 265 | int ret = BLKPREP_OK; |
272 | 266 | ||
273 | if (h->path_state != HP_SW_PATH_ACTIVE) { | 267 | if (h->path_state != HP_SW_PATH_ACTIVE) { |
@@ -292,7 +286,7 @@ static int hp_sw_activate(struct scsi_device *sdev, | |||
292 | activate_complete fn, void *data) | 286 | activate_complete fn, void *data) |
293 | { | 287 | { |
294 | int ret = SCSI_DH_OK; | 288 | int ret = SCSI_DH_OK; |
295 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | 289 | struct hp_sw_dh_data *h = sdev->handler_data; |
296 | 290 | ||
297 | ret = hp_sw_tur(sdev, h); | 291 | ret = hp_sw_tur(sdev, h); |
298 | 292 | ||
@@ -311,43 +305,14 @@ static int hp_sw_activate(struct scsi_device *sdev, | |||
311 | return 0; | 305 | return 0; |
312 | } | 306 | } |
313 | 307 | ||
314 | static const struct { | 308 | static int hp_sw_bus_attach(struct scsi_device *sdev) |
315 | char *vendor; | ||
316 | char *model; | ||
317 | } hp_sw_dh_data_list[] = { | ||
318 | {"COMPAQ", "MSA1000 VOLUME"}, | ||
319 | {"COMPAQ", "HSV110"}, | ||
320 | {"HP", "HSV100"}, | ||
321 | {"DEC", "HSG80"}, | ||
322 | {NULL, NULL}, | ||
323 | }; | ||
324 | |||
325 | static bool hp_sw_match(struct scsi_device *sdev) | ||
326 | { | ||
327 | int i; | ||
328 | |||
329 | if (scsi_device_tpgs(sdev)) | ||
330 | return false; | ||
331 | |||
332 | for (i = 0; hp_sw_dh_data_list[i].vendor; i++) { | ||
333 | if (!strncmp(sdev->vendor, hp_sw_dh_data_list[i].vendor, | ||
334 | strlen(hp_sw_dh_data_list[i].vendor)) && | ||
335 | !strncmp(sdev->model, hp_sw_dh_data_list[i].model, | ||
336 | strlen(hp_sw_dh_data_list[i].model))) { | ||
337 | return true; | ||
338 | } | ||
339 | } | ||
340 | return false; | ||
341 | } | ||
342 | |||
343 | static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev) | ||
344 | { | 309 | { |
345 | struct hp_sw_dh_data *h; | 310 | struct hp_sw_dh_data *h; |
346 | int ret; | 311 | int ret; |
347 | 312 | ||
348 | h = kzalloc(sizeof(*h), GFP_KERNEL); | 313 | h = kzalloc(sizeof(*h), GFP_KERNEL); |
349 | if (!h) | 314 | if (!h) |
350 | return ERR_PTR(-ENOMEM); | 315 | return -ENOMEM; |
351 | h->path_state = HP_SW_PATH_UNINITIALIZED; | 316 | h->path_state = HP_SW_PATH_UNINITIALIZED; |
352 | h->retries = HP_SW_RETRIES; | 317 | h->retries = HP_SW_RETRIES; |
353 | h->sdev = sdev; | 318 | h->sdev = sdev; |
@@ -359,17 +324,18 @@ static struct scsi_dh_data *hp_sw_bus_attach(struct scsi_device *sdev) | |||
359 | sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", | 324 | sdev_printk(KERN_INFO, sdev, "%s: attached to %s path\n", |
360 | HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? | 325 | HP_SW_NAME, h->path_state == HP_SW_PATH_ACTIVE? |
361 | "active":"passive"); | 326 | "active":"passive"); |
362 | return &h->dh_data; | 327 | |
328 | sdev->handler_data = h; | ||
329 | return 0; | ||
363 | failed: | 330 | failed: |
364 | kfree(h); | 331 | kfree(h); |
365 | return ERR_PTR(-EINVAL); | 332 | return -EINVAL; |
366 | } | 333 | } |
367 | 334 | ||
368 | static void hp_sw_bus_detach( struct scsi_device *sdev ) | 335 | static void hp_sw_bus_detach( struct scsi_device *sdev ) |
369 | { | 336 | { |
370 | struct hp_sw_dh_data *h = get_hp_sw_data(sdev); | 337 | kfree(sdev->handler_data); |
371 | 338 | sdev->handler_data = NULL; | |
372 | kfree(h); | ||
373 | } | 339 | } |
374 | 340 | ||
375 | static struct scsi_device_handler hp_sw_dh = { | 341 | static struct scsi_device_handler hp_sw_dh = { |
@@ -379,7 +345,6 @@ static struct scsi_device_handler hp_sw_dh = { | |||
379 | .detach = hp_sw_bus_detach, | 345 | .detach = hp_sw_bus_detach, |
380 | .activate = hp_sw_activate, | 346 | .activate = hp_sw_activate, |
381 | .prep_fn = hp_sw_prep_fn, | 347 | .prep_fn = hp_sw_prep_fn, |
382 | .match = hp_sw_match, | ||
383 | }; | 348 | }; |
384 | 349 | ||
385 | static int __init hp_sw_init(void) | 350 | static int __init hp_sw_init(void) |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index b46ace3d4bf0..361358134315 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
@@ -181,7 +181,6 @@ struct c2_inquiry { | |||
181 | }; | 181 | }; |
182 | 182 | ||
183 | struct rdac_dh_data { | 183 | struct rdac_dh_data { |
184 | struct scsi_dh_data dh_data; | ||
185 | struct rdac_controller *ctlr; | 184 | struct rdac_controller *ctlr; |
186 | #define UNINITIALIZED_LUN (1 << 8) | 185 | #define UNINITIALIZED_LUN (1 << 8) |
187 | unsigned lun; | 186 | unsigned lun; |
@@ -260,11 +259,6 @@ do { \ | |||
260 | sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \ | 259 | sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \ |
261 | } while (0); | 260 | } while (0); |
262 | 261 | ||
263 | static inline struct rdac_dh_data *get_rdac_data(struct scsi_device *sdev) | ||
264 | { | ||
265 | return container_of(sdev->scsi_dh_data, struct rdac_dh_data, dh_data); | ||
266 | } | ||
267 | |||
268 | static struct request *get_rdac_req(struct scsi_device *sdev, | 262 | static struct request *get_rdac_req(struct scsi_device *sdev, |
269 | void *buffer, unsigned buflen, int rw) | 263 | void *buffer, unsigned buflen, int rw) |
270 | { | 264 | { |
@@ -544,7 +538,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev, | |||
544 | { | 538 | { |
545 | struct scsi_sense_hdr sense_hdr; | 539 | struct scsi_sense_hdr sense_hdr; |
546 | int err = SCSI_DH_IO, ret; | 540 | int err = SCSI_DH_IO, ret; |
547 | struct rdac_dh_data *h = get_rdac_data(sdev); | 541 | struct rdac_dh_data *h = sdev->handler_data; |
548 | 542 | ||
549 | ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr); | 543 | ret = scsi_normalize_sense(sensebuf, SCSI_SENSE_BUFFERSIZE, &sense_hdr); |
550 | if (!ret) | 544 | if (!ret) |
@@ -589,7 +583,7 @@ static void send_mode_select(struct work_struct *work) | |||
589 | container_of(work, struct rdac_controller, ms_work); | 583 | container_of(work, struct rdac_controller, ms_work); |
590 | struct request *rq; | 584 | struct request *rq; |
591 | struct scsi_device *sdev = ctlr->ms_sdev; | 585 | struct scsi_device *sdev = ctlr->ms_sdev; |
592 | struct rdac_dh_data *h = get_rdac_data(sdev); | 586 | struct rdac_dh_data *h = sdev->handler_data; |
593 | struct request_queue *q = sdev->request_queue; | 587 | struct request_queue *q = sdev->request_queue; |
594 | int err, retry_cnt = RDAC_RETRY_COUNT; | 588 | int err, retry_cnt = RDAC_RETRY_COUNT; |
595 | struct rdac_queue_data *tmp, *qdata; | 589 | struct rdac_queue_data *tmp, *qdata; |
@@ -648,7 +642,7 @@ static int queue_mode_select(struct scsi_device *sdev, | |||
648 | if (!qdata) | 642 | if (!qdata) |
649 | return SCSI_DH_RETRY; | 643 | return SCSI_DH_RETRY; |
650 | 644 | ||
651 | qdata->h = get_rdac_data(sdev); | 645 | qdata->h = sdev->handler_data; |
652 | qdata->callback_fn = fn; | 646 | qdata->callback_fn = fn; |
653 | qdata->callback_data = data; | 647 | qdata->callback_data = data; |
654 | 648 | ||
@@ -667,7 +661,7 @@ static int queue_mode_select(struct scsi_device *sdev, | |||
667 | static int rdac_activate(struct scsi_device *sdev, | 661 | static int rdac_activate(struct scsi_device *sdev, |
668 | activate_complete fn, void *data) | 662 | activate_complete fn, void *data) |
669 | { | 663 | { |
670 | struct rdac_dh_data *h = get_rdac_data(sdev); | 664 | struct rdac_dh_data *h = sdev->handler_data; |
671 | int err = SCSI_DH_OK; | 665 | int err = SCSI_DH_OK; |
672 | int act = 0; | 666 | int act = 0; |
673 | 667 | ||
@@ -702,7 +696,7 @@ done: | |||
702 | 696 | ||
703 | static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) | 697 | static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) |
704 | { | 698 | { |
705 | struct rdac_dh_data *h = get_rdac_data(sdev); | 699 | struct rdac_dh_data *h = sdev->handler_data; |
706 | int ret = BLKPREP_OK; | 700 | int ret = BLKPREP_OK; |
707 | 701 | ||
708 | if (h->state != RDAC_STATE_ACTIVE) { | 702 | if (h->state != RDAC_STATE_ACTIVE) { |
@@ -716,7 +710,7 @@ static int rdac_prep_fn(struct scsi_device *sdev, struct request *req) | |||
716 | static int rdac_check_sense(struct scsi_device *sdev, | 710 | static int rdac_check_sense(struct scsi_device *sdev, |
717 | struct scsi_sense_hdr *sense_hdr) | 711 | struct scsi_sense_hdr *sense_hdr) |
718 | { | 712 | { |
719 | struct rdac_dh_data *h = get_rdac_data(sdev); | 713 | struct rdac_dh_data *h = sdev->handler_data; |
720 | 714 | ||
721 | RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, " | 715 | RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, " |
722 | "I/O returned with sense %02x/%02x/%02x", | 716 | "I/O returned with sense %02x/%02x/%02x", |
@@ -778,56 +772,7 @@ static int rdac_check_sense(struct scsi_device *sdev, | |||
778 | return SCSI_RETURN_NOT_HANDLED; | 772 | return SCSI_RETURN_NOT_HANDLED; |
779 | } | 773 | } |
780 | 774 | ||
781 | static const struct { | 775 | static int rdac_bus_attach(struct scsi_device *sdev) |
782 | char *vendor; | ||
783 | char *model; | ||
784 | } rdac_dev_list[] = { | ||
785 | {"IBM", "1722"}, | ||
786 | {"IBM", "1724"}, | ||
787 | {"IBM", "1726"}, | ||
788 | {"IBM", "1742"}, | ||
789 | {"IBM", "1745"}, | ||
790 | {"IBM", "1746"}, | ||
791 | {"IBM", "1813"}, | ||
792 | {"IBM", "1814"}, | ||
793 | {"IBM", "1815"}, | ||
794 | {"IBM", "1818"}, | ||
795 | {"IBM", "3526"}, | ||
796 | {"SGI", "TP9"}, | ||
797 | {"SGI", "IS"}, | ||
798 | {"STK", "OPENstorage D280"}, | ||
799 | {"STK", "FLEXLINE 380"}, | ||
800 | {"SUN", "CSM"}, | ||
801 | {"SUN", "LCSM100"}, | ||
802 | {"SUN", "STK6580_6780"}, | ||
803 | {"SUN", "SUN_6180"}, | ||
804 | {"SUN", "ArrayStorage"}, | ||
805 | {"DELL", "MD3"}, | ||
806 | {"NETAPP", "INF-01-00"}, | ||
807 | {"LSI", "INF-01-00"}, | ||
808 | {"ENGENIO", "INF-01-00"}, | ||
809 | {NULL, NULL}, | ||
810 | }; | ||
811 | |||
812 | static bool rdac_match(struct scsi_device *sdev) | ||
813 | { | ||
814 | int i; | ||
815 | |||
816 | if (scsi_device_tpgs(sdev)) | ||
817 | return false; | ||
818 | |||
819 | for (i = 0; rdac_dev_list[i].vendor; i++) { | ||
820 | if (!strncmp(sdev->vendor, rdac_dev_list[i].vendor, | ||
821 | strlen(rdac_dev_list[i].vendor)) && | ||
822 | !strncmp(sdev->model, rdac_dev_list[i].model, | ||
823 | strlen(rdac_dev_list[i].model))) { | ||
824 | return true; | ||
825 | } | ||
826 | } | ||
827 | return false; | ||
828 | } | ||
829 | |||
830 | static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev) | ||
831 | { | 776 | { |
832 | struct rdac_dh_data *h; | 777 | struct rdac_dh_data *h; |
833 | int err; | 778 | int err; |
@@ -836,7 +781,7 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev) | |||
836 | 781 | ||
837 | h = kzalloc(sizeof(*h) , GFP_KERNEL); | 782 | h = kzalloc(sizeof(*h) , GFP_KERNEL); |
838 | if (!h) | 783 | if (!h) |
839 | return ERR_PTR(-ENOMEM); | 784 | return -ENOMEM; |
840 | h->lun = UNINITIALIZED_LUN; | 785 | h->lun = UNINITIALIZED_LUN; |
841 | h->state = RDAC_STATE_ACTIVE; | 786 | h->state = RDAC_STATE_ACTIVE; |
842 | 787 | ||
@@ -861,7 +806,8 @@ static struct scsi_dh_data *rdac_bus_attach(struct scsi_device *sdev) | |||
861 | RDAC_NAME, h->lun, mode[(int)h->mode], | 806 | RDAC_NAME, h->lun, mode[(int)h->mode], |
862 | lun_state[(int)h->lun_state]); | 807 | lun_state[(int)h->lun_state]); |
863 | 808 | ||
864 | return &h->dh_data; | 809 | sdev->handler_data = h; |
810 | return 0; | ||
865 | 811 | ||
866 | clean_ctlr: | 812 | clean_ctlr: |
867 | spin_lock(&list_lock); | 813 | spin_lock(&list_lock); |
@@ -870,12 +816,12 @@ clean_ctlr: | |||
870 | 816 | ||
871 | failed: | 817 | failed: |
872 | kfree(h); | 818 | kfree(h); |
873 | return ERR_PTR(-EINVAL); | 819 | return -EINVAL; |
874 | } | 820 | } |
875 | 821 | ||
876 | static void rdac_bus_detach( struct scsi_device *sdev ) | 822 | static void rdac_bus_detach( struct scsi_device *sdev ) |
877 | { | 823 | { |
878 | struct rdac_dh_data *h = get_rdac_data(sdev); | 824 | struct rdac_dh_data *h = sdev->handler_data; |
879 | 825 | ||
880 | if (h->ctlr && h->ctlr->ms_queued) | 826 | if (h->ctlr && h->ctlr->ms_queued) |
881 | flush_workqueue(kmpath_rdacd); | 827 | flush_workqueue(kmpath_rdacd); |
@@ -884,6 +830,7 @@ static void rdac_bus_detach( struct scsi_device *sdev ) | |||
884 | if (h->ctlr) | 830 | if (h->ctlr) |
885 | kref_put(&h->ctlr->kref, release_controller); | 831 | kref_put(&h->ctlr->kref, release_controller); |
886 | spin_unlock(&list_lock); | 832 | spin_unlock(&list_lock); |
833 | sdev->handler_data = NULL; | ||
887 | kfree(h); | 834 | kfree(h); |
888 | } | 835 | } |
889 | 836 | ||
@@ -895,7 +842,6 @@ static struct scsi_device_handler rdac_dh = { | |||
895 | .attach = rdac_bus_attach, | 842 | .attach = rdac_bus_attach, |
896 | .detach = rdac_bus_detach, | 843 | .detach = rdac_bus_detach, |
897 | .activate = rdac_activate, | 844 | .activate = rdac_activate, |
898 | .match = rdac_match, | ||
899 | }; | 845 | }; |
900 | 846 | ||
901 | static int __init rdac_init(void) | 847 | static int __init rdac_init(void) |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index ec193a8357d7..d3eb80c46bbe 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -364,7 +364,7 @@ static int fcoe_interface_setup(struct fcoe_interface *fcoe, | |||
364 | * on the ethertype for the given device | 364 | * on the ethertype for the given device |
365 | */ | 365 | */ |
366 | fcoe->fcoe_packet_type.func = fcoe_rcv; | 366 | fcoe->fcoe_packet_type.func = fcoe_rcv; |
367 | fcoe->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE); | 367 | fcoe->fcoe_packet_type.type = htons(ETH_P_FCOE); |
368 | fcoe->fcoe_packet_type.dev = netdev; | 368 | fcoe->fcoe_packet_type.dev = netdev; |
369 | dev_add_pack(&fcoe->fcoe_packet_type); | 369 | dev_add_pack(&fcoe->fcoe_packet_type); |
370 | 370 | ||
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 341191952155..b62836ddbbee 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -4555,7 +4555,7 @@ static ssize_t ipr_store_raw_mode(struct device *dev, | |||
4555 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 4555 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
4556 | res = (struct ipr_resource_entry *)sdev->hostdata; | 4556 | res = (struct ipr_resource_entry *)sdev->hostdata; |
4557 | if (res) { | 4557 | if (res) { |
4558 | if (ioa_cfg->sis64 && ipr_is_af_dasd_device(res)) { | 4558 | if (ipr_is_af_dasd_device(res)) { |
4559 | res->raw_mode = simple_strtoul(buf, NULL, 10); | 4559 | res->raw_mode = simple_strtoul(buf, NULL, 10); |
4560 | len = strlen(buf); | 4560 | len = strlen(buf); |
4561 | if (res->sdev) | 4561 | if (res->sdev) |
@@ -6383,9 +6383,13 @@ static int ipr_queuecommand(struct Scsi_Host *shost, | |||
6383 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) { | 6383 | (!ipr_is_gscsi(res) || scsi_cmd->cmnd[0] == IPR_QUERY_RSRC_STATE)) { |
6384 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; | 6384 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_IOACMD; |
6385 | } | 6385 | } |
6386 | if (res->raw_mode && ipr_is_af_dasd_device(res)) | 6386 | if (res->raw_mode && ipr_is_af_dasd_device(res)) { |
6387 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_PIPE; | 6387 | ioarcb->cmd_pkt.request_type = IPR_RQTYPE_PIPE; |
6388 | 6388 | ||
6389 | if (scsi_cmd->underflow == 0) | ||
6390 | ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_ULEN_CHK; | ||
6391 | } | ||
6392 | |||
6389 | if (ioa_cfg->sis64) | 6393 | if (ioa_cfg->sis64) |
6390 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); | 6394 | rc = ipr_build_ioadl64(ioa_cfg, ipr_cmd); |
6391 | else | 6395 | else |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index eb627724417e..4abb93a83e0f 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
@@ -2284,7 +2284,7 @@ lpfc_mbx_cmpl_rdp_page_a2(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | |||
2284 | (struct lpfc_rdp_context *)(mbox->context2); | 2284 | (struct lpfc_rdp_context *)(mbox->context2); |
2285 | 2285 | ||
2286 | if (bf_get(lpfc_mqe_status, &mbox->u.mqe)) | 2286 | if (bf_get(lpfc_mqe_status, &mbox->u.mqe)) |
2287 | goto error; | 2287 | goto error_mbuf_free; |
2288 | 2288 | ||
2289 | lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a2, | 2289 | lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a2, |
2290 | DMP_SFF_PAGE_A2_SIZE); | 2290 | DMP_SFF_PAGE_A2_SIZE); |
@@ -2299,13 +2299,14 @@ lpfc_mbx_cmpl_rdp_page_a2(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) | |||
2299 | mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_link_stat; | 2299 | mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_link_stat; |
2300 | mbox->context2 = (struct lpfc_rdp_context *) rdp_context; | 2300 | mbox->context2 = (struct lpfc_rdp_context *) rdp_context; |
2301 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED) | 2301 | if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED) |
2302 | goto error; | 2302 | goto error_cmd_free; |
2303 | 2303 | ||
2304 | return; | 2304 | return; |
2305 | 2305 | ||
2306 | error: | 2306 | error_mbuf_free: |
2307 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2307 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2308 | kfree(mp); | 2308 | kfree(mp); |
2309 | error_cmd_free: | ||
2309 | lpfc_sli4_mbox_cmd_free(phba, mbox); | 2310 | lpfc_sli4_mbox_cmd_free(phba, mbox); |
2310 | rdp_context->cmpl(phba, rdp_context, FAILURE); | 2311 | rdp_context->cmpl(phba, rdp_context, FAILURE); |
2311 | } | 2312 | } |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 6dec7cff316f..c167911221e9 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -112,9 +112,12 @@ _scsih_set_fwfault_debug(const char *val, struct kernel_param *kp) | |||
112 | if (ret) | 112 | if (ret) |
113 | return ret; | 113 | return ret; |
114 | 114 | ||
115 | /* global ioc spinlock to protect controller list on list operations */ | ||
115 | printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug); | 116 | printk(KERN_INFO "setting fwfault_debug(%d)\n", mpt2sas_fwfault_debug); |
117 | spin_lock(&gioc_lock); | ||
116 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) | 118 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) |
117 | ioc->fwfault_debug = mpt2sas_fwfault_debug; | 119 | ioc->fwfault_debug = mpt2sas_fwfault_debug; |
120 | spin_unlock(&gioc_lock); | ||
118 | return 0; | 121 | return 0; |
119 | } | 122 | } |
120 | 123 | ||
@@ -4437,6 +4440,8 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) | |||
4437 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, | 4440 | dexitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, |
4438 | __func__)); | 4441 | __func__)); |
4439 | 4442 | ||
4443 | /* synchronizing freeing resource with pci_access_mutex lock */ | ||
4444 | mutex_lock(&ioc->pci_access_mutex); | ||
4440 | if (ioc->chip_phys && ioc->chip) { | 4445 | if (ioc->chip_phys && ioc->chip) { |
4441 | _base_mask_interrupts(ioc); | 4446 | _base_mask_interrupts(ioc); |
4442 | ioc->shost_recovery = 1; | 4447 | ioc->shost_recovery = 1; |
@@ -4456,6 +4461,7 @@ mpt2sas_base_free_resources(struct MPT2SAS_ADAPTER *ioc) | |||
4456 | pci_disable_pcie_error_reporting(pdev); | 4461 | pci_disable_pcie_error_reporting(pdev); |
4457 | pci_disable_device(pdev); | 4462 | pci_disable_device(pdev); |
4458 | } | 4463 | } |
4464 | mutex_unlock(&ioc->pci_access_mutex); | ||
4459 | return; | 4465 | return; |
4460 | } | 4466 | } |
4461 | 4467 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h index caff8d10cca4..97ea360c6920 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.h +++ b/drivers/scsi/mpt2sas/mpt2sas_base.h | |||
@@ -238,6 +238,7 @@ | |||
238 | * @flags: MPT_TARGET_FLAGS_XXX flags | 238 | * @flags: MPT_TARGET_FLAGS_XXX flags |
239 | * @deleted: target flaged for deletion | 239 | * @deleted: target flaged for deletion |
240 | * @tm_busy: target is busy with TM request. | 240 | * @tm_busy: target is busy with TM request. |
241 | * @sdev: The sas_device associated with this target | ||
241 | */ | 242 | */ |
242 | struct MPT2SAS_TARGET { | 243 | struct MPT2SAS_TARGET { |
243 | struct scsi_target *starget; | 244 | struct scsi_target *starget; |
@@ -248,6 +249,7 @@ struct MPT2SAS_TARGET { | |||
248 | u32 flags; | 249 | u32 flags; |
249 | u8 deleted; | 250 | u8 deleted; |
250 | u8 tm_busy; | 251 | u8 tm_busy; |
252 | struct _sas_device *sdev; | ||
251 | }; | 253 | }; |
252 | 254 | ||
253 | 255 | ||
@@ -376,8 +378,24 @@ struct _sas_device { | |||
376 | u8 phy; | 378 | u8 phy; |
377 | u8 responding; | 379 | u8 responding; |
378 | u8 pfa_led_on; | 380 | u8 pfa_led_on; |
381 | struct kref refcount; | ||
379 | }; | 382 | }; |
380 | 383 | ||
384 | static inline void sas_device_get(struct _sas_device *s) | ||
385 | { | ||
386 | kref_get(&s->refcount); | ||
387 | } | ||
388 | |||
389 | static inline void sas_device_free(struct kref *r) | ||
390 | { | ||
391 | kfree(container_of(r, struct _sas_device, refcount)); | ||
392 | } | ||
393 | |||
394 | static inline void sas_device_put(struct _sas_device *s) | ||
395 | { | ||
396 | kref_put(&s->refcount, sas_device_free); | ||
397 | } | ||
398 | |||
381 | /** | 399 | /** |
382 | * struct _raid_device - raid volume link list | 400 | * struct _raid_device - raid volume link list |
383 | * @list: sas device list | 401 | * @list: sas device list |
@@ -799,6 +817,12 @@ typedef void (*MPT2SAS_FLUSH_RUNNING_CMDS)(struct MPT2SAS_ADAPTER *ioc); | |||
799 | * @delayed_tr_list: target reset link list | 817 | * @delayed_tr_list: target reset link list |
800 | * @delayed_tr_volume_list: volume target reset link list | 818 | * @delayed_tr_volume_list: volume target reset link list |
801 | * @@temp_sensors_count: flag to carry the number of temperature sensors | 819 | * @@temp_sensors_count: flag to carry the number of temperature sensors |
820 | * @pci_access_mutex: Mutex to synchronize ioctl,sysfs show path and | ||
821 | * pci resource handling. PCI resource freeing will lead to free | ||
822 | * vital hardware/memory resource, which might be in use by cli/sysfs | ||
823 | * path functions resulting in Null pointer reference followed by kernel | ||
824 | * crash. To avoid the above race condition we use mutex syncrhonization | ||
825 | * which ensures the syncrhonization between cli/sysfs_show path | ||
802 | */ | 826 | */ |
803 | struct MPT2SAS_ADAPTER { | 827 | struct MPT2SAS_ADAPTER { |
804 | struct list_head list; | 828 | struct list_head list; |
@@ -1015,6 +1039,7 @@ struct MPT2SAS_ADAPTER { | |||
1015 | u8 mfg_pg10_hide_flag; | 1039 | u8 mfg_pg10_hide_flag; |
1016 | u8 hide_drives; | 1040 | u8 hide_drives; |
1017 | 1041 | ||
1042 | struct mutex pci_access_mutex; | ||
1018 | }; | 1043 | }; |
1019 | 1044 | ||
1020 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | 1045 | typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, |
@@ -1023,6 +1048,17 @@ typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
1023 | 1048 | ||
1024 | /* base shared API */ | 1049 | /* base shared API */ |
1025 | extern struct list_head mpt2sas_ioc_list; | 1050 | extern struct list_head mpt2sas_ioc_list; |
1051 | /* spinlock on list operations over IOCs | ||
1052 | * Case: when multiple warpdrive cards(IOCs) are in use | ||
1053 | * Each IOC will added to the ioc list stucture on initialization. | ||
1054 | * Watchdog threads run at regular intervals to check IOC for any | ||
1055 | * fault conditions which will trigger the dead_ioc thread to | ||
1056 | * deallocate pci resource, resulting deleting the IOC netry from list, | ||
1057 | * this deletion need to protected by spinlock to enusre that | ||
1058 | * ioc removal is syncrhonized, if not synchronized it might lead to | ||
1059 | * list_del corruption as the ioc list is traversed in cli path | ||
1060 | */ | ||
1061 | extern spinlock_t gioc_lock; | ||
1026 | void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc); | 1062 | void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc); |
1027 | void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc); | 1063 | void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc); |
1028 | 1064 | ||
@@ -1095,11 +1131,12 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_handle(struct MPT2SAS_ADAPTER * | |||
1095 | u16 handle); | 1131 | u16 handle); |
1096 | struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER | 1132 | struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAPTER |
1097 | *ioc, u64 sas_address); | 1133 | *ioc, u64 sas_address); |
1098 | struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address( | 1134 | struct _sas_device *mpt2sas_get_sdev_by_addr( |
1135 | struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | ||
1136 | struct _sas_device *__mpt2sas_get_sdev_by_addr( | ||
1099 | struct MPT2SAS_ADAPTER *ioc, u64 sas_address); | 1137 | struct MPT2SAS_ADAPTER *ioc, u64 sas_address); |
1100 | 1138 | ||
1101 | void mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc); | 1139 | void mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc); |
1102 | |||
1103 | void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); | 1140 | void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase); |
1104 | 1141 | ||
1105 | /* config shared API */ | 1142 | /* config shared API */ |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 4e509604b571..3694b63bd993 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -427,13 +427,16 @@ static int | |||
427 | _ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp) | 427 | _ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp) |
428 | { | 428 | { |
429 | struct MPT2SAS_ADAPTER *ioc; | 429 | struct MPT2SAS_ADAPTER *ioc; |
430 | 430 | /* global ioc lock to protect controller on list operations */ | |
431 | spin_lock(&gioc_lock); | ||
431 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { | 432 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { |
432 | if (ioc->id != ioc_number) | 433 | if (ioc->id != ioc_number) |
433 | continue; | 434 | continue; |
435 | spin_unlock(&gioc_lock); | ||
434 | *iocpp = ioc; | 436 | *iocpp = ioc; |
435 | return ioc_number; | 437 | return ioc_number; |
436 | } | 438 | } |
439 | spin_unlock(&gioc_lock); | ||
437 | *iocpp = NULL; | 440 | *iocpp = NULL; |
438 | return -1; | 441 | return -1; |
439 | } | 442 | } |
@@ -522,10 +525,15 @@ _ctl_poll(struct file *filep, poll_table *wait) | |||
522 | 525 | ||
523 | poll_wait(filep, &ctl_poll_wait, wait); | 526 | poll_wait(filep, &ctl_poll_wait, wait); |
524 | 527 | ||
528 | /* global ioc lock to protect controller on list operations */ | ||
529 | spin_lock(&gioc_lock); | ||
525 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { | 530 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { |
526 | if (ioc->aen_event_read_flag) | 531 | if (ioc->aen_event_read_flag) { |
532 | spin_unlock(&gioc_lock); | ||
527 | return POLLIN | POLLRDNORM; | 533 | return POLLIN | POLLRDNORM; |
534 | } | ||
528 | } | 535 | } |
536 | spin_unlock(&gioc_lock); | ||
529 | return 0; | 537 | return 0; |
530 | } | 538 | } |
531 | 539 | ||
@@ -2168,16 +2176,23 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, | |||
2168 | 2176 | ||
2169 | if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) | 2177 | if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) |
2170 | return -ENODEV; | 2178 | return -ENODEV; |
2179 | /* pci_access_mutex lock acquired by ioctl path */ | ||
2180 | mutex_lock(&ioc->pci_access_mutex); | ||
2171 | if (ioc->shost_recovery || ioc->pci_error_recovery || | 2181 | if (ioc->shost_recovery || ioc->pci_error_recovery || |
2172 | ioc->is_driver_loading) | 2182 | ioc->is_driver_loading || ioc->remove_host) { |
2173 | return -EAGAIN; | 2183 | ret = -EAGAIN; |
2184 | goto out_unlock_pciaccess; | ||
2185 | } | ||
2174 | 2186 | ||
2175 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; | 2187 | state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; |
2176 | if (state == NON_BLOCKING) { | 2188 | if (state == NON_BLOCKING) { |
2177 | if (!mutex_trylock(&ioc->ctl_cmds.mutex)) | 2189 | if (!mutex_trylock(&ioc->ctl_cmds.mutex)) { |
2178 | return -EAGAIN; | 2190 | ret = -EAGAIN; |
2191 | goto out_unlock_pciaccess; | ||
2192 | } | ||
2179 | } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { | 2193 | } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { |
2180 | return -ERESTARTSYS; | 2194 | ret = -ERESTARTSYS; |
2195 | goto out_unlock_pciaccess; | ||
2181 | } | 2196 | } |
2182 | 2197 | ||
2183 | switch (cmd) { | 2198 | switch (cmd) { |
@@ -2258,6 +2273,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, | |||
2258 | } | 2273 | } |
2259 | 2274 | ||
2260 | mutex_unlock(&ioc->ctl_cmds.mutex); | 2275 | mutex_unlock(&ioc->ctl_cmds.mutex); |
2276 | out_unlock_pciaccess: | ||
2277 | mutex_unlock(&ioc->pci_access_mutex); | ||
2261 | return ret; | 2278 | return ret; |
2262 | } | 2279 | } |
2263 | 2280 | ||
@@ -2711,6 +2728,12 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, | |||
2711 | "warpdrive\n", ioc->name, __func__); | 2728 | "warpdrive\n", ioc->name, __func__); |
2712 | goto out; | 2729 | goto out; |
2713 | } | 2730 | } |
2731 | /* pci_access_mutex lock acquired by sysfs show path */ | ||
2732 | mutex_lock(&ioc->pci_access_mutex); | ||
2733 | if (ioc->pci_error_recovery || ioc->remove_host) { | ||
2734 | mutex_unlock(&ioc->pci_access_mutex); | ||
2735 | return 0; | ||
2736 | } | ||
2714 | 2737 | ||
2715 | /* allocate upto GPIOVal 36 entries */ | 2738 | /* allocate upto GPIOVal 36 entries */ |
2716 | sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); | 2739 | sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); |
@@ -2749,6 +2772,7 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, | |||
2749 | 2772 | ||
2750 | out: | 2773 | out: |
2751 | kfree(io_unit_pg3); | 2774 | kfree(io_unit_pg3); |
2775 | mutex_unlock(&ioc->pci_access_mutex); | ||
2752 | return rc; | 2776 | return rc; |
2753 | } | 2777 | } |
2754 | static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); | 2778 | static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 3f26147bbc64..0ad09b2bff9c 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c | |||
@@ -79,7 +79,8 @@ static int _scsih_scan_finished(struct Scsi_Host *shost, unsigned long time); | |||
79 | 79 | ||
80 | /* global parameters */ | 80 | /* global parameters */ |
81 | LIST_HEAD(mpt2sas_ioc_list); | 81 | LIST_HEAD(mpt2sas_ioc_list); |
82 | 82 | /* global ioc lock for list operations */ | |
83 | DEFINE_SPINLOCK(gioc_lock); | ||
83 | /* local parameters */ | 84 | /* local parameters */ |
84 | static u8 scsi_io_cb_idx = -1; | 85 | static u8 scsi_io_cb_idx = -1; |
85 | static u8 tm_cb_idx = -1; | 86 | static u8 tm_cb_idx = -1; |
@@ -176,9 +177,37 @@ struct fw_event_work { | |||
176 | u8 VP_ID; | 177 | u8 VP_ID; |
177 | u8 ignore; | 178 | u8 ignore; |
178 | u16 event; | 179 | u16 event; |
180 | struct kref refcount; | ||
179 | char event_data[0] __aligned(4); | 181 | char event_data[0] __aligned(4); |
180 | }; | 182 | }; |
181 | 183 | ||
184 | static void fw_event_work_free(struct kref *r) | ||
185 | { | ||
186 | kfree(container_of(r, struct fw_event_work, refcount)); | ||
187 | } | ||
188 | |||
189 | static void fw_event_work_get(struct fw_event_work *fw_work) | ||
190 | { | ||
191 | kref_get(&fw_work->refcount); | ||
192 | } | ||
193 | |||
194 | static void fw_event_work_put(struct fw_event_work *fw_work) | ||
195 | { | ||
196 | kref_put(&fw_work->refcount, fw_event_work_free); | ||
197 | } | ||
198 | |||
199 | static struct fw_event_work *alloc_fw_event_work(int len) | ||
200 | { | ||
201 | struct fw_event_work *fw_event; | ||
202 | |||
203 | fw_event = kzalloc(sizeof(*fw_event) + len, GFP_ATOMIC); | ||
204 | if (!fw_event) | ||
205 | return NULL; | ||
206 | |||
207 | kref_init(&fw_event->refcount); | ||
208 | return fw_event; | ||
209 | } | ||
210 | |||
182 | /* raid transport support */ | 211 | /* raid transport support */ |
183 | static struct raid_template *mpt2sas_raid_template; | 212 | static struct raid_template *mpt2sas_raid_template; |
184 | 213 | ||
@@ -293,8 +322,10 @@ _scsih_set_debug_level(const char *val, struct kernel_param *kp) | |||
293 | return ret; | 322 | return ret; |
294 | 323 | ||
295 | printk(KERN_INFO "setting logging_level(0x%08x)\n", logging_level); | 324 | printk(KERN_INFO "setting logging_level(0x%08x)\n", logging_level); |
325 | spin_lock(&gioc_lock); | ||
296 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) | 326 | list_for_each_entry(ioc, &mpt2sas_ioc_list, list) |
297 | ioc->logging_level = logging_level; | 327 | ioc->logging_level = logging_level; |
328 | spin_unlock(&gioc_lock); | ||
298 | return 0; | 329 | return 0; |
299 | } | 330 | } |
300 | module_param_call(logging_level, _scsih_set_debug_level, param_get_int, | 331 | module_param_call(logging_level, _scsih_set_debug_level, param_get_int, |
@@ -526,8 +557,61 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc, | |||
526 | } | 557 | } |
527 | } | 558 | } |
528 | 559 | ||
560 | static struct _sas_device * | ||
561 | __mpt2sas_get_sdev_from_target(struct MPT2SAS_ADAPTER *ioc, | ||
562 | struct MPT2SAS_TARGET *tgt_priv) | ||
563 | { | ||
564 | struct _sas_device *ret; | ||
565 | |||
566 | assert_spin_locked(&ioc->sas_device_lock); | ||
567 | |||
568 | ret = tgt_priv->sdev; | ||
569 | if (ret) | ||
570 | sas_device_get(ret); | ||
571 | |||
572 | return ret; | ||
573 | } | ||
574 | |||
575 | static struct _sas_device * | ||
576 | mpt2sas_get_sdev_from_target(struct MPT2SAS_ADAPTER *ioc, | ||
577 | struct MPT2SAS_TARGET *tgt_priv) | ||
578 | { | ||
579 | struct _sas_device *ret; | ||
580 | unsigned long flags; | ||
581 | |||
582 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
583 | ret = __mpt2sas_get_sdev_from_target(ioc, tgt_priv); | ||
584 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
585 | |||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | |||
590 | struct _sas_device * | ||
591 | __mpt2sas_get_sdev_by_addr(struct MPT2SAS_ADAPTER *ioc, | ||
592 | u64 sas_address) | ||
593 | { | ||
594 | struct _sas_device *sas_device; | ||
595 | |||
596 | assert_spin_locked(&ioc->sas_device_lock); | ||
597 | |||
598 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | ||
599 | if (sas_device->sas_address == sas_address) | ||
600 | goto found_device; | ||
601 | |||
602 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | ||
603 | if (sas_device->sas_address == sas_address) | ||
604 | goto found_device; | ||
605 | |||
606 | return NULL; | ||
607 | |||
608 | found_device: | ||
609 | sas_device_get(sas_device); | ||
610 | return sas_device; | ||
611 | } | ||
612 | |||
529 | /** | 613 | /** |
530 | * mpt2sas_scsih_sas_device_find_by_sas_address - sas device search | 614 | * mpt2sas_get_sdev_by_addr - sas device search |
531 | * @ioc: per adapter object | 615 | * @ioc: per adapter object |
532 | * @sas_address: sas address | 616 | * @sas_address: sas address |
533 | * Context: Calling function should acquire ioc->sas_device_lock | 617 | * Context: Calling function should acquire ioc->sas_device_lock |
@@ -536,24 +620,44 @@ _scsih_determine_boot_device(struct MPT2SAS_ADAPTER *ioc, | |||
536 | * object. | 620 | * object. |
537 | */ | 621 | */ |
538 | struct _sas_device * | 622 | struct _sas_device * |
539 | mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, | 623 | mpt2sas_get_sdev_by_addr(struct MPT2SAS_ADAPTER *ioc, |
540 | u64 sas_address) | 624 | u64 sas_address) |
541 | { | 625 | { |
542 | struct _sas_device *sas_device; | 626 | struct _sas_device *sas_device; |
627 | unsigned long flags; | ||
628 | |||
629 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
630 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, | ||
631 | sas_address); | ||
632 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
633 | |||
634 | return sas_device; | ||
635 | } | ||
636 | |||
637 | static struct _sas_device * | ||
638 | __mpt2sas_get_sdev_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | ||
639 | { | ||
640 | struct _sas_device *sas_device; | ||
641 | |||
642 | assert_spin_locked(&ioc->sas_device_lock); | ||
543 | 643 | ||
544 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | 644 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) |
545 | if (sas_device->sas_address == sas_address) | 645 | if (sas_device->handle == handle) |
546 | return sas_device; | 646 | goto found_device; |
547 | 647 | ||
548 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | 648 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) |
549 | if (sas_device->sas_address == sas_address) | 649 | if (sas_device->handle == handle) |
550 | return sas_device; | 650 | goto found_device; |
551 | 651 | ||
552 | return NULL; | 652 | return NULL; |
653 | |||
654 | found_device: | ||
655 | sas_device_get(sas_device); | ||
656 | return sas_device; | ||
553 | } | 657 | } |
554 | 658 | ||
555 | /** | 659 | /** |
556 | * _scsih_sas_device_find_by_handle - sas device search | 660 | * mpt2sas_get_sdev_by_handle - sas device search |
557 | * @ioc: per adapter object | 661 | * @ioc: per adapter object |
558 | * @handle: sas device handle (assigned by firmware) | 662 | * @handle: sas device handle (assigned by firmware) |
559 | * Context: Calling function should acquire ioc->sas_device_lock | 663 | * Context: Calling function should acquire ioc->sas_device_lock |
@@ -562,19 +666,16 @@ mpt2sas_scsih_sas_device_find_by_sas_address(struct MPT2SAS_ADAPTER *ioc, | |||
562 | * object. | 666 | * object. |
563 | */ | 667 | */ |
564 | static struct _sas_device * | 668 | static struct _sas_device * |
565 | _scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | 669 | mpt2sas_get_sdev_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) |
566 | { | 670 | { |
567 | struct _sas_device *sas_device; | 671 | struct _sas_device *sas_device; |
672 | unsigned long flags; | ||
568 | 673 | ||
569 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) | 674 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
570 | if (sas_device->handle == handle) | 675 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
571 | return sas_device; | 676 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
572 | |||
573 | list_for_each_entry(sas_device, &ioc->sas_device_init_list, list) | ||
574 | if (sas_device->handle == handle) | ||
575 | return sas_device; | ||
576 | 677 | ||
577 | return NULL; | 678 | return sas_device; |
578 | } | 679 | } |
579 | 680 | ||
580 | /** | 681 | /** |
@@ -583,7 +684,7 @@ _scsih_sas_device_find_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
583 | * @sas_device: the sas_device object | 684 | * @sas_device: the sas_device object |
584 | * Context: This function will acquire ioc->sas_device_lock. | 685 | * Context: This function will acquire ioc->sas_device_lock. |
585 | * | 686 | * |
586 | * Removing object and freeing associated memory from the ioc->sas_device_list. | 687 | * If sas_device is on the list, remove it and decrement its reference count. |
587 | */ | 688 | */ |
588 | static void | 689 | static void |
589 | _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc, | 690 | _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc, |
@@ -594,9 +695,15 @@ _scsih_sas_device_remove(struct MPT2SAS_ADAPTER *ioc, | |||
594 | if (!sas_device) | 695 | if (!sas_device) |
595 | return; | 696 | return; |
596 | 697 | ||
698 | /* | ||
699 | * The lock serializes access to the list, but we still need to verify | ||
700 | * that nobody removed the entry while we were waiting on the lock. | ||
701 | */ | ||
597 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 702 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
598 | list_del(&sas_device->list); | 703 | if (!list_empty(&sas_device->list)) { |
599 | kfree(sas_device); | 704 | list_del_init(&sas_device->list); |
705 | sas_device_put(sas_device); | ||
706 | } | ||
600 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 707 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
601 | } | 708 | } |
602 | 709 | ||
@@ -620,6 +727,7 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc, | |||
620 | sas_device->handle, (unsigned long long)sas_device->sas_address)); | 727 | sas_device->handle, (unsigned long long)sas_device->sas_address)); |
621 | 728 | ||
622 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 729 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
730 | sas_device_get(sas_device); | ||
623 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | 731 | list_add_tail(&sas_device->list, &ioc->sas_device_list); |
624 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 732 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
625 | 733 | ||
@@ -659,6 +767,7 @@ _scsih_sas_device_init_add(struct MPT2SAS_ADAPTER *ioc, | |||
659 | sas_device->handle, (unsigned long long)sas_device->sas_address)); | 767 | sas_device->handle, (unsigned long long)sas_device->sas_address)); |
660 | 768 | ||
661 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 769 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
770 | sas_device_get(sas_device); | ||
662 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); | 771 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); |
663 | _scsih_determine_boot_device(ioc, sas_device, 0); | 772 | _scsih_determine_boot_device(ioc, sas_device, 0); |
664 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 773 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -1208,12 +1317,15 @@ _scsih_change_queue_depth(struct scsi_device *sdev, int qdepth) | |||
1208 | goto not_sata; | 1317 | goto not_sata; |
1209 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) | 1318 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) |
1210 | goto not_sata; | 1319 | goto not_sata; |
1320 | |||
1211 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1321 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1212 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1322 | sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); |
1213 | sas_device_priv_data->sas_target->sas_address); | 1323 | if (sas_device) { |
1214 | if (sas_device && sas_device->device_info & | 1324 | if (sas_device->device_info & MPI2_SAS_DEVICE_INFO_SATA_DEVICE) |
1215 | MPI2_SAS_DEVICE_INFO_SATA_DEVICE) | 1325 | max_depth = MPT2SAS_SATA_QUEUE_DEPTH; |
1216 | max_depth = MPT2SAS_SATA_QUEUE_DEPTH; | 1326 | |
1327 | sas_device_put(sas_device); | ||
1328 | } | ||
1217 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1329 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1218 | 1330 | ||
1219 | not_sata: | 1331 | not_sata: |
@@ -1271,18 +1383,20 @@ _scsih_target_alloc(struct scsi_target *starget) | |||
1271 | /* sas/sata devices */ | 1383 | /* sas/sata devices */ |
1272 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1384 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1273 | rphy = dev_to_rphy(starget->dev.parent); | 1385 | rphy = dev_to_rphy(starget->dev.parent); |
1274 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1386 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
1275 | rphy->identify.sas_address); | 1387 | rphy->identify.sas_address); |
1276 | 1388 | ||
1277 | if (sas_device) { | 1389 | if (sas_device) { |
1278 | sas_target_priv_data->handle = sas_device->handle; | 1390 | sas_target_priv_data->handle = sas_device->handle; |
1279 | sas_target_priv_data->sas_address = sas_device->sas_address; | 1391 | sas_target_priv_data->sas_address = sas_device->sas_address; |
1392 | sas_target_priv_data->sdev = sas_device; | ||
1280 | sas_device->starget = starget; | 1393 | sas_device->starget = starget; |
1281 | sas_device->id = starget->id; | 1394 | sas_device->id = starget->id; |
1282 | sas_device->channel = starget->channel; | 1395 | sas_device->channel = starget->channel; |
1283 | if (test_bit(sas_device->handle, ioc->pd_handles)) | 1396 | if (test_bit(sas_device->handle, ioc->pd_handles)) |
1284 | sas_target_priv_data->flags |= | 1397 | sas_target_priv_data->flags |= |
1285 | MPT_TARGET_FLAGS_RAID_COMPONENT; | 1398 | MPT_TARGET_FLAGS_RAID_COMPONENT; |
1399 | |||
1286 | } | 1400 | } |
1287 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1401 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1288 | 1402 | ||
@@ -1324,13 +1438,21 @@ _scsih_target_destroy(struct scsi_target *starget) | |||
1324 | 1438 | ||
1325 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1439 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1326 | rphy = dev_to_rphy(starget->dev.parent); | 1440 | rphy = dev_to_rphy(starget->dev.parent); |
1327 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1441 | sas_device = __mpt2sas_get_sdev_from_target(ioc, sas_target_priv_data); |
1328 | rphy->identify.sas_address); | ||
1329 | if (sas_device && (sas_device->starget == starget) && | 1442 | if (sas_device && (sas_device->starget == starget) && |
1330 | (sas_device->id == starget->id) && | 1443 | (sas_device->id == starget->id) && |
1331 | (sas_device->channel == starget->channel)) | 1444 | (sas_device->channel == starget->channel)) |
1332 | sas_device->starget = NULL; | 1445 | sas_device->starget = NULL; |
1333 | 1446 | ||
1447 | if (sas_device) { | ||
1448 | /* | ||
1449 | * Corresponding get() is in _scsih_target_alloc() | ||
1450 | */ | ||
1451 | sas_target_priv_data->sdev = NULL; | ||
1452 | sas_device_put(sas_device); | ||
1453 | |||
1454 | sas_device_put(sas_device); | ||
1455 | } | ||
1334 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1456 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1335 | 1457 | ||
1336 | out: | 1458 | out: |
@@ -1386,7 +1508,7 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1386 | 1508 | ||
1387 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1509 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { |
1388 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1510 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1389 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1511 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
1390 | sas_target_priv_data->sas_address); | 1512 | sas_target_priv_data->sas_address); |
1391 | if (sas_device && (sas_device->starget == NULL)) { | 1513 | if (sas_device && (sas_device->starget == NULL)) { |
1392 | sdev_printk(KERN_INFO, sdev, | 1514 | sdev_printk(KERN_INFO, sdev, |
@@ -1394,6 +1516,10 @@ _scsih_slave_alloc(struct scsi_device *sdev) | |||
1394 | __func__, __LINE__); | 1516 | __func__, __LINE__); |
1395 | sas_device->starget = starget; | 1517 | sas_device->starget = starget; |
1396 | } | 1518 | } |
1519 | |||
1520 | if (sas_device) | ||
1521 | sas_device_put(sas_device); | ||
1522 | |||
1397 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1523 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1398 | } | 1524 | } |
1399 | 1525 | ||
@@ -1428,10 +1554,13 @@ _scsih_slave_destroy(struct scsi_device *sdev) | |||
1428 | 1554 | ||
1429 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { | 1555 | if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { |
1430 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1556 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1431 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1557 | sas_device = __mpt2sas_get_sdev_from_target(ioc, |
1432 | sas_target_priv_data->sas_address); | 1558 | sas_target_priv_data); |
1433 | if (sas_device && !sas_target_priv_data->num_luns) | 1559 | if (sas_device && !sas_target_priv_data->num_luns) |
1434 | sas_device->starget = NULL; | 1560 | sas_device->starget = NULL; |
1561 | |||
1562 | if (sas_device) | ||
1563 | sas_device_put(sas_device); | ||
1435 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1564 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1436 | } | 1565 | } |
1437 | 1566 | ||
@@ -2078,7 +2207,7 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
2078 | } | 2207 | } |
2079 | 2208 | ||
2080 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2209 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2081 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 2210 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
2082 | sas_device_priv_data->sas_target->sas_address); | 2211 | sas_device_priv_data->sas_target->sas_address); |
2083 | if (!sas_device) { | 2212 | if (!sas_device) { |
2084 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2213 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -2112,17 +2241,18 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
2112 | (unsigned long long) sas_device->enclosure_logical_id, | 2241 | (unsigned long long) sas_device->enclosure_logical_id, |
2113 | sas_device->slot); | 2242 | sas_device->slot); |
2114 | 2243 | ||
2244 | sas_device_put(sas_device); | ||
2115 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2245 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2116 | if (!ssp_target) | 2246 | if (!ssp_target) |
2117 | _scsih_display_sata_capabilities(ioc, handle, sdev); | 2247 | _scsih_display_sata_capabilities(ioc, handle, sdev); |
2118 | 2248 | ||
2119 | |||
2120 | _scsih_change_queue_depth(sdev, qdepth); | 2249 | _scsih_change_queue_depth(sdev, qdepth); |
2121 | 2250 | ||
2122 | if (ssp_target) { | 2251 | if (ssp_target) { |
2123 | sas_read_port_mode_page(sdev); | 2252 | sas_read_port_mode_page(sdev); |
2124 | _scsih_enable_tlr(ioc, sdev); | 2253 | _scsih_enable_tlr(ioc, sdev); |
2125 | } | 2254 | } |
2255 | |||
2126 | return 0; | 2256 | return 0; |
2127 | } | 2257 | } |
2128 | 2258 | ||
@@ -2509,8 +2639,7 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2509 | device_str, (unsigned long long)priv_target->sas_address); | 2639 | device_str, (unsigned long long)priv_target->sas_address); |
2510 | } else { | 2640 | } else { |
2511 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2641 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
2512 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 2642 | sas_device = __mpt2sas_get_sdev_from_target(ioc, priv_target); |
2513 | priv_target->sas_address); | ||
2514 | if (sas_device) { | 2643 | if (sas_device) { |
2515 | if (priv_target->flags & | 2644 | if (priv_target->flags & |
2516 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2645 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
@@ -2529,6 +2658,8 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2529 | "enclosure_logical_id(0x%016llx), slot(%d)\n", | 2658 | "enclosure_logical_id(0x%016llx), slot(%d)\n", |
2530 | (unsigned long long)sas_device->enclosure_logical_id, | 2659 | (unsigned long long)sas_device->enclosure_logical_id, |
2531 | sas_device->slot); | 2660 | sas_device->slot); |
2661 | |||
2662 | sas_device_put(sas_device); | ||
2532 | } | 2663 | } |
2533 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2664 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2534 | } | 2665 | } |
@@ -2604,12 +2735,12 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2604 | { | 2735 | { |
2605 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2736 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2606 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 2737 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
2607 | struct _sas_device *sas_device; | 2738 | struct _sas_device *sas_device = NULL; |
2608 | unsigned long flags; | ||
2609 | u16 handle; | 2739 | u16 handle; |
2610 | int r; | 2740 | int r; |
2611 | 2741 | ||
2612 | struct scsi_target *starget = scmd->device->sdev_target; | 2742 | struct scsi_target *starget = scmd->device->sdev_target; |
2743 | struct MPT2SAS_TARGET *target_priv_data = starget->hostdata; | ||
2613 | 2744 | ||
2614 | starget_printk(KERN_INFO, starget, "attempting device reset! " | 2745 | starget_printk(KERN_INFO, starget, "attempting device reset! " |
2615 | "scmd(%p)\n", scmd); | 2746 | "scmd(%p)\n", scmd); |
@@ -2629,12 +2760,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2629 | handle = 0; | 2760 | handle = 0; |
2630 | if (sas_device_priv_data->sas_target->flags & | 2761 | if (sas_device_priv_data->sas_target->flags & |
2631 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2762 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2632 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2763 | sas_device = mpt2sas_get_sdev_from_target(ioc, |
2633 | sas_device = _scsih_sas_device_find_by_handle(ioc, | 2764 | target_priv_data); |
2634 | sas_device_priv_data->sas_target->handle); | ||
2635 | if (sas_device) | 2765 | if (sas_device) |
2636 | handle = sas_device->volume_handle; | 2766 | handle = sas_device->volume_handle; |
2637 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2638 | } else | 2767 | } else |
2639 | handle = sas_device_priv_data->sas_target->handle; | 2768 | handle = sas_device_priv_data->sas_target->handle; |
2640 | 2769 | ||
@@ -2651,6 +2780,10 @@ _scsih_dev_reset(struct scsi_cmnd *scmd) | |||
2651 | out: | 2780 | out: |
2652 | sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", | 2781 | sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n", |
2653 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); | 2782 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); |
2783 | |||
2784 | if (sas_device) | ||
2785 | sas_device_put(sas_device); | ||
2786 | |||
2654 | return r; | 2787 | return r; |
2655 | } | 2788 | } |
2656 | 2789 | ||
@@ -2665,11 +2798,11 @@ _scsih_target_reset(struct scsi_cmnd *scmd) | |||
2665 | { | 2798 | { |
2666 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); | 2799 | struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host); |
2667 | struct MPT2SAS_DEVICE *sas_device_priv_data; | 2800 | struct MPT2SAS_DEVICE *sas_device_priv_data; |
2668 | struct _sas_device *sas_device; | 2801 | struct _sas_device *sas_device = NULL; |
2669 | unsigned long flags; | ||
2670 | u16 handle; | 2802 | u16 handle; |
2671 | int r; | 2803 | int r; |
2672 | struct scsi_target *starget = scmd->device->sdev_target; | 2804 | struct scsi_target *starget = scmd->device->sdev_target; |
2805 | struct MPT2SAS_TARGET *target_priv_data = starget->hostdata; | ||
2673 | 2806 | ||
2674 | starget_printk(KERN_INFO, starget, "attempting target reset! " | 2807 | starget_printk(KERN_INFO, starget, "attempting target reset! " |
2675 | "scmd(%p)\n", scmd); | 2808 | "scmd(%p)\n", scmd); |
@@ -2689,12 +2822,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd) | |||
2689 | handle = 0; | 2822 | handle = 0; |
2690 | if (sas_device_priv_data->sas_target->flags & | 2823 | if (sas_device_priv_data->sas_target->flags & |
2691 | MPT_TARGET_FLAGS_RAID_COMPONENT) { | 2824 | MPT_TARGET_FLAGS_RAID_COMPONENT) { |
2692 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 2825 | sas_device = mpt2sas_get_sdev_from_target(ioc, |
2693 | sas_device = _scsih_sas_device_find_by_handle(ioc, | 2826 | target_priv_data); |
2694 | sas_device_priv_data->sas_target->handle); | ||
2695 | if (sas_device) | 2827 | if (sas_device) |
2696 | handle = sas_device->volume_handle; | 2828 | handle = sas_device->volume_handle; |
2697 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
2698 | } else | 2829 | } else |
2699 | handle = sas_device_priv_data->sas_target->handle; | 2830 | handle = sas_device_priv_data->sas_target->handle; |
2700 | 2831 | ||
@@ -2711,6 +2842,10 @@ _scsih_target_reset(struct scsi_cmnd *scmd) | |||
2711 | out: | 2842 | out: |
2712 | starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", | 2843 | starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n", |
2713 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); | 2844 | ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd); |
2845 | |||
2846 | if (sas_device) | ||
2847 | sas_device_put(sas_device); | ||
2848 | |||
2714 | return r; | 2849 | return r; |
2715 | } | 2850 | } |
2716 | 2851 | ||
@@ -2768,36 +2903,39 @@ _scsih_fw_event_add(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work *fw_event) | |||
2768 | return; | 2903 | return; |
2769 | 2904 | ||
2770 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 2905 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
2906 | fw_event_work_get(fw_event); | ||
2771 | list_add_tail(&fw_event->list, &ioc->fw_event_list); | 2907 | list_add_tail(&fw_event->list, &ioc->fw_event_list); |
2772 | INIT_DELAYED_WORK(&fw_event->delayed_work, _firmware_event_work); | 2908 | INIT_DELAYED_WORK(&fw_event->delayed_work, _firmware_event_work); |
2909 | fw_event_work_get(fw_event); | ||
2773 | queue_delayed_work(ioc->firmware_event_thread, | 2910 | queue_delayed_work(ioc->firmware_event_thread, |
2774 | &fw_event->delayed_work, 0); | 2911 | &fw_event->delayed_work, 0); |
2775 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 2912 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
2776 | } | 2913 | } |
2777 | 2914 | ||
2778 | /** | 2915 | /** |
2779 | * _scsih_fw_event_free - delete fw_event | 2916 | * _scsih_fw_event_del_from_list - delete fw_event from the list |
2780 | * @ioc: per adapter object | 2917 | * @ioc: per adapter object |
2781 | * @fw_event: object describing the event | 2918 | * @fw_event: object describing the event |
2782 | * Context: This function will acquire ioc->fw_event_lock. | 2919 | * Context: This function will acquire ioc->fw_event_lock. |
2783 | * | 2920 | * |
2784 | * This removes firmware event object from link list, frees associated memory. | 2921 | * If the fw_event is on the fw_event_list, remove it and do a put. |
2785 | * | 2922 | * |
2786 | * Return nothing. | 2923 | * Return nothing. |
2787 | */ | 2924 | */ |
2788 | static void | 2925 | static void |
2789 | _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work | 2926 | _scsih_fw_event_del_from_list(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work |
2790 | *fw_event) | 2927 | *fw_event) |
2791 | { | 2928 | { |
2792 | unsigned long flags; | 2929 | unsigned long flags; |
2793 | 2930 | ||
2794 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | 2931 | spin_lock_irqsave(&ioc->fw_event_lock, flags); |
2795 | list_del(&fw_event->list); | 2932 | if (!list_empty(&fw_event->list)) { |
2796 | kfree(fw_event); | 2933 | list_del_init(&fw_event->list); |
2934 | fw_event_work_put(fw_event); | ||
2935 | } | ||
2797 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | 2936 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); |
2798 | } | 2937 | } |
2799 | 2938 | ||
2800 | |||
2801 | /** | 2939 | /** |
2802 | * _scsih_error_recovery_delete_devices - remove devices not responding | 2940 | * _scsih_error_recovery_delete_devices - remove devices not responding |
2803 | * @ioc: per adapter object | 2941 | * @ioc: per adapter object |
@@ -2812,13 +2950,14 @@ _scsih_error_recovery_delete_devices(struct MPT2SAS_ADAPTER *ioc) | |||
2812 | if (ioc->is_driver_loading) | 2950 | if (ioc->is_driver_loading) |
2813 | return; | 2951 | return; |
2814 | 2952 | ||
2815 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 2953 | fw_event = alloc_fw_event_work(0); |
2816 | if (!fw_event) | 2954 | if (!fw_event) |
2817 | return; | 2955 | return; |
2818 | 2956 | ||
2819 | fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES; | 2957 | fw_event->event = MPT2SAS_REMOVE_UNRESPONDING_DEVICES; |
2820 | fw_event->ioc = ioc; | 2958 | fw_event->ioc = ioc; |
2821 | _scsih_fw_event_add(ioc, fw_event); | 2959 | _scsih_fw_event_add(ioc, fw_event); |
2960 | fw_event_work_put(fw_event); | ||
2822 | } | 2961 | } |
2823 | 2962 | ||
2824 | /** | 2963 | /** |
@@ -2832,12 +2971,29 @@ mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc) | |||
2832 | { | 2971 | { |
2833 | struct fw_event_work *fw_event; | 2972 | struct fw_event_work *fw_event; |
2834 | 2973 | ||
2835 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 2974 | fw_event = alloc_fw_event_work(0); |
2836 | if (!fw_event) | 2975 | if (!fw_event) |
2837 | return; | 2976 | return; |
2838 | fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE; | 2977 | fw_event->event = MPT2SAS_PORT_ENABLE_COMPLETE; |
2839 | fw_event->ioc = ioc; | 2978 | fw_event->ioc = ioc; |
2840 | _scsih_fw_event_add(ioc, fw_event); | 2979 | _scsih_fw_event_add(ioc, fw_event); |
2980 | fw_event_work_put(fw_event); | ||
2981 | } | ||
2982 | |||
2983 | static struct fw_event_work *dequeue_next_fw_event(struct MPT2SAS_ADAPTER *ioc) | ||
2984 | { | ||
2985 | unsigned long flags; | ||
2986 | struct fw_event_work *fw_event = NULL; | ||
2987 | |||
2988 | spin_lock_irqsave(&ioc->fw_event_lock, flags); | ||
2989 | if (!list_empty(&ioc->fw_event_list)) { | ||
2990 | fw_event = list_first_entry(&ioc->fw_event_list, | ||
2991 | struct fw_event_work, list); | ||
2992 | list_del_init(&fw_event->list); | ||
2993 | } | ||
2994 | spin_unlock_irqrestore(&ioc->fw_event_lock, flags); | ||
2995 | |||
2996 | return fw_event; | ||
2841 | } | 2997 | } |
2842 | 2998 | ||
2843 | /** | 2999 | /** |
@@ -2852,17 +3008,25 @@ mpt2sas_port_enable_complete(struct MPT2SAS_ADAPTER *ioc) | |||
2852 | static void | 3008 | static void |
2853 | _scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc) | 3009 | _scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc) |
2854 | { | 3010 | { |
2855 | struct fw_event_work *fw_event, *next; | 3011 | struct fw_event_work *fw_event; |
2856 | 3012 | ||
2857 | if (list_empty(&ioc->fw_event_list) || | 3013 | if (list_empty(&ioc->fw_event_list) || |
2858 | !ioc->firmware_event_thread || in_interrupt()) | 3014 | !ioc->firmware_event_thread || in_interrupt()) |
2859 | return; | 3015 | return; |
2860 | 3016 | ||
2861 | list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) { | 3017 | while ((fw_event = dequeue_next_fw_event(ioc))) { |
2862 | if (cancel_delayed_work_sync(&fw_event->delayed_work)) { | 3018 | /* |
2863 | _scsih_fw_event_free(ioc, fw_event); | 3019 | * Wait on the fw_event to complete. If this returns 1, then |
2864 | continue; | 3020 | * the event was never executed, and we need a put for the |
2865 | } | 3021 | * reference the delayed_work had on the fw_event. |
3022 | * | ||
3023 | * If it did execute, we wait for it to finish, and the put will | ||
3024 | * happen from _firmware_event_work() | ||
3025 | */ | ||
3026 | if (cancel_delayed_work_sync(&fw_event->delayed_work)) | ||
3027 | fw_event_work_put(fw_event); | ||
3028 | |||
3029 | fw_event_work_put(fw_event); | ||
2866 | } | 3030 | } |
2867 | } | 3031 | } |
2868 | 3032 | ||
@@ -3002,15 +3166,15 @@ _scsih_block_io_to_children_attached_to_ex(struct MPT2SAS_ADAPTER *ioc, | |||
3002 | 3166 | ||
3003 | list_for_each_entry(mpt2sas_port, | 3167 | list_for_each_entry(mpt2sas_port, |
3004 | &sas_expander->sas_port_list, port_list) { | 3168 | &sas_expander->sas_port_list, port_list) { |
3005 | if (mpt2sas_port->remote_identify.device_type == | 3169 | if (mpt2sas_port->remote_identify.device_type == SAS_END_DEVICE) { |
3006 | SAS_END_DEVICE) { | ||
3007 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 3170 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
3008 | sas_device = | 3171 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
3009 | mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 3172 | mpt2sas_port->remote_identify.sas_address); |
3010 | mpt2sas_port->remote_identify.sas_address); | 3173 | if (sas_device) { |
3011 | if (sas_device) | ||
3012 | set_bit(sas_device->handle, | 3174 | set_bit(sas_device->handle, |
3013 | ioc->blocking_handles); | 3175 | ioc->blocking_handles); |
3176 | sas_device_put(sas_device); | ||
3177 | } | ||
3014 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 3178 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
3015 | } | 3179 | } |
3016 | } | 3180 | } |
@@ -3080,7 +3244,7 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3080 | { | 3244 | { |
3081 | Mpi2SCSITaskManagementRequest_t *mpi_request; | 3245 | Mpi2SCSITaskManagementRequest_t *mpi_request; |
3082 | u16 smid; | 3246 | u16 smid; |
3083 | struct _sas_device *sas_device; | 3247 | struct _sas_device *sas_device = NULL; |
3084 | struct MPT2SAS_TARGET *sas_target_priv_data = NULL; | 3248 | struct MPT2SAS_TARGET *sas_target_priv_data = NULL; |
3085 | u64 sas_address = 0; | 3249 | u64 sas_address = 0; |
3086 | unsigned long flags; | 3250 | unsigned long flags; |
@@ -3110,7 +3274,7 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3110 | return; | 3274 | return; |
3111 | 3275 | ||
3112 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 3276 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
3113 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 3277 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
3114 | if (sas_device && sas_device->starget && | 3278 | if (sas_device && sas_device->starget && |
3115 | sas_device->starget->hostdata) { | 3279 | sas_device->starget->hostdata) { |
3116 | sas_target_priv_data = sas_device->starget->hostdata; | 3280 | sas_target_priv_data = sas_device->starget->hostdata; |
@@ -3131,14 +3295,14 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3131 | if (!smid) { | 3295 | if (!smid) { |
3132 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); | 3296 | delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); |
3133 | if (!delayed_tr) | 3297 | if (!delayed_tr) |
3134 | return; | 3298 | goto out; |
3135 | INIT_LIST_HEAD(&delayed_tr->list); | 3299 | INIT_LIST_HEAD(&delayed_tr->list); |
3136 | delayed_tr->handle = handle; | 3300 | delayed_tr->handle = handle; |
3137 | list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); | 3301 | list_add_tail(&delayed_tr->list, &ioc->delayed_tr_list); |
3138 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT | 3302 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT |
3139 | "DELAYED:tr:handle(0x%04x), (open)\n", | 3303 | "DELAYED:tr:handle(0x%04x), (open)\n", |
3140 | ioc->name, handle)); | 3304 | ioc->name, handle)); |
3141 | return; | 3305 | goto out; |
3142 | } | 3306 | } |
3143 | 3307 | ||
3144 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), " | 3308 | dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "tr_send:handle(0x%04x), " |
@@ -3150,6 +3314,9 @@ _scsih_tm_tr_send(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
3150 | mpi_request->DevHandle = cpu_to_le16(handle); | 3314 | mpi_request->DevHandle = cpu_to_le16(handle); |
3151 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | 3315 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; |
3152 | mpt2sas_base_put_smid_hi_priority(ioc, smid); | 3316 | mpt2sas_base_put_smid_hi_priority(ioc, smid); |
3317 | out: | ||
3318 | if (sas_device) | ||
3319 | sas_device_put(sas_device); | ||
3153 | } | 3320 | } |
3154 | 3321 | ||
3155 | 3322 | ||
@@ -4068,7 +4235,6 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
4068 | char *desc_scsi_state = ioc->tmp_string; | 4235 | char *desc_scsi_state = ioc->tmp_string; |
4069 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); | 4236 | u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo); |
4070 | struct _sas_device *sas_device = NULL; | 4237 | struct _sas_device *sas_device = NULL; |
4071 | unsigned long flags; | ||
4072 | struct scsi_target *starget = scmd->device->sdev_target; | 4238 | struct scsi_target *starget = scmd->device->sdev_target; |
4073 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; | 4239 | struct MPT2SAS_TARGET *priv_target = starget->hostdata; |
4074 | char *device_str = NULL; | 4240 | char *device_str = NULL; |
@@ -4200,9 +4366,7 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
4200 | printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name, | 4366 | printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name, |
4201 | device_str, (unsigned long long)priv_target->sas_address); | 4367 | device_str, (unsigned long long)priv_target->sas_address); |
4202 | } else { | 4368 | } else { |
4203 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4369 | sas_device = mpt2sas_get_sdev_from_target(ioc, priv_target); |
4204 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
4205 | priv_target->sas_address); | ||
4206 | if (sas_device) { | 4370 | if (sas_device) { |
4207 | printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), " | 4371 | printk(MPT2SAS_WARN_FMT "\tsas_address(0x%016llx), " |
4208 | "phy(%d)\n", ioc->name, sas_device->sas_address, | 4372 | "phy(%d)\n", ioc->name, sas_device->sas_address, |
@@ -4211,8 +4375,9 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
4211 | "\tenclosure_logical_id(0x%016llx), slot(%d)\n", | 4375 | "\tenclosure_logical_id(0x%016llx), slot(%d)\n", |
4212 | ioc->name, sas_device->enclosure_logical_id, | 4376 | ioc->name, sas_device->enclosure_logical_id, |
4213 | sas_device->slot); | 4377 | sas_device->slot); |
4378 | |||
4379 | sas_device_put(sas_device); | ||
4214 | } | 4380 | } |
4215 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4216 | } | 4381 | } |
4217 | 4382 | ||
4218 | printk(MPT2SAS_WARN_FMT "\thandle(0x%04x), ioc_status(%s)(0x%04x), " | 4383 | printk(MPT2SAS_WARN_FMT "\thandle(0x%04x), ioc_status(%s)(0x%04x), " |
@@ -4259,7 +4424,7 @@ _scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4259 | Mpi2SepRequest_t mpi_request; | 4424 | Mpi2SepRequest_t mpi_request; |
4260 | struct _sas_device *sas_device; | 4425 | struct _sas_device *sas_device; |
4261 | 4426 | ||
4262 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4427 | sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); |
4263 | if (!sas_device) | 4428 | if (!sas_device) |
4264 | return; | 4429 | return; |
4265 | 4430 | ||
@@ -4274,7 +4439,7 @@ _scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4274 | &mpi_request)) != 0) { | 4439 | &mpi_request)) != 0) { |
4275 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, | 4440 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name, |
4276 | __FILE__, __LINE__, __func__); | 4441 | __FILE__, __LINE__, __func__); |
4277 | return; | 4442 | goto out; |
4278 | } | 4443 | } |
4279 | sas_device->pfa_led_on = 1; | 4444 | sas_device->pfa_led_on = 1; |
4280 | 4445 | ||
@@ -4284,8 +4449,10 @@ _scsih_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4284 | "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", | 4449 | "enclosure_processor: ioc_status (0x%04x), loginfo(0x%08x)\n", |
4285 | ioc->name, le16_to_cpu(mpi_reply.IOCStatus), | 4450 | ioc->name, le16_to_cpu(mpi_reply.IOCStatus), |
4286 | le32_to_cpu(mpi_reply.IOCLogInfo))); | 4451 | le32_to_cpu(mpi_reply.IOCLogInfo))); |
4287 | return; | 4452 | goto out; |
4288 | } | 4453 | } |
4454 | out: | ||
4455 | sas_device_put(sas_device); | ||
4289 | } | 4456 | } |
4290 | 4457 | ||
4291 | /** | 4458 | /** |
@@ -4340,13 +4507,14 @@ _scsih_send_event_to_turn_on_pfa_led(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4340 | { | 4507 | { |
4341 | struct fw_event_work *fw_event; | 4508 | struct fw_event_work *fw_event; |
4342 | 4509 | ||
4343 | fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); | 4510 | fw_event = alloc_fw_event_work(0); |
4344 | if (!fw_event) | 4511 | if (!fw_event) |
4345 | return; | 4512 | return; |
4346 | fw_event->event = MPT2SAS_TURN_ON_PFA_LED; | 4513 | fw_event->event = MPT2SAS_TURN_ON_PFA_LED; |
4347 | fw_event->device_handle = handle; | 4514 | fw_event->device_handle = handle; |
4348 | fw_event->ioc = ioc; | 4515 | fw_event->ioc = ioc; |
4349 | _scsih_fw_event_add(ioc, fw_event); | 4516 | _scsih_fw_event_add(ioc, fw_event); |
4517 | fw_event_work_put(fw_event); | ||
4350 | } | 4518 | } |
4351 | 4519 | ||
4352 | /** | 4520 | /** |
@@ -4370,19 +4538,17 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4370 | 4538 | ||
4371 | /* only handle non-raid devices */ | 4539 | /* only handle non-raid devices */ |
4372 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 4540 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
4373 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 4541 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
4374 | if (!sas_device) { | 4542 | if (!sas_device) { |
4375 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4543 | goto out_unlock; |
4376 | return; | ||
4377 | } | 4544 | } |
4378 | starget = sas_device->starget; | 4545 | starget = sas_device->starget; |
4379 | sas_target_priv_data = starget->hostdata; | 4546 | sas_target_priv_data = starget->hostdata; |
4380 | 4547 | ||
4381 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || | 4548 | if ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_RAID_COMPONENT) || |
4382 | ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) { | 4549 | ((sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME))) |
4383 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4550 | goto out_unlock; |
4384 | return; | 4551 | |
4385 | } | ||
4386 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); | 4552 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); |
4387 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4553 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4388 | 4554 | ||
@@ -4396,7 +4562,7 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4396 | if (!event_reply) { | 4562 | if (!event_reply) { |
4397 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 4563 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
4398 | ioc->name, __FILE__, __LINE__, __func__); | 4564 | ioc->name, __FILE__, __LINE__, __func__); |
4399 | return; | 4565 | goto out; |
4400 | } | 4566 | } |
4401 | 4567 | ||
4402 | event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; | 4568 | event_reply->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; |
@@ -4413,6 +4579,14 @@ _scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
4413 | event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); | 4579 | event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); |
4414 | mpt2sas_ctl_add_to_event_log(ioc, event_reply); | 4580 | mpt2sas_ctl_add_to_event_log(ioc, event_reply); |
4415 | kfree(event_reply); | 4581 | kfree(event_reply); |
4582 | out: | ||
4583 | if (sas_device) | ||
4584 | sas_device_put(sas_device); | ||
4585 | return; | ||
4586 | |||
4587 | out_unlock: | ||
4588 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
4589 | goto out; | ||
4416 | } | 4590 | } |
4417 | 4591 | ||
4418 | /** | 4592 | /** |
@@ -5148,14 +5322,13 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
5148 | 5322 | ||
5149 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5323 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5150 | sas_address = le64_to_cpu(sas_device_pg0.SASAddress); | 5324 | sas_address = le64_to_cpu(sas_device_pg0.SASAddress); |
5151 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 5325 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
5152 | sas_address); | 5326 | sas_address); |
5153 | 5327 | ||
5154 | if (!sas_device) { | 5328 | if (!sas_device) { |
5155 | printk(MPT2SAS_ERR_FMT "device is not present " | 5329 | printk(MPT2SAS_ERR_FMT "device is not present " |
5156 | "handle(0x%04x), no sas_device!!!\n", ioc->name, handle); | 5330 | "handle(0x%04x), no sas_device!!!\n", ioc->name, handle); |
5157 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5331 | goto out_unlock; |
5158 | return; | ||
5159 | } | 5332 | } |
5160 | 5333 | ||
5161 | if (unlikely(sas_device->handle != handle)) { | 5334 | if (unlikely(sas_device->handle != handle)) { |
@@ -5172,19 +5345,24 @@ _scsih_check_device(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
5172 | MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { | 5345 | MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT)) { |
5173 | printk(MPT2SAS_ERR_FMT "device is not present " | 5346 | printk(MPT2SAS_ERR_FMT "device is not present " |
5174 | "handle(0x%04x), flags!!!\n", ioc->name, handle); | 5347 | "handle(0x%04x), flags!!!\n", ioc->name, handle); |
5175 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5348 | goto out_unlock; |
5176 | return; | ||
5177 | } | 5349 | } |
5178 | 5350 | ||
5179 | /* check if there were any issues with discovery */ | 5351 | /* check if there were any issues with discovery */ |
5180 | if (_scsih_check_access_status(ioc, sas_address, handle, | 5352 | if (_scsih_check_access_status(ioc, sas_address, handle, |
5181 | sas_device_pg0.AccessStatus)) { | 5353 | sas_device_pg0.AccessStatus)) |
5182 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5354 | goto out_unlock; |
5183 | return; | 5355 | |
5184 | } | ||
5185 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5356 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5186 | _scsih_ublock_io_device(ioc, sas_address); | 5357 | _scsih_ublock_io_device(ioc, sas_address); |
5358 | if (sas_device) | ||
5359 | sas_device_put(sas_device); | ||
5360 | return; | ||
5187 | 5361 | ||
5362 | out_unlock: | ||
5363 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5364 | if (sas_device) | ||
5365 | sas_device_put(sas_device); | ||
5188 | } | 5366 | } |
5189 | 5367 | ||
5190 | /** | 5368 | /** |
@@ -5208,7 +5386,6 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
5208 | u32 ioc_status; | 5386 | u32 ioc_status; |
5209 | __le64 sas_address; | 5387 | __le64 sas_address; |
5210 | u32 device_info; | 5388 | u32 device_info; |
5211 | unsigned long flags; | ||
5212 | 5389 | ||
5213 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | 5390 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, |
5214 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | 5391 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { |
@@ -5250,14 +5427,13 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
5250 | return -1; | 5427 | return -1; |
5251 | } | 5428 | } |
5252 | 5429 | ||
5253 | 5430 | sas_device = mpt2sas_get_sdev_by_addr(ioc, | |
5254 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
5255 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
5256 | sas_address); | 5431 | sas_address); |
5257 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
5258 | 5432 | ||
5259 | if (sas_device) | 5433 | if (sas_device) { |
5434 | sas_device_put(sas_device); | ||
5260 | return 0; | 5435 | return 0; |
5436 | } | ||
5261 | 5437 | ||
5262 | sas_device = kzalloc(sizeof(struct _sas_device), | 5438 | sas_device = kzalloc(sizeof(struct _sas_device), |
5263 | GFP_KERNEL); | 5439 | GFP_KERNEL); |
@@ -5267,6 +5443,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
5267 | return -1; | 5443 | return -1; |
5268 | } | 5444 | } |
5269 | 5445 | ||
5446 | kref_init(&sas_device->refcount); | ||
5270 | sas_device->handle = handle; | 5447 | sas_device->handle = handle; |
5271 | if (_scsih_get_sas_address(ioc, le16_to_cpu | 5448 | if (_scsih_get_sas_address(ioc, le16_to_cpu |
5272 | (sas_device_pg0.ParentDevHandle), | 5449 | (sas_device_pg0.ParentDevHandle), |
@@ -5296,6 +5473,7 @@ _scsih_add_device(struct MPT2SAS_ADAPTER *ioc, u16 handle, u8 phy_num, u8 is_pd) | |||
5296 | else | 5473 | else |
5297 | _scsih_sas_device_add(ioc, sas_device); | 5474 | _scsih_sas_device_add(ioc, sas_device); |
5298 | 5475 | ||
5476 | sas_device_put(sas_device); | ||
5299 | return 0; | 5477 | return 0; |
5300 | } | 5478 | } |
5301 | 5479 | ||
@@ -5344,7 +5522,6 @@ _scsih_remove_device(struct MPT2SAS_ADAPTER *ioc, | |||
5344 | "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, | 5522 | "handle(0x%04x), sas_addr(0x%016llx)\n", ioc->name, __func__, |
5345 | sas_device->handle, (unsigned long long) | 5523 | sas_device->handle, (unsigned long long) |
5346 | sas_device->sas_address)); | 5524 | sas_device->sas_address)); |
5347 | kfree(sas_device); | ||
5348 | } | 5525 | } |
5349 | /** | 5526 | /** |
5350 | * _scsih_device_remove_by_handle - removing device object by handle | 5527 | * _scsih_device_remove_by_handle - removing device object by handle |
@@ -5363,12 +5540,17 @@ _scsih_device_remove_by_handle(struct MPT2SAS_ADAPTER *ioc, u16 handle) | |||
5363 | return; | 5540 | return; |
5364 | 5541 | ||
5365 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5542 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5366 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 5543 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
5367 | if (sas_device) | 5544 | if (sas_device) { |
5368 | list_del(&sas_device->list); | 5545 | list_del_init(&sas_device->list); |
5546 | sas_device_put(sas_device); | ||
5547 | } | ||
5369 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5548 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5370 | if (sas_device) | 5549 | |
5550 | if (sas_device) { | ||
5371 | _scsih_remove_device(ioc, sas_device); | 5551 | _scsih_remove_device(ioc, sas_device); |
5552 | sas_device_put(sas_device); | ||
5553 | } | ||
5372 | } | 5554 | } |
5373 | 5555 | ||
5374 | /** | 5556 | /** |
@@ -5389,13 +5571,17 @@ mpt2sas_device_remove_by_sas_address(struct MPT2SAS_ADAPTER *ioc, | |||
5389 | return; | 5571 | return; |
5390 | 5572 | ||
5391 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5573 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5392 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 5574 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, sas_address); |
5393 | sas_address); | 5575 | if (sas_device) { |
5394 | if (sas_device) | 5576 | list_del_init(&sas_device->list); |
5395 | list_del(&sas_device->list); | 5577 | sas_device_put(sas_device); |
5578 | } | ||
5396 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5579 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5397 | if (sas_device) | 5580 | |
5581 | if (sas_device) { | ||
5398 | _scsih_remove_device(ioc, sas_device); | 5582 | _scsih_remove_device(ioc, sas_device); |
5583 | sas_device_put(sas_device); | ||
5584 | } | ||
5399 | } | 5585 | } |
5400 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5586 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
5401 | /** | 5587 | /** |
@@ -5716,26 +5902,28 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc, | |||
5716 | 5902 | ||
5717 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 5903 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
5718 | sas_address = le64_to_cpu(event_data->SASAddress); | 5904 | sas_address = le64_to_cpu(event_data->SASAddress); |
5719 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 5905 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
5720 | sas_address); | 5906 | sas_address); |
5721 | 5907 | ||
5722 | if (!sas_device || !sas_device->starget) { | 5908 | if (!sas_device || !sas_device->starget) |
5723 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5909 | goto out; |
5724 | return; | ||
5725 | } | ||
5726 | 5910 | ||
5727 | target_priv_data = sas_device->starget->hostdata; | 5911 | target_priv_data = sas_device->starget->hostdata; |
5728 | if (!target_priv_data) { | 5912 | if (!target_priv_data) |
5729 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5913 | goto out; |
5730 | return; | ||
5731 | } | ||
5732 | 5914 | ||
5733 | if (event_data->ReasonCode == | 5915 | if (event_data->ReasonCode == |
5734 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) | 5916 | MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET) |
5735 | target_priv_data->tm_busy = 1; | 5917 | target_priv_data->tm_busy = 1; |
5736 | else | 5918 | else |
5737 | target_priv_data->tm_busy = 0; | 5919 | target_priv_data->tm_busy = 0; |
5920 | |||
5921 | out: | ||
5922 | if (sas_device) | ||
5923 | sas_device_put(sas_device); | ||
5924 | |||
5738 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 5925 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
5926 | |||
5739 | } | 5927 | } |
5740 | 5928 | ||
5741 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING | 5929 | #ifdef CONFIG_SCSI_MPT2SAS_LOGGING |
@@ -6123,7 +6311,7 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc, | |||
6123 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 6311 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
6124 | 6312 | ||
6125 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6313 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6126 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6314 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
6127 | if (sas_device) { | 6315 | if (sas_device) { |
6128 | sas_device->volume_handle = 0; | 6316 | sas_device->volume_handle = 0; |
6129 | sas_device->volume_wwid = 0; | 6317 | sas_device->volume_wwid = 0; |
@@ -6142,6 +6330,8 @@ _scsih_sas_pd_expose(struct MPT2SAS_ADAPTER *ioc, | |||
6142 | /* exposing raid component */ | 6330 | /* exposing raid component */ |
6143 | if (starget) | 6331 | if (starget) |
6144 | starget_for_each_device(starget, NULL, _scsih_reprobe_lun); | 6332 | starget_for_each_device(starget, NULL, _scsih_reprobe_lun); |
6333 | |||
6334 | sas_device_put(sas_device); | ||
6145 | } | 6335 | } |
6146 | 6336 | ||
6147 | /** | 6337 | /** |
@@ -6170,7 +6360,7 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc, | |||
6170 | &volume_wwid); | 6360 | &volume_wwid); |
6171 | 6361 | ||
6172 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6362 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6173 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6363 | sas_device = __mpt2sas_get_sdev_by_handle(ioc, handle); |
6174 | if (sas_device) { | 6364 | if (sas_device) { |
6175 | set_bit(handle, ioc->pd_handles); | 6365 | set_bit(handle, ioc->pd_handles); |
6176 | if (sas_device->starget && sas_device->starget->hostdata) { | 6366 | if (sas_device->starget && sas_device->starget->hostdata) { |
@@ -6189,6 +6379,8 @@ _scsih_sas_pd_hide(struct MPT2SAS_ADAPTER *ioc, | |||
6189 | /* hiding raid component */ | 6379 | /* hiding raid component */ |
6190 | if (starget) | 6380 | if (starget) |
6191 | starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); | 6381 | starget_for_each_device(starget, (void *)1, _scsih_reprobe_lun); |
6382 | |||
6383 | sas_device_put(sas_device); | ||
6192 | } | 6384 | } |
6193 | 6385 | ||
6194 | /** | 6386 | /** |
@@ -6221,7 +6413,6 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
6221 | Mpi2EventIrConfigElement_t *element) | 6413 | Mpi2EventIrConfigElement_t *element) |
6222 | { | 6414 | { |
6223 | struct _sas_device *sas_device; | 6415 | struct _sas_device *sas_device; |
6224 | unsigned long flags; | ||
6225 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); | 6416 | u16 handle = le16_to_cpu(element->PhysDiskDevHandle); |
6226 | Mpi2ConfigReply_t mpi_reply; | 6417 | Mpi2ConfigReply_t mpi_reply; |
6227 | Mpi2SasDevicePage0_t sas_device_pg0; | 6418 | Mpi2SasDevicePage0_t sas_device_pg0; |
@@ -6231,11 +6422,11 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER *ioc, | |||
6231 | 6422 | ||
6232 | set_bit(handle, ioc->pd_handles); | 6423 | set_bit(handle, ioc->pd_handles); |
6233 | 6424 | ||
6234 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6425 | sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); |
6235 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6426 | if (sas_device) { |
6236 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6427 | sas_device_put(sas_device); |
6237 | if (sas_device) | ||
6238 | return; | 6428 | return; |
6429 | } | ||
6239 | 6430 | ||
6240 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, | 6431 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0, |
6241 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { | 6432 | MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) { |
@@ -6509,7 +6700,6 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
6509 | u16 handle, parent_handle; | 6700 | u16 handle, parent_handle; |
6510 | u32 state; | 6701 | u32 state; |
6511 | struct _sas_device *sas_device; | 6702 | struct _sas_device *sas_device; |
6512 | unsigned long flags; | ||
6513 | Mpi2ConfigReply_t mpi_reply; | 6703 | Mpi2ConfigReply_t mpi_reply; |
6514 | Mpi2SasDevicePage0_t sas_device_pg0; | 6704 | Mpi2SasDevicePage0_t sas_device_pg0; |
6515 | u32 ioc_status; | 6705 | u32 ioc_status; |
@@ -6542,12 +6732,11 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc, | |||
6542 | if (!ioc->is_warpdrive) | 6732 | if (!ioc->is_warpdrive) |
6543 | set_bit(handle, ioc->pd_handles); | 6733 | set_bit(handle, ioc->pd_handles); |
6544 | 6734 | ||
6545 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6735 | sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); |
6546 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 6736 | if (sas_device) { |
6547 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 6737 | sas_device_put(sas_device); |
6548 | |||
6549 | if (sas_device) | ||
6550 | return; | 6738 | return; |
6739 | } | ||
6551 | 6740 | ||
6552 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, | 6741 | if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, |
6553 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | 6742 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, |
@@ -7015,6 +7204,7 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) | |||
7015 | struct _raid_device *raid_device, *raid_device_next; | 7204 | struct _raid_device *raid_device, *raid_device_next; |
7016 | struct list_head tmp_list; | 7205 | struct list_head tmp_list; |
7017 | unsigned long flags; | 7206 | unsigned long flags; |
7207 | LIST_HEAD(head); | ||
7018 | 7208 | ||
7019 | printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n", | 7209 | printk(MPT2SAS_INFO_FMT "removing unresponding devices: start\n", |
7020 | ioc->name); | 7210 | ioc->name); |
@@ -7022,14 +7212,29 @@ _scsih_remove_unresponding_sas_devices(struct MPT2SAS_ADAPTER *ioc) | |||
7022 | /* removing unresponding end devices */ | 7212 | /* removing unresponding end devices */ |
7023 | printk(MPT2SAS_INFO_FMT "removing unresponding devices: end-devices\n", | 7213 | printk(MPT2SAS_INFO_FMT "removing unresponding devices: end-devices\n", |
7024 | ioc->name); | 7214 | ioc->name); |
7215 | |||
7216 | /* | ||
7217 | * Iterate, pulling off devices marked as non-responding. We become the | ||
7218 | * owner for the reference the list had on any object we prune. | ||
7219 | */ | ||
7220 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
7025 | list_for_each_entry_safe(sas_device, sas_device_next, | 7221 | list_for_each_entry_safe(sas_device, sas_device_next, |
7026 | &ioc->sas_device_list, list) { | 7222 | &ioc->sas_device_list, list) { |
7027 | if (!sas_device->responding) | 7223 | if (!sas_device->responding) |
7028 | mpt2sas_device_remove_by_sas_address(ioc, | 7224 | list_move_tail(&sas_device->list, &head); |
7029 | sas_device->sas_address); | ||
7030 | else | 7225 | else |
7031 | sas_device->responding = 0; | 7226 | sas_device->responding = 0; |
7032 | } | 7227 | } |
7228 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
7229 | |||
7230 | /* | ||
7231 | * Now, uninitialize and remove the unresponding devices we pruned. | ||
7232 | */ | ||
7233 | list_for_each_entry_safe(sas_device, sas_device_next, &head, list) { | ||
7234 | _scsih_remove_device(ioc, sas_device); | ||
7235 | list_del_init(&sas_device->list); | ||
7236 | sas_device_put(sas_device); | ||
7237 | } | ||
7033 | 7238 | ||
7034 | /* removing unresponding volumes */ | 7239 | /* removing unresponding volumes */ |
7035 | if (ioc->ir_firmware) { | 7240 | if (ioc->ir_firmware) { |
@@ -7179,11 +7384,11 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) | |||
7179 | } | 7384 | } |
7180 | phys_disk_num = pd_pg0.PhysDiskNum; | 7385 | phys_disk_num = pd_pg0.PhysDiskNum; |
7181 | handle = le16_to_cpu(pd_pg0.DevHandle); | 7386 | handle = le16_to_cpu(pd_pg0.DevHandle); |
7182 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7387 | sas_device = mpt2sas_get_sdev_by_handle(ioc, handle); |
7183 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | 7388 | if (sas_device) { |
7184 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7389 | sas_device_put(sas_device); |
7185 | if (sas_device) | ||
7186 | continue; | 7390 | continue; |
7391 | } | ||
7187 | if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, | 7392 | if (mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, |
7188 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, | 7393 | &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, |
7189 | handle) != 0) | 7394 | handle) != 0) |
@@ -7302,12 +7507,12 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc) | |||
7302 | if (!(_scsih_is_end_device( | 7507 | if (!(_scsih_is_end_device( |
7303 | le32_to_cpu(sas_device_pg0.DeviceInfo)))) | 7508 | le32_to_cpu(sas_device_pg0.DeviceInfo)))) |
7304 | continue; | 7509 | continue; |
7305 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 7510 | sas_device = mpt2sas_get_sdev_by_addr(ioc, |
7306 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | ||
7307 | le64_to_cpu(sas_device_pg0.SASAddress)); | 7511 | le64_to_cpu(sas_device_pg0.SASAddress)); |
7308 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 7512 | if (sas_device) { |
7309 | if (sas_device) | 7513 | sas_device_put(sas_device); |
7310 | continue; | 7514 | continue; |
7515 | } | ||
7311 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); | 7516 | parent_handle = le16_to_cpu(sas_device_pg0.ParentDevHandle); |
7312 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { | 7517 | if (!_scsih_get_sas_address(ioc, parent_handle, &sas_address)) { |
7313 | printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: " | 7518 | printk(MPT2SAS_INFO_FMT "\tBEFORE adding end device: " |
@@ -7410,17 +7615,27 @@ _firmware_event_work(struct work_struct *work) | |||
7410 | struct fw_event_work, delayed_work.work); | 7615 | struct fw_event_work, delayed_work.work); |
7411 | struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; | 7616 | struct MPT2SAS_ADAPTER *ioc = fw_event->ioc; |
7412 | 7617 | ||
7618 | _scsih_fw_event_del_from_list(ioc, fw_event); | ||
7619 | |||
7413 | /* the queue is being flushed so ignore this event */ | 7620 | /* the queue is being flushed so ignore this event */ |
7414 | if (ioc->remove_host || | 7621 | if (ioc->remove_host || ioc->pci_error_recovery) { |
7415 | ioc->pci_error_recovery) { | 7622 | fw_event_work_put(fw_event); |
7416 | _scsih_fw_event_free(ioc, fw_event); | ||
7417 | return; | 7623 | return; |
7418 | } | 7624 | } |
7419 | 7625 | ||
7420 | switch (fw_event->event) { | 7626 | switch (fw_event->event) { |
7421 | case MPT2SAS_REMOVE_UNRESPONDING_DEVICES: | 7627 | case MPT2SAS_REMOVE_UNRESPONDING_DEVICES: |
7422 | while (scsi_host_in_recovery(ioc->shost) || ioc->shost_recovery) | 7628 | while (scsi_host_in_recovery(ioc->shost) || |
7629 | ioc->shost_recovery) { | ||
7630 | /* | ||
7631 | * If we're unloading, bail. Otherwise, this can become | ||
7632 | * an infinite loop. | ||
7633 | */ | ||
7634 | if (ioc->remove_host) | ||
7635 | goto out; | ||
7636 | |||
7423 | ssleep(1); | 7637 | ssleep(1); |
7638 | } | ||
7424 | _scsih_remove_unresponding_sas_devices(ioc); | 7639 | _scsih_remove_unresponding_sas_devices(ioc); |
7425 | _scsih_scan_for_devices_after_reset(ioc); | 7640 | _scsih_scan_for_devices_after_reset(ioc); |
7426 | break; | 7641 | break; |
@@ -7469,7 +7684,8 @@ _firmware_event_work(struct work_struct *work) | |||
7469 | _scsih_sas_ir_operation_status_event(ioc, fw_event); | 7684 | _scsih_sas_ir_operation_status_event(ioc, fw_event); |
7470 | break; | 7685 | break; |
7471 | } | 7686 | } |
7472 | _scsih_fw_event_free(ioc, fw_event); | 7687 | out: |
7688 | fw_event_work_put(fw_event); | ||
7473 | } | 7689 | } |
7474 | 7690 | ||
7475 | /** | 7691 | /** |
@@ -7607,7 +7823,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
7607 | } | 7823 | } |
7608 | 7824 | ||
7609 | sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; | 7825 | sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; |
7610 | fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC); | 7826 | fw_event = alloc_fw_event_work(sz); |
7611 | if (!fw_event) { | 7827 | if (!fw_event) { |
7612 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", | 7828 | printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", |
7613 | ioc->name, __FILE__, __LINE__, __func__); | 7829 | ioc->name, __FILE__, __LINE__, __func__); |
@@ -7620,6 +7836,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, | |||
7620 | fw_event->VP_ID = mpi_reply->VP_ID; | 7836 | fw_event->VP_ID = mpi_reply->VP_ID; |
7621 | fw_event->event = event; | 7837 | fw_event->event = event; |
7622 | _scsih_fw_event_add(ioc, fw_event); | 7838 | _scsih_fw_event_add(ioc, fw_event); |
7839 | fw_event_work_put(fw_event); | ||
7623 | return; | 7840 | return; |
7624 | } | 7841 | } |
7625 | 7842 | ||
@@ -7867,7 +8084,9 @@ _scsih_remove(struct pci_dev *pdev) | |||
7867 | sas_remove_host(shost); | 8084 | sas_remove_host(shost); |
7868 | scsi_remove_host(shost); | 8085 | scsi_remove_host(shost); |
7869 | mpt2sas_base_detach(ioc); | 8086 | mpt2sas_base_detach(ioc); |
8087 | spin_lock(&gioc_lock); | ||
7870 | list_del(&ioc->list); | 8088 | list_del(&ioc->list); |
8089 | spin_unlock(&gioc_lock); | ||
7871 | scsi_host_put(shost); | 8090 | scsi_host_put(shost); |
7872 | } | 8091 | } |
7873 | 8092 | ||
@@ -7966,6 +8185,48 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc) | |||
7966 | } | 8185 | } |
7967 | } | 8186 | } |
7968 | 8187 | ||
8188 | static struct _sas_device *get_next_sas_device(struct MPT2SAS_ADAPTER *ioc) | ||
8189 | { | ||
8190 | struct _sas_device *sas_device = NULL; | ||
8191 | unsigned long flags; | ||
8192 | |||
8193 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
8194 | if (!list_empty(&ioc->sas_device_init_list)) { | ||
8195 | sas_device = list_first_entry(&ioc->sas_device_init_list, | ||
8196 | struct _sas_device, list); | ||
8197 | sas_device_get(sas_device); | ||
8198 | } | ||
8199 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
8200 | |||
8201 | return sas_device; | ||
8202 | } | ||
8203 | |||
8204 | static void sas_device_make_active(struct MPT2SAS_ADAPTER *ioc, | ||
8205 | struct _sas_device *sas_device) | ||
8206 | { | ||
8207 | unsigned long flags; | ||
8208 | |||
8209 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | ||
8210 | |||
8211 | /* | ||
8212 | * Since we dropped the lock during the call to port_add(), we need to | ||
8213 | * be careful here that somebody else didn't move or delete this item | ||
8214 | * while we were busy with other things. | ||
8215 | * | ||
8216 | * If it was on the list, we need a put() for the reference the list | ||
8217 | * had. Either way, we need a get() for the destination list. | ||
8218 | */ | ||
8219 | if (!list_empty(&sas_device->list)) { | ||
8220 | list_del_init(&sas_device->list); | ||
8221 | sas_device_put(sas_device); | ||
8222 | } | ||
8223 | |||
8224 | sas_device_get(sas_device); | ||
8225 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | ||
8226 | |||
8227 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | ||
8228 | } | ||
8229 | |||
7969 | /** | 8230 | /** |
7970 | * _scsih_probe_sas - reporting sas devices to sas transport | 8231 | * _scsih_probe_sas - reporting sas devices to sas transport |
7971 | * @ioc: per adapter object | 8232 | * @ioc: per adapter object |
@@ -7975,34 +8236,30 @@ _scsih_probe_raid(struct MPT2SAS_ADAPTER *ioc) | |||
7975 | static void | 8236 | static void |
7976 | _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) | 8237 | _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc) |
7977 | { | 8238 | { |
7978 | struct _sas_device *sas_device, *next; | 8239 | struct _sas_device *sas_device; |
7979 | unsigned long flags; | ||
7980 | |||
7981 | /* SAS Device List */ | ||
7982 | list_for_each_entry_safe(sas_device, next, &ioc->sas_device_init_list, | ||
7983 | list) { | ||
7984 | 8240 | ||
7985 | if (ioc->hide_drives) | 8241 | if (ioc->hide_drives) |
7986 | continue; | 8242 | return; |
7987 | 8243 | ||
8244 | while ((sas_device = get_next_sas_device(ioc))) { | ||
7988 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, | 8245 | if (!mpt2sas_transport_port_add(ioc, sas_device->handle, |
7989 | sas_device->sas_address_parent)) { | 8246 | sas_device->sas_address_parent)) { |
7990 | list_del(&sas_device->list); | 8247 | _scsih_sas_device_remove(ioc, sas_device); |
7991 | kfree(sas_device); | 8248 | sas_device_put(sas_device); |
7992 | continue; | 8249 | continue; |
7993 | } else if (!sas_device->starget) { | 8250 | } else if (!sas_device->starget) { |
7994 | if (!ioc->is_driver_loading) { | 8251 | if (!ioc->is_driver_loading) { |
7995 | mpt2sas_transport_port_remove(ioc, | 8252 | mpt2sas_transport_port_remove(ioc, |
7996 | sas_device->sas_address, | 8253 | sas_device->sas_address, |
7997 | sas_device->sas_address_parent); | 8254 | sas_device->sas_address_parent); |
7998 | list_del(&sas_device->list); | 8255 | _scsih_sas_device_remove(ioc, sas_device); |
7999 | kfree(sas_device); | 8256 | sas_device_put(sas_device); |
8000 | continue; | 8257 | continue; |
8001 | } | 8258 | } |
8002 | } | 8259 | } |
8003 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 8260 | |
8004 | list_move_tail(&sas_device->list, &ioc->sas_device_list); | 8261 | sas_device_make_active(ioc, sas_device); |
8005 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 8262 | sas_device_put(sas_device); |
8006 | } | 8263 | } |
8007 | } | 8264 | } |
8008 | 8265 | ||
@@ -8142,7 +8399,9 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8142 | ioc = shost_priv(shost); | 8399 | ioc = shost_priv(shost); |
8143 | memset(ioc, 0, sizeof(struct MPT2SAS_ADAPTER)); | 8400 | memset(ioc, 0, sizeof(struct MPT2SAS_ADAPTER)); |
8144 | INIT_LIST_HEAD(&ioc->list); | 8401 | INIT_LIST_HEAD(&ioc->list); |
8402 | spin_lock(&gioc_lock); | ||
8145 | list_add_tail(&ioc->list, &mpt2sas_ioc_list); | 8403 | list_add_tail(&ioc->list, &mpt2sas_ioc_list); |
8404 | spin_unlock(&gioc_lock); | ||
8146 | ioc->shost = shost; | 8405 | ioc->shost = shost; |
8147 | ioc->id = mpt_ids++; | 8406 | ioc->id = mpt_ids++; |
8148 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); | 8407 | sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id); |
@@ -8167,6 +8426,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8167 | ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; | 8426 | ioc->schedule_dead_ioc_flush_running_cmds = &_scsih_flush_running_cmds; |
8168 | /* misc semaphores and spin locks */ | 8427 | /* misc semaphores and spin locks */ |
8169 | mutex_init(&ioc->reset_in_progress_mutex); | 8428 | mutex_init(&ioc->reset_in_progress_mutex); |
8429 | /* initializing pci_access_mutex lock */ | ||
8430 | mutex_init(&ioc->pci_access_mutex); | ||
8170 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); | 8431 | spin_lock_init(&ioc->ioc_reset_in_progress_lock); |
8171 | spin_lock_init(&ioc->scsi_lookup_lock); | 8432 | spin_lock_init(&ioc->scsi_lookup_lock); |
8172 | spin_lock_init(&ioc->sas_device_lock); | 8433 | spin_lock_init(&ioc->sas_device_lock); |
@@ -8269,7 +8530,9 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
8269 | out_attach_fail: | 8530 | out_attach_fail: |
8270 | destroy_workqueue(ioc->firmware_event_thread); | 8531 | destroy_workqueue(ioc->firmware_event_thread); |
8271 | out_thread_fail: | 8532 | out_thread_fail: |
8533 | spin_lock(&gioc_lock); | ||
8272 | list_del(&ioc->list); | 8534 | list_del(&ioc->list); |
8535 | spin_unlock(&gioc_lock); | ||
8273 | scsi_host_put(shost); | 8536 | scsi_host_put(shost); |
8274 | return rv; | 8537 | return rv; |
8275 | } | 8538 | } |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_transport.c b/drivers/scsi/mpt2sas/mpt2sas_transport.c index ff2500ab9ba4..af868009395d 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_transport.c +++ b/drivers/scsi/mpt2sas/mpt2sas_transport.c | |||
@@ -1323,15 +1323,17 @@ _transport_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier) | |||
1323 | int rc; | 1323 | int rc; |
1324 | 1324 | ||
1325 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1325 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1326 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1326 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
1327 | rphy->identify.sas_address); | 1327 | rphy->identify.sas_address); |
1328 | if (sas_device) { | 1328 | if (sas_device) { |
1329 | *identifier = sas_device->enclosure_logical_id; | 1329 | *identifier = sas_device->enclosure_logical_id; |
1330 | rc = 0; | 1330 | rc = 0; |
1331 | sas_device_put(sas_device); | ||
1331 | } else { | 1332 | } else { |
1332 | *identifier = 0; | 1333 | *identifier = 0; |
1333 | rc = -ENXIO; | 1334 | rc = -ENXIO; |
1334 | } | 1335 | } |
1336 | |||
1335 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1337 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1336 | return rc; | 1338 | return rc; |
1337 | } | 1339 | } |
@@ -1351,12 +1353,14 @@ _transport_get_bay_identifier(struct sas_rphy *rphy) | |||
1351 | int rc; | 1353 | int rc; |
1352 | 1354 | ||
1353 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 1355 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
1354 | sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc, | 1356 | sas_device = __mpt2sas_get_sdev_by_addr(ioc, |
1355 | rphy->identify.sas_address); | 1357 | rphy->identify.sas_address); |
1356 | if (sas_device) | 1358 | if (sas_device) { |
1357 | rc = sas_device->slot; | 1359 | rc = sas_device->slot; |
1358 | else | 1360 | sas_device_put(sas_device); |
1361 | } else { | ||
1359 | rc = -ENXIO; | 1362 | rc = -ENXIO; |
1363 | } | ||
1360 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1364 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1361 | return rc; | 1365 | return rc; |
1362 | } | 1366 | } |
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h index c34c1157907b..ec27ad2d186f 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * scatter/gather formats. | 8 | * scatter/gather formats. |
9 | * Creation Date: June 21, 2006 | 9 | * Creation Date: June 21, 2006 |
10 | * | 10 | * |
11 | * mpi2.h Version: 02.00.31 | 11 | * mpi2.h Version: 02.00.35 |
12 | * | 12 | * |
13 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 | 13 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 |
14 | * prefix are for use only on MPI v2.5 products, and must not be used | 14 | * prefix are for use only on MPI v2.5 products, and must not be used |
@@ -88,6 +88,10 @@ | |||
88 | * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. | 88 | * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. |
89 | * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. | 89 | * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. |
90 | * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. | 90 | * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. |
91 | * 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT. | ||
92 | * 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT. | ||
93 | * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT | ||
94 | * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT. | ||
91 | * -------------------------------------------------------------------------- | 95 | * -------------------------------------------------------------------------- |
92 | */ | 96 | */ |
93 | 97 | ||
@@ -121,7 +125,7 @@ | |||
121 | #define MPI2_VERSION_02_05 (0x0205) | 125 | #define MPI2_VERSION_02_05 (0x0205) |
122 | 126 | ||
123 | /*Unit and Dev versioning for this MPI header set */ | 127 | /*Unit and Dev versioning for this MPI header set */ |
124 | #define MPI2_HEADER_VERSION_UNIT (0x1F) | 128 | #define MPI2_HEADER_VERSION_UNIT (0x23) |
125 | #define MPI2_HEADER_VERSION_DEV (0x00) | 129 | #define MPI2_HEADER_VERSION_DEV (0x00) |
126 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) | 130 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) |
127 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) | 131 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) |
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h index e261a3153bb3..581fdb375db5 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI Configuration messages and pages | 6 | * Title: MPI Configuration messages and pages |
7 | * Creation Date: November 10, 2006 | 7 | * Creation Date: November 10, 2006 |
8 | * | 8 | * |
9 | * mpi2_cnfg.h Version: 02.00.26 | 9 | * mpi2_cnfg.h Version: 02.00.29 |
10 | * | 10 | * |
11 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 | 11 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 |
12 | * prefix are for use only on MPI v2.5 products, and must not be used | 12 | * prefix are for use only on MPI v2.5 products, and must not be used |
@@ -165,6 +165,20 @@ | |||
165 | * match the specification. | 165 | * match the specification. |
166 | * 08-19-13 02.00.26 Added reserved words to MPI2_CONFIG_PAGE_IO_UNIT_7 for | 166 | * 08-19-13 02.00.26 Added reserved words to MPI2_CONFIG_PAGE_IO_UNIT_7 for |
167 | * future use. | 167 | * future use. |
168 | * 12-05-13 02.00.27 Added MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL for | ||
169 | * MPI2_CONFIG_PAGE_MAN_7. | ||
170 | * Added EnclosureLevel and ConnectorName fields to | ||
171 | * MPI2_CONFIG_PAGE_SAS_DEV_0. | ||
172 | * Added MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID for | ||
173 | * MPI2_CONFIG_PAGE_SAS_DEV_0. | ||
174 | * Added EnclosureLevel field to | ||
175 | * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. | ||
176 | * Added MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID for | ||
177 | * MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0. | ||
178 | * 01-08-14 02.00.28 Added more defines for the BiosOptions field of | ||
179 | * MPI2_CONFIG_PAGE_BIOS_1. | ||
180 | * 06-13-14 02.00.29 Added SSUTimeout field to MPI2_CONFIG_PAGE_BIOS_1, and | ||
181 | * more defines for the BiosOptions field.. | ||
168 | * -------------------------------------------------------------------------- | 182 | * -------------------------------------------------------------------------- |
169 | */ | 183 | */ |
170 | 184 | ||
@@ -724,6 +738,7 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_7 { | |||
724 | #define MPI2_MANUFACTURING7_PAGEVERSION (0x01) | 738 | #define MPI2_MANUFACTURING7_PAGEVERSION (0x01) |
725 | 739 | ||
726 | /*defines for the Flags field */ | 740 | /*defines for the Flags field */ |
741 | #define MPI2_MANPAGE7_FLAG_BASE_ENCLOSURE_LEVEL (0x00000008) | ||
727 | #define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) | 742 | #define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) |
728 | #define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) | 743 | #define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) |
729 | 744 | ||
@@ -1311,7 +1326,9 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { | |||
1311 | MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ | 1326 | MPI2_CONFIG_PAGE_HEADER Header; /*0x00 */ |
1312 | U32 BiosOptions; /*0x04 */ | 1327 | U32 BiosOptions; /*0x04 */ |
1313 | U32 IOCSettings; /*0x08 */ | 1328 | U32 IOCSettings; /*0x08 */ |
1314 | U32 Reserved1; /*0x0C */ | 1329 | U8 SSUTimeout; /*0x0C */ |
1330 | U8 Reserved1; /*0x0D */ | ||
1331 | U16 Reserved2; /*0x0E */ | ||
1315 | U32 DeviceSettings; /*0x10 */ | 1332 | U32 DeviceSettings; /*0x10 */ |
1316 | U16 NumberOfDevices; /*0x14 */ | 1333 | U16 NumberOfDevices; /*0x14 */ |
1317 | U16 UEFIVersion; /*0x16 */ | 1334 | U16 UEFIVersion; /*0x16 */ |
@@ -1323,9 +1340,24 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { | |||
1323 | *PTR_MPI2_CONFIG_PAGE_BIOS_1, | 1340 | *PTR_MPI2_CONFIG_PAGE_BIOS_1, |
1324 | Mpi2BiosPage1_t, *pMpi2BiosPage1_t; | 1341 | Mpi2BiosPage1_t, *pMpi2BiosPage1_t; |
1325 | 1342 | ||
1326 | #define MPI2_BIOSPAGE1_PAGEVERSION (0x05) | 1343 | #define MPI2_BIOSPAGE1_PAGEVERSION (0x07) |
1327 | 1344 | ||
1328 | /*values for BIOS Page 1 BiosOptions field */ | 1345 | /*values for BIOS Page 1 BiosOptions field */ |
1346 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_MASK (0x00003800) | ||
1347 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_PBDHL (0x00000000) | ||
1348 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_ENCSLOSURE (0x00000800) | ||
1349 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_LWWID (0x00001000) | ||
1350 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_PSENS (0x00001800) | ||
1351 | #define MPI2_BIOSPAGE1_OPTIONS_PNS_ESPHY (0x00002000) | ||
1352 | |||
1353 | #define MPI2_BIOSPAGE1_OPTIONS_X86_DISABLE_BIOS (0x00000400) | ||
1354 | |||
1355 | #define MPI2_BIOSPAGE1_OPTIONS_MASK_REGISTRATION_UEFI_BSD (0x00000300) | ||
1356 | #define MPI2_BIOSPAGE1_OPTIONS_USE_BIT0_REGISTRATION_UEFI_BSD (0x00000000) | ||
1357 | #define MPI2_BIOSPAGE1_OPTIONS_FULL_REGISTRATION_UEFI_BSD (0x00000100) | ||
1358 | #define MPI2_BIOSPAGE1_OPTIONS_ADAPTER_REGISTRATION_UEFI_BSD (0x00000200) | ||
1359 | #define MPI2_BIOSPAGE1_OPTIONS_DISABLE_REGISTRATION_UEFI_BSD (0x00000300) | ||
1360 | |||
1329 | #define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0) | 1361 | #define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0) |
1330 | #define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000) | 1362 | #define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000) |
1331 | 1363 | ||
@@ -2633,9 +2665,9 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 { | |||
2633 | U8 | 2665 | U8 |
2634 | ControlGroup; /*0x2E */ | 2666 | ControlGroup; /*0x2E */ |
2635 | U8 | 2667 | U8 |
2636 | Reserved1; /*0x2F */ | 2668 | EnclosureLevel; /*0x2F */ |
2637 | U32 | 2669 | U32 |
2638 | Reserved2; /*0x30 */ | 2670 | ConnectorName[4]; /*0x30 */ |
2639 | U32 | 2671 | U32 |
2640 | Reserved3; /*0x34 */ | 2672 | Reserved3; /*0x34 */ |
2641 | } MPI2_CONFIG_PAGE_SAS_DEV_0, | 2673 | } MPI2_CONFIG_PAGE_SAS_DEV_0, |
@@ -2643,7 +2675,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 { | |||
2643 | Mpi2SasDevicePage0_t, | 2675 | Mpi2SasDevicePage0_t, |
2644 | *pMpi2SasDevicePage0_t; | 2676 | *pMpi2SasDevicePage0_t; |
2645 | 2677 | ||
2646 | #define MPI2_SASDEVICE0_PAGEVERSION (0x08) | 2678 | #define MPI2_SASDEVICE0_PAGEVERSION (0x09) |
2647 | 2679 | ||
2648 | /*values for SAS Device Page 0 AccessStatus field */ | 2680 | /*values for SAS Device Page 0 AccessStatus field */ |
2649 | #define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) | 2681 | #define MPI2_SAS_DEVICE0_ASTATUS_NO_ERRORS (0x00) |
@@ -2683,6 +2715,7 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_DEV_0 { | |||
2683 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) | 2715 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_NCQ_SUPPORTED (0x0020) |
2684 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) | 2716 | #define MPI2_SAS_DEVICE0_FLAGS_SATA_FUA_SUPPORTED (0x0010) |
2685 | #define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) | 2717 | #define MPI2_SAS_DEVICE0_FLAGS_PORT_SELECTOR_ATTACH (0x0008) |
2718 | #define MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID (0x0002) | ||
2686 | #define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) | 2719 | #define MPI2_SAS_DEVICE0_FLAGS_DEVICE_PRESENT (0x0001) |
2687 | 2720 | ||
2688 | 2721 | ||
@@ -3019,8 +3052,10 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 { | |||
3019 | NumSlots; /*0x18 */ | 3052 | NumSlots; /*0x18 */ |
3020 | U16 | 3053 | U16 |
3021 | StartSlot; /*0x1A */ | 3054 | StartSlot; /*0x1A */ |
3022 | U16 | 3055 | U8 |
3023 | Reserved2; /*0x1C */ | 3056 | Reserved2; /*0x1C */ |
3057 | U8 | ||
3058 | EnclosureLevel; /*0x1D */ | ||
3024 | U16 | 3059 | U16 |
3025 | SEPDevHandle; /*0x1E */ | 3060 | SEPDevHandle; /*0x1E */ |
3026 | U32 | 3061 | U32 |
@@ -3031,9 +3066,10 @@ typedef struct _MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 { | |||
3031 | *PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, | 3066 | *PTR_MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0, |
3032 | Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t; | 3067 | Mpi2SasEnclosurePage0_t, *pMpi2SasEnclosurePage0_t; |
3033 | 3068 | ||
3034 | #define MPI2_SASENCLOSURE0_PAGEVERSION (0x03) | 3069 | #define MPI2_SASENCLOSURE0_PAGEVERSION (0x04) |
3035 | 3070 | ||
3036 | /*values for SAS Enclosure Page 0 Flags field */ | 3071 | /*values for SAS Enclosure Page 0 Flags field */ |
3072 | #define MPI2_SAS_ENCLS0_FLAGS_ENCL_LEVEL_VALID (0x0010) | ||
3037 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK (0x000F) | 3073 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_MASK (0x000F) |
3038 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000) | 3074 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_UNKNOWN (0x0000) |
3039 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES (0x0001) | 3075 | #define MPI2_SAS_ENCLS0_FLAGS_MNG_IOC_SES (0x0001) |
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h index 490830957806..d7598cc4bb8e 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages | 6 | * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages |
7 | * Creation Date: October 11, 2006 | 7 | * Creation Date: October 11, 2006 |
8 | * | 8 | * |
9 | * mpi2_ioc.h Version: 02.00.23 | 9 | * mpi2_ioc.h Version: 02.00.24 |
10 | * | 10 | * |
11 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 | 11 | * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 |
12 | * prefix are for use only on MPI v2.5 products, and must not be used | 12 | * prefix are for use only on MPI v2.5 products, and must not be used |
@@ -132,6 +132,7 @@ | |||
132 | * Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE. | 132 | * Added MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE. |
133 | * Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY. | 133 | * Added MPI2_FW_DOWNLOAD_ITYPE_PUBLIC_KEY. |
134 | * Added Encrypted Hash Extended Image. | 134 | * Added Encrypted Hash Extended Image. |
135 | * 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS. | ||
135 | * -------------------------------------------------------------------------- | 136 | * -------------------------------------------------------------------------- |
136 | */ | 137 | */ |
137 | 138 | ||
@@ -1598,6 +1599,7 @@ Mpi25EncryptedHashEntry_t, *pMpi25EncryptedHashEntry_t; | |||
1598 | /* values for HashImageType */ | 1599 | /* values for HashImageType */ |
1599 | #define MPI25_HASH_IMAGE_TYPE_UNUSED (0x00) | 1600 | #define MPI25_HASH_IMAGE_TYPE_UNUSED (0x00) |
1600 | #define MPI25_HASH_IMAGE_TYPE_FIRMWARE (0x01) | 1601 | #define MPI25_HASH_IMAGE_TYPE_FIRMWARE (0x01) |
1602 | #define MPI25_HASH_IMAGE_TYPE_BIOS (0x02) | ||
1601 | 1603 | ||
1602 | /* values for HashAlgorithm */ | 1604 | /* values for HashAlgorithm */ |
1603 | #define MPI25_HASH_ALGORITHM_UNUSED (0x00) | 1605 | #define MPI25_HASH_ALGORITHM_UNUSED (0x00) |
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h index 904910d8a737..1629e5bce7e1 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * Title: MPI diagnostic tool structures and definitions | 6 | * Title: MPI diagnostic tool structures and definitions |
7 | * Creation Date: March 26, 2007 | 7 | * Creation Date: March 26, 2007 |
8 | * | 8 | * |
9 | * mpi2_tool.h Version: 02.00.11 | 9 | * mpi2_tool.h Version: 02.00.12 |
10 | * | 10 | * |
11 | * Version History | 11 | * Version History |
12 | * --------------- | 12 | * --------------- |
@@ -33,6 +33,7 @@ | |||
33 | * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that | 33 | * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that |
34 | * it uses MPI Chain SGE as well as MPI Simple SGE. | 34 | * it uses MPI Chain SGE as well as MPI Simple SGE. |
35 | * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. | 35 | * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. |
36 | * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC. | ||
36 | * -------------------------------------------------------------------------- | 37 | * -------------------------------------------------------------------------- |
37 | */ | 38 | */ |
38 | 39 | ||
@@ -100,6 +101,7 @@ typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST { | |||
100 | #define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) | 101 | #define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) |
101 | #define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) | 102 | #define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) |
102 | #define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) | 103 | #define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) |
104 | #define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000) | ||
103 | #define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) | 105 | #define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) |
104 | #define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) | 106 | #define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) |
105 | #define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) | 107 | #define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 43f87e904b98..d4f1dcdb8361 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -83,10 +83,10 @@ static int msix_disable = -1; | |||
83 | module_param(msix_disable, int, 0); | 83 | module_param(msix_disable, int, 0); |
84 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); | 84 | MODULE_PARM_DESC(msix_disable, " disable msix routed interrupts (default=0)"); |
85 | 85 | ||
86 | static int max_msix_vectors = 8; | 86 | static int max_msix_vectors = -1; |
87 | module_param(max_msix_vectors, int, 0); | 87 | module_param(max_msix_vectors, int, 0); |
88 | MODULE_PARM_DESC(max_msix_vectors, | 88 | MODULE_PARM_DESC(max_msix_vectors, |
89 | " max msix vectors - (default=8)"); | 89 | " max msix vectors"); |
90 | 90 | ||
91 | static int mpt3sas_fwfault_debug; | 91 | static int mpt3sas_fwfault_debug; |
92 | MODULE_PARM_DESC(mpt3sas_fwfault_debug, | 92 | MODULE_PARM_DESC(mpt3sas_fwfault_debug, |
@@ -1009,8 +1009,30 @@ _base_interrupt(int irq, void *bus_id) | |||
1009 | } | 1009 | } |
1010 | 1010 | ||
1011 | wmb(); | 1011 | wmb(); |
1012 | writel(reply_q->reply_post_host_index | (msix_index << | 1012 | |
1013 | MPI2_RPHI_MSIX_INDEX_SHIFT), &ioc->chip->ReplyPostHostIndex); | 1013 | /* Update Reply Post Host Index. |
1014 | * For those HBA's which support combined reply queue feature | ||
1015 | * 1. Get the correct Supplemental Reply Post Host Index Register. | ||
1016 | * i.e. (msix_index / 8)th entry from Supplemental Reply Post Host | ||
1017 | * Index Register address bank i.e replyPostRegisterIndex[], | ||
1018 | * 2. Then update this register with new reply host index value | ||
1019 | * in ReplyPostIndex field and the MSIxIndex field with | ||
1020 | * msix_index value reduced to a value between 0 and 7, | ||
1021 | * using a modulo 8 operation. Since each Supplemental Reply Post | ||
1022 | * Host Index Register supports 8 MSI-X vectors. | ||
1023 | * | ||
1024 | * For other HBA's just update the Reply Post Host Index register with | ||
1025 | * new reply host index value in ReplyPostIndex Field and msix_index | ||
1026 | * value in MSIxIndex field. | ||
1027 | */ | ||
1028 | if (ioc->msix96_vector) | ||
1029 | writel(reply_q->reply_post_host_index | ((msix_index & 7) << | ||
1030 | MPI2_RPHI_MSIX_INDEX_SHIFT), | ||
1031 | ioc->replyPostRegisterIndex[msix_index/8]); | ||
1032 | else | ||
1033 | writel(reply_q->reply_post_host_index | (msix_index << | ||
1034 | MPI2_RPHI_MSIX_INDEX_SHIFT), | ||
1035 | &ioc->chip->ReplyPostHostIndex); | ||
1014 | atomic_dec(&reply_q->busy); | 1036 | atomic_dec(&reply_q->busy); |
1015 | return IRQ_HANDLED; | 1037 | return IRQ_HANDLED; |
1016 | } | 1038 | } |
@@ -1338,7 +1360,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, | |||
1338 | 1360 | ||
1339 | sg_scmd = scsi_sglist(scmd); | 1361 | sg_scmd = scsi_sglist(scmd); |
1340 | sges_left = scsi_dma_map(scmd); | 1362 | sges_left = scsi_dma_map(scmd); |
1341 | if (!sges_left) { | 1363 | if (sges_left < 0) { |
1342 | sdev_printk(KERN_ERR, scmd->device, | 1364 | sdev_printk(KERN_ERR, scmd->device, |
1343 | "pci_map_sg failed: request for %d bytes!\n", | 1365 | "pci_map_sg failed: request for %d bytes!\n", |
1344 | scsi_bufflen(scmd)); | 1366 | scsi_bufflen(scmd)); |
@@ -1407,7 +1429,7 @@ _base_build_sg_scmd_ieee(struct MPT3SAS_ADAPTER *ioc, | |||
1407 | fill_in_last_segment: | 1429 | fill_in_last_segment: |
1408 | 1430 | ||
1409 | /* fill the last segment */ | 1431 | /* fill the last segment */ |
1410 | while (sges_left) { | 1432 | while (sges_left > 0) { |
1411 | if (sges_left == 1) | 1433 | if (sges_left == 1) |
1412 | _base_add_sg_single_ieee(sg_local, | 1434 | _base_add_sg_single_ieee(sg_local, |
1413 | simple_sgl_flags_last, 0, sg_dma_len(sg_scmd), | 1435 | simple_sgl_flags_last, 0, sg_dma_len(sg_scmd), |
@@ -1560,8 +1582,6 @@ _base_check_enable_msix(struct MPT3SAS_ADAPTER *ioc) | |||
1560 | 1582 | ||
1561 | pci_read_config_word(ioc->pdev, base + 2, &message_control); | 1583 | pci_read_config_word(ioc->pdev, base + 2, &message_control); |
1562 | ioc->msix_vector_count = (message_control & 0x3FF) + 1; | 1584 | ioc->msix_vector_count = (message_control & 0x3FF) + 1; |
1563 | if (ioc->msix_vector_count > 8) | ||
1564 | ioc->msix_vector_count = 8; | ||
1565 | dinitprintk(ioc, pr_info(MPT3SAS_FMT | 1585 | dinitprintk(ioc, pr_info(MPT3SAS_FMT |
1566 | "msix is supported, vector_count(%d)\n", | 1586 | "msix is supported, vector_count(%d)\n", |
1567 | ioc->name, ioc->msix_vector_count)); | 1587 | ioc->name, ioc->msix_vector_count)); |
@@ -1793,6 +1813,36 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) | |||
1793 | } | 1813 | } |
1794 | 1814 | ||
1795 | /** | 1815 | /** |
1816 | * mpt3sas_base_unmap_resources - free controller resources | ||
1817 | * @ioc: per adapter object | ||
1818 | */ | ||
1819 | void | ||
1820 | mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) | ||
1821 | { | ||
1822 | struct pci_dev *pdev = ioc->pdev; | ||
1823 | |||
1824 | dexitprintk(ioc, printk(MPT3SAS_FMT "%s\n", | ||
1825 | ioc->name, __func__)); | ||
1826 | |||
1827 | _base_free_irq(ioc); | ||
1828 | _base_disable_msix(ioc); | ||
1829 | |||
1830 | if (ioc->msix96_vector) | ||
1831 | kfree(ioc->replyPostRegisterIndex); | ||
1832 | |||
1833 | if (ioc->chip_phys) { | ||
1834 | iounmap(ioc->chip); | ||
1835 | ioc->chip_phys = 0; | ||
1836 | } | ||
1837 | |||
1838 | if (pci_is_enabled(pdev)) { | ||
1839 | pci_release_selected_regions(ioc->pdev, ioc->bars); | ||
1840 | pci_disable_pcie_error_reporting(pdev); | ||
1841 | pci_disable_device(pdev); | ||
1842 | } | ||
1843 | } | ||
1844 | |||
1845 | /** | ||
1796 | * mpt3sas_base_map_resources - map in controller resources (io/irq/memap) | 1846 | * mpt3sas_base_map_resources - map in controller resources (io/irq/memap) |
1797 | * @ioc: per adapter object | 1847 | * @ioc: per adapter object |
1798 | * | 1848 | * |
@@ -1882,6 +1932,36 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
1882 | if (r) | 1932 | if (r) |
1883 | goto out_fail; | 1933 | goto out_fail; |
1884 | 1934 | ||
1935 | /* Use the Combined reply queue feature only for SAS3 C0 & higher | ||
1936 | * revision HBAs and also only when reply queue count is greater than 8 | ||
1937 | */ | ||
1938 | if (ioc->msix96_vector && ioc->reply_queue_count > 8) { | ||
1939 | /* Determine the Supplemental Reply Post Host Index Registers | ||
1940 | * Addresse. Supplemental Reply Post Host Index Registers | ||
1941 | * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and | ||
1942 | * each register is at offset bytes of | ||
1943 | * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one. | ||
1944 | */ | ||
1945 | ioc->replyPostRegisterIndex = kcalloc( | ||
1946 | MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT, | ||
1947 | sizeof(resource_size_t *), GFP_KERNEL); | ||
1948 | if (!ioc->replyPostRegisterIndex) { | ||
1949 | dfailprintk(ioc, printk(MPT3SAS_FMT | ||
1950 | "allocation for reply Post Register Index failed!!!\n", | ||
1951 | ioc->name)); | ||
1952 | r = -ENOMEM; | ||
1953 | goto out_fail; | ||
1954 | } | ||
1955 | |||
1956 | for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) { | ||
1957 | ioc->replyPostRegisterIndex[i] = (resource_size_t *) | ||
1958 | ((u8 *)&ioc->chip->Doorbell + | ||
1959 | MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET + | ||
1960 | (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET)); | ||
1961 | } | ||
1962 | } else | ||
1963 | ioc->msix96_vector = 0; | ||
1964 | |||
1885 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) | 1965 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) |
1886 | pr_info(MPT3SAS_FMT "%s: IRQ %d\n", | 1966 | pr_info(MPT3SAS_FMT "%s: IRQ %d\n", |
1887 | reply_q->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : | 1967 | reply_q->name, ((ioc->msix_enable) ? "PCI-MSI-X enabled" : |
@@ -1897,12 +1977,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
1897 | return 0; | 1977 | return 0; |
1898 | 1978 | ||
1899 | out_fail: | 1979 | out_fail: |
1900 | if (ioc->chip_phys) | 1980 | mpt3sas_base_unmap_resources(ioc); |
1901 | iounmap(ioc->chip); | ||
1902 | ioc->chip_phys = 0; | ||
1903 | pci_release_selected_regions(ioc->pdev, ioc->bars); | ||
1904 | pci_disable_pcie_error_reporting(pdev); | ||
1905 | pci_disable_device(pdev); | ||
1906 | return r; | 1981 | return r; |
1907 | } | 1982 | } |
1908 | 1983 | ||
@@ -2292,6 +2367,99 @@ _base_display_intel_branding(struct MPT3SAS_ADAPTER *ioc) | |||
2292 | 2367 | ||
2293 | 2368 | ||
2294 | /** | 2369 | /** |
2370 | * _base_display_dell_branding - Display branding string | ||
2371 | * @ioc: per adapter object | ||
2372 | * | ||
2373 | * Return nothing. | ||
2374 | */ | ||
2375 | static void | ||
2376 | _base_display_dell_branding(struct MPT3SAS_ADAPTER *ioc) | ||
2377 | { | ||
2378 | if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_DELL) | ||
2379 | return; | ||
2380 | |||
2381 | switch (ioc->pdev->device) { | ||
2382 | case MPI25_MFGPAGE_DEVID_SAS3008: | ||
2383 | switch (ioc->pdev->subsystem_device) { | ||
2384 | case MPT3SAS_DELL_12G_HBA_SSDID: | ||
2385 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2386 | MPT3SAS_DELL_12G_HBA_BRANDING); | ||
2387 | break; | ||
2388 | default: | ||
2389 | pr_info(MPT3SAS_FMT | ||
2390 | "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name, | ||
2391 | ioc->pdev->subsystem_device); | ||
2392 | break; | ||
2393 | } | ||
2394 | break; | ||
2395 | default: | ||
2396 | pr_info(MPT3SAS_FMT | ||
2397 | "Dell 12Gbps HBA: Subsystem ID: 0x%X\n", ioc->name, | ||
2398 | ioc->pdev->subsystem_device); | ||
2399 | break; | ||
2400 | } | ||
2401 | } | ||
2402 | |||
2403 | /** | ||
2404 | * _base_display_cisco_branding - Display branding string | ||
2405 | * @ioc: per adapter object | ||
2406 | * | ||
2407 | * Return nothing. | ||
2408 | */ | ||
2409 | static void | ||
2410 | _base_display_cisco_branding(struct MPT3SAS_ADAPTER *ioc) | ||
2411 | { | ||
2412 | if (ioc->pdev->subsystem_vendor != PCI_VENDOR_ID_CISCO) | ||
2413 | return; | ||
2414 | |||
2415 | switch (ioc->pdev->device) { | ||
2416 | case MPI25_MFGPAGE_DEVID_SAS3008: | ||
2417 | switch (ioc->pdev->subsystem_device) { | ||
2418 | case MPT3SAS_CISCO_12G_8E_HBA_SSDID: | ||
2419 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2420 | MPT3SAS_CISCO_12G_8E_HBA_BRANDING); | ||
2421 | break; | ||
2422 | case MPT3SAS_CISCO_12G_8I_HBA_SSDID: | ||
2423 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2424 | MPT3SAS_CISCO_12G_8I_HBA_BRANDING); | ||
2425 | break; | ||
2426 | case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: | ||
2427 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2428 | MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); | ||
2429 | break; | ||
2430 | default: | ||
2431 | pr_info(MPT3SAS_FMT | ||
2432 | "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", | ||
2433 | ioc->name, ioc->pdev->subsystem_device); | ||
2434 | break; | ||
2435 | } | ||
2436 | break; | ||
2437 | case MPI25_MFGPAGE_DEVID_SAS3108_1: | ||
2438 | switch (ioc->pdev->subsystem_device) { | ||
2439 | case MPT3SAS_CISCO_12G_AVILA_HBA_SSDID: | ||
2440 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2441 | MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING); | ||
2442 | break; | ||
2443 | case MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID: | ||
2444 | pr_info(MPT3SAS_FMT "%s\n", ioc->name, | ||
2445 | MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING); | ||
2446 | break; | ||
2447 | default: | ||
2448 | pr_info(MPT3SAS_FMT | ||
2449 | "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", | ||
2450 | ioc->name, ioc->pdev->subsystem_device); | ||
2451 | break; | ||
2452 | } | ||
2453 | break; | ||
2454 | default: | ||
2455 | pr_info(MPT3SAS_FMT | ||
2456 | "Cisco 12Gbps SAS HBA: Subsystem ID: 0x%X\n", | ||
2457 | ioc->name, ioc->pdev->subsystem_device); | ||
2458 | break; | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | /** | ||
2295 | * _base_display_ioc_capabilities - Disply IOC's capabilities. | 2463 | * _base_display_ioc_capabilities - Disply IOC's capabilities. |
2296 | * @ioc: per adapter object | 2464 | * @ioc: per adapter object |
2297 | * | 2465 | * |
@@ -2321,6 +2489,8 @@ _base_display_ioc_capabilities(struct MPT3SAS_ADAPTER *ioc) | |||
2321 | bios_version & 0x000000FF); | 2489 | bios_version & 0x000000FF); |
2322 | 2490 | ||
2323 | _base_display_intel_branding(ioc); | 2491 | _base_display_intel_branding(ioc); |
2492 | _base_display_dell_branding(ioc); | ||
2493 | _base_display_cisco_branding(ioc); | ||
2324 | 2494 | ||
2325 | pr_info(MPT3SAS_FMT "Protocol=(", ioc->name); | 2495 | pr_info(MPT3SAS_FMT "Protocol=(", ioc->name); |
2326 | 2496 | ||
@@ -3139,6 +3309,9 @@ _base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout, | |||
3139 | * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell. | 3309 | * Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell. |
3140 | */ | 3310 | */ |
3141 | static int | 3311 | static int |
3312 | _base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag); | ||
3313 | |||
3314 | static int | ||
3142 | _base_wait_for_doorbell_int(struct MPT3SAS_ADAPTER *ioc, int timeout, | 3315 | _base_wait_for_doorbell_int(struct MPT3SAS_ADAPTER *ioc, int timeout, |
3143 | int sleep_flag) | 3316 | int sleep_flag) |
3144 | { | 3317 | { |
@@ -3681,6 +3854,64 @@ _base_get_port_facts(struct MPT3SAS_ADAPTER *ioc, int port, int sleep_flag) | |||
3681 | } | 3854 | } |
3682 | 3855 | ||
3683 | /** | 3856 | /** |
3857 | * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL | ||
3858 | * @ioc: per adapter object | ||
3859 | * @timeout: | ||
3860 | * @sleep_flag: CAN_SLEEP or NO_SLEEP | ||
3861 | * | ||
3862 | * Returns 0 for success, non-zero for failure. | ||
3863 | */ | ||
3864 | static int | ||
3865 | _base_wait_for_iocstate(struct MPT3SAS_ADAPTER *ioc, int timeout, | ||
3866 | int sleep_flag) | ||
3867 | { | ||
3868 | u32 ioc_state; | ||
3869 | int rc; | ||
3870 | |||
3871 | dinitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ioc->name, | ||
3872 | __func__)); | ||
3873 | |||
3874 | if (ioc->pci_error_recovery) { | ||
3875 | dfailprintk(ioc, printk(MPT3SAS_FMT | ||
3876 | "%s: host in pci error recovery\n", ioc->name, __func__)); | ||
3877 | return -EFAULT; | ||
3878 | } | ||
3879 | |||
3880 | ioc_state = mpt3sas_base_get_iocstate(ioc, 0); | ||
3881 | dhsprintk(ioc, printk(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n", | ||
3882 | ioc->name, __func__, ioc_state)); | ||
3883 | |||
3884 | if (((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) || | ||
3885 | (ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL) | ||
3886 | return 0; | ||
3887 | |||
3888 | if (ioc_state & MPI2_DOORBELL_USED) { | ||
3889 | dhsprintk(ioc, printk(MPT3SAS_FMT | ||
3890 | "unexpected doorbell active!\n", ioc->name)); | ||
3891 | goto issue_diag_reset; | ||
3892 | } | ||
3893 | |||
3894 | if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { | ||
3895 | mpt3sas_base_fault_info(ioc, ioc_state & | ||
3896 | MPI2_DOORBELL_DATA_MASK); | ||
3897 | goto issue_diag_reset; | ||
3898 | } | ||
3899 | |||
3900 | ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY, | ||
3901 | timeout, sleep_flag); | ||
3902 | if (ioc_state) { | ||
3903 | dfailprintk(ioc, printk(MPT3SAS_FMT | ||
3904 | "%s: failed going to ready state (ioc_state=0x%x)\n", | ||
3905 | ioc->name, __func__, ioc_state)); | ||
3906 | return -EFAULT; | ||
3907 | } | ||
3908 | |||
3909 | issue_diag_reset: | ||
3910 | rc = _base_diag_reset(ioc, sleep_flag); | ||
3911 | return rc; | ||
3912 | } | ||
3913 | |||
3914 | /** | ||
3684 | * _base_get_ioc_facts - obtain ioc facts reply and save in ioc | 3915 | * _base_get_ioc_facts - obtain ioc facts reply and save in ioc |
3685 | * @ioc: per adapter object | 3916 | * @ioc: per adapter object |
3686 | * @sleep_flag: CAN_SLEEP or NO_SLEEP | 3917 | * @sleep_flag: CAN_SLEEP or NO_SLEEP |
@@ -3698,6 +3929,13 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
3698 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, | 3929 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, |
3699 | __func__)); | 3930 | __func__)); |
3700 | 3931 | ||
3932 | r = _base_wait_for_iocstate(ioc, 10, sleep_flag); | ||
3933 | if (r) { | ||
3934 | dfailprintk(ioc, printk(MPT3SAS_FMT | ||
3935 | "%s: failed getting to correct state\n", | ||
3936 | ioc->name, __func__)); | ||
3937 | return r; | ||
3938 | } | ||
3701 | mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); | 3939 | mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); |
3702 | mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); | 3940 | mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); |
3703 | memset(&mpi_request, 0, mpi_request_sz); | 3941 | memset(&mpi_request, 0, mpi_request_sz); |
@@ -3783,7 +4021,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
3783 | mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER; | 4021 | mpi_request.WhoInit = MPI2_WHOINIT_HOST_DRIVER; |
3784 | mpi_request.VF_ID = 0; /* TODO */ | 4022 | mpi_request.VF_ID = 0; /* TODO */ |
3785 | mpi_request.VP_ID = 0; | 4023 | mpi_request.VP_ID = 0; |
3786 | mpi_request.MsgVersion = cpu_to_le16(MPI2_VERSION); | 4024 | mpi_request.MsgVersion = cpu_to_le16(MPI25_VERSION); |
3787 | mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); | 4025 | mpi_request.HeaderVersion = cpu_to_le16(MPI2_HEADER_VERSION); |
3788 | 4026 | ||
3789 | if (_base_is_controller_msix_enabled(ioc)) | 4027 | if (_base_is_controller_msix_enabled(ioc)) |
@@ -4524,8 +4762,15 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
4524 | 4762 | ||
4525 | /* initialize reply post host index */ | 4763 | /* initialize reply post host index */ |
4526 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { | 4764 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { |
4527 | writel(reply_q->msix_index << MPI2_RPHI_MSIX_INDEX_SHIFT, | 4765 | if (ioc->msix96_vector) |
4528 | &ioc->chip->ReplyPostHostIndex); | 4766 | writel((reply_q->msix_index & 7)<< |
4767 | MPI2_RPHI_MSIX_INDEX_SHIFT, | ||
4768 | ioc->replyPostRegisterIndex[reply_q->msix_index/8]); | ||
4769 | else | ||
4770 | writel(reply_q->msix_index << | ||
4771 | MPI2_RPHI_MSIX_INDEX_SHIFT, | ||
4772 | &ioc->chip->ReplyPostHostIndex); | ||
4773 | |||
4529 | if (!_base_is_controller_msix_enabled(ioc)) | 4774 | if (!_base_is_controller_msix_enabled(ioc)) |
4530 | goto skip_init_reply_post_host_index; | 4775 | goto skip_init_reply_post_host_index; |
4531 | } | 4776 | } |
@@ -4564,8 +4809,6 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
4564 | void | 4809 | void |
4565 | mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) | 4810 | mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) |
4566 | { | 4811 | { |
4567 | struct pci_dev *pdev = ioc->pdev; | ||
4568 | |||
4569 | dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, | 4812 | dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, |
4570 | __func__)); | 4813 | __func__)); |
4571 | 4814 | ||
@@ -4576,18 +4819,7 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc) | |||
4576 | ioc->shost_recovery = 0; | 4819 | ioc->shost_recovery = 0; |
4577 | } | 4820 | } |
4578 | 4821 | ||
4579 | _base_free_irq(ioc); | 4822 | mpt3sas_base_unmap_resources(ioc); |
4580 | _base_disable_msix(ioc); | ||
4581 | |||
4582 | if (ioc->chip_phys && ioc->chip) | ||
4583 | iounmap(ioc->chip); | ||
4584 | ioc->chip_phys = 0; | ||
4585 | |||
4586 | if (pci_is_enabled(pdev)) { | ||
4587 | pci_release_selected_regions(ioc->pdev, ioc->bars); | ||
4588 | pci_disable_pcie_error_reporting(pdev); | ||
4589 | pci_disable_device(pdev); | ||
4590 | } | ||
4591 | return; | 4823 | return; |
4592 | } | 4824 | } |
4593 | 4825 | ||
@@ -4602,6 +4834,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
4602 | { | 4834 | { |
4603 | int r, i; | 4835 | int r, i; |
4604 | int cpu_id, last_cpu_id = 0; | 4836 | int cpu_id, last_cpu_id = 0; |
4837 | u8 revision; | ||
4605 | 4838 | ||
4606 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, | 4839 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, |
4607 | __func__)); | 4840 | __func__)); |
@@ -4621,6 +4854,20 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
4621 | goto out_free_resources; | 4854 | goto out_free_resources; |
4622 | } | 4855 | } |
4623 | 4856 | ||
4857 | /* Check whether the controller revision is C0 or above. | ||
4858 | * only C0 and above revision controllers support 96 MSI-X vectors. | ||
4859 | */ | ||
4860 | revision = ioc->pdev->revision; | ||
4861 | |||
4862 | if ((ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3004 || | ||
4863 | ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3008 || | ||
4864 | ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_1 || | ||
4865 | ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_2 || | ||
4866 | ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_5 || | ||
4867 | ioc->pdev->device == MPI25_MFGPAGE_DEVID_SAS3108_6) && | ||
4868 | (revision >= 0x02)) | ||
4869 | ioc->msix96_vector = 1; | ||
4870 | |||
4624 | ioc->rdpq_array_enable_assigned = 0; | 4871 | ioc->rdpq_array_enable_assigned = 0; |
4625 | ioc->dma_mask = 0; | 4872 | ioc->dma_mask = 0; |
4626 | r = mpt3sas_base_map_resources(ioc); | 4873 | r = mpt3sas_base_map_resources(ioc); |
@@ -4643,7 +4890,6 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
4643 | ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; | 4890 | ioc->build_sg_scmd = &_base_build_sg_scmd_ieee; |
4644 | ioc->build_sg = &_base_build_sg_ieee; | 4891 | ioc->build_sg = &_base_build_sg_ieee; |
4645 | ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; | 4892 | ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; |
4646 | ioc->mpi25 = 1; | ||
4647 | ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); | 4893 | ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); |
4648 | 4894 | ||
4649 | /* | 4895 | /* |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index afa881682bef..f0e462b0880d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
@@ -71,8 +71,8 @@ | |||
71 | #define MPT3SAS_DRIVER_NAME "mpt3sas" | 71 | #define MPT3SAS_DRIVER_NAME "mpt3sas" |
72 | #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>" | 72 | #define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>" |
73 | #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" | 73 | #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" |
74 | #define MPT3SAS_DRIVER_VERSION "04.100.00.00" | 74 | #define MPT3SAS_DRIVER_VERSION "09.100.00.00" |
75 | #define MPT3SAS_MAJOR_VERSION 4 | 75 | #define MPT3SAS_MAJOR_VERSION 9 |
76 | #define MPT3SAS_MINOR_VERSION 100 | 76 | #define MPT3SAS_MINOR_VERSION 100 |
77 | #define MPT3SAS_BUILD_VERSION 0 | 77 | #define MPT3SAS_BUILD_VERSION 0 |
78 | #define MPT3SAS_RELEASE_VERSION 00 | 78 | #define MPT3SAS_RELEASE_VERSION 00 |
@@ -152,12 +152,49 @@ | |||
152 | #define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524 | 152 | #define MPT3SAS_INTEL_RS3UC080_SSDID 0x3524 |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * Dell HBA branding | ||
156 | */ | ||
157 | #define MPT3SAS_DELL_12G_HBA_BRANDING \ | ||
158 | "Dell 12Gbps HBA" | ||
159 | |||
160 | /* | ||
161 | * Dell HBA SSDIDs | ||
162 | */ | ||
163 | #define MPT3SAS_DELL_12G_HBA_SSDID 0x1F46 | ||
164 | |||
165 | /* | ||
166 | * Cisco HBA branding | ||
167 | */ | ||
168 | #define MPT3SAS_CISCO_12G_8E_HBA_BRANDING \ | ||
169 | "Cisco 9300-8E 12G SAS HBA" | ||
170 | #define MPT3SAS_CISCO_12G_8I_HBA_BRANDING \ | ||
171 | "Cisco 9300-8i 12G SAS HBA" | ||
172 | #define MPT3SAS_CISCO_12G_AVILA_HBA_BRANDING \ | ||
173 | "Cisco 12G Modular SAS Pass through Controller" | ||
174 | #define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_BRANDING \ | ||
175 | "UCS C3X60 12G SAS Pass through Controller" | ||
176 | /* | ||
177 | * Cisco HBA SSSDIDs | ||
178 | */ | ||
179 | #define MPT3SAS_CISCO_12G_8E_HBA_SSDID 0x14C | ||
180 | #define MPT3SAS_CISCO_12G_8I_HBA_SSDID 0x154 | ||
181 | #define MPT3SAS_CISCO_12G_AVILA_HBA_SSDID 0x155 | ||
182 | #define MPT3SAS_CISCO_12G_COLUSA_MEZZANINE_HBA_SSDID 0x156 | ||
183 | |||
184 | /* | ||
155 | * status bits for ioc->diag_buffer_status | 185 | * status bits for ioc->diag_buffer_status |
156 | */ | 186 | */ |
157 | #define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) | 187 | #define MPT3_DIAG_BUFFER_IS_REGISTERED (0x01) |
158 | #define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) | 188 | #define MPT3_DIAG_BUFFER_IS_RELEASED (0x02) |
159 | #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) | 189 | #define MPT3_DIAG_BUFFER_IS_DIAG_RESET (0x04) |
160 | 190 | ||
191 | /* | ||
192 | * Combined Reply Queue constants, | ||
193 | * There are twelve Supplemental Reply Post Host Index Registers | ||
194 | * and each register is at offset 0x10 bytes from the previous one. | ||
195 | */ | ||
196 | #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12 | ||
197 | #define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) | ||
161 | 198 | ||
162 | /* OEM Identifiers */ | 199 | /* OEM Identifiers */ |
163 | #define MFG10_OEM_ID_INVALID (0x00000000) | 200 | #define MFG10_OEM_ID_INVALID (0x00000000) |
@@ -173,6 +210,8 @@ | |||
173 | #define MFG10_GF0_SSD_DATA_SCRUB_DISABLE (0x00000008) | 210 | #define MFG10_GF0_SSD_DATA_SCRUB_DISABLE (0x00000008) |
174 | #define MFG10_GF0_SINGLE_DRIVE_R0 (0x00000010) | 211 | #define MFG10_GF0_SINGLE_DRIVE_R0 (0x00000010) |
175 | 212 | ||
213 | #define VIRTUAL_IO_FAILED_RETRY (0x32010081) | ||
214 | |||
176 | /* OEM Specific Flags will come from OEM specific header files */ | 215 | /* OEM Specific Flags will come from OEM specific header files */ |
177 | struct Mpi2ManufacturingPage10_t { | 216 | struct Mpi2ManufacturingPage10_t { |
178 | MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ | 217 | MPI2_CONFIG_PAGE_HEADER Header; /* 00h */ |
@@ -294,7 +333,8 @@ struct _internal_cmd { | |||
294 | * @responding: used in _scsih_sas_device_mark_responding | 333 | * @responding: used in _scsih_sas_device_mark_responding |
295 | * @fast_path: fast path feature enable bit | 334 | * @fast_path: fast path feature enable bit |
296 | * @pfa_led_on: flag for PFA LED status | 335 | * @pfa_led_on: flag for PFA LED status |
297 | * | 336 | * @pend_sas_rphy_add: flag to check if device is in sas_rphy_add() |
337 | * addition routine. | ||
298 | */ | 338 | */ |
299 | struct _sas_device { | 339 | struct _sas_device { |
300 | struct list_head list; | 340 | struct list_head list; |
@@ -315,6 +355,9 @@ struct _sas_device { | |||
315 | u8 responding; | 355 | u8 responding; |
316 | u8 fast_path; | 356 | u8 fast_path; |
317 | u8 pfa_led_on; | 357 | u8 pfa_led_on; |
358 | u8 pend_sas_rphy_add; | ||
359 | u8 enclosure_level; | ||
360 | u8 connector_name[4]; | ||
318 | }; | 361 | }; |
319 | 362 | ||
320 | /** | 363 | /** |
@@ -728,7 +771,8 @@ typedef void (*MPT3SAS_FLUSH_RUNNING_CMDS)(struct MPT3SAS_ADAPTER *ioc); | |||
728 | * is assigned only ones | 771 | * is assigned only ones |
729 | * @reply_queue_count: number of reply queue's | 772 | * @reply_queue_count: number of reply queue's |
730 | * @reply_queue_list: link list contaning the reply queue info | 773 | * @reply_queue_list: link list contaning the reply queue info |
731 | * @reply_post_host_index: head index in the pool where FW completes IO | 774 | * @msix96_vector: 96 MSI-X vector support |
775 | * @replyPostRegisterIndex: index of next position in Reply Desc Post Queue | ||
732 | * @delayed_tr_list: target reset link list | 776 | * @delayed_tr_list: target reset link list |
733 | * @delayed_tr_volume_list: volume target reset link list | 777 | * @delayed_tr_volume_list: volume target reset link list |
734 | * @@temp_sensors_count: flag to carry the number of temperature sensors | 778 | * @@temp_sensors_count: flag to carry the number of temperature sensors |
@@ -814,7 +858,6 @@ struct MPT3SAS_ADAPTER { | |||
814 | MPT_BUILD_SG_SCMD build_sg_scmd; | 858 | MPT_BUILD_SG_SCMD build_sg_scmd; |
815 | MPT_BUILD_SG build_sg; | 859 | MPT_BUILD_SG build_sg; |
816 | MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge; | 860 | MPT_BUILD_ZERO_LEN_SGE build_zero_len_sge; |
817 | u8 mpi25; | ||
818 | u16 sge_size_ieee; | 861 | u16 sge_size_ieee; |
819 | 862 | ||
820 | /* function ptr for MPI sg elements only */ | 863 | /* function ptr for MPI sg elements only */ |
@@ -937,6 +980,10 @@ struct MPT3SAS_ADAPTER { | |||
937 | u8 reply_queue_count; | 980 | u8 reply_queue_count; |
938 | struct list_head reply_queue_list; | 981 | struct list_head reply_queue_list; |
939 | 982 | ||
983 | u8 msix96_vector; | ||
984 | /* reply post register index */ | ||
985 | resource_size_t **replyPostRegisterIndex; | ||
986 | |||
940 | struct list_head delayed_tr_list; | 987 | struct list_head delayed_tr_list; |
941 | struct list_head delayed_tr_volume_list; | 988 | struct list_head delayed_tr_volume_list; |
942 | u8 temp_sensors_count; | 989 | u8 temp_sensors_count; |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 5a97e3286719..8ccef38523fa 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
@@ -585,6 +585,22 @@ _scsih_sas_device_remove(struct MPT3SAS_ADAPTER *ioc, | |||
585 | 585 | ||
586 | if (!sas_device) | 586 | if (!sas_device) |
587 | return; | 587 | return; |
588 | pr_info(MPT3SAS_FMT | ||
589 | "removing handle(0x%04x), sas_addr(0x%016llx)\n", | ||
590 | ioc->name, sas_device->handle, | ||
591 | (unsigned long long) sas_device->sas_address); | ||
592 | |||
593 | if (sas_device->enclosure_handle != 0) | ||
594 | pr_info(MPT3SAS_FMT | ||
595 | "removing enclosure logical id(0x%016llx), slot(%d)\n", | ||
596 | ioc->name, (unsigned long long) | ||
597 | sas_device->enclosure_logical_id, sas_device->slot); | ||
598 | |||
599 | if (sas_device->connector_name[0] != '\0') | ||
600 | pr_info(MPT3SAS_FMT | ||
601 | "removing enclosure level(0x%04x), connector name( %s)\n", | ||
602 | ioc->name, sas_device->enclosure_level, | ||
603 | sas_device->connector_name); | ||
588 | 604 | ||
589 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 605 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
590 | list_del(&sas_device->list); | 606 | list_del(&sas_device->list); |
@@ -663,6 +679,18 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, | |||
663 | ioc->name, __func__, sas_device->handle, | 679 | ioc->name, __func__, sas_device->handle, |
664 | (unsigned long long)sas_device->sas_address)); | 680 | (unsigned long long)sas_device->sas_address)); |
665 | 681 | ||
682 | if (sas_device->enclosure_handle != 0) | ||
683 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
684 | "%s: enclosure logical id(0x%016llx), slot( %d)\n", | ||
685 | ioc->name, __func__, (unsigned long long) | ||
686 | sas_device->enclosure_logical_id, sas_device->slot)); | ||
687 | |||
688 | if (sas_device->connector_name[0] != '\0') | ||
689 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
690 | "%s: enclosure level(0x%04x), connector name( %s)\n", | ||
691 | ioc->name, __func__, | ||
692 | sas_device->enclosure_level, sas_device->connector_name)); | ||
693 | |||
666 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 694 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
667 | list_add_tail(&sas_device->list, &ioc->sas_device_list); | 695 | list_add_tail(&sas_device->list, &ioc->sas_device_list); |
668 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 696 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
@@ -704,6 +732,18 @@ _scsih_sas_device_init_add(struct MPT3SAS_ADAPTER *ioc, | |||
704 | __func__, sas_device->handle, | 732 | __func__, sas_device->handle, |
705 | (unsigned long long)sas_device->sas_address)); | 733 | (unsigned long long)sas_device->sas_address)); |
706 | 734 | ||
735 | if (sas_device->enclosure_handle != 0) | ||
736 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
737 | "%s: enclosure logical id(0x%016llx), slot( %d)\n", | ||
738 | ioc->name, __func__, (unsigned long long) | ||
739 | sas_device->enclosure_logical_id, sas_device->slot)); | ||
740 | |||
741 | if (sas_device->connector_name[0] != '\0') | ||
742 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
743 | "%s: enclosure level(0x%04x), connector name( %s)\n", | ||
744 | ioc->name, __func__, sas_device->enclosure_level, | ||
745 | sas_device->connector_name)); | ||
746 | |||
707 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 747 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
708 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); | 748 | list_add_tail(&sas_device->list, &ioc->sas_device_init_list); |
709 | _scsih_determine_boot_device(ioc, sas_device, 0); | 749 | _scsih_determine_boot_device(ioc, sas_device, 0); |
@@ -1772,10 +1812,16 @@ _scsih_slave_configure(struct scsi_device *sdev) | |||
1772 | "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", | 1812 | "sas_addr(0x%016llx), phy(%d), device_name(0x%016llx)\n", |
1773 | ds, handle, (unsigned long long)sas_device->sas_address, | 1813 | ds, handle, (unsigned long long)sas_device->sas_address, |
1774 | sas_device->phy, (unsigned long long)sas_device->device_name); | 1814 | sas_device->phy, (unsigned long long)sas_device->device_name); |
1775 | sdev_printk(KERN_INFO, sdev, | 1815 | if (sas_device->enclosure_handle != 0) |
1776 | "%s: enclosure_logical_id(0x%016llx), slot(%d)\n", | 1816 | sdev_printk(KERN_INFO, sdev, |
1777 | ds, (unsigned long long) | 1817 | "%s: enclosure_logical_id(0x%016llx), slot(%d)\n", |
1778 | sas_device->enclosure_logical_id, sas_device->slot); | 1818 | ds, (unsigned long long) |
1819 | sas_device->enclosure_logical_id, sas_device->slot); | ||
1820 | if (sas_device->connector_name[0] != '\0') | ||
1821 | sdev_printk(KERN_INFO, sdev, | ||
1822 | "%s: enclosure level(0x%04x), connector name( %s)\n", | ||
1823 | ds, sas_device->enclosure_level, | ||
1824 | sas_device->connector_name); | ||
1779 | 1825 | ||
1780 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 1826 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
1781 | 1827 | ||
@@ -2189,10 +2235,17 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) | |||
2189 | sas_device->handle, | 2235 | sas_device->handle, |
2190 | (unsigned long long)sas_device->sas_address, | 2236 | (unsigned long long)sas_device->sas_address, |
2191 | sas_device->phy); | 2237 | sas_device->phy); |
2192 | starget_printk(KERN_INFO, starget, | 2238 | if (sas_device->enclosure_handle != 0) |
2193 | "enclosure_logical_id(0x%016llx), slot(%d)\n", | 2239 | starget_printk(KERN_INFO, starget, |
2194 | (unsigned long long)sas_device->enclosure_logical_id, | 2240 | "enclosure_logical_id(0x%016llx), slot(%d)\n", |
2195 | sas_device->slot); | 2241 | (unsigned long long) |
2242 | sas_device->enclosure_logical_id, | ||
2243 | sas_device->slot); | ||
2244 | if (sas_device->connector_name) | ||
2245 | starget_printk(KERN_INFO, starget, | ||
2246 | "enclosure level(0x%04x),connector name(%s)\n", | ||
2247 | sas_device->enclosure_level, | ||
2248 | sas_device->connector_name); | ||
2196 | } | 2249 | } |
2197 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 2250 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
2198 | } | 2251 | } |
@@ -2552,6 +2605,75 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc) | |||
2552 | } | 2605 | } |
2553 | 2606 | ||
2554 | /** | 2607 | /** |
2608 | * _scsih_internal_device_block - block the sdev device | ||
2609 | * @sdev: per device object | ||
2610 | * @sas_device_priv_data : per device driver private data | ||
2611 | * | ||
2612 | * make sure device is blocked without error, if not | ||
2613 | * print an error | ||
2614 | */ | ||
2615 | static void | ||
2616 | _scsih_internal_device_block(struct scsi_device *sdev, | ||
2617 | struct MPT3SAS_DEVICE *sas_device_priv_data) | ||
2618 | { | ||
2619 | int r = 0; | ||
2620 | |||
2621 | sdev_printk(KERN_INFO, sdev, "device_block, handle(0x%04x)\n", | ||
2622 | sas_device_priv_data->sas_target->handle); | ||
2623 | sas_device_priv_data->block = 1; | ||
2624 | |||
2625 | r = scsi_internal_device_block(sdev); | ||
2626 | if (r == -EINVAL) | ||
2627 | sdev_printk(KERN_WARNING, sdev, | ||
2628 | "device_block failed with return(%d) for handle(0x%04x)\n", | ||
2629 | sas_device_priv_data->sas_target->handle, r); | ||
2630 | } | ||
2631 | |||
2632 | /** | ||
2633 | * _scsih_internal_device_unblock - unblock the sdev device | ||
2634 | * @sdev: per device object | ||
2635 | * @sas_device_priv_data : per device driver private data | ||
2636 | * make sure device is unblocked without error, if not retry | ||
2637 | * by blocking and then unblocking | ||
2638 | */ | ||
2639 | |||
2640 | static void | ||
2641 | _scsih_internal_device_unblock(struct scsi_device *sdev, | ||
2642 | struct MPT3SAS_DEVICE *sas_device_priv_data) | ||
2643 | { | ||
2644 | int r = 0; | ||
2645 | |||
2646 | sdev_printk(KERN_WARNING, sdev, "device_unblock and setting to running, " | ||
2647 | "handle(0x%04x)\n", sas_device_priv_data->sas_target->handle); | ||
2648 | sas_device_priv_data->block = 0; | ||
2649 | r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); | ||
2650 | if (r == -EINVAL) { | ||
2651 | /* The device has been set to SDEV_RUNNING by SD layer during | ||
2652 | * device addition but the request queue is still stopped by | ||
2653 | * our earlier block call. We need to perform a block again | ||
2654 | * to get the device to SDEV_BLOCK and then to SDEV_RUNNING */ | ||
2655 | |||
2656 | sdev_printk(KERN_WARNING, sdev, | ||
2657 | "device_unblock failed with return(%d) for handle(0x%04x) " | ||
2658 | "performing a block followed by an unblock\n", | ||
2659 | sas_device_priv_data->sas_target->handle, r); | ||
2660 | sas_device_priv_data->block = 1; | ||
2661 | r = scsi_internal_device_block(sdev); | ||
2662 | if (r) | ||
2663 | sdev_printk(KERN_WARNING, sdev, "retried device_block " | ||
2664 | "failed with return(%d) for handle(0x%04x)\n", | ||
2665 | sas_device_priv_data->sas_target->handle, r); | ||
2666 | |||
2667 | sas_device_priv_data->block = 0; | ||
2668 | r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); | ||
2669 | if (r) | ||
2670 | sdev_printk(KERN_WARNING, sdev, "retried device_unblock" | ||
2671 | " failed with return(%d) for handle(0x%04x)\n", | ||
2672 | sas_device_priv_data->sas_target->handle, r); | ||
2673 | } | ||
2674 | } | ||
2675 | |||
2676 | /** | ||
2555 | * _scsih_ublock_io_all_device - unblock every device | 2677 | * _scsih_ublock_io_all_device - unblock every device |
2556 | * @ioc: per adapter object | 2678 | * @ioc: per adapter object |
2557 | * | 2679 | * |
@@ -2570,11 +2692,10 @@ _scsih_ublock_io_all_device(struct MPT3SAS_ADAPTER *ioc) | |||
2570 | if (!sas_device_priv_data->block) | 2692 | if (!sas_device_priv_data->block) |
2571 | continue; | 2693 | continue; |
2572 | 2694 | ||
2573 | sas_device_priv_data->block = 0; | ||
2574 | dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, | 2695 | dewtprintk(ioc, sdev_printk(KERN_INFO, sdev, |
2575 | "device_running, handle(0x%04x)\n", | 2696 | "device_running, handle(0x%04x)\n", |
2576 | sas_device_priv_data->sas_target->handle)); | 2697 | sas_device_priv_data->sas_target->handle)); |
2577 | scsi_internal_device_unblock(sdev, SDEV_RUNNING); | 2698 | _scsih_internal_device_unblock(sdev, sas_device_priv_data); |
2578 | } | 2699 | } |
2579 | } | 2700 | } |
2580 | 2701 | ||
@@ -2599,10 +2720,9 @@ _scsih_ublock_io_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address) | |||
2599 | if (sas_device_priv_data->sas_target->sas_address | 2720 | if (sas_device_priv_data->sas_target->sas_address |
2600 | != sas_address) | 2721 | != sas_address) |
2601 | continue; | 2722 | continue; |
2602 | if (sas_device_priv_data->block) { | 2723 | if (sas_device_priv_data->block) |
2603 | sas_device_priv_data->block = 0; | 2724 | _scsih_internal_device_unblock(sdev, |
2604 | scsi_internal_device_unblock(sdev, SDEV_RUNNING); | 2725 | sas_device_priv_data); |
2605 | } | ||
2606 | } | 2726 | } |
2607 | } | 2727 | } |
2608 | 2728 | ||
@@ -2625,10 +2745,7 @@ _scsih_block_io_all_device(struct MPT3SAS_ADAPTER *ioc) | |||
2625 | continue; | 2745 | continue; |
2626 | if (sas_device_priv_data->block) | 2746 | if (sas_device_priv_data->block) |
2627 | continue; | 2747 | continue; |
2628 | sas_device_priv_data->block = 1; | 2748 | _scsih_internal_device_block(sdev, sas_device_priv_data); |
2629 | scsi_internal_device_block(sdev); | ||
2630 | sdev_printk(KERN_INFO, sdev, "device_blocked, handle(0x%04x)\n", | ||
2631 | sas_device_priv_data->sas_target->handle); | ||
2632 | } | 2749 | } |
2633 | } | 2750 | } |
2634 | 2751 | ||
@@ -2644,6 +2761,11 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2644 | { | 2761 | { |
2645 | struct MPT3SAS_DEVICE *sas_device_priv_data; | 2762 | struct MPT3SAS_DEVICE *sas_device_priv_data; |
2646 | struct scsi_device *sdev; | 2763 | struct scsi_device *sdev; |
2764 | struct _sas_device *sas_device; | ||
2765 | |||
2766 | sas_device = _scsih_sas_device_find_by_handle(ioc, handle); | ||
2767 | if (!sas_device) | ||
2768 | return; | ||
2647 | 2769 | ||
2648 | shost_for_each_device(sdev, ioc->shost) { | 2770 | shost_for_each_device(sdev, ioc->shost) { |
2649 | sas_device_priv_data = sdev->hostdata; | 2771 | sas_device_priv_data = sdev->hostdata; |
@@ -2653,10 +2775,9 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2653 | continue; | 2775 | continue; |
2654 | if (sas_device_priv_data->block) | 2776 | if (sas_device_priv_data->block) |
2655 | continue; | 2777 | continue; |
2656 | sas_device_priv_data->block = 1; | 2778 | if (sas_device->pend_sas_rphy_add) |
2657 | scsi_internal_device_block(sdev); | 2779 | continue; |
2658 | sdev_printk(KERN_INFO, sdev, | 2780 | _scsih_internal_device_block(sdev, sas_device_priv_data); |
2659 | "device_blocked, handle(0x%04x)\n", handle); | ||
2660 | } | 2781 | } |
2661 | } | 2782 | } |
2662 | 2783 | ||
@@ -2806,6 +2927,18 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
2806 | "setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n", | 2927 | "setting delete flag: handle(0x%04x), sas_addr(0x%016llx)\n", |
2807 | ioc->name, handle, | 2928 | ioc->name, handle, |
2808 | (unsigned long long)sas_address)); | 2929 | (unsigned long long)sas_address)); |
2930 | if (sas_device->enclosure_handle != 0) | ||
2931 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
2932 | "setting delete flag:enclosure logical id(0x%016llx)," | ||
2933 | " slot(%d)\n", ioc->name, (unsigned long long) | ||
2934 | sas_device->enclosure_logical_id, | ||
2935 | sas_device->slot)); | ||
2936 | if (sas_device->connector_name) | ||
2937 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
2938 | "setting delete flag: enclosure level(0x%04x)," | ||
2939 | " connector name( %s)\n", ioc->name, | ||
2940 | sas_device->enclosure_level, | ||
2941 | sas_device->connector_name)); | ||
2809 | _scsih_ublock_io_device(ioc, sas_address); | 2942 | _scsih_ublock_io_device(ioc, sas_address); |
2810 | sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; | 2943 | sas_target_priv_data->handle = MPT3SAS_INVALID_DEVICE_HANDLE; |
2811 | } | 2944 | } |
@@ -3821,10 +3954,19 @@ _scsih_scsi_ioc_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, | |||
3821 | "\tsas_address(0x%016llx), phy(%d)\n", | 3954 | "\tsas_address(0x%016llx), phy(%d)\n", |
3822 | ioc->name, (unsigned long long) | 3955 | ioc->name, (unsigned long long) |
3823 | sas_device->sas_address, sas_device->phy); | 3956 | sas_device->sas_address, sas_device->phy); |
3824 | pr_warn(MPT3SAS_FMT | 3957 | if (sas_device->enclosure_handle != 0) |
3825 | "\tenclosure_logical_id(0x%016llx), slot(%d)\n", | 3958 | pr_warn(MPT3SAS_FMT |
3826 | ioc->name, (unsigned long long) | 3959 | "\tenclosure_logical_id(0x%016llx)," |
3827 | sas_device->enclosure_logical_id, sas_device->slot); | 3960 | "slot(%d)\n", ioc->name, |
3961 | (unsigned long long) | ||
3962 | sas_device->enclosure_logical_id, | ||
3963 | sas_device->slot); | ||
3964 | if (sas_device->connector_name[0]) | ||
3965 | pr_warn(MPT3SAS_FMT | ||
3966 | "\tenclosure level(0x%04x)," | ||
3967 | " connector name( %s)\n", ioc->name, | ||
3968 | sas_device->enclosure_level, | ||
3969 | sas_device->connector_name); | ||
3828 | } | 3970 | } |
3829 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 3971 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
3830 | } | 3972 | } |
@@ -3999,7 +4141,16 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
3999 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4141 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4000 | return; | 4142 | return; |
4001 | } | 4143 | } |
4002 | starget_printk(KERN_WARNING, starget, "predicted fault\n"); | 4144 | if (sas_device->enclosure_handle != 0) |
4145 | starget_printk(KERN_INFO, starget, "predicted fault, " | ||
4146 | "enclosure logical id(0x%016llx), slot(%d)\n", | ||
4147 | (unsigned long long)sas_device->enclosure_logical_id, | ||
4148 | sas_device->slot); | ||
4149 | if (sas_device->connector_name[0] != '\0') | ||
4150 | starget_printk(KERN_WARNING, starget, "predicted fault, " | ||
4151 | "enclosure level(0x%04x), connector name( %s)\n", | ||
4152 | sas_device->enclosure_level, | ||
4153 | sas_device->connector_name); | ||
4003 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); | 4154 | spin_unlock_irqrestore(&ioc->sas_device_lock, flags); |
4004 | 4155 | ||
4005 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) | 4156 | if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) |
@@ -4119,8 +4270,15 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4119 | _scsih_smart_predicted_fault(ioc, | 4270 | _scsih_smart_predicted_fault(ioc, |
4120 | le16_to_cpu(mpi_reply->DevHandle)); | 4271 | le16_to_cpu(mpi_reply->DevHandle)); |
4121 | mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); | 4272 | mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); |
4122 | } | ||
4123 | 4273 | ||
4274 | #ifdef CONFIG_SCSI_MPT3SAS_LOGGING | ||
4275 | if (!(ioc->logging_level & MPT_DEBUG_REPLY) && | ||
4276 | ((scmd->sense_buffer[2] == UNIT_ATTENTION) || | ||
4277 | (scmd->sense_buffer[2] == MEDIUM_ERROR) || | ||
4278 | (scmd->sense_buffer[2] == HARDWARE_ERROR))) | ||
4279 | _scsih_scsi_ioc_info(ioc, scmd, mpi_reply, smid); | ||
4280 | #endif | ||
4281 | } | ||
4124 | switch (ioc_status) { | 4282 | switch (ioc_status) { |
4125 | case MPI2_IOCSTATUS_BUSY: | 4283 | case MPI2_IOCSTATUS_BUSY: |
4126 | case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: | 4284 | case MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES: |
@@ -4146,6 +4304,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) | |||
4146 | scmd->device->expecting_cc_ua = 1; | 4304 | scmd->device->expecting_cc_ua = 1; |
4147 | } | 4305 | } |
4148 | break; | 4306 | break; |
4307 | } else if (log_info == VIRTUAL_IO_FAILED_RETRY) { | ||
4308 | scmd->result = DID_RESET << 16; | ||
4309 | break; | ||
4149 | } | 4310 | } |
4150 | scmd->result = DID_SOFT_ERROR << 16; | 4311 | scmd->result = DID_SOFT_ERROR << 16; |
4151 | break; | 4312 | break; |
@@ -4788,6 +4949,16 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc, | |||
4788 | sas_device->handle, handle); | 4949 | sas_device->handle, handle); |
4789 | sas_target_priv_data->handle = handle; | 4950 | sas_target_priv_data->handle = handle; |
4790 | sas_device->handle = handle; | 4951 | sas_device->handle = handle; |
4952 | if (sas_device_pg0.Flags & | ||
4953 | MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { | ||
4954 | sas_device->enclosure_level = | ||
4955 | le16_to_cpu(sas_device_pg0.EnclosureLevel); | ||
4956 | memcpy(&sas_device->connector_name[0], | ||
4957 | &sas_device_pg0.ConnectorName[0], 4); | ||
4958 | } else { | ||
4959 | sas_device->enclosure_level = 0; | ||
4960 | sas_device->connector_name[0] = '\0'; | ||
4961 | } | ||
4791 | } | 4962 | } |
4792 | 4963 | ||
4793 | /* check if device is present */ | 4964 | /* check if device is present */ |
@@ -4894,14 +5065,24 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, | |||
4894 | ioc->name, __FILE__, __LINE__, __func__); | 5065 | ioc->name, __FILE__, __LINE__, __func__); |
4895 | sas_device->enclosure_handle = | 5066 | sas_device->enclosure_handle = |
4896 | le16_to_cpu(sas_device_pg0.EnclosureHandle); | 5067 | le16_to_cpu(sas_device_pg0.EnclosureHandle); |
4897 | sas_device->slot = | 5068 | if (sas_device->enclosure_handle != 0) |
4898 | le16_to_cpu(sas_device_pg0.Slot); | 5069 | sas_device->slot = |
5070 | le16_to_cpu(sas_device_pg0.Slot); | ||
4899 | sas_device->device_info = device_info; | 5071 | sas_device->device_info = device_info; |
4900 | sas_device->sas_address = sas_address; | 5072 | sas_device->sas_address = sas_address; |
4901 | sas_device->phy = sas_device_pg0.PhyNum; | 5073 | sas_device->phy = sas_device_pg0.PhyNum; |
4902 | sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & | 5074 | sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & |
4903 | MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; | 5075 | MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; |
4904 | 5076 | ||
5077 | if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { | ||
5078 | sas_device->enclosure_level = | ||
5079 | le16_to_cpu(sas_device_pg0.EnclosureLevel); | ||
5080 | memcpy(&sas_device->connector_name[0], | ||
5081 | &sas_device_pg0.ConnectorName[0], 4); | ||
5082 | } else { | ||
5083 | sas_device->enclosure_level = 0; | ||
5084 | sas_device->connector_name[0] = '\0'; | ||
5085 | } | ||
4905 | /* get enclosure_logical_id */ | 5086 | /* get enclosure_logical_id */ |
4906 | if (sas_device->enclosure_handle && !(mpt3sas_config_get_enclosure_pg0( | 5087 | if (sas_device->enclosure_handle && !(mpt3sas_config_get_enclosure_pg0( |
4907 | ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, | 5088 | ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE, |
@@ -4943,6 +5124,18 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, | |||
4943 | ioc->name, __func__, | 5124 | ioc->name, __func__, |
4944 | sas_device->handle, (unsigned long long) | 5125 | sas_device->handle, (unsigned long long) |
4945 | sas_device->sas_address)); | 5126 | sas_device->sas_address)); |
5127 | if (sas_device->enclosure_handle != 0) | ||
5128 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
5129 | "%s: enter: enclosure logical id(0x%016llx), slot(%d)\n", | ||
5130 | ioc->name, __func__, | ||
5131 | (unsigned long long)sas_device->enclosure_logical_id, | ||
5132 | sas_device->slot)); | ||
5133 | if (sas_device->connector_name[0] != '\0') | ||
5134 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
5135 | "%s: enter: enclosure level(0x%04x), connector name( %s)\n", | ||
5136 | ioc->name, __func__, | ||
5137 | sas_device->enclosure_level, | ||
5138 | sas_device->connector_name)); | ||
4946 | 5139 | ||
4947 | if (sas_device->starget && sas_device->starget->hostdata) { | 5140 | if (sas_device->starget && sas_device->starget->hostdata) { |
4948 | sas_target_priv_data = sas_device->starget->hostdata; | 5141 | sas_target_priv_data = sas_device->starget->hostdata; |
@@ -4959,12 +5152,34 @@ _scsih_remove_device(struct MPT3SAS_ADAPTER *ioc, | |||
4959 | "removing handle(0x%04x), sas_addr(0x%016llx)\n", | 5152 | "removing handle(0x%04x), sas_addr(0x%016llx)\n", |
4960 | ioc->name, sas_device->handle, | 5153 | ioc->name, sas_device->handle, |
4961 | (unsigned long long) sas_device->sas_address); | 5154 | (unsigned long long) sas_device->sas_address); |
5155 | if (sas_device->enclosure_handle != 0) | ||
5156 | pr_info(MPT3SAS_FMT | ||
5157 | "removing : enclosure logical id(0x%016llx), slot(%d)\n", | ||
5158 | ioc->name, | ||
5159 | (unsigned long long)sas_device->enclosure_logical_id, | ||
5160 | sas_device->slot); | ||
5161 | if (sas_device->connector_name[0] != '\0') | ||
5162 | pr_info(MPT3SAS_FMT | ||
5163 | "removing enclosure level(0x%04x), connector name( %s)\n", | ||
5164 | ioc->name, sas_device->enclosure_level, | ||
5165 | sas_device->connector_name); | ||
4962 | 5166 | ||
4963 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | 5167 | dewtprintk(ioc, pr_info(MPT3SAS_FMT |
4964 | "%s: exit: handle(0x%04x), sas_addr(0x%016llx)\n", | 5168 | "%s: exit: handle(0x%04x), sas_addr(0x%016llx)\n", |
4965 | ioc->name, __func__, | 5169 | ioc->name, __func__, |
4966 | sas_device->handle, (unsigned long long) | 5170 | sas_device->handle, (unsigned long long) |
4967 | sas_device->sas_address)); | 5171 | sas_device->sas_address)); |
5172 | if (sas_device->enclosure_handle != 0) | ||
5173 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
5174 | "%s: exit: enclosure logical id(0x%016llx), slot(%d)\n", | ||
5175 | ioc->name, __func__, | ||
5176 | (unsigned long long)sas_device->enclosure_logical_id, | ||
5177 | sas_device->slot)); | ||
5178 | if (sas_device->connector_name[0] != '\0') | ||
5179 | dewtprintk(ioc, pr_info(MPT3SAS_FMT | ||
5180 | "%s: exit: enclosure level(0x%04x), connector name(%s)\n", | ||
5181 | ioc->name, __func__, sas_device->enclosure_level, | ||
5182 | sas_device->connector_name)); | ||
4968 | 5183 | ||
4969 | kfree(sas_device); | 5184 | kfree(sas_device); |
4970 | } | 5185 | } |
@@ -6357,9 +6572,7 @@ _scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc) | |||
6357 | /** | 6572 | /** |
6358 | * _scsih_mark_responding_sas_device - mark a sas_devices as responding | 6573 | * _scsih_mark_responding_sas_device - mark a sas_devices as responding |
6359 | * @ioc: per adapter object | 6574 | * @ioc: per adapter object |
6360 | * @sas_address: sas address | 6575 | * @sas_device_pg0: SAS Device page 0 |
6361 | * @slot: enclosure slot id | ||
6362 | * @handle: device handle | ||
6363 | * | 6576 | * |
6364 | * After host reset, find out whether devices are still responding. | 6577 | * After host reset, find out whether devices are still responding. |
6365 | * Used in _scsih_remove_unresponsive_sas_devices. | 6578 | * Used in _scsih_remove_unresponsive_sas_devices. |
@@ -6367,8 +6580,8 @@ _scsih_prep_device_scan(struct MPT3SAS_ADAPTER *ioc) | |||
6367 | * Return nothing. | 6580 | * Return nothing. |
6368 | */ | 6581 | */ |
6369 | static void | 6582 | static void |
6370 | _scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, | 6583 | _scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, |
6371 | u16 slot, u16 handle) | 6584 | Mpi2SasDevicePage0_t *sas_device_pg0) |
6372 | { | 6585 | { |
6373 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; | 6586 | struct MPT3SAS_TARGET *sas_target_priv_data = NULL; |
6374 | struct scsi_target *starget; | 6587 | struct scsi_target *starget; |
@@ -6377,8 +6590,8 @@ _scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, | |||
6377 | 6590 | ||
6378 | spin_lock_irqsave(&ioc->sas_device_lock, flags); | 6591 | spin_lock_irqsave(&ioc->sas_device_lock, flags); |
6379 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { | 6592 | list_for_each_entry(sas_device, &ioc->sas_device_list, list) { |
6380 | if (sas_device->sas_address == sas_address && | 6593 | if ((sas_device->sas_address == sas_device_pg0->SASAddress) && |
6381 | sas_device->slot == slot) { | 6594 | (sas_device->slot == sas_device_pg0->Slot)) { |
6382 | sas_device->responding = 1; | 6595 | sas_device->responding = 1; |
6383 | starget = sas_device->starget; | 6596 | starget = sas_device->starget; |
6384 | if (starget && starget->hostdata) { | 6597 | if (starget && starget->hostdata) { |
@@ -6387,22 +6600,40 @@ _scsih_mark_responding_sas_device(struct MPT3SAS_ADAPTER *ioc, u64 sas_address, | |||
6387 | sas_target_priv_data->deleted = 0; | 6600 | sas_target_priv_data->deleted = 0; |
6388 | } else | 6601 | } else |
6389 | sas_target_priv_data = NULL; | 6602 | sas_target_priv_data = NULL; |
6390 | if (starget) | 6603 | if (starget) { |
6391 | starget_printk(KERN_INFO, starget, | 6604 | starget_printk(KERN_INFO, starget, |
6392 | "handle(0x%04x), sas_addr(0x%016llx), " | 6605 | "handle(0x%04x), sas_addr(0x%016llx)\n", |
6393 | "enclosure logical id(0x%016llx), " | 6606 | sas_device_pg0->DevHandle, |
6394 | "slot(%d)\n", handle, | ||
6395 | (unsigned long long)sas_device->sas_address, | ||
6396 | (unsigned long long) | 6607 | (unsigned long long) |
6397 | sas_device->enclosure_logical_id, | 6608 | sas_device->sas_address); |
6398 | sas_device->slot); | 6609 | |
6399 | if (sas_device->handle == handle) | 6610 | if (sas_device->enclosure_handle != 0) |
6611 | starget_printk(KERN_INFO, starget, | ||
6612 | "enclosure logical id(0x%016llx)," | ||
6613 | " slot(%d)\n", | ||
6614 | (unsigned long long) | ||
6615 | sas_device->enclosure_logical_id, | ||
6616 | sas_device->slot); | ||
6617 | } | ||
6618 | if (sas_device_pg0->Flags & | ||
6619 | MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { | ||
6620 | sas_device->enclosure_level = | ||
6621 | le16_to_cpu(sas_device_pg0->EnclosureLevel); | ||
6622 | memcpy(&sas_device->connector_name[0], | ||
6623 | &sas_device_pg0->ConnectorName[0], 4); | ||
6624 | } else { | ||
6625 | sas_device->enclosure_level = 0; | ||
6626 | sas_device->connector_name[0] = '\0'; | ||
6627 | } | ||
6628 | |||
6629 | if (sas_device->handle == sas_device_pg0->DevHandle) | ||
6400 | goto out; | 6630 | goto out; |
6401 | pr_info("\thandle changed from(0x%04x)!!!\n", | 6631 | pr_info("\thandle changed from(0x%04x)!!!\n", |
6402 | sas_device->handle); | 6632 | sas_device->handle); |
6403 | sas_device->handle = handle; | 6633 | sas_device->handle = sas_device_pg0->DevHandle; |
6404 | if (sas_target_priv_data) | 6634 | if (sas_target_priv_data) |
6405 | sas_target_priv_data->handle = handle; | 6635 | sas_target_priv_data->handle = |
6636 | sas_device_pg0->DevHandle; | ||
6406 | goto out; | 6637 | goto out; |
6407 | } | 6638 | } |
6408 | } | 6639 | } |
@@ -6441,13 +6672,15 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc) | |||
6441 | MPI2_IOCSTATUS_MASK; | 6672 | MPI2_IOCSTATUS_MASK; |
6442 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) | 6673 | if (ioc_status != MPI2_IOCSTATUS_SUCCESS) |
6443 | break; | 6674 | break; |
6444 | handle = le16_to_cpu(sas_device_pg0.DevHandle); | 6675 | handle = sas_device_pg0.DevHandle = |
6676 | le16_to_cpu(sas_device_pg0.DevHandle); | ||
6445 | device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); | 6677 | device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); |
6446 | if (!(_scsih_is_end_device(device_info))) | 6678 | if (!(_scsih_is_end_device(device_info))) |
6447 | continue; | 6679 | continue; |
6448 | _scsih_mark_responding_sas_device(ioc, | 6680 | sas_device_pg0.SASAddress = |
6449 | le64_to_cpu(sas_device_pg0.SASAddress), | 6681 | le64_to_cpu(sas_device_pg0.SASAddress); |
6450 | le16_to_cpu(sas_device_pg0.Slot), handle); | 6682 | sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot); |
6683 | _scsih_mark_responding_sas_device(ioc, &sas_device_pg0); | ||
6451 | } | 6684 | } |
6452 | 6685 | ||
6453 | out: | 6686 | out: |
@@ -7854,8 +8087,8 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
7854 | /* event thread */ | 8087 | /* event thread */ |
7855 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), | 8088 | snprintf(ioc->firmware_event_name, sizeof(ioc->firmware_event_name), |
7856 | "fw_event%d", ioc->id); | 8089 | "fw_event%d", ioc->id); |
7857 | ioc->firmware_event_thread = create_singlethread_workqueue( | 8090 | ioc->firmware_event_thread = alloc_ordered_workqueue( |
7858 | ioc->firmware_event_name); | 8091 | ioc->firmware_event_name, WQ_MEM_RECLAIM); |
7859 | if (!ioc->firmware_event_thread) { | 8092 | if (!ioc->firmware_event_thread) { |
7860 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 8093 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
7861 | ioc->name, __FILE__, __LINE__, __func__); | 8094 | ioc->name, __FILE__, __LINE__, __func__); |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index efb98afc46e0..70fd019e7ee5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c | |||
@@ -649,6 +649,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
649 | unsigned long flags; | 649 | unsigned long flags; |
650 | struct _sas_node *sas_node; | 650 | struct _sas_node *sas_node; |
651 | struct sas_rphy *rphy; | 651 | struct sas_rphy *rphy; |
652 | struct _sas_device *sas_device = NULL; | ||
652 | int i; | 653 | int i; |
653 | struct sas_port *port; | 654 | struct sas_port *port; |
654 | 655 | ||
@@ -731,10 +732,27 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
731 | mpt3sas_port->remote_identify.device_type); | 732 | mpt3sas_port->remote_identify.device_type); |
732 | 733 | ||
733 | rphy->identify = mpt3sas_port->remote_identify; | 734 | rphy->identify = mpt3sas_port->remote_identify; |
735 | |||
736 | if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) { | ||
737 | sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, | ||
738 | mpt3sas_port->remote_identify.sas_address); | ||
739 | if (!sas_device) { | ||
740 | dfailprintk(ioc, printk(MPT3SAS_FMT | ||
741 | "failure at %s:%d/%s()!\n", | ||
742 | ioc->name, __FILE__, __LINE__, __func__)); | ||
743 | goto out_fail; | ||
744 | } | ||
745 | sas_device->pend_sas_rphy_add = 1; | ||
746 | } | ||
747 | |||
734 | if ((sas_rphy_add(rphy))) { | 748 | if ((sas_rphy_add(rphy))) { |
735 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", | 749 | pr_err(MPT3SAS_FMT "failure at %s:%d/%s()!\n", |
736 | ioc->name, __FILE__, __LINE__, __func__); | 750 | ioc->name, __FILE__, __LINE__, __func__); |
737 | } | 751 | } |
752 | |||
753 | if (mpt3sas_port->remote_identify.device_type == SAS_END_DEVICE) | ||
754 | sas_device->pend_sas_rphy_add = 0; | ||
755 | |||
738 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) | 756 | if ((ioc->logging_level & MPT_DEBUG_TRANSPORT)) |
739 | dev_printk(KERN_INFO, &rphy->dev, | 757 | dev_printk(KERN_INFO, &rphy->dev, |
740 | "add: handle(0x%04x), sas_addr(0x%016llx)\n", | 758 | "add: handle(0x%04x), sas_addr(0x%016llx)\n", |
@@ -1946,7 +1964,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1946 | } else { | 1964 | } else { |
1947 | dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), | 1965 | dma_addr_out = pci_map_single(ioc->pdev, bio_data(req->bio), |
1948 | blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); | 1966 | blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); |
1949 | if (!dma_addr_out) { | 1967 | if (pci_dma_mapping_error(ioc->pdev, dma_addr_out)) { |
1950 | pr_info(MPT3SAS_FMT "%s(): DMA Addr out = NULL\n", | 1968 | pr_info(MPT3SAS_FMT "%s(): DMA Addr out = NULL\n", |
1951 | ioc->name, __func__); | 1969 | ioc->name, __func__); |
1952 | rc = -ENOMEM; | 1970 | rc = -ENOMEM; |
@@ -1968,7 +1986,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1968 | } else { | 1986 | } else { |
1969 | dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), | 1987 | dma_addr_in = pci_map_single(ioc->pdev, bio_data(rsp->bio), |
1970 | blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); | 1988 | blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); |
1971 | if (!dma_addr_in) { | 1989 | if (pci_dma_mapping_error(ioc->pdev, dma_addr_in)) { |
1972 | pr_info(MPT3SAS_FMT "%s(): DMA Addr in = NULL\n", | 1990 | pr_info(MPT3SAS_FMT "%s(): DMA Addr in = NULL\n", |
1973 | ioc->name, __func__); | 1991 | ioc->name, __func__); |
1974 | rc = -ENOMEM; | 1992 | rc = -ENOMEM; |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 39306b1e704c..04e67a190652 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -2642,6 +2642,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2642 | ts->resp = SAS_TASK_COMPLETE; | 2642 | ts->resp = SAS_TASK_COMPLETE; |
2643 | ts->stat = SAS_OPEN_REJECT; | 2643 | ts->stat = SAS_OPEN_REJECT; |
2644 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; | 2644 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; |
2645 | break; | ||
2645 | default: | 2646 | default: |
2646 | PM8001_IO_DBG(pm8001_ha, | 2647 | PM8001_IO_DBG(pm8001_ha, |
2647 | pm8001_printk("Unknown status 0x%x\n", status)); | 2648 | pm8001_printk("Unknown status 0x%x\n", status)); |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 0e1628f2018e..9a389f1508de 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c | |||
@@ -2337,6 +2337,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) | |||
2337 | ts->resp = SAS_TASK_COMPLETE; | 2337 | ts->resp = SAS_TASK_COMPLETE; |
2338 | ts->stat = SAS_OPEN_REJECT; | 2338 | ts->stat = SAS_OPEN_REJECT; |
2339 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; | 2339 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; |
2340 | break; | ||
2340 | default: | 2341 | default: |
2341 | PM8001_IO_DBG(pm8001_ha, | 2342 | PM8001_IO_DBG(pm8001_ha, |
2342 | pm8001_printk("Unknown status 0x%x\n", status)); | 2343 | pm8001_printk("Unknown status 0x%x\n", status)); |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 30268bb2ddb6..dfcc45bb03b1 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -25,6 +25,9 @@ | |||
25 | * module options to "modprobe scsi_debug num_tgts=2" [20021221] | 25 | * module options to "modprobe scsi_debug num_tgts=2" [20021221] |
26 | */ | 26 | */ |
27 | 27 | ||
28 | |||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ | ||
30 | |||
28 | #include <linux/module.h> | 31 | #include <linux/module.h> |
29 | 32 | ||
30 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
@@ -201,7 +204,6 @@ static const char *scsi_debug_version_date = "20141022"; | |||
201 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) | 204 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) |
202 | * or "peripheral device" addressing (value 0) */ | 205 | * or "peripheral device" addressing (value 0) */ |
203 | #define SAM2_LUN_ADDRESS_METHOD 0 | 206 | #define SAM2_LUN_ADDRESS_METHOD 0 |
204 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | ||
205 | 207 | ||
206 | /* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued | 208 | /* SCSI_DEBUG_CANQUEUE is the maximum number of commands that can be queued |
207 | * (for response) at one time. Can be reduced by max_queue option. Command | 209 | * (for response) at one time. Can be reduced by max_queue option. Command |
@@ -698,7 +700,7 @@ static void sdebug_max_tgts_luns(void) | |||
698 | else | 700 | else |
699 | hpnt->max_id = scsi_debug_num_tgts; | 701 | hpnt->max_id = scsi_debug_num_tgts; |
700 | /* scsi_debug_max_luns; */ | 702 | /* scsi_debug_max_luns; */ |
701 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; | 703 | hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1; |
702 | } | 704 | } |
703 | spin_unlock(&sdebug_host_list_lock); | 705 | spin_unlock(&sdebug_host_list_lock); |
704 | } | 706 | } |
@@ -1288,7 +1290,7 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
1288 | arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC); | 1290 | arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC); |
1289 | if (! arr) | 1291 | if (! arr) |
1290 | return DID_REQUEUE << 16; | 1292 | return DID_REQUEUE << 16; |
1291 | have_wlun = (scp->device->lun == SAM2_WLUN_REPORT_LUNS); | 1293 | have_wlun = (scp->device->lun == SCSI_W_LUN_REPORT_LUNS); |
1292 | if (have_wlun) | 1294 | if (have_wlun) |
1293 | pq_pdt = 0x1e; /* present, wlun */ | 1295 | pq_pdt = 0x1e; /* present, wlun */ |
1294 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | 1296 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) |
@@ -1427,12 +1429,11 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
1427 | unsigned char * sbuff; | 1429 | unsigned char * sbuff; |
1428 | unsigned char *cmd = scp->cmnd; | 1430 | unsigned char *cmd = scp->cmnd; |
1429 | unsigned char arr[SCSI_SENSE_BUFFERSIZE]; | 1431 | unsigned char arr[SCSI_SENSE_BUFFERSIZE]; |
1430 | bool dsense, want_dsense; | 1432 | bool dsense; |
1431 | int len = 18; | 1433 | int len = 18; |
1432 | 1434 | ||
1433 | memset(arr, 0, sizeof(arr)); | 1435 | memset(arr, 0, sizeof(arr)); |
1434 | dsense = !!(cmd[1] & 1); | 1436 | dsense = !!(cmd[1] & 1); |
1435 | want_dsense = dsense || scsi_debug_dsense; | ||
1436 | sbuff = scp->sense_buffer; | 1437 | sbuff = scp->sense_buffer; |
1437 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { | 1438 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
1438 | if (dsense) { | 1439 | if (dsense) { |
@@ -2446,8 +2447,7 @@ static int dif_verify(struct sd_dif_tuple *sdt, const void *data, | |||
2446 | __be16 csum = dif_compute_csum(data, scsi_debug_sector_size); | 2447 | __be16 csum = dif_compute_csum(data, scsi_debug_sector_size); |
2447 | 2448 | ||
2448 | if (sdt->guard_tag != csum) { | 2449 | if (sdt->guard_tag != csum) { |
2449 | pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n", | 2450 | pr_err("GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n", |
2450 | __func__, | ||
2451 | (unsigned long)sector, | 2451 | (unsigned long)sector, |
2452 | be16_to_cpu(sdt->guard_tag), | 2452 | be16_to_cpu(sdt->guard_tag), |
2453 | be16_to_cpu(csum)); | 2453 | be16_to_cpu(csum)); |
@@ -2455,14 +2455,14 @@ static int dif_verify(struct sd_dif_tuple *sdt, const void *data, | |||
2455 | } | 2455 | } |
2456 | if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && | 2456 | if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && |
2457 | be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { | 2457 | be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { |
2458 | pr_err("%s: REF check failed on sector %lu\n", | 2458 | pr_err("REF check failed on sector %lu\n", |
2459 | __func__, (unsigned long)sector); | 2459 | (unsigned long)sector); |
2460 | return 0x03; | 2460 | return 0x03; |
2461 | } | 2461 | } |
2462 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && | 2462 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && |
2463 | be32_to_cpu(sdt->ref_tag) != ei_lba) { | 2463 | be32_to_cpu(sdt->ref_tag) != ei_lba) { |
2464 | pr_err("%s: REF check failed on sector %lu\n", | 2464 | pr_err("REF check failed on sector %lu\n", |
2465 | __func__, (unsigned long)sector); | 2465 | (unsigned long)sector); |
2466 | return 0x03; | 2466 | return 0x03; |
2467 | } | 2467 | } |
2468 | return 0; | 2468 | return 0; |
@@ -2680,7 +2680,7 @@ resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
2680 | return 0; | 2680 | return 0; |
2681 | } | 2681 | } |
2682 | 2682 | ||
2683 | void dump_sector(unsigned char *buf, int len) | 2683 | static void dump_sector(unsigned char *buf, int len) |
2684 | { | 2684 | { |
2685 | int i, j, n; | 2685 | int i, j, n; |
2686 | 2686 | ||
@@ -3365,8 +3365,8 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
3365 | one_lun[i].scsi_lun[1] = lun & 0xff; | 3365 | one_lun[i].scsi_lun[1] = lun & 0xff; |
3366 | } | 3366 | } |
3367 | if (want_wlun) { | 3367 | if (want_wlun) { |
3368 | one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff; | 3368 | one_lun[i].scsi_lun[0] = (SCSI_W_LUN_REPORT_LUNS >> 8) & 0xff; |
3369 | one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff; | 3369 | one_lun[i].scsi_lun[1] = SCSI_W_LUN_REPORT_LUNS & 0xff; |
3370 | i++; | 3370 | i++; |
3371 | } | 3371 | } |
3372 | alloc_len = (unsigned char *)(one_lun + i) - arr; | 3372 | alloc_len = (unsigned char *)(one_lun + i) - arr; |
@@ -3449,7 +3449,7 @@ static void sdebug_q_cmd_complete(unsigned long indx) | |||
3449 | atomic_inc(&sdebug_completions); | 3449 | atomic_inc(&sdebug_completions); |
3450 | qa_indx = indx; | 3450 | qa_indx = indx; |
3451 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { | 3451 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { |
3452 | pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx); | 3452 | pr_err("wild qa_indx=%d\n", qa_indx); |
3453 | return; | 3453 | return; |
3454 | } | 3454 | } |
3455 | spin_lock_irqsave(&queued_arr_lock, iflags); | 3455 | spin_lock_irqsave(&queued_arr_lock, iflags); |
@@ -3457,21 +3457,21 @@ static void sdebug_q_cmd_complete(unsigned long indx) | |||
3457 | scp = sqcp->a_cmnd; | 3457 | scp = sqcp->a_cmnd; |
3458 | if (NULL == scp) { | 3458 | if (NULL == scp) { |
3459 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3459 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3460 | pr_err("%s: scp is NULL\n", __func__); | 3460 | pr_err("scp is NULL\n"); |
3461 | return; | 3461 | return; |
3462 | } | 3462 | } |
3463 | devip = (struct sdebug_dev_info *)scp->device->hostdata; | 3463 | devip = (struct sdebug_dev_info *)scp->device->hostdata; |
3464 | if (devip) | 3464 | if (devip) |
3465 | atomic_dec(&devip->num_in_q); | 3465 | atomic_dec(&devip->num_in_q); |
3466 | else | 3466 | else |
3467 | pr_err("%s: devip=NULL\n", __func__); | 3467 | pr_err("devip=NULL\n"); |
3468 | if (atomic_read(&retired_max_queue) > 0) | 3468 | if (atomic_read(&retired_max_queue) > 0) |
3469 | retiring = 1; | 3469 | retiring = 1; |
3470 | 3470 | ||
3471 | sqcp->a_cmnd = NULL; | 3471 | sqcp->a_cmnd = NULL; |
3472 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { | 3472 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { |
3473 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3473 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3474 | pr_err("%s: Unexpected completion\n", __func__); | 3474 | pr_err("Unexpected completion\n"); |
3475 | return; | 3475 | return; |
3476 | } | 3476 | } |
3477 | 3477 | ||
@@ -3481,7 +3481,7 @@ static void sdebug_q_cmd_complete(unsigned long indx) | |||
3481 | retval = atomic_read(&retired_max_queue); | 3481 | retval = atomic_read(&retired_max_queue); |
3482 | if (qa_indx >= retval) { | 3482 | if (qa_indx >= retval) { |
3483 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3483 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3484 | pr_err("%s: index %d too large\n", __func__, retval); | 3484 | pr_err("index %d too large\n", retval); |
3485 | return; | 3485 | return; |
3486 | } | 3486 | } |
3487 | k = find_last_bit(queued_in_use_bm, retval); | 3487 | k = find_last_bit(queued_in_use_bm, retval); |
@@ -3509,7 +3509,7 @@ sdebug_q_cmd_hrt_complete(struct hrtimer *timer) | |||
3509 | atomic_inc(&sdebug_completions); | 3509 | atomic_inc(&sdebug_completions); |
3510 | qa_indx = sd_hrtp->qa_indx; | 3510 | qa_indx = sd_hrtp->qa_indx; |
3511 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { | 3511 | if ((qa_indx < 0) || (qa_indx >= SCSI_DEBUG_CANQUEUE)) { |
3512 | pr_err("%s: wild qa_indx=%d\n", __func__, qa_indx); | 3512 | pr_err("wild qa_indx=%d\n", qa_indx); |
3513 | goto the_end; | 3513 | goto the_end; |
3514 | } | 3514 | } |
3515 | spin_lock_irqsave(&queued_arr_lock, iflags); | 3515 | spin_lock_irqsave(&queued_arr_lock, iflags); |
@@ -3517,21 +3517,21 @@ sdebug_q_cmd_hrt_complete(struct hrtimer *timer) | |||
3517 | scp = sqcp->a_cmnd; | 3517 | scp = sqcp->a_cmnd; |
3518 | if (NULL == scp) { | 3518 | if (NULL == scp) { |
3519 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3519 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3520 | pr_err("%s: scp is NULL\n", __func__); | 3520 | pr_err("scp is NULL\n"); |
3521 | goto the_end; | 3521 | goto the_end; |
3522 | } | 3522 | } |
3523 | devip = (struct sdebug_dev_info *)scp->device->hostdata; | 3523 | devip = (struct sdebug_dev_info *)scp->device->hostdata; |
3524 | if (devip) | 3524 | if (devip) |
3525 | atomic_dec(&devip->num_in_q); | 3525 | atomic_dec(&devip->num_in_q); |
3526 | else | 3526 | else |
3527 | pr_err("%s: devip=NULL\n", __func__); | 3527 | pr_err("devip=NULL\n"); |
3528 | if (atomic_read(&retired_max_queue) > 0) | 3528 | if (atomic_read(&retired_max_queue) > 0) |
3529 | retiring = 1; | 3529 | retiring = 1; |
3530 | 3530 | ||
3531 | sqcp->a_cmnd = NULL; | 3531 | sqcp->a_cmnd = NULL; |
3532 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { | 3532 | if (!test_and_clear_bit(qa_indx, queued_in_use_bm)) { |
3533 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3533 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3534 | pr_err("%s: Unexpected completion\n", __func__); | 3534 | pr_err("Unexpected completion\n"); |
3535 | goto the_end; | 3535 | goto the_end; |
3536 | } | 3536 | } |
3537 | 3537 | ||
@@ -3541,7 +3541,7 @@ sdebug_q_cmd_hrt_complete(struct hrtimer *timer) | |||
3541 | retval = atomic_read(&retired_max_queue); | 3541 | retval = atomic_read(&retired_max_queue); |
3542 | if (qa_indx >= retval) { | 3542 | if (qa_indx >= retval) { |
3543 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 3543 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
3544 | pr_err("%s: index %d too large\n", __func__, retval); | 3544 | pr_err("index %d too large\n", retval); |
3545 | goto the_end; | 3545 | goto the_end; |
3546 | } | 3546 | } |
3547 | k = find_last_bit(queued_in_use_bm, retval); | 3547 | k = find_last_bit(queued_in_use_bm, retval); |
@@ -3580,7 +3580,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
3580 | return devip; | 3580 | return devip; |
3581 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); | 3581 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); |
3582 | if (!sdbg_host) { | 3582 | if (!sdbg_host) { |
3583 | pr_err("%s: Host info NULL\n", __func__); | 3583 | pr_err("Host info NULL\n"); |
3584 | return NULL; | 3584 | return NULL; |
3585 | } | 3585 | } |
3586 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | 3586 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { |
@@ -3596,8 +3596,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
3596 | if (!open_devip) { /* try and make a new one */ | 3596 | if (!open_devip) { /* try and make a new one */ |
3597 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); | 3597 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); |
3598 | if (!open_devip) { | 3598 | if (!open_devip) { |
3599 | printk(KERN_ERR "%s: out of memory at line %d\n", | 3599 | pr_err("out of memory at line %d\n", __LINE__); |
3600 | __func__, __LINE__); | ||
3601 | return NULL; | 3600 | return NULL; |
3602 | } | 3601 | } |
3603 | } | 3602 | } |
@@ -3615,7 +3614,7 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
3615 | static int scsi_debug_slave_alloc(struct scsi_device *sdp) | 3614 | static int scsi_debug_slave_alloc(struct scsi_device *sdp) |
3616 | { | 3615 | { |
3617 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 3616 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
3618 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %llu>\n", | 3617 | pr_info("slave_alloc <%u %u %u %llu>\n", |
3619 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | 3618 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); |
3620 | queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue); | 3619 | queue_flag_set_unlocked(QUEUE_FLAG_BIDI, sdp->request_queue); |
3621 | return 0; | 3620 | return 0; |
@@ -3626,7 +3625,7 @@ static int scsi_debug_slave_configure(struct scsi_device *sdp) | |||
3626 | struct sdebug_dev_info *devip; | 3625 | struct sdebug_dev_info *devip; |
3627 | 3626 | ||
3628 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 3627 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
3629 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %llu>\n", | 3628 | pr_info("slave_configure <%u %u %u %llu>\n", |
3630 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | 3629 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); |
3631 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 3630 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
3632 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 3631 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
@@ -3646,7 +3645,7 @@ static void scsi_debug_slave_destroy(struct scsi_device *sdp) | |||
3646 | (struct sdebug_dev_info *)sdp->hostdata; | 3645 | (struct sdebug_dev_info *)sdp->hostdata; |
3647 | 3646 | ||
3648 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 3647 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
3649 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %llu>\n", | 3648 | pr_info("slave_destroy <%u %u %u %llu>\n", |
3650 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | 3649 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); |
3651 | if (devip) { | 3650 | if (devip) { |
3652 | /* make this slot available for re-use */ | 3651 | /* make this slot available for re-use */ |
@@ -3897,8 +3896,7 @@ static void __init sdebug_build_parts(unsigned char *ramp, | |||
3897 | return; | 3896 | return; |
3898 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { | 3897 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { |
3899 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; | 3898 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; |
3900 | pr_warn("%s: reducing partitions to %d\n", __func__, | 3899 | pr_warn("reducing partitions to %d\n", SDEBUG_MAX_PARTS); |
3901 | SDEBUG_MAX_PARTS); | ||
3902 | } | 3900 | } |
3903 | num_sectors = (int)sdebug_store_sectors; | 3901 | num_sectors = (int)sdebug_store_sectors; |
3904 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 3902 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
@@ -3942,14 +3940,20 @@ schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | |||
3942 | unsigned long iflags; | 3940 | unsigned long iflags; |
3943 | int k, num_in_q, qdepth, inject; | 3941 | int k, num_in_q, qdepth, inject; |
3944 | struct sdebug_queued_cmd *sqcp = NULL; | 3942 | struct sdebug_queued_cmd *sqcp = NULL; |
3945 | struct scsi_device *sdp = cmnd->device; | 3943 | struct scsi_device *sdp; |
3944 | |||
3945 | /* this should never happen */ | ||
3946 | if (WARN_ON(!cmnd)) | ||
3947 | return SCSI_MLQUEUE_HOST_BUSY; | ||
3946 | 3948 | ||
3947 | if (NULL == cmnd || NULL == devip) { | 3949 | if (NULL == devip) { |
3948 | pr_warn("%s: called with NULL cmnd or devip pointer\n", | 3950 | pr_warn("called devip == NULL\n"); |
3949 | __func__); | ||
3950 | /* no particularly good error to report back */ | 3951 | /* no particularly good error to report back */ |
3951 | return SCSI_MLQUEUE_HOST_BUSY; | 3952 | return SCSI_MLQUEUE_HOST_BUSY; |
3952 | } | 3953 | } |
3954 | |||
3955 | sdp = cmnd->device; | ||
3956 | |||
3953 | if ((scsi_result) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 3957 | if ((scsi_result) && (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
3954 | sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n", | 3958 | sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n", |
3955 | __func__, scsi_result); | 3959 | __func__, scsi_result); |
@@ -4383,8 +4387,7 @@ static ssize_t fake_rw_store(struct device_driver *ddp, const char *buf, | |||
4383 | 4387 | ||
4384 | fake_storep = vmalloc(sz); | 4388 | fake_storep = vmalloc(sz); |
4385 | if (NULL == fake_storep) { | 4389 | if (NULL == fake_storep) { |
4386 | pr_err("%s: out of memory, 9\n", | 4390 | pr_err("out of memory, 9\n"); |
4387 | __func__); | ||
4388 | return -ENOMEM; | 4391 | return -ENOMEM; |
4389 | } | 4392 | } |
4390 | memset(fake_storep, 0, sz); | 4393 | memset(fake_storep, 0, sz); |
@@ -4784,8 +4787,7 @@ static int __init scsi_debug_init(void) | |||
4784 | atomic_set(&retired_max_queue, 0); | 4787 | atomic_set(&retired_max_queue, 0); |
4785 | 4788 | ||
4786 | if (scsi_debug_ndelay >= 1000000000) { | 4789 | if (scsi_debug_ndelay >= 1000000000) { |
4787 | pr_warn("%s: ndelay must be less than 1 second, ignored\n", | 4790 | pr_warn("ndelay must be less than 1 second, ignored\n"); |
4788 | __func__); | ||
4789 | scsi_debug_ndelay = 0; | 4791 | scsi_debug_ndelay = 0; |
4790 | } else if (scsi_debug_ndelay > 0) | 4792 | } else if (scsi_debug_ndelay > 0) |
4791 | scsi_debug_delay = DELAY_OVERRIDDEN; | 4793 | scsi_debug_delay = DELAY_OVERRIDDEN; |
@@ -4797,8 +4799,7 @@ static int __init scsi_debug_init(void) | |||
4797 | case 4096: | 4799 | case 4096: |
4798 | break; | 4800 | break; |
4799 | default: | 4801 | default: |
4800 | pr_err("%s: invalid sector_size %d\n", __func__, | 4802 | pr_err("invalid sector_size %d\n", scsi_debug_sector_size); |
4801 | scsi_debug_sector_size); | ||
4802 | return -EINVAL; | 4803 | return -EINVAL; |
4803 | } | 4804 | } |
4804 | 4805 | ||
@@ -4811,29 +4812,28 @@ static int __init scsi_debug_init(void) | |||
4811 | break; | 4812 | break; |
4812 | 4813 | ||
4813 | default: | 4814 | default: |
4814 | pr_err("%s: dif must be 0, 1, 2 or 3\n", __func__); | 4815 | pr_err("dif must be 0, 1, 2 or 3\n"); |
4815 | return -EINVAL; | 4816 | return -EINVAL; |
4816 | } | 4817 | } |
4817 | 4818 | ||
4818 | if (scsi_debug_guard > 1) { | 4819 | if (scsi_debug_guard > 1) { |
4819 | pr_err("%s: guard must be 0 or 1\n", __func__); | 4820 | pr_err("guard must be 0 or 1\n"); |
4820 | return -EINVAL; | 4821 | return -EINVAL; |
4821 | } | 4822 | } |
4822 | 4823 | ||
4823 | if (scsi_debug_ato > 1) { | 4824 | if (scsi_debug_ato > 1) { |
4824 | pr_err("%s: ato must be 0 or 1\n", __func__); | 4825 | pr_err("ato must be 0 or 1\n"); |
4825 | return -EINVAL; | 4826 | return -EINVAL; |
4826 | } | 4827 | } |
4827 | 4828 | ||
4828 | if (scsi_debug_physblk_exp > 15) { | 4829 | if (scsi_debug_physblk_exp > 15) { |
4829 | pr_err("%s: invalid physblk_exp %u\n", __func__, | 4830 | pr_err("invalid physblk_exp %u\n", scsi_debug_physblk_exp); |
4830 | scsi_debug_physblk_exp); | ||
4831 | return -EINVAL; | 4831 | return -EINVAL; |
4832 | } | 4832 | } |
4833 | 4833 | ||
4834 | if (scsi_debug_lowest_aligned > 0x3fff) { | 4834 | if (scsi_debug_lowest_aligned > 0x3fff) { |
4835 | pr_err("%s: lowest_aligned too big: %u\n", __func__, | 4835 | pr_err("lowest_aligned too big: %u\n", |
4836 | scsi_debug_lowest_aligned); | 4836 | scsi_debug_lowest_aligned); |
4837 | return -EINVAL; | 4837 | return -EINVAL; |
4838 | } | 4838 | } |
4839 | 4839 | ||
@@ -4863,7 +4863,7 @@ static int __init scsi_debug_init(void) | |||
4863 | if (0 == scsi_debug_fake_rw) { | 4863 | if (0 == scsi_debug_fake_rw) { |
4864 | fake_storep = vmalloc(sz); | 4864 | fake_storep = vmalloc(sz); |
4865 | if (NULL == fake_storep) { | 4865 | if (NULL == fake_storep) { |
4866 | pr_err("%s: out of memory, 1\n", __func__); | 4866 | pr_err("out of memory, 1\n"); |
4867 | return -ENOMEM; | 4867 | return -ENOMEM; |
4868 | } | 4868 | } |
4869 | memset(fake_storep, 0, sz); | 4869 | memset(fake_storep, 0, sz); |
@@ -4877,11 +4877,10 @@ static int __init scsi_debug_init(void) | |||
4877 | dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); | 4877 | dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); |
4878 | dif_storep = vmalloc(dif_size); | 4878 | dif_storep = vmalloc(dif_size); |
4879 | 4879 | ||
4880 | pr_err("%s: dif_storep %u bytes @ %p\n", __func__, dif_size, | 4880 | pr_err("dif_storep %u bytes @ %p\n", dif_size, dif_storep); |
4881 | dif_storep); | ||
4882 | 4881 | ||
4883 | if (dif_storep == NULL) { | 4882 | if (dif_storep == NULL) { |
4884 | pr_err("%s: out of mem. (DIX)\n", __func__); | 4883 | pr_err("out of mem. (DIX)\n"); |
4885 | ret = -ENOMEM; | 4884 | ret = -ENOMEM; |
4886 | goto free_vm; | 4885 | goto free_vm; |
4887 | } | 4886 | } |
@@ -4903,18 +4902,17 @@ static int __init scsi_debug_init(void) | |||
4903 | if (scsi_debug_unmap_alignment && | 4902 | if (scsi_debug_unmap_alignment && |
4904 | scsi_debug_unmap_granularity <= | 4903 | scsi_debug_unmap_granularity <= |
4905 | scsi_debug_unmap_alignment) { | 4904 | scsi_debug_unmap_alignment) { |
4906 | pr_err("%s: ERR: unmap_granularity <= unmap_alignment\n", | 4905 | pr_err("ERR: unmap_granularity <= unmap_alignment\n"); |
4907 | __func__); | ||
4908 | return -EINVAL; | 4906 | return -EINVAL; |
4909 | } | 4907 | } |
4910 | 4908 | ||
4911 | map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; | 4909 | map_size = lba_to_map_index(sdebug_store_sectors - 1) + 1; |
4912 | map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); | 4910 | map_storep = vmalloc(BITS_TO_LONGS(map_size) * sizeof(long)); |
4913 | 4911 | ||
4914 | pr_info("%s: %lu provisioning blocks\n", __func__, map_size); | 4912 | pr_info("%lu provisioning blocks\n", map_size); |
4915 | 4913 | ||
4916 | if (map_storep == NULL) { | 4914 | if (map_storep == NULL) { |
4917 | pr_err("%s: out of mem. (MAP)\n", __func__); | 4915 | pr_err("out of mem. (MAP)\n"); |
4918 | ret = -ENOMEM; | 4916 | ret = -ENOMEM; |
4919 | goto free_vm; | 4917 | goto free_vm; |
4920 | } | 4918 | } |
@@ -4928,18 +4926,18 @@ static int __init scsi_debug_init(void) | |||
4928 | 4926 | ||
4929 | pseudo_primary = root_device_register("pseudo_0"); | 4927 | pseudo_primary = root_device_register("pseudo_0"); |
4930 | if (IS_ERR(pseudo_primary)) { | 4928 | if (IS_ERR(pseudo_primary)) { |
4931 | pr_warn("%s: root_device_register() error\n", __func__); | 4929 | pr_warn("root_device_register() error\n"); |
4932 | ret = PTR_ERR(pseudo_primary); | 4930 | ret = PTR_ERR(pseudo_primary); |
4933 | goto free_vm; | 4931 | goto free_vm; |
4934 | } | 4932 | } |
4935 | ret = bus_register(&pseudo_lld_bus); | 4933 | ret = bus_register(&pseudo_lld_bus); |
4936 | if (ret < 0) { | 4934 | if (ret < 0) { |
4937 | pr_warn("%s: bus_register error: %d\n", __func__, ret); | 4935 | pr_warn("bus_register error: %d\n", ret); |
4938 | goto dev_unreg; | 4936 | goto dev_unreg; |
4939 | } | 4937 | } |
4940 | ret = driver_register(&sdebug_driverfs_driver); | 4938 | ret = driver_register(&sdebug_driverfs_driver); |
4941 | if (ret < 0) { | 4939 | if (ret < 0) { |
4942 | pr_warn("%s: driver_register error: %d\n", __func__, ret); | 4940 | pr_warn("driver_register error: %d\n", ret); |
4943 | goto bus_unreg; | 4941 | goto bus_unreg; |
4944 | } | 4942 | } |
4945 | 4943 | ||
@@ -4948,16 +4946,14 @@ static int __init scsi_debug_init(void) | |||
4948 | 4946 | ||
4949 | for (k = 0; k < host_to_add; k++) { | 4947 | for (k = 0; k < host_to_add; k++) { |
4950 | if (sdebug_add_adapter()) { | 4948 | if (sdebug_add_adapter()) { |
4951 | pr_err("%s: sdebug_add_adapter failed k=%d\n", | 4949 | pr_err("sdebug_add_adapter failed k=%d\n", k); |
4952 | __func__, k); | ||
4953 | break; | 4950 | break; |
4954 | } | 4951 | } |
4955 | } | 4952 | } |
4956 | 4953 | ||
4957 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { | 4954 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
4958 | pr_info("%s: built %d host(s)\n", __func__, | 4955 | pr_info("built %d host(s)\n", scsi_debug_add_host); |
4959 | scsi_debug_add_host); | 4956 | |
4960 | } | ||
4961 | return 0; | 4957 | return 0; |
4962 | 4958 | ||
4963 | bus_unreg: | 4959 | bus_unreg: |
@@ -4965,10 +4961,8 @@ bus_unreg: | |||
4965 | dev_unreg: | 4961 | dev_unreg: |
4966 | root_device_unregister(pseudo_primary); | 4962 | root_device_unregister(pseudo_primary); |
4967 | free_vm: | 4963 | free_vm: |
4968 | if (map_storep) | 4964 | vfree(map_storep); |
4969 | vfree(map_storep); | 4965 | vfree(dif_storep); |
4970 | if (dif_storep) | ||
4971 | vfree(dif_storep); | ||
4972 | vfree(fake_storep); | 4966 | vfree(fake_storep); |
4973 | 4967 | ||
4974 | return ret; | 4968 | return ret; |
@@ -4986,9 +4980,7 @@ static void __exit scsi_debug_exit(void) | |||
4986 | bus_unregister(&pseudo_lld_bus); | 4980 | bus_unregister(&pseudo_lld_bus); |
4987 | root_device_unregister(pseudo_primary); | 4981 | root_device_unregister(pseudo_primary); |
4988 | 4982 | ||
4989 | if (dif_storep) | 4983 | vfree(dif_storep); |
4990 | vfree(dif_storep); | ||
4991 | |||
4992 | vfree(fake_storep); | 4984 | vfree(fake_storep); |
4993 | } | 4985 | } |
4994 | 4986 | ||
@@ -5012,8 +5004,7 @@ static int sdebug_add_adapter(void) | |||
5012 | 5004 | ||
5013 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); | 5005 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
5014 | if (NULL == sdbg_host) { | 5006 | if (NULL == sdbg_host) { |
5015 | printk(KERN_ERR "%s: out of memory at line %d\n", | 5007 | pr_err("out of memory at line %d\n", __LINE__); |
5016 | __func__, __LINE__); | ||
5017 | return -ENOMEM; | 5008 | return -ENOMEM; |
5018 | } | 5009 | } |
5019 | 5010 | ||
@@ -5023,8 +5014,7 @@ static int sdebug_add_adapter(void) | |||
5023 | for (k = 0; k < devs_per_host; k++) { | 5014 | for (k = 0; k < devs_per_host; k++) { |
5024 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); | 5015 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); |
5025 | if (!sdbg_devinfo) { | 5016 | if (!sdbg_devinfo) { |
5026 | printk(KERN_ERR "%s: out of memory at line %d\n", | 5017 | pr_err("out of memory at line %d\n", __LINE__); |
5027 | __func__, __LINE__); | ||
5028 | error = -ENOMEM; | 5018 | error = -ENOMEM; |
5029 | goto clean; | 5019 | goto clean; |
5030 | } | 5020 | } |
@@ -5178,7 +5168,7 @@ scsi_debug_queuecommand(struct scsi_cmnd *scp) | |||
5178 | } | 5168 | } |
5179 | sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b); | 5169 | sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, b); |
5180 | } | 5170 | } |
5181 | has_wlun_rl = (sdp->lun == SAM2_WLUN_REPORT_LUNS); | 5171 | has_wlun_rl = (sdp->lun == SCSI_W_LUN_REPORT_LUNS); |
5182 | if ((sdp->lun >= scsi_debug_max_luns) && !has_wlun_rl) | 5172 | if ((sdp->lun >= scsi_debug_max_luns) && !has_wlun_rl) |
5183 | return schedule_resp(scp, NULL, errsts_no_connect, 0); | 5173 | return schedule_resp(scp, NULL, errsts_no_connect, 0); |
5184 | 5174 | ||
@@ -5338,7 +5328,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
5338 | sdebug_driver_template.use_clustering = ENABLE_CLUSTERING; | 5328 | sdebug_driver_template.use_clustering = ENABLE_CLUSTERING; |
5339 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); | 5329 | hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host)); |
5340 | if (NULL == hpnt) { | 5330 | if (NULL == hpnt) { |
5341 | pr_err("%s: scsi_host_alloc failed\n", __func__); | 5331 | pr_err("scsi_host_alloc failed\n"); |
5342 | error = -ENODEV; | 5332 | error = -ENODEV; |
5343 | return error; | 5333 | return error; |
5344 | } | 5334 | } |
@@ -5349,7 +5339,8 @@ static int sdebug_driver_probe(struct device * dev) | |||
5349 | hpnt->max_id = scsi_debug_num_tgts + 1; | 5339 | hpnt->max_id = scsi_debug_num_tgts + 1; |
5350 | else | 5340 | else |
5351 | hpnt->max_id = scsi_debug_num_tgts; | 5341 | hpnt->max_id = scsi_debug_num_tgts; |
5352 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ | 5342 | /* = scsi_debug_max_luns; */ |
5343 | hpnt->max_lun = SCSI_W_LUN_REPORT_LUNS + 1; | ||
5353 | 5344 | ||
5354 | host_prot = 0; | 5345 | host_prot = 0; |
5355 | 5346 | ||
@@ -5381,7 +5372,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
5381 | 5372 | ||
5382 | scsi_host_set_prot(hpnt, host_prot); | 5373 | scsi_host_set_prot(hpnt, host_prot); |
5383 | 5374 | ||
5384 | printk(KERN_INFO "scsi_debug: host protection%s%s%s%s%s%s%s\n", | 5375 | pr_info("host protection%s%s%s%s%s%s%s\n", |
5385 | (host_prot & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "", | 5376 | (host_prot & SHOST_DIF_TYPE1_PROTECTION) ? " DIF1" : "", |
5386 | (host_prot & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "", | 5377 | (host_prot & SHOST_DIF_TYPE2_PROTECTION) ? " DIF2" : "", |
5387 | (host_prot & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "", | 5378 | (host_prot & SHOST_DIF_TYPE3_PROTECTION) ? " DIF3" : "", |
@@ -5409,7 +5400,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
5409 | 5400 | ||
5410 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 5401 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
5411 | if (error) { | 5402 | if (error) { |
5412 | printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); | 5403 | pr_err("scsi_add_host failed\n"); |
5413 | error = -ENODEV; | 5404 | error = -ENODEV; |
5414 | scsi_host_put(hpnt); | 5405 | scsi_host_put(hpnt); |
5415 | } else | 5406 | } else |
@@ -5426,8 +5417,7 @@ static int sdebug_driver_remove(struct device * dev) | |||
5426 | sdbg_host = to_sdebug_host(dev); | 5417 | sdbg_host = to_sdebug_host(dev); |
5427 | 5418 | ||
5428 | if (!sdbg_host) { | 5419 | if (!sdbg_host) { |
5429 | printk(KERN_ERR "%s: Unable to locate host info\n", | 5420 | pr_err("Unable to locate host info\n"); |
5430 | __func__); | ||
5431 | return -ENODEV; | 5421 | return -ENODEV; |
5432 | } | 5422 | } |
5433 | 5423 | ||
diff --git a/drivers/scsi/scsi_dh.c b/drivers/scsi/scsi_dh.c new file mode 100644 index 000000000000..edb044a7b56d --- /dev/null +++ b/drivers/scsi/scsi_dh.c | |||
@@ -0,0 +1,437 @@ | |||
1 | /* | ||
2 | * SCSI device handler infrastruture. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | * | ||
18 | * Copyright IBM Corporation, 2007 | ||
19 | * Authors: | ||
20 | * Chandra Seetharaman <sekharan@us.ibm.com> | ||
21 | * Mike Anderson <andmike@linux.vnet.ibm.com> | ||
22 | */ | ||
23 | |||
24 | #include <linux/slab.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <scsi/scsi_dh.h> | ||
27 | #include "scsi_priv.h" | ||
28 | |||
29 | static DEFINE_SPINLOCK(list_lock); | ||
30 | static LIST_HEAD(scsi_dh_list); | ||
31 | |||
32 | struct scsi_dh_blist { | ||
33 | const char *vendor; | ||
34 | const char *model; | ||
35 | const char *driver; | ||
36 | }; | ||
37 | |||
38 | static const struct scsi_dh_blist scsi_dh_blist[] = { | ||
39 | {"DGC", "RAID", "clariion" }, | ||
40 | {"DGC", "DISK", "clariion" }, | ||
41 | {"DGC", "VRAID", "clariion" }, | ||
42 | |||
43 | {"COMPAQ", "MSA1000 VOLUME", "hp_sw" }, | ||
44 | {"COMPAQ", "HSV110", "hp_sw" }, | ||
45 | {"HP", "HSV100", "hp_sw"}, | ||
46 | {"DEC", "HSG80", "hp_sw"}, | ||
47 | |||
48 | {"IBM", "1722", "rdac", }, | ||
49 | {"IBM", "1724", "rdac", }, | ||
50 | {"IBM", "1726", "rdac", }, | ||
51 | {"IBM", "1742", "rdac", }, | ||
52 | {"IBM", "1745", "rdac", }, | ||
53 | {"IBM", "1746", "rdac", }, | ||
54 | {"IBM", "1813", "rdac", }, | ||
55 | {"IBM", "1814", "rdac", }, | ||
56 | {"IBM", "1815", "rdac", }, | ||
57 | {"IBM", "1818", "rdac", }, | ||
58 | {"IBM", "3526", "rdac", }, | ||
59 | {"SGI", "TP9", "rdac", }, | ||
60 | {"SGI", "IS", "rdac", }, | ||
61 | {"STK", "OPENstorage D280", "rdac", }, | ||
62 | {"STK", "FLEXLINE 380", "rdac", }, | ||
63 | {"SUN", "CSM", "rdac", }, | ||
64 | {"SUN", "LCSM100", "rdac", }, | ||
65 | {"SUN", "STK6580_6780", "rdac", }, | ||
66 | {"SUN", "SUN_6180", "rdac", }, | ||
67 | {"SUN", "ArrayStorage", "rdac", }, | ||
68 | {"DELL", "MD3", "rdac", }, | ||
69 | {"NETAPP", "INF-01-00", "rdac", }, | ||
70 | {"LSI", "INF-01-00", "rdac", }, | ||
71 | {"ENGENIO", "INF-01-00", "rdac", }, | ||
72 | {NULL, NULL, NULL }, | ||
73 | }; | ||
74 | |||
75 | static const char * | ||
76 | scsi_dh_find_driver(struct scsi_device *sdev) | ||
77 | { | ||
78 | const struct scsi_dh_blist *b; | ||
79 | |||
80 | if (scsi_device_tpgs(sdev)) | ||
81 | return "alua"; | ||
82 | |||
83 | for (b = scsi_dh_blist; b->vendor; b++) { | ||
84 | if (!strncmp(sdev->vendor, b->vendor, strlen(b->vendor)) && | ||
85 | !strncmp(sdev->model, b->model, strlen(b->model))) { | ||
86 | return b->driver; | ||
87 | } | ||
88 | } | ||
89 | return NULL; | ||
90 | } | ||
91 | |||
92 | |||
93 | static struct scsi_device_handler *__scsi_dh_lookup(const char *name) | ||
94 | { | ||
95 | struct scsi_device_handler *tmp, *found = NULL; | ||
96 | |||
97 | spin_lock(&list_lock); | ||
98 | list_for_each_entry(tmp, &scsi_dh_list, list) { | ||
99 | if (!strncmp(tmp->name, name, strlen(tmp->name))) { | ||
100 | found = tmp; | ||
101 | break; | ||
102 | } | ||
103 | } | ||
104 | spin_unlock(&list_lock); | ||
105 | return found; | ||
106 | } | ||
107 | |||
108 | static struct scsi_device_handler *scsi_dh_lookup(const char *name) | ||
109 | { | ||
110 | struct scsi_device_handler *dh; | ||
111 | |||
112 | dh = __scsi_dh_lookup(name); | ||
113 | if (!dh) { | ||
114 | request_module(name); | ||
115 | dh = __scsi_dh_lookup(name); | ||
116 | } | ||
117 | |||
118 | return dh; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * scsi_dh_handler_attach - Attach a device handler to a device | ||
123 | * @sdev - SCSI device the device handler should attach to | ||
124 | * @scsi_dh - The device handler to attach | ||
125 | */ | ||
126 | static int scsi_dh_handler_attach(struct scsi_device *sdev, | ||
127 | struct scsi_device_handler *scsi_dh) | ||
128 | { | ||
129 | int error; | ||
130 | |||
131 | if (!try_module_get(scsi_dh->module)) | ||
132 | return -EINVAL; | ||
133 | |||
134 | error = scsi_dh->attach(sdev); | ||
135 | if (error) { | ||
136 | sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n", | ||
137 | scsi_dh->name, error); | ||
138 | module_put(scsi_dh->module); | ||
139 | } else | ||
140 | sdev->handler = scsi_dh; | ||
141 | |||
142 | return error; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * scsi_dh_handler_detach - Detach a device handler from a device | ||
147 | * @sdev - SCSI device the device handler should be detached from | ||
148 | */ | ||
149 | static void scsi_dh_handler_detach(struct scsi_device *sdev) | ||
150 | { | ||
151 | sdev->handler->detach(sdev); | ||
152 | sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name); | ||
153 | module_put(sdev->handler->module); | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Functions for sysfs attribute 'dh_state' | ||
158 | */ | ||
159 | static ssize_t | ||
160 | store_dh_state(struct device *dev, struct device_attribute *attr, | ||
161 | const char *buf, size_t count) | ||
162 | { | ||
163 | struct scsi_device *sdev = to_scsi_device(dev); | ||
164 | struct scsi_device_handler *scsi_dh; | ||
165 | int err = -EINVAL; | ||
166 | |||
167 | if (sdev->sdev_state == SDEV_CANCEL || | ||
168 | sdev->sdev_state == SDEV_DEL) | ||
169 | return -ENODEV; | ||
170 | |||
171 | if (!sdev->handler) { | ||
172 | /* | ||
173 | * Attach to a device handler | ||
174 | */ | ||
175 | scsi_dh = scsi_dh_lookup(buf); | ||
176 | if (!scsi_dh) | ||
177 | return err; | ||
178 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
179 | } else { | ||
180 | if (!strncmp(buf, "detach", 6)) { | ||
181 | /* | ||
182 | * Detach from a device handler | ||
183 | */ | ||
184 | sdev_printk(KERN_WARNING, sdev, | ||
185 | "can't detach handler %s.\n", | ||
186 | sdev->handler->name); | ||
187 | err = -EINVAL; | ||
188 | } else if (!strncmp(buf, "activate", 8)) { | ||
189 | /* | ||
190 | * Activate a device handler | ||
191 | */ | ||
192 | if (sdev->handler->activate) | ||
193 | err = sdev->handler->activate(sdev, NULL, NULL); | ||
194 | else | ||
195 | err = 0; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | return err<0?err:count; | ||
200 | } | ||
201 | |||
202 | static ssize_t | ||
203 | show_dh_state(struct device *dev, struct device_attribute *attr, char *buf) | ||
204 | { | ||
205 | struct scsi_device *sdev = to_scsi_device(dev); | ||
206 | |||
207 | if (!sdev->handler) | ||
208 | return snprintf(buf, 20, "detached\n"); | ||
209 | |||
210 | return snprintf(buf, 20, "%s\n", sdev->handler->name); | ||
211 | } | ||
212 | |||
213 | static struct device_attribute scsi_dh_state_attr = | ||
214 | __ATTR(dh_state, S_IRUGO | S_IWUSR, show_dh_state, | ||
215 | store_dh_state); | ||
216 | |||
217 | int scsi_dh_add_device(struct scsi_device *sdev) | ||
218 | { | ||
219 | struct scsi_device_handler *devinfo = NULL; | ||
220 | const char *drv; | ||
221 | int err; | ||
222 | |||
223 | err = device_create_file(&sdev->sdev_gendev, &scsi_dh_state_attr); | ||
224 | if (err) | ||
225 | return err; | ||
226 | |||
227 | drv = scsi_dh_find_driver(sdev); | ||
228 | if (drv) | ||
229 | devinfo = scsi_dh_lookup(drv); | ||
230 | if (devinfo) | ||
231 | err = scsi_dh_handler_attach(sdev, devinfo); | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | void scsi_dh_remove_device(struct scsi_device *sdev) | ||
236 | { | ||
237 | if (sdev->handler) | ||
238 | scsi_dh_handler_detach(sdev); | ||
239 | device_remove_file(&sdev->sdev_gendev, &scsi_dh_state_attr); | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * scsi_register_device_handler - register a device handler personality | ||
244 | * module. | ||
245 | * @scsi_dh - device handler to be registered. | ||
246 | * | ||
247 | * Returns 0 on success, -EBUSY if handler already registered. | ||
248 | */ | ||
249 | int scsi_register_device_handler(struct scsi_device_handler *scsi_dh) | ||
250 | { | ||
251 | if (__scsi_dh_lookup(scsi_dh->name)) | ||
252 | return -EBUSY; | ||
253 | |||
254 | if (!scsi_dh->attach || !scsi_dh->detach) | ||
255 | return -EINVAL; | ||
256 | |||
257 | spin_lock(&list_lock); | ||
258 | list_add(&scsi_dh->list, &scsi_dh_list); | ||
259 | spin_unlock(&list_lock); | ||
260 | |||
261 | printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name); | ||
262 | |||
263 | return SCSI_DH_OK; | ||
264 | } | ||
265 | EXPORT_SYMBOL_GPL(scsi_register_device_handler); | ||
266 | |||
267 | /* | ||
268 | * scsi_unregister_device_handler - register a device handler personality | ||
269 | * module. | ||
270 | * @scsi_dh - device handler to be unregistered. | ||
271 | * | ||
272 | * Returns 0 on success, -ENODEV if handler not registered. | ||
273 | */ | ||
274 | int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh) | ||
275 | { | ||
276 | if (!__scsi_dh_lookup(scsi_dh->name)) | ||
277 | return -ENODEV; | ||
278 | |||
279 | spin_lock(&list_lock); | ||
280 | list_del(&scsi_dh->list); | ||
281 | spin_unlock(&list_lock); | ||
282 | printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name); | ||
283 | |||
284 | return SCSI_DH_OK; | ||
285 | } | ||
286 | EXPORT_SYMBOL_GPL(scsi_unregister_device_handler); | ||
287 | |||
288 | static struct scsi_device *get_sdev_from_queue(struct request_queue *q) | ||
289 | { | ||
290 | struct scsi_device *sdev; | ||
291 | unsigned long flags; | ||
292 | |||
293 | spin_lock_irqsave(q->queue_lock, flags); | ||
294 | sdev = q->queuedata; | ||
295 | if (!sdev || !get_device(&sdev->sdev_gendev)) | ||
296 | sdev = NULL; | ||
297 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
298 | |||
299 | return sdev; | ||
300 | } | ||
301 | |||
302 | /* | ||
303 | * scsi_dh_activate - activate the path associated with the scsi_device | ||
304 | * corresponding to the given request queue. | ||
305 | * Returns immediately without waiting for activation to be completed. | ||
306 | * @q - Request queue that is associated with the scsi_device to be | ||
307 | * activated. | ||
308 | * @fn - Function to be called upon completion of the activation. | ||
309 | * Function fn is called with data (below) and the error code. | ||
310 | * Function fn may be called from the same calling context. So, | ||
311 | * do not hold the lock in the caller which may be needed in fn. | ||
312 | * @data - data passed to the function fn upon completion. | ||
313 | * | ||
314 | */ | ||
315 | int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) | ||
316 | { | ||
317 | struct scsi_device *sdev; | ||
318 | int err = SCSI_DH_NOSYS; | ||
319 | |||
320 | sdev = get_sdev_from_queue(q); | ||
321 | if (!sdev) { | ||
322 | if (fn) | ||
323 | fn(data, err); | ||
324 | return err; | ||
325 | } | ||
326 | |||
327 | if (!sdev->handler) | ||
328 | goto out_fn; | ||
329 | err = SCSI_DH_NOTCONN; | ||
330 | if (sdev->sdev_state == SDEV_CANCEL || | ||
331 | sdev->sdev_state == SDEV_DEL) | ||
332 | goto out_fn; | ||
333 | |||
334 | err = SCSI_DH_DEV_OFFLINED; | ||
335 | if (sdev->sdev_state == SDEV_OFFLINE) | ||
336 | goto out_fn; | ||
337 | |||
338 | if (sdev->handler->activate) | ||
339 | err = sdev->handler->activate(sdev, fn, data); | ||
340 | |||
341 | out_put_device: | ||
342 | put_device(&sdev->sdev_gendev); | ||
343 | return err; | ||
344 | |||
345 | out_fn: | ||
346 | if (fn) | ||
347 | fn(data, err); | ||
348 | goto out_put_device; | ||
349 | } | ||
350 | EXPORT_SYMBOL_GPL(scsi_dh_activate); | ||
351 | |||
352 | /* | ||
353 | * scsi_dh_set_params - set the parameters for the device as per the | ||
354 | * string specified in params. | ||
355 | * @q - Request queue that is associated with the scsi_device for | ||
356 | * which the parameters to be set. | ||
357 | * @params - parameters in the following format | ||
358 | * "no_of_params\0param1\0param2\0param3\0...\0" | ||
359 | * for example, string for 2 parameters with value 10 and 21 | ||
360 | * is specified as "2\010\021\0". | ||
361 | */ | ||
362 | int scsi_dh_set_params(struct request_queue *q, const char *params) | ||
363 | { | ||
364 | struct scsi_device *sdev; | ||
365 | int err = -SCSI_DH_NOSYS; | ||
366 | |||
367 | sdev = get_sdev_from_queue(q); | ||
368 | if (!sdev) | ||
369 | return err; | ||
370 | |||
371 | if (sdev->handler && sdev->handler->set_params) | ||
372 | err = sdev->handler->set_params(sdev, params); | ||
373 | put_device(&sdev->sdev_gendev); | ||
374 | return err; | ||
375 | } | ||
376 | EXPORT_SYMBOL_GPL(scsi_dh_set_params); | ||
377 | |||
378 | /* | ||
379 | * scsi_dh_attach - Attach device handler | ||
380 | * @q - Request queue that is associated with the scsi_device | ||
381 | * the handler should be attached to | ||
382 | * @name - name of the handler to attach | ||
383 | */ | ||
384 | int scsi_dh_attach(struct request_queue *q, const char *name) | ||
385 | { | ||
386 | struct scsi_device *sdev; | ||
387 | struct scsi_device_handler *scsi_dh; | ||
388 | int err = 0; | ||
389 | |||
390 | sdev = get_sdev_from_queue(q); | ||
391 | if (!sdev) | ||
392 | return -ENODEV; | ||
393 | |||
394 | scsi_dh = scsi_dh_lookup(name); | ||
395 | if (!scsi_dh) { | ||
396 | err = -EINVAL; | ||
397 | goto out_put_device; | ||
398 | } | ||
399 | |||
400 | if (sdev->handler) { | ||
401 | if (sdev->handler != scsi_dh) | ||
402 | err = -EBUSY; | ||
403 | goto out_put_device; | ||
404 | } | ||
405 | |||
406 | err = scsi_dh_handler_attach(sdev, scsi_dh); | ||
407 | |||
408 | out_put_device: | ||
409 | put_device(&sdev->sdev_gendev); | ||
410 | return err; | ||
411 | } | ||
412 | EXPORT_SYMBOL_GPL(scsi_dh_attach); | ||
413 | |||
414 | /* | ||
415 | * scsi_dh_attached_handler_name - Get attached device handler's name | ||
416 | * @q - Request queue that is associated with the scsi_device | ||
417 | * that may have a device handler attached | ||
418 | * @gfp - the GFP mask used in the kmalloc() call when allocating memory | ||
419 | * | ||
420 | * Returns name of attached handler, NULL if no handler is attached. | ||
421 | * Caller must take care to free the returned string. | ||
422 | */ | ||
423 | const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp) | ||
424 | { | ||
425 | struct scsi_device *sdev; | ||
426 | const char *handler_name = NULL; | ||
427 | |||
428 | sdev = get_sdev_from_queue(q); | ||
429 | if (!sdev) | ||
430 | return NULL; | ||
431 | |||
432 | if (sdev->handler) | ||
433 | handler_name = kstrdup(sdev->handler->name, gfp); | ||
434 | put_device(&sdev->sdev_gendev); | ||
435 | return handler_name; | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name); | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index afd34a608fe7..b616a6bef44a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <scsi/scsi_transport.h> | 36 | #include <scsi/scsi_transport.h> |
37 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
38 | #include <scsi/scsi_ioctl.h> | 38 | #include <scsi/scsi_ioctl.h> |
39 | #include <scsi/scsi_dh.h> | ||
39 | #include <scsi/sg.h> | 40 | #include <scsi/sg.h> |
40 | 41 | ||
41 | #include "scsi_priv.h" | 42 | #include "scsi_priv.h" |
@@ -463,11 +464,10 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
463 | if (scsi_sense_is_deferred(&sshdr)) | 464 | if (scsi_sense_is_deferred(&sshdr)) |
464 | return NEEDS_RETRY; | 465 | return NEEDS_RETRY; |
465 | 466 | ||
466 | if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh && | 467 | if (sdev->handler && sdev->handler->check_sense) { |
467 | sdev->scsi_dh_data->scsi_dh->check_sense) { | ||
468 | int rc; | 468 | int rc; |
469 | 469 | ||
470 | rc = sdev->scsi_dh_data->scsi_dh->check_sense(sdev, &sshdr); | 470 | rc = sdev->handler->check_sense(sdev, &sshdr); |
471 | if (rc != SCSI_RETURN_NOT_HANDLED) | 471 | if (rc != SCSI_RETURN_NOT_HANDLED) |
472 | return rc; | 472 | return rc; |
473 | /* handler does not care. Drop down to default handling */ | 473 | /* handler does not care. Drop down to default handling */ |
@@ -2178,8 +2178,17 @@ int scsi_error_handler(void *data) | |||
2178 | * We never actually get interrupted because kthread_run | 2178 | * We never actually get interrupted because kthread_run |
2179 | * disables signal delivery for the created thread. | 2179 | * disables signal delivery for the created thread. |
2180 | */ | 2180 | */ |
2181 | while (!kthread_should_stop()) { | 2181 | while (true) { |
2182 | /* | ||
2183 | * The sequence in kthread_stop() sets the stop flag first | ||
2184 | * then wakes the process. To avoid missed wakeups, the task | ||
2185 | * should always be in a non running state before the stop | ||
2186 | * flag is checked | ||
2187 | */ | ||
2182 | set_current_state(TASK_INTERRUPTIBLE); | 2188 | set_current_state(TASK_INTERRUPTIBLE); |
2189 | if (kthread_should_stop()) | ||
2190 | break; | ||
2191 | |||
2183 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || | 2192 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || |
2184 | shost->host_failed != atomic_read(&shost->host_busy)) { | 2193 | shost->host_failed != atomic_read(&shost->host_busy)) { |
2185 | SCSI_LOG_ERROR_RECOVERY(1, | 2194 | SCSI_LOG_ERROR_RECOVERY(1, |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 882864f5cbae..cbfc5990052b 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <scsi/scsi_driver.h> | 31 | #include <scsi/scsi_driver.h> |
32 | #include <scsi/scsi_eh.h> | 32 | #include <scsi/scsi_eh.h> |
33 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_dh.h> | ||
34 | 35 | ||
35 | #include <trace/events/scsi.h> | 36 | #include <trace/events/scsi.h> |
36 | 37 | ||
@@ -1248,9 +1249,8 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | |||
1248 | { | 1249 | { |
1249 | struct scsi_cmnd *cmd = req->special; | 1250 | struct scsi_cmnd *cmd = req->special; |
1250 | 1251 | ||
1251 | if (unlikely(sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh | 1252 | if (unlikely(sdev->handler && sdev->handler->prep_fn)) { |
1252 | && sdev->scsi_dh_data->scsi_dh->prep_fn)) { | 1253 | int ret = sdev->handler->prep_fn(sdev, req); |
1253 | int ret = sdev->scsi_dh_data->scsi_dh->prep_fn(sdev, req); | ||
1254 | if (ret != BLKPREP_OK) | 1254 | if (ret != BLKPREP_OK) |
1255 | return ret; | 1255 | return ret; |
1256 | } | 1256 | } |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index e3902fc66278..644bb7339b55 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -170,6 +170,15 @@ static inline void scsi_autopm_put_host(struct Scsi_Host *h) {} | |||
170 | extern struct async_domain scsi_sd_pm_domain; | 170 | extern struct async_domain scsi_sd_pm_domain; |
171 | extern struct async_domain scsi_sd_probe_domain; | 171 | extern struct async_domain scsi_sd_probe_domain; |
172 | 172 | ||
173 | /* scsi_dh.c */ | ||
174 | #ifdef CONFIG_SCSI_DH | ||
175 | int scsi_dh_add_device(struct scsi_device *sdev); | ||
176 | void scsi_dh_remove_device(struct scsi_device *sdev); | ||
177 | #else | ||
178 | static inline int scsi_dh_add_device(struct scsi_device *sdev) { return 0; } | ||
179 | static inline void scsi_dh_remove_device(struct scsi_device *sdev) { } | ||
180 | #endif | ||
181 | |||
173 | /* | 182 | /* |
174 | * internal scsi timeout functions: for use by mid-layer and transport | 183 | * internal scsi timeout functions: for use by mid-layer and transport |
175 | * classes. | 184 | * classes. |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 9ad41168d26d..b333389f248f 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -1030,11 +1030,20 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
1030 | "failed to add device: %d\n", error); | 1030 | "failed to add device: %d\n", error); |
1031 | return error; | 1031 | return error; |
1032 | } | 1032 | } |
1033 | |||
1034 | error = scsi_dh_add_device(sdev); | ||
1035 | if (error) { | ||
1036 | sdev_printk(KERN_INFO, sdev, | ||
1037 | "failed to add device handler: %d\n", error); | ||
1038 | return error; | ||
1039 | } | ||
1040 | |||
1033 | device_enable_async_suspend(&sdev->sdev_dev); | 1041 | device_enable_async_suspend(&sdev->sdev_dev); |
1034 | error = device_add(&sdev->sdev_dev); | 1042 | error = device_add(&sdev->sdev_dev); |
1035 | if (error) { | 1043 | if (error) { |
1036 | sdev_printk(KERN_INFO, sdev, | 1044 | sdev_printk(KERN_INFO, sdev, |
1037 | "failed to add class device: %d\n", error); | 1045 | "failed to add class device: %d\n", error); |
1046 | scsi_dh_remove_device(sdev); | ||
1038 | device_del(&sdev->sdev_gendev); | 1047 | device_del(&sdev->sdev_gendev); |
1039 | return error; | 1048 | return error; |
1040 | } | 1049 | } |
@@ -1074,6 +1083,7 @@ void __scsi_remove_device(struct scsi_device *sdev) | |||
1074 | bsg_unregister_queue(sdev->request_queue); | 1083 | bsg_unregister_queue(sdev->request_queue); |
1075 | device_unregister(&sdev->sdev_dev); | 1084 | device_unregister(&sdev->sdev_dev); |
1076 | transport_remove_device(dev); | 1085 | transport_remove_device(dev); |
1086 | scsi_dh_remove_device(sdev); | ||
1077 | device_del(dev); | 1087 | device_del(dev); |
1078 | } else | 1088 | } else |
1079 | put_device(&sdev->sdev_dev); | 1089 | put_device(&sdev->sdev_dev); |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 9a058194b9bd..30d26e345dcc 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -1222,13 +1222,6 @@ show_sas_rphy_enclosure_identifier(struct device *dev, | |||
1222 | u64 identifier; | 1222 | u64 identifier; |
1223 | int error; | 1223 | int error; |
1224 | 1224 | ||
1225 | /* | ||
1226 | * Only devices behind an expander are supported, because the | ||
1227 | * enclosure identifier is a SMP feature. | ||
1228 | */ | ||
1229 | if (scsi_is_sas_phy_local(phy)) | ||
1230 | return -EINVAL; | ||
1231 | |||
1232 | error = i->f->get_enclosure_identifier(rphy, &identifier); | 1225 | error = i->f->get_enclosure_identifier(rphy, &identifier); |
1233 | if (error) | 1226 | if (error) |
1234 | return error; | 1227 | return error; |
@@ -1248,9 +1241,6 @@ show_sas_rphy_bay_identifier(struct device *dev, | |||
1248 | struct sas_internal *i = to_sas_internal(shost->transportt); | 1241 | struct sas_internal *i = to_sas_internal(shost->transportt); |
1249 | int val; | 1242 | int val; |
1250 | 1243 | ||
1251 | if (scsi_is_sas_phy_local(phy)) | ||
1252 | return -EINVAL; | ||
1253 | |||
1254 | val = i->f->get_bay_identifier(rphy); | 1244 | val = i->f->get_bay_identifier(rphy); |
1255 | if (val < 0) | 1245 | if (val < 0) |
1256 | return val; | 1246 | return val; |