]>
Commit | Line | Data |
---|---|---|
e2b52abc GKH |
1 | From 4224489f45b503f0a1f1cf310f76dc108f45689a Mon Sep 17 00:00:00 2001 |
2 | From: Kashyap, Desai <kashyap.desai@lsi.com> | |
3 | Date: Tue, 4 Jan 2011 11:38:39 +0530 | |
4 | Subject: [SCSI] mpt2sas: Kernel Panic during Large Topology discovery | |
5 | ||
6 | From: Kashyap, Desai <kashyap.desai@lsi.com> | |
7 | ||
8 | commit 4224489f45b503f0a1f1cf310f76dc108f45689a upstream. | |
9 | ||
10 | There was a configuration page timing out during the initial port | |
11 | enable at driver load time. The port enable would fail, and this would | |
12 | result in the driver unloading itself, meanwhile the driver was accessing | |
13 | freed memory in another context resulting in the panic. The fix is to | |
14 | prevent access to freed memory once the driver had issued the diag reset | |
15 | which woke up the sleeping port enable process. The routine | |
16 | _base_reset_handler was reorganized so the last sleeping process woken up was | |
17 | the port_enable. | |
18 | ||
19 | Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> | |
20 | Signed-off-by: James Bottomley <James.Bottomley@suse.de> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
22 | ||
23 | --- | |
24 | drivers/scsi/mpt2sas/mpt2sas_base.c | 13 +++++++++++-- | |
25 | 1 file changed, 11 insertions(+), 2 deletions(-) | |
26 | ||
27 | --- a/drivers/scsi/mpt2sas/mpt2sas_base.c | |
28 | +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |
29 | @@ -3786,6 +3786,8 @@ mpt2sas_base_detach(struct MPT2SAS_ADAPT | |
30 | static void | |
31 | _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) | |
32 | { | |
33 | + mpt2sas_scsih_reset_handler(ioc, reset_phase); | |
34 | + mpt2sas_ctl_reset_handler(ioc, reset_phase); | |
35 | switch (reset_phase) { | |
36 | case MPT2_IOC_PRE_RESET: | |
37 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: " | |
38 | @@ -3816,8 +3818,6 @@ _base_reset_handler(struct MPT2SAS_ADAPT | |
39 | "MPT2_IOC_DONE_RESET\n", ioc->name, __func__)); | |
40 | break; | |
41 | } | |
42 | - mpt2sas_scsih_reset_handler(ioc, reset_phase); | |
43 | - mpt2sas_ctl_reset_handler(ioc, reset_phase); | |
44 | } | |
45 | ||
46 | /** | |
47 | @@ -3871,6 +3871,7 @@ mpt2sas_base_hard_reset_handler(struct M | |
48 | { | |
49 | int r; | |
50 | unsigned long flags; | |
51 | + u8 pe_complete = ioc->wait_for_port_enable_to_complete; | |
52 | ||
53 | dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name, | |
54 | __func__)); | |
55 | @@ -3913,6 +3914,14 @@ mpt2sas_base_hard_reset_handler(struct M | |
56 | if (r) | |
57 | goto out; | |
58 | _base_reset_handler(ioc, MPT2_IOC_AFTER_RESET); | |
59 | + | |
60 | + /* If this hard reset is called while port enable is active, then | |
61 | + * there is no reason to call make_ioc_operational | |
62 | + */ | |
63 | + if (pe_complete) { | |
64 | + r = -EFAULT; | |
65 | + goto out; | |
66 | + } | |
67 | r = _base_make_ioc_operational(ioc, sleep_flag); | |
68 | if (!r) | |
69 | _base_reset_handler(ioc, MPT2_IOC_DONE_RESET); |